Class RDoc::RDoc
In: lib/rdoc/rdoc.rb
Parent: Object

Encapsulate the production of rdoc documentation. Basically you can use this as you would invoke rdoc from the command line:

   rdoc = RDoc::RDoc.new
   rdoc.document(args)

where args is an array of strings, each corresponding to an argument you‘d give rdoc on the command line. See rdoc/rdoc.rb for details.

Methods

Constants

Generator = Struct.new(:file_name, :class_name, :key)   This is the list of output generators that we support
GENERATORS = {}

Public Instance methods

Format up one or more files according to the given arguments. For simplicity, argv is an array of strings, equivalent to the strings that would be passed on the command line. (This isn‘t a coincidence, as we do pass in ARGV when running interactively). For a list of options, see rdoc/rdoc.rb. By default, output will be stored in a directory called doc below the current directory, so make sure you‘re somewhere writable before invoking.

Throws: RDocError on error

[Source]

     # File lib/rdoc/rdoc.rb, line 249
249:     def document(argv)
250: 
251:       TopLevel::reset
252: 
253:       @stats = Stats.new
254: 
255:       options = Options.instance
256:       options.parse(argv, GENERATORS)
257: 
258:       @last_created = nil
259:       unless options.all_one_file
260:         @last_created = setup_output_dir(options.op_dir, options.force_update)
261:       end
262:       start_time = Time.now
263: 
264:       file_info = parse_files(options)
265: 
266:       if file_info.empty?
267:         $stderr.puts "\nNo newer files." unless options.quiet
268:       else
269:         gen = options.generator
270: 
271:         $stderr.puts "\nGenerating #{gen.key.upcase}..." unless options.quiet
272: 
273:         require gen.file_name
274: 
275:         gen_class = Generators.const_get(gen.class_name)
276:         gen = gen_class.for(options)
277: 
278:         pwd = Dir.pwd
279: 
280:         Dir.chdir(options.op_dir)  unless options.all_one_file
281: 
282:         begin
283:           Diagram.new(file_info, options).draw if options.diagram
284:           gen.generate(file_info)
285:           update_output_dir(".", start_time)
286:         ensure
287:           Dir.chdir(pwd)
288:         end
289:       end
290: 
291:       unless options.quiet
292:         puts
293:         @stats.print
294:       end
295:     end

Private Instance methods

Report an error message and exit

[Source]

     # File lib/rdoc/rdoc.rb, line 100
100:     def error(msg)
101:       raise RDocError.new(msg)
102:     end

Return a list of the files to be processed in a directory. We know that this directory doesn‘t have a .document file, so we‘re looking for real files. However we may well contain subdirectories which must be tested for .document files

[Source]

     # File lib/rdoc/rdoc.rb, line 202
202:     def list_files_in_directory(dir, options)
203:       normalized_file_list(options, Dir.glob(File.join(dir, "*")), false, options.exclude)
204:     end

Given a list of files and directories, create a list of all the Ruby files they contain.

If force_doc is true, we always add the given files. If false, only add files that we guarantee we can parse It is true when looking at files given on the command line, false when recursing through subdirectories.

The effect of this is that if you want a file with a non- standard extension parsed, you must name it explicity.

[Source]

     # File lib/rdoc/rdoc.rb, line 172
172:     def normalized_file_list(options, relative_files, force_doc = false, exclude_pattern=nil)
173:       file_list = []
174: 
175:       relative_files.each do |rel_file_name|
176:         next if exclude_pattern && exclude_pattern =~ rel_file_name
177:         stat = File.stat(rel_file_name)
178:         case type = stat.ftype
179:         when "file"
180:           next if @last_created and stat.mtime < @last_created
181:           file_list << rel_file_name.sub(/^\.\//, '') if force_doc || ParserFactory.can_parse(rel_file_name)
182:         when "directory"
183:           next if rel_file_name == "CVS" || rel_file_name == ".svn"
184:           dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
185:           if File.file?(dot_doc)
186:             file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
187:           else
188:             file_list.concat(list_files_in_directory(rel_file_name, options))
189:           end
190:         else
191:           raise RDocError.new("I can't deal with a #{type} #{rel_file_name}")
192:         end
193:       end
194:       file_list
195:     end

Return the path name of the flag file in an output directory.

[Source]

     # File lib/rdoc/rdoc.rb, line 139
139:     def output_flag_file(op_dir)
140:       File.join(op_dir, "created.rid")
141:     end

The .document file contains a list of file and directory name patterns, representing candidates for documentation. It may also contain comments (starting with ’#’)

[Source]

     # File lib/rdoc/rdoc.rb, line 146
146:     def parse_dot_doc_file(in_dir, filename, options)
147:       # read and strip comments
148:       patterns = File.read(filename).gsub(/#.*/, '')
149: 
150:       result = []
151: 
152:       patterns.split.each do |patt|
153:         candidates = Dir.glob(File.join(in_dir, patt))
154:         result.concat(normalized_file_list(options,  candidates))
155:       end
156:       result
157:     end

Parse each file on the command line, recursively entering directories

[Source]

     # File lib/rdoc/rdoc.rb, line 210
210:     def parse_files(options)
211:  
212:       file_info = []
213: 
214:       files = options.files
215:       files = ["."] if files.empty?
216: 
217:       file_list = normalized_file_list(options, files, true)
218: 
219:       file_list.each do |fn|
220:         $stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet
221:         
222:         content = File.open(fn, "r") {|f| f.read}
223: 
224:         top_level = TopLevel.new(fn)
225:         parser = ParserFactory.parser_for(top_level, fn, content, options, @stats)
226:         file_info << parser.scan
227:         @stats.num_files += 1
228:       end
229: 
230:       file_info
231:     end

Create an output dir if it doesn‘t exist. If it does exist, but doesn‘t contain the flag file created.rid then we refuse to use it, as we may clobber some manually generated documentation

[Source]

     # File lib/rdoc/rdoc.rb, line 110
110:     def setup_output_dir(op_dir, force)
111:       flag_file = output_flag_file(op_dir)
112:       if File.exist?(op_dir)
113:         unless File.directory?(op_dir)
114:           error "'#{op_dir}' exists, and is not a directory" 
115:         end
116:         begin
117:           created = File.read(flag_file)
118:         rescue SystemCallError
119:           error "\nDirectory #{op_dir} already exists, but it looks like it\n" +
120:             "isn't an RDoc directory. Because RDoc doesn't want to risk\n" +
121:             "destroying any of your existing files, you'll need to\n" +
122:             "specify a different output directory name (using the\n" +
123:             "--op <dir> option).\n\n"
124:         else
125:           last = (Time.parse(created) unless force rescue nil)
126:         end
127:       else
128:         File.makedirs(op_dir)
129:       end
130:       last
131:     end

Update the flag file in an output directory.

[Source]

     # File lib/rdoc/rdoc.rb, line 134
134:     def update_output_dir(op_dir, time)
135:       File.open(output_flag_file(op_dir), "w") {|f| f.puts time.rfc2822 }
136:     end

[Validate]