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,48 @@
1
+ # Help for Textpads
2
+
3
+ (These were earlier called _TextViews_ )
4
+
5
+ Textpads allow display of multiline textual information and provide for
6
+ basic search, and vim-like navigation keys.
7
+
8
+ Some textpads are extended to display multiple buffers such as the help
9
+ screens. Textpads may display text that has ANSI escape codes such as
10
+ unix `man` pages, or the output of commands such as `ri` or `dooby` or
11
+ any other unix command that outputs colored output.
12
+
13
+ There is a second format that provides a lot more control than ANSI,
14
+ which is a `tmux` like format. This is used in the `status_line`.
15
+
16
+ Finally, there is a (new) help format, much like markdown (very
17
+ restricted, though). This page is formatted using the help format.
18
+
19
+ Following are some styles it provides:
20
+
21
+ - strong using __ as in __strong__. end
22
+ - strong using double asterisks that is ** : **strong text with spaces**. end
23
+ - emphasis using single asterisk * as in *emphasis*. end.
24
+ Emphasis *taking spaces in* between with single asterisk.
25
+ - emphasis using single _ as in _thisisemphsized_, will not take _
26
+ inside.
27
+ - code using tilde as in `do_process_now` or `@bgcolor` and `$fgcolor`.
28
+ - underline using bar as in |underlined|, this depends on TERM setting.
29
+ xterm shows underlines, most others do not.
30
+ - Link as in [[list]] (double brackets in source, but single in display).
31
+ - key using angular brackets as in <KEY_BACKSPACE>.
32
+
33
+ A block follows in white and bold (start with a single > on previous
34
+ line, and end with a single < char after block:
35
+ >
36
+ I think most of these need to be fixed so they don't start capturing
37
+ if surrounded by spaces. A lookahead and lookbehind is required other
38
+ wise they can wreak havoc.
39
+ <
40
+
41
+
42
+ Textpads do not provide row selection, but do allow mapping of the <ENTER>
43
+ key and provide the `word_under_cursor` to the calling block as part of
44
+ the action event. For instance, on this (or other) help pages, pressing
45
+ the <TAB> key will take the cursor to the next link (if there is one).
46
+ Pressing <ENTER> on the link will open the linked help file. This is the
47
+ link to the [[index]] or main help page.
48
+
@@ -0,0 +1,23 @@
1
+ # Help for Trees
2
+
3
+ Trees are multirow components that support tree-like information, with
4
+ leafs and branches (nodes) that contain more leafs or branches.
5
+
6
+ These are often used for directory-like structures.
7
+
8
+ Trees support all or most motion commands of [[Textpad]] in addition to
9
+ defining some additional ones such as:
10
+ >
11
+ - O Expand all children
12
+ - X Collapse all children
13
+ - o toggle expanded state
14
+ - p go to parent
15
+ - x collapse parent
16
+ <
17
+
18
+ Pressing <ENTER> expands or collapses a node (branch).
19
+ The `$row_selector` key by default is "v" which is used to trigger a
20
+ method, such as displaying details on some other list or view.
21
+
22
+ (This page needs to be completed)
23
+
Binary file
@@ -0,0 +1,83 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: action.rb
3
+ # Description: A common action class which can be used with buttons, popupmenu
4
+ # and anythign else that takes an action or command
5
+ # Author: jkepler http://github.com/mare-imbrium/canis/
6
+ # Date: been around since the beginning
7
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
8
+ # Last update: 2014-04-28 14:53
9
+ # NOTE: I don't like the dependence on rwidget and EventHandler. Seems it needs
10
+ # that only for fire_handler and not sure if that's used. I've not bound :FIRE
11
+ # ever.
12
+ #
13
+ # Darn, do i really need to have dsl_accessors and property This is not a
14
+ # widget and there's no repaint. Do button's and popups really repaint
15
+ # themselves when a dsl_property is modified ?
16
+ # ----------------------------------------------------------------------------- #
17
+ #
18
+ #require 'canis/core/widgets/rwidget'
19
+ include Canis
20
+ module Canis
21
+ ## encapsulates behaviour allowing centralization
22
+ # == Example
23
+ # a = Action.new("&New Row") { commands }
24
+ # a.accelerator "Alt N"
25
+ # menu.add(a)
26
+ # b = Button.new form do
27
+ # action a
28
+ # ...
29
+ # end
30
+ class Action < Proc
31
+ # once again commented on 2014-04-28 - 14:37 to keep simple
32
+ #include EventHandler # removed 2012-01-3 maybe you can bind FIRE
33
+ #include ConfigSetup # removed 2012-01-3
34
+ # name used on button or menu
35
+ attr_accessor :name
36
+ attr_accessor :enabled
37
+ attr_accessor :tooltip_text
38
+ attr_accessor :help_text
39
+ attr_accessor :mnemonic
40
+ attr_accessor :accelerator
41
+
42
+ def initialize name, config={}, &block
43
+ super &block
44
+ @name = name
45
+ @name.freeze
46
+ @enabled = true
47
+ # removing dependency from config
48
+ #config_setup config # @config.each_pair { |k,v| variable_set(k,v) }
49
+ @config = config
50
+ keys = @config.keys
51
+ keys.each do |e|
52
+ variable_set(e, @config[e])
53
+ end
54
+ #@_events = [:FIRE]
55
+ end
56
+ def call *args
57
+ return unless @enabled
58
+ # seems to be here, if you've bound :FIRE no this, not on any widget
59
+ #fire_handler :FIRE, self
60
+ super
61
+ end
62
+
63
+
64
+ # the next 3 are to adapt this to CMenuitems
65
+ def hotkey
66
+ return @mnemonic if @mnemonic
67
+ ix = @name.index('&')
68
+ if ix
69
+ return @name[ix+1, 1].downcase
70
+ end
71
+ end
72
+ # to adapt this to CMenuitems
73
+ def label
74
+ @name.sub('&','')
75
+ end
76
+ # to adapt this to CMenuitems
77
+ def action
78
+ self
79
+ end
80
+
81
+ end # class
82
+ end # module
83
+
@@ -0,0 +1,49 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: actionmanager.rb
3
+ # Description: a class that manages actions for a widget
4
+ #
5
+ # Author: jkepler http://github.com/mare-imbrium/canis/
6
+ # Date: 2012-01-4
7
+ # License: Same as Ruby's License (http://www.ruby-lang.org/LICENSE.txt)
8
+ # Last update: ,,L
9
+ # ----------------------------------------------------------------------------- #
10
+ #
11
+ # Maintains actions for a widget
12
+ module Canis
13
+ class ActionManager
14
+ include Io
15
+ attr_reader :actions
16
+
17
+ def initialize #form, config={}, &block
18
+ @actions = []
19
+ #instance_eval &block if block_given?
20
+ end
21
+ def add_action act
22
+ @actions << act
23
+ end
24
+ def remove_action act
25
+ @actions.remove act
26
+ end
27
+ #
28
+ # insert an item at given position (index)
29
+ def insert_action pos, *val
30
+ @actions[pos] = val
31
+ end
32
+ #def create_menuitem *args
33
+ #PromptMenu.create_menuitem *args
34
+ #end
35
+
36
+ # popup the hist
37
+ #
38
+ def show_actions
39
+ return if @actions.empty?
40
+ list = @actions
41
+ menu = PromptMenu.new self do |m|
42
+ list.each { |e|
43
+ m.add *e
44
+ }
45
+ end
46
+ menu.display_new :title => 'Widget Menu (Press letter)'
47
+ end
48
+ end # class
49
+ end # mod RubyC
@@ -0,0 +1,179 @@
1
+ module Canis
2
+ module Utils
3
+ private
4
+ def _suspend clear=true
5
+ return unless block_given?
6
+ Ncurses.def_prog_mode
7
+ if clear
8
+ Ncurses.endwin
9
+ # NOTE: avoid false since screen remains half off
10
+ # too many issues
11
+ else
12
+ system "/bin/stty sane"
13
+ end
14
+ yield if block_given?
15
+ Ncurses.reset_prog_mode
16
+ if !clear
17
+ # Hope we don't screw your terminal up with this constantly.
18
+ Canis::stop_ncurses
19
+ Canis::start_ncurses
20
+ #@form.reset_all # not required
21
+ end
22
+ @form.repaint if @form
23
+ @window.wrefresh if @window
24
+ Ncurses::Panel.update_panels
25
+ end
26
+ #
27
+ # Suspends to shell so user can execute commands.
28
+ # Maybe not be able to get your prompt correctly.
29
+ #
30
+ public
31
+ def suspend
32
+ _suspend(false) do
33
+ system("tput cup 26 0")
34
+ system("tput ed")
35
+ system("echo Enter C-d to return to application")
36
+ system (ENV['PS1']='\s-\v\$ ') if ENV['SHELL']== '/bin/bash'
37
+ system(ENV['SHELL']);
38
+ end
39
+ end
40
+
41
+ #
42
+ # prompts user for unix command and displays output in viewer
43
+ #
44
+ def shell_output
45
+ $shell_history ||= []
46
+ cmd = get_string("Enter shell command:", :maxlen => 50) do |f|
47
+ require 'canis/core/include/rhistory'
48
+ f.extend(FieldHistory)
49
+ f.history($shell_history)
50
+ end
51
+ if cmd && !cmd.empty?
52
+ run_command cmd
53
+ $shell_history.push(cmd) unless $shell_history.include? cmd
54
+ end
55
+ end
56
+
57
+ #
58
+ # executes given command and displays in viewer
59
+ # @param [String] unix command, e.g., git -st
60
+ def run_command cmd
61
+ # http://whynotwiki.com/Ruby_/_Process_management#What_happens_to_standard_error_.28stderr.29.3F
62
+ require 'canis/core/util/viewer'
63
+ begin
64
+ res = `#{cmd} 2>&1`
65
+ rescue => ex
66
+ res = ex.to_s
67
+ res << ex.backtrace.join("\n")
68
+ end
69
+ res.gsub!("\t"," ")
70
+ # Earlier close key was ENTER but we need that to execute or fire
71
+ Canis::Viewer.view(res.split("\n"), :close_key => 'q', :title => "<q> to close, M-l M-h to scroll")
72
+ end
73
+ def shell_out command
74
+ w = @window || @form.window
75
+ w.hide
76
+ Ncurses.endwin
77
+ ret = system command
78
+ Ncurses.refresh
79
+ #Ncurses.curs_set 0 # why ?
80
+ w.show
81
+ return ret
82
+ end
83
+ end # utils
84
+ class PrefixCommand
85
+ attr_accessor :object
86
+ def initialize _symbol, calling, config={}, &block
87
+ @object = calling
88
+ @symbol = _symbol
89
+ @descriptions = {}
90
+ define_prefix_command _symbol
91
+ yield self if block_given?
92
+ end
93
+ def define_prefix_command _name, config={}
94
+ $rb_prefix_map ||= {}
95
+ #h = {}
96
+ #@map = h
97
+ _name = _name.to_sym unless _name.is_a? Symbol
98
+ # TODO it may already exist, so retrieve it
99
+ $rb_prefix_map[_name] ||= {}
100
+ @map = $rb_prefix_map[_name]
101
+ # create a variable by name _name
102
+ # create a method by same name to use
103
+ @object.instance_eval %{
104
+ def #{_name.to_s} *args
105
+ h = $rb_prefix_map["#{_name}".to_sym]
106
+ raise "No prefix_map named #{_name}, #{$rb_prefix_map.keys} " unless h
107
+ ch = @window.getchar
108
+ if ch
109
+ res = h[ch]
110
+ if res.is_a? Proc
111
+ res.call
112
+ else
113
+ send(res) if res
114
+ end
115
+ else
116
+ 0
117
+ end
118
+ end
119
+ }
120
+ return _name
121
+ end
122
+ def call
123
+ h = @map
124
+ ch = @object.window.getch # dicey.
125
+ $log.debug "XXX: CALLED #{ch} "
126
+ if ch
127
+ if ch == KEY_F1
128
+ text = ["Options are: "]
129
+ h.keys.each { |e| c = keycode_tos(e); text << " #{c} #{@descriptions[e]} " }
130
+ textdialog text, :title => " #{@symbol} key bindings "
131
+ return
132
+ end
133
+ res = h[ch]
134
+ if res.is_a? Proc
135
+ res.call
136
+ elsif res.is_a? Symbol
137
+ @object.send(res) if res
138
+ else
139
+ Ncurses.beep
140
+ @object.window.ungetch(ch)
141
+
142
+ :UNHANDLED
143
+ end
144
+ else
145
+ raise "got nothing"
146
+ end
147
+ end
148
+
149
+ # define a key within a prefix key map such as C-x
150
+ # Now that i am moving this from global, how will describe bindings get hold of the bindings
151
+ # and descriptions
152
+ def define_key _keycode, *args, &blk
153
+ _symbol = @symbol
154
+ h = $rb_prefix_map[_symbol]
155
+ raise ArgumentError, "No such keymap #{_symbol} defined. Use define_prefix_command." unless h
156
+ _keycode = _keycode[0].getbyte(0) if _keycode[0].class == String
157
+ arg = args.shift
158
+ if arg.is_a? String
159
+ desc = arg
160
+ arg = args.shift
161
+ elsif arg.is_a? Symbol
162
+ # its a symbol
163
+ desc = arg.to_s
164
+ elsif arg.nil?
165
+ desc = "unknown"
166
+ else
167
+ raise ArgumentError, "Don't know how to handle #{arg.class} in PrefixManager"
168
+ end
169
+ @descriptions[_keycode] = desc
170
+
171
+ if !block_given?
172
+ blk = arg
173
+ end
174
+ h[_keycode] = blk
175
+ end
176
+ alias :key :define_key
177
+ end
178
+ end # module RubyC
179
+ include Canis::Utils
@@ -0,0 +1,49 @@
1
+ # I am moving the common title and border printing stuff into
2
+ # a separate module.
3
+ module Canis
4
+ module BorderTitle
5
+ dsl_accessor :suppress_borders #to_print_borders
6
+ dsl_accessor :border_attrib, :border_color
7
+ dsl_accessor :title #set this on top
8
+ dsl_accessor :title_attrib #bold, reverse, normal
9
+
10
+ def bordertitle_init
11
+ @_bordertitle_init_called = true
12
+ @row_offset = @col_offset = 0 if @suppress_borders
13
+ @internal_width = 1 if @suppress_borders # the other programs have zero not 1 NOTE
14
+ end
15
+ # why the dash does it reduce height by one.
16
+ def print_borders
17
+ bordertitle_init unless @_bordertitle_init_called
18
+ raise ArgumentError, "Graphic not set" unless @graphic
19
+ raise "#{self} needs width" unless @width
20
+ raise "#{self} needs height" unless @height
21
+ width = @width
22
+ height = @height-1
23
+ window = @graphic
24
+ startcol = @col
25
+ startrow = @row
26
+ @color_pair = get_color($datacolor)
27
+ bordercolor = @border_color || @color_pair
28
+ borderatt = @border_attrib || Ncurses::A_NORMAL
29
+ window.print_border startrow, startcol, height, width, bordercolor, borderatt
30
+ print_title
31
+ end
32
+ def print_title
33
+ bordertitle_init unless @_bordertitle_init_called
34
+ return unless @title
35
+ raise "#{self} needs width" unless @width
36
+ # removed || since this can change after first invocation and should be recalculated.
37
+ @color_pair = get_color($datacolor)
38
+ #$log.debug " print_title #{@row}, #{@col}, #{@width} "
39
+ # check title.length and truncate if exceeds width
40
+ _title = @title
41
+ if @title.length > @width - 2
42
+ _title = @title[0..@width-2]
43
+ end
44
+ @graphic.printstring( @row, @col+(@width-_title.length)/2, _title, @color_pair, @title_attrib) unless @title.nil?
45
+ end
46
+
47
+ end
48
+ end
49
+ include BorderTitle
@@ -0,0 +1,100 @@
1
+ # ----------------------------------------------------------------------------- #
2
+ # File: canisparser.rb
3
+ # Description: creates an returns instances of parser objects
4
+ # Author: j kepler http://github.com/mare-imbrium/canis/
5
+ # Date: 2014-06-11 - 12:23
6
+ # License: MIT
7
+ # Last update: 2014-06-16 16:56
8
+ # ----------------------------------------------------------------------------- #
9
+ # canisparser.rb Copyright (C) 2012-2014 j kepler
10
+ module Canis
11
+
12
+ # Uses multiton pattern from http://blog.rubybestpractices.com/posts/gregory/059-issue-25-creational-design-patterns.html
13
+ # to create and returns cached instances of a text parser.
14
+ # Users will call the +[]+ method rather than the +new+ method.
15
+ # If users wish to declare their own custom parser, then the +map+ method is to be used.
16
+ #
17
+ # @example
18
+ #
19
+ # CanisParser[:tmux]
20
+ #
21
+ # To define your own parser:
22
+ #
23
+ # CanisParser.map( :custom => [ 'canis/core/include/customparser', 'Canis::CustomParser' ]
24
+ #
25
+ # and later at some point,
26
+ #
27
+ # CanisParser[:custom]
28
+ #
29
+ class CanisParser
30
+ class << self
31
+ # hash storing a filename and classname per content_type
32
+ def content_types
33
+ #@content_types ||= {}
34
+ unless @content_types
35
+ @content_types = {}
36
+ #map(:tmux => [ 'canis/core/util/defaultcolorparser', 'DefaultColorParser'])
37
+ #map(:ansi => [ 'canis/core/util/ansiparser', 'AnsiParser'] )
38
+ @content_types[:tmux] = [ 'canis/core/util/defaultcolorparser', 'DefaultColorParser']
39
+ @content_types[:ansi] = [ 'canis/core/util/ansiparser', 'AnsiParser']
40
+ end
41
+ return @content_types
42
+ end
43
+ # hash storing a parser instance per content_type
44
+ def instances
45
+ @instances ||= {}
46
+ end
47
+ # Used by user to define a new parser
48
+ # map( :tmux => ['filename', 'klassname'] )
49
+ def map(params)
50
+ content_types.update params
51
+ end
52
+
53
+ # Used by user to retrieve a parser instance, creating one if not present
54
+ # CanisParser[:tmux]
55
+ def [](name)
56
+ $log.debug " [] got #{name} "
57
+ raise "nil received by [] " unless name
58
+ instances[name] ||= new(content_types[name])
59
+ #instances[name] ||= create(content_types[name])
60
+ end
61
+ def create args
62
+ filename = args.first
63
+ klassname = args[1]
64
+ $log.debug " canisparser create got #{args} "
65
+ require filename
66
+ clazz = Object.const_get(klassname).new
67
+ $log.debug " created #{clazz.class} "
68
+ # clazz = 'Foo::Bar'.split('::').inject(Object) {|o,c| o.const_get c}
69
+ return clazz
70
+ end
71
+ end
72
+ ## WARNING - this creates a CanisParser class which we really can't use.
73
+ # So we need to delegate to the color parse we created.
74
+ # create and return a parser instance
75
+ # Canisparser.new filename, klassname
76
+ # Usually, *not* called by user, since this instance is not cached. Use +map+
77
+ # and then +[]+ instead for creating and cacheing.
78
+ def initialize *args
79
+ args = args.flatten
80
+ filename = args.first
81
+ klassname = args[1]
82
+ $log.debug " canisparser init got #{args} "
83
+ raise "Canisparser init got nil" unless filename
84
+ require filename
85
+ clazz = Object.const_get(klassname).new
86
+ # clazz = 'Foo::Bar'.split('::').inject(Object) {|o,c| o.const_get c}
87
+ #return clazz
88
+ @clazz = clazz
89
+ end
90
+ # delegate call to color parser
91
+ def parse_format s, *args, &block
92
+ @clazz.parse_format(s, *args, &block)
93
+ end
94
+ # delegate all call to color parser
95
+ def method_missing meth, *args, &block
96
+ #$log.debug " canisparser got method_missing for #{meth}, sending to #{@clazz.class} "
97
+ @clazz.send( meth, *args, &block)
98
+ end
99
+ end
100
+ end