clio 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/CHANGES +66 -0
  2. data/MANIFEST +48 -169
  3. data/README +13 -17
  4. data/RELEASE +8 -0
  5. data/VERSION +1 -0
  6. data/lib/clio/buffer.rb +93 -0
  7. data/lib/clio/commandable.rb +71 -69
  8. data/lib/clio/commandline.rb +429 -230
  9. data/lib/clio/consoleutils.rb +0 -16
  10. data/lib/clio/facets/kernel.rb +13 -0
  11. data/lib/clio/facets/string.rb +25 -0
  12. data/lib/clio/layout.rb +14 -0
  13. data/lib/clio/layout/flow.rb +1 -0
  14. data/lib/clio/layout/line.rb +23 -0
  15. data/lib/clio/layout/list.rb +33 -0
  16. data/lib/clio/layout/split.rb +122 -0
  17. data/lib/clio/layout/stack.rb +17 -0
  18. data/lib/clio/layout/table.rb +46 -0
  19. data/lib/clio/progressbar.rb +189 -210
  20. data/lib/clio/string.rb +116 -109
  21. data/lib/clio/usage.rb +184 -0
  22. data/lib/clio/usage/argument.rb +84 -0
  23. data/lib/clio/usage/command.rb +440 -0
  24. data/lib/clio/usage/interface.rb +122 -0
  25. data/lib/clio/usage/main.rb +165 -0
  26. data/lib/clio/usage/option.rb +251 -0
  27. data/lib/clio/usage/parser.rb +191 -0
  28. data/lib/clio/usage/signature.rb +55 -0
  29. data/meta/abstract +3 -0
  30. data/meta/authors +1 -0
  31. data/meta/created +1 -0
  32. data/meta/homepage +1 -0
  33. data/meta/license +1 -0
  34. data/meta/repository +1 -0
  35. data/meta/summary +1 -0
  36. data/spec/commandline/autousage.rd +56 -0
  37. data/spec/commandline/bracket.rd +64 -0
  38. data/spec/commandline/completion.rd +38 -0
  39. data/spec/commandline/define.rd +44 -0
  40. data/spec/commandline/method.rd +60 -0
  41. data/spec/commandline/parse.rd +72 -0
  42. data/spec/commandline/scenario.rd +81 -0
  43. data/spec/commandline/subclass.rd +54 -0
  44. data/spec/string/unit.rd +58 -0
  45. data/spec/usage/define.rd +44 -0
  46. data/spec/usage/parse.rd +47 -0
  47. metadata +65 -196
  48. data/HISTORY +0 -11
  49. data/METADATA +0 -18
  50. data/NEWS +0 -10
  51. data/admin/config/reap.yaml +0 -30
  52. data/admin/depot/commandline.rb +0 -219
  53. data/admin/depot/multicommand.rb +0 -403
  54. data/admin/depot/test_multicommand.rb +0 -40
  55. data/admin/log/notes.xml +0 -28
  56. data/admin/log/stats.html +0 -25
  57. data/admin/log/syntax.log +0 -0
  58. data/admin/log/testunit.log +0 -16
  59. data/admin/pack/clio-0.0.1.gem +0 -0
  60. data/admin/share/reap/example.rb +0 -7
  61. data/admin/temps/lib/clio/about.rb.erb +0 -4
  62. data/lib/clio/command.rb +0 -296
  63. data/lib/clio/option.rb +0 -36
  64. data/lib/clio/runmode.rb +0 -126
  65. data/test/test_command.rb +0 -42
  66. data/test/test_commandline.rb +0 -83
  67. data/vendor/Console/Console.cpp +0 -1203
  68. data/vendor/Console/Console.rdoc +0 -690
  69. data/vendor/Console/Console_ANSI.rdoc +0 -302
  70. data/vendor/Console/HISTORY.txt +0 -7
  71. data/vendor/Console/INSTALL.txt +0 -18
  72. data/vendor/Console/Makefile +0 -162
  73. data/vendor/Console/README.txt +0 -26
  74. data/vendor/Console/doc/classes/Win32.html +0 -115
  75. data/vendor/Console/doc/classes/Win32/Console.html +0 -650
  76. data/vendor/Console/doc/classes/Win32/Console.src/M000001.html +0 -31
  77. data/vendor/Console/doc/classes/Win32/Console.src/M000002.html +0 -23
  78. data/vendor/Console/doc/classes/Win32/Console.src/M000003.html +0 -23
  79. data/vendor/Console/doc/classes/Win32/Console.src/M000004.html +0 -27
  80. data/vendor/Console/doc/classes/Win32/Console.src/M000005.html +0 -23
  81. data/vendor/Console/doc/classes/Win32/Console.src/M000006.html +0 -28
  82. data/vendor/Console/doc/classes/Win32/Console.src/M000007.html +0 -23
  83. data/vendor/Console/doc/classes/Win32/Console.src/M000008.html +0 -24
  84. data/vendor/Console/doc/classes/Win32/Console.src/M000009.html +0 -44
  85. data/vendor/Console/doc/classes/Win32/Console.src/M000010.html +0 -23
  86. data/vendor/Console/doc/classes/Win32/Console.src/M000011.html +0 -33
  87. data/vendor/Console/doc/classes/Win32/Console.src/M000012.html +0 -26
  88. data/vendor/Console/doc/classes/Win32/Console.src/M000013.html +0 -27
  89. data/vendor/Console/doc/classes/Win32/Console.src/M000014.html +0 -28
  90. data/vendor/Console/doc/classes/Win32/Console.src/M000015.html +0 -23
  91. data/vendor/Console/doc/classes/Win32/Console.src/M000016.html +0 -23
  92. data/vendor/Console/doc/classes/Win32/Console.src/M000017.html +0 -23
  93. data/vendor/Console/doc/classes/Win32/Console.src/M000018.html +0 -29
  94. data/vendor/Console/doc/classes/Win32/Console.src/M000019.html +0 -23
  95. data/vendor/Console/doc/classes/Win32/Console.src/M000020.html +0 -23
  96. data/vendor/Console/doc/classes/Win32/Console.src/M000021.html +0 -28
  97. data/vendor/Console/doc/classes/Win32/Console.src/M000022.html +0 -23
  98. data/vendor/Console/doc/classes/Win32/Console.src/M000023.html +0 -28
  99. data/vendor/Console/doc/classes/Win32/Console.src/M000024.html +0 -35
  100. data/vendor/Console/doc/classes/Win32/Console.src/M000025.html +0 -28
  101. data/vendor/Console/doc/classes/Win32/Console.src/M000026.html +0 -28
  102. data/vendor/Console/doc/classes/Win32/Console.src/M000027.html +0 -28
  103. data/vendor/Console/doc/classes/Win32/Console.src/M000028.html +0 -31
  104. data/vendor/Console/doc/classes/Win32/Console.src/M000029.html +0 -23
  105. data/vendor/Console/doc/classes/Win32/Console.src/M000030.html +0 -23
  106. data/vendor/Console/doc/classes/Win32/Console.src/M000031.html +0 -23
  107. data/vendor/Console/doc/classes/Win32/Console.src/M000032.html +0 -27
  108. data/vendor/Console/doc/classes/Win32/Console.src/M000033.html +0 -27
  109. data/vendor/Console/doc/classes/Win32/Console.src/M000034.html +0 -25
  110. data/vendor/Console/doc/classes/Win32/Console/ANSI.html +0 -103
  111. data/vendor/Console/doc/classes/Win32/Console/ANSI/IO.html +0 -220
  112. data/vendor/Console/doc/classes/Win32/Console/ANSI/IO.src/M000035.html +0 -32
  113. data/vendor/Console/doc/classes/Win32/Console/ANSI/IO.src/M000036.html +0 -205
  114. data/vendor/Console/doc/classes/Win32/Console/ANSI/IO.src/M000037.html +0 -40
  115. data/vendor/Console/doc/classes/Win32/Console/ANSI/IO.src/M000038.html +0 -25
  116. data/vendor/Console/doc/classes/Win32/Console/API.html +0 -758
  117. data/vendor/Console/doc/classes/Win32/Console/API.src/M000039.html +0 -27
  118. data/vendor/Console/doc/classes/Win32/Console/API.src/M000040.html +0 -27
  119. data/vendor/Console/doc/classes/Win32/Console/API.src/M000041.html +0 -27
  120. data/vendor/Console/doc/classes/Win32/Console/API.src/M000042.html +0 -32
  121. data/vendor/Console/doc/classes/Win32/Console/API.src/M000043.html +0 -32
  122. data/vendor/Console/doc/classes/Win32/Console/API.src/M000044.html +0 -28
  123. data/vendor/Console/doc/classes/Win32/Console/API.src/M000045.html +0 -26
  124. data/vendor/Console/doc/classes/Win32/Console/API.src/M000046.html +0 -26
  125. data/vendor/Console/doc/classes/Win32/Console/API.src/M000047.html +0 -27
  126. data/vendor/Console/doc/classes/Win32/Console/API.src/M000048.html +0 -30
  127. data/vendor/Console/doc/classes/Win32/Console/API.src/M000049.html +0 -29
  128. data/vendor/Console/doc/classes/Win32/Console/API.src/M000050.html +0 -27
  129. data/vendor/Console/doc/classes/Win32/Console/API.src/M000051.html +0 -28
  130. data/vendor/Console/doc/classes/Win32/Console/API.src/M000052.html +0 -30
  131. data/vendor/Console/doc/classes/Win32/Console/API.src/M000053.html +0 -27
  132. data/vendor/Console/doc/classes/Win32/Console/API.src/M000054.html +0 -29
  133. data/vendor/Console/doc/classes/Win32/Console/API.src/M000055.html +0 -29
  134. data/vendor/Console/doc/classes/Win32/Console/API.src/M000056.html +0 -28
  135. data/vendor/Console/doc/classes/Win32/Console/API.src/M000057.html +0 -27
  136. data/vendor/Console/doc/classes/Win32/Console/API.src/M000058.html +0 -47
  137. data/vendor/Console/doc/classes/Win32/Console/API.src/M000059.html +0 -32
  138. data/vendor/Console/doc/classes/Win32/Console/API.src/M000060.html +0 -47
  139. data/vendor/Console/doc/classes/Win32/Console/API.src/M000061.html +0 -34
  140. data/vendor/Console/doc/classes/Win32/Console/API.src/M000062.html +0 -32
  141. data/vendor/Console/doc/classes/Win32/Console/API.src/M000063.html +0 -32
  142. data/vendor/Console/doc/classes/Win32/Console/API.src/M000064.html +0 -35
  143. data/vendor/Console/doc/classes/Win32/Console/API.src/M000065.html +0 -26
  144. data/vendor/Console/doc/classes/Win32/Console/API.src/M000066.html +0 -27
  145. data/vendor/Console/doc/classes/Win32/Console/API.src/M000067.html +0 -29
  146. data/vendor/Console/doc/classes/Win32/Console/API.src/M000068.html +0 -27
  147. data/vendor/Console/doc/classes/Win32/Console/API.src/M000069.html +0 -27
  148. data/vendor/Console/doc/classes/Win32/Console/API.src/M000070.html +0 -28
  149. data/vendor/Console/doc/classes/Win32/Console/API.src/M000071.html +0 -27
  150. data/vendor/Console/doc/classes/Win32/Console/API.src/M000072.html +0 -26
  151. data/vendor/Console/doc/classes/Win32/Console/API.src/M000073.html +0 -27
  152. data/vendor/Console/doc/classes/Win32/Console/API.src/M000074.html +0 -31
  153. data/vendor/Console/doc/classes/Win32/Console/API.src/M000075.html +0 -27
  154. data/vendor/Console/doc/classes/Win32/Console/API.src/M000076.html +0 -32
  155. data/vendor/Console/doc/classes/Win32/Console/API.src/M000077.html +0 -27
  156. data/vendor/Console/doc/classes/Win32/Console/API.src/M000078.html +0 -32
  157. data/vendor/Console/doc/classes/Win32/Console/API.src/M000079.html +0 -32
  158. data/vendor/Console/doc/classes/Win32/Console/API.src/M000080.html +0 -32
  159. data/vendor/Console/doc/classes/Win32/Console/Constants.html +0 -360
  160. data/vendor/Console/doc/created.rid +0 -1
  161. data/vendor/Console/doc/files/Console_ANSI_rdoc.html +0 -407
  162. data/vendor/Console/doc/files/Console_cpp.html +0 -104
  163. data/vendor/Console/doc/files/Console_rdoc.html +0 -964
  164. data/vendor/Console/doc/files/lib/Win32/Console/ANSI_rb.html +0 -123
  165. data/vendor/Console/doc/files/lib/Win32/Console_rb.html +0 -297
  166. data/vendor/Console/doc/fr_class_index.html +0 -32
  167. data/vendor/Console/doc/fr_file_index.html +0 -31
  168. data/vendor/Console/doc/fr_method_index.html +0 -106
  169. data/vendor/Console/doc/index.html +0 -24
  170. data/vendor/Console/doc/rdoc-style.css +0 -172
  171. data/vendor/Console/extconf.rb +0 -18
  172. data/vendor/Console/lib/Term/ansicolor.rb +0 -76
  173. data/vendor/Console/lib/Win32/Console.rb +0 -970
  174. data/vendor/Console/lib/Win32/Console/ANSI.rb +0 -305
  175. data/vendor/Console/test/test_cursor.rb +0 -9
  176. data/vendor/Console/test/test_mouse.rb +0 -6
  177. data/vendor/Console/test/test_readinput.rb +0 -62
  178. data/vendor/Console/test/test_readoutput.rb +0 -52
  179. data/vendor/Console/test/test_sendevent.rb +0 -17
  180. data/vendor/Console/test/test_title.rb +0 -14
  181. data/vendor/Console/test/test_write.rb +0 -36
data/lib/clio/string.rb CHANGED
@@ -1,147 +1,154 @@
1
- #require 'facets/rope'
2
1
  require 'clio/ansicode'
3
- require 'facets/string/mask'
2
+ require 'clio/layout/split'
3
+ require 'clio/facets/string'
4
4
 
5
5
  module Clio
6
6
 
7
- # = Clio String class.
7
+ def self.string(str)
8
+ String.new(str)
9
+ end
10
+
11
+ # Clio Strings stores a regular string (@text) and
12
+ # a Hash mapping character index to ansicodes (@marks).
13
+ # For example is we has the string:
14
+ #
15
+ # "Big Apple"
16
+ #
17
+ # And applied the color red to it, the marks hash would be:
18
+ #
19
+ # { 0=>[:red] , 9=>[:clear] }
8
20
  #
9
21
  class String
10
22
 
11
- ESC_RE = /\e\[[0-9]*\w/
12
-
13
- private
14
-
15
- def initialize(text, ansi=nil)
16
- @text = text.to_s
17
- @ansi = ansi || text.to_s
18
- end
19
-
20
- public
21
-
22
23
  attr :text
24
+ attr :marks
23
25
 
24
- attr :ansi
25
-
26
- #
27
- def to_s ; ansi ; end
28
-
29
- #def to_str ; text ; end
30
-
31
- #
32
- def +(append)
33
- case append
34
- when Symbol
35
- t = text
36
- a = ansi + ANSICode.send(append)
37
- when self.class
38
- t = text + append.text
39
- a = ansi + append.ansi
40
- else
41
- t = text + append
42
- a = ansi + append
43
- end
44
- self.class.new(t, a)
26
+ def initialize(text=nil, marks=nil)
27
+ @text = text || ''
28
+ @marks = marks || Hash.new{ |h,k| h[k]=[] }
45
29
  end
46
30
 
47
- #
48
- def <<(append)
49
- case append
50
- when Symbol
51
- @ansi << ANSICode.send(append)
52
- when self.class
53
- @text << append.text
54
- @ansi << append.ansi
55
- else
56
- @text << append
57
- @ansi << append
31
+ def to_s
32
+ s = text.dup
33
+ m = marks.sort{ |a,b| b[0] <=> a[0] }
34
+ m.each do |index, codes|
35
+ codes.each do |code|
36
+ s.insert(index, ANSICode.send(code))
37
+ end
58
38
  end
39
+ s
59
40
  end
60
41
 
61
- #
62
42
  def size ; text.size ; end
63
- alias_method(:length, :size)
64
43
 
65
- # Give the string a color.
66
- def color(ansicolor=nil)
67
- self.class.new(text, ANSICode.send(ansicolor){ansi})
44
+ ###
45
+ def color!(ansicolor)
46
+ marks[0] << ansicolor
47
+ marks[size] << :clear
68
48
  end
69
49
 
70
- # Give the string a color.
71
- def color!(ansicolor=nil)
72
- @ansi = ANSICode.send(ansicolor){ansi}
50
+ ###
51
+ def color(ansicolor)
52
+ m = marks.dup
53
+ m[0] << ansicolor
54
+ m[size] << :clear
55
+ self.class.new(text, m)
73
56
  end
74
57
 
75
- #--
76
- # TODO: No doubt the delegation will need to be made more robust.
77
- #++
78
-
79
- INPLACE_DELEGATE_METHODS = /(\[\]=|replace|!$)/
80
- EXCLUDE_DELEGATE_METHODS = /(split|^to_)/
81
-
82
- # Delegate to underlying text/ansi.
83
- def method_missing(s, *a, &b)
84
- case s.to_s
85
- when EXCLUDE_DELEGATE_METHODS
86
- super
87
- when INPLACE_DELEGATE_METHODS
88
- text.send(s, *a, &b)
89
- m = ansi.to_mask
90
- e = ansi.to_mask(ESC_RE)
91
- n = (e - m)
92
- e.instance_delegate.send(s,*a, &b)
93
- r = e + n
94
- @ansi = r.to_s
58
+ ###
59
+ def upcase ; self.class.new(text.upcase, marks) ; end
60
+ def upcase! ; text.upcase! ; end
61
+
62
+ ###
63
+ def downcase ; self.class.new(text.upcase, marks) ; end
64
+ def downcase! ; text.upcase! ; end
65
+
66
+ ###
67
+ def +(other)
68
+ case other
69
+ when String
70
+ ntext = text + other.text
71
+ nmarks = marks.dup
72
+ other.marks.each{ |i, c| m[i] << c }
95
73
  else
96
- apply(s, *a, &b)
74
+ ntext = text + other.to_s
75
+ nmarks = marks.dup
97
76
  end
77
+ self.class.new(ntext, nmarks)
98
78
  end
99
79
 
100
- private
101
-
102
- #
103
- def apply(s, *a, &b)
104
- t = text.send(s, *a, &b)
105
- m = ansi.to_mask
106
- e = ansi.to_mask(ESC_RE)
107
- n = (e - m)
108
- x = e.apply(s,*a, &b)
109
- r = x + n
110
- self.class.new(t, r.to_s)
80
+ def |(other)
81
+ Split.new(self, other)
111
82
  end
112
83
 
113
- end
114
-
115
- end
116
-
117
-
118
- =begin SPECIFICATION
119
-
120
- require 'quarry/spec'
84
+ def lr(other, options={})
85
+ Split.new(self, other, options)
86
+ end
121
87
 
122
- Quarry.spec "Clio::String" do
88
+ ### slice
89
+ def slice(*args)
90
+ if args.size == 2
91
+ index, len = *args
92
+ endex = index+len
93
+ new_text = text[index, len]
94
+ new_marks = {}
95
+ marks.each do |i, v|
96
+ new_marks[i] = v if i >= index && i < endex
97
+ end
98
+ self.class.new(new_text, new_marks)
99
+ elsif args.size == 1
100
+ rng = args.first
101
+ case rng
102
+ when Range
103
+ index, endex = rng.begin, rng.end
104
+ new_text = text[rng]
105
+ new_marks = {}
106
+ marks.each do |i, v|
107
+ new_marks[i] = v if i >= index && i < endex
108
+ end
109
+ self.class.new(new_text, new_marks)
110
+ else
111
+ self.class.new(text[rng,1], {rng=>marks[rng]})
112
+ end
113
+ else
114
+ raise ArgumentError
115
+ end
116
+ end
123
117
 
124
- s1 = Clio::String.new("Hi how are you.")
125
- s2 = Clio::String.new("Fine thanks.")
118
+ alias_method :[], :slice
126
119
 
127
- verify "color" do
128
- r = s1.color(:red)
129
- e = Clio::ANSICode.red(s1.text)
130
- e.assert == r.to_s
120
+ # TODO: block support and \1, \2 support.
121
+ def sub(pattern,replacement)
122
+ if md = pattern.match(@text)
123
+ delta = replacement.size - md.size
124
+ marks2 = shift_marks(md.end, delta)
125
+ text2 = text.sub(pattern,replacement)
126
+ self.class.new(text2, marks2)
127
+ else
128
+ self.class.new(text, marks)
129
+ end
131
130
  end
132
131
 
133
- verify "non-in-place delegation" do
134
- r = s1.upcase
135
- e = s1.text.upcase
136
- e.assert == r.to_s
132
+ #
133
+ def gsub
137
134
  end
138
135
 
139
- verify "string addition" do
140
- r = s1 + s2
141
- e = s1.text + s2.text
136
+ private
137
+
138
+ def shift_marks(index, delta)
139
+ new_marks = {}
140
+ marks.each do |i, v|
141
+ case i <=> index
142
+ when 0, -1
143
+ new_marks[i] = v
144
+ when 1
145
+ new_marks[i+delta] = v
146
+ end
147
+ end
148
+ new_marks
142
149
  end
143
150
 
144
151
  end
145
152
 
146
- =end
153
+ end
147
154
 
data/lib/clio/usage.rb ADDED
@@ -0,0 +1,184 @@
1
+ require 'clio/usage/main'
2
+ require 'clio/usage/parser'
3
+
4
+ module Clio
5
+
6
+ # = Usage
7
+ #
8
+ # Uasge provides a verstile but easy to use system of describing
9
+ # a commandline interface.
10
+ #
11
+ # == Underlying Fluent and Block Notation
12
+ #
13
+ # Underlying all usage is a fluent interface for decalaring
14
+ # a commandline's structure. Here is an example of using
15
+ # this DSL, albeit rather brutely.
16
+ #
17
+ # usage = Clio::Usage.new
18
+ # usage.command(:document).help('generate documentation')
19
+ # usage.command(:document).option(:output, :o).type('FILE')
20
+ # usage.command(:document).option(:output).help('output directory')
21
+ # usage.option(:verbose, :V).help('verbose output')
22
+ # usage.option(:quiet, :q).help('run silently').xor(:V)
23
+ #
24
+ # The example defines a subcommand 'document' that can take an
25
+ # 'output' option, and two mutually excluive universal options,
26
+ # 'verbose' and 'quiet', with respective one-letter aliases.
27
+ #
28
+ # As you might expect the fluent notation can be broken down into
29
+ # block notation which is easier to read.
30
+ #
31
+ # usage = Usage.new
32
+ # usage do
33
+ # option(:verbose, :v) do
34
+ # help('verbose output')
35
+ # end
36
+ # option(:quiet, :q) do
37
+ # help('run silently')
38
+ # xor(:V)
39
+ # end
40
+ # command(:document) do
41
+ # help('generate documentation')
42
+ # option(:output, :o) do
43
+ # type('FILE')
44
+ # help('output directory')
45
+ # end
46
+ # argument('files') do
47
+ # multiple
48
+ # end
49
+ # end
50
+ # end
51
+ #
52
+ # Clearly block notation is DRY and more elegant the the previous fluent
53
+ # version, but fluent notation is important because it allows the usage
54
+ # object to be easily passed around and augmented as needed.
55
+ #
56
+ #--
57
+ # == Abbriviated Notation
58
+ #
59
+ # While comprehensble, the core Usage DSL can be a somewhat verbose.
60
+ # So abbriviated forms of these methods are provided. These methods
61
+ # go one step further as well, and allow for some additional arguments.
62
+ #
63
+ # cli.usage do
64
+ # opt('verbose -v', 'verbose output') |
65
+ # opt('quiet -q' , 'run silently')
66
+ # cmd('document', 'generate documentation') do
67
+ # opt('output=FILE -o', 'output directory')
68
+ # arg('FILE*')
69
+ # end
70
+ # end
71
+ #
72
+ # Notice the use of '|'. This allows us to define mutual exclusion
73
+ # without resorting to #xor as was done in the first example.
74
+ #++
75
+ #
76
+ # = Method Notation
77
+ #
78
+ # This notation is very elegant, but slightly more limited in scope.
79
+ # For instance, subcommands that use non-letter characters, such as ':',
80
+ # can not be described with this notation.
81
+ #
82
+ # usage.document('<file*>', '--output=FILE -o')
83
+ # usage('--verbose -V','--quiet -q')
84
+ #
85
+ # usage.help(
86
+ # 'document' , 'generate documentation',
87
+ # 'validate' , 'run tests or specifications',
88
+ # '--verbose' , 'verbose output',
89
+ # '--quiet' , 'run siltently'
90
+ # )
91
+ #
92
+ # usage.document.help(
93
+ # '--output', 'output directory'
94
+ # 'file*', 'files to document'
95
+ # )
96
+ #
97
+ # This notation is slightly more limited in scope... so...
98
+ #
99
+ # usage.command(:document, '--output=FILE -o', '<file*>')
100
+ #
101
+ # == Bracket Shorthand Notation
102
+ #
103
+ # The core notation can be somewhat verbose. As a further convenience
104
+ # commandline usage can be defined with a brief <i>bracket shorthand</i>.
105
+ # This is especailly useful when the usage is simple and statically defined.
106
+ #
107
+ # usage['document']['--output=FILE -o']['FILE*']
108
+ #
109
+ # Using a little creativity to improve readabilty we can convert the
110
+ # whole example from above using this notation.
111
+ #
112
+ # usage['--verbose -V', 'verbose output' ] \
113
+ # ['--quiet -q', 'run silently' ] \
114
+ # ['document', 'generate documention' ] \
115
+ # [ '--output=FILE -o', 'output directory' ] \
116
+ # [ 'FILE*', 'files to document' ]
117
+ #
118
+ # Alternately the help information can be left out and defined in
119
+ # a seprate set of usage calls.
120
+ #
121
+ # usage['--verbose -V']['--quiet -q'] \
122
+ # ['document']['--output=FILE -o']['FILE*']
123
+ #
124
+ # usage.help(
125
+ # 'document' , 'generate documentation',
126
+ # 'validate' , 'run tests or specifications',
127
+ # '--verbose' , 'verbose output',
128
+ # '--quiet' , 'run siltently'
129
+ # )
130
+ #
131
+ # usage['document'].help(
132
+ # '--output', 'output directory'
133
+ # 'FILE', 'files to docment'
134
+ # )
135
+ #
136
+ # A little more verbose, but a bit more intutive.
137
+ #
138
+ # == "Alien" Notation
139
+ #
140
+ # As a side note, it is easy enough to alias #[] to #_, so alternatively
141
+ # one code create a variant shorthand written as:
142
+ #
143
+ # usage do
144
+ # _ '--verbose -V', 'verbose output'
145
+ # _ '--quiet -q', 'run silently'
146
+ # _ 'document', 'generate documentation' do
147
+ # _ '--output=FILE -o', 'output directory'
148
+ # _ 'FILE*', 'files to document'
149
+ # end
150
+ # end
151
+ #
152
+ # To demonsrtate it's equvalence to bracket shorthand, it can be chained as well.
153
+ #
154
+ # usage._('document')._('--output=FILE -o')._('FILE*')
155
+ #
156
+ # This notation is not supported by default, but if it is more your style
157
+ # it is easy enough to implement by extending Clio::Usage::Command like this:
158
+ #
159
+ # class Clio::Usage::Command
160
+ # alias_method :_, :[]
161
+ # end
162
+ #
163
+ # == Combining Notations
164
+ #
165
+ # Since the various notations all translate to same underlying
166
+ # structures, they can be mixed and matched as suites ones taste.
167
+ # For example we could mix Method Notation and Bracket Notation.
168
+ #
169
+ # usage.document['--output=FILE -o']['file*']
170
+ # usage['--verbose -V']['--quiet -q']
171
+ #
172
+ # The important thing to keep in mind when doing this is what is
173
+ # returned by each type of usage call.
174
+ #
175
+ module Usage
176
+
177
+ def self.new(name=nil, &block)
178
+ Main.new(name, &block)
179
+ end
180
+
181
+ end#module Usage
182
+
183
+ end#module Clio
184
+
@@ -0,0 +1,84 @@
1
+ module Clio
2
+
3
+ module Usage #:nodoc:
4
+
5
+ # = Usage Argument
6
+ #
7
+ class Argument
8
+ #attr :parent
9
+ attr :name
10
+ attr :type
11
+ attr :help
12
+ attr :splat
13
+
14
+ # New Argument.
15
+ #def initialize(name, parent=nil, &block)
16
+ def initialize(name, &block)
17
+ @name = name.to_s
18
+ @type = name.upcase
19
+ #@parent = parent
20
+ @splat = false
21
+ @help = ''
22
+ instance_eval(&block) if block
23
+ end
24
+
25
+ #
26
+ def initialize_copy(o)
27
+ @name = o.name.dup
28
+ @type = o.type.dup
29
+ @help = o.help.dup
30
+ end
31
+
32
+ # Same as +name+ but given as a symbol.
33
+ def key
34
+ name.to_sym
35
+ end
36
+
37
+ # Specify the type of the argument.
38
+ # This is an arbitrary description of the type.
39
+ # The value given is converted to uppercase.
40
+ #
41
+ # arg.type('file')
42
+ # arg.type #=> 'FILE'
43
+ #
44
+ def type(string=nil)
45
+ return @type unless string
46
+ @type = string.to_s.upcase
47
+ self
48
+ end
49
+
50
+ #
51
+ def splat(true_or_false=nil)
52
+ return @splat if true_or_false.nil?
53
+ @splat = true_or_false
54
+ end
55
+
56
+ # Specify help text for argument.
57
+ def help(string=nil)
58
+ @help.replace(string.to_s) if string
59
+ @help
60
+ end
61
+
62
+ def to_s
63
+ if name.upcase == type
64
+ s = "<#{name}"
65
+ else
66
+ s = "<#{name}:#{type}"
67
+ end
68
+ s << (splat ? "...>" : ">")
69
+ s
70
+ end
71
+
72
+ def inspect
73
+ s = "<#{name}"
74
+ s << ":#{type.inspect}" if type
75
+ s << ">"
76
+ s
77
+ end
78
+
79
+ end #class Argument
80
+
81
+ end #module Usage
82
+
83
+ end #module Clio
84
+