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
@@ -30,7 +30,7 @@ class RDoc::Markup::ToTexInfo < RDoc::Markup::Formatter
30
30
 
31
31
  def accept_heading(attributes, text)
32
32
  heading = ['@majorheading', '@chapheading'][text.head_level - 1] || '@heading'
33
- @text << "#{heading}{#{format(text)}}"
33
+ @text << "#{heading} #{format(text)}"
34
34
  end
35
35
 
36
36
  def accept_list_start(attributes, text)
data/lib/rdoc/parser.rb CHANGED
@@ -62,11 +62,32 @@ class RDoc::Parser
62
62
  true
63
63
  end
64
64
 
65
+ ##
66
+ # Shamelessly stolen from the ptools gem (since RDoc cannot depend on
67
+ # the gem).
68
+
69
+ def self.binary?(file)
70
+ s = (File.read(file, File.stat(file).blksize) || "").split(//)
71
+ ((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30
72
+ end
73
+ private_class_method :binary?
74
+
65
75
  ##
66
76
  # Return a parser that can handle a particular extension
67
77
 
68
78
  def self.can_parse(file_name)
69
- RDoc::Parser.parsers.find { |regexp, parser| regexp =~ file_name }.last
79
+ parser = RDoc::Parser.parsers.find { |regexp, parser| regexp =~ file_name }.last
80
+
81
+ #
82
+ # The default parser should *NOT* parse binary files.
83
+ #
84
+ if parser == RDoc::Parser::Simple then
85
+ if binary? file_name then
86
+ return nil
87
+ end
88
+ end
89
+
90
+ return parser
70
91
  end
71
92
 
72
93
  ##
data/lib/rdoc/parser/c.rb CHANGED
@@ -270,7 +270,7 @@ class RDoc::Parser::C < RDoc::Parser
270
270
  def find_body(meth_name, meth_obj, body, quiet = false)
271
271
  case body
272
272
  when %r"((?>/\*.*?\*/\s*))(?:static\s+)?VALUE\s+#{meth_name}
273
- \s*(\([^)]*\))\s*\{.*?^\}"xm
273
+ \s*(\([^)]*\))([^;]|$)"xm
274
274
  comment, params = $1, $2
275
275
  body_text = $&
276
276
 
@@ -279,9 +279,7 @@ class RDoc::Parser::C < RDoc::Parser
279
279
  # see if we can find the whole body
280
280
 
281
281
  re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}'
282
- if Regexp.new(re, Regexp::MULTILINE).match(body)
283
- body_text = $&
284
- end
282
+ body_text = $& if /#{re}/m =~ body
285
283
 
286
284
  # The comment block may have been overridden with a 'Document-method'
287
285
  # block. This happens in the interpreter when multiple methods are
@@ -562,18 +560,16 @@ class RDoc::Parser::C < RDoc::Parser
562
560
 
563
561
  return unless class_name
564
562
 
565
- class_obj = find_class(var_name, class_name)
563
+ class_obj = find_class var_name, class_name
566
564
 
567
- if class_obj
568
- if meth_name == "initialize"
565
+ if class_obj then
566
+ if meth_name == "initialize" then
569
567
  meth_name = "new"
570
568
  type = "singleton_method"
571
569
  end
572
- meth_obj = RDoc::AnyMethod.new("", meth_name)
573
- meth_obj.singleton =
574
- %w{singleton_method module_function}.include?(type)
575
570
 
576
- @stats.add_method meth_obj
571
+ meth_obj = RDoc::AnyMethod.new '', meth_name
572
+ meth_obj.singleton = %w[singleton_method module_function].include? type
577
573
 
578
574
  p_count = (Integer(param_count) rescue -1)
579
575
 
@@ -585,14 +581,16 @@ class RDoc::Parser::C < RDoc::Parser
585
581
  meth_obj.params = "(" + (1..p_count).map{|i| "p#{i}"}.join(", ") + ")"
586
582
  end
587
583
 
588
- if source_file
584
+ if source_file then
589
585
  file_name = File.join(@file_dir, source_file)
590
586
  body = (@@known_bodies[source_file] ||= File.read(file_name))
591
587
  else
592
588
  body = @content
593
589
  end
594
- if find_body(meth_body, meth_obj, body) and meth_obj.document_self
595
- class_obj.add_method(meth_obj)
590
+
591
+ if find_body(meth_body, meth_obj, body) and meth_obj.document_self then
592
+ class_obj.add_method meth_obj
593
+ @stats.add_method meth_obj
596
594
  end
597
595
  end
598
596
  end
@@ -628,8 +626,8 @@ class RDoc::Parser::C < RDoc::Parser
628
626
  end
629
627
 
630
628
  def remove_private_comments(comment)
631
- comment.gsub!(/\/?\*--(.*?)\/?\*\+\+/m, '')
632
- comment.sub!(/\/?\*--.*/m, '')
629
+ comment.gsub!(/\/?\*--\n(.*?)\/?\*\+\+/m, '')
630
+ comment.sub!(/\/?\*--\n.*/m, '')
633
631
  end
634
632
 
635
633
  ##
@@ -134,7 +134,7 @@ module RDoc::RubyToken
134
134
 
135
135
  TokenDefinitions = [
136
136
  [:TkCLASS, TkKW, "class", EXPR_CLASS],
137
- [:TkMODULE, TkKW, "module", EXPR_BEG],
137
+ [:TkMODULE, TkKW, "module", EXPR_CLASS],
138
138
  [:TkDEF, TkKW, "def", EXPR_FNAME],
139
139
  [:TkUNDEF, TkKW, "undef", EXPR_FNAME],
140
140
  [:TkBEGIN, TkKW, "begin", EXPR_BEG],
@@ -2683,8 +2683,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
2683
2683
  end
2684
2684
 
2685
2685
  def remove_private_comments(comment)
2686
- comment.gsub!(/^#--.*?^#\+\+/m, '')
2687
- comment.sub!(/^#--.*/m, '')
2686
+ comment.gsub!(/^#--\n.*?^#\+\+/m, '')
2687
+ comment.sub!(/^#--\n.*/m, '')
2688
2688
  end
2689
2689
 
2690
2690
  def remove_token_listener(obj)
@@ -31,7 +31,7 @@ class RDoc::Parser::Simple < RDoc::Parser
31
31
  end
32
32
 
33
33
  def remove_private_comments(comment)
34
- comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
34
+ comment.gsub(/^--\n.*?^\+\+/m, '').sub(/^--\n.*/m, '')
35
35
  end
36
36
 
37
37
  end
data/lib/rdoc/rdoc.rb CHANGED
@@ -288,6 +288,5 @@ module RDoc
288
288
  end
289
289
  end
290
290
  end
291
-
292
291
  end
293
292
 
data/lib/rdoc/ri/cache.rb CHANGED
@@ -14,7 +14,7 @@ class RDoc::RI::ClassEntry
14
14
  @inferior_classes = []
15
15
  end
16
16
 
17
- # We found this class in more tha one place, so add
17
+ # We found this class in more than one place, so add
18
18
  # in the name from there.
19
19
  def add_path(path)
20
20
  @path_names << path
@@ -37,10 +37,10 @@ class RDoc::RI::ClassEntry
37
37
  if name =~ /^(.*?)-(c|i).yaml$/
38
38
  external_name = $1
39
39
  is_class_method = $2 == "c"
40
- internal_name = RiWriter.external_to_internal(external_name)
40
+ internal_name = RDoc::RI::Writer.external_to_internal(external_name)
41
41
  list = is_class_method ? @class_methods : @instance_methods
42
42
  path = File.join(dir, name)
43
- list << MethodEntry.new(path, internal_name, is_class_method, self)
43
+ list << RDoc::RI::MethodEntry.new(path, internal_name, is_class_method, self)
44
44
  else
45
45
  full_name = File.join(dir, name)
46
46
  if File.directory?(full_name)
@@ -48,7 +48,7 @@ class RDoc::RI::ClassEntry
48
48
  if inf_class
49
49
  inf_class.add_path(full_name)
50
50
  else
51
- inf_class = ClassEntry.new(full_name, name, self)
51
+ inf_class = RDoc::RI::ClassEntry.new(full_name, name, self)
52
52
  @inferior_classes << inf_class
53
53
  end
54
54
  inf_class.load_from(full_name)
@@ -168,7 +168,7 @@ class RDoc::RI::MethodEntry
168
168
  end
169
169
 
170
170
  ##
171
- # We represent everything know about all 'ri' files accessible to this program
171
+ # We represent everything known about all 'ri' files accessible to this program
172
172
 
173
173
  class RDoc::RI::Cache
174
174
 
@@ -185,4 +185,3 @@ class RDoc::RI::Cache
185
185
  end
186
186
 
187
187
  end
188
-
@@ -77,7 +77,9 @@ end
77
77
  class RDoc::RI::ModuleDescription < RDoc::RI::Description
78
78
 
79
79
  attr_accessor :class_methods
80
+ attr_accessor :class_method_extensions
80
81
  attr_accessor :instance_methods
82
+ attr_accessor :instance_method_extensions
81
83
  attr_accessor :attributes
82
84
  attr_accessor :constants
83
85
  attr_accessor :includes
@@ -148,6 +150,7 @@ class RDoc::RI::MethodDescription < RDoc::RI::Description
148
150
  attr_accessor :aliases
149
151
  attr_accessor :is_alias_for
150
152
  attr_accessor :params
153
+ attr_accessor :source_path
151
154
 
152
155
  end
153
156
 
@@ -1,5 +1,15 @@
1
1
  require 'rdoc/ri'
2
2
 
3
+ # readline support might not be present, so be careful
4
+ # when requiring it.
5
+ begin
6
+ require('readline')
7
+ require('abbrev')
8
+ CAN_USE_READLINE = true
9
+ rescue
10
+ CAN_USE_READLINE = false
11
+ end
12
+
3
13
  ##
4
14
  # This is a kind of 'flag' module. If you want to write your own 'ri' display
5
15
  # module (perhaps because you're writing an IDE), you write a class which
@@ -41,7 +51,7 @@ class RDoc::RI::DefaultDisplay
41
51
  # Display information about +klass+. Fetches additional information from
42
52
  # +ri_reader+ as necessary.
43
53
 
44
- def display_class_info(klass, ri_reader)
54
+ def display_class_info(klass)
45
55
  page do
46
56
  superclass = klass.superclass_string
47
57
 
@@ -61,17 +71,11 @@ class RDoc::RI::DefaultDisplay
61
71
  @formatter.blankline
62
72
  @formatter.display_heading("Includes:", 2, "")
63
73
  incs = []
74
+
64
75
  klass.includes.each do |inc|
65
- inc_desc = ri_reader.find_class_by_name(inc.name)
66
- if inc_desc
67
- str = inc.name + "("
68
- str << inc_desc.instance_methods.map{|m| m.name}.join(", ")
69
- str << ")"
70
- incs << str
71
- else
72
- incs << inc.name
73
- end
74
- end
76
+ incs << inc.name
77
+ end
78
+
75
79
  @formatter.wrap(incs.sort.join(', '))
76
80
  end
77
81
 
@@ -94,27 +98,6 @@ class RDoc::RI::DefaultDisplay
94
98
  end
95
99
  end
96
100
 
97
- class_data = [
98
- :class_methods,
99
- :class_method_extensions,
100
- :instance_methods,
101
- :instance_method_extensions,
102
- ]
103
-
104
- class_data.each do |data_type|
105
- data = klass.send data_type
106
-
107
- unless data.empty? then
108
- @formatter.blankline
109
-
110
- heading = data_type.to_s.split('_').join(' ').capitalize << ':'
111
- @formatter.display_heading heading, 2, ''
112
-
113
- data = data.map { |item| item.name }.sort.join ', '
114
- @formatter.wrap data
115
- end
116
- end
117
-
118
101
  unless klass.attributes.empty? then
119
102
  @formatter.blankline
120
103
 
@@ -133,8 +116,115 @@ class RDoc::RI::DefaultDisplay
133
116
  end
134
117
  end
135
118
  end
119
+
120
+ return display_class_method_list(klass)
136
121
  end
137
122
  end
123
+
124
+ ##
125
+ # Given a Hash mapping a class' methods to method types (returned by
126
+ # display_class_method_list), this method allows the user to
127
+ # choose one of the methods.
128
+
129
+ def get_class_method_choice(method_map)
130
+ if CAN_USE_READLINE
131
+ # prepare abbreviations for tab completion
132
+ abbreviations = method_map.keys.abbrev
133
+ Readline.completion_proc = proc do |string|
134
+ abbreviations.values.uniq.grep(/^#{string}/)
135
+ end
136
+ end
137
+
138
+ @formatter.raw_print_line "\nEnter the method name you want.\n"
139
+ @formatter.raw_print_line "Class methods can be preceeded by '::' and instance methods by '#'.\n"
140
+
141
+ if CAN_USE_READLINE
142
+ @formatter.raw_print_line "You can use tab to autocomplete.\n"
143
+ @formatter.raw_print_line "Enter a blank line to exit.\n"
144
+
145
+ choice_string = Readline.readline(">> ").strip
146
+ else
147
+ @formatter.raw_print_line "Enter a blank line to exit.\n"
148
+ @formatter.raw_print_line ">> "
149
+ choice_string = $stdin.gets.strip
150
+ end
151
+
152
+ if choice_string == ''
153
+ return nil
154
+ else
155
+ class_or_instance = method_map[choice_string]
156
+
157
+ if class_or_instance
158
+ # If the user's choice is not preceeded by a '::' or a '#', figure
159
+ # out whether they want a class or an instance method and decorate
160
+ # the choice appropriately.
161
+ if(choice_string =~ /^[a-zA-Z]/)
162
+ if(class_or_instance == :class)
163
+ choice_string = "::#{choice_string}"
164
+ else
165
+ choice_string = "##{choice_string}"
166
+ end
167
+ end
168
+
169
+ return choice_string
170
+ else
171
+ @formatter.raw_print_line "No method matched '#{choice_string}'.\n"
172
+ return nil
173
+ end
174
+ end
175
+ end
176
+
177
+
178
+ ##
179
+ # Display methods on +klass+
180
+ # Returns a hash mapping method name to method contents (HACK?)
181
+
182
+ def display_class_method_list(klass)
183
+ method_map = {}
184
+
185
+ class_data = [
186
+ :class_methods,
187
+ :class_method_extensions,
188
+ :instance_methods,
189
+ :instance_method_extensions,
190
+ ]
191
+
192
+ class_data.each do |data_type|
193
+ data = klass.send data_type
194
+
195
+ unless data.nil? or data.empty? then
196
+ @formatter.blankline
197
+
198
+ heading = data_type.to_s.split('_').join(' ').capitalize << ':'
199
+ @formatter.display_heading heading, 2, ''
200
+
201
+ method_names = []
202
+ data.each do |item|
203
+ method_names << item.name
204
+
205
+ if(data_type == :class_methods ||
206
+ data_type == :class_method_extensions) then
207
+ method_map["::#{item.name}"] = :class
208
+ method_map[item.name] = :class
209
+ else
210
+ #
211
+ # Since we iterate over instance methods after class methods,
212
+ # an instance method always will overwrite the unqualified
213
+ # class method entry for a class method of the same name.
214
+ #
215
+ method_map["##{item.name}"] = :instance
216
+ method_map[item.name] = :instance
217
+ end
218
+ end
219
+ method_names.sort!
220
+
221
+ @formatter.wrap method_names.join(',')
222
+ end
223
+ end
224
+
225
+ method_map
226
+ end
227
+ private :display_class_method_list
138
228
 
139
229
  ##
140
230
  # Display an Array of RDoc::Markup::Flow objects, +flow+.
@@ -172,10 +262,42 @@ class RDoc::RI::DefaultDisplay
172
262
  def display_method_list(methods)
173
263
  page do
174
264
  @formatter.wrap "More than one method matched your request. You can refine your search by asking for information on one of:"
265
+ @formatter.blankline
266
+
267
+ methods.each do |method|
268
+ @formatter.raw_print_line "#{method.full_name} [#{method.source_path}]\n"
269
+ end
270
+ end
271
+ end
272
+
273
+ ##
274
+ # Display a list of +methods+ and allow the user to select one of them.
175
275
 
276
+ def display_method_list_choice(methods)
277
+ page do
278
+ @formatter.wrap "More than one method matched your request. Please choose one of the possible matches."
176
279
  @formatter.blankline
177
280
 
178
- @formatter.wrap methods.map { |m| m.full_name }.join(", ")
281
+ methods.each_with_index do |method, index|
282
+ @formatter.raw_print_line "%3d %s [%s]\n" % [index + 1, method.full_name, method.source_path]
283
+ end
284
+
285
+ @formatter.raw_print_line ">> "
286
+
287
+ choice = $stdin.gets.strip!
288
+
289
+ if(choice == '')
290
+ return
291
+ end
292
+
293
+ choice = choice.to_i
294
+
295
+ if ((choice == 0) || (choice > methods.size)) then
296
+ @formatter.raw_print_line "Invalid choice!\n"
297
+ else
298
+ method = methods[choice - 1]
299
+ display_method_info(method)
300
+ end
179
301
  end
180
302
  end
181
303
 
@@ -198,10 +320,8 @@ class RDoc::RI::DefaultDisplay
198
320
  @formatter.break_to_newline
199
321
  end
200
322
 
201
- if method.source_path then
202
- @formatter.blankline
203
- @formatter.wrap("Extension from #{method.source_path}")
204
- end
323
+ @formatter.blankline
324
+ @formatter.wrap("From #{method.source_path}")
205
325
  end
206
326
 
207
327
  ##