monospace_text_formatter 0.0.1

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 ADDED
@@ -0,0 +1,2 @@
1
+ 0.0.1 (February 16, 2012)
2
+ Initial release.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Jacek Mikrut
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,173 @@
1
+ MonospaceTextFormatter
2
+ ======================
3
+
4
+ MonospaceTextFormatter is a Ruby Gem that formats monospaced text into a **line or visual box** of defined **width** and **height** boundaries (expressed in number of characters), by wrapping and/or truncating the text, and filling remaining area with spaces (or custom characters) so that it forms a rectangular block. It **doesn't split words** unless they are longer than the width boundary. It also applies **horizontal** and **vertical alignment** to the text. All these attributes are customizable and optional.
5
+
6
+ * **MonospaceTextFormatter::Line** class formats a single-line text;
7
+
8
+ * **MonospaceTextFormatter::Box** class formats multiple-line text.
9
+
10
+ Usage examples
11
+ --------------
12
+
13
+ Note: All the following attributes can also be provided in Hash as the second argument for the constructor.
14
+
15
+ ### MonospaceTextFormatter::Line
16
+
17
+ The `line` object for the following examples:
18
+
19
+ ```ruby
20
+ line = MonospaceTextFormatter::Line.new("This is some text.")
21
+ ```
22
+
23
+ ```ruby
24
+ line.to_s
25
+ => "This is some text."
26
+ ```
27
+
28
+ * `width` (a number of characters)
29
+
30
+ ```ruby
31
+ line.width = 20
32
+ line.to_s
33
+ => "This is some text. "
34
+
35
+ line.width = 16
36
+ line.to_s
37
+ => "This is some ..."
38
+ ```
39
+
40
+ * `omission`
41
+
42
+ ```ruby
43
+ line.omission = " [...]"
44
+ line.to_s
45
+ => "This is [...] "
46
+ ```
47
+
48
+ * `align` (available options: `:left` _(default)_, `:center` and `:right`)
49
+
50
+ ```ruby
51
+ line.align = :right
52
+ line.to_s
53
+ => " This is [...]"
54
+ ```
55
+
56
+ * `fill`
57
+
58
+ ```ruby
59
+ line.fill = "-"
60
+ line.to_s
61
+ => "---This is [...]"
62
+ ```
63
+
64
+ ### MonospaceTextFormatter::Box
65
+
66
+ The `box` object for the following examples:
67
+
68
+ ```ruby
69
+ box = MonospaceTextFormatter::Box.new("First line.\nAnd second, a little bit longer line.")
70
+ ```
71
+
72
+ ```ruby
73
+ box.to_s
74
+ => "First line. \nAnd second, a little bit longer line."
75
+
76
+ box.lines
77
+ => ["First line. ",
78
+ "And second, a little bit longer line."]
79
+ ```
80
+
81
+ * `width` (a number of characters)
82
+
83
+ ```ruby
84
+ box.width = 20
85
+ box.lines
86
+ => ["First line. ",
87
+ "And second, a little",
88
+ "bit longer line. "]
89
+ ```
90
+
91
+ * `height` (a number of lines)
92
+
93
+ ```ruby
94
+ box.height = 5
95
+ box.lines
96
+ => ["First line. ",
97
+ "And second, a little",
98
+ "bit longer line. ",
99
+ " ",
100
+ " "]
101
+
102
+ box.height = 2
103
+ box.lines
104
+ => ["First line. ",
105
+ "And second, a ... "]
106
+ ```
107
+
108
+ * `omission`
109
+
110
+ ```ruby
111
+ box.omission = " [...]"
112
+ box.lines
113
+ => ["First line. ",
114
+ "And second, a [...] "]
115
+ ```
116
+
117
+ * `align` (available options: `:left` _(default)_, `:center` and `:right`)
118
+
119
+ ```ruby
120
+ box.align = :center
121
+ box.lines
122
+ => [" First line. ",
123
+ "And second, a [...] "]
124
+ ```
125
+
126
+ * `valign` (available options: `:top` _(default)_, `:middle` and `:bottom`)
127
+
128
+ ```ruby
129
+ box.height = 5
130
+ box.valign = :bottom
131
+ box.lines
132
+ => [" ",
133
+ " ",
134
+ " First line. ",
135
+ "And second, a little",
136
+ " bit longer line. "]
137
+ ```
138
+
139
+ * `fill`
140
+
141
+ ``` ruby
142
+ box.fill = "#"
143
+ box.lines
144
+ => ["####################",
145
+ "####################",
146
+ "####First line.#####",
147
+ "And second, a little",
148
+ "##bit longer line.##"]
149
+ ```
150
+
151
+ More can be found in **RSpec examples**.
152
+
153
+ Installation
154
+ ------------
155
+
156
+ As a Ruby Gem, MonospaceTextFormatter can be installed either by running
157
+
158
+ ```bash
159
+ gem install monospace_text_formatter
160
+ ```
161
+
162
+ or adding
163
+
164
+ ```ruby
165
+ gem "monospace_text_formatter"
166
+ ```
167
+
168
+ to the Gemfile and then invoking `bundle install`.
169
+
170
+ License
171
+ -------
172
+
173
+ License is included in the LICENSE file.
@@ -0,0 +1,40 @@
1
+ module MonospaceTextFormatter
2
+ class AtomicChunk
3
+
4
+ def initialize(string)
5
+ @string = string
6
+ end
7
+
8
+ def display_string
9
+ @display_string ||= @string
10
+ end
11
+
12
+ def display_length
13
+ @display_length ||= display_string.length
14
+ end
15
+
16
+ def newline?
17
+ @string == "\n"
18
+ end
19
+
20
+ def blank?
21
+ @string.strip.empty?
22
+ end
23
+
24
+ def empty?
25
+ @string.empty?
26
+ end
27
+
28
+ def to_s
29
+ @string
30
+ end
31
+
32
+ def inspect
33
+ %Q(#<#{self.class} #{to_s.inspect}>)
34
+ end
35
+
36
+ def ==(other)
37
+ to_s == other.to_s
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module MonospaceTextFormatter
2
+ class AtomicChunkFactory
3
+
4
+ REGEXP = /^(?:\n|[ \t]+|[^ \t\n]+)/
5
+
6
+ def new(string)
7
+ AtomicChunk.new(string)
8
+ end
9
+
10
+ def slice_from!(string)
11
+ (slice = string.slice!(regexp)) ? new(slice) : nil
12
+ end
13
+
14
+ def slice_from(string)
15
+ slice_from!(string.dup)
16
+ end
17
+
18
+ def split_string(string, length)
19
+ duplicated_string = string.dup
20
+ head_chunk = new(duplicated_string.slice!(0, length))
21
+ tail_chunk = new(duplicated_string)
22
+ [ head_chunk, tail_chunk ]
23
+ end
24
+
25
+ protected
26
+
27
+ def regexp
28
+ REGEXP
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,158 @@
1
+ module MonospaceTextFormatter
2
+ class Box
3
+
4
+ def initialize(string_or_chunk, attrs={})
5
+ @omission = string_to_chunk(" ...")
6
+ @align = :left
7
+ @valign = :top
8
+ @fill = " "
9
+
10
+ raise ArgumentError, "No string given" unless string_or_chunk
11
+ @original_chunk = to_chunk_if_string(string_or_chunk)
12
+
13
+ attributes(attrs)
14
+ end
15
+
16
+ attr_reader :omission, :align, :valign, :fill
17
+
18
+ def width
19
+ @fixed_width || content_lines.first && content_lines.first.width
20
+ end
21
+
22
+ def height
23
+ @fixed_height || content_lines.size
24
+ end
25
+
26
+ def attributes(attrs={})
27
+ attrs.each { |name, value| send("#{name}=", value) }
28
+ end
29
+
30
+ def width=(fixed_width)
31
+ return if fixed_width == @fixed_width
32
+ raise ArgumentError, "The :width must be equal or greater than 0, but is #{fixed_width}" unless fixed_width.nil? or fixed_width >= 0
33
+
34
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = nil
35
+ @fixed_width = fixed_width
36
+ end
37
+
38
+ def height=(fixed_height)
39
+ return if fixed_height == @fixed_height
40
+ raise ArgumentError, "The :height must be equal or greater than 0, but is #{fixed_height}" unless fixed_height.nil? or fixed_height >= 0
41
+
42
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @content_lines = @empty_bottom_lines = nil
43
+ @fixed_height = fixed_height
44
+ end
45
+
46
+ def omission=(omission)
47
+ return if omission == @omission
48
+
49
+ @to_s = @lines = @aligned_all_lines = @all_lines = @content_lines = nil if @content_lines && truncated?
50
+ @omission = to_chunk_if_string(omission)
51
+ end
52
+
53
+ def align=(align)
54
+ return if align == @align
55
+ raise ArgumentError, "The :align must be a Symbol or String with value 'left', 'center' or 'right', but is #{align.inspect}" unless [:left, :center, :right].include?(align.to_sym)
56
+
57
+ @to_s = @lines = @aligned_all_lines = nil
58
+ @align = align.to_sym
59
+ end
60
+
61
+ def valign=(valign)
62
+ return if valign == @valign
63
+ raise ArgumentError, "The :valign must be a Symbol or String with value 'top', 'middle' or 'bottom', but is #{valign.inspect}" unless [:top, :middle, :bottom].include?(valign.to_sym)
64
+
65
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @empty_bottom_lines = nil
66
+ @valign = valign.to_sym
67
+ end
68
+
69
+ def fill=(fill)
70
+ return if fill == @fill
71
+
72
+ @to_s = @lines = @aligned_all_lines = @all_lines = @empty_top_lines = @empty_bottom_lines = nil
73
+ @fill = fill
74
+ end
75
+
76
+ def truncated?
77
+ content_lines.last && content_lines.last.truncated?
78
+ end
79
+
80
+ def lines
81
+ @lines ||= aligned_all_lines.map { |aligned_line| aligned_line.to_s }
82
+ end
83
+
84
+ def to_s
85
+ @to_s ||= lines.join("\n")
86
+ end
87
+
88
+ private
89
+
90
+ def to_chunk_if_string(string)
91
+ string.is_a?(String) ? string_to_chunk(string) : string
92
+ end
93
+
94
+ def string_to_chunk(string)
95
+ Chunk.new(string)
96
+ end
97
+
98
+ def aligned_all_lines
99
+ @aligned_all_lines ||= all_lines.each do |line|
100
+ line.attributes(:align => align, :fill => fill, :width => width)
101
+ end
102
+ end
103
+
104
+ def all_lines
105
+ @all_lines ||= empty_top_lines + content_lines + empty_bottom_lines
106
+ end
107
+
108
+ def empty_top_lines
109
+ @empty_top_lines ||= if @fixed_height && fill && !fill.empty?
110
+ case valign
111
+ when :top
112
+ []
113
+ when :middle
114
+ Array.new(((@fixed_height - content_lines.size) / 2.0).floor, Line.new(""))
115
+ when :bottom
116
+ Array.new(@fixed_height - content_lines.size, Line.new(""))
117
+ end
118
+ else
119
+ []
120
+ end
121
+ end
122
+
123
+ def empty_bottom_lines
124
+ @empty_bottom_lines ||= if @fixed_height && fill && !fill.empty?
125
+ case valign
126
+ when :top
127
+ Array.new(@fixed_height - content_lines.size, Line.new(""))
128
+ when :middle
129
+ Array.new(((@fixed_height - content_lines.size) / 2.0).ceil, Line.new(""))
130
+ when :bottom
131
+ []
132
+ end
133
+ else
134
+ []
135
+ end
136
+ end
137
+
138
+ def content_lines
139
+ return @content_lines unless @content_lines.nil?
140
+ return @content_lines = [] if @fixed_width == 0 && @fixed_height.nil?
141
+ return @content_lines = [Line.new("")] if @original_chunk.empty?
142
+
143
+ @remaining_chunk = @original_chunk.duplicate
144
+ @line_chunks = []
145
+
146
+ until (@fixed_height && @line_chunks.size == @fixed_height) || @remaining_chunk.empty?
147
+ @line_chunks << if @line_chunks.size + 1 == @fixed_height
148
+ @remaining_chunk
149
+ else
150
+ @remaining_chunk.slice!(@fixed_width ? @fixed_width : nil)
151
+ end
152
+ end
153
+
154
+ common_width = @fixed_width || @line_chunks.map { |chunk| chunk.display_length }.max
155
+ @content_lines = @line_chunks.map { |chunk| Line.new(chunk, :width => common_width, :omission => omission) }
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,174 @@
1
+ module MonospaceTextFormatter
2
+ class Chunk
3
+
4
+ def initialize(string=nil)
5
+ @remaining_string = ""
6
+ @atomic_chunks = []
7
+ @display_length = 0
8
+
9
+ concat(string) unless string.nil?
10
+ end
11
+
12
+ def duplicate
13
+ duplicate = self.clone
14
+ duplicate.instance_variable_set("@remaining_string", @remaining_string.clone)
15
+ duplicate.instance_variable_set( "@atomic_chunks", @atomic_chunks.clone)
16
+ duplicate
17
+ end
18
+
19
+ def multiline?
20
+ atomic_chunks.any? { |atomic_chunk| atomic_chunk.newline? } or remaining_string.include?("\n")
21
+ end
22
+
23
+ def blank?
24
+ to_s.strip.empty?
25
+ end
26
+
27
+ def empty?
28
+ to_s.empty?
29
+ end
30
+
31
+ def display_length
32
+ slice_whole_remaining_string unless remaining_string.empty?
33
+ @display_length
34
+ end
35
+
36
+ def concat(string_or_chunk)
37
+
38
+ if string_or_chunk.kind_of?(Chunk)
39
+ slice_whole_remaining_string if string_or_chunk.atomic_chunks.any?
40
+
41
+ string_or_chunk.atomic_chunks.each { |atomic_chunk| push_atomic_chunk(atomic_chunk) }
42
+ remaining_string.concat(string_or_chunk.remaining_string)
43
+
44
+ else
45
+ remaining_string.concat(string_or_chunk)
46
+
47
+ end
48
+ self
49
+ end
50
+
51
+ def +(string_or_chunk)
52
+ duplicate.concat(string_or_chunk)
53
+ end
54
+
55
+ def slice!(max_display_length=nil, smartly_split_too_long_words=true)
56
+ sliced_chunk = self.class.new
57
+ return sliced_chunk if max_display_length == 0
58
+
59
+ while retrieve_first_atomic_chunk
60
+
61
+ if atomic_chunks.first.blank? and sliced_chunk.blank?
62
+ shift_atomic_chunk
63
+ next
64
+
65
+ elsif max_display_length && (atomic_chunks.first.display_length + sliced_chunk.display_length > max_display_length)
66
+ break
67
+
68
+ elsif atomic_chunks.first.newline?
69
+ shift_atomic_chunk
70
+ break
71
+
72
+ else
73
+ sliced_chunk.push_atomic_chunk(shift_atomic_chunk)
74
+ end
75
+ end
76
+
77
+ sliced_chunk.pop_atomic_chunk while sliced_chunk.atomic_chunks.last && sliced_chunk.atomic_chunks.last.blank?
78
+
79
+ if smartly_split_too_long_words &&
80
+ max_display_length &&
81
+ retrieve_first_atomic_chunk &&
82
+ atomic_chunks.first.display_length > max_display_length
83
+
84
+ smartly_split_too_long_word(max_display_length, sliced_chunk)
85
+ end
86
+
87
+ sliced_chunk
88
+ end
89
+
90
+ def slice(max_display_length)
91
+ duplicate.slice!(max_display_length)
92
+ end
93
+
94
+ def to_s
95
+ atomic_chunks.map { |atomic_chunk| atomic_chunk.to_s }.join + remaining_string
96
+ end
97
+
98
+ def inspect
99
+ %Q(#<#{self.class} #{to_s.inspect}>)
100
+ end
101
+
102
+ def ==(other)
103
+ to_s == other.to_s
104
+ end
105
+
106
+ protected
107
+
108
+ def atomic_chunk_factory
109
+ @atomic_chunk_factory ||= AtomicChunkFactory.new
110
+ end
111
+
112
+ attr_accessor :atomic_chunks, :remaining_string
113
+
114
+ def push_atomic_chunk(atomic_chunk)
115
+ atomic_chunks.push(atomic_chunk)
116
+ @display_length += atomic_chunk.display_length
117
+ end
118
+
119
+ def pop_atomic_chunk
120
+ chunk = atomic_chunks.pop
121
+ @display_length -= chunk.display_length
122
+ chunk
123
+ end
124
+
125
+ def unshift_atomic_chunk(atomic_chunk)
126
+ atomic_chunks.unshift(atomic_chunk)
127
+ @display_length += atomic_chunk.display_length
128
+ end
129
+
130
+ def shift_atomic_chunk
131
+ chunk = atomic_chunks.shift
132
+ @display_length -= chunk.display_length
133
+ chunk
134
+ end
135
+
136
+ def delete_atomic_chunk_at(index)
137
+ chunk = atomic_chunks.delete_at(index)
138
+ @display_length -= chunk.display_length
139
+ chunk
140
+ end
141
+
142
+ def retrieve_first_atomic_chunk
143
+ !!(atomic_chunks.first or slice_atomic_chunk_from_remaining_string!)
144
+ end
145
+
146
+ def slice_whole_remaining_string
147
+ slice_atomic_chunk_from_remaining_string! until remaining_string.empty?
148
+ end
149
+
150
+ def slice_atomic_chunk_from_remaining_string!
151
+ if atomic_chunk = slice_from_remaining_string!
152
+ push_atomic_chunk(atomic_chunk)
153
+ atomic_chunk
154
+ end
155
+ end
156
+
157
+ def slice_from_remaining_string!
158
+ atomic_chunk_factory.slice_from!(remaining_string)
159
+ end
160
+
161
+ def smartly_split_too_long_word(max_display_length, sliced_chunk)
162
+ length_needed = max_display_length - sliced_chunk.display_length - (sliced_chunk.blank? ? 0 : 1)
163
+ return unless atomic_chunks.first.display_length % max_display_length <= length_needed
164
+
165
+ atomic_chunk = shift_atomic_chunk
166
+ atomic_chunk_1, atomic_chunk_2 = atomic_chunk_factory.split_string(atomic_chunk.to_s, length_needed)
167
+
168
+ sliced_chunk.concat(" ") unless sliced_chunk.blank?
169
+ sliced_chunk.concat(atomic_chunk_1.to_s)
170
+
171
+ unshift_atomic_chunk(atomic_chunk_2)
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,100 @@
1
+ module MonospaceTextFormatter
2
+ class Line
3
+
4
+ def initialize(string_or_chunk, attrs={})
5
+ @omission = string_to_chunk(" ...")
6
+ @align = :left
7
+ @fill = " "
8
+ @truncated = nil
9
+
10
+ raise ArgumentError, "No string given" unless string_or_chunk
11
+ @original_chunk = to_chunk_if_string(string_or_chunk)
12
+
13
+ attributes(attrs)
14
+ end
15
+
16
+ attr_reader :omission, :align, :fill
17
+
18
+ def width
19
+ @fixed_width || visible_chunk.display_length
20
+ end
21
+
22
+ def attributes(attrs={})
23
+ attrs.each { |name, value| send("#{name}=", value) }
24
+ end
25
+
26
+ def width=(fixed_width)
27
+ return if fixed_width == @fixed_width
28
+ raise ArgumentError, "The :width must be equal or greater than 0, but is #{fixed_width}" unless fixed_width.nil? or fixed_width >= 0
29
+
30
+ @aligned_visible_text = @visible_chunk = nil
31
+ @fixed_width = fixed_width
32
+ end
33
+
34
+ def omission=(omission)
35
+ return if omission == @omission
36
+
37
+ @aligned_visible_text = @visible_chunk = nil if @truncated
38
+ @omission = to_chunk_if_string(omission)
39
+ end
40
+
41
+ def align=(align)
42
+ return if align == @align
43
+ raise ArgumentError, "The :align must be a Symbol or String with value 'left', 'center' or 'right', but is #{align.inspect}" unless [:left, :center, :right].include?(align.to_sym)
44
+
45
+ @aligned_visible_text = nil
46
+ @align = align.to_sym
47
+ end
48
+
49
+ def fill=(fill)
50
+ return if fill == @fill
51
+
52
+ @aligned_visible_text = nil
53
+ @fill = fill
54
+ end
55
+
56
+ def truncated?
57
+ visible_chunk
58
+ @truncated
59
+ end
60
+
61
+ def to_s
62
+ aligned_visible_text
63
+ end
64
+
65
+ private
66
+
67
+ def to_chunk_if_string(string)
68
+ string.is_a?(String) ? string_to_chunk(string) : string
69
+ end
70
+
71
+ def string_to_chunk(string)
72
+ Chunk.new(string)
73
+ end
74
+
75
+ def aligned_visible_text
76
+ @aligned_visible_text ||= if @fixed_width.nil? or fill.nil? or fill.empty?
77
+ visible_chunk.to_s
78
+ else
79
+ case align
80
+ when :left
81
+ visible_chunk.to_s.ljust(@fixed_width, fill)
82
+ when :center
83
+ visible_chunk.to_s.center(@fixed_width, fill)
84
+ when :right
85
+ visible_chunk.to_s.rjust(@fixed_width, fill)
86
+ end
87
+ end
88
+ end
89
+
90
+ def visible_chunk
91
+ @visible_chunk ||= if @original_chunk.multiline? || @fixed_width && @original_chunk.display_length > @fixed_width
92
+ @truncated = true
93
+ @original_chunk.slice(@fixed_width ? @fixed_width - omission.display_length : nil).concat(omission).slice!(@fixed_width)
94
+ else
95
+ @truncated = false
96
+ @original_chunk.slice(@fixed_width)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ module MonospaceTextFormatter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ require "monospace_text_formatter/version"
2
+
3
+ require "monospace_text_formatter/atomic_chunk"
4
+ require "monospace_text_formatter/atomic_chunk_factory"
5
+ require "monospace_text_formatter/chunk"
6
+ require "monospace_text_formatter/line"
7
+ require "monospace_text_formatter/box"
8
+
9
+ module MonospaceTextFormatter
10
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monospace_text_formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jacek Mikrut
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70478590 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70478590
25
+ description: Formats monospaced text into a line or visual box of defined 'width'
26
+ and 'height' boundaries (expressed in number of characters).
27
+ email: jacekmikrut.software@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - lib/monospace_text_formatter/atomic_chunk_factory.rb
33
+ - lib/monospace_text_formatter/box.rb
34
+ - lib/monospace_text_formatter/version.rb
35
+ - lib/monospace_text_formatter/atomic_chunk.rb
36
+ - lib/monospace_text_formatter/line.rb
37
+ - lib/monospace_text_formatter/chunk.rb
38
+ - lib/monospace_text_formatter.rb
39
+ - README.md
40
+ - LICENSE
41
+ - Changelog
42
+ homepage: http://github.com/jacekmikrut/monospace_text_formatter
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.12
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Formats monospaced text into a line or visual box.
66
+ test_files: []