wordnet 0.0.5 → 1.0.0.pre.126

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gemtest +0 -0
  2. data/History.rdoc +5 -0
  3. data/LICENSE +9 -9
  4. data/Manifest.txt +39 -0
  5. data/README.rdoc +60 -0
  6. data/Rakefile +47 -267
  7. data/TODO +9 -0
  8. data/WordNet30-license.txt +31 -0
  9. data/examples/add-laced-boots.rb +35 -0
  10. data/examples/clothes-with-collars.rb +42 -0
  11. data/examples/clothesWithTongues.rb +0 -0
  12. data/examples/domainTree.rb +0 -0
  13. data/examples/memberTree.rb +0 -0
  14. data/lib/wordnet/constants.rb +259 -296
  15. data/lib/wordnet/lexicallink.rb +34 -0
  16. data/lib/wordnet/lexicon.rb +158 -386
  17. data/lib/wordnet/mixins.rb +62 -0
  18. data/lib/wordnet/model.rb +78 -0
  19. data/lib/wordnet/morph.rb +25 -0
  20. data/lib/wordnet/semanticlink.rb +52 -0
  21. data/lib/wordnet/sense.rb +55 -0
  22. data/lib/wordnet/sumoterm.rb +21 -0
  23. data/lib/wordnet/synset.rb +404 -859
  24. data/lib/wordnet/utils.rb +126 -0
  25. data/lib/wordnet/word.rb +119 -0
  26. data/lib/wordnet.rb +113 -76
  27. data/spec/lib/helpers.rb +102 -133
  28. data/spec/linguawordnet.tests.rb +38 -0
  29. data/spec/wordnet/lexicon_spec.rb +96 -186
  30. data/spec/wordnet/model_spec.rb +59 -0
  31. data/spec/wordnet/semanticlink_spec.rb +42 -0
  32. data/spec/wordnet/synset_spec.rb +27 -256
  33. data/spec/wordnet/word_spec.rb +58 -0
  34. data/spec/wordnet_spec.rb +52 -0
  35. data.tar.gz.sig +0 -0
  36. metadata +227 -188
  37. metadata.gz.sig +0 -0
  38. data/ChangeLog +0 -720
  39. data/README +0 -93
  40. data/Rakefile.local +0 -46
  41. data/convertdb.rb +0 -417
  42. data/examples/addLacedBoots.rb +0 -27
  43. data/examples/clothesWithCollars.rb +0 -36
  44. data/rake/dependencies.rb +0 -76
  45. data/rake/helpers.rb +0 -384
  46. data/rake/manual.rb +0 -755
  47. data/rake/packaging.rb +0 -112
  48. data/rake/publishing.rb +0 -303
  49. data/rake/rdoc.rb +0 -35
  50. data/rake/style.rb +0 -62
  51. data/rake/svn.rb +0 -469
  52. data/rake/testing.rb +0 -192
  53. data/rake/verifytask.rb +0 -64
  54. data/utils.rb +0 -838
data/utils.rb DELETED
@@ -1,838 +0,0 @@
1
- #
2
- # Install/distribution utility functions
3
- # $Id: utils.rb 94 2008-07-25 02:47:42Z deveiant $
4
- #
5
- # Copyright (c) 2001-2008, The FaerieMUD Consortium.
6
- #
7
- # All rights reserved.
8
- #
9
- # Redistribution and use in source and binary forms, with or without modification, are
10
- # permitted provided that the following conditions are met:
11
- #
12
- # * Redistributions of source code must retain the above copyright notice, this
13
- # list of conditions and the following disclaimer.
14
- #
15
- # * Redistributions in binary form must reproduce the above copyright notice, this
16
- # list of conditions and the following disclaimer in the documentation and/or
17
- # other materials provided with the distribution.
18
- #
19
- # * Neither the name of FaerieMUD, nor the names of its contributors may be used to
20
- # endorse or promote products derived from this software without specific prior
21
- # written permission.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27
- # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
- # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- #
35
-
36
-
37
- BEGIN {
38
- require 'pathname'
39
- require 'rbconfig'
40
- require 'uri'
41
- require 'find'
42
- require 'pp'
43
- require 'irb'
44
-
45
- begin
46
- require 'readline'
47
- include Readline
48
- rescue LoadError => e
49
- $stderr.puts "Faking readline..."
50
- def readline( prompt )
51
- $stderr.print prompt.chomp
52
- return $stdin.gets.chomp
53
- end
54
- end
55
-
56
- }
57
-
58
-
59
- ### Command-line utility functions
60
- module UtilityFunctions
61
- include Config
62
-
63
- # The list of regexen that eliminate files from the MANIFEST
64
- ANTIMANIFEST = [
65
- /makedist\.rb/,
66
- /\bCVS\b/,
67
- /~$/,
68
- /^#/,
69
- %r{docs/html},
70
- %r{docs/man},
71
- /\bTEMPLATE\.\w+\.tpl\b/,
72
- /\.cvsignore/,
73
- /\.s?o$/,
74
- ]
75
-
76
- # Set some ANSI escape code constants (Shamelessly stolen from Perl's
77
- # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
78
- AnsiAttributes = {
79
- 'clear' => 0,
80
- 'reset' => 0,
81
- 'bold' => 1,
82
- 'dark' => 2,
83
- 'underline' => 4,
84
- 'underscore' => 4,
85
- 'blink' => 5,
86
- 'reverse' => 7,
87
- 'concealed' => 8,
88
-
89
- 'black' => 30, 'on_black' => 40,
90
- 'red' => 31, 'on_red' => 41,
91
- 'green' => 32, 'on_green' => 42,
92
- 'yellow' => 33, 'on_yellow' => 43,
93
- 'blue' => 34, 'on_blue' => 44,
94
- 'magenta' => 35, 'on_magenta' => 45,
95
- 'cyan' => 36, 'on_cyan' => 46,
96
- 'white' => 37, 'on_white' => 47
97
- }
98
-
99
- ErasePreviousLine = "\033[A\033[K"
100
-
101
- ManifestHeader = (<<-"EOF").gsub( /^\t+/, '' )
102
- #
103
- # Distribution Manifest
104
- # Created: #{Time::now.to_s}
105
- #
106
-
107
- EOF
108
-
109
- # A cache of programs found by find_program()
110
- Programs = {}
111
-
112
-
113
- ###############
114
- module_function
115
- ###############
116
-
117
- # Create a string that contains the ANSI codes specified and return it
118
- def ansi_code( *attributes )
119
- attributes.flatten!
120
- # $stderr.puts "Returning ansicode for TERM = %p: %p" %
121
- # [ ENV['TERM'], attributes ]
122
- return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
123
- attributes = AnsiAttributes.values_at( *attributes ).compact.join(';')
124
-
125
- # $stderr.puts " attr is: %p" % [attributes]
126
- if attributes.empty?
127
- return ''
128
- else
129
- return "\e[%sm" % attributes
130
- end
131
- end
132
-
133
-
134
- ### Colorize the given +string+ with the specified +attributes+ and return it, handling line-endings, etc.
135
- def colorize( string, *attributes )
136
- ending = string[/(\s)$/] || ''
137
- string = string.rstrip
138
- return ansi_code( attributes.flatten ) + string + ansi_code( 'reset' ) + ending
139
- end
140
-
141
-
142
- # Test for the presence of the specified <tt>library</tt>, and output a
143
- # message describing the test using <tt>nicename</tt>. If <tt>nicename</tt>
144
- # is <tt>nil</tt>, the value in <tt>library</tt> is used to build a default.
145
- def test_for_library( library, nicename=nil, progress=false )
146
- nicename ||= library
147
- message( "Testing for the #{nicename} library..." ) if progress
148
- if $LOAD_PATH.detect {|dir|
149
- File.exists?(File.join(dir,"#{library}.rb")) ||
150
- File.exists?(File.join(dir,"#{library}.#{CONFIG['DLEXT']}"))
151
- }
152
- message( "found.\n" ) if progress
153
- return true
154
- else
155
- message( "not found.\n" ) if progress
156
- return false
157
- end
158
- end
159
-
160
-
161
- # Test for the presence of the specified <tt>library</tt>, and output a
162
- # message describing the problem using <tt>nicename</tt>. If
163
- # <tt>nicename</tt> is <tt>nil</tt>, the value in <tt>library</tt> is used
164
- # to build a default. If <tt>raa_url</tt> and/or <tt>download_url</tt> are
165
- # specified, they are also use to build a message describing how to find the
166
- # required library. If <tt>fatal</tt> is <tt>true</tt>, a missing library
167
- # will cause the program to abort.
168
- def test_for_required_library( library, nicename=nil, raa_url=nil, download_url=nil, fatal=true )
169
- nicename ||= library
170
- unless test_for_library( library, nicename )
171
- msgs = [ "You are missing the required #{nicename} library.\n" ]
172
- msgs << "RAA: #{raa_url}\n" if raa_url
173
- msgs << "Download: #{download_url}\n" if download_url
174
- if fatal
175
- abort msgs.join('')
176
- else
177
- error_message msgs.join('')
178
- end
179
- end
180
- return true
181
- end
182
-
183
-
184
- ### Output <tt>msg</tt> as a ANSI-colored program/section header (white on
185
- ### blue).
186
- def header( msg )
187
- msg.chomp!
188
- $stderr.puts ansi_code( 'bold', 'white', 'on_blue' ) + msg + ansi_code( 'reset' )
189
- $stderr.flush
190
- end
191
-
192
-
193
- ### Output <tt>msg</tt> to STDERR and flush it.
194
- def message( *msgs )
195
- $stderr.print( msgs.join("\n") )
196
- $stderr.flush
197
- end
198
-
199
-
200
- ### Output +msg+ to STDERR and flush it if $VERBOSE is true.
201
- def verbose_msg( msg )
202
- msg.chomp!
203
- message( msg + "\n" ) if $VERBOSE
204
- end
205
-
206
-
207
- ### Output the specified <tt>msg</tt> as an ANSI-colored error message
208
- ### (white on red).
209
- def error_msg( msg )
210
- message ansi_code( 'bold', 'white', 'on_red' ) + msg + ansi_code( 'reset' )
211
- end
212
- alias :error_message :error_msg
213
-
214
-
215
- ### Output the specified <tt>msg</tt> as an ANSI-colored debugging message
216
- ### (yellow on blue).
217
- def debug_msg( msg )
218
- return unless $DEBUG
219
- msg.chomp!
220
- $stderr.puts ansi_code( 'bold', 'yellow', 'on_blue' ) + ">>> #{msg}" + ansi_code( 'reset' )
221
- $stderr.flush
222
- end
223
-
224
-
225
- ### Erase the previous line (if supported by your terminal) and output the
226
- ### specified <tt>msg</tt> instead.
227
- def replace_msg( msg )
228
- $stderr.puts
229
- $stderr.print ErasePreviousLine
230
- message( msg )
231
- end
232
- alias :replace_message :replace_msg
233
-
234
-
235
- ### Output a divider made up of <tt>length</tt> hyphen characters.
236
- def divider( length=75 )
237
- $stderr.puts "\r" + ("-" * length )
238
- end
239
- alias :write_line :divider
240
-
241
-
242
- ### Output the specified <tt>msg</tt> colored in ANSI red and exit with a
243
- ### status of 1.
244
- def abort( msg )
245
- print ansi_code( 'bold', 'red' ) + "Aborted: " + msg.chomp + ansi_code( 'reset' ) + "\n\n"
246
- Kernel.exit!( 1 )
247
- end
248
-
249
-
250
- ### Output the specified <tt>prompt_string</tt> as a prompt (in green) and
251
- ### return the user's input with leading and trailing spaces removed. If a
252
- ### test is provided, the prompt will repeat until the test returns true.
253
- ### An optional failure message can also be passed in.
254
- def prompt( prompt_string, failure_msg="Try again." ) # :yields: response
255
- prompt_string.chomp!
256
- prompt_string << ":" unless /\W$/.match( prompt_string )
257
- response = nil
258
-
259
- begin
260
- response = readline( ansi_code('bold', 'green') +
261
- "#{prompt_string} " + ansi_code('reset') ) || ''
262
- response.strip!
263
- if block_given? && ! yield( response )
264
- error_message( failure_msg + "\n\n" )
265
- response = nil
266
- end
267
- end until response
268
-
269
- return response
270
- end
271
-
272
-
273
- ### Prompt the user with the given <tt>prompt_string</tt> via #prompt,
274
- ### substituting the given <tt>default</tt> if the user doesn't input
275
- ### anything. If a test is provided, the prompt will repeat until the test
276
- ### returns true. An optional failure message can also be passed in.
277
- def prompt_with_default( prompt_string, default, failure_msg="Try again." )
278
- response = nil
279
-
280
- begin
281
- response = prompt( "%s [%s]" % [ prompt_string, default ] )
282
- response = default if response.empty?
283
-
284
- if block_given? && ! yield( response )
285
- error_message( failure_msg + "\n\n" )
286
- response = nil
287
- end
288
- end until response
289
-
290
- return response
291
- end
292
-
293
-
294
- ### Display a description of a potentially-dangerous task, and prompt
295
- ### for confirmation. If the user answers with anything that begins
296
- ### with 'y', yield to the block, else raise with an error.
297
- def ask_for_confirmation( description )
298
- puts description
299
-
300
- answer = prompt_with_default( "Continue?", 'n' ) do |input|
301
- input =~ /^[yn]/i
302
- end
303
-
304
- case answer
305
- when /^y/i
306
- yield
307
- else
308
- error "Aborted."
309
- fail
310
- end
311
- end
312
-
313
-
314
- ### Search for the program specified by the given <tt>progname</tt> in the
315
- ### user's <tt>PATH</tt>, and return the full path to it, or <tt>nil</tt> if
316
- ### no such program is in the path.
317
- def find_program( progname )
318
- unless Programs.key?( progname )
319
- ENV['PATH'].split(File::PATH_SEPARATOR).
320
- collect {|dir| Pathnanme.new(dir) }.each do |dir|
321
- file = dir + progname
322
- if file.executable?
323
- Programs[ progname ] = file
324
- break
325
- end
326
- end
327
- end
328
-
329
- return Programs[ progname ].to_s
330
- end
331
-
332
-
333
- ### Search for the release version for the project in the specified
334
- ### +directory+ using tags named "RELEASE_<major>_<minor>" if it's a CVS project
335
- ### or the 'project-version' metadata value of the toplevel directory if it's
336
- ### a Subversion project.
337
- def extract_version( directory='.' )
338
- release = nil
339
-
340
- Dir::chdir( directory ) do
341
- if File::directory?( "CVS" )
342
- verbose_msg( "Project is versioned via CVS. Searching for RELEASE_*_* tags..." )
343
-
344
- if (( cvs = find_program('cvs') ))
345
- revs = []
346
- output = %x{cvs log}
347
- output.scan( /RELEASE_(\d+(?:_\d\w+)*)/ ) {|match|
348
- rev = $1.split(/_/).collect {|s| Integer(s) rescue 0}
349
- verbose_msg( "Found %s...\n" % rev.join('.') )
350
- revs << rev
351
- }
352
-
353
- release = revs.sort.last
354
- end
355
-
356
- elsif File::directory?( '.svn' )
357
- verbose_msg( "Project is versioned via Subversion" )
358
-
359
- if (( svn = find_program('svn') ))
360
- output = %x{svn pg project-version}.chomp
361
- unless output.empty?
362
- verbose_msg( "Using 'project-version' property: %p" % output )
363
- release = output.split( /[._]/ ).collect {|s| Integer(s) rescue 0}
364
- end
365
- end
366
- end
367
- end
368
-
369
- return release
370
- end
371
-
372
-
373
- ### Find the current release version for the project in the specified
374
- ### +directory+ and return its successor.
375
- def extract_next_version( directory='.' )
376
- version = extract_version( directory ) || [0,0,0]
377
- version.compact!
378
- version[-1] += 1
379
-
380
- return version
381
- end
382
-
383
-
384
- # Pattern for extracting the name of the project from a Subversion URL
385
- SVNUrlPath = %r{
386
- .*/ # Skip all but the last bit
387
- ([^/]+) # $1 = project name
388
- / # Followed by / +
389
- (?:
390
- trunk | # 'trunk'
391
- (
392
- branches | # ...or branches/branch-name
393
- tags # ...or tags/tag-name
394
- )/\w
395
- )
396
- $ # bound to the end
397
- }ix
398
-
399
- ### Extract the project name for the given +directory+. The project name is
400
- ### the repository name if it's versioned with CVS, set via the 'project-name'
401
- ### metadata value if versioned with Subversion, or just based on the name of the
402
- ### directory itself if it's not versioned with one of those two systems.
403
- def extract_project_name( directory='.' )
404
- name = nil
405
-
406
- Dir::chdir( directory ) do
407
-
408
- # CVS-controlled
409
- if File::directory?( "CVS" )
410
- verbose_msg( "Project is versioned via CVS. Using repository name." )
411
- name = File.open( "CVS/Repository", "r").readline.chomp
412
- name.sub!( %r{.*/}, '' )
413
-
414
- # Subversion-controlled
415
- elsif File::directory?( '.svn' )
416
- verbose_msg( "Project is versioned via Subversion" )
417
-
418
- # If the machine has the svn tool, try to get the project name
419
- if (( svn = find_program( 'svn' ) ))
420
-
421
- # First try an explicit property
422
- output = shell_command( svn, 'pg', 'project-name' )
423
- if !output.empty?
424
- verbose_msg( "Using 'project-name' property: %p" % output )
425
- name = output.first.chomp
426
-
427
- # If that doesn't work, try to figure it out from the URL
428
- elsif (( uri = get_svn_uri() ))
429
- name = uri.path.sub( SVNUrlPath ) { $1 }
430
- end
431
- end
432
- end
433
-
434
- # Fall back to guessing based on the directory name
435
- unless name
436
- name = File::basename(File::dirname( File::expand_path(__FILE__) ))
437
- end
438
- end
439
-
440
- return name
441
- end
442
-
443
-
444
- ### Extract the Subversion URL from the specified directory and return it as
445
- ### a URI object.
446
- def get_svn_uri( directory='.' )
447
- uri = nil
448
-
449
- Dir::chdir( directory ) do
450
- output = %x{svn info}
451
- debug_msg( "Using info: %p" % output )
452
-
453
- if /^URL: \s* ( .* )/xi.match( output )
454
- uri = URI::parse( $1 )
455
- end
456
- end
457
-
458
- return uri
459
- end
460
-
461
-
462
- ### (Re)make a manifest file in the specified +path+.
463
- def make_manifest( path="MANIFEST" )
464
- if File::exists?( path )
465
- reply = prompt_with_default( "Replace current '#{path}'? [yN]", "n" )
466
- return false unless /^y/i.match( reply )
467
-
468
- verbose_msg "Replacing manifest at '#{path}'"
469
- else
470
- verbose_msg "Creating new manifest at '#{path}'"
471
- end
472
-
473
- files = []
474
- verbose_msg( "Finding files...\n" )
475
- Find::find( Dir::pwd ) do |f|
476
- Find::prune if File::directory?( f ) &&
477
- /^\./.match( File::basename(f) )
478
- verbose_msg( " found: #{f}\n" )
479
- files << f.sub( %r{^#{Dir::pwd}/?}, '' )
480
- end
481
- files = vet_manifest( files )
482
-
483
- verbose_msg( "Writing new manifest to #{path}..." )
484
- File::open( path, File::WRONLY|File::CREAT|File::TRUNC ) do |ofh|
485
- ofh.puts( ManifestHeader )
486
- ofh.puts( files )
487
- end
488
- verbose_msg( "done." )
489
- end
490
-
491
-
492
- ### Read the specified <tt>manifest_file</tt>, which is a text file
493
- ### describing which files to package up for a distribution. The manifest
494
- ### should consist of one or more lines, each containing one filename or
495
- ### shell glob pattern.
496
- def read_manifest( manifest_file="MANIFEST" )
497
- verbose_msg "Building manifest..."
498
- raise "Missing #{manifest_file}, please remake it" unless File.exists? manifest_file
499
-
500
- manifest = IO::readlines( manifest_file ).collect {|line|
501
- line.chomp
502
- }.select {|line|
503
- line !~ /^(\s*(#.*)?)?$/
504
- }
505
-
506
- filelist = []
507
- for pat in manifest
508
- verbose_msg "Adding files that match '#{pat}' to the file list"
509
- filelist |= Dir.glob( pat ).find_all {|f| FileTest.file?(f)}
510
- end
511
-
512
- verbose_msg "found #{filelist.length} files.\n"
513
- return filelist
514
- end
515
-
516
-
517
- ### Given a <tt>filelist</tt> like that returned by #read_manifest, remove
518
- ### the entries therein which match the Regexp objects in the given
519
- ### <tt>antimanifest</tt> and return the resultant Array.
520
- def vet_manifest( filelist, antimanifest=ANTIMANIFEST )
521
- orig_length = filelist.length
522
- verbose_msg "Vetting manifest..."
523
-
524
- for regex in antimanifest
525
- verbose_msg "\n\tPattern /#{regex.source}/ removed: " +
526
- filelist.find_all {|file| regex.match(file)}.join(', ')
527
- filelist.delete_if {|file| regex.match(file)}
528
- end
529
-
530
- verbose_msg "removed #{orig_length - filelist.length} files from the list.\n"
531
- return filelist
532
- end
533
-
534
-
535
- ### Combine a call to #read_manifest with one to #vet_manifest.
536
- def get_vetted_manifest( manifest_file="MANIFEST", antimanifest=ANTIMANIFEST )
537
- vet_manifest( read_manifest(manifest_file), antimanifest )
538
- end
539
-
540
-
541
- ### Given a documentation <tt>catalog_file</tt>, extract the title, if
542
- ### available, and return it. Otherwise generate a title from the name of
543
- ### the CVS module.
544
- def find_rdoc_title( catalog_file="docs/CATALOG" )
545
-
546
- # Try extracting it from the CATALOG file from a line that looks like:
547
- # Title: Foo Bar Module
548
- title = find_catalog_keyword( 'title', catalog_file )
549
-
550
- # If that doesn't work for some reason, use the name of the project.
551
- title = extract_project_name()
552
-
553
- return title
554
- end
555
-
556
-
557
- ### Given a documentation <tt>catalog_file</tt>, extract the name of the file
558
- ### to use as the initally displayed page. If extraction fails, the
559
- ### +default+ will be used if it exists. Returns +nil+ if there is no main
560
- ### file to be found.
561
- def find_rdoc_main( catalog_file="docs/CATALOG", default="README" )
562
-
563
- # Try extracting it from the CATALOG file from a line that looks like:
564
- # Main: Foo Bar Module
565
- main = find_catalog_keyword( 'main', catalog_file )
566
-
567
- # Try to make some educated guesses if that doesn't work
568
- if main.nil?
569
- basedir = File::dirname( __FILE__ )
570
- basedir = File::dirname( basedir ) if /docs$/ =~ basedir
571
-
572
- if File::exists?( File::join(basedir, default) )
573
- main = default
574
- end
575
- end
576
-
577
- return main
578
- end
579
-
580
-
581
- ### Given a documentation <tt>catalog_file</tt>, extract an upload URL for
582
- ### RDoc.
583
- def find_rdoc_upload( catalog_file="docs/CATALOG" )
584
- find_catalog_keyword( 'upload', catalog_file )
585
- end
586
-
587
-
588
- ### Given a documentation <tt>catalog_file</tt>, extract a CVS web frontend
589
- ### URL for RDoc.
590
- def find_rdoc_cvs_url( catalog_file="docs/CATALOG" )
591
- find_catalog_keyword( 'webcvs', catalog_file )
592
- end
593
-
594
-
595
- ### Find one or more 'accessor' directives in the catalog if they exist and
596
- ### return an Array of them.
597
- def find_rdoc_accessors( catalog_file="docs/CATALOG" )
598
- accessors = []
599
- in_attr_section = false
600
- indent = ''
601
-
602
- if File::exists?( catalog_file )
603
- verbose_msg "Extracting accessors from CATALOG file (%s).\n" % catalog_file
604
-
605
- # Read lines from the catalog
606
- File::foreach( catalog_file ) do |line|
607
- debug_msg( " Examining line #{line.inspect}..." )
608
-
609
- # Multi-line accessors
610
- if in_attr_section
611
- if /^#\s+([a-z0-9_]+(?:\s*=\s*.*)?)$/i.match( line )
612
- debug_msg( " Found accessor: #$1" )
613
- accessors << $1
614
- next
615
- end
616
-
617
- debug_msg( " End of accessors section." )
618
- in_attr_section = false
619
-
620
- # Single-line accessor
621
- elsif /^#\s*Accessors:\s*(\S+)$/i.match( line )
622
- debug_msg( " Found single accessors line: #$1" )
623
- vals = $1.split(/,/).collect {|val| val.strip }
624
- accessors.replace( vals )
625
-
626
- # Multi-line accessor header
627
- elsif /^#\s*Accessors:\s*$/i.match( line )
628
- debug_msg( " Start of accessors section." )
629
- in_attr_section = true
630
- end
631
-
632
- end
633
- end
634
-
635
- debug_msg( "Found accessors: %s" % accessors.join(",") )
636
- return accessors
637
- end
638
-
639
-
640
- ### Given a documentation <tt>catalog_file</tt>, try extracting the given
641
- ### +keyword+'s value from it. Keywords are lines that look like:
642
- ### # <keyword>: <value>
643
- ### Returns +nil+ if the catalog file was unreadable or didn't contain the
644
- ### specified +keyword+.
645
- def find_catalog_keyword( keyword, catalog_file="docs/CATALOG" )
646
- val = nil
647
-
648
- if File::exists? catalog_file
649
- verbose_msg "Extracting '#{keyword}' from CATALOG file (%s).\n" % catalog_file
650
- File::foreach( catalog_file ) do |line|
651
- debug_msg( "Examining line #{line.inspect}..." )
652
- val = $1.strip and break if /^#\s*#{keyword}:\s*(.*)$/i.match( line )
653
- end
654
- end
655
-
656
- return val
657
- end
658
-
659
-
660
- ### Given a documentation <tt>catalog_file</tt>, which is in the same format
661
- ### as that described by #read_manifest, read and expand it, and then return
662
- ### a list of those files which appear to have RDoc documentation in
663
- ### them. If <tt>catalog_file</tt> is nil or does not exist, the MANIFEST
664
- ### file is used instead.
665
- def find_rdocable_files( catalog_file="docs/CATALOG" )
666
- startlist = []
667
- if File.exists? catalog_file
668
- verbose_msg "Using CATALOG file (%s).\n" % catalog_file
669
- startlist = get_vetted_manifest( catalog_file )
670
- else
671
- verbose_msg "Using default MANIFEST\n"
672
- startlist = get_vetted_manifest()
673
- end
674
-
675
- verbose_msg "Looking for RDoc comments in:\n"
676
- startlist.select {|fn|
677
- verbose_msg " #{fn}: "
678
- found = false
679
- File::open( fn, "r" ) {|fh|
680
- fh.each {|line|
681
- if line =~ /^(\s*#)?\s*=/ || line =~ /:\w+:/ || line =~ %r{/\*}
682
- found = true
683
- break
684
- end
685
- }
686
- }
687
-
688
- verbose_msg( (found ? "yes" : "no") + "\n" )
689
- found
690
- }
691
- end
692
-
693
-
694
- ### Open a file and filter each of its lines through the given block a
695
- ### <tt>line</tt> at a time. The return value of the block is used as the
696
- ### new line, or omitted if the block returns <tt>nil</tt> or
697
- ### <tt>false</tt>.
698
- def edit_in_place( file, test_mode=false ) # :yields: line
699
- raise "No block specified for editing operation" unless block_given?
700
-
701
- temp_name = "#{file}.#{$$}"
702
- File::open( temp_name, File::RDWR|File::CREAT, 0600 ) do |tempfile|
703
- File::open( file, File::RDONLY ) do |fh|
704
- fh.each do |line|
705
- newline = yield( line ) or next
706
- tempfile.print( newline )
707
- $stderr.puts "%p -> %p" % [ line, newline ] if
708
- line != newline
709
- end
710
- end
711
- end
712
-
713
- if test_mode
714
- File::unlink( temp_name )
715
- else
716
- File::rename( temp_name, file )
717
- end
718
- end
719
-
720
-
721
- ### Execute the specified shell <tt>command</tt>, read the results, and
722
- ### return them. Like a %x{} that returns an Array instead of a String.
723
- def shell_command( *command )
724
- raise "Empty command" if command.empty?
725
-
726
- cmdpipe = IO::open( '|-' ) or exec( *command )
727
- return cmdpipe.readlines
728
- end
729
-
730
-
731
- ### Execute a block with $VERBOSE set to +false+, restoring it to its
732
- ### previous value before returning.
733
- def verbose_off
734
- raise LocalJumpError, "No block given" unless block_given?
735
-
736
- thrcrit = Thread.critical
737
- oldverbose = $VERBOSE
738
- begin
739
- Thread.critical = true
740
- $VERBOSE = false
741
- yield
742
- ensure
743
- $VERBOSE = oldverbose
744
- Thread.critical = false
745
- end
746
- end
747
-
748
-
749
- ### Try the specified code block, printing the given
750
- def try( msg, bind=TOPLEVEL_BINDING )
751
- result = ''
752
- if msg =~ /^to\s/
753
- message "Trying #{msg}...\n"
754
- else
755
- message msg + "\n"
756
- end
757
-
758
- begin
759
- rval = nil
760
- if block_given?
761
- rval = yield
762
- else
763
- file, line = caller(1)[0].split(/:/,2)
764
- rval = eval( msg, bind, file, line.to_i )
765
- end
766
-
767
- PP.pp( rval, result )
768
-
769
- rescue Exception => err
770
- if err.backtrace
771
- nicetrace = err.backtrace.delete_if {|frame|
772
- /in `(try|eval)'/ =~ frame
773
- }.join("\n\t")
774
- else
775
- nicetrace = "Exception had no backtrace"
776
- end
777
-
778
- result = err.message + "\n\t" + nicetrace
779
-
780
- ensure
781
- divider
782
- message result.chomp + "\n"
783
- divider
784
- $stderr.puts
785
- end
786
- end
787
-
788
-
789
- ### Start an IRB session with the specified binding +b+ as the current scope.
790
- def start_irb_session( b )
791
- IRB.setup(nil)
792
-
793
- workspace = IRB::WorkSpace.new( b )
794
-
795
- if IRB.conf[:SCRIPT]
796
- irb = IRB::Irb.new( workspace, IRB.conf[:SCRIPT] )
797
- else
798
- irb = IRB::Irb.new( workspace )
799
- end
800
-
801
- IRB.conf[:IRB_RC].call( irb.context ) if IRB.conf[:IRB_RC]
802
- IRB.conf[:MAIN_CONTEXT] = irb.context
803
-
804
- trap("SIGINT") do
805
- irb.signal_handle
806
- end
807
-
808
- catch(:IRB_EXIT) do
809
- irb.eval_input
810
- end
811
- end
812
-
813
- end # module UtilityFunctions
814
-
815
-
816
-
817
- if __FILE__ == $0
818
- # $DEBUG = true
819
- include UtilityFunctions
820
-
821
- projname = extract_project_name()
822
- header "Project: #{projname}"
823
-
824
- ver = extract_version() || [0,0,1]
825
- puts "Version: %s\n" % ver.join('.')
826
-
827
- if File::directory?( "docs" )
828
- puts "Rdoc:",
829
- " Title: " + find_rdoc_title(),
830
- " Main: " + find_rdoc_main(),
831
- " Upload: " + find_rdoc_upload(),
832
- " VCS URL: " + find_rdoc_cvs_url(),
833
- " Accessors: " + find_rdoc_accessors().join(",")
834
- end
835
-
836
- puts "Manifest:",
837
- " " + get_vetted_manifest().join("\n ")
838
- end