mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Collapse namespaces and refactor requires in RDoc
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b0f13cfebe
commit
b543ed3ac8
6 changed files with 389 additions and 403 deletions
8
lib/rdoc/generators.rb
Normal file
8
lib/rdoc/generators.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
require 'cgi'
|
||||
require 'rdoc/options'
|
||||
require 'rdoc/markup/simple_markup'
|
||||
require 'rdoc/template'
|
||||
|
||||
module Generators
|
||||
end
|
||||
|
|
@ -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)
|
||||
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"
|
||||
|
||||
exit 99
|
||||
end
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@op_name = @options.op_name || "rdoc"
|
||||
check_for_html_help_workshop
|
||||
values['all_html_files'] = files
|
||||
|
||||
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
|
||||
|
||||
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 }
|
||||
|
||||
internals = []
|
||||
|
||||
methods = entry.build_method_summary_list(entry.path)
|
||||
|
||||
content_entry["methods"] = methods unless methods.empty?
|
||||
contents << content_entry
|
||||
index.concat methods
|
||||
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"
|
||||
|
||||
exit 99
|
||||
values = { "contents" => contents }
|
||||
template = TemplatePage.new(RDoc::Page::CONTENTS)
|
||||
File.open("contents.hhc", "w") do |f|
|
||||
template.write_html_on(f, values)
|
||||
end
|
||||
|
||||
##
|
||||
# Generate the html as normal, then wrap it in a help project
|
||||
|
||||
def generate(info)
|
||||
super
|
||||
@project_name = @op_name + ".hhp"
|
||||
create_help_project
|
||||
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
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
values['all_html_files'] = files
|
||||
|
||||
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
|
||||
|
||||
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 }
|
||||
|
||||
internals = []
|
||||
|
||||
methods = entry.build_method_summary_list(entry.path)
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
##
|
||||
# Invoke the windows help compiler to compiler the project
|
||||
|
||||
def compile_project
|
||||
system(HHC_PATH, @project_name)
|
||||
end
|
||||
##
|
||||
# Invoke the windows help compiler to compiler the project
|
||||
|
||||
def compile_project
|
||||
system(HHC_PATH, @project_name)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -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 @@ module Generators
|
|||
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 @@ module Generators
|
|||
# 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
|
||||
|
||||
|
|
|
@ -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)
|
||||
class << self
|
||||
protected :new
|
||||
end
|
||||
|
||||
##
|
||||
# Set up a new RIGenerator.
|
||||
|
||||
def initialize(options) #:not-new:
|
||||
@options = options
|
||||
@ri_writer = RI::RiWriter.new(".")
|
||||
@markup = SM::SimpleMarkup.new
|
||||
@to_flow = SM::ToFlow.new
|
||||
end
|
||||
|
||||
##
|
||||
# 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
|
||||
|
||||
def process_class(from_class)
|
||||
generate_class_info(from_class)
|
||||
|
||||
# now recure into this classes constituent classess
|
||||
from_class.each_classmodule do |mod|
|
||||
process_class(mod)
|
||||
end
|
||||
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.attributes =cls.attributes.sort.map do |a|
|
||||
RI::Attribute.new(a.name, a.rw, markup(a.comment))
|
||||
end
|
||||
|
||||
class <<self
|
||||
protected :new
|
||||
cls_desc.constants = cls.constants.map do |c|
|
||||
RI::Constant.new(c.name, c.value, markup(c.comment))
|
||||
end
|
||||
|
||||
##
|
||||
# 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
|
||||
cls_desc.includes = cls.includes.map do |i|
|
||||
RI::IncludedModule.new(i.name)
|
||||
end
|
||||
|
||||
##
|
||||
# Build the initial indices and output objects based on an array of
|
||||
# TopLevel objects containing the extracted information.
|
||||
class_methods, instance_methods = method_list(cls)
|
||||
|
||||
def generate(toplevels)
|
||||
RDoc::TopLevel.all_classes_and_modules.each do |cls|
|
||||
process_class(cls)
|
||||
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
|
||||
|
||||
update_or_replace(cls_desc)
|
||||
|
||||
class_methods.each do |m|
|
||||
generate_method_info(cls_desc, m)
|
||||
end
|
||||
|
||||
instance_methods.each do |m|
|
||||
generate_method_info(cls_desc, m)
|
||||
end
|
||||
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
|
||||
|
||||
meth_desc.aliases = method.aliases.map do |a|
|
||||
RI::AliasName.new(a.name)
|
||||
end
|
||||
|
||||
@ri_writer.add_method(cls_desc, meth_desc)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Returns a list of class and instance methods that we'll be documenting
|
||||
|
||||
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
|
||||
|
||||
def process_class(from_class)
|
||||
generate_class_info(from_class)
|
||||
|
||||
# now recure into this classes constituent classess
|
||||
from_class.each_classmodule do |mod|
|
||||
process_class(mod)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_class_info(cls)
|
||||
if cls === RDoc::NormalModule
|
||||
cls_desc = RI::ModuleDescription.new
|
||||
c = []
|
||||
i = []
|
||||
list.sort.each do |m|
|
||||
if m.singleton
|
||||
c << m
|
||||
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.attributes =cls.attributes.sort.map do |a|
|
||||
RI::Attribute.new(a.name, a.rw, markup(a.comment))
|
||||
end
|
||||
|
||||
cls_desc.constants = cls.constants.map do |c|
|
||||
RI::Constant.new(c.name, c.value, markup(c.comment))
|
||||
end
|
||||
|
||||
cls_desc.includes = cls.includes.map do |i|
|
||||
RI::IncludedModule.new(i.name)
|
||||
end
|
||||
|
||||
class_methods, instance_methods = method_list(cls)
|
||||
|
||||
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
|
||||
|
||||
update_or_replace(cls_desc)
|
||||
|
||||
class_methods.each do |m|
|
||||
generate_method_info(cls_desc, m)
|
||||
end
|
||||
|
||||
instance_methods.each do |m|
|
||||
generate_method_info(cls_desc, m)
|
||||
i << m
|
||||
end
|
||||
end
|
||||
return c,i
|
||||
end
|
||||
|
||||
def params_of(method)
|
||||
if method.call_seq
|
||||
method.call_seq
|
||||
else
|
||||
params = method.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
|
||||
p = params.gsub(/\s*\#.*/, '')
|
||||
p = p.tr("\n", " ").squeeze(" ")
|
||||
p = "(" + p + ")" unless p[0] == ?(
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Returns a list of class and instance methods that we'll be documenting
|
||||
|
||||
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
|
||||
if (block = method.block_params)
|
||||
block.gsub!(/\s*\#.*/, '')
|
||||
block = block.tr("\n", " ").squeeze(" ")
|
||||
if block[0] == ?(
|
||||
block.sub!(/^\(/, '').sub!(/\)/, '')
|
||||
end
|
||||
p << " {|#{block.strip}| ...}"
|
||||
end
|
||||
|
||||
c = []
|
||||
i = []
|
||||
list.sort.each do |m|
|
||||
if m.singleton
|
||||
c << m
|
||||
else
|
||||
i << m
|
||||
end
|
||||
end
|
||||
return c,i
|
||||
p
|
||||
end
|
||||
end
|
||||
|
||||
def params_of(method)
|
||||
if method.call_seq
|
||||
method.call_seq
|
||||
def markup(comment)
|
||||
return nil if !comment || comment.empty?
|
||||
|
||||
# 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)
|
||||
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.
|
||||
|
||||
def update_or_replace(cls_desc)
|
||||
old_cls = nil
|
||||
|
||||
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
|
||||
params = method.params || ""
|
||||
|
||||
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 << " {|#{block.strip}| ...}"
|
||||
end
|
||||
p
|
||||
old_cls = namespace[0]
|
||||
end
|
||||
end
|
||||
|
||||
def markup(comment)
|
||||
return nil if !comment || comment.empty?
|
||||
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)
|
||||
|
||||
# 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)
|
||||
old_desc.merge_in(cls_desc)
|
||||
@ri_writer.add_class(old_desc)
|
||||
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.
|
||||
|
||||
def update_or_replace(cls_desc)
|
||||
old_cls = nil
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
end
|
||||
|
|
|
@ -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)
|
||||
##
|
||||
# Build the initial indices and output objects
|
||||
# based on an array of TopLevel objects containing
|
||||
# the extracted information.
|
||||
|
||||
def generate(info)
|
||||
@info = info
|
||||
@files = []
|
||||
@classes = []
|
||||
@hyperlinks = {}
|
||||
|
||||
build_indices
|
||||
generate_xml
|
||||
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 << Generators::HtmlFile.new(toplevel, @options, Generators::FILE_DIR)
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
RDoc::TopLevel.all_classes_and_modules.each do |cls|
|
||||
build_class_list(cls, @files[0], Generators::CLASS_DIR)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Build the initial indices and output objects
|
||||
# based on an array of TopLevel objects containing
|
||||
# the extracted information.
|
||||
|
||||
def generate(info)
|
||||
@info = info
|
||||
@files = []
|
||||
@classes = []
|
||||
@hyperlinks = {}
|
||||
|
||||
build_indices
|
||||
generate_xml
|
||||
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:
|
||||
#
|
||||
# * 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)
|
||||
##
|
||||
# Generate all the HTML. For the one-file case, we generate
|
||||
# all the information in to one big hash
|
||||
|
||||
def build_indices
|
||||
def generate_xml
|
||||
values = {
|
||||
'charset' => @options.charset,
|
||||
'files' => gen_into(@files),
|
||||
'classes' => gen_into(@classes)
|
||||
}
|
||||
|
||||
@info.each do |toplevel|
|
||||
@files << HtmlFile.new(toplevel, @options, FILE_DIR)
|
||||
end
|
||||
# this method is defined in the template file
|
||||
write_extra_pages if defined? write_extra_pages
|
||||
|
||||
RDoc::TopLevel.all_classes_and_modules.each do |cls|
|
||||
build_class_list(cls, @files[0], CLASS_DIR)
|
||||
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)
|
||||
end
|
||||
|
||||
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_class_index
|
||||
gen_an_index(@classes, 'Classes')
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
##
|
||||
# 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)
|
||||
}
|
||||
|
||||
# this method is defined in the template file
|
||||
write_extra_pages if defined? write_extra_pages
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
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_class_index
|
||||
gen_an_index(@classes, 'Classes')
|
||||
end
|
||||
|
||||
def gen_method_index
|
||||
gen_an_index(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
|
||||
end
|
||||
|
||||
return {
|
||||
"entries" => res,
|
||||
'list_title' => title,
|
||||
'index_url' => main_url,
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
"entries" => res,
|
||||
'list_title' => title,
|
||||
'index_url' => main_url,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -18,8 +18,7 @@ require 'find'
|
|||
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.
|
||||
#
|
||||
|
|
Loading…
Reference in a new issue