canis 0.0.4

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.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +45 -0
  3. data/CHANGES +52 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +24 -0
  7. data/Rakefile +2 -0
  8. data/canis.gemspec +25 -0
  9. data/examples/alpmenu.rb +46 -0
  10. data/examples/app.sample +19 -0
  11. data/examples/appemail.rb +191 -0
  12. data/examples/atree.rb +105 -0
  13. data/examples/bline.rb +181 -0
  14. data/examples/common/devel.rb +319 -0
  15. data/examples/common/file.rb +93 -0
  16. data/examples/data/README.markdown +9 -0
  17. data/examples/data/brew.txt +38 -0
  18. data/examples/data/color.2 +37 -0
  19. data/examples/data/gemlist.txt +59 -0
  20. data/examples/data/lotr.txt +12 -0
  21. data/examples/data/ports.txt +136 -0
  22. data/examples/data/table.txt +37 -0
  23. data/examples/data/tasks.csv +88 -0
  24. data/examples/data/tasks.txt +27 -0
  25. data/examples/data/todo.txt +16 -0
  26. data/examples/data/todocsv.csv +28 -0
  27. data/examples/data/unix1.txt +21 -0
  28. data/examples/data/unix2.txt +11 -0
  29. data/examples/dbdemo.rb +506 -0
  30. data/examples/dirtree.rb +177 -0
  31. data/examples/newtabbedwindow.rb +100 -0
  32. data/examples/newtesttabp.rb +92 -0
  33. data/examples/tabular.rb +212 -0
  34. data/examples/tasks.rb +179 -0
  35. data/examples/term2.rb +88 -0
  36. data/examples/testbuttons.rb +307 -0
  37. data/examples/testcombo.rb +102 -0
  38. data/examples/testdb.rb +182 -0
  39. data/examples/testfields.rb +208 -0
  40. data/examples/testflowlayout.rb +43 -0
  41. data/examples/testkeypress.rb +98 -0
  42. data/examples/testlistbox.rb +187 -0
  43. data/examples/testlistbox1.rb +199 -0
  44. data/examples/testmessagebox.rb +144 -0
  45. data/examples/testprogress.rb +116 -0
  46. data/examples/testree.rb +107 -0
  47. data/examples/testsplitlayout.rb +53 -0
  48. data/examples/testsplitlayout1.rb +49 -0
  49. data/examples/teststacklayout.rb +48 -0
  50. data/examples/testwsshortcuts.rb +68 -0
  51. data/examples/testwsshortcuts2.rb +129 -0
  52. data/lib/canis.rb +16 -0
  53. data/lib/canis/core/docs/index.txt +104 -0
  54. data/lib/canis/core/docs/list.txt +16 -0
  55. data/lib/canis/core/docs/style_help.yml +34 -0
  56. data/lib/canis/core/docs/tabbedpane.txt +15 -0
  57. data/lib/canis/core/docs/table.txt +31 -0
  58. data/lib/canis/core/docs/textpad.txt +48 -0
  59. data/lib/canis/core/docs/tree.txt +23 -0
  60. data/lib/canis/core/include/.DS_Store +0 -0
  61. data/lib/canis/core/include/action.rb +83 -0
  62. data/lib/canis/core/include/actionmanager.rb +49 -0
  63. data/lib/canis/core/include/appmethods.rb +179 -0
  64. data/lib/canis/core/include/bordertitle.rb +49 -0
  65. data/lib/canis/core/include/canisparser.rb +100 -0
  66. data/lib/canis/core/include/colorparser.rb +437 -0
  67. data/lib/canis/core/include/defaultfilerenderer.rb +64 -0
  68. data/lib/canis/core/include/io.rb +320 -0
  69. data/lib/canis/core/include/layouts/SplitLayout.rb +161 -0
  70. data/lib/canis/core/include/layouts/abstractlayout.rb +213 -0
  71. data/lib/canis/core/include/layouts/flowlayout.rb +104 -0
  72. data/lib/canis/core/include/layouts/stacklayout.rb +109 -0
  73. data/lib/canis/core/include/listbindings.rb +89 -0
  74. data/lib/canis/core/include/listeditable.rb +319 -0
  75. data/lib/canis/core/include/listoperations.rb +61 -0
  76. data/lib/canis/core/include/listselectionmodel.rb +388 -0
  77. data/lib/canis/core/include/multibuffer.rb +173 -0
  78. data/lib/canis/core/include/ractionevent.rb +73 -0
  79. data/lib/canis/core/include/rchangeevent.rb +27 -0
  80. data/lib/canis/core/include/rhistory.rb +95 -0
  81. data/lib/canis/core/include/rinputdataevent.rb +47 -0
  82. data/lib/canis/core/include/textdocument.rb +111 -0
  83. data/lib/canis/core/include/vieditable.rb +175 -0
  84. data/lib/canis/core/include/widgetmenu.rb +66 -0
  85. data/lib/canis/core/system/colormap.rb +165 -0
  86. data/lib/canis/core/system/keydefs.rb +32 -0
  87. data/lib/canis/core/system/ncurses.rb +237 -0
  88. data/lib/canis/core/system/panel.rb +129 -0
  89. data/lib/canis/core/system/window.rb +1081 -0
  90. data/lib/canis/core/util/ansiparser.rb +119 -0
  91. data/lib/canis/core/util/app.rb +696 -0
  92. data/lib/canis/core/util/basestack.rb +412 -0
  93. data/lib/canis/core/util/defaultcolorparser.rb +84 -0
  94. data/lib/canis/core/util/extras/README +5 -0
  95. data/lib/canis/core/util/extras/bottomline.rb +1815 -0
  96. data/lib/canis/core/util/extras/padreader.rb +192 -0
  97. data/lib/canis/core/util/focusmanager.rb +31 -0
  98. data/lib/canis/core/util/helpmanager.rb +160 -0
  99. data/lib/canis/core/util/oldwidgetshortcuts.rb +304 -0
  100. data/lib/canis/core/util/promptmenu.rb +235 -0
  101. data/lib/canis/core/util/rcommandwindow.rb +933 -0
  102. data/lib/canis/core/util/rdialogs.rb +520 -0
  103. data/lib/canis/core/util/textutils.rb +74 -0
  104. data/lib/canis/core/util/viewer.rb +238 -0
  105. data/lib/canis/core/util/widgetshortcuts.rb +508 -0
  106. data/lib/canis/core/widgets/applicationheader.rb +103 -0
  107. data/lib/canis/core/widgets/box.rb +58 -0
  108. data/lib/canis/core/widgets/divider.rb +310 -0
  109. data/lib/canis/core/widgets/extras/README.md +12 -0
  110. data/lib/canis/core/widgets/extras/rtextarea.rb +960 -0
  111. data/lib/canis/core/widgets/extras/stackflow.rb +474 -0
  112. data/lib/canis/core/widgets/keylabelprinter.rb +194 -0
  113. data/lib/canis/core/widgets/listbox.rb +326 -0
  114. data/lib/canis/core/widgets/listfooter.rb +86 -0
  115. data/lib/canis/core/widgets/rcombo.rb +210 -0
  116. data/lib/canis/core/widgets/rcontainer.rb +415 -0
  117. data/lib/canis/core/widgets/rlink.rb +30 -0
  118. data/lib/canis/core/widgets/rmenu.rb +970 -0
  119. data/lib/canis/core/widgets/rmenulink.rb +30 -0
  120. data/lib/canis/core/widgets/rmessagebox.rb +400 -0
  121. data/lib/canis/core/widgets/rprogress.rb +118 -0
  122. data/lib/canis/core/widgets/rtabbedpane.rb +631 -0
  123. data/lib/canis/core/widgets/rtabbedwindow.rb +70 -0
  124. data/lib/canis/core/widgets/rwidget.rb +3634 -0
  125. data/lib/canis/core/widgets/scrollbar.rb +147 -0
  126. data/lib/canis/core/widgets/statusline.rb +113 -0
  127. data/lib/canis/core/widgets/table.rb +1072 -0
  128. data/lib/canis/core/widgets/tabular.rb +264 -0
  129. data/lib/canis/core/widgets/textpad.rb +1674 -0
  130. data/lib/canis/core/widgets/tree.rb +690 -0
  131. data/lib/canis/core/widgets/tree/treecellrenderer.rb +150 -0
  132. data/lib/canis/core/widgets/tree/treemodel.rb +432 -0
  133. data/lib/canis/version.rb +3 -0
  134. metadata +229 -0
@@ -0,0 +1,412 @@
1
+ # Common stack flow functionality
2
+ # * Name: basestack.rb
3
+ # * Description: Classes that allow user to stack and flow components
4
+ # This is currently used only by experimental. +core+ does not use this
5
+ # for stack and flow. it uses wsshortcuts which does not maintain objects.
6
+ # This maintains objects.
7
+ #
8
+ # * Date: 30.10.11 - 12:57
9
+ # * Last update: 2014-05-02 20:15
10
+ #
11
+ module RubyCurses
12
+ module ModStack
13
+ #
14
+ # Base class for stacks and flows.
15
+ # Will manage determining row col and width height of objects
16
+ # Stacks place objects one below another. Flows place objects to the
17
+ # right of the previous. Orientation can be reversed.
18
+ #
19
+ class BaseStack
20
+ attr_accessor :components
21
+ attr_reader :config
22
+ attr_accessor :form
23
+ def initialize config={}, components=[]
24
+ @config = config
25
+ config.each do |k, v|
26
+ instance_variable_set "@#{k}", v
27
+ end
28
+ @components = components
29
+ @calc_needed = true
30
+ end
31
+ # XXX if user sets later, we won't be checking the config
32
+ # We check the actual variables which config sets in init
33
+ %w[ parent_component width height weight row col orientation margin_top margin_bottom margin_left margin_right].each { |e|
34
+ eval(
35
+ "def #{e}
36
+ @config[:#{e}]
37
+ end
38
+ def #{e}=(val)
39
+ @config[:#{e}]=val
40
+ instance_variable_set \"@#{e}\", val
41
+ @calc_needed = true
42
+ end"
43
+ )
44
+ }
45
+ alias :parent :parent_component
46
+ #alias :parent= :parent_component
47
+ def repaint # stack
48
+ $log.debug "XXX: stack repaint recalc #{@calc_needed} "
49
+ @components.each { |e| e.form = @form unless e.form } #unless @calc_needed
50
+ recalc if @calc_needed
51
+ @components.each { |e| e.repaint }
52
+ end
53
+ def repaint_all x
54
+ @calc_needed = true
55
+ end
56
+ def override_graphic gr
57
+ @graphic = gr
58
+ end
59
+ def focusable; false; end
60
+ # Calculates row col and width height
61
+ # for each subc-omponent based on coords of Container
62
+ # This is to be called only when the container has got its coordinates (i.e
63
+ # Containers repaint). This should be in this objects repaint.
64
+ def recalc
65
+ @calc_needed = false
66
+ comp = self
67
+ if comp.is_a? BaseStack
68
+ check_coords comp
69
+ @margin_left ||= 0
70
+ @margin_right ||= 0
71
+ @margin_top ||= 0
72
+ @margin_bottom ||= 0
73
+ if comp.is_a? Stack
74
+ r = row + @margin_top
75
+ rem = 0
76
+ ht = height - (@margin_top + @margin_bottom)
77
+ if @orientation == :bottom
78
+ mult = -1
79
+ comps = @components.reverse
80
+ r = row + height - @margin_bottom
81
+
82
+ else
83
+ mult = 1
84
+ comps = @components
85
+
86
+ end
87
+ comps.each { |e|
88
+ # should only happen if expandable FIXME
89
+ e.margin_top ||= 0
90
+ e.margin_bottom ||= 0
91
+ e.height = 0.01 * e.weight * (ht - (e.margin_top + e.margin_bottom))
92
+ hround = e.height.floor
93
+ rem += e.height - hround
94
+ e.height = hround #- (@margin_top + @margin_bottom)
95
+ # rounding creates a problem, since 0.5 gets rounded up and we can exceed bound
96
+ # So i floor, and maintain the lost space, and add it back when it exceeds 1
97
+ # This way the last components gets stretched to meet the end, which is required
98
+ # when the height of the stack is odd and there's a left-over row
99
+ if rem >= 1
100
+ e.height += 1
101
+ rem = 0
102
+ end
103
+ # Item level margins have not been accounted for when calculating weightages, and
104
+ # should not be used on the weightage axis
105
+ r += e.margin_top
106
+ if @orientation == :bottom
107
+ r += e.height * mult
108
+ e.row = r
109
+ else
110
+ e.row = r
111
+ r += e.height + 0
112
+ end
113
+ e.margin_left ||= 0
114
+ e.margin_right ||= 0
115
+ e.width = width - (@margin_left + @margin_right + e.margin_left + e.margin_right)
116
+ e.col = col + @margin_left + e.margin_left # ??? XXX
117
+ #$log.debug "XXX: recalc stack #{e.widget.class} r:#{e.row} c:#{e.col} h:#{e.height} = we:#{e.weight} * h:#{height} "
118
+ #e.col_offset = col_offset # ??? XXX
119
+ check_coords e
120
+ e.repaint_all(true)
121
+ e.recalc if e.is_a? BaseStack
122
+ }
123
+ elsif comp.is_a? Flow
124
+ c = col + @margin_left #+ col_offset
125
+ rem = 0
126
+ wd = width - (@margin_left + @margin_right)
127
+ # right_to_left orientation
128
+ if @orientation == :right
129
+ mult = -1
130
+ comps = @components.reverse
131
+ c = col + width - @margin_right
132
+ $log.debug "XXX: ORIENT1f recalc #{@orientation} "
133
+ else
134
+ mult = 1
135
+ comps = @components
136
+ $log.debug "XXX: ORIENT2f recalc #{@orientation} "
137
+ end
138
+ comps.each { |e|
139
+ e.width = e.weight * wd * 0.01
140
+ wround = e.width.floor
141
+ rem += e.width - wround
142
+ e.width = wround
143
+ # see comment in prev block regarding remaininder
144
+ if rem >= 1
145
+ e.width += 1
146
+ rem = 0
147
+ end
148
+ e.height = height - (@margin_top + @margin_bottom) #* weight * 0.01
149
+ #e.height = e.height.round
150
+ if @orientation == :right
151
+ c += e.width * mult # mult 1 or -1
152
+ e.col = c
153
+ else
154
+ e.col = c
155
+ c += e.width * mult # mult 1 or -1
156
+ end
157
+ e.row = row + @margin_top
158
+ check_coords e
159
+ $log.debug "XXX: recalc flow #{e.widget.class} r:#{e.row} c:#{e.col} h:#{e.height} = we:#{e.weight} * w:#{width} "
160
+ e.repaint_all(true) # why not happening when we change row, hieght etc
161
+ e.recalc if e.is_a? BaseStack
162
+ }
163
+ end
164
+ else
165
+ alert "in else recalc DOES NOT COME HERE "
166
+ comp.col = comp.parent.col
167
+ comp.row = comp.parent.row
168
+ comp.height = comp.parent.height
169
+ comp.width = comp.parent.width
170
+ $log.debug "XXX: recalc else #{comp.class} r #{comp.row} c #{comp.col} . h #{comp} height w #{comp.width} "
171
+ end
172
+ end
173
+ # Traverses the comopnent tree and calculates weightages for all components
174
+ # based on what has been specified by user
175
+ def check_coords e # stack
176
+ r = e.row
177
+ c = e.col
178
+ if r >= row + height
179
+ $log.warn "XXX: WARN e.class is out of bounds row #{r} "
180
+ e.visible = false
181
+ end
182
+ if c >= col + width
183
+ $log.warn "XXX: WARN e.class is out of bounds col #{c} "
184
+ e.visible = false
185
+ end
186
+ end
187
+ def increase c=@current_component
188
+ p = self #c.parent_component
189
+ ci = p.components.index(c)
190
+ ni = ci + 1
191
+ if p.components[ni].nil?
192
+ ni = nil
193
+ end
194
+ case p
195
+ when Flow
196
+ # increase width of current and reduce from neighbor
197
+ if ni
198
+ n = p.components[ni]
199
+ $log.debug "XXX: INC fl current #{ci}, total#{p.components.count}, next #{n} "
200
+
201
+ c.width += 1
202
+ n.width -= 1
203
+ n.col += 1
204
+ end
205
+
206
+ when Stack
207
+ if ni
208
+ n = p.components[ni]
209
+ $log.debug "XXX: INC fl current #{ci}, total#{p.components.count}, next #{n} "
210
+
211
+ c.height += 1
212
+ n.height -= 1
213
+ n.row += 1
214
+ end
215
+ $log.debug "XXX: INC st current #{ci}, total#{p.components.count} "
216
+ end
217
+
218
+ end
219
+ def decrease c=@current_component
220
+ p = self #c.parent_component
221
+ ci = p.components.index(c)
222
+ ni = ci + 1
223
+ if p.components[ni].nil?
224
+ ni = nil
225
+ end
226
+ case p
227
+ when Flow
228
+ # increase width of current and reduce from neighbor
229
+ if ni
230
+ n = p.components[ni]
231
+ $log.debug "XXX: INC fl current #{ci}, total#{p.components.count}, next #{n} "
232
+
233
+ c.width -= 1
234
+ n.width += 1
235
+ n.col -= 1
236
+ end
237
+
238
+ when Stack
239
+ if ni
240
+ n = p.components[ni]
241
+ $log.debug "XXX: INC fl current #{ci}, total#{p.components.count}, next #{n} "
242
+
243
+ c.height -= 1
244
+ n.height += 1
245
+ n.row -= 1
246
+ end
247
+ $log.debug "XXX: INC st current #{ci}, total#{p.components.count} "
248
+ end
249
+
250
+ end
251
+ def to_s
252
+ @components
253
+ end
254
+ end # class Base
255
+ # A stack positions objects one below the other
256
+ class Stack < BaseStack; end
257
+ # A flow positions objects in a left to right
258
+ class Flow < BaseStack; end
259
+ #
260
+ # A wrapper over widget mostly because it adds weight and margins
261
+ #
262
+ class Item
263
+ attr_reader :config, :widget
264
+ attr_reader :margin_top, :margin_left, :margin_bottom, :margin_right
265
+ def initialize config={}, widget
266
+ @config = config
267
+ config.each do |k, v|
268
+ instance_variable_set "@#{k}", v
269
+ end
270
+ @margin_left ||= 0
271
+ @margin_right ||= 0
272
+ @margin_top ||= 0
273
+ @margin_bottom ||= 0
274
+ @widget = widget
275
+ end
276
+ def weight; @config[:weight]||100; end
277
+ def weight=(val); @config[:weight]=val; end
278
+ def repaint; @widget.repaint; end
279
+ %w[ form parent parent_component width height row col row_offset col_offset focusable].each { |e|
280
+ eval(
281
+ "def #{e}
282
+ @widget.#{e}
283
+ end
284
+ def #{e}=(val)
285
+ @widget.#{e}=val
286
+ end"
287
+ )
288
+ }
289
+ def method_missing(sym, *args, &block)
290
+ @widget.send sym, *args, &block
291
+ end
292
+ end # class Item
293
+
294
+ # --------------------- module level ------------------------------#
295
+ # General routin to traverse components and their components
296
+ def traverse c, &block
297
+ if c.is_a? BaseStack
298
+ yield c
299
+ c.components.each { |e|
300
+ yield e
301
+ }
302
+ c.components.each { |e| traverse(e, &block) }
303
+ @ctr -= 1
304
+ else
305
+ end
306
+ end
307
+
308
+ # traverse the components and their children
309
+ #
310
+ def each &block
311
+ @components.each { |e| traverse e, &block }
312
+ end
313
+ # module level
314
+ private
315
+ def _stack type, config={}, &block
316
+ case type
317
+ when :stack
318
+ s = Stack.new(config)
319
+ when :flow
320
+ s = Flow.new(config)
321
+ end
322
+ _add s
323
+ @active << s
324
+ yield_or_eval &block if block_given?
325
+ @active.pop
326
+ # if active is empty then this is where we could calculate
327
+ # percentatges and do recalc, thus making it independent
328
+ end
329
+ # module level
330
+ private
331
+ def _add s
332
+ if @active.empty?
333
+ $log.debug "XXX: ADDING TO components #{s} "
334
+ unless s.is_a? BaseStack
335
+ raise "No stack or flow to add to. Results may not be what you want"
336
+ end
337
+ @components << s
338
+ else
339
+ @active.last.components << s
340
+ end
341
+ __add s
342
+ end
343
+
344
+ # module level
345
+ public
346
+ def stack config={}, &block
347
+ _stack :stack, config, &block
348
+ end
349
+ def flow config={}, &block
350
+ _stack :flow, config, &block
351
+ end
352
+ # module level
353
+ private
354
+ def add w, config={}
355
+ i = Item.new config, w
356
+ _add i
357
+ end
358
+ alias :add_widget :add
359
+ # module level
360
+ private
361
+ def calc_weightages2 components, parent
362
+ #puts " #{@ctr} --> #{c.type}, wt: #{c.config[:weight]} "
363
+ @ctr += 1
364
+ wt = 0
365
+ cnt = 0
366
+ sz = components.count
367
+ $log.debug "XXX: calc COMP COUNT #{sz} "
368
+ # calculate how much weightage has been given by user
369
+ # so we can allocate average to other components
370
+ components.each { |e|
371
+ if e.config[:weight]
372
+ wt += e.config[:weight]
373
+ cnt += 1
374
+ end
375
+ $log.debug "XXX: INC setting parent #{parent} to #{e} "
376
+ e.config[:parent] = parent
377
+ e.config[:level] = @ctr
378
+ }
379
+ used = sz - cnt
380
+ $log.debug "XXX: ADDING calc COMP COUNT #{sz} - #{cnt} "
381
+ if used > 0
382
+ avg = (100-wt)/used
383
+ # Allocate average to other components
384
+ components.each { |e| e.config[:weight] = avg unless e.config[:weight] }
385
+ end
386
+ components.each { |e| calc_weightages2(e.components, e) if e.respond_to? :components }
387
+ @ctr -= 1
388
+ end
389
+ # module level
390
+ #private
391
+ public
392
+ # given an widget, return the item, so we can change weight or some other config
393
+ def item_for widget
394
+ each do |e|
395
+ if e.is_a? Item
396
+ if e.widget == widget
397
+ return e
398
+ end
399
+ end
400
+ end
401
+ return nil
402
+ end
403
+ # module level
404
+ # returns the parent (flow or stack) for a given widget
405
+ # allowing user to change configuration such as weight
406
+ def parent_of widget
407
+ f = item_for widget
408
+ return f.config[:parent] if f
409
+ return nil
410
+ end
411
+ end # mod modstack
412
+ end # mod
@@ -0,0 +1,84 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: colorparser.rb
3
+ # Description: Default parse for our tmux format
4
+ # The aim is to be able to specify parsers so different kinds
5
+ # of formatting or documents can be used, such as ANSI formatted
6
+ # manpages.
7
+ # Author: jkepler http://github.com/mare-imbrium/canis/
8
+ # Date: 07.11.11 - 13:17
9
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
10
+ # Last update: 2014-05-19 12:56
11
+ # ----------------------------------------------------------------------------- #
12
+ # == TODO
13
+ # - perhaps we can compile the regexp once and reuse
14
+ # == CHANGES
15
+ # - adding style 2014-05-19 - 12:52
16
+ #
17
+
18
+ module Canis
19
+ class DefaultColorParser
20
+
21
+ # NOTE: Experimental and minimal
22
+ # parses the formatted string and yields either an array of color, bgcolor and attrib
23
+ # or the text. This will be called by convert_to_chunk.
24
+ #
25
+ # Currently, assumes colors and attributes are correct. No error checking or fancy stuff.
26
+ # s="#[fg=green]hello there#[fg=yellow, bg=black, dim]"
27
+ # @since 1.4.1 2011-11-3 experimental, can change
28
+ # @return [nil] knows nothign about output format.
29
+
30
+ # 187compat 2013-03-20 - 19:33 not working in 187 so added ,1 in some cases for string
31
+ def parse_format s # yields attribs or text
32
+ ## set default colors
33
+ color = :white
34
+ bgcolor = :black
35
+ attrib = FFI::NCurses::A_NORMAL
36
+ text = ""
37
+
38
+ ## split #[...]
39
+ a = s.split /(#\[[^\]]*\])/
40
+ a.each { |e|
41
+ ## process color or attrib portion
42
+ if e[0,2] == "#[" && e[-1,1] == "]"
43
+ # now resetting 1:20 PM November 3, 2011 , earlier we were carrying over
44
+ color, bgcolor, attrib = nil, nil, nil
45
+ style = nil
46
+ catch(:done) do
47
+ e = e[2..-2]
48
+ # TODO we could atthis point check against a hash to see if this string exists, and take
49
+ # the array from there and pass back so we don't keep splitting and parsing.
50
+ ## first split on commas to separate fg, bg and attr
51
+ atts = e.split /\s*,\s*/
52
+ atts.each { |att|
53
+ ## next split on =
54
+ part = att.split /\s*=\s*/
55
+ case part[0]
56
+ when "fg"
57
+ color = part[1]
58
+ when "bg"
59
+ bgcolor = part[1]
60
+ when "style"
61
+ style = part[1]
62
+ when "/end", "end"
63
+ yield :endcolor if block_given?
64
+ #next
65
+ throw :done
66
+ else
67
+ # attrib
68
+ attrib = part[0]
69
+ end
70
+ }
71
+ # 2013-03-25 - 13:31 if numeric color specified
72
+ color = color.to_i if color =~ /^[0-9]+$/
73
+ bgcolor = bgcolor.to_i if bgcolor =~ /^[0-9]+$/
74
+ yield [color,bgcolor,attrib,style] if block_given?
75
+ end # catch
76
+ else
77
+ text = e
78
+ yield text if block_given?
79
+ end
80
+ }
81
+ end
82
+
83
+ end
84
+ end