Class | RDoc::RDoc |
In: |
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.
Generator | = | Struct.new(:file_name, :class_name, :key) | This is the list of output generators that we support | |
GENERATORS | = | {} |
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.
# File rdoc.rb, line 235 235: def document(argv) 236: 237: TopLevel::reset 238: 239: @stats = Stats.new 240: 241: options = Options.instance 242: options.parse(argv, GENERATORS) 243: 244: unless options.all_one_file 245: setup_output_dir(options.op_dir) 246: end 247: 248: file_info = parse_files(options) 249: 250: gen = options.generator 251: 252: $stderr.puts "\nGenerating #{gen.key.upcase}..." unless options.quiet 253: 254: require gen.file_name 255: 256: gen_class = Generators.const_get(gen.class_name) 257: 258: unless file_info.empty? 259: gen = gen_class.for(options) 260: 261: pwd = Dir.pwd 262: 263: Dir.chdir(options.op_dir) unless options.all_one_file 264: 265: begin 266: Diagram.new(file_info, options).draw if options.diagram 267: gen.generate(file_info) 268: ensure 269: Dir.chdir(pwd) 270: end 271: end 272: 273: unless options.quiet 274: puts 275: @stats.print 276: end 277: 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.rb, line 188 188: def list_files_in_directory(dir, options) 189: normalized_file_list(options, Dir.glob(File.join(dir, "*")), false, options.exclude) 190: 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.
# File rdoc.rb, line 160 160: def normalized_file_list(options, relative_files, force_doc = false, exclude_pattern=nil) 161: file_list = [] 162: 163: relative_files.each do |rel_file_name| 164: next if exclude_pattern && exclude_pattern =~ rel_file_name 165: case type = File.stat(rel_file_name).ftype 166: when "file" 167: file_list << rel_file_name.sub(/^\.\//, '') if force_doc || ParserFactory.can_parse(rel_file_name) 168: when "directory" 169: next if rel_file_name == "CVS" || rel_file_name == ".svn" 170: dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME) 171: if File.file?(dot_doc) 172: file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options)) 173: else 174: file_list.concat(list_files_in_directory(rel_file_name, options)) 175: end 176: else 177: raise RDocError.new("I can't deal with a #{type} #{rel_file_name}") 178: end 179: end 180: file_list 181: 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.rb, line 134 134: def parse_dot_doc_file(in_dir, filename, options) 135: # read and strip comments 136: patterns = File.read(filename).gsub(/#.*/, '') 137: 138: result = [] 139: 140: patterns.split.each do |patt| 141: candidates = Dir.glob(File.join(in_dir, patt)) 142: result.concat(normalized_file_list(options, candidates)) 143: end 144: result 145: end
Parse each file on the command line, recursively entering directories
# File rdoc.rb, line 196 196: def parse_files(options) 197: 198: file_info = [] 199: 200: files = options.files 201: files = ["."] if files.empty? 202: 203: file_list = normalized_file_list(options, files, true) 204: 205: file_list.each do |fn| 206: $stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet 207: 208: content = File.open(fn, "r") {|f| f.read} 209: 210: top_level = TopLevel.new(fn) 211: parser = ParserFactory.parser_for(top_level, fn, content, options, @stats) 212: file_info << parser.scan 213: @stats.num_files += 1 214: end 215: 216: file_info 217: 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.rb, line 111 111: def setup_output_dir(op_dir) 112: flag_file = File.join(op_dir, "created.rid") 113: if File.exist?(op_dir) 114: unless File.directory?(op_dir) 115: error "'#{op_dir}' exists, and is not a directory" 116: end 117: unless File.file?(flag_file) 118: error "\nDirectory #{op_dir} already exists, but it looks like it\n" + 119: "isn't an RDoc directory. Because RDoc doesn't want to risk\n" + 120: "destroying any of your existing files, you'll need to\n" + 121: "specify a different output directory name (using the\n" + 122: "--op <dir> option).\n\n" 123: end 124: else 125: File.makedirs(op_dir) 126: end 127: File.open(flag_file, "w") {|f| f.puts Time.now } 128: end