ruby-changes:3427
From: ko1@a...
Date: 7 Jan 2008 10:36:53 +0900
Subject: [ruby-changes:3427] drbrain - Ruby:r14920 (trunk): Collapse namespaces and refactor requires in RDoc
drbrain 2008-01-07 10:36:33 +0900 (Mon, 07 Jan 2008) New Revision: 14920 Added files: trunk/lib/rdoc/generators.rb Modified files: trunk/lib/rdoc/generators/chm_generator.rb trunk/lib/rdoc/generators/html_generator.rb trunk/lib/rdoc/generators/ri_generator.rb trunk/lib/rdoc/generators/xml_generator.rb trunk/lib/rdoc/rdoc.rb Log: Collapse namespaces and refactor requires in RDoc http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generators/xml_generator.rb?r1=14920&r2=14919&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generators/chm_generator.rb?r1=14920&r2=14919&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generators.rb?revision=14920&view=markup http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generators/ri_generator.rb?r1=14920&r2=14919&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/rdoc.rb?r1=14920&r2=14919&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rdoc/generators/html_generator.rb?r1=14920&r2=14919&diff_format=u Index: lib/rdoc/generators/chm_generator.rb =================================================================== --- lib/rdoc/generators/chm_generator.rb (revision 14919) +++ lib/rdoc/generators/chm_generator.rb (revision 14920) @@ -1,118 +1,114 @@ require 'rdoc/generators/html_generator' -module Generators +class Generators::CHMGenerator < Generators::HTMLGenerator - class CHMGenerator < HTMLGenerator + HHC_PATH = "c:/Program Files/HTML Help Workshop/hhc.exe" - HHC_PATH = "c:/Program Files/HTML Help Workshop/hhc.exe" + ## + # Standard generator factory - ## - # Standard generator factory + def self.for(options) + new(options) + end - def CHMGenerator.for(options) - CHMGenerator.new(options) - end + def initialize(*args) + super + @op_name = @options.op_name || "rdoc" + check_for_html_help_workshop + end - def initialize(*args) - super - @op_name = @options.op_name || "rdoc" - check_for_html_help_workshop - end + def check_for_html_help_workshop + stat = File.stat(HHC_PATH) + rescue + $stderr << + "\n.chm output generation requires that Microsoft's Html Help\n" << + "Workshop is installed. RDoc looks for it in:\n\n " << + HHC_PATH << + "\n\nYou can download a copy for free from:\n\n" << + " http://msdn.microsoft.com/library/default.asp?" << + "url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\n\n" - def check_for_html_help_workshop - stat = File.stat(HHC_PATH) - rescue - $stderr << - "\n.chm output generation requires that Microsoft's Html Help\n" << - "Workshop is installed. RDoc looks for it in:\n\n " << - HHC_PATH << - "\n\nYou can download a copy for free from:\n\n" << - " http://msdn.microsoft.com/library/default.asp?" << - "url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\n\n" + exit 99 + end - exit 99 - end + ## + # Generate the html as normal, then wrap it in a help project - ## - # Generate the html as normal, then wrap it in a help project + def generate(info) + super + @project_name = @op_name + ".hhp" + create_help_project + end - def generate(info) - super - @project_name = @op_name + ".hhp" - create_help_project - end + ## + # The project contains the project file, a table of contents and an index - ## - # The project contains the project file, a table of contents and an index + def create_help_project + create_project_file + create_contents_and_index + compile_project + end - def create_help_project - create_project_file - create_contents_and_index - compile_project + ## + # The project file links together all the various + # files that go to make up the help. + + def create_project_file + template = TemplatePage.new(RDoc::Page::HPP_FILE) + values = { "title" => @options.title, "opname" => @op_name } + files = [] + @files.each do |f| + files << { "html_file_name" => f.path } end - ## - # The project file links together all the various - # files that go to make up the help. + values['all_html_files'] = files - def create_project_file - template = TemplatePage.new(RDoc::Page::HPP_FILE) - values = { "title" => @options.title, "opname" => @op_name } - files = [] - @files.each do |f| - files << { "html_file_name" => f.path } - end - - values['all_html_files'] = files - - File.open(@project_name, "w") do |f| - template.write_html_on(f, values) - end + File.open(@project_name, "w") do |f| + template.write_html_on(f, values) end + end - ## - # The contents is a list of all files and modules. - # For each we include as sub-entries the list - # of methods they contain. As we build the contents - # we also build an index file + ## + # The contents is a list of all files and modules. + # For each we include as sub-entries the list + # of methods they contain. As we build the contents + # we also build an index file - def create_contents_and_index - contents = [] - index = [] + def create_contents_and_index + contents = [] + index = [] - (@files+@classes).sort.each do |entry| - content_entry = { "c_name" => entry.name, "ref" => entry.path } - index << { "name" => entry.name, "aref" => entry.path } + (@files+@classes).sort.each do |entry| + content_entry = { "c_name" => entry.name, "ref" => entry.path } + index << { "name" => entry.name, "aref" => entry.path } - internals = [] + internals = [] - methods = entry.build_method_summary_list(entry.path) + methods = entry.build_method_summary_list(entry.path) - content_entry["methods"] = methods unless methods.empty? - contents << content_entry - index.concat methods - end + content_entry["methods"] = methods unless methods.empty? + contents << content_entry + index.concat methods + end - values = { "contents" => contents } - template = TemplatePage.new(RDoc::Page::CONTENTS) - File.open("contents.hhc", "w") do |f| - template.write_html_on(f, values) - end - - values = { "index" => index } - template = TemplatePage.new(RDoc::Page::CHM_INDEX) - File.open("index.hhk", "w") do |f| - template.write_html_on(f, values) - end + values = { "contents" => contents } + template = TemplatePage.new(RDoc::Page::CONTENTS) + File.open("contents.hhc", "w") do |f| + template.write_html_on(f, values) end - ## - # Invoke the windows help compiler to compiler the project - - def compile_project - system(HHC_PATH, @project_name) + values = { "index" => index } + template = TemplatePage.new(RDoc::Page::CHM_INDEX) + File.open("index.hhk", "w") do |f| + template.write_html_on(f, values) end + end + ## + # Invoke the windows help compiler to compiler the project + + def compile_project + system(HHC_PATH, @project_name) end end Index: lib/rdoc/generators/ri_generator.rb =================================================================== --- lib/rdoc/generators/ri_generator.rb (revision 14919) +++ lib/rdoc/generators/ri_generator.rb (revision 14920) @@ -1,229 +1,221 @@ -require 'rdoc/options' -require 'rdoc/template' -require 'rdoc/markup/simple_markup' +require 'rdoc/generators' require 'rdoc/markup/simple_markup/to_flow' -require 'cgi' require 'rdoc/ri/ri_cache' require 'rdoc/ri/ri_reader' require 'rdoc/ri/ri_writer' require 'rdoc/ri/ri_descriptions' -module Generators +class Generators::RIGenerator - class RIGenerator + ## + # Generators may need to return specific subclasses depending on the + # options they are passed. Because of this we create them using a factory - ## - # Generators may need to return specific subclasses depending on the - # options they are passed. Because of this we create them using a factory + def self.for(options) + new(options) + end - def RIGenerator.for(options) - new(options) - end + class << self + protected :new + end - class <<self - protected :new - end + ## + # Set up a new RIGenerator. - ## - # Set up a new HTML generator. Basically all we do here is load up the - # correct output temlate + def initialize(options) #:not-new: + @options = options + @ri_writer = RI::RiWriter.new(".") + @markup = SM::SimpleMarkup.new + @to_flow = SM::ToFlow.new + end - def initialize(options) #:not-new: - @options = options - @ri_writer = RI::RiWriter.new(".") - @markup = SM::SimpleMarkup.new - @to_flow = SM::ToFlow.new + ## + # Build the initial indices and output objects based on an array of + # TopLevel objects containing the extracted information. + + def generate(toplevels) + RDoc::TopLevel.all_classes_and_modules.each do |cls| + process_class(cls) end + end - ## - # Build the initial indices and output objects based on an array of - # TopLevel objects containing the extracted information. + def process_class(from_class) + generate_class_info(from_class) - def generate(toplevels) - RDoc::TopLevel.all_classes_and_modules.each do |cls| - process_class(cls) - end + # now recure into this classes constituent classess + from_class.each_classmodule do |mod| + process_class(mod) end + end - def process_class(from_class) - generate_class_info(from_class) + def generate_class_info(cls) + if cls === RDoc::NormalModule + cls_desc = RI::ModuleDescription.new + else + cls_desc = RI::ClassDescription.new + cls_desc.superclass = cls.superclass + end + cls_desc.name = cls.name + cls_desc.full_name = cls.full_name + cls_desc.comment = markup(cls.comment) - # now recure into this classes constituent classess - from_class.each_classmodule do |mod| - process_class(mod) - end + cls_desc.attributes =cls.attributes.sort.map do |a| + RI::Attribute.new(a.name, a.rw, markup(a.comment)) end - def generate_class_info(cls) - if cls === RDoc::NormalModule - cls_desc = RI::ModuleDescription.new - else - cls_desc = RI::ClassDescription.new - cls_desc.superclass = cls.superclass - end - cls_desc.name = cls.name - cls_desc.full_name = cls.full_name - cls_desc.comment = markup(cls.comment) + cls_desc.constants = cls.constants.map do |c| + RI::Constant.new(c.name, c.value, markup(c.comment)) + end - cls_desc.attributes =cls.attributes.sort.map do |a| - RI::Attribute.new(a.name, a.rw, markup(a.comment)) - end + cls_desc.includes = cls.includes.map do |i| + RI::IncludedModule.new(i.name) + end - cls_desc.constants = cls.constants.map do |c| - RI::Constant.new(c.name, c.value, markup(c.comment)) - end + class_methods, instance_methods = method_list(cls) - cls_desc.includes = cls.includes.map do |i| - RI::IncludedModule.new(i.name) - end + cls_desc.class_methods = class_methods.map do |m| + RI::MethodSummary.new(m.name) + end + cls_desc.instance_methods = instance_methods.map do |m| + RI::MethodSummary.new(m.name) + end - class_methods, instance_methods = method_list(cls) + update_or_replace(cls_desc) - cls_desc.class_methods = class_methods.map do |m| - RI::MethodSummary.new(m.name) - end - cls_desc.instance_methods = instance_methods.map do |m| - RI::MethodSummary.new(m.name) - end + class_methods.each do |m| + generate_method_info(cls_desc, m) + end - update_or_replace(cls_desc) + instance_methods.each do |m| + generate_method_info(cls_desc, m) + end + end - class_methods.each do |m| - generate_method_info(cls_desc, m) - end - instance_methods.each do |m| - generate_method_info(cls_desc, m) - end + def generate_method_info(cls_desc, method) + meth_desc = RI::MethodDescription.new + meth_desc.name = method.name + meth_desc.full_name = cls_desc.full_name + if method.singleton + meth_desc.full_name += "::" + else + meth_desc.full_name += "#" end + meth_desc.full_name << method.name + meth_desc.comment = markup(method.comment) + meth_desc.params = params_of(method) + meth_desc.visibility = method.visibility.to_s + meth_desc.is_singleton = method.singleton + meth_desc.block_params = method.block_params - def generate_method_info(cls_desc, method) - meth_desc = RI::MethodDescription.new - meth_desc.name = method.name - meth_desc.full_name = cls_desc.full_name - if method.singleton - meth_desc.full_name += "::" - else - meth_desc.full_name += "#" - end - meth_desc.full_name << method.name - - meth_desc.comment = markup(method.comment) - meth_desc.params = params_of(method) - meth_desc.visibility = method.visibility.to_s - meth_desc.is_singleton = method.singleton - meth_desc.block_params = method.block_params - - meth_desc.aliases = method.aliases.map do |a| - RI::AliasName.new(a.name) - end - - @ri_writer.add_method(cls_desc, meth_desc) + meth_desc.aliases = method.aliases.map do |a| + RI::AliasName.new(a.name) end - private + @ri_writer.add_method(cls_desc, meth_desc) + end - ## - # Returns a list of class and instance methods that we'll be documenting + private - def method_list(cls) - list = cls.method_list - unless @options.show_all - list = list.find_all do |m| - m.visibility == :public || m.visibility == :protected || m.force_documentation - end - end + ## + # Returns a list of class and instance methods that we'll be documenting - c = [] - i = [] - list.sort.each do |m| - if m.singleton - c << m - else - i << m - end + def method_list(cls) + list = cls.method_list + unless @options.show_all + list = list.find_all do |m| + m.visibility == :public || m.visibility == :protected || m.force_documentation end - return c,i end - def params_of(method) - if method.call_seq - method.call_seq + c = [] + i = [] + list.sort.each do |m| + if m.singleton + c << m else - params = method.params || "" + i << m + end + end + return c,i + end - p = params.gsub(/\s*\#.*/, '') - p = p.tr("\n", " ").squeeze(" ") - p = "(" + p + ")" unless p[0] == ?( + def params_of(method) + if method.call_seq + method.call_seq + else + params = method.params || "" - if (block = method.block_params) - block.gsub!(/\s*\#.*/, '') - block = block.tr("\n", " ").squeeze(" ") - if block[0] == ?( - block.sub!(/^\(/, '').sub!(/\)/, '') - end - p << " {|#{block.strip}| ...}" + p = params.gsub(/\s*\#.*/, '') + p = p.tr("\n", " ").squeeze(" ") + p = "(" + p + ")" unless p[0] == ?( + + if (block = method.block_params) + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') end - p + p << " {|#{block.strip}| ...}" end + p end + end - def markup(comment) - return nil if !comment || comment.empty? + def markup(comment) + return nil if !comment || comment.empty? - # Convert leading comment markers to spaces, but only - # if all non-blank lines have them + # Convert leading comment markers to spaces, but only + # if all non-blank lines have them - if comment =~ /^(?>\s*)[^\#]/ - content = comment - else - content = comment.gsub(/^\s*(#+)/) { $1.tr('#',' ') } - end - @markup.convert(content, @to_flow) + if comment =~ /^(?>\s*)[^\#]/ + content = comment + else + content = comment.gsub(/^\s*(#+)/) { $1.tr('#',' ') } end + @markup.convert(content, @to_flow) + 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. + ## + # 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. - def update_or_replace(cls_desc) - old_cls = nil + def update_or_replace(cls_desc) + old_cls = nil - if @options.merge - rdr = RI::RiReader.new(RI::RiCache.new(@options.op_dir)) + if @options.merge + rdr = RI::RiReader.new(RI::RiCache.new(@options.op_dir)) - namespace = rdr.top_level_namespace - namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) - if namespace.empty? - $stderr.puts "You asked me to merge this source into existing " - $stderr.puts "documentation. This file references a class or " - $stderr.puts "module called #{cls_desc.name} which I don't" - $stderr.puts "have existing documentation for." - $stderr.puts - $stderr.puts "Perhaps you need to generate its documentation first" - exit 1 - else - old_cls = namespace[0] - end - end - - if old_cls.nil? - # no merge: simply overwrite - @ri_writer.remove_class(cls_desc) - @ri_writer.add_class(cls_desc) + namespace = rdr.top_level_namespace + namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) + if namespace.empty? + $stderr.puts "You asked me to merge this source into existing " + $stderr.puts "documentation. This file references a class or " + $stderr.puts "module called #{cls_desc.name} which I don't" + $stderr.puts "have existing documentation for." + $stderr.puts + $stderr.puts "Perhaps you need to generate its documentation first" + exit 1 else - # existing class: merge in - old_desc = rdr.get_class(old_cls) - - old_desc.merge_in(cls_desc) - @ri_writer.add_class(old_desc) + old_cls = namespace[0] end end + if old_cls.nil? + # no merge: simply overwrite + @ri_writer.remove_class(cls_desc) + @ri_writer.add_class(cls_desc) + else + # existing class: merge in + old_desc = rdr.get_class(old_cls) + + old_desc.merge_in(cls_desc) + @ri_writer.add_class(old_desc) + end end end Index: lib/rdoc/generators/xml_generator.rb =================================================================== --- lib/rdoc/generators/xml_generator.rb (revision 14919) +++ lib/rdoc/generators/xml_generator.rb (revision 14920) @@ -1,127 +1,119 @@ -require 'rdoc/options' -require 'rdoc/markup/simple_markup' -require 'rdoc/markup/simple_markup/to_html' require 'rdoc/generators/html_generator' -module Generators +## +# Generate XML output as one big file +class Generators::XMLGenerator < Generators::HTMLGenerator + ## - # Generate XML output as one big file + # Standard generator factory - class XMLGenerator < HTMLGenerator + def self.for(options) + new(options) + end - ## - # Standard generator factory + def initialize(*args) + super + end - def XMLGenerator.for(options) - XMLGenerator.new(options) - end + ## + # Build the initial indices and output objects + # based on an array of TopLevel objects containing + # the extracted information. - def initialize(*args) - super - end + def generate(info) + @info = info + @files = [] + @classes = [] + @hyperlinks = {} - ## - # Build the initial indices and output objects - # based on an array of TopLevel objects containing - # the extracted information. + build_indices + generate_xml + end - def generate(info) - @info = info - @files = [] - @classes = [] - @hyperlinks = {} + ## + # Generate: + # + # * a list of HtmlFile objects for each TopLevel object. + # * a list of HtmlClass objects for each first level + # class or module in the TopLevel objects + # * a complete list of all hyperlinkable terms (file, + # class, module, and method names) - build_indices - generate_xml + def build_indices + @info.each do |toplevel| + @files << Generators::HtmlFile.new(toplevel, @options, Generators::FILE_DIR) end - ## - # Generate: - # - # * a list of HtmlFile objects for each TopLevel object. - # * a list of HtmlClass objects for each first level - # class or module in the TopLevel objects - # * a complete list of all hyperlinkable terms (file, - # class, module, and method names) - - def build_indices - - @info.each do |toplevel| - @files << HtmlFile.new(toplevel, @options, FILE_DIR) - end - - RDoc::TopLevel.all_classes_and_modules.each do |cls| - build_class_list(cls, @files[0], CLASS_DIR) - end + RDoc::TopLevel.all_classes_and_modules.each do |cls| + build_class_list(cls, @files[0], Generators::CLASS_DIR) end + end - def build_class_list(from, html_file, class_dir) - @classes << HtmlClass.new(from, html_file, class_dir, @options) - from.each_classmodule do |mod| - build_class_list(mod, html_file, class_dir) - end + def build_class_list(from, html_file, class_dir) + @classes << Generators::HtmlClass.new(from, html_file, class_dir, @options) + from.each_classmodule do |mod| + build_class_list(mod, html_file, class_dir) end + end - ## - # Generate all the HTML. For the one-file case, we generate - # all the information in to one big hash + ## + # Generate all the HTML. For the one-file case, we generate + # all the information in to one big hash - def generate_xml - values = { - 'charset' => @options.charset, - 'files' => gen_into(@files), - 'classes' => gen_into(@classes) - } + def generate_xml + values = { + 'charset' => @options.charset, + 'files' => gen_into(@files), + 'classes' => gen_into(@classes) + } - # this method is defined in the template file - write_extra_pages if defined? write_extra_pages + # this method is defined in the template file + write_extra_pages if defined? write_extra_pages - template = TemplatePage.new(RDoc::Page::ONE_PAGE) + template = TemplatePage.new(RDoc::Page::ONE_PAGE) - if @options.op_name - opfile = File.open(@options.op_name, "w") - else - opfile = $stdout - end - template.write_html_on(opfile, values) + if @options.op_name + opfile = File.open(@options.op_name, "w") + else + opfile = $stdout end + template.write_html_on(opfile, values) + end - def gen_into(list) - res = [] - list.each do |item| - res << item.value_hash - end - res + def gen_into(list) + res = [] + list.each do |item| + res << item.value_hash end + res + end - def gen_file_index - gen_an_index(@files, 'Files') - end + def gen_file_index + gen_an_index(@files, 'Files') + end - def gen_class_index - gen_an_index(@classes, 'Classes') - end + def gen_class_index + gen_an_index(@classes, 'Classes') + end - def gen_method_index - gen_an_index(HtmlMethod.all_methods, 'Methods') - end + def gen_method_index + gen_an_index(Generators::HtmlMethod.all_methods, 'Methods') + end - def gen_an_index(collection, title) - res = [] - collection.sort.each do |f| - if f.document_self - res << { "href" => f.path, "name" => f.index_name } - end + def gen_an_index(collection, title) + res = [] + collection.sort.each do |f| + if f.document_self + res << { "href" => f.path, "name" => f.index_name } end - - return { - "entries" => res, - 'list_title' => title, - 'index_url' => main_url, - } end + return { + "entries" => res, + 'list_title' => title, + 'index_url' => main_url, + } end end Index: lib/rdoc/generators/html_generator.rb =================================================================== --- lib/rdoc/generators/html_generator.rb (revision 14919) +++ lib/rdoc/generators/html_generator.rb (revision 14920) @@ -1,10 +1,7 @@ require 'fileutils' -require 'rdoc/options' -require 'rdoc/template' -require 'rdoc/markup/simple_markup' +require 'rdoc/generators' require 'rdoc/markup/simple_markup/to_html' -require 'cgi' module Generators @@ -780,7 +777,9 @@ end def filename_to_label - @context.file_relative_name.gsub(/%|\/|\?|\#/) {|s| '%' + ("%x" % s[0]) } + @context.file_relative_name.gsub(/%|\/|\?|\#/) do |s| + '%%%x' % s[0].unpack('C') + end end def index_name @@ -1177,7 +1176,7 @@ # Generators may need to return specific subclasses depending on the # options they are passed. Because of this we create them using a factory - def HTMLGenerator.for(options) + def self.for(options) AllReferences::reset HtmlMethod::reset Index: lib/rdoc/rdoc.rb =================================================================== --- lib/rdoc/rdoc.rb (revision 14919) +++ lib/rdoc/rdoc.rb (revision 14920) @@ -18,8 +18,7 @@ require 'fileutils' require 'time' -# We put rdoc stuff in the RDoc module to avoid namespace -# clutter. +# We put rdoc stuff in the RDoc module to avoid namespace clutter. # # ToDo: This isn't universally true. # Index: lib/rdoc/generators.rb =================================================================== --- lib/rdoc/generators.rb (revision 0) +++ lib/rdoc/generators.rb (revision 14920) @@ -0,0 +1,8 @@ +require 'cgi' +require 'rdoc/options' +require 'rdoc/markup/simple_markup' +require 'rdoc/template' + +module Generators +end + -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml