rwdeliza 0.03

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. data/ElizaData/database/db.1 +7015 -0
  2. data/ElizaData/database/db.10 +7001 -0
  3. data/ElizaData/database/db.11 +7001 -0
  4. data/ElizaData/database/db.12 +7003 -0
  5. data/ElizaData/database/db.13 +7003 -0
  6. data/ElizaData/database/db.14 +7008 -0
  7. data/ElizaData/database/db.15 +7001 -0
  8. data/ElizaData/database/db.16 +7001 -0
  9. data/ElizaData/database/db.17 +7001 -0
  10. data/ElizaData/database/db.18 +7001 -0
  11. data/ElizaData/database/db.19 +7001 -0
  12. data/ElizaData/database/db.2 +7001 -0
  13. data/ElizaData/database/db.20 +5467 -0
  14. data/ElizaData/database/db.3 +7001 -0
  15. data/ElizaData/database/db.4 +7001 -0
  16. data/ElizaData/database/db.5 +7001 -0
  17. data/ElizaData/database/db.6 +7001 -0
  18. data/ElizaData/database/db.7 +7001 -0
  19. data/ElizaData/database/db.8 +7001 -0
  20. data/ElizaData/database/db.9 +7001 -0
  21. data/ElizaData/responses/hello.res +1 -0
  22. data/ElizaData/responses/i_agree.res +1 -0
  23. data/ElizaData/responses/i_am_listening_to_you.res +1 -0
  24. data/ElizaData/responses/please_explain.res +1 -0
  25. data/ElizaData/responses/thank_you.res +1 -0
  26. data/ElizaData/tiny.dict +211 -0
  27. data/ElizaData/words/adjectives1.words +906 -0
  28. data/ElizaData/words/adjectives2w.words +1 -0
  29. data/ElizaData/words/noun0.words +15 -0
  30. data/ElizaData/words/noun1.words +1391 -0
  31. data/ElizaData/words/noun2.words +1924 -0
  32. data/ElizaData/words/noun4.words +330 -0
  33. data/ElizaData/words/pronoun1.words +6 -0
  34. data/ElizaData/words/verb4.words +350 -0
  35. data/ElizaData/words/verb42.words +391 -0
  36. data/ElizaData/words/verb42w.words +1 -0
  37. data/ElizaData/words/verb43.words +402 -0
  38. data/ElizaData/words/verb43w.words +1 -0
  39. data/ElizaData/words/verb45.words +452 -0
  40. data/ElizaData/words/verb4w.words +1 -0
  41. data/ElizaData/words/verb5.words +13 -0
  42. data/ElizaData/words/verb61.words +35 -0
  43. data/ElizaData/words/verb62.words +41 -0
  44. data/ElizaData/words/verb83.words +17 -0
  45. data/Readme.txt +462 -0
  46. data/bin/rwdeliza +19 -0
  47. data/code/01rwdcore/01rwdcore.rb +29 -0
  48. data/code/01rwdcore/02helptexthashbegin.rb +4 -0
  49. data/code/01rwdcore/03helptexthash.rb +23 -0
  50. data/code/01rwdcore/04helptextend.rb +6 -0
  51. data/code/01rwdcore/jumplinkcommand.rb +26 -0
  52. data/code/01rwdcore/openhelpwindow.rb +31 -0
  53. data/code/01rwdcore/returntomain.rb +10 -0
  54. data/code/01rwdcore/rundocuments.rb +10 -0
  55. data/code/01rwdcore/runeditconfiguration.rb +10 -0
  56. data/code/01rwdcore/runhelpabout.rb +10 -0
  57. data/code/01rwdcore/runopentinkerdocument.rb +7 -0
  58. data/code/01rwdcore/rwdtinkerversion.rb +22 -0
  59. data/code/01rwdcore/rwdwindowreturn.rb +9 -0
  60. data/code/01rwdcore/selectiontab.rb +9 -0
  61. data/code/01rwdcore/setuphelpaboutoptions.rb +13 -0
  62. data/code/01rwdcore/setuptinkerdocuments.rb +6 -0
  63. data/code/01rwdcore/test_cases.rb +109 -0
  64. data/code/01rwdcore/test_harness.rb +13 -0
  65. data/code/01rwdcore/uploadreturns.rb +62 -0
  66. data/code/dd0viewphoto/dd0viewphoto.rb +3 -0
  67. data/code/superant.com.rwdeliza/0uninstallapplet.rb +10 -0
  68. data/code/superant.com.rwdeliza/eliza01.rb +45 -0
  69. data/code/superant.com.rwdeliza/helptexthashrwdeliza.rb +39 -0
  70. data/code/superant.com.rwdeliza/openhelpwindowrwdeliza.rb +23 -0
  71. data/code/superant.com.rwdeliza/runrwdshellwindow.rb +12 -0
  72. data/code/superant.com.rwdeliza/rwdtinkerversion.rb +10 -0
  73. data/code/superant.com.rwdeliza/tagsentence.rb +39 -0
  74. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +19 -0
  75. data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +61 -0
  76. data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +240 -0
  77. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +34 -0
  78. data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +20 -0
  79. data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
  80. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +53 -0
  81. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +12 -0
  82. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +27 -0
  83. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +22 -0
  84. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -0
  85. data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
  86. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +19 -0
  87. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +38 -0
  88. data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
  89. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +46 -0
  90. data/code/superant.com.rwdtinkerbackwindow/removeappletvariables.rb +52 -0
  91. data/code/superant.com.rwdtinkerbackwindow/runremoteinstall.rb +11 -0
  92. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +15 -0
  93. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +13 -0
  94. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -0
  95. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +22 -0
  96. data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +24 -0
  97. data/code/superant.com.words/dictlookup.rb +20 -0
  98. data/code/superant.com.words/runfortunewindow.rb +14 -0
  99. data/code/superant.com.words/runrwdwordsbackwindow.rb +10 -0
  100. data/code/superant.com.words/runrwdwordsversion.rb +14 -0
  101. data/code/superant.com.words/rwdtinkerversion.rb +10 -0
  102. data/code/zz0applicationend/zz0end.rb +4 -0
  103. data/configuration/language.dist +8 -0
  104. data/configuration/rwdapplicationidentity.dist +3 -0
  105. data/configuration/rwdtinker.dist +18 -0
  106. data/configuration/rwdweliza-0.03.dist +31 -0
  107. data/configuration/tinkerwin2variables.dist +17 -0
  108. data/gui/00coreguibegin/applicationguitop.rwd +4 -0
  109. data/gui/frontwindow0/cc0openphoto.rwd +22 -0
  110. data/gui/frontwindowselections/00selectiontabbegin.rwd +11 -0
  111. data/gui/frontwindowselections/jumplinkcommands.rwd +15 -0
  112. data/gui/frontwindowselections/wwselectionend.rwd +3 -0
  113. data/gui/frontwindowtdocuments/00documentbegin.rwd +6 -0
  114. data/gui/frontwindowtdocuments/tinkerdocuments.rwd +14 -0
  115. data/gui/frontwindowtdocuments/zzdocumentend.rwd +8 -0
  116. data/gui/helpaboutbegin/zzzrwdlasttab.rwd +6 -0
  117. data/gui/helpaboutbegin/zzzzhelpscreenstart.rwd +3 -0
  118. data/gui/helpaboutbegin/zzzzzzhelpabouttab.rwd +15 -0
  119. data/gui/helpaboutzend/helpscreenend.rwd +3 -0
  120. data/gui/helpaboutzend/zhelpscreenstart2.rwd +3 -0
  121. data/gui/helpaboutzend/zzzzhelpabout2.rwd +15 -0
  122. data/gui/helpaboutzend/zzzzhelpscreen2end.rwd +3 -0
  123. data/gui/tinkerbackwindows/superant.com.refreshwindow/fortunerefreshwindowtwo.rwd +9 -0
  124. data/gui/tinkerbackwindows/superant.com.rwdeliza/1appname.rwd +5 -0
  125. data/gui/tinkerbackwindows/superant.com.rwdeliza/1eliza.rwd +21 -0
  126. data/gui/tinkerbackwindows/superant.com.rwdeliza/4sentance.rwd +21 -0
  127. data/gui/tinkerbackwindows/superant.com.rwdeliza/98jumplinkcommands.rwd +17 -0
  128. data/gui/tinkerbackwindows/superant.com.rwdeliza/zbackend.rwd +6 -0
  129. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/1appname.rwd +5 -0
  130. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/20downloadftp.rwd +45 -0
  131. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +29 -0
  132. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/70rwddiagnostics.rwd +16 -0
  133. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m01menubegin.rwd +18 -0
  134. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/zvbackend.rwd +6 -0
  135. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
  136. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +41 -0
  137. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
  138. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
  139. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +30 -0
  140. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
  141. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/81jumplinkcommands.rwd +17 -0
  142. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
  143. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
  144. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
  145. data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
  146. data/gui/tinkerbackwindows/superant.com.versionwindow/helpaboutwindow.rwd +17 -0
  147. data/gui/tinkerbackwindows/superant.com.words/1appname.rwd +4 -0
  148. data/gui/tinkerbackwindows/superant.com.words/1dictionary.rwd +19 -0
  149. data/gui/tinkerbackwindows/superant.com.words/3rwdfortune.rwd +14 -0
  150. data/gui/tinkerbackwindows/superant.com.words/77jumplinkcommands.rwd +17 -0
  151. data/gui/tinkerbackwindows/superant.com.words/z9end.rwd +6 -0
  152. data/gui/zzcoreguiend/yy9rwdend.rwd +4 -0
  153. data/init.rb +277 -0
  154. data/installed/rwdweliza-0.03.inf +24 -0
  155. data/installed/temp.rb +1 -0
  156. data/lang/en/rwdcore/languagefile.rb +58 -0
  157. data/lang/es/rwdcore/languagefile-es.rb +62 -0
  158. data/lang/fr/rwdcore/languagefile.rb +64 -0
  159. data/lang/jp/rwdcore/languagefile.rb +72 -0
  160. data/lang/nl/rwdcore/languagefile.rb +75 -0
  161. data/lib/dict.rb +438 -0
  162. data/lib/druida.rb +499 -0
  163. data/lib/hashslice.rb +71 -0
  164. data/lib/linguistics.rb +360 -0
  165. data/lib/linguistics/en.rb +1601 -0
  166. data/lib/linguistics/en/infinitive.rb +1148 -0
  167. data/lib/linguistics/en/linkparser.rb +142 -0
  168. data/lib/linguistics/en/wordnet.rb +253 -0
  169. data/lib/linguistics/iso639.rb +456 -0
  170. data/lib/linkparser.rb +461 -0
  171. data/lib/linkparser/connection.rb +81 -0
  172. data/lib/linkparser/connector.rb +201 -0
  173. data/lib/linkparser/definition.rb +225 -0
  174. data/lib/linkparser/dictionary.rb +208 -0
  175. data/lib/linkparser/linkage.rb +185 -0
  176. data/lib/linkparser/log.rb +39 -0
  177. data/lib/linkparser/sentence.rb +79 -0
  178. data/lib/linkparser/utils.rb +540 -0
  179. data/lib/linkparser/word.rb +92 -0
  180. data/lib/rconftool.rb +380 -0
  181. data/lib/rwd/browser.rb +123 -0
  182. data/lib/rwd/ftools.rb +174 -0
  183. data/lib/rwd/mime.rb +328 -0
  184. data/lib/rwd/net.rb +866 -0
  185. data/lib/rwd/ruby.rb +889 -0
  186. data/lib/rwd/rwd.rb +1942 -0
  187. data/lib/rwd/sgml.rb +236 -0
  188. data/lib/rwd/thread.rb +63 -0
  189. data/lib/rwd/tree.rb +371 -0
  190. data/lib/rwd/xml.rb +101 -0
  191. data/lib/zip/ioextras.rb +114 -0
  192. data/lib/zip/stdrubyext.rb +111 -0
  193. data/lib/zip/tempfile_bugfixed.rb +195 -0
  194. data/lib/zip/zip.rb +1378 -0
  195. data/lib/zip/zipfilesystem.rb +558 -0
  196. data/lib/zip/ziprequire.rb +61 -0
  197. data/rwd_files/HowTo_Eliza.txt +195 -0
  198. data/rwd_files/HowTo_Tinker.txt +471 -0
  199. data/rwd_files/HowTo_TinkerWin2.txt +202 -0
  200. data/rwd_files/Readme.txt +57 -0
  201. data/rwd_files/RubyWebDialogs.html +6 -0
  202. data/rwd_files/favicon.ico +0 -0
  203. data/rwd_files/rdoc-style.css +175 -0
  204. data/rwd_files/rwdapplications.html +54 -0
  205. data/rwd_files/tinker.png +0 -0
  206. data/rwdconfig.dist +21 -0
  207. data/rwdeliza.rb +1 -0
  208. data/tests/RubyGauge.rb +179 -0
  209. data/tests/checkdepends.sh +4 -0
  210. data/tests/cleancnf.sh +6 -0
  211. data/tests/makedist-rwdweliza.rb +56 -0
  212. data/tests/makedist.rb +66 -0
  213. data/tests/rdep.rb +354 -0
  214. data/tests/totranslate.lang +93 -0
  215. data/zips/rwdwaddresses-1.05.zip +0 -0
  216. data/zips/rwdwcalc-0.61.zip +0 -0
  217. data/zips/rwdwgutenberg-0.09.zip +0 -0
  218. data/zips/rwdwschedule-1.04.zip +0 -0
  219. data/zips/rwdwshell-1.04.zip +0 -0
  220. data/zips/temp.rb +1 -0
  221. data/zips/wrubyslippers-1.06.zip +0 -0
  222. metadata +282 -0
@@ -0,0 +1,540 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # utils.rb - a file with general purpose utilities for the link parser system.
4
+ #
5
+ # == Synopsis
6
+ #
7
+ # require "linkparser/utils"
8
+ #
9
+ # == Rcsid
10
+ #
11
+ # $Id: utils.rb,v 1.5 2003/08/09 17:53:53 stillflame Exp $
12
+ #
13
+ # == Authors
14
+ #
15
+ # Martin Chase <stillflame@FaerieMUD.org>
16
+ #
17
+ #:include: COPYRIGHT
18
+ #
19
+ #---
20
+ #
21
+ # Please see the file COPYRIGHT for licensing details.
22
+ #
23
+
24
+
25
+ ### Some minor modifications to the base Array class.
26
+ class Array
27
+
28
+ # Returns all 'right' elements.
29
+ def right
30
+ self.find_all {|elem| elem.right?}
31
+ end
32
+
33
+ # Returns all 'left' elements.
34
+ def left
35
+ self.find_all {|elem| elem.left?}
36
+ end
37
+
38
+ # Performs combine in place
39
+ def combine!(other)
40
+ return self.replace(other) if self.empty?
41
+ return self if other.empty?
42
+ temp = self.dup
43
+ self.clear
44
+ temp.each {|mine|
45
+ other.each {|theirs|
46
+ self << mine + theirs
47
+ }
48
+ }
49
+ self
50
+ end
51
+
52
+ # Returns every possible combination of the elements in both this array and
53
+ # the supplied other array. Combinations are formed using the '+' method.
54
+ def combine(other)
55
+ return other.dup if self.empty?
56
+ return self.dup if other.empty?
57
+ temp = []
58
+ self.each {|mine|
59
+ other.each {|theirs|
60
+ temp << mine + theirs
61
+ }
62
+ }
63
+ temp
64
+ end
65
+
66
+ ### Performs '+' in place.
67
+ def add!( other )
68
+ self.replace(self + other) # not optimized.
69
+ end
70
+
71
+ ### An alias for '+' to go along with 'add!'.
72
+ alias :add :+;
73
+
74
+ ### Performs a varient on '==', similar to what would be set equality, but
75
+ ### with the extra assumption that the elements of this set are sets
76
+ ### themselves.
77
+ def set_of_sets_equal?(other)
78
+ self.set_of_sets_minus(other).empty? and other.set_of_sets_minus(self).empty?
79
+ end
80
+
81
+ ### Performs a varient on '-', similar to what would be set subtraction, but
82
+ ### with the extra assumption that the elements of this set are sets
83
+ ### themselves.
84
+ def set_of_sets_minus(other)
85
+ self.dup.set_of_sets_minus!(other)
86
+ end
87
+
88
+ ### Performs set_of_sets_minus in place.
89
+ def set_of_sets_minus!(other)
90
+ self.delete_if {|set|
91
+ other.set_include?(set)
92
+ }
93
+ end
94
+
95
+ ### Performs a varient on 'include?', only assuming that the elements of
96
+ ### both arrays are sets of objects.
97
+ def set_include?(other)
98
+ self.find {|set|
99
+ set.set_equal?(other)
100
+ }
101
+ end
102
+
103
+ ### Performs a varient on '==', similar to what would be set equality.
104
+ def set_equal?(other)
105
+ (self.minus other).empty? and (other.minus self).empty?
106
+ end
107
+
108
+ ### Like "-", but uses == instead of an id comparison.
109
+ def minus(other)
110
+ self.dup.minus!(other)
111
+ end
112
+
113
+ ### Like minus, but in place.
114
+ def minus!(other)
115
+ other.each {|bad|
116
+ self.delete_if {|elem| elem == bad}
117
+ }
118
+ self
119
+ end
120
+
121
+ ### Superimposes one array over another, overwriting non-nil values.
122
+ def superimpose(other)
123
+ self.dup.superimpose!(other)
124
+ end
125
+
126
+ ### Performs superimpose in place.
127
+ def superimpose!(other)
128
+ return self unless other.respond_to?(:[])
129
+ other.each_with_index {|o,i|
130
+ (self[i] = o) unless(self[i])
131
+ }
132
+ self
133
+ end
134
+
135
+ ### Creates the set of all the combinations of the members of this set and
136
+ ### another.
137
+ def set_combine(other)
138
+ if self.empty?
139
+ return other
140
+ elsif other.empty?
141
+ return self
142
+ else
143
+ results = []
144
+ self.each {|a|
145
+ other.each {|b|
146
+ results << a.combine(b)
147
+ }
148
+ }
149
+ return results
150
+ end
151
+ end
152
+
153
+ ### Performs set_combine in place.
154
+ def set_combine!(other)
155
+ self.replace(self.set_combine(other))
156
+ end
157
+
158
+ ### Returns whether or not the array has any elements which respond
159
+ ### positively to the provided test.
160
+ def any_pass?(test, *args)
161
+ self.find {|elem| elem.send(test, *args)}
162
+ end
163
+
164
+ ### Returns whether or not the array has any elements which respond
165
+ ### negatively to the provided test.
166
+ def any_fail?(test, *args)
167
+ self.find {|elem| ! elem.send(test, *args)}
168
+ end
169
+
170
+ ### Returns whether or not the array has no elements which respond
171
+ ### negatively to the provided test.
172
+ def all_pass?(test, *args)
173
+ self.find_all {|elem| ! elem.send(test, *args)}.empty?
174
+ end
175
+
176
+ ### Returns whether or not the array has no elements which respond
177
+ ### positively to the provided test.
178
+ def all_fail?(test, *args)
179
+ self.find_all {|elem| elem.send(test, *args)}.empty?
180
+ end
181
+
182
+ end # class Array
183
+
184
+ class LinkParser
185
+
186
+ ### An exception for parses.
187
+ class ParseError < Exception; end
188
+
189
+ end # class LinkParser
190
+
191
+
192
+ ### Minor addition to the behavior of a struct.
193
+ class Struct
194
+
195
+ ### Using either another struct or a hash, updates all the values of this
196
+ ### instance of a struct.
197
+ def update(obj)
198
+ self.members.each {|member|
199
+ self[member.to_s] = obj[member.intern] || self[member]
200
+ }
201
+ self
202
+ end
203
+
204
+ end # class Struct
205
+
206
+ # Stuff for installation usage.
207
+
208
+ BEGIN {
209
+ begin
210
+ require 'readline'
211
+ include Readline
212
+ rescue LoadError => e
213
+ $stderr.puts "Faking readline..."
214
+ def readline( prompt )
215
+ $stderr.print prompt.chomp
216
+ return $stdin.gets.chomp
217
+ end
218
+ end
219
+ }
220
+
221
+ module UtilityFunctions
222
+
223
+ # The list of regexen that eliminate files from the MANIFEST
224
+ ANTIMANIFEST = [
225
+ /makedist\.rb/,
226
+ /\bCVS\b/,
227
+ /~$/,
228
+ /^#/,
229
+ %r{docs/html},
230
+ %r{docs/man},
231
+ /^TEMPLATE/,
232
+ /\.cvsignore/,
233
+ /\.s?o$/
234
+ ]
235
+
236
+ # Set some ANSI escape code constants (Shamelessly stolen from Perl's
237
+ # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
238
+ AnsiAttributes = {
239
+ 'clear' => 0,
240
+ 'reset' => 0,
241
+ 'bold' => 1,
242
+ 'dark' => 2,
243
+ 'underline' => 4,
244
+ 'underscore' => 4,
245
+ 'blink' => 5,
246
+ 'reverse' => 7,
247
+ 'concealed' => 8,
248
+
249
+ 'black' => 30, 'on_black' => 40,
250
+ 'red' => 31, 'on_red' => 41,
251
+ 'green' => 32, 'on_green' => 42,
252
+ 'yellow' => 33, 'on_yellow' => 43,
253
+ 'blue' => 34, 'on_blue' => 44,
254
+ 'magenta' => 35, 'on_magenta' => 45,
255
+ 'cyan' => 36, 'on_cyan' => 46,
256
+ 'white' => 37, 'on_white' => 47
257
+ }
258
+
259
+ ErasePreviousLine = "\033[A\033[K"
260
+
261
+
262
+ ###############
263
+ module_function
264
+ ###############
265
+
266
+ # Create a string that contains the ANSI codes specified and return it
267
+ def ansiCode( *attributes )
268
+ attr = attributes.collect {|a| AnsiAttributes[a] ? AnsiAttributes[a] : nil}.compact.join(';')
269
+ if attr.empty?
270
+ return ''
271
+ else
272
+ return "\e[%sm" % attr
273
+ end
274
+ end
275
+
276
+ # Test for the presence of the specified <tt>library</tt>, and output a
277
+ # message describing the test using <tt>nicename</tt>. If <tt>nicename</tt>
278
+ # is <tt>nil</tt>, the value in <tt>library</tt> is used to build a default.
279
+ def testForLibrary( library, nicename=nil )
280
+ nicename ||= library
281
+ message( "Testing for the #{nicename} library..." )
282
+ if $:.detect {|dir| File.exists?(File.join(dir,"#{library}.rb")) || File.exists?(File.join(dir,"#{library}.so"))}
283
+ message( "found.\n" )
284
+ return true
285
+ else
286
+ message( "not found.\n" )
287
+ return false
288
+ end
289
+ end
290
+
291
+ # Test for the presence of the specified <tt>library</tt>, and output a
292
+ # message describing the problem using <tt>nicename</tt>. If
293
+ # <tt>nicename</tt> is <tt>nil</tt>, the value in <tt>library</tt> is used
294
+ # to build a default. If <tt>raaUrl</tt> and/or <tt>downloadUrl</tt> are
295
+ # specified, they are also use to build a message describing how to find the
296
+ # required library. If <tt>fatal</tt> is <tt>true</tt>, a missing library
297
+ # will cause the program to abort.
298
+ def testForRequiredLibrary( library, nicename=nil, raaUrl=nil, downloadUrl=nil, fatal=true )
299
+ nicename ||= library
300
+ unless testForLibrary( library, nicename )
301
+ msgs = [ "You are missing the required #{nicename} library.\n" ]
302
+ msgs << "RAA: #{raaUrl}\n" if raaUrl
303
+ msgs << "Download: #{downloadUrl}\n" if downloadUrl
304
+ if fatal
305
+ abort msgs.join('')
306
+ else
307
+ errorMessage msgs.join('')
308
+ end
309
+ end
310
+ return true
311
+ end
312
+
313
+ ### Output <tt>msg</tt> as a ANSI-colored program/section header (white on
314
+ ### blue).
315
+ def header( msg )
316
+ msg.chomp!
317
+ $stderr.puts ansiCode( 'bold', 'white', 'on_blue' ) + msg + ansiCode( 'reset' )
318
+ $stderr.flush
319
+ end
320
+
321
+ ### Output <tt>msg</tt> to STDERR and flush it.
322
+ def message( msg )
323
+ $stderr.print msg
324
+ $stderr.flush
325
+ end
326
+
327
+ ### Output the specified <tt>msg</tt> as an ANSI-colored error message
328
+ ### (white on red).
329
+ def errorMessage( msg )
330
+ message ansiCode( 'bold', 'white', 'on_red' ) + msg + ansiCode( 'reset' )
331
+ end
332
+
333
+ ### Output the specified <tt>msg</tt> as an ANSI-colored debugging message
334
+ ### (yellow on blue).
335
+ def debugMsg( msg )
336
+ return unless $DEBUG
337
+ msg.chomp!
338
+ $stderr.puts ansiCode( 'bold', 'yellow', 'on_blue' ) + ">>> #{msg}" + ansiCode( 'reset' )
339
+ $stderr.flush
340
+ end
341
+
342
+ ### Erase the previous line (if supported by your terminal) and output the
343
+ ### specified <tt>msg</tt> instead.
344
+ def replaceMessage( msg )
345
+ print ErasePreviousLine
346
+ message( msg )
347
+ end
348
+
349
+ ### Output a divider made up of <tt>length</tt> hyphen characters.
350
+ def divider( length=75 )
351
+ puts "\r" + ("-" * length )
352
+ end
353
+ alias :writeLine :divider
354
+
355
+ ### Output the specified <tt>msg</tt> colored in ANSI red and exit with a
356
+ ### status of 1.
357
+ def abort( msg )
358
+ print ansiCode( 'bold', 'red' ) + "Aborted: " + msg.chomp + ansiCode( 'reset' ) + "\n\n"
359
+ Kernel.exit!( 1 )
360
+ end
361
+
362
+ ### Output the specified <tt>promptString</tt> as a prompt (in green) and
363
+ ### return the user's input with leading and trailing spaces removed.
364
+ def prompt( promptString )
365
+ promptString.chomp!
366
+ return readline( ansiCode('bold', 'green') + "#{promptString}: " + ansiCode('reset') ).strip
367
+ end
368
+
369
+ ### Prompt the user with the given <tt>promptString</tt> via #prompt,
370
+ ### substituting the given <tt>default</tt> if the user doesn't input
371
+ ### anything.
372
+ def promptWithDefault( promptString, default )
373
+ response = prompt( "%s [%s]" % [ promptString, default ] )
374
+ if response.empty?
375
+ return default
376
+ else
377
+ return response
378
+ end
379
+ end
380
+
381
+ ### Search for the program specified by the given <tt>progname</tt> in the
382
+ ### user's <tt>PATH</tt>, and return the full path to it, or <tt>nil</tt> if
383
+ ### no such program is in the path.
384
+ def findProgram( progname )
385
+ ENV['PATH'].split(File::PATH_SEPARATOR).each {|d|
386
+ file = File.join( d, progname )
387
+ return file if File.executable?( file )
388
+ }
389
+ return nil
390
+ end
391
+
392
+ ### Using the CVS log for the given <tt>file</tt> attempt to guess what the
393
+ ### next release version might be. This only works if releases are tagged
394
+ ### with tags like 'RELEASE_x_y'.
395
+ def extractNextVersionFromTags( file )
396
+ message "Attempting to extract next release version from CVS tags for #{file}...\n"
397
+ raise RuntimeError, "No such file '#{file}'" unless File.exists?( file )
398
+ cvsPath = findProgram( 'cvs' ) or
399
+ raise RuntimeError, "Cannot find the 'cvs' program. Aborting."
400
+
401
+ output = %x{#{cvsPath} log #{file}}
402
+ release = [ 0, 0 ]
403
+ output.scan( /RELEASE_(\d+)_(\d+)/ ) {|match|
404
+ if $1.to_i > release[0] || $2.to_i > release[1]
405
+ release = [ $1.to_i, $2.to_i ]
406
+ replaceMessage( "Found %d.%02d...\n" % release )
407
+ end
408
+ }
409
+
410
+ if release[1] >= 99
411
+ release[0] += 1
412
+ release[1] = 1
413
+ else
414
+ release[1] += 1
415
+ end
416
+
417
+ return "%d.%02d" % release
418
+ end
419
+
420
+ ### Extract the project name (CVS Repository name) for the given directory.
421
+ def extractProjectName
422
+ File.open( "CVS/Repository", "r").readline.chomp
423
+ end
424
+
425
+ ### Read the specified <tt>manifestFile</tt>, which is a text file
426
+ ### describing which files to package up for a distribution. The manifest
427
+ ### should consist of one or more lines, each containing one filename or
428
+ ### shell glob pattern.
429
+ def readManifest( manifestFile="MANIFEST" )
430
+ message "Building manifest..."
431
+ raise "Missing #{manifestFile}, please remake it" unless File.exists? manifestFile
432
+
433
+ manifest = IO::readlines( manifestFile ).collect {|line|
434
+ line.chomp
435
+ }.select {|line|
436
+ line !~ /^(\s*(#.*)?)?$/
437
+ }
438
+
439
+ filelist = []
440
+ for pat in manifest
441
+ $stderr.puts "Adding files that match '#{pat}' to the file list" if $VERBOSE
442
+ filelist |= Dir.glob( pat ).find_all {|f| FileTest.file?(f)}
443
+ end
444
+
445
+ message "found #{filelist.length} files.\n"
446
+ return filelist
447
+ end
448
+
449
+ ### Given a <tt>filelist</tt> like that returned by #readManifest, remove
450
+ ### the entries therein which match the Regexp objects in the given
451
+ ### <tt>antimanifest</tt> and return the resultant Array.
452
+ def vetManifest( filelist, antimanifest=ANITMANIFEST )
453
+ origLength = filelist.length
454
+ message "Vetting manifest..."
455
+
456
+ for regex in antimanifest
457
+ if $VERBOSE
458
+ message "\n\tPattern /#{regex.source}/ removed: " +
459
+ filelist.find_all {|file| regex.match(file)}.join(', ')
460
+ end
461
+ filelist.delete_if {|file| regex.match(file)}
462
+ end
463
+
464
+ message "removed #{origLength - filelist.length} files from the list.\n"
465
+ return filelist
466
+ end
467
+
468
+ ### Combine a call to #readManifest with one to #vetManifest.
469
+ def getVettedManifest( manifestFile="MANIFEST", antimanifest=ANTIMANIFEST )
470
+ vetManifest( readManifest(manifestFile), antimanifest )
471
+ end
472
+
473
+ ### Given a documentation <tt>catalogFile</tt>, which is in the same format
474
+ ### as that described by #readManifest, read and expand it, and then return
475
+ ### a list of those files which appear to have RDoc documentation in
476
+ ### them. If <tt>catalogFile</tt> is nil or does not exist, the MANIFEST
477
+ ### file is used instead.
478
+ def findRdocableFiles( catalogFile="docs/CATALOG" )
479
+ startlist = []
480
+ if File.exists? catalogFile
481
+ message "Using CATALOG file (%s).\n" % catalogFile
482
+ startlist = getVettedManifest( catalogFile )
483
+ else
484
+ message "Using default MANIFEST\n"
485
+ startlist = getVettedManifest()
486
+ end
487
+
488
+ message "Looking for RDoc comments in:\n" if $VERBOSE
489
+ startlist.select {|fn|
490
+ message " #{fn}: " if $VERBOSE
491
+ found = false
492
+ File::open( fn, "r" ) {|fh|
493
+ fh.each {|line|
494
+ if line =~ /^(\s*#)?\s*=/ || line =~ /:\w+:/ || line =~ %r{/\*}
495
+ found = true
496
+ break
497
+ end
498
+ }
499
+ }
500
+
501
+ message( (found ? "yes" : "no") + "\n" ) if $VERBOSE
502
+ found
503
+ }
504
+ end
505
+
506
+ ### Open a file and filter each of its lines through the given block a
507
+ ### <tt>line</tt> at a time. The return value of the block is used as the
508
+ ### new line, or omitted if the block returns <tt>nil</tt> or
509
+ ### <tt>false</tt>.
510
+ def editInPlace( file ) # :yields: line
511
+ raise "No block specified for editing operation" unless block_given?
512
+
513
+ tempName = "#{file}.#{$$}"
514
+ File::open( tempName, File::RDWR|File::CREAT, 0600 ) {|tempfile|
515
+ File::unlink( tempName )
516
+ File::open( file, File::RDONLY ) {|fh|
517
+ fh.each {|line|
518
+ newline = yield( line ) or next
519
+ tempfile.print( newline )
520
+ }
521
+ }
522
+
523
+ tempfile.seek(0)
524
+
525
+ File::open( file, File::TRUNC|File::WRONLY, 0644 ) {|newfile|
526
+ newfile.print( tempfile.read )
527
+ }
528
+ }
529
+ end
530
+
531
+ ### Execute the specified shell <tt>command</tt>, read the results, and
532
+ ### return them. Like a %x{} that returns an Array instead of a String.
533
+ def shellCommand( *command )
534
+ raise "Empty command" if command.empty?
535
+
536
+ cmdpipe = IO::popen( command.join(' '), 'r' )
537
+ return cmdpipe.readlines
538
+ end
539
+
540
+ end