chamomile-flourish 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flourish
4
+ module Wrap
5
+ class << self
6
+ def word_wrap(str, width)
7
+ return str if width <= 0
8
+
9
+ lines = str.split("\n", -1)
10
+ result = []
11
+
12
+ lines.each do |line|
13
+ result.concat(wrap_line(line, width))
14
+ end
15
+
16
+ result.join("\n")
17
+ end
18
+
19
+ private
20
+
21
+ def wrap_line(line, width)
22
+ return [""] if line.empty?
23
+
24
+ state = { result: [], current: +"", current_width: 0, active_sgr: +"" }
25
+ i = 0
26
+ chars = line.chars
27
+
28
+ while i < chars.length
29
+ seq = chars[i] == "\e" ? ANSI.extract_escape(chars, i) : nil
30
+ if seq
31
+ state[:current] << seq
32
+ ANSI.track_sgr(state[:active_sgr], seq)
33
+ i += seq.length
34
+ next
35
+ end
36
+
37
+ ch = chars[i]
38
+ ch_width = ANSI.printable_width(ch)
39
+ i += 1
40
+
41
+ if state[:current_width] + ch_width > width && state[:current_width].positive?
42
+ emit_break(state)
43
+ next if ch == " " # skip leading space after break
44
+ end
45
+
46
+ state[:current] << ch
47
+ state[:current_width] += ch_width
48
+ end
49
+
50
+ close_final_line(state)
51
+ end
52
+
53
+ def emit_break(state)
54
+ break_pos = find_break_pos(state[:current])
55
+
56
+ if break_pos&.positive?
57
+ break_at_word_boundary(state, break_pos)
58
+ else
59
+ force_break(state)
60
+ end
61
+ end
62
+
63
+ def break_at_word_boundary(state, break_pos)
64
+ before = state[:current][0...break_pos]
65
+ after_start = break_pos
66
+ after_start += 1 if state[:current][break_pos] == " "
67
+ after = state[:current][after_start..]
68
+
69
+ before << "\e[0m" unless state[:active_sgr].empty?
70
+ state[:result] << before
71
+
72
+ state[:current] = +""
73
+ state[:current] << state[:active_sgr] unless state[:active_sgr].empty?
74
+ state[:current] << after
75
+ state[:current_width] = ANSI.printable_width(after)
76
+ end
77
+
78
+ def force_break(state)
79
+ state[:current] << "\e[0m" unless state[:active_sgr].empty?
80
+ state[:result] << state[:current]
81
+ state[:current] = +""
82
+ state[:current] << state[:active_sgr] unless state[:active_sgr].empty?
83
+ state[:current_width] = 0
84
+ end
85
+
86
+ def close_final_line(state)
87
+ state[:current] << "\e[0m" if !state[:active_sgr].empty? && !state[:current].empty?
88
+ state[:result] << state[:current]
89
+ state[:result]
90
+ end
91
+
92
+ def find_break_pos(str)
93
+ pos = nil
94
+ i = 0
95
+ chars = str.chars
96
+ while i < chars.length
97
+ if chars[i] == "\e"
98
+ esc = ANSI.extract_escape(chars, i)
99
+ if esc
100
+ i += esc.length
101
+ next
102
+ end
103
+ end
104
+ pos = i if [" ", "-"].include?(chars[i])
105
+ i += 1
106
+ end
107
+ pos
108
+ end
109
+ end
110
+ end
111
+ end
data/lib/flourish.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "flourish/version"
4
+ require_relative "flourish/ansi"
5
+ require_relative "flourish/color"
6
+ require_relative "flourish/color_profile"
7
+ require_relative "flourish/wrap"
8
+ require_relative "flourish/border"
9
+ require_relative "flourish/align"
10
+ require_relative "flourish/join"
11
+ require_relative "flourish/place"
12
+ require_relative "flourish/style"
13
+
14
+ module Flourish
15
+ # Position constants
16
+ TOP = 0.0
17
+ LEFT = 0.0
18
+ CENTER = 0.5
19
+ BOTTOM = 1.0
20
+ RIGHT = 1.0
21
+
22
+ class << self
23
+ def width(str)
24
+ ANSI.printable_width(str)
25
+ end
26
+
27
+ def height(str)
28
+ ANSI.height(str)
29
+ end
30
+
31
+ def size(str)
32
+ ANSI.size(str)
33
+ end
34
+
35
+ def join_horizontal(position, *strs)
36
+ Join.horizontal(position, *strs)
37
+ end
38
+
39
+ def join_vertical(position, *strs)
40
+ Join.vertical(position, *strs)
41
+ end
42
+
43
+ def place(width, height, h_pos, v_pos, str)
44
+ Place.place(width, height, h_pos, v_pos, str)
45
+ end
46
+
47
+ def place_horizontal(width, pos, str)
48
+ Place.place_horizontal(width, pos, str)
49
+ end
50
+
51
+ def place_vertical(height, pos, str)
52
+ Place.place_vertical(height, pos, str)
53
+ end
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chamomile-flourish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chamomile Contributors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: CSS-like box model styling for terminal output — colors, padding, margins,
42
+ borders, alignment
43
+ email:
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/flourish.rb
49
+ - lib/flourish/align.rb
50
+ - lib/flourish/ansi.rb
51
+ - lib/flourish/border.rb
52
+ - lib/flourish/color.rb
53
+ - lib/flourish/color_profile.rb
54
+ - lib/flourish/join.rb
55
+ - lib/flourish/place.rb
56
+ - lib/flourish/style.rb
57
+ - lib/flourish/version.rb
58
+ - lib/flourish/wrap.rb
59
+ homepage: https://github.com/chamomile-rb/flourish
60
+ licenses:
61
+ - MIT
62
+ metadata:
63
+ rubygems_mfa_required: 'true'
64
+ homepage_uri: https://github.com/chamomile-rb/flourish
65
+ source_code_uri: https://github.com/chamomile-rb/flourish
66
+ changelog_uri: https://github.com/chamomile-rb/flourish/blob/master/CHANGELOG.md
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.2.0
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.5.11
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Terminal styling library for Ruby
86
+ test_files: []