monospace_text_formatter 0.0.1

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