montoc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 22d841de97a5b5b8e39b3e5827693fe6fb81a3c5
4
+ data.tar.gz: f478d0705f8ddc55f14f1621caa08071f7bc057b
5
+ SHA512:
6
+ metadata.gz: 91687e0f2ea29d6e5933047eba244f5a862bec15ef9d982d6bd29eb3f4aefaf73d7168d60e7c37b8eb892264b3bc51d11a678942ba56afa9be1b02e6106e025e
7
+ data.tar.gz: 3337e1f3fbde5af5675274d94dc1a3624962cba774bb65ce1244c6930adb59659fac250953a88bddc8ed00e1a194b4b5378b92783aafe74bf0b9cf6ae2e18e2e
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in montoc.gemspec
4
+ gemspec
@@ -0,0 +1,15 @@
1
+ Montoc (Monospace Text Document), a library to modify/format plain text.
2
+ Copyright (C) 2014 Adrian Setyadi
3
+
4
+ This program is free software: you can redistribute it and/or modify it
5
+ under the terms of the GNU General Public License as published by the
6
+ Free Software Foundation, either version 3 of the License, or (at your
7
+ option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful, but
10
+ WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12
+ Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License along
15
+ with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,35 @@
1
+ # Montoc
2
+
3
+ Monospace Text Document: convert any plain text to rectangularize text
4
+ (same number of characters per line) or text matrix (two dimensional
5
+ Array of chars) by adding spaces in between the text. Set alignment to
6
+ left, right, center, and justify. You can also reflow the text to the
7
+ specified columns, and many other features.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'montoc'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install montoc
24
+
25
+ ## Usage
26
+
27
+ require 'montoc'
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it ( https://github.com/styd/montoc/fork )
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,336 @@
1
+ require "montoc/version"
2
+
3
+ module Montoc
4
+ class TextMatrix
5
+ attr_reader :text, :format
6
+
7
+ def initialize text = ""
8
+ @text = text
9
+ @rows = rows
10
+ @columns = columns
11
+ @format = :virgin
12
+ yield self if block_given?
13
+ end
14
+
15
+ def to_s
16
+ return @text
17
+ end
18
+
19
+ def + string
20
+ @text = squeeze_space
21
+ @text << string.to_s
22
+ @format = :left if @format == :virgin
23
+ method(@format.id2name + "!").call
24
+ return self
25
+ end
26
+
27
+ def text= string
28
+ @original = string
29
+ @text = string
30
+ end
31
+
32
+ # Find the longest lines in text and return the first match.
33
+ # to_s is called from the longest_line to avoid chomp being called
34
+ # from nil, in the case of text = ""
35
+ def longest_line remove_new_line_char = true
36
+ longest_line = squeeze_space.lines.max_by(&:length)
37
+ longest_line = longest_line.to_s.chomp if remove_new_line_char
38
+ return longest_line
39
+ end
40
+
41
+ def rows
42
+ return @text.lines.length
43
+ end
44
+
45
+ def row row_no = 1
46
+ raise ArgumentError, "Row number cannot be lower than 1." \
47
+ if row_no < 1
48
+ matricize
49
+ row_text = text.lines[row_no-1]
50
+ return row_text
51
+ end
52
+
53
+ def columns
54
+ return longest_line.length
55
+ end
56
+
57
+ def column col_no = 1
58
+ raise ArgumentError, "Column number cannot be lower than 1." \
59
+ if col_no < 1
60
+ matricize
61
+ if col_no > columns
62
+ return nil
63
+ end
64
+ column_text = ""
65
+ @text.each_line do |line|
66
+ column_text << line.to_s.chomp[col_no-1]
67
+ end
68
+ return column_text
69
+ end
70
+
71
+ def matricize align = :left, columns = 80
72
+ if !matrix?
73
+ reflow! columns
74
+ method(align.id2name + "!").call
75
+ end
76
+ end
77
+
78
+ def matricize! align = :left, columns = 80
79
+ squeeze_space!
80
+ matricize align, columns
81
+ end
82
+
83
+ def matrix?
84
+ @text.each_line do |line|
85
+ return false if line.to_s.chomp.length != columns
86
+ end
87
+ return true
88
+ end
89
+
90
+ def virginize
91
+ @format = :virgin
92
+ @text = @original
93
+ return self
94
+ end
95
+
96
+ def virgin?
97
+ return true if @format == :virgin
98
+ return false
99
+ end
100
+
101
+ def left
102
+ new_text = squeeze_space.split("\n").map do |line|
103
+ line = line.to_s.ljust columns
104
+ end .join "\n"
105
+ return self.class.new(new_text)
106
+ end
107
+
108
+ def left!
109
+ @text = left.text
110
+ @format = :left
111
+ return self
112
+ end
113
+
114
+ def right
115
+ new_text = squeeze_space.split("\n").map do |line|
116
+ line = line.chomp.strip.rjust columns
117
+ end .join "\n"
118
+ return self.class.new(new_text)
119
+ end
120
+
121
+ def right!
122
+ @text = right.text
123
+ @format = :right
124
+ return self
125
+ end
126
+
127
+ def center
128
+ new_text = squeeze_space.split("\n").map do |line|
129
+ line = line.chomp.strip.rjust columns-(columns-line.length)/2
130
+ line = line.ljust columns
131
+ end .join "\n"
132
+ return self.class.new(new_text)
133
+ end
134
+
135
+ def center!
136
+ @text = center.text
137
+ @format = :center
138
+ return self
139
+ end
140
+
141
+ def squeeze_space
142
+ inter_text = @text
143
+ new_text = "".to_s
144
+ # strip extra space between non-space characters
145
+ inter_text.each_line do |line|
146
+ new_text << line.strip.squeeze(" ") + "\n"
147
+ end
148
+
149
+ return new_text
150
+ end
151
+
152
+ def squeeze_space!
153
+ @text = squeeze_space
154
+ end
155
+
156
+ def space_weight
157
+ # Initialize space position at line 0 as 0
158
+ space_weight = {0=>0}
159
+
160
+ i = 0
161
+ squeeze_space.each_line do |line|
162
+ # Initialize weight carried by a space at space position 0 as 0
163
+ weight = {0=>0}
164
+
165
+ # Space position index in each line starting from 0
166
+ j = 0
167
+
168
+ # Capture weight carried by each space in each line
169
+ # Weight means the total number of characters to the left and right
170
+ # of a space.
171
+ line.tr("\n","").split.each_cons(2) do |left_word, right_word|
172
+ weight[j] = left_word.length + right_word.length if left_word
173
+
174
+ # Move index to next space position
175
+ j += 1
176
+ end
177
+
178
+ # Copy space weight per line to overall space weight hash
179
+ space_weight[i] = weight
180
+ i +=1
181
+ end
182
+
183
+ return space_weight
184
+ # Return format:
185
+ # {line number => {space number => weight, next space number => weight, ...},
186
+ # next line number => {space number => weight, ...},
187
+ # ...}
188
+ # Return example:
189
+ # {0=>{0=>6, 1=>3, 2=>8}, 1=>{0=>4, 1=>8}, 2=>{0=>0}, 3=>{0=>8, 1=>8, 2=>9}}
190
+ # Meaning:
191
+ # Line 0 has 3 spaces with the first and the last space has weight of 6 and
192
+ # 8, respectively. Line 2 is an empty line.
193
+ end
194
+
195
+ def justify left_align_EOP = true
196
+ spacing_priority = {}
197
+ space_weight.each do |line, weights|
198
+ spacing_priority[line] = weights.sort_by do |position, weight|
199
+ weight
200
+ end .reverse.to_h.map do |position, weight|
201
+ position
202
+ end
203
+ end
204
+ # Result example:
205
+ # {0=>[2, 0, 1], 1=>[1, 0], 2=>[0], 3=>[2, 1, 0], 4=>[0]}
206
+
207
+ squeezed_text = squeeze_space
208
+ end_of_para = []
209
+ # Get lines that end paragraphs
210
+ squeezed_text.each_line.with_index do |line, line_index|
211
+ if line =~ /^\s*$/ && line_index != 0
212
+ end_of_para.push(line_index - 1)
213
+ end
214
+ end
215
+
216
+ inter_text = ""
217
+ squeezed_text.each_line.with_index do |line, line_index|
218
+ words_arr = line.split
219
+ words_arr_length = words_arr.length < 2 ? 1 : words_arr.length-1
220
+ spaces_arr = (" ,"*words_arr_length).split(",")
221
+ space_needed = columns-line.tr("\n", "").length
222
+ (0...space_needed).each do |i|
223
+ spaces_arr.length == 0 ? index = i : index = i % spaces_arr.length
224
+ spaces_arr[spacing_priority[line_index][index]] += " "
225
+ end
226
+
227
+ (0...words_arr.length).each do |j|
228
+ inter_text << words_arr[j]
229
+ inter_text << spaces_arr[j] unless j == words_arr.length - 1
230
+ end
231
+
232
+ inter_text << "\n"
233
+ end
234
+
235
+ if left_align_EOP == true
236
+ text_arr = inter_text.split("\n")
237
+ inter_text.each_line.with_index do |line, line_index|
238
+ if end_of_para.include?(line_index) || line == inter_text.lines[-1]
239
+ text_arr[line_index] = line.strip.squeeze(" ").ljust(columns)
240
+ end
241
+ end
242
+ inter_text = text_arr.join("\n")
243
+ end
244
+
245
+ new_text = ""
246
+ inter_text.each_line do |line|
247
+ line = line.tr("\n","")
248
+ line = " ".ljust(columns) if line =~ /^\s*$/
249
+ new_text << line + "\n"
250
+ end
251
+
252
+ # In case line contains only one word, this will add trailing spaces
253
+ newer_text = ""
254
+ new_text.each_line do |line|
255
+ newer_text << line.strip.ljust(columns) + "\n"
256
+ end
257
+ newer_text.chomp!
258
+
259
+ # return new object with new text
260
+ return self.class.new(newer_text)
261
+ end
262
+
263
+ def justify! left_align_EOP = true
264
+ @text = justify(left_align_EOP).text
265
+ @format = :justify
266
+ return self
267
+ end
268
+
269
+ def longest_word
270
+ longest_word = squeeze_space.split.max_by(&:length)
271
+ return longest_word
272
+ end
273
+
274
+ def reflow column_width = `echo $COLUMNS`.to_i
275
+ raise ArgumentError, "Columns cannot be shorter than the longest word." \
276
+ if columns < longest_word.length
277
+ new_text = ""
278
+ text_arr = @text.split(/\n\s*\n/)
279
+ new_paragraph = []
280
+ text_arr.each do |paragraph|
281
+ para = []
282
+ para_arr = paragraph.split(" ")
283
+ while para_arr.length > 0
284
+ line_arr = []
285
+ para_arr.take_while do |word|
286
+ line_arr.push(word)
287
+ line_arr.join(" ").length <= column_width
288
+ end
289
+ line_arr.pop if line_arr.join(" ").length > column_width
290
+ len = line_arr.length
291
+ para_arr.shift(len)
292
+ line = line_arr.join(" ")
293
+ para << line + " \n"
294
+ end
295
+ new_paragraph << para.join
296
+ end
297
+ new_text = new_paragraph.join("\n")
298
+
299
+ unless @format == :virgin
300
+ new_text = self.class.new(new_text).method(@format).call.text
301
+ else
302
+ return self.class.new(new_text).left # default alignment
303
+ end
304
+
305
+ return self.class.new(new_text)
306
+ end
307
+
308
+ def reflow! column_width = `echo $COLUMNS`.to_i
309
+ obj = reflow(column_width)
310
+ @text = obj.text
311
+ @format = obj.format
312
+ return self
313
+ end
314
+
315
+ # Define alias methods
316
+ method_aliases = %w{col column line row cols columns unmatricize
317
+ squeeze_space! unmat squeeze_space! restore
318
+ virginize}
319
+ method_aliases.each_slice(2) do |new_method, ori_method|
320
+ alias_method new_method, ori_method
321
+ end
322
+
323
+ end
324
+ end
325
+
326
+ class String
327
+ def +(other)
328
+ if other.kind_of? Montoc::TextMatrix
329
+ new_text = self + other.text
330
+ return new_text
331
+ end
332
+ result = self.dup
333
+ result << other.to_s
334
+ return result
335
+ end
336
+ end
@@ -0,0 +1,3 @@
1
+ module Montoc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'montoc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "montoc"
8
+ spec.version = Montoc::VERSION
9
+ spec.authors = ["Adrian Setyadi"]
10
+ spec.email = ["a.styd@yahoo.com"]
11
+ spec.summary = %q{Monospace Text Document}
12
+ spec.description = %q{Monospace Text Document: convert any plain text to rectangularized text
13
+ (same number of characters per line) or text matrix (two dimensional
14
+ Array of chars of the text) by adding spaces in between the text.
15
+ Set alignment to left, right, center, and justify. You can also reflow
16
+ the text to the specified columns, and many other features.}
17
+ spec.homepage = "https://github.com/styd/montoc/"
18
+ spec.license = "GPLv3"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.6"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: montoc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adrian Setyadi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: "Monospace Text Document: convert any plain text to rectangularized text
42
+ \n(same number of characters per line) or text matrix (two dimensional\nArray of
43
+ chars of the text) by adding spaces in between the text.\nSet alignment to left,
44
+ right, center, and justify. You can also reflow\nthe text to the specified columns,
45
+ and many other features."
46
+ email:
47
+ - a.styd@yahoo.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - ".gitignore"
53
+ - Gemfile
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - lib/montoc.rb
58
+ - lib/montoc/version.rb
59
+ - montoc.gemspec
60
+ homepage: https://github.com/styd/montoc/
61
+ licenses:
62
+ - GPLv3
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.4.1
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Monospace Text Document
84
+ test_files: []