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.
This is the list of output generator that we support
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: RDoc::Error on error
# File rdoc/rdoc.rb, line 243
def document(argv)
TopLevel::reset
@options = Options.new GENERATORS
@options.parse argv
@last_created = nil
unless @options.all_one_file then
@last_created = setup_output_dir @options.op_dir, @options.force_update
end
start_time = Time.now
file_info = parse_files @options
@options.title = "RDoc Documentation"
if file_info.empty?
$stderr.puts "\nNo newer files." unless @options.quiet
else
@gen = @options.generator
$stderr.puts "\nGenerating #{@gen.key.upcase}..." unless @options.quiet
require @gen.file_name
gen_class = ::RDoc::Generator.const_get @gen.class_name
@gen = gen_class.for @options
pwd = Dir.pwd
Dir.chdir @options.op_dir unless @options.all_one_file
begin
Diagram.new(file_info, @options).draw if @options.diagram
@gen.generate(file_info)
update_output_dir(".", start_time)
ensure
Dir.chdir(pwd)
end
end
unless @options.quiet
puts
@stats.print
end
end
Report an error message and exit
# File rdoc/rdoc.rb, line 70
def error(msg)
raise ::RDoc::Error, msg
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.
# File rdoc/rdoc.rb, line 182
def list_files_in_directory(dir, options)
files = Dir.glob File.join(dir, "*")
normalized_file_list options, files, false, options.exclude
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 explicitly.
# File rdoc/rdoc.rb, line 146
def normalized_file_list(options, relative_files, force_doc = false,
exclude_pattern = nil)
file_list = []
relative_files.each do |rel_file_name|
next if exclude_pattern && exclude_pattern =~ rel_file_name
stat = File.stat(rel_file_name)
case type = stat.ftype
when "file"
next if @last_created and stat.mtime < @last_created
if force_doc or ::RDoc::Parser.can_parse(rel_file_name) then
file_list << rel_file_name.sub(/^\.\//, '')
end
when "directory"
next if rel_file_name == "CVS" || rel_file_name == ".svn"
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
if File.file?(dot_doc)
file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))
else
file_list.concat(list_files_in_directory(rel_file_name, options))
end
else
raise RDoc::Error, "I can't deal with a #{type} #{rel_file_name}"
end
end
file_list
end
Return the path name of the flag file in an output directory.
# File rdoc/rdoc.rb, line 112
def output_flag_file(op_dir)
File.join(op_dir, "created.rid")
end
The .document file contains a list of file and directory name patterns, representing candidates for documentation. It may also contain comments (starting with ‘#’)
# File rdoc/rdoc.rb, line 121
def parse_dot_doc_file(in_dir, filename, options)
# read and strip comments
patterns = File.read(filename).gsub(/#.*/, '')
result = []
patterns.split.each do |patt|
candidates = Dir.glob(File.join(in_dir, patt))
result.concat(normalized_file_list(options, candidates))
end
result
end
Parse each file on the command line, recursively entering directories.
# File rdoc/rdoc.rb, line 191
def parse_files(options)
@stats = Stats.new options.verbosity
files = options.files
files = ["."] if files.empty?
file_list = normalized_file_list(options, files, true, options.exclude)
return [] if file_list.empty?
file_info = []
file_list.each do |filename|
@stats.add_file filename
content = if RUBY_VERSION >= '1.9' then
File.open(filename, "r:ascii-8bit") { |f| f.read }
else
File.read filename
end
if defined? Encoding then
if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
if enc = ::Encoding.find($1)
content.force_encoding(enc)
end
end
end
top_level = ::RDoc::TopLevel.new filename
parser = ::RDoc::Parser.for top_level, filename, content, options,
@stats
file_info << parser.scan
end
file_info
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
# File rdoc/rdoc.rb, line 79
def setup_output_dir(op_dir, force)
flag_file = output_flag_file(op_dir)
if File.exist?(op_dir)
unless File.directory?(op_dir)
error "'#{op_dir}' exists, and is not a directory"
end
begin
created = File.read(flag_file)
rescue SystemCallError
error "\nDirectory #{op_dir} already exists, but it looks like it\n" +
"isn't an RDoc directory. Because RDoc doesn't want to risk\n" +
"destroying any of your existing files, you'll need to\n" +
"specify a different output directory name (using the\n" +
"--op <dir> option).\n\n"
else
last = (Time.parse(created) unless force rescue nil)
end
else
FileUtils.mkdir_p(op_dir)
end
last
end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please see Improve the docs, or visit Documenting-ruby.org.