Class RDoc::Generator::RI
In: generator/ri.rb
Parent: Object

Methods

Public Class methods

Generator may need to return specific subclasses depending on the options they are passed. Because of this we create them using a factory

[Source]

    # File generator/ri.rb, line 15
15:   def self.for(options)
16:     new(options)
17:   end

Set up a new RDoc::Generator::RI.

[Source]

    # File generator/ri.rb, line 26
26:   def initialize(options) #:not-new:
27:     @options   = options
28:     @ri_writer = RDoc::RI::Writer.new "."
29:     @markup    = RDoc::Markup.new
30:     @to_flow   = RDoc::Markup::ToFlow.new
31: 
32:     @generated = {}
33:   end

Public Instance methods

Build the initial indices and output objects based on an array of TopLevel objects containing the extracted information.

[Source]

    # File generator/ri.rb, line 39
39:   def generate(toplevels)
40:     RDoc::TopLevel.all_classes_and_modules.each do |cls|
41:       process_class cls
42:     end
43:   end

[Source]

    # File generator/ri.rb, line 54
54:   def generate_class_info(cls)
55:     if cls === RDoc::NormalModule
56:       cls_desc = RDoc::RI::ModuleDescription.new
57:     else
58:       cls_desc = RDoc::RI::ClassDescription.new
59:       cls_desc.superclass  = cls.superclass
60:     end
61: 
62:     cls_desc.name        = cls.name
63:     cls_desc.full_name   = cls.full_name
64:     cls_desc.comment     = markup(cls.comment)
65: 
66:     cls_desc.attributes = cls.attributes.sort.map do |a|
67:       RDoc::RI::Attribute.new(a.name, a.rw, markup(a.comment))
68:     end
69: 
70:     cls_desc.constants = cls.constants.map do |c|
71:       RDoc::RI::Constant.new(c.name, c.value, markup(c.comment))
72:     end
73: 
74:     cls_desc.includes = cls.includes.map do |i|
75:       RDoc::RI::IncludedModule.new(i.name)
76:     end
77: 
78:     class_methods, instance_methods = method_list(cls)
79: 
80:     cls_desc.class_methods = class_methods.map do |m|
81:       RDoc::RI::MethodSummary.new(m.name)
82:     end
83: 
84:     cls_desc.instance_methods = instance_methods.map do |m|
85:       RDoc::RI::MethodSummary.new(m.name)
86:     end
87: 
88:     update_or_replace(cls_desc)
89: 
90:     class_methods.each do |m|
91:       generate_method_info(cls_desc, m)
92:     end
93: 
94:     instance_methods.each do |m|
95:       generate_method_info(cls_desc, m)
96:     end
97:   end

[Source]

     # File generator/ri.rb, line 99
 99:   def generate_method_info(cls_desc, method)
100:     meth_desc = RDoc::RI::MethodDescription.new
101:     meth_desc.name = method.name
102:     meth_desc.full_name = cls_desc.full_name
103:     if method.singleton
104:       meth_desc.full_name += "::"
105:     else
106:       meth_desc.full_name += "#"
107:     end
108:     meth_desc.full_name << method.name
109: 
110:     meth_desc.comment = markup(method.comment)
111:     meth_desc.params = params_of(method)
112:     meth_desc.visibility = method.visibility.to_s
113:     meth_desc.is_singleton = method.singleton
114:     meth_desc.block_params = method.block_params
115: 
116:     meth_desc.aliases = method.aliases.map do |a|
117:       RDoc::RI::AliasName.new(a.name)
118:     end
119: 
120:     @ri_writer.add_method(cls_desc, meth_desc)
121:   end

[Source]

     # File generator/ri.rb, line 170
170:   def markup(comment)
171:     return nil if !comment || comment.empty?
172: 
173:     # Convert leading comment markers to spaces, but only
174:     # if all non-blank lines have them
175: 
176:     if comment =~ /^(?>\s*)[^\#]/
177:       content = comment
178:     else
179:       content = comment.gsub(/^\s*(#+)/)  { $1.tr('#',' ') }
180:     end
181:     @markup.convert(content, @to_flow)
182:   end

Returns a list of class and instance methods that we‘ll be documenting

[Source]

     # File generator/ri.rb, line 128
128:   def method_list(cls)
129:     list = cls.method_list
130:     unless @options.show_all
131:       list = list.find_all do |m|
132:         m.visibility == :public || m.visibility == :protected || m.force_documentation
133:       end
134:     end
135: 
136:     c = []
137:     i = []
138:     list.sort.each do |m|
139:       if m.singleton
140:         c << m
141:       else
142:         i << m
143:       end
144:     end
145:     return c,i
146:   end

[Source]

     # File generator/ri.rb, line 148
148:   def params_of(method)
149:     if method.call_seq
150:       method.call_seq
151:     else
152:       params = method.params || ""
153: 
154:       p = params.gsub(/\s*\#.*/, '')
155:       p = p.tr("\n", " ").squeeze(" ")
156:       p = "(" + p + ")" unless p[0] == ?(
157: 
158:       if (block = method.block_params)
159:         block.gsub!(/\s*\#.*/, '')
160:         block = block.tr("\n", " ").squeeze(" ")
161:         if block[0] == ?(
162:           block.sub!(/^\(/, '').sub!(/\)/, '')
163:         end
164:         p << " {|#{block.strip}| ...}"
165:       end
166:       p
167:     end
168:   end

[Source]

    # File generator/ri.rb, line 45
45:   def process_class(from_class)
46:     generate_class_info(from_class)
47: 
48:     # now recure into this classes constituent classess
49:     from_class.each_classmodule do |mod|
50:       process_class(mod)
51:     end
52:   end

By default we replace existing classes with the same name. If the —merge option was given, we instead merge this definition into an existing class. We add our methods, aliases, etc to that class, but do not change the class‘s description.

[Source]

     # File generator/ri.rb, line 190
190:   def update_or_replace(cls_desc)
191:     old_cls = nil
192: 
193:     if @options.merge
194:       rdr = RDoc::RI::Reader.new RDoc::RI::Cache.new(@options.op_dir)
195: 
196:       namespace = rdr.top_level_namespace
197:       namespace = rdr.lookup_namespace_in(cls_desc.name, namespace)
198:       if namespace.empty?
199:         $stderr.puts "You asked me to merge this source into existing "
200:         $stderr.puts "documentation. This file references a class or "
201:         $stderr.puts "module called #{cls_desc.name} which I don't"
202:         $stderr.puts "have existing documentation for."
203:         $stderr.puts
204:         $stderr.puts "Perhaps you need to generate its documentation first"
205:         exit 1
206:       else
207:         old_cls = namespace[0]
208:       end
209:     end
210: 
211:     prev_cls = @generated[cls_desc.full_name]
212: 
213:     if old_cls and not prev_cls then
214:       old_desc = rdr.get_class old_cls
215:       cls_desc.merge_in old_desc
216:     end
217: 
218:     if prev_cls then
219:       cls_desc.merge_in prev_cls
220:     end
221: 
222:     @generated[cls_desc.full_name] = cls_desc
223: 
224:     @ri_writer.remove_class cls_desc
225:     @ri_writer.add_class cls_desc
226:   end

[Validate]