voloko-sdoc 0.1.7 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/LICENSE +21 -0
  2. data/VERSION.yml +4 -0
  3. data/lib/sdoc/generator/shtml.rb +1 -4
  4. data/lib/sdoc.rb +0 -1
  5. metadata +32 -101
  6. data/rdoc/History.txt +0 -254
  7. data/rdoc/Manifest.txt +0 -126
  8. data/rdoc/README.txt +0 -47
  9. data/rdoc/RI.txt +0 -58
  10. data/rdoc/Rakefile +0 -70
  11. data/rdoc/bin/rdoc +0 -35
  12. data/rdoc/bin/ri +0 -5
  13. data/rdoc/lib/rdoc/alias.rb +0 -54
  14. data/rdoc/lib/rdoc/anon_class.rb +0 -10
  15. data/rdoc/lib/rdoc/any_method.rb +0 -190
  16. data/rdoc/lib/rdoc/attr.rb +0 -79
  17. data/rdoc/lib/rdoc/cache.rb +0 -41
  18. data/rdoc/lib/rdoc/class_module.rb +0 -87
  19. data/rdoc/lib/rdoc/code_object.rb +0 -152
  20. data/rdoc/lib/rdoc/code_objects.rb +0 -23
  21. data/rdoc/lib/rdoc/constant.rb +0 -36
  22. data/rdoc/lib/rdoc/context.rb +0 -712
  23. data/rdoc/lib/rdoc/diagram.rb +0 -340
  24. data/rdoc/lib/rdoc/dot.rb +0 -249
  25. data/rdoc/lib/rdoc/generator/darkfish.rb +0 -455
  26. data/rdoc/lib/rdoc/generator/markup.rb +0 -194
  27. data/rdoc/lib/rdoc/generator/ri.rb +0 -230
  28. data/rdoc/lib/rdoc/generator/template/darkfish/classpage.rhtml +0 -281
  29. data/rdoc/lib/rdoc/generator/template/darkfish/filepage.rhtml +0 -112
  30. data/rdoc/lib/rdoc/generator/template/darkfish/images/brick.png +0 -0
  31. data/rdoc/lib/rdoc/generator/template/darkfish/images/brick_link.png +0 -0
  32. data/rdoc/lib/rdoc/generator/template/darkfish/images/bug.png +0 -0
  33. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_black.png +0 -0
  34. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png +0 -0
  35. data/rdoc/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png +0 -0
  36. data/rdoc/lib/rdoc/generator/template/darkfish/images/date.png +0 -0
  37. data/rdoc/lib/rdoc/generator/template/darkfish/images/find.png +0 -0
  38. data/rdoc/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif +0 -0
  39. data/rdoc/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png +0 -0
  40. data/rdoc/lib/rdoc/generator/template/darkfish/images/package.png +0 -0
  41. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_green.png +0 -0
  42. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_white_text.png +0 -0
  43. data/rdoc/lib/rdoc/generator/template/darkfish/images/page_white_width.png +0 -0
  44. data/rdoc/lib/rdoc/generator/template/darkfish/images/plugin.png +0 -0
  45. data/rdoc/lib/rdoc/generator/template/darkfish/images/ruby.png +0 -0
  46. data/rdoc/lib/rdoc/generator/template/darkfish/images/tag_green.png +0 -0
  47. data/rdoc/lib/rdoc/generator/template/darkfish/images/wrench.png +0 -0
  48. data/rdoc/lib/rdoc/generator/template/darkfish/images/wrench_orange.png +0 -0
  49. data/rdoc/lib/rdoc/generator/template/darkfish/images/zoom.png +0 -0
  50. data/rdoc/lib/rdoc/generator/template/darkfish/index.rhtml +0 -64
  51. data/rdoc/lib/rdoc/generator/template/darkfish/js/darkfish.js +0 -116
  52. data/rdoc/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -32
  53. data/rdoc/lib/rdoc/generator/template/darkfish/js/quicksearch.js +0 -114
  54. data/rdoc/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +0 -10
  55. data/rdoc/lib/rdoc/generator/template/darkfish/rdoc.css +0 -696
  56. data/rdoc/lib/rdoc/generator.rb +0 -8
  57. data/rdoc/lib/rdoc/ghost_method.rb +0 -8
  58. data/rdoc/lib/rdoc/include.rb +0 -39
  59. data/rdoc/lib/rdoc/known_classes.rb +0 -68
  60. data/rdoc/lib/rdoc/markup/attribute_manager.rb +0 -311
  61. data/rdoc/lib/rdoc/markup/formatter.rb +0 -25
  62. data/rdoc/lib/rdoc/markup/fragments.rb +0 -377
  63. data/rdoc/lib/rdoc/markup/inline.rb +0 -126
  64. data/rdoc/lib/rdoc/markup/lines.rb +0 -156
  65. data/rdoc/lib/rdoc/markup/preprocess.rb +0 -80
  66. data/rdoc/lib/rdoc/markup/to_flow.rb +0 -211
  67. data/rdoc/lib/rdoc/markup/to_html.rb +0 -406
  68. data/rdoc/lib/rdoc/markup/to_html_crossref.rb +0 -140
  69. data/rdoc/lib/rdoc/markup/to_latex.rb +0 -328
  70. data/rdoc/lib/rdoc/markup/to_test.rb +0 -53
  71. data/rdoc/lib/rdoc/markup/to_texinfo.rb +0 -73
  72. data/rdoc/lib/rdoc/markup.rb +0 -378
  73. data/rdoc/lib/rdoc/meta_method.rb +0 -8
  74. data/rdoc/lib/rdoc/normal_class.rb +0 -18
  75. data/rdoc/lib/rdoc/normal_module.rb +0 -34
  76. data/rdoc/lib/rdoc/options.rb +0 -542
  77. data/rdoc/lib/rdoc/parser/c.rb +0 -678
  78. data/rdoc/lib/rdoc/parser/perl.rb +0 -165
  79. data/rdoc/lib/rdoc/parser/ruby.rb +0 -2904
  80. data/rdoc/lib/rdoc/parser/simple.rb +0 -39
  81. data/rdoc/lib/rdoc/parser.rb +0 -138
  82. data/rdoc/lib/rdoc/rdoc.rb +0 -375
  83. data/rdoc/lib/rdoc/require.rb +0 -32
  84. data/rdoc/lib/rdoc/ri/cache.rb +0 -187
  85. data/rdoc/lib/rdoc/ri/descriptions.rb +0 -156
  86. data/rdoc/lib/rdoc/ri/display.rb +0 -340
  87. data/rdoc/lib/rdoc/ri/driver.rb +0 -828
  88. data/rdoc/lib/rdoc/ri/formatter.rb +0 -654
  89. data/rdoc/lib/rdoc/ri/paths.rb +0 -93
  90. data/rdoc/lib/rdoc/ri/reader.rb +0 -106
  91. data/rdoc/lib/rdoc/ri/util.rb +0 -79
  92. data/rdoc/lib/rdoc/ri/writer.rb +0 -68
  93. data/rdoc/lib/rdoc/ri.rb +0 -8
  94. data/rdoc/lib/rdoc/single_class.rb +0 -8
  95. data/rdoc/lib/rdoc/stats.rb +0 -178
  96. data/rdoc/lib/rdoc/task.rb +0 -276
  97. data/rdoc/lib/rdoc/tokenstream.rb +0 -33
  98. data/rdoc/lib/rdoc/top_level.rb +0 -242
  99. data/rdoc/lib/rdoc.rb +0 -398
@@ -1,828 +0,0 @@
1
- require 'abbrev'
2
- require 'optparse'
3
- require 'yaml'
4
-
5
- begin
6
- require 'readline'
7
- rescue LoadError
8
- end
9
-
10
- require 'rdoc/ri'
11
- require 'rdoc/ri/paths'
12
- require 'rdoc/ri/formatter'
13
- require 'rdoc/ri/display'
14
- require 'fileutils'
15
- require 'rdoc/markup'
16
- require 'rdoc/markup/to_flow'
17
-
18
- class RDoc::RI::Driver
19
-
20
- ##
21
- # This class offers both Hash and OpenStruct functionality. We convert from
22
- # the Core Hash to this before calling any of the display methods, in order
23
- # to give the display methods a cleaner API for accessing the data.
24
-
25
- class OpenStructHash < Hash
26
-
27
- ##
28
- # This method converts from a Hash to an OpenStructHash.
29
-
30
- def self.convert(object)
31
- case object
32
- when Hash then
33
- new_hash = new # Convert Hash -> OpenStructHash
34
-
35
- object.each do |key, value|
36
- new_hash[key] = convert value
37
- end
38
-
39
- new_hash
40
- when Array then
41
- object.map do |element|
42
- convert element
43
- end
44
- else
45
- object
46
- end
47
- end
48
-
49
- def merge_enums(other)
50
- other.each do |k, v|
51
- if self[k] then
52
- case v
53
- when Array then
54
- # HACK dunno
55
- if String === self[k] and self[k].empty? then
56
- self[k] = v
57
- else
58
- self[k] += v
59
- end
60
- when Hash then
61
- self[k].update v
62
- else
63
- # do nothing
64
- end
65
- else
66
- self[k] = v
67
- end
68
- end
69
- end
70
-
71
- def method_missing method, *args
72
- self[method.to_s]
73
- end
74
- end
75
-
76
- class Error < RDoc::RI::Error; end
77
-
78
- class NotFoundError < Error
79
- def message
80
- "Nothing known about #{super}"
81
- end
82
- end
83
-
84
- attr_accessor :homepath # :nodoc:
85
-
86
- ##
87
- # Default options for ri
88
-
89
- def self.default_options
90
- options = {}
91
- options[:use_stdout] = !$stdout.tty?
92
- options[:width] = 72
93
- options[:formatter] = RDoc::RI::Formatter.for 'plain'
94
- options[:interactive] = false
95
- options[:use_cache] = true
96
-
97
- # By default all standard paths are used.
98
- options[:use_system] = true
99
- options[:use_site] = true
100
- options[:use_home] = true
101
- options[:use_gems] = true
102
- options[:extra_doc_dirs] = []
103
-
104
- return options
105
- end
106
-
107
- ##
108
- # Parses +argv+ and returns a Hash of options
109
-
110
- def self.process_args(argv)
111
- options = default_options
112
-
113
- opts = OptionParser.new do |opt|
114
- opt.program_name = File.basename $0
115
- opt.version = RDoc::VERSION
116
- opt.release = nil
117
- opt.summary_indent = ' ' * 4
118
-
119
- directories = [
120
- RDoc::RI::Paths::SYSDIR,
121
- RDoc::RI::Paths::SITEDIR,
122
- RDoc::RI::Paths::HOMEDIR
123
- ]
124
-
125
- if RDoc::RI::Paths::GEMDIRS then
126
- Gem.path.each do |dir|
127
- directories << "#{dir}/doc/*/ri"
128
- end
129
- end
130
-
131
- opt.banner = <<-EOT
132
- Usage: #{opt.program_name} [options] [names...]
133
-
134
- Where name can be:
135
-
136
- Class | Class::method | Class#method | Class.method | method
137
-
138
- All class names may be abbreviated to their minimum unambiguous form. If a name
139
- is ambiguous, all valid options will be listed.
140
-
141
- The form '.' method matches either class or instance methods, while #method
142
- matches only instance and ::method matches only class methods.
143
-
144
- For example:
145
-
146
- #{opt.program_name} Fil
147
- #{opt.program_name} File
148
- #{opt.program_name} File.new
149
- #{opt.program_name} zip
150
-
151
- Note that shell quoting may be required for method names containing
152
- punctuation:
153
-
154
- #{opt.program_name} 'Array.[]'
155
- #{opt.program_name} compact\\!
156
-
157
- By default ri searches for documentation in the following directories:
158
-
159
- #{directories.join "\n "}
160
-
161
- Specifying the --system, --site, --home, --gems or --doc-dir options will
162
- limit ri to searching only the specified directories.
163
-
164
- Options may also be set in the 'RI' environment variable.
165
- EOT
166
-
167
- opt.separator nil
168
- opt.separator "Options:"
169
- opt.separator nil
170
-
171
- opt.on("--fmt=FORMAT", "--format=FORMAT", "-f",
172
- RDoc::RI::Formatter::FORMATTERS.keys,
173
- "Format to use when displaying output:",
174
- " #{RDoc::RI::Formatter.list}",
175
- "Use 'bs' (backspace) with most pager",
176
- "programs. To use ANSI, either disable the",
177
- "pager or tell the pager to allow control",
178
- "characters.") do |value|
179
- options[:formatter] = RDoc::RI::Formatter.for value
180
- end
181
-
182
- opt.separator nil
183
-
184
- opt.on("--doc-dir=DIRNAME", "-d", Array,
185
- "List of directories from which to source",
186
- "documentation in addition to the standard",
187
- "directories. May be repeated.") do |value|
188
- value.each do |dir|
189
- unless File.directory? dir then
190
- raise OptionParser::InvalidArgument, "#{dir} is not a directory"
191
- end
192
-
193
- options[:extra_doc_dirs] << File.expand_path(dir)
194
- end
195
- end
196
-
197
- opt.separator nil
198
-
199
- opt.on("--[no-]use-cache",
200
- "Whether or not to use ri's cache.",
201
- "True by default.") do |value|
202
- options[:use_cache] = value
203
- end
204
-
205
- opt.separator nil
206
-
207
- opt.on("--no-standard-docs",
208
- "Do not include documentation from",
209
- "the Ruby standard library, site_lib,",
210
- "installed gems, or ~/.rdoc.",
211
- "Equivalent to specifying",
212
- "the options --no-system, --no-site, --no-gems,",
213
- "and --no-home") do
214
- options[:use_system] = false
215
- options[:use_site] = false
216
- options[:use_gems] = false
217
- options[:use_home] = false
218
- end
219
-
220
- opt.separator nil
221
-
222
- opt.on("--[no-]system",
223
- "Include documentation from Ruby's standard",
224
- "library. Defaults to true.") do |value|
225
- options[:use_system] = value
226
- end
227
-
228
- opt.separator nil
229
-
230
- opt.on("--[no-]site",
231
- "Include documentation from libraries",
232
- "installed in site_lib.",
233
- "Defaults to true.") do |value|
234
- options[:use_site] = value
235
- end
236
-
237
- opt.separator nil
238
-
239
- opt.on("--[no-]gems",
240
- "Include documentation from RubyGems.",
241
- "Defaults to true.") do |value|
242
- options[:use_gems] = value
243
- end
244
-
245
- opt.separator nil
246
-
247
- opt.on("--[no-]home",
248
- "Include documentation stored in ~/.rdoc.",
249
- "Defaults to true.") do |value|
250
- options[:use_home] = value
251
- end
252
-
253
- opt.separator nil
254
-
255
- opt.on("--list-doc-dirs",
256
- "List the directories from which ri will",
257
- "source documentation on stdout and exit.") do
258
- options[:list_doc_dirs] = true
259
- end
260
-
261
- opt.separator nil
262
-
263
- opt.on("--no-pager", "-T",
264
- "Send output directly to stdout,",
265
- "rather than to a pager.") do
266
- options[:use_stdout] = true
267
- end
268
-
269
- opt.on("--interactive", "-i",
270
- "This makes ri go into interactive mode.",
271
- "When ri is in interactive mode it will",
272
- "allow the user to disambiguate lists of",
273
- "methods in case multiple methods match",
274
- "against a method search string. It also",
275
- "will allow the user to enter in a method",
276
- "name (with auto-completion, if readline",
277
- "is supported) when viewing a class.") do
278
- options[:interactive] = true
279
- end
280
-
281
- opt.separator nil
282
-
283
- opt.on("--width=WIDTH", "-w", OptionParser::DecimalInteger,
284
- "Set the width of the output.") do |value|
285
- options[:width] = value
286
- end
287
- end
288
-
289
- argv = ENV['RI'].to_s.split.concat argv
290
-
291
- opts.parse! argv
292
-
293
- options[:names] = argv
294
-
295
- options[:formatter] ||= RDoc::RI::Formatter.for('plain')
296
- options[:use_stdout] ||= !$stdout.tty?
297
- options[:use_stdout] ||= options[:interactive]
298
- options[:width] ||= 72
299
-
300
- options
301
-
302
- rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
303
- puts opts
304
- puts
305
- puts e
306
- exit 1
307
- end
308
-
309
- ##
310
- # Runs the ri command line executable using +argv+
311
-
312
- def self.run(argv = ARGV)
313
- options = process_args argv
314
- ri = new options
315
- ri.run
316
- end
317
-
318
- def initialize(initial_options={})
319
- options = self.class.default_options.update(initial_options)
320
-
321
- @names = options[:names]
322
- @class_cache_name = 'classes'
323
-
324
- @doc_dirs = RDoc::RI::Paths.path(options[:use_system],
325
- options[:use_site],
326
- options[:use_home],
327
- options[:use_gems],
328
- options[:extra_doc_dirs])
329
-
330
- @homepath = RDoc::RI::Paths.raw_path(false, false, true, false).first
331
- @homepath = @homepath.sub(/\.rdoc/, '.ri')
332
- @sys_dir = RDoc::RI::Paths.raw_path(true, false, false, false).first
333
- @list_doc_dirs = options[:list_doc_dirs]
334
-
335
- FileUtils.mkdir_p cache_file_path unless File.directory? cache_file_path
336
- @cache_doc_dirs_path = File.join cache_file_path, ".doc_dirs"
337
-
338
- @use_cache = options[:use_cache]
339
- @class_cache = nil
340
-
341
- @interactive = options[:interactive]
342
- @display = RDoc::RI::DefaultDisplay.new(options[:formatter],
343
- options[:width],
344
- options[:use_stdout])
345
- end
346
-
347
- ##
348
- # Cache of classes ri knows about
349
-
350
- def class_cache
351
- return @class_cache if @class_cache
352
-
353
- # Get the documentation directories used to make the cache in order to see
354
- # whether the cache is valid for the current ri instantiation.
355
- if(File.readable?(@cache_doc_dirs_path))
356
- cache_doc_dirs = IO.read(@cache_doc_dirs_path).split("\n")
357
- else
358
- cache_doc_dirs = []
359
- end
360
-
361
- newest = map_dirs('created.rid') do |f|
362
- File.mtime f if test ?f, f
363
- end.max
364
-
365
- # An up to date cache file must have been created more recently than
366
- # the last modification of any of the documentation directories. It also
367
- # must have been created with the same documentation directories
368
- # as those from which ri currently is sourcing documentation.
369
- up_to_date = (File.exist?(class_cache_file_path) and
370
- newest and newest < File.mtime(class_cache_file_path) and
371
- (cache_doc_dirs == @doc_dirs))
372
-
373
- if up_to_date and @use_cache then
374
- open class_cache_file_path, 'rb' do |fp|
375
- begin
376
- @class_cache = Marshal.load fp.read
377
- rescue
378
- #
379
- # This shouldn't be necessary, since the up_to_date logic above
380
- # should force the cache to be recreated when a new version of
381
- # rdoc is installed. This seems like a worthwhile enhancement
382
- # to ri's robustness, however.
383
- #
384
- $stderr.puts "Error reading the class cache; recreating the class cache!"
385
- @class_cache = create_class_cache
386
- end
387
- end
388
- else
389
- @class_cache = create_class_cache
390
- end
391
-
392
- @class_cache
393
- end
394
-
395
- ##
396
- # Creates the class cache if it is empty
397
-
398
- def create_class_cache
399
- class_cache = OpenStructHash.new
400
-
401
- if(@use_cache)
402
- # Dump the documentation directories to a file in the cache, so that
403
- # we only will use the cache for future instantiations with identical
404
- # documentation directories.
405
- File.open @cache_doc_dirs_path, "wb" do |fp|
406
- fp << @doc_dirs.join("\n")
407
- end
408
- end
409
-
410
- classes = map_dirs('**/cdesc*.yaml') { |f| Dir[f] }
411
- warn "Updating ri class cache with #{classes.size} classes..."
412
- populate_class_cache class_cache, classes
413
-
414
- write_cache class_cache, class_cache_file_path
415
-
416
- class_cache
417
- end
418
-
419
- ##
420
- # Populates +class_cache+ with +classes+, adding +extension+ data for found
421
- # methods when asked
422
-
423
- def populate_class_cache(class_cache, classes, extension = false)
424
- classes.each do |cdesc|
425
- desc = read_yaml cdesc
426
- klassname = desc["full_name"]
427
-
428
- unless class_cache.has_key? klassname then
429
- desc["display_name"] = "Class"
430
- desc["sources"] = [cdesc]
431
- desc["instance_method_extensions"] = []
432
- desc["class_method_extensions"] = []
433
- class_cache[klassname] = desc
434
- else
435
- klass = class_cache[klassname]
436
-
437
- if extension then
438
- desc["instance_method_extensions"] = desc.delete "instance_methods"
439
- desc["class_method_extensions"] = desc.delete "class_methods"
440
- end
441
-
442
- klass.merge_enums desc
443
- klass["sources"] << cdesc
444
- end
445
- end
446
- end
447
-
448
- ##
449
- # Path to the class_cache
450
-
451
- def class_cache_file_path
452
- File.join cache_file_path, @class_cache_name
453
- end
454
-
455
- ##
456
- # Path to the cache file for +klassname+
457
-
458
- def cache_file_for(klassname)
459
- File.join cache_file_path, klassname.gsub(/:+/, "-")
460
- end
461
-
462
- ##
463
- # Directory where cache files live
464
-
465
- def cache_file_path
466
- File.join @homepath, 'cache'
467
- end
468
-
469
- ##
470
- # Displays the module, class or method +name+. For methods, locates the
471
- # method in the ancestors list if it isn't in the named module.
472
-
473
- def display_name(name)
474
- if class_cache.key? name then
475
- method_map = display_class name
476
- elsif name =~ /::|\#|\./ then
477
- method = nil
478
- klass, = parse_name name
479
-
480
- klass = expand_klass klass unless class_cache.key? klass
481
-
482
- orig_klass = klass
483
- orig_name = name
484
-
485
- loop do
486
- method = lookup_method name, klass
487
-
488
- break if method
489
-
490
- ancestor = lookup_ancestor klass, orig_klass
491
-
492
- break unless ancestor
493
-
494
- name = name.sub klass, ancestor
495
- klass = ancestor
496
- end
497
-
498
- raise NotFoundError, orig_name unless method
499
-
500
- display_method method
501
- else
502
- methods = select_methods(/#{name}/)
503
-
504
- if methods.size == 0
505
- raise NotFoundError, name
506
- elsif methods.size == 1
507
- display_method methods[0]
508
- else
509
- @display.display_method_list methods
510
- end
511
- end
512
- end
513
-
514
- ##
515
- # Displays info for class or module +name+
516
-
517
- def display_class(name)
518
- klass = class_cache[name]
519
- @display.display_class_info klass
520
- end
521
-
522
- ##
523
- # Displays info for method +method+
524
-
525
- def display_method(method)
526
- @display.display_method_info method
527
- end
528
-
529
- ##
530
- # Runs ri interactively using Readline if it is available.
531
-
532
- def interactive
533
- formatter = @display.formatter
534
-
535
- if defined? Readline then
536
- # prepare abbreviations for tab completion
537
- klasses = class_cache.keys
538
-
539
- Readline.completion_proc = proc do |name|
540
- case name
541
- when /(#|\.|::)([^A-Z]|$)/ then
542
- methods = []
543
- method_type = $1 == '.' ? '#|::' : $1
544
-
545
- klass, method = if $2.empty? then
546
- [$`, '']
547
- else
548
- parse_name name
549
- end
550
-
551
- cache = load_cache_for klass
552
-
553
- methods += cache.keys.select do |method_name|
554
- method_name =~ /^#{klass}#{method_type}#{method}/
555
- end
556
-
557
- # TODO ancestor lookup
558
-
559
- if method_type == '::' and method.empty? then
560
- methods += klasses.grep(/^#{klass}::/)
561
- end
562
-
563
- methods
564
- when /^[A-Z]\w*/ then
565
- klasses.grep(/^#{name}/)
566
- else
567
- []
568
- end
569
- end
570
- end
571
-
572
- formatter.raw_print_line "\nEnter the method name you want to look up.\n"
573
-
574
- if defined? Readline then
575
- formatter.raw_print_line "You can use tab to autocomplete.\n"
576
- end
577
-
578
- formatter.raw_print_line "Enter a blank line to exit.\n\n"
579
-
580
- loop do
581
- name = if defined? Readline then
582
- Readline.readline ">> "
583
- else
584
- formatter.raw_print_line ">> "
585
- $stdin.gets
586
- end
587
-
588
- return if name.nil? or name.empty?
589
-
590
- name = name.strip
591
-
592
- begin
593
- display_name name
594
- rescue NotFoundError => e
595
- formatter.raw_print_line "#{e.message}\n"
596
- end
597
- end
598
-
599
- rescue Interrupt
600
- exit
601
- end
602
-
603
- ##
604
- # Expands abbreviated klass +klass+ into a fully-qualified klass. "Zl::Da"
605
- # will be expanded to Zlib::DataError.
606
-
607
- def expand_klass(klass)
608
- klass.split('::').inject '' do |expanded, klass_part|
609
- expanded << '::' unless expanded.empty?
610
- short = expanded << klass_part
611
-
612
- subset = class_cache.keys.select do |klass_name|
613
- klass =~ /^#{expanded}[^:]*$/
614
- end
615
-
616
- abbrevs = Abbrev.abbrev subset
617
-
618
- expanded = abbrevs[short]
619
-
620
- raise NotFoundError, short unless expanded
621
-
622
- expanded.dup
623
- end
624
- end
625
-
626
- ##
627
- # Loads the cache for +klassname+
628
-
629
- def load_cache_for(klassname)
630
- path = cache_file_for klassname
631
-
632
- cache = nil
633
-
634
- if File.exist? path and
635
- File.mtime(path) >= File.mtime(class_cache_file_path) and
636
- @use_cache then
637
- open path, 'rb' do |fp|
638
- begin
639
- cache = Marshal.load fp.read
640
- rescue
641
- #
642
- # The cache somehow is bad. Recreate the cache.
643
- #
644
- $stderr.puts "Error reading the cache for #{klassname}; recreating the cache!"
645
- cache = create_cache_for klassname, path
646
- end
647
- end
648
- else
649
- cache = create_cache_for klassname, path
650
- end
651
-
652
- cache
653
- end
654
-
655
- ##
656
- # Writes a cache file for +klassname+ to +path+
657
-
658
- def create_cache_for(klassname, path)
659
- klass = class_cache[klassname]
660
- return nil unless klass
661
-
662
- method_files = klass["sources"]
663
- cache = OpenStructHash.new
664
-
665
- method_files.each do |f|
666
- system_file = f.index(@sys_dir) == 0
667
- Dir[File.join(File.dirname(f), "*")].each do |yaml|
668
- next unless yaml =~ /yaml$/
669
- next if yaml =~ /cdesc-[^\/]+yaml$/
670
-
671
- method = read_yaml yaml
672
-
673
- if system_file then
674
- method["source_path"] = "Ruby #{RDoc::RI::Paths::VERSION}"
675
- else
676
- gem = Gem.path.any? do |gem_path|
677
- pattern = File.join Regexp.escape(gem_path), 'doc', '(.*?)', ''
678
-
679
- f =~ /^#{pattern}/
680
- end
681
-
682
- method["source_path"] = if gem then
683
- "gem #{$1}"
684
- else
685
- f
686
- end
687
- end
688
-
689
- name = method["full_name"]
690
- cache[name] = method
691
- end
692
- end
693
-
694
- write_cache cache, path
695
- end
696
-
697
- ##
698
- # Finds the next ancestor of +orig_klass+ after +klass+.
699
-
700
- def lookup_ancestor(klass, orig_klass)
701
- # This is a bit hacky, but ri will go into an infinite loop otherwise,
702
- # since Object has an Object ancestor for some reason. Depending on the
703
- # documentation state, I've seen Kernel as an ancestor of Object and not
704
- # as an ancestor of Object.
705
- if orig_klass == "Object" && (klass == "Kernel" || klass == "Object") then
706
- return nil
707
- end
708
-
709
- cache = class_cache[orig_klass]
710
-
711
- return nil unless cache
712
-
713
- ancestors = [orig_klass]
714
- ancestors.push(*cache.includes.map { |inc| inc['name'] })
715
- ancestors << cache.superclass
716
-
717
- ancestor_index = ancestors.index klass
718
-
719
- if ancestor_index
720
- ancestor = ancestors[ancestors.index(klass) + 1]
721
- return ancestor if ancestor
722
- end
723
-
724
- lookup_ancestor klass, cache.superclass
725
- end
726
-
727
- ##
728
- # Finds the method
729
-
730
- def lookup_method(name, klass)
731
- cache = load_cache_for klass
732
- return nil unless cache
733
-
734
- method = cache[name.gsub('.', '#')]
735
- method = cache[name.gsub('.', '::')] unless method
736
- method
737
- end
738
-
739
- def map_dirs(file_name)
740
- @doc_dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact
741
- end
742
-
743
- ##
744
- # Extract the class and method name parts from +name+ like Foo::Bar#baz
745
-
746
- def parse_name(name)
747
- parts = name.split(/(::|\#|\.)/)
748
-
749
- if parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
750
- meth = parts.pop
751
- parts.pop
752
- end
753
-
754
- klass = parts.join
755
-
756
- [klass, meth]
757
- end
758
-
759
- ##
760
- # Reads ri YAML data from +path+, converting RDoc 1.x classes to RDoc 2.x
761
- # classes
762
-
763
- def read_yaml(path)
764
- data = File.read path
765
-
766
- # Necessary to be backward-compatible with documentation generated
767
- # by earliar RDoc versions.
768
- data = data.gsub(/ \!ruby\/(object|struct):(RDoc::RI|RI).*/, '')
769
- data = data.gsub(/ \!ruby\/(object|struct):SM::(\S+)/,
770
- ' !ruby/\1:RDoc::Markup::\2')
771
-
772
- OpenStructHash.convert YAML.load(data)
773
- end
774
-
775
- ##
776
- # Looks up and displays ri data according to the options given.
777
-
778
- def run
779
- if @list_doc_dirs then
780
- puts @doc_dirs
781
- elsif @interactive then
782
- interactive
783
- elsif @names.empty? then
784
- @display.list_known_classes class_cache.keys.sort
785
- else
786
- @names.each do |name|
787
- display_name name
788
- end
789
- end
790
- rescue NotFoundError => e
791
- abort e.message
792
- end
793
-
794
- ##
795
- # Selects methods matching +pattern+ from all modules
796
-
797
- def select_methods(pattern)
798
- methods = []
799
- class_cache.keys.sort.each do |klass|
800
- class_cache[klass]["instance_methods"].map{|h|h["name"]}.grep(pattern) do |name|
801
- method = load_cache_for(klass)[klass+'#'+name]
802
- methods << method if method
803
- end
804
- class_cache[klass]["class_methods"].map{|h|h["name"]}.grep(pattern) do |name|
805
- method = load_cache_for(klass)[klass+'::'+name]
806
- methods << method if method
807
- end
808
- end
809
- methods
810
- end
811
-
812
- ##
813
- # Writes +cache+ to +path+
814
-
815
- def write_cache(cache, path)
816
- if @use_cache then
817
- File.open path, "wb" do |cache_file|
818
- Marshal.dump cache, cache_file
819
- end
820
- end
821
-
822
- cache
823
- rescue Errno::EISDIR # HACK toplevel, replace with main
824
- cache
825
- end
826
-
827
- end
828
-