rdoc 2.0.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 (62) hide show
  1. data/History.txt +13 -0
  2. data/Manifest.txt +61 -0
  3. data/README.txt +34 -0
  4. data/Rakefile +10 -0
  5. data/bin/rdoc +22 -0
  6. data/bin/ri +6 -0
  7. data/lib/rdoc.rb +277 -0
  8. data/lib/rdoc/code_objects.rb +776 -0
  9. data/lib/rdoc/diagram.rb +338 -0
  10. data/lib/rdoc/dot.rb +249 -0
  11. data/lib/rdoc/generator.rb +1048 -0
  12. data/lib/rdoc/generator/chm.rb +113 -0
  13. data/lib/rdoc/generator/chm/chm.rb +98 -0
  14. data/lib/rdoc/generator/html.rb +370 -0
  15. data/lib/rdoc/generator/html/hefss.rb +414 -0
  16. data/lib/rdoc/generator/html/html.rb +704 -0
  17. data/lib/rdoc/generator/html/kilmer.rb +418 -0
  18. data/lib/rdoc/generator/html/one_page_html.rb +121 -0
  19. data/lib/rdoc/generator/ri.rb +229 -0
  20. data/lib/rdoc/generator/xml.rb +120 -0
  21. data/lib/rdoc/generator/xml/rdf.rb +113 -0
  22. data/lib/rdoc/generator/xml/xml.rb +111 -0
  23. data/lib/rdoc/markup.rb +473 -0
  24. data/lib/rdoc/markup/attribute_manager.rb +274 -0
  25. data/lib/rdoc/markup/formatter.rb +14 -0
  26. data/lib/rdoc/markup/fragments.rb +337 -0
  27. data/lib/rdoc/markup/inline.rb +101 -0
  28. data/lib/rdoc/markup/lines.rb +152 -0
  29. data/lib/rdoc/markup/preprocess.rb +71 -0
  30. data/lib/rdoc/markup/to_flow.rb +185 -0
  31. data/lib/rdoc/markup/to_html.rb +353 -0
  32. data/lib/rdoc/markup/to_html_crossref.rb +86 -0
  33. data/lib/rdoc/markup/to_latex.rb +328 -0
  34. data/lib/rdoc/markup/to_test.rb +50 -0
  35. data/lib/rdoc/options.rb +616 -0
  36. data/lib/rdoc/parsers/parse_c.rb +775 -0
  37. data/lib/rdoc/parsers/parse_f95.rb +1841 -0
  38. data/lib/rdoc/parsers/parse_rb.rb +2584 -0
  39. data/lib/rdoc/parsers/parse_simple.rb +40 -0
  40. data/lib/rdoc/parsers/parserfactory.rb +99 -0
  41. data/lib/rdoc/rdoc.rb +277 -0
  42. data/lib/rdoc/ri.rb +4 -0
  43. data/lib/rdoc/ri/cache.rb +188 -0
  44. data/lib/rdoc/ri/descriptions.rb +150 -0
  45. data/lib/rdoc/ri/display.rb +274 -0
  46. data/lib/rdoc/ri/driver.rb +452 -0
  47. data/lib/rdoc/ri/formatter.rb +616 -0
  48. data/lib/rdoc/ri/paths.rb +102 -0
  49. data/lib/rdoc/ri/reader.rb +106 -0
  50. data/lib/rdoc/ri/util.rb +81 -0
  51. data/lib/rdoc/ri/writer.rb +68 -0
  52. data/lib/rdoc/stats.rb +25 -0
  53. data/lib/rdoc/template.rb +64 -0
  54. data/lib/rdoc/tokenstream.rb +33 -0
  55. data/test/test_rdoc_c_parser.rb +261 -0
  56. data/test/test_rdoc_markup.rb +613 -0
  57. data/test/test_rdoc_markup_attribute_manager.rb +224 -0
  58. data/test/test_rdoc_ri_attribute_formatter.rb +42 -0
  59. data/test/test_rdoc_ri_default_display.rb +295 -0
  60. data/test/test_rdoc_ri_formatter.rb +318 -0
  61. data/test/test_rdoc_ri_overstrike_formatter.rb +69 -0
  62. metadata +134 -0
@@ -0,0 +1,102 @@
1
+ require 'rdoc/ri'
2
+
3
+ ##
4
+ # Encapsulate all the strangeness to do with finding out where to find RDoc
5
+ # files
6
+ #
7
+ # We basically deal with three directories:
8
+ #
9
+ # 1. The 'system' documentation directory, which holds the documentation
10
+ # distributed with Ruby, and which is managed by the Ruby install process
11
+ # 2. The 'site' directory, which contains site-wide documentation added
12
+ # locally.
13
+ # 3. The 'user' documentation directory, stored under the user's own home
14
+ # directory.
15
+ #
16
+ # There's contention about all this, but for now:
17
+ #
18
+ # system:: $datadir/ri/<ver>/system/...
19
+ # site:: $datadir/ri/<ver>/site/...
20
+ # user:: ~/.rdoc
21
+
22
+ module RDoc::RI::Paths
23
+
24
+ #:stopdoc:
25
+ require 'rbconfig'
26
+
27
+ DOC_DIR = "doc/rdoc"
28
+
29
+ version = RbConfig::CONFIG['ruby_version']
30
+
31
+ base = File.join(RbConfig::CONFIG['datadir'], "ri", version)
32
+ SYSDIR = File.join(base, "system")
33
+ SITEDIR = File.join(base, "site")
34
+ homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
35
+
36
+ if homedir then
37
+ HOMEDIR = File.join(homedir, ".rdoc")
38
+ else
39
+ HOMEDIR = nil
40
+ end
41
+
42
+ # This is the search path for 'ri'
43
+ PATH = [ SYSDIR, SITEDIR, HOMEDIR ].find_all {|p| p && File.directory?(p)}
44
+
45
+ begin
46
+ require 'rubygems' unless defined?(Gem) and defined?(Gem::Enable) and
47
+ Gem::Enable
48
+
49
+ # HACK dup'd from Gem.latest_partials and friends
50
+ all_paths = []
51
+
52
+ all_paths = Gem.path.map do |dir|
53
+ Dir[File.join(dir, 'doc', '*', 'ri')]
54
+ end.flatten
55
+
56
+ ri_paths = {}
57
+
58
+ all_paths.each do |dir|
59
+ base = File.basename File.dirname(dir)
60
+ if base =~ /(.*)-((\d+\.)*\d+)/ then
61
+ name, version = $1, $2
62
+ ver = Gem::Version.new version
63
+ if ri_paths[name].nil? or ver > ri_paths[name][0] then
64
+ ri_paths[name] = [ver, dir]
65
+ end
66
+ end
67
+ end
68
+
69
+ GEMDIRS = ri_paths.map { |k,v| v.last }.sort
70
+ GEMDIRS.each { |dir| PATH << dir }
71
+ rescue LoadError
72
+ GEMDIRS = []
73
+ end
74
+
75
+ # Returns the selected documentation directories as an Array, or PATH if no
76
+ # overriding directories were given.
77
+
78
+ def self.path(use_system, use_site, use_home, use_gems, *extra_dirs)
79
+ path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
80
+ return path.select { |directory| File.directory? directory }
81
+ end
82
+
83
+ # Returns the selected documentation directories including nonexistent
84
+ # directories. Used to print out what paths were searched if no ri was
85
+ # found.
86
+
87
+ def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)
88
+ return PATH unless use_system or use_site or use_home or use_gems or
89
+ not extra_dirs.empty?
90
+
91
+ path = []
92
+ path << extra_dirs unless extra_dirs.empty?
93
+ path << SYSDIR if use_system
94
+ path << SITEDIR if use_site
95
+ path << HOMEDIR if use_home
96
+ path << GEMDIRS if use_gems
97
+
98
+ return path.flatten.compact
99
+ end
100
+
101
+ end
102
+
@@ -0,0 +1,106 @@
1
+ require 'rdoc/ri'
2
+ require 'rdoc/ri/descriptions'
3
+ require 'rdoc/ri/writer'
4
+ require 'rdoc/markup/to_flow'
5
+
6
+ class RDoc::RI::Reader
7
+
8
+ def initialize(ri_cache)
9
+ @cache = ri_cache
10
+ end
11
+
12
+ def top_level_namespace
13
+ [ @cache.toplevel ]
14
+ end
15
+
16
+ def lookup_namespace_in(target, namespaces)
17
+ result = []
18
+ for n in namespaces
19
+ result.concat(n.contained_modules_matching(target))
20
+ end
21
+ result
22
+ end
23
+
24
+ def find_class_by_name(full_name)
25
+ names = full_name.split(/::/)
26
+ ns = @cache.toplevel
27
+ for name in names
28
+ ns = ns.contained_class_named(name)
29
+ return nil if ns.nil?
30
+ end
31
+ get_class(ns)
32
+ end
33
+
34
+ def find_methods(name, is_class_method, namespaces)
35
+ result = []
36
+ namespaces.each do |ns|
37
+ result.concat ns.methods_matching(name, is_class_method)
38
+ end
39
+ result
40
+ end
41
+
42
+ ##
43
+ # Return the MethodDescription for a given MethodEntry by deserializing the
44
+ # YAML
45
+
46
+ def get_method(method_entry)
47
+ path = method_entry.path_name
48
+ File.open(path) { |f| RI::Description.deserialize(f) }
49
+ end
50
+
51
+ ##
52
+ # Return a class description
53
+
54
+ def get_class(class_entry)
55
+ result = nil
56
+ for path in class_entry.path_names
57
+ path = RiWriter.class_desc_path(path, class_entry)
58
+ desc = File.open(path) {|f| RI::Description.deserialize(f) }
59
+ if result
60
+ result.merge_in(desc)
61
+ else
62
+ result = desc
63
+ end
64
+ end
65
+ result
66
+ end
67
+
68
+ ##
69
+ # Return the names of all classes and modules
70
+
71
+ def full_class_names
72
+ res = []
73
+ find_classes_in(res, @cache.toplevel)
74
+ end
75
+
76
+ ##
77
+ # Return a list of all classes, modules, and methods
78
+
79
+ def all_names
80
+ res = []
81
+ find_names_in(res, @cache.toplevel)
82
+ end
83
+
84
+ private
85
+
86
+ def find_classes_in(res, klass)
87
+ classes = klass.classes_and_modules
88
+ for c in classes
89
+ res << c.full_name
90
+ find_classes_in(res, c)
91
+ end
92
+ res
93
+ end
94
+
95
+ def find_names_in(res, klass)
96
+ classes = klass.classes_and_modules
97
+ for c in classes
98
+ res << c.full_name
99
+ res.concat c.all_method_names
100
+ find_names_in(res, c)
101
+ end
102
+ res
103
+ end
104
+
105
+ end
106
+
@@ -0,0 +1,81 @@
1
+ require 'rdoc/ri'
2
+
3
+ class RDoc::RI::Error < RuntimeError; end
4
+
5
+ ##
6
+ # Break argument into its constituent class or module names, an
7
+ # optional method type, and a method name
8
+
9
+ class RDoc::RI::NameDescriptor
10
+
11
+ attr_reader :class_names
12
+ attr_reader :method_name
13
+
14
+ ##
15
+ # true and false have the obvious meaning. nil means we don't care
16
+
17
+ attr_reader :is_class_method
18
+
19
+ ##
20
+ # +arg+ may be
21
+ #
22
+ # 1. A class or module name (optionally qualified with other class or module
23
+ # names (Kernel, File::Stat etc)
24
+ # 2. A method name
25
+ # 3. A method name qualified by a optionally fully qualified class or module
26
+ # name
27
+ #
28
+ # We're fairly casual about delimiters: folks can say Kernel::puts,
29
+ # Kernel.puts, or Kernel\#puts for example. There's one exception: if you
30
+ # say IO::read, we look for a class method, but if you say IO.read, we look
31
+ # for an instance method
32
+
33
+ def initialize(arg)
34
+ @class_names = []
35
+ separator = nil
36
+
37
+ tokens = arg.split(/(\.|::|#)/)
38
+
39
+ # Skip leading '::', '#' or '.', but remember it might
40
+ # be a method name qualifier
41
+ separator = tokens.shift if tokens[0] =~ /^(\.|::|#)/
42
+
43
+ # Skip leading '::', but remember we potentially have an inst
44
+
45
+ # leading stuff must be class names
46
+
47
+ while tokens[0] =~ /^[A-Z]/
48
+ @class_names << tokens.shift
49
+ unless tokens.empty?
50
+ separator = tokens.shift
51
+ break unless separator == "::"
52
+ end
53
+ end
54
+
55
+ # Now must have a single token, the method name, or an empty array
56
+ unless tokens.empty?
57
+ @method_name = tokens.shift
58
+ # We may now have a trailing !, ?, or = to roll into
59
+ # the method name
60
+ if !tokens.empty? && tokens[0] =~ /^[!?=]$/
61
+ @method_name << tokens.shift
62
+ end
63
+
64
+ if @method_name =~ /::|\.|#/ or !tokens.empty?
65
+ raise RDoc::RI::Error.new("Bad argument: #{arg}")
66
+ end
67
+ if separator && separator != '.'
68
+ @is_class_method = separator == "::"
69
+ end
70
+ end
71
+ end
72
+
73
+ # Return the full class name (with '::' between the components) or "" if
74
+ # there's no class name
75
+
76
+ def full_class_name
77
+ @class_names.join("::")
78
+ end
79
+
80
+ end
81
+
@@ -0,0 +1,68 @@
1
+ require 'fileutils'
2
+ require 'rdoc/ri'
3
+
4
+ class RDoc::RI::Writer
5
+
6
+ def self.class_desc_path(dir, class_desc)
7
+ File.join(dir, "cdesc-" + class_desc.name + ".yaml")
8
+ end
9
+
10
+ ##
11
+ # Convert a name from internal form (containing punctuation) to an external
12
+ # form (where punctuation is replaced by %xx)
13
+
14
+ def self.internal_to_external(name)
15
+ if ''.respond_to? :ord then
16
+ name.gsub(/\W/) { "%%%02x" % $&[0].ord }
17
+ else
18
+ name.gsub(/\W/) { "%%%02x" % $&[0] }
19
+ end
20
+ end
21
+
22
+ ##
23
+ # And the reverse operation
24
+
25
+ def self.external_to_internal(name)
26
+ name.gsub(/%([0-9a-f]{2,2})/) { $1.to_i(16).chr }
27
+ end
28
+
29
+ def initialize(base_dir)
30
+ @base_dir = base_dir
31
+ end
32
+
33
+ def remove_class(class_desc)
34
+ FileUtils.rm_rf(path_to_dir(class_desc.full_name))
35
+ end
36
+
37
+ def add_class(class_desc)
38
+ dir = path_to_dir(class_desc.full_name)
39
+ FileUtils.mkdir_p(dir)
40
+ class_file_name = self.class.class_desc_path(dir, class_desc)
41
+ File.open(class_file_name, "w") do |f|
42
+ f.write(class_desc.serialize)
43
+ end
44
+ end
45
+
46
+ def add_method(class_desc, method_desc)
47
+ dir = path_to_dir(class_desc.full_name)
48
+ file_name = self.class.internal_to_external(method_desc.name)
49
+ meth_file_name = File.join(dir, file_name)
50
+ if method_desc.is_singleton
51
+ meth_file_name += "-c.yaml"
52
+ else
53
+ meth_file_name += "-i.yaml"
54
+ end
55
+
56
+ File.open(meth_file_name, "w") do |f|
57
+ f.write(method_desc.serialize)
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def path_to_dir(class_name)
64
+ File.join(@base_dir, *class_name.split('::'))
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,25 @@
1
+ require 'rdoc'
2
+
3
+ ##
4
+ # Simple stats collector
5
+
6
+ class RDoc::Stats
7
+
8
+ attr_accessor :num_files, :num_classes, :num_modules, :num_methods
9
+
10
+ def initialize
11
+ @num_files = @num_classes = @num_modules = @num_methods = 0
12
+ @start = Time.now
13
+ end
14
+
15
+ def print
16
+ puts "Files: #@num_files"
17
+ puts "Classes: #@num_classes"
18
+ puts "Modules: #@num_modules"
19
+ puts "Methods: #@num_methods"
20
+ puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start)
21
+ end
22
+
23
+ end
24
+
25
+
@@ -0,0 +1,64 @@
1
+ require 'erb'
2
+
3
+ module RDoc; end
4
+
5
+ ##
6
+ # An ERb wrapper that allows nesting of one ERb template inside another.
7
+ #
8
+ # This TemplatePage operates similarly to RDoc 1.x's TemplatePage, but uses
9
+ # ERb instead of a custom template language.
10
+ #
11
+ # Converting from a RDoc 1.x template to an RDoc 2.x template is fairly easy.
12
+ #
13
+ # * %blah% becomes <%= values["blah"] %>
14
+ # * !INCLUDE! becomes <%= template_include %>
15
+ # * HREF:aref:name becomes <%= href values["aref"], values["name"] %>
16
+ # * IF:blah becomes <% if values["blah"] then %>
17
+ # * IFNOT:blah becomes <% unless values["blah"] then %>
18
+ # * ENDIF:blah becomes <% end %>
19
+ # * START:blah becomes <% values["blah"].each do |blah| %>
20
+ # * END:blah becomes <% end %>
21
+ #
22
+ # To make nested loops easier to convert, start by converting START statements
23
+ # to:
24
+ #
25
+ # <% values["blah"].each do |blah| $stderr.puts blah.keys %>
26
+ #
27
+ # So you can see what is being used inside which loop.
28
+
29
+ class RDoc::TemplatePage
30
+
31
+ ##
32
+ # Create a new TemplatePage that will use +templates+.
33
+
34
+ def initialize(*templates)
35
+ @templates = templates
36
+ end
37
+
38
+ ##
39
+ # Returns "<a href=\"#{ref}\">#{name}</a>"
40
+
41
+ def href(ref, name)
42
+ if ref then
43
+ "<a href=\"#{ref}\">#{name}</a>"
44
+ else
45
+ name
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Process the template using +values+, writing the result to +io+.
51
+
52
+ def write_html_on(io, values)
53
+ b = binding
54
+ template_include = ""
55
+
56
+ @templates.reverse_each do |template|
57
+ template_include = ERB.new(template).result b
58
+ end
59
+
60
+ io.write template_include
61
+ end
62
+
63
+ end
64
+