monospace_text_formatter 0.0.3 → 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.
data/Changelog CHANGED
@@ -1,3 +1,7 @@
1
+ 0.1.0 (February 29, 2012)
2
+ Implemented "padding" setting.
3
+ Fixed "width" calculation for Box class.
4
+
1
5
  0.0.3 (February 18, 2012)
2
6
  Fixed handling of non display length for horizontal alignment.
3
7
  Minor refactorings.
data/README.md CHANGED
@@ -37,6 +37,16 @@ The `line` object for the following examples:
37
37
  => "This is some ..."
38
38
  ```
39
39
 
40
+ * `padding_left` and `padding_right` (in number of characters)
41
+
42
+ ```ruby
43
+ line.padding_left = 3
44
+ line.padding_right = 2
45
+
46
+ line.to_s
47
+ => " This is ... "
48
+ ```
49
+
40
50
  * `omission`
41
51
 
42
52
  ```ruby
@@ -105,6 +115,24 @@ The `box` object for the following examples:
105
115
  "And second, a ... "]
106
116
  ```
107
117
 
118
+ * `padding_top`, `padding_right`, `padding_bottom` and `padding_left` (in number of lines/characters)
119
+
120
+ ```ruby
121
+ box.height = 5
122
+
123
+ box.padding_top = 1
124
+ box.padding_right = 1
125
+ box.padding_bottom = 2
126
+ box.padding_left = 2
127
+
128
+ box.lines
129
+ => [" ",
130
+ " First line. ",
131
+ " And second, a ... ",
132
+ " ",
133
+ " "]
134
+ ```
135
+
108
136
  * `omission`
109
137
 
110
138
  ```ruby
@@ -2,6 +2,11 @@ module MonospaceTextFormatter
2
2
  class Box
3
3
 
4
4
  def initialize(string_or_chunk, attrs={})
5
+ @padding_top = 0
6
+ @padding_right = 0
7
+ @padding_bottom = 0
8
+ @padding_left = 0
9
+
5
10
  @omission = string_to_chunk(" ...")
6
11
  @align = :left
7
12
  @valign = :top
@@ -13,6 +18,7 @@ module MonospaceTextFormatter
13
18
  attributes(attrs)
14
19
  end
15
20
 
21
+ attr_reader :padding_top, :padding_right, :padding_bottom, :padding_left
16
22
  attr_reader :omission, :align, :valign, :fill
17
23
 
18
24
  def width
@@ -20,7 +26,7 @@ module MonospaceTextFormatter
20
26
  end
21
27
 
22
28
  def height
23
- @fixed_height || content_lines.size
29
+ @fixed_height || padding_top + content_lines.size + padding_bottom
24
30
  end
25
31
 
26
32
  def attributes(attrs={})
@@ -31,7 +37,7 @@ module MonospaceTextFormatter
31
37
  return if fixed_width == @fixed_width
32
38
  raise ArgumentError, "The :width must be equal or greater than 0, but is #{fixed_width}" unless fixed_width.nil? or fixed_width >= 0
33
39
 
34
- @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = nil
40
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = @fixed_width_minus_padding = nil
35
41
  @fixed_width = fixed_width
36
42
  end
37
43
 
@@ -39,10 +45,46 @@ module MonospaceTextFormatter
39
45
  return if fixed_height == @fixed_height
40
46
  raise ArgumentError, "The :height must be equal or greater than 0, but is #{fixed_height}" unless fixed_height.nil? or fixed_height >= 0
41
47
 
42
- @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = nil
48
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = @fixed_height_minus_padding = nil
43
49
  @fixed_height = fixed_height
44
50
  end
45
51
 
52
+ def padding_top=(padding_top)
53
+ return if padding_top == @padding_top
54
+ raise ArgumentError, "The :padding_top must be a number equal or greater than 0, but is #{padding_top.inspect}" unless padding_top.kind_of?(Fixnum) && padding_top >= 0
55
+
56
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = nil
57
+ @content_lines = @empty_bottom_lines = @fixed_height_minus_padding = nil if @fixed_height
58
+ @padding_top = padding_top
59
+ end
60
+
61
+ def padding_right=(padding_right)
62
+ return if padding_right == @padding_right
63
+ raise ArgumentError, "The :padding_right must be a number equal or greater than 0, but is #{padding_right.inspect}" unless padding_right.kind_of?(Fixnum) && padding_right >= 0
64
+
65
+ @to_s = @lines = @aligned_all_lines = @all_lines = @content_lines = nil
66
+ @fixed_width_minus_padding = nil if @fixed_width
67
+ @padding_right = padding_right
68
+ end
69
+
70
+ def padding_bottom=(padding_bottom)
71
+ return if padding_bottom == @padding_bottom
72
+ raise ArgumentError, "The :padding_bottom must be a number equal or greater than 0, but is #{padding_bottom.inspect}" unless padding_bottom.kind_of?(Fixnum) && padding_bottom >= 0
73
+
74
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_bottom_lines = nil
75
+ @content_lines = @empty_top_lines = @fixed_height_minus_padding = nil if @fixed_height
76
+ @padding_bottom = padding_bottom
77
+ end
78
+
79
+ def padding_left=(padding_left)
80
+ return if padding_left == @padding_left
81
+ raise ArgumentError, "The :padding_left must be a number equal or greater than 0, but is #{padding_left.inspect}" unless padding_left.kind_of?(Fixnum) && padding_left >= 0
82
+
83
+ @to_s = @lines = @aligned_all_lines = @all_lines = @content_lines = nil
84
+ @fixed_width_minus_padding = nil if @fixed_width
85
+ @padding_left = padding_left
86
+ end
87
+
46
88
  def omission=(omission)
47
89
  return if omission == @omission
48
90
 
@@ -103,9 +145,17 @@ module MonospaceTextFormatter
103
145
  Line.new(string_or_chunk, attrs)
104
146
  end
105
147
 
148
+ def fixed_height_minus_padding
149
+ @fixed_height_minus_padding ||= @fixed_height && (@fixed_height - padding_top - padding_bottom)
150
+ end
151
+
152
+ def fixed_width_minus_padding
153
+ @fixed_width_minus_padding ||= @fixed_width && (@fixed_width - padding_left - padding_right)
154
+ end
155
+
106
156
  def aligned_all_lines
107
157
  @aligned_all_lines ||= all_lines.each do |line|
108
- line.attributes(:align => align, :fill => fill, :width => width)
158
+ line.attributes(:align => align, :fill => fill, :width => width, :padding_left => padding_left, :padding_right => padding_right)
109
159
  end
110
160
  end
111
161
 
@@ -114,53 +164,68 @@ module MonospaceTextFormatter
114
164
  end
115
165
 
116
166
  def empty_top_lines
117
- @empty_top_lines ||= if @fixed_height && fill && !fill.empty?
118
- case valign
119
- when :top
120
- []
121
- when :middle
122
- Array.new(((@fixed_height - content_lines.size) / 2.0).floor, new_line(""))
123
- when :bottom
124
- Array.new(@fixed_height - content_lines.size, new_line(""))
125
- end
126
- else
127
- []
128
- end
167
+ @empty_top_lines ||= Array.new(empty_top_lines_number, new_line(""))
168
+ end
169
+
170
+ def empty_top_lines_number
171
+ return 0 if fill.nil? or fill.empty?
172
+
173
+ [[padding_top +
174
+ if @fixed_height
175
+ case valign
176
+ when :top
177
+ 0
178
+ when :middle
179
+ ((fixed_height_minus_padding - content_lines.size) / 2.0).floor
180
+ when :bottom
181
+ fixed_height_minus_padding - content_lines.size
182
+ end
183
+ else
184
+ 0
185
+ end, @fixed_height && @fixed_height - content_lines.size].compact.min, 0].max
129
186
  end
130
187
 
131
188
  def empty_bottom_lines
132
- @empty_bottom_lines ||= if @fixed_height && fill && !fill.empty?
133
- case valign
134
- when :top
135
- Array.new(@fixed_height - content_lines.size, new_line(""))
136
- when :middle
137
- Array.new(((@fixed_height - content_lines.size) / 2.0).ceil, new_line(""))
138
- when :bottom
139
- []
140
- end
141
- else
142
- []
143
- end
189
+ @empty_bottom_lines ||= Array.new(empty_bottom_lines_number, new_line(""))
190
+ end
191
+
192
+ def empty_bottom_lines_number
193
+ return 0 if fill.nil? or fill.empty?
194
+
195
+ [[padding_bottom +
196
+ if @fixed_height
197
+ case valign
198
+ when :top
199
+ fixed_height_minus_padding - content_lines.size
200
+ when :middle
201
+ ((fixed_height_minus_padding - content_lines.size) / 2.0).ceil
202
+ when :bottom
203
+ 0
204
+ end
205
+ else
206
+ 0
207
+ end, @fixed_height && @fixed_height - content_lines.size].compact.min, 0].max
144
208
  end
145
209
 
146
210
  def content_lines
147
211
  return @content_lines unless @content_lines.nil?
148
- return @content_lines = [] if @fixed_width == 0 && @fixed_height.nil?
212
+ return @content_lines = [] if fixed_width_minus_padding && fixed_width_minus_padding <= 0 && fixed_height_minus_padding.nil?
149
213
  return @content_lines = [new_line("")] if @original_chunk.empty?
150
214
 
151
215
  @remaining_chunk = @original_chunk.duplicate
152
216
  @line_chunks = []
153
217
 
154
- until (@fixed_height && @line_chunks.size == @fixed_height) || @remaining_chunk.empty?
155
- @line_chunks << if @line_chunks.size + 1 == @fixed_height
218
+ until (fixed_height_minus_padding && @line_chunks.size >= fixed_height_minus_padding) || @remaining_chunk.empty?
219
+ @line_chunks << if @line_chunks.size + 1 == fixed_height_minus_padding
156
220
  @remaining_chunk
157
221
  else
158
- @remaining_chunk.slice!(@fixed_width ? @fixed_width : nil)
222
+ @remaining_chunk.slice!(fixed_width_minus_padding ? [fixed_width_minus_padding, 0].max : nil)
159
223
  end
160
224
  end
161
225
 
162
- common_width = @fixed_width || @line_chunks.map { |chunk| chunk.display_length }.max
163
- @content_lines = @line_chunks.map { |chunk| new_line(chunk, :width => common_width, :omission => omission) }
226
+ @content_lines = @line_chunks.map { |chunk| new_line(chunk, :omission => omission, :padding_left => padding_left, :padding_right => padding_right) }
227
+ common_width = @fixed_width || @content_lines.map { |line| line.width }.max
228
+ @content_lines.each { |line| line.width = common_width }
164
229
  end
165
230
  end
166
231
  end
@@ -2,10 +2,12 @@ module MonospaceTextFormatter
2
2
  class Line
3
3
 
4
4
  def initialize(string_or_chunk, attrs={})
5
- @omission = string_to_chunk(" ...")
6
- @align = :left
7
- @fill = " "
8
- @truncated = nil
5
+ @padding_left = 0
6
+ @padding_right = 0
7
+ @omission = string_to_chunk(" ...")
8
+ @align = :left
9
+ @fill = " "
10
+ @truncated = nil
9
11
 
10
12
  raise ArgumentError, "No string given" unless string_or_chunk
11
13
  @original_chunk = to_chunk_if_string(string_or_chunk)
@@ -13,10 +15,10 @@ module MonospaceTextFormatter
13
15
  attributes(attrs)
14
16
  end
15
17
 
16
- attr_reader :omission, :align, :fill
18
+ attr_reader :padding_left, :padding_right, :omission, :align, :fill
17
19
 
18
20
  def width
19
- @fixed_width || visible_chunk.display_length
21
+ @fixed_width || padding_left + visible_chunk.display_length + padding_right
20
22
  end
21
23
 
22
24
  def attributes(attrs={})
@@ -27,10 +29,28 @@ module MonospaceTextFormatter
27
29
  return if fixed_width == @fixed_width
28
30
  raise ArgumentError, "The :width must be equal or greater than 0, but is #{fixed_width}" unless fixed_width.nil? or fixed_width >= 0
29
31
 
30
- @aligned_visible_text = @visible_chunk = nil
32
+ @aligned_visible_text = @visible_chunk = @fixed_width_minus_padding = nil
31
33
  @fixed_width = fixed_width
32
34
  end
33
35
 
36
+ def padding_left=(padding_left)
37
+ return if padding_left == @padding_left
38
+ raise ArgumentError, "The :padding_left must be a number equal or greater than 0, but is #{padding_left.inspect}" unless padding_left.kind_of?(Fixnum) && padding_left >= 0
39
+
40
+ @aligned_visible_text = nil
41
+ @visible_chunk = @fixed_width_minus_padding = nil if @fixed_width
42
+ @padding_left = padding_left
43
+ end
44
+
45
+ def padding_right=(padding_right)
46
+ return if padding_right == @padding_right
47
+ raise ArgumentError, "The :padding_right must be a number equal or greater than 0, but is #{padding_right.inspect}" unless padding_right.kind_of?(Fixnum) && padding_right >= 0
48
+
49
+ @aligned_visible_text = nil
50
+ @visible_chunk = @fixed_width_minus_padding = nil if @fixed_width
51
+ @padding_right = padding_right
52
+ end
53
+
34
54
  def omission=(omission)
35
55
  return if omission == @omission
36
56
 
@@ -76,28 +96,66 @@ module MonospaceTextFormatter
76
96
  Chunk.new(string)
77
97
  end
78
98
 
99
+ def fixed_width_minus_padding
100
+ @fixed_width_minus_padding ||= @fixed_width && (@fixed_width - padding_left - padding_right)
101
+ end
102
+
79
103
  def aligned_visible_text
80
- @aligned_visible_text ||= if @fixed_width.nil? or fill.nil? or fill.empty?
104
+ @aligned_visible_text ||= if fill.nil? or fill.empty?
81
105
  visible_chunk.to_s
82
106
  else
83
- case align
84
- when :left
85
- visible_chunk.to_s.ljust( @fixed_width + visible_chunk.non_display_length, fill)
86
- when :center
87
- visible_chunk.to_s.center(@fixed_width + visible_chunk.non_display_length, fill)
88
- when :right
89
- visible_chunk.to_s.rjust( @fixed_width + visible_chunk.non_display_length, fill)
90
- end
107
+ string = visible_chunk.to_s
108
+ string
109
+ .rjust(left_fill_length(visible_chunk.display_length) + string.length , fill)
110
+ .ljust(left_fill_length(visible_chunk.display_length) + string.length + right_fill_length(visible_chunk.display_length), fill)
91
111
  end
92
112
  end
93
113
 
114
+ def left_fill_length(display_length)
115
+ return 0 if fill.nil? or fill.empty?
116
+ return @fixed_width || 0 if display_length == 0
117
+
118
+ [padding_left +
119
+ if @fixed_width
120
+ case align
121
+ when :left
122
+ 0
123
+ when :center
124
+ ((fixed_width_minus_padding - display_length) / 2.0).floor
125
+ when :right
126
+ fixed_width_minus_padding - display_length
127
+ end
128
+ else
129
+ 0
130
+ end, @fixed_width && @fixed_width - display_length].compact.min
131
+ end
132
+
133
+ def right_fill_length(display_length)
134
+ return 0 if fill.nil? or fill.empty?
135
+ return 0 if display_length == 0
136
+
137
+ [padding_right +
138
+ if @fixed_width
139
+ case align
140
+ when :left
141
+ fixed_width_minus_padding - display_length
142
+ when :center
143
+ ((fixed_width_minus_padding - display_length) / 2.0).ceil
144
+ when :right
145
+ 0
146
+ end
147
+ else
148
+ 0
149
+ end, @fixed_width && @fixed_width - display_length].compact.min
150
+ end
151
+
94
152
  def visible_chunk
95
- @visible_chunk ||= if @original_chunk.multiline? || @fixed_width && @original_chunk.display_length > @fixed_width
153
+ @visible_chunk ||= if @original_chunk.multiline? || fixed_width_minus_padding && @original_chunk.display_length > fixed_width_minus_padding
96
154
  @truncated = true
97
- @original_chunk.slice(@fixed_width ? @fixed_width - omission.display_length : nil).concat(omission).slice!(@fixed_width)
155
+ @original_chunk.slice(fixed_width_minus_padding ? fixed_width_minus_padding - omission.display_length : nil).concat(omission).slice!(fixed_width_minus_padding)
98
156
  else
99
157
  @truncated = false
100
- @original_chunk.slice(@fixed_width)
158
+ @original_chunk.slice(fixed_width_minus_padding)
101
159
  end
102
160
  end
103
161
  end
@@ -1,3 +1,3 @@
1
1
  module MonospaceTextFormatter
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monospace_text_formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-18 00:00:00.000000000Z
12
+ date: 2012-02-29 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &83233040 !ruby/object:Gem::Requirement
16
+ requirement: &71850560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '2.0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *83233040
24
+ version_requirements: *71850560
25
25
  description: Formats monospaced text into a line or visual box of defined 'width'
26
26
  and 'height' boundaries (expressed in number of characters).
27
27
  email: jacekmikrut.software@gmail.com