rdoc 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

Files changed (57) hide show
  1. data/History.txt +82 -1
  2. data/Manifest.txt +8 -0
  3. data/README.txt +33 -9
  4. data/RI.txt +58 -0
  5. data/Rakefile +2 -0
  6. data/bin/ri +1 -2
  7. data/lib/rdoc.rb +154 -36
  8. data/lib/rdoc/code_objects.rb +38 -2
  9. data/lib/rdoc/diagram.rb +17 -15
  10. data/lib/rdoc/generator.rb +21 -15
  11. data/lib/rdoc/generator/chm/chm.rb +2 -0
  12. data/lib/rdoc/generator/html.rb +137 -89
  13. data/lib/rdoc/generator/html/common.rb +24 -0
  14. data/lib/rdoc/generator/html/frameless.rb +28 -731
  15. data/lib/rdoc/generator/html/hefss.rb +47 -311
  16. data/lib/rdoc/generator/html/html.rb +226 -156
  17. data/lib/rdoc/generator/html/kilmer.rb +31 -298
  18. data/lib/rdoc/generator/html/kilmerfactory.rb +427 -0
  19. data/lib/rdoc/generator/html/one_page_html.rb +6 -5
  20. data/lib/rdoc/generator/texinfo.rb +3 -6
  21. data/lib/rdoc/generator/xml.rb +4 -7
  22. data/lib/rdoc/generator/xml/xml.rb +21 -9
  23. data/lib/rdoc/markup.rb +0 -95
  24. data/lib/rdoc/markup/inline.rb +1 -1
  25. data/lib/rdoc/markup/to_html.rb +9 -6
  26. data/lib/rdoc/markup/to_html_crossref.rb +67 -21
  27. data/lib/rdoc/markup/to_texinfo.rb +1 -1
  28. data/lib/rdoc/parser.rb +22 -1
  29. data/lib/rdoc/parser/c.rb +14 -16
  30. data/lib/rdoc/parser/ruby.rb +3 -3
  31. data/lib/rdoc/parser/simple.rb +1 -1
  32. data/lib/rdoc/rdoc.rb +0 -1
  33. data/lib/rdoc/ri/cache.rb +5 -6
  34. data/lib/rdoc/ri/descriptions.rb +3 -0
  35. data/lib/rdoc/ri/display.rb +157 -37
  36. data/lib/rdoc/ri/driver.rb +314 -198
  37. data/lib/rdoc/ri/formatter.rb +1 -1
  38. data/lib/rdoc/ri/paths.rb +2 -11
  39. data/lib/rdoc/ri/reader.rb +3 -3
  40. data/lib/rdoc/ri/util.rb +0 -2
  41. data/test/binary.dat +0 -0
  42. data/test/rdoc_markup_to_html_crossref_reference.rb +31 -0
  43. data/test/test_attribute_manager.rb +73 -0
  44. data/test/test_rdoc_info_formatting.rb +6 -6
  45. data/test/test_rdoc_info_sections.rb +2 -2
  46. data/test/test_rdoc_markup_attribute_manager.rb +14 -14
  47. data/test/test_rdoc_markup_to_html.rb +15 -3
  48. data/test/test_rdoc_markup_to_html_crossref.rb +276 -7
  49. data/test/test_rdoc_parser.rb +13 -0
  50. data/test/test_rdoc_parser_c.rb +1 -1
  51. data/test/test_rdoc_parser_ruby.rb +72 -1
  52. data/test/test_rdoc_ri_default_display.rb +23 -22
  53. data/test/test_rdoc_ri_driver.rb +1 -1
  54. data/test/test_rdoc_ri_formatter.rb +1 -1
  55. metadata +27 -35
  56. data.tar.gz.sig +0 -1
  57. metadata.gz.sig +0 -0
@@ -219,6 +219,22 @@ module RDoc
219
219
  @modules.values
220
220
  end
221
221
 
222
+ ##
223
+ # return the classes Hash (only to be used internally)
224
+
225
+ def classes_hash
226
+ @classes
227
+ end
228
+ protected :classes_hash
229
+
230
+ ##
231
+ # return the modules Hash (only to be used internally)
232
+
233
+ def modules_hash
234
+ @modules
235
+ end
236
+ protected :modules_hash
237
+
222
238
  ##
223
239
  # Change the default visibility for new methods
224
240
 
@@ -272,7 +288,23 @@ module RDoc
272
288
  end
273
289
 
274
290
  def add_class(class_type, name, superclass)
275
- add_class_or_module @classes, class_type, name, superclass
291
+ klass = add_class_or_module @classes, class_type, name, superclass
292
+
293
+ #
294
+ # If the parser encounters Container::Item before encountering
295
+ # Container, then it assumes that Container is a module. This
296
+ # may not be the case, so remove Container from the module list
297
+ # if present and transfer any contained classes and modules to
298
+ # the new class.
299
+ #
300
+ mod = @modules.delete(name)
301
+
302
+ if mod then
303
+ klass.classes_hash.update(mod.classes_hash)
304
+ klass.modules_hash.update(mod.modules_hash)
305
+ end
306
+
307
+ return klass
276
308
  end
277
309
 
278
310
  def add_module(class_type, name)
@@ -374,9 +406,12 @@ module RDoc
374
406
 
375
407
  # Find a named module
376
408
  def find_module_named(name)
377
- return self if self.name == name
409
+ # First check the enclosed modules, then check the module itself,
410
+ # then check the enclosing modules (this mirrors the check done by
411
+ # the Ruby parser)
378
412
  res = @modules[name] || @classes[name]
379
413
  return res if res
414
+ return self if self.name == name
380
415
  find_enclosing_module_named(name)
381
416
  end
382
417
 
@@ -435,6 +470,7 @@ module RDoc
435
470
  unless modules.empty? then
436
471
  module_name = modules.shift
437
472
  result = find_module_named(module_name)
473
+
438
474
  if result then
439
475
  modules.each do |name|
440
476
  result = result.find_module_named(name)
data/lib/rdoc/diagram.rb CHANGED
@@ -311,28 +311,30 @@ module RDoc
311
311
  # inclusion on the page
312
312
 
313
313
  def wrap_in_image_map(src, dot)
314
- res = %{<map id="map" name="map">\n}
314
+ res = ""
315
315
  dot_map = `dot -Tismap #{src}`
316
- dot_map.split($/).each do |area|
317
- unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/
318
- $stderr.puts "Unexpected output from dot:\n#{area}"
319
- return nil
320
- end
316
+
317
+ if(!dot_map.empty?)
318
+ res << %{<map id="map" name="map">\n}
319
+ dot_map.split($/).each do |area|
320
+ unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/
321
+ $stderr.puts "Unexpected output from dot:\n#{area}"
322
+ return nil
323
+ end
321
324
 
322
- xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i]
323
- url, area_name = $5, $6
325
+ xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i]
326
+ url, area_name = $5, $6
324
327
 
325
- res << %{ <area shape="rect" coords="#{xs.min},#{ys.min},#{xs.max},#{ys.max}" }
326
- res << %{ href="#{url}" alt="#{area_name}" />\n}
328
+ res << %{ <area shape="rect" coords="#{xs.min},#{ys.min},#{xs.max},#{ys.max}" }
329
+ res << %{ href="#{url}" alt="#{area_name}" />\n}
330
+ end
331
+ res << "</map>\n"
327
332
  end
328
- res << "</map>\n"
329
- # map_file = src.sub(/.dot/, '.map')
330
- # system("dot -Timap #{src} -o #{map_file}")
331
- res << %{<img src="#{dot}" usemap="#map" border="0" alt="#{dot}">}
333
+
334
+ res << %{<img src="#{dot}" usemap="#map" alt="#{dot}" />}
332
335
  return res
333
336
  end
334
337
 
335
338
  end
336
339
 
337
340
  end
338
-
@@ -127,7 +127,7 @@ module RDoc::Generator
127
127
  # * a complete list of all hyperlinkable terms (file, class, module, and
128
128
  # method names)
129
129
 
130
- def self.build_indicies(toplevels, options)
130
+ def self.build_indices(toplevels, options)
131
131
  files = []
132
132
  classes = []
133
133
 
@@ -215,7 +215,7 @@ module RDoc::Generator
215
215
  @methods.sort.map do |meth|
216
216
  {
217
217
  "name" => CGI.escapeHTML(meth.name),
218
- "aref" => "#{path_prefix}\##{meth.aref}"
218
+ "aref" => "##{meth.aref}"
219
219
  }
220
220
  end
221
221
  end
@@ -614,9 +614,9 @@ module RDoc::Generator
614
614
  def class_attribute_values
615
615
  h_name = CGI.escapeHTML(name)
616
616
 
617
- @values["path"] = @path
617
+ @values["href"] = @path
618
618
  @values["classmod"] = @is_module ? "Module" : "Class"
619
- @values["title"] = "#{@values['classmod']}: #{h_name}"
619
+ @values["title"] = "#{@values['classmod']}: #{h_name} [#{@options.title}]"
620
620
 
621
621
  c = @context
622
622
  c = c.parent while c and not c.diagram
@@ -704,7 +704,7 @@ module RDoc::Generator
704
704
 
705
705
  def filename_to_label
706
706
  @context.file_relative_name.gsub(/%|\/|\?|\#/) do
707
- '%%%x' % $&[0].unpack('C')
707
+ ('%%%x' % $&[0]).unpack('C')
708
708
  end
709
709
  end
710
710
 
@@ -791,7 +791,7 @@ module RDoc::Generator
791
791
  full_path = @context.file_absolute_name
792
792
  short_name = ::File.basename full_path
793
793
 
794
- @values["title"] = CGI.escapeHTML("File: #{short_name}")
794
+ @values["title"] = CGI.escapeHTML("File: #{short_name} [#{@options.title}]")
795
795
 
796
796
  if @context.diagram then
797
797
  @values["diagram"] = diagram_reference(@context.diagram)
@@ -821,18 +821,18 @@ module RDoc::Generator
821
821
  attr_reader :img_url
822
822
  attr_reader :source_code
823
823
 
824
- @@seq = "M000000"
825
-
826
- @@all_methods = []
827
-
828
824
  def self.all_methods
829
825
  @@all_methods
830
826
  end
831
827
 
832
828
  def self.reset
833
829
  @@all_methods = []
830
+ @@seq = "M000000"
834
831
  end
835
832
 
833
+ # Initialize the class variables.
834
+ self.reset
835
+
836
836
  def initialize(context, html_class, options)
837
837
  # TODO: rethink the class hierarchy here...
838
838
  @context = context
@@ -1043,12 +1043,18 @@ module RDoc::Generator
1043
1043
  first = $1.to_i - 1
1044
1044
  last = first + src.count("\n")
1045
1045
  size = last.to_s.length
1046
- real_fmt = "%#{size}d: "
1047
- fmt = " " * (size+2)
1046
+ fmt = "%#{size}d: "
1047
+ is_first_line = true
1048
+ line_num = first
1048
1049
  src.gsub!(/^/) do
1049
- res = sprintf(fmt, first)
1050
- first += 1
1051
- fmt = real_fmt
1050
+ if is_first_line then
1051
+ is_first_line = false
1052
+ res = " " * (size+2)
1053
+ else
1054
+ res = sprintf(fmt, line_num)
1055
+ end
1056
+
1057
+ line_num += 1
1052
1058
  res
1053
1059
  end
1054
1060
  end
@@ -6,6 +6,8 @@ module RDoc::Generator::CHM::CHM
6
6
  HTML = RDoc::Generator::HTML::HTML
7
7
 
8
8
  INDEX = HTML::INDEX
9
+
10
+ STYLE = HTML::STYLE
9
11
 
10
12
  CLASS_INDEX = HTML::CLASS_INDEX
11
13
  CLASS_PAGE = HTML::CLASS_PAGE
@@ -68,7 +68,6 @@ class RDoc::Generator::HTML
68
68
  def initialize(options) #:not-new:
69
69
  @options = options
70
70
  load_html_template
71
- @main_page_path = nil
72
71
  end
73
72
 
74
73
  ##
@@ -94,6 +93,15 @@ class RDoc::Generator::HTML
94
93
  # If the template name contains a slash, use it literally
95
94
 
96
95
  def load_html_template
96
+ #
97
+ # If the template is not a path, first look for it
98
+ # in rdoc's HTML template directory. Perhaps this behavior should
99
+ # be reversed (first try to include the template and, only if that
100
+ # fails, try to include it in the default template directory).
101
+ # One danger with reversing the behavior, however, is that
102
+ # if something like require 'html' could load up an
103
+ # unrelated file in the standard library or in a gem.
104
+ #
97
105
  template = @options.template
98
106
 
99
107
  unless template =~ %r{/|\\} then
@@ -101,14 +109,25 @@ class RDoc::Generator::HTML
101
109
  template)
102
110
  end
103
111
 
104
- require template
105
-
106
- @template = self.class.const_get @options.template.upcase
107
- @options.template_class = @template
112
+ begin
113
+ require template
114
+
115
+ @template = self.class.const_get @options.template.upcase
116
+ @options.template_class = @template
117
+ rescue LoadError => e
118
+ #
119
+ # The template did not exist in the default template directory, so
120
+ # see if require can find the template elsewhere (in a gem, for
121
+ # instance).
122
+ #
123
+ if(e.message[template] && template != @options.template)
124
+ template = @options.template
125
+ retry
126
+ end
108
127
 
109
- rescue LoadError
110
- $stderr.puts "Could not find HTML template '#{template}'"
111
- exit 99
128
+ $stderr.puts "Could not find HTML template '#{template}': #{e.message}"
129
+ exit 99
130
+ end
112
131
  end
113
132
 
114
133
  ##
@@ -146,14 +165,16 @@ class RDoc::Generator::HTML
146
165
  end
147
166
 
148
167
  def build_indices
149
- @files, @classes = RDoc::Generator::Context.build_indicies(@toplevels,
150
- @options)
168
+ @files, @classes = RDoc::Generator::Context.build_indices(@toplevels,
169
+ @options)
151
170
  end
152
171
 
153
172
  ##
154
173
  # Generate all the HTML
155
174
 
156
175
  def generate_html
176
+ @main_url = main_url
177
+
157
178
  # the individual descriptions for files and classes
158
179
  gen_into(@files)
159
180
  gen_into(@classes)
@@ -165,23 +186,50 @@ class RDoc::Generator::HTML
165
186
  gen_main_index
166
187
 
167
188
  # this method is defined in the template file
168
- write_extra_pages if defined? write_extra_pages
189
+ values = {
190
+ 'title_suffix' => CGI.escapeHTML("[#{@options.title}]"),
191
+ 'charset' => @options.charset,
192
+ 'style_url' => style_url('', @options.css),
193
+ }
194
+
195
+ @template.write_extra_pages(values) if @template.respond_to?(:write_extra_pages)
169
196
  end
170
197
 
171
198
  def gen_into(list)
172
- @file_list ||= index_to_links @files
173
- @class_list ||= index_to_links @classes
174
- @method_list ||= index_to_links RDoc::Generator::Method.all_methods
199
+ #
200
+ # The file, class, and method lists technically should be regenerated
201
+ # for every output file, in order that the relative links be correct
202
+ # (we are worried here about frameless templates, which need this
203
+ # information for every generated page). Doing this is a bit slow,
204
+ # however. For a medium-sized gem, this increased rdoc's runtime by
205
+ # about 5% (using the 'time' command-line utility). While this is not
206
+ # necessarily a problem, I do not want to pessimize rdoc for large
207
+ # projects, however, and so we only regenerate the lists when the
208
+ # directory of the output file changes, which seems like a reasonable
209
+ # optimization.
210
+ #
211
+ file_list = {}
212
+ class_list = {}
213
+ method_list = {}
214
+ prev_op_dir = nil
175
215
 
176
216
  list.each do |item|
177
217
  next unless item.document_self
178
218
 
179
219
  op_file = item.path
220
+ op_dir = File.dirname(op_file)
221
+
222
+ if(op_dir != prev_op_dir)
223
+ file_list = index_to_links op_file, @files
224
+ class_list = index_to_links op_file, @classes
225
+ method_list = index_to_links op_file, RDoc::Generator::Method.all_methods
226
+ end
227
+ prev_op_dir = op_dir
180
228
 
181
- FileUtils.mkdir_p File.dirname(op_file)
229
+ FileUtils.mkdir_p op_dir
182
230
 
183
231
  open op_file, 'w' do |io|
184
- item.write_on io, @file_list, @class_list, @method_list
232
+ item.write_on io, file_list, class_list, method_list
185
233
  end
186
234
  end
187
235
  end
@@ -211,8 +259,9 @@ class RDoc::Generator::HTML
211
259
 
212
260
  values = {
213
261
  "entries" => res,
262
+ 'title' => CGI.escapeHTML("#{title} [#{@options.title}]"),
214
263
  'list_title' => CGI.escapeHTML(title),
215
- 'index_url' => main_url,
264
+ 'index_url' => @main_url,
216
265
  'charset' => @options.charset,
217
266
  'style_url' => style_url('', @options.css),
218
267
  }
@@ -230,47 +279,55 @@ class RDoc::Generator::HTML
230
279
 
231
280
  def gen_main_index
232
281
  if @template.const_defined? :FRAMELESS then
233
- main = @files.find do |file|
234
- @main_page == file.name
235
- end
236
-
237
- if main.nil? then
238
- main = @classes.find do |klass|
239
- main_page == klass.context.full_name
240
- end
282
+ #
283
+ # If we're using a template without frames, then just redirect
284
+ # to it from index.html.
285
+ #
286
+ # One alternative to this, expanding the main page's template into
287
+ # index.html, is tricky because the relative URLs will be different
288
+ # (since index.html is located in at the site's root,
289
+ # rather than within a files or a classes subdirectory).
290
+ #
291
+ open 'index.html', 'w' do |f|
292
+ f.puts(%{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
293
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">})
294
+ f.puts(%{<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
295
+ lang="en">})
296
+ f.puts(%{<head>})
297
+ f.puts(%{<title>#{CGI.escapeHTML(@options.title)}</title>})
298
+ f.puts(%{<meta http-equiv="refresh" content="0; url=#{@main_url}" />})
299
+ f.puts(%{</head>})
300
+ f.puts(%{<body></body>})
301
+ f.puts(%{</html>})
241
302
  end
242
303
  else
243
304
  main = RDoc::TemplatePage.new @template::INDEX
244
- end
245
305
 
246
- open 'index.html', 'w' do |f|
247
- style_url = style_url '', @options.css
306
+ open 'index.html', 'w' do |f|
307
+ style_url = style_url '', @options.css
308
+
309
+ classes = @classes.sort.map { |klass| klass.value_hash }
310
+
311
+ values = {
312
+ 'initial_page' => @main_url,
313
+ 'style_url' => style_url('', @options.css),
314
+ 'title' => CGI.escapeHTML(@options.title),
315
+ 'charset' => @options.charset,
316
+ 'classes' => classes,
317
+ }
318
+
319
+ values['inline_source'] = @options.inline_source
248
320
 
249
- classes = @classes.sort.map { |klass| klass.value_hash }
250
-
251
- values = {
252
- 'main_page' => @main_page,
253
- 'initial_page' => main_url,
254
- 'style_url' => style_url('', @options.css),
255
- 'title' => CGI.escapeHTML(@options.title),
256
- 'charset' => @options.charset,
257
- 'classes' => classes,
258
- }
259
-
260
- values['inline_source'] = @options.inline_source
261
-
262
- if main.respond_to? :write_on then
263
- main.write_on f, @file_list, @class_list, @method_list, values
264
- else
265
321
  main.write_html_on f, values
266
322
  end
267
323
  end
268
324
  end
269
325
 
270
- def index_to_links(collection)
326
+ def index_to_links(output_path, collection)
271
327
  collection.sort.map do |f|
272
328
  next unless f.document_self
273
- { "href" => f.path, "name" => f.index_name }
329
+ { "href" => RDoc::Markup::ToHtml.gen_relative_url(output_path, f.path),
330
+ "name" => f.index_name }
274
331
  end.compact
275
332
  end
276
333
 
@@ -278,32 +335,48 @@ class RDoc::Generator::HTML
278
335
  # Returns the url of the main page
279
336
 
280
337
  def main_url
281
- @main_page = @options.main_page
282
- @main_page_ref = nil
283
-
284
- if @main_page then
285
- @main_page_ref = RDoc::Generator::AllReferences[@main_page]
286
-
287
- if @main_page_ref then
288
- @main_page_path = @main_page_ref.path
338
+ main_page = @options.main_page
339
+
340
+ #
341
+ # If a main page has been specified (--main), then search for it
342
+ # in the AllReferences array. This allows either files or classes
343
+ # to be used for the main page.
344
+ #
345
+ if main_page then
346
+ main_page_ref = RDoc::Generator::AllReferences[main_page]
347
+
348
+ if main_page_ref then
349
+ return main_page_ref.path
289
350
  else
290
- $stderr.puts "Could not find main page #{@main_page}"
351
+ $stderr.puts "Could not find main page #{main_page}"
291
352
  end
292
353
  end
293
354
 
294
- unless @main_page_path then
295
- file = @files.find { |context| context.document_self }
296
- @main_page_path = file.path if file
355
+ #
356
+ # No main page has been specified, so just use the README.
357
+ #
358
+ @files.each do |file|
359
+ if file.name =~ /^README/ then
360
+ return file.path
361
+ end
297
362
  end
298
363
 
299
- unless @main_page_path then
300
- $stderr.puts "Couldn't find anything to document"
301
- $stderr.puts "Perhaps you've used :stopdoc: in all classes"
302
- exit 1
364
+ #
365
+ # There's no README (shame! shame!). Just use the first file
366
+ # that will be documented.
367
+ #
368
+ @files.each do |file|
369
+ if file.document_self then
370
+ return file.path
371
+ end
303
372
  end
304
373
 
305
- @main_page_path
374
+ #
375
+ # There are no files to be documented... Something seems very wrong.
376
+ #
377
+ raise RDoc::Error, "Couldn't find anything to document (perhaps :stopdoc: has been used in all classes)!"
306
378
  end
379
+ private :main_url
307
380
 
308
381
  end
309
382
 
@@ -349,12 +422,9 @@ class RDoc::Generator::HTMLInOne < RDoc::Generator::HTML
349
422
  'charset' => @options.charset,
350
423
  'files' => gen_into(@files),
351
424
  'classes' => gen_into(@classes),
352
- 'title' => CGI.escapeHTML(@options.title),
425
+ 'title' => CGI.escapeHTML(@options.title),
353
426
  }
354
427
 
355
- # this method is defined in the template file
356
- write_extra_pages if defined? write_extra_pages
357
-
358
428
  template = RDoc::TemplatePage.new @template::ONE_PAGE
359
429
 
360
430
  if @options.op_name
@@ -372,26 +442,4 @@ class RDoc::Generator::HTMLInOne < RDoc::Generator::HTML
372
442
  end
373
443
  res
374
444
  end
375
-
376
- def gen_file_index
377
- gen_an_index(@files, 'Files')
378
- end
379
-
380
- def gen_class_index
381
- gen_an_index(@classes, 'Classes')
382
- end
383
-
384
- def gen_method_index
385
- gen_an_index(RDoc::Generator::Method.all_methods, 'Methods')
386
- end
387
-
388
- def gen_an_index(collection, title)
389
- return {
390
- "entries" => index_to_links(collection),
391
- 'list_title' => title,
392
- 'index_url' => main_url,
393
- }
394
- end
395
-
396
445
  end
397
-