In Files

  • rdoc/rdoc.rb

Files

Class/Module Index [+]

Quicksearch

RDoc::RDoc

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.

Constants

GENERATORS

This is the list of output generator that we support

Generator

Attributes

stats[R]

Accessor for statistics. Available after each call to #parse_files

Public Class Methods

new() click to toggle source
 
               # File rdoc/rdoc.rb, line 63
def initialize
  @stats = nil
end
            

Public Instance Methods

document(argv) click to toggle source

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
            
error(msg) click to toggle source

Report an error message and exit

 
               # File rdoc/rdoc.rb, line 70
def error(msg)
  raise ::RDoc::Error, msg
end
            
list_files_in_directory(dir, options) click to toggle source

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
            
normalized_file_list(options, relative_files, force_doc = false, exclude_pattern = nil) click to toggle source

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
            
output_flag_file(op_dir) click to toggle source

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
            
parse_dot_doc_file(in_dir, filename, options) click to toggle source

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_files(options) click to toggle source

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
            
setup_output_dir(op_dir, force) click to toggle source

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
            
update_output_dir(op_dir, time) click to toggle source

Update the flag file in an output directory.

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