textify 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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Joseph Weissman
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 ADDED
@@ -0,0 +1,33 @@
1
+ = Textify
2
+
3
+ Some basic, non-curses-based functions to aid user
4
+ interaction in text-only ruby scripts. Included are
5
+ functions for
6
+
7
+ * Justifying strings
8
+ * List selection, confirmation, data entry
9
+ * Displaying arrays and hashes as tables
10
+
11
+ == Usage
12
+ require "textify"
13
+ class MyClass
14
+ textify
15
+ def foo
16
+ [[1,2,3],[4,5,6],[7,8,9]].table({:headings => %w[ one two three ]})
17
+ end
18
+ end
19
+
20
+ o = MyClass.new
21
+ o.foo
22
+
23
+
24
+ The snippet above outputs:
25
+
26
+
27
+ ****************************************
28
+ * one * two * three *
29
+ ****************************************
30
+ * 1 * 2 * 3 *
31
+ * 4 * 5 * 6 *
32
+ * 7 * 8 * 9 *
33
+ ****************************************
@@ -0,0 +1,33 @@
1
+ = Textify
2
+
3
+ Some basic, non-curses-based functions to aid user
4
+ interaction in text-only ruby scripts. Included are
5
+ functions for
6
+
7
+ * Justifying strings
8
+ * List selection, confirmation, data entry
9
+ * Displaying arrays and hashes as tables
10
+
11
+ == Usage
12
+ require "textify"
13
+ class MyClass
14
+ textify
15
+ def foo
16
+ [[1,2,3],[4,5,6],[7,8,9]].table({:headings => %w[ one two three ]})
17
+ end
18
+ end
19
+
20
+ o = MyClass.new
21
+ o.foo
22
+
23
+
24
+ The snippet above outputs:
25
+
26
+
27
+ ****************************************
28
+ * one * two * three *
29
+ ****************************************
30
+ * 1 * 2 * 3 *
31
+ * 4 * 5 * 6 *
32
+ * 7 * 8 * 9 *
33
+ ****************************************
@@ -0,0 +1,21 @@
1
+ require "textify"
2
+ class MyClass
3
+ textify
4
+ def foo
5
+ # @val = ask "Enter a value: "
6
+ [[1,2,3],[4,5,6],[7,8,9]].table({:headings => %w[ one two three ]})
7
+ end
8
+ end
9
+
10
+ o = MyClass.new
11
+ o.foo
12
+
13
+ =begin
14
+ ****************************************
15
+ * one * two * three *
16
+ ****************************************
17
+ * 1 * 2 * 3 *
18
+ * 4 * 5 * 6 *
19
+ * 7 * 8 * 9 *
20
+ ****************************************
21
+ =end
@@ -0,0 +1,348 @@
1
+ module Textify
2
+ =begin
3
+
4
+ = Textify
5
+
6
+ Some basic, non-curses-based functions to aid user
7
+ interaction in text-only ruby scripts. Included are
8
+ functions for
9
+
10
+ * Justifying strings
11
+ * List selection, confirmation, data entry
12
+ * Displaying arrays and hashes as tables
13
+
14
+ == Usage
15
+ require "textify"
16
+ class MyClass
17
+ textify
18
+ def foo
19
+ [[1,2,3],[4,5,6],[7,8,9]].table({:headings => %w[ one two three ]})
20
+ end
21
+ end
22
+
23
+ o = MyClass.new
24
+ o.foo
25
+
26
+
27
+ The snippet above outputs:
28
+
29
+
30
+ ****************************************
31
+ * one * two * three *
32
+ ****************************************
33
+ * 1 * 2 * 3 *
34
+ * 4 * 5 * 6 *
35
+ * 7 * 8 * 9 *
36
+ ****************************************
37
+
38
+ =end
39
+
40
+ DefaultScreenWidth = 40
41
+
42
+ # minor utility fns
43
+ def br n=1; puts until (n-=1)<0; end
44
+ def cls; br 50; end
45
+
46
+
47
+ =begin
48
+
49
+ Textual.justify (direction, text, options={})
50
+
51
+ Justifies text within the default screen width. Accepts in the options hash:
52
+
53
+ :width set a new default width for this justification
54
+ :character fill with another characer (default is ' ')
55
+
56
+ =end
57
+
58
+ def justify(direction, text, options={})
59
+ # puts "Entering justify..."
60
+ width = options[:width] || DefaultScreenWidth
61
+ if text.length >= width
62
+ # puts "Returning, text '#{text}' (#{text.size}) too big for width #{width}."
63
+ return text
64
+ end
65
+
66
+ orig_text = text
67
+ char = options[:character] || ' '
68
+
69
+ usable_space = width-text.length
70
+ offset = char*usable_space
71
+ left_offset = char * (usable_space.to_f/2).ceil
72
+ right_offset = char * (usable_space - left_offset.size)
73
+
74
+ #half_offset = offset.slice(0..(offset.size/2).floor)
75
+ # puts "Usable space: #{usable_space}. Left: #{left_offset.size}. Right: #{right_offset.size}."
76
+
77
+ text = case direction #.downcase.to_sym
78
+ when :left then "#{text}#{offset}"
79
+ when :right then "#{offset}#{text}"
80
+ when :center then "#{left_offset}#{text}#{right_offset}"
81
+ else text
82
+ end
83
+
84
+ # puts "- Justifying (#{direction.to_s}) to width (#{width}): '#{orig_text}' => \t'#{text}'"
85
+
86
+ text
87
+ end
88
+
89
+
90
+ def test_justify
91
+ title " Testing justify command "
92
+ text = justify :left, "Left Justifed"
93
+ puts text
94
+ puts justify(:right, "Right Justifed")
95
+ puts justify(:center, "Center Justifed")
96
+ puts "Unjustified"
97
+ true
98
+ end
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+ def title name, options={}
107
+ br options[:offset] || 2
108
+ print "#{justify :center, name, {:character => options[:character] || '='}}"
109
+ br options[:offset] || 2
110
+ end
111
+
112
+ def test_title
113
+ title " Sample Title 1 "
114
+ title " Sample Title 2 ", {:character => '@', :offset => 3 }
115
+ title " Sample Title 3 ", {:character => "&", :offset => 2 }
116
+ true
117
+ end
118
+
119
+
120
+
121
+ def display_selection items, prompt
122
+ title prompt # print "\n"*3
123
+ items.each_with_index { |item, n| puts " [#{n+1}] #{item.gsub('_',' ').capitalize} \n" }
124
+ print "\n > "
125
+ @input = gets.to_i;
126
+ end
127
+
128
+ def select(items, prompt=" Please select one of the following options: ", options={})
129
+ #title prompt # print "\n"*3
130
+ #items.each_with_index { |item, n| puts " [#{n+1}] #{item.gsub('_',' ').capitalize} \n" }
131
+ #print "\n > "
132
+ #input = gets.to_i;
133
+ # display_selection;
134
+ @input=0; display_selection(items, prompt) until (@input >= 1 and @input <= items.size)
135
+ #title prompt # print "\n"*3
136
+ #items.each_with_index { |item, n| puts " [#{n+1}] #{item.gsub('_',' ').capitalize} \n" }
137
+ #print "\n > "
138
+ #input = gets.to_i
139
+ #end
140
+
141
+ puts "Selected #{@input} (#{items[@input-1]}).. " #{ }"#{options[input-1]}."
142
+ return items[@input-1]
143
+ end
144
+
145
+ def test_select
146
+ title " Selection Test "
147
+ choices = %w[ apples strawberries bananas mandarin_oranges tangerines oranges cherries watermelons raspberries ]
148
+ option = select choices
149
+ title "Thanks for choosing #{option}!"
150
+ true
151
+ end
152
+
153
+
154
+
155
+
156
+ def confirm(prompt = "Please confirm. ", options = {})
157
+ choices = options[:choices] || %w[ Yes No]
158
+ input = select choices, prompt
159
+ return true if input == choices[0]
160
+ return false
161
+ end
162
+
163
+ def test_confirm
164
+ puts "Must be nice..." if confirm "Are you human?"
165
+ true
166
+ end
167
+
168
+
169
+
170
+ def ask(prompt="\n >",options={})
171
+ prompt = prompt.to_s + "? " if prompt.class == Symbol
172
+ print prompt.capitalize
173
+
174
+ if options[:validate]
175
+ input = gets.chomp
176
+ if options[:validate].downcase == 'numeric'
177
+ end
178
+ else
179
+ return gets.chomp
180
+ end
181
+ end
182
+
183
+ def test_ask
184
+ title " Test Input Gathering "
185
+ name = ask "What's your name? "
186
+ puts "Thanks for answering, #{name}!"
187
+ age = ask "How old are you? "
188
+ puts "Great! It must be nice to be #{age} years old."
189
+ true
190
+ end
191
+
192
+
193
+
194
+
195
+
196
+
197
+ def tabulate(data, options={}); data.table options if %w[ Hash Array ].include? data.class.name; end
198
+
199
+ def test_table
200
+ title " Testing tables "
201
+
202
+ tabulate({:one => "1", :two => "2", :three => "3", :four => "4", :five => "512351234123"}); br 2
203
+ tabulate([[1,2,3,4],[4,5,6,7],[7,8,9,0]], {:headings => %w[ alpha beta gamma delta ], :width => 100} ); br 3
204
+ tabulate([[1,2,3,4],[4,5,6,7],[7,8,9,0]], {:headings => %w[ alpha beta gamma delta ], :width => 50} ); br 3
205
+
206
+ true
207
+ end
208
+
209
+
210
+
211
+
212
+ def unit_test
213
+
214
+ title " Textual Unit Test "
215
+
216
+ results = {}
217
+
218
+ %w[ title ask select confirm justify table ].each {
219
+ |operation| results[operation.to_sym] = send("test_"+operation)
220
+ }
221
+ =begin
222
+ results << {:title, test_title}
223
+ results << {:ask, test_ask}
224
+ results << {:select, test_select}
225
+ results << {:confirm, test_confirm}
226
+ results << {:justify, test_justify}
227
+ results << {:table, test_table}
228
+ =end
229
+ title " Internal Unit Test Results "
230
+ results.each_pair {|k,v| puts " #{k} => #{v==true ? 'pass' : 'fail'}" }
231
+
232
+ assertions = results.size
233
+ passed = results.select { |k,v| v=true }.size
234
+ failed = results.select { |k,v| v=false }.size
235
+
236
+ title " #{assertions} assertions, #{failed} failed, #{passed} passed "
237
+
238
+ return false if failed > 0
239
+ true
240
+ end
241
+ end
242
+
243
+ def textify; include Textify; end
244
+
245
+
246
+ #################################
247
+ # Extensions to Hash
248
+ ########
249
+
250
+ class Hash
251
+ textify
252
+ # include Textual
253
+ def self_analyze
254
+ @minimal_element, @maximal_element = nil,nil
255
+ @min_elem_sz, @max_elem_sz = 0, 0
256
+ each_pair do |k,v|
257
+ [k,v].each do |element|
258
+ if element.to_s.size > @max_elem_sz
259
+ @maximal_element = element; @max_elem_sz = element.to_s.size
260
+ elsif element.to_s.size < @min_elem_sz
261
+ @minimal_element = element; @min_elem_sz = element.to_s.size
262
+ end
263
+ end
264
+ end
265
+ # puts "[Hash.self_analyze] Maximal element => '#{@maximal_element}' (#{@max_elem_sz}), minimal element => '#{@minimal_element}'"
266
+ end
267
+
268
+ def table options={}
269
+ self_analyze
270
+ width = options[:width] || DefaultScreenWidth
271
+ min_column_width = @maximal_element.to_s.size + 2
272
+ column_width = [min_column_width, (width-3).to_f/2].max.to_i
273
+ width = column_width*2 + 3
274
+ hb = "*"*width+"\n"
275
+ result = hb
276
+ each_pair{|k,v| result += "*#{justify :center, k.to_s, :width => (column_width)}*#{justify :center, v, :width=>(column_width)}*\n"}
277
+ result += hb
278
+ puts result
279
+ end
280
+ end
281
+
282
+
283
+ ####################
284
+ # Extensions to Array
285
+ #####
286
+
287
+ class Array
288
+ # include Textual
289
+ textify
290
+
291
+ def self_analyze
292
+ @minimal_element, @maximal_element = nil,nil
293
+ @min_elem_sz, @max_elem_sz = 0, 0
294
+ each do |row|
295
+ if row.is_a? Array
296
+ row.each do |element|
297
+ if element.to_s.size > @max_elem_sz
298
+ @maximal_element = element; @max_elem_sz = element.to_s.size
299
+ elsif element.to_s.size < @min_elem_sz
300
+ @minimal_element = element; @min_elem_sz = element.to_s.size
301
+ end
302
+ end
303
+ end
304
+ end
305
+ # puts "[Array.self_analyze] Maximal element => '#{@maximal_element}' (#{@max_elem_sz}), minimal element => '#{@minimal_element}'"
306
+ end
307
+
308
+ def table options = {}
309
+ width = options[:width] || DefaultScreenWidth
310
+ self_analyze
311
+
312
+ columns = self[0].size
313
+
314
+ min_column_width = @maximal_element.to_s.size + 2
315
+ column_width = [min_column_width, ((width.to_i-columns).to_f/columns)].max.to_i
316
+ width = (column_width*columns) + columns + 1
317
+
318
+ hb = ("*"*(width))+"\n"
319
+ result = hb
320
+
321
+ # puts "[Array.table] Columns = #{columns}. Total width = #{width}. Column width = #{column_width}."
322
+
323
+ if options[:headings] then
324
+ options[:headings].each{ |th| result += "*#{justify :center, th.to_s, :width => column_width}"}
325
+ result += "*\n"
326
+ result += hb
327
+ end
328
+ each do |row|
329
+ row.each do |item|
330
+ result += "*#{justify :center, item.to_s, :width => column_width}"
331
+ end
332
+ result += "*\n"
333
+ end
334
+ result += hb
335
+
336
+ puts result
337
+ end
338
+ end
339
+
340
+
341
+ #### sample interface unit test ##############
342
+
343
+
344
+ if __FILE__ == $0
345
+ class SampleUI; textify; def test_textify; unit_test; end; end
346
+ sample_user_interface = SampleUI.new
347
+ sample_user_interface.test_textify
348
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'textify'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+ require 'textify'
3
+
4
+ class TestTextify < Test::Unit::TestCase
5
+ should "pass internal unit test" do
6
+ class SampleUI; textify; def test_textify; unit_test; end; end
7
+ sample_user_interface = SampleUI.new
8
+ passed_unit_test = sample_user_interface.test_textify
9
+
10
+ assert passed_unit_test
11
+ flunk "failed internal unit test!" if not passed_unit_test
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: textify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joseph Weissman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-08 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A collection of simple, non-curses-based functions to assist building user interaction into text-only ruby scripts
17
+ email: jweissman1986@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README
25
+ - README.rdoc
26
+ files:
27
+ - lib/sample.rb
28
+ - lib/textify.rb
29
+ - LICENSE
30
+ - README
31
+ - README.rdoc
32
+ has_rdoc: true
33
+ homepage: http://github.com/jweissman1986/Textify
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.3.5
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: non-curses text-based library to aid user interaction
60
+ test_files:
61
+ - test/helper.rb
62
+ - test/test_textify.rb