rwdeliza 0.03

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 (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