monospace_text_formatter 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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