summaryrefslogtreecommitdiff
path: root/lib/rdoc/generators
diff options
context:
space:
mode:
authordave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-12-01 07:12:49 +0000
committerdave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-12-01 07:12:49 +0000
commit87762adcb0d38d6c575448f67c2906964215f3a1 (patch)
treec74f6e5b2b51f641cdc7895a37eb4c161b2c6d72 /lib/rdoc/generators
parentc1c55573bdaecbd972f57b46dd22dfbd0e1a02dd (diff)
Add RDoc
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/generators')
-rw-r--r--lib/rdoc/generators/chm_generator.rb112
-rw-r--r--lib/rdoc/generators/html_generator.rb1370
-rw-r--r--lib/rdoc/generators/template/chm/chm.rb86
-rw-r--r--lib/rdoc/generators/template/html/css2.rb631
-rw-r--r--lib/rdoc/generators/template/html/hefss.rb418
-rw-r--r--lib/rdoc/generators/template/html/html.rb762
-rw-r--r--lib/rdoc/generators/template/html/kilmer.rb398
-rw-r--r--lib/rdoc/generators/template/xml/rdf.rb112
-rw-r--r--lib/rdoc/generators/template/xml/xml.rb112
-rw-r--r--lib/rdoc/generators/xml_generator.rb130
10 files changed, 4131 insertions, 0 deletions
diff --git a/lib/rdoc/generators/chm_generator.rb b/lib/rdoc/generators/chm_generator.rb
new file mode 100644
index 0000000000..1c46769cc2
--- /dev/null
+++ b/lib/rdoc/generators/chm_generator.rb
@@ -0,0 +1,112 @@
+require 'rdoc/generators/html_generator'
+
+module Generators
+
+ class CHMGenerator < HTMLGenerator
+
+ HHC_PATH = "c:\\Program Files\\HTML Help Workshop\\hhc.exe"
+
+ # Standard generator factory
+ 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 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
+
+ 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
+
+ end
+
+
+end
diff --git a/lib/rdoc/generators/html_generator.rb b/lib/rdoc/generators/html_generator.rb
new file mode 100644
index 0000000000..36e2f351da
--- /dev/null
+++ b/lib/rdoc/generators/html_generator.rb
@@ -0,0 +1,1370 @@
+# We're responsible for generating all the HTML files
+# from the object tree defined in code_objects.rb. We
+# generate:
+#
+# [files] an html file for each input file given. These
+# input files appear as objects of class
+# TopLevel
+#
+# [classes] an html file for each class or module encountered.
+# These classes are not grouped by file: if a file
+# contains four classes, we'll generate an html
+# file for the file itself, and four html files
+# for the individual classes.
+#
+# [indices] we generate three indices for files, classes,
+# and methods. These are displayed in a browser
+# like window with three index panes across the
+# top and the selected description below
+#
+# Method descriptions appear in whatever entity (file, class,
+# or module) that contains them.
+#
+# We generate files in a structure below a specified subdirectory,
+# normally +doc+.
+#
+# opdir
+# |
+# |___ files
+# | |__ per file summaries
+# |
+# |___ classes
+# |__ per class/module descriptions
+#
+# HTML is generated using the Template class.
+#
+
+require 'ftools'
+
+require 'rdoc/options'
+require 'rdoc/template'
+require 'rdoc/markup/simple_markup'
+require 'rdoc/markup/simple_markup/to_html'
+require 'cgi'
+
+module Generators
+
+ # Name of sub-direcories that hold file and class/module descriptions
+
+ FILE_DIR = "files"
+ CLASS_DIR = "classes"
+ CSS_NAME = "rdoc-style.css"
+
+
+ ##
+ # Build a hash of all items that can be cross-referenced.
+ # This is used when we output required and included names:
+ # if the names appear in this hash, we can generate
+ # an html cross reference to the appropriate description.
+ # We also use this when parsing comment blocks: any decorated
+ # words matching an entry in this list are hyperlinked.
+
+ class AllReferences
+ @@refs = {}
+
+ def AllReferences::reset
+ @@refs = {}
+ end
+
+ def AllReferences.add(name, html_class)
+ @@refs[name] = html_class
+ end
+
+ def AllReferences.[](name)
+ @@refs[name]
+ end
+ end
+
+
+ ##
+ # Subclass of the SM::ToHtml class that supports looking
+ # up words in the AllReferences list. Those that are
+ # found (like AllReferences in this comment) will
+ # be hyperlinked
+
+ class HyperlinkHtml < SM::ToHtml
+ # We need to record the html path of our caller so we can generate
+ # correct relative paths for any hyperlinks that we find
+ def initialize(from_path, context)
+ super()
+ @from_path = from_path
+
+ @parent_name = context.parent_name
+ @parent_name += "::" if @parent_name
+ @context = context
+ end
+
+ # We're invoked when any text matches the CROSSREF pattern
+ # (defined in MarkUp). If we fine the corresponding reference,
+ # generate a hyperlink. If the name we're looking for contains
+ # no punctuation, we look for it up the module/class chain. For
+ # example, HyperlinkHtml is found, even without the Generators::
+ # prefix, because we look for it in module Generators first.
+
+ def handle_special_CROSSREF(special)
+ name = special.text
+ if name[0,1] == '#'
+ lookup = name[1..-1]
+ name = lookup unless Options.instance.show_hash
+ else
+ lookup = name
+ end
+
+ if /([A-Z].*)[.\#](.*)/ =~ lookup
+ container = $1
+ method = $2
+ ref = @context.find_symbol(container, method)
+ else
+ ref = @context.find_symbol(lookup)
+ end
+
+ if ref and ref.document_self
+ "<a href=\"#{ref.as_href(@from_path)}\">#{name}</a>"
+ else
+ name
+ end
+ end
+
+ # And we're invoked with a potential external hyperlink mailto:
+ # just gets inserted. http: links are checked to see if they
+ # reference an image. If so, that image gets inserted using an
+ # <img> tag. Otherwise a conventional <a href> is used. We also
+ # support a special type of hyperlink, link:, which is a reference
+ # to a local file whose path is relative to the --op directory.
+
+ def handle_special_HYPERLINK(special)
+ url = special.text
+ if url =~ /([A-Za-z]+):(.*)/
+ type = $1
+ path = $2
+ else
+ type = "http"
+ path = url
+ url = "http://#{url}"
+ end
+
+ if type == "link"
+ if path[0,1] == '#' # is this meaningful?
+ url = path
+ else
+ url = HTMLGenerator.gen_url(@from_path, path)
+ end
+ end
+
+ if (type == "http" || type == "link") &&
+ url =~ /\.(gif|png|jpg|jpeg|bmp)$/
+
+ "<img src=\"#{url}\">"
+ else
+ "<a href=\"#{url}\">#{url.sub(%r{^\w+:/*}, '')}</a>"
+ end
+ end
+
+ # HEre's a hypedlink where the label is different to the URL
+ # <label>[url]
+ #
+
+ def handle_special_TIDYLINK(special)
+ text = special.text
+ unless text =~ /(\S+)\[(.*?)\]/
+ return text
+ end
+ label = $1
+ url = $2
+
+ unless url =~ /\w+?:/
+ url = "http://#{url}"
+ end
+
+ "<a href=\"#{url}\">#{label}</a>"
+ end
+
+ end
+
+
+
+ #####################################################################
+ #
+ # Handle common markup tasks for the various Html classes
+ #
+
+ module MarkUp
+
+ # Convert a string in markup format into HTML. We keep a cached
+ # SimpleMarkup object lying around after the first time we're
+ # called per object.
+
+ def markup(str, remove_para=false)
+ return '' unless str
+ unless defined? @markup
+ @markup = SM::SimpleMarkup.new
+
+ # class names, variable names, file names, or instance variables
+ @markup.add_special(/(
+ \b([A-Z]\w*(::\w+)*[.\#]\w+) # A::B.meth
+ | \b([A-Z]\w+(::\w+)*) # A::B..
+ | \#\w+[!?=]? # #meth_name
+ | \b\w+([_\/\.]+\w+)+[!?=]? # meth_name
+ )/x,
+ :CROSSREF)
+
+ # external hyperlinks
+ @markup.add_special(/((link:|http:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
+
+ # and links of the form <text>[<url>]
+ @markup.add_special(/\b(\S+?\[\S+?\.\S+?\])/, :TIDYLINK)
+
+ end
+ unless defined? @html_formatter
+ @html_formatter = HyperlinkHtml.new(self.path, self)
+ end
+
+ # Convert leading comment markers to spaces, but only
+ # if all non-blank lines have them
+
+ if str =~ /^(?>\s*)[^\#]/
+ content = str
+ else
+ content = str.gsub(/^\s*(#+)/) { $1.tr('#',' ') }
+ end
+
+ res = @markup.convert(content, @html_formatter)
+ if remove_para
+ res.sub!(/^<p>/, '')
+ res.sub!(/<\/p>$/, '')
+ end
+ res
+ end
+
+ # Qualify a stylesheet URL; if if +css_name+ does not begin with '/' or
+ # 'http[s]://', prepend a prefix relative to +path+. Otherwise, return it
+ # unmodified.
+
+ def style_url(path, css_name=nil)
+# $stderr.puts "style_url( #{path.inspect}, #{css_name.inspect} )"
+ css_name ||= CSS_NAME
+ if %r{^(https?:/)?/} =~ css_name
+ return css_name
+ else
+ return HTMLGenerator.gen_url(path, css_name)
+ end
+ end
+
+ # Build a webcvs URL with the given 'url' argument. URLs with a '%s' in them
+ # get the file's path sprintfed into them; otherwise they're just catenated
+ # together.
+
+ def cvs_url(url, full_path)
+ if /%s/ =~ url
+ return sprintf( url, full_path )
+ else
+ return url + full_path
+ end
+ end
+ end
+
+
+ #####################################################################
+ #
+ # A Context is built by the parser to represent a container: contexts
+ # hold classes, modules, methods, require lists and include lists.
+ # ClassModule and TopLevel are the context objects we process here
+ #
+ class ContextUser
+
+ include MarkUp
+
+ attr_reader :context
+
+ def initialize(context, options)
+ @context = context
+ @options = options
+ end
+
+ # convenience method to build a hyperlink
+ def href(link, cls, name)
+ %{<a href="#{link}" class="#{cls}">#{name}</a>} #"
+ end
+
+ # return a reference to outselves to be used as an href=
+ # the form depends on whether we're all in one file
+ # or in multiple files
+
+ def as_href(from_path)
+ if @options.all_one_file
+ "#" + path
+ else
+ HTMLGenerator.gen_url(from_path, path)
+ end
+ end
+
+ # Create a list of HtmlMethod objects for each method
+ # in the corresponding context object. If the @options.show_all
+ # variable is set (corresponding to the <tt>--all</tt> option,
+ # we include all methods, otherwise just the public ones.
+
+ def collect_methods
+ list = @context.method_list
+ unless @options.show_all
+ list = list.find_all {|m| m.visibility == :public || m.force_documentation }
+ end
+ @methods = list.collect {|m| HtmlMethod.new(m, self, @options) }
+ end
+
+ # Build a summary list of all the methods in this context
+ def build_method_summary_list(path_prefix="")
+ collect_methods unless @methods
+ meths = @methods.sort
+ res = []
+ meths.each do |meth|
+ res << {
+ "name" => CGI.escapeHTML(meth.name),
+ "aref" => "#{path_prefix}\##{meth.aref}"
+ }
+ end
+ res
+ end
+
+
+ # Build a list of aliases fo which we couldn't find a corresponding method
+ def build_alias_summary_list
+ @context.aliases.map do |al|
+ {
+ 'old_name' => al.old_name,
+ 'new_name' => al.new_name,
+ }
+ end
+ end
+
+ # Build a list of constants
+ def build_constants_summary_list
+ @context.constants.map do |co|
+ res = {
+ 'name' => co.name,
+ 'value' => co.value
+ }
+ res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty?
+ res
+ end
+ end
+
+ def build_requires_list(context)
+ potentially_referenced_list(context.requires) {|fn| [fn + ".rb"] }
+ end
+
+ def build_include_list(context)
+ potentially_referenced_list(context.includes)
+ end
+
+ # Build a list from an array of <i>Htmlxxx</i> items. Look up each
+ # in the AllReferences hash: if we find a corresponding entry,
+ # we generate a hyperlink to it, otherwise just output the name.
+ # However, some names potentially need massaging. For example,
+ # you may require a Ruby file without the .rb extension,
+ # but the file names we know about may have it. To deal with
+ # this, we pass in a block which performs the massaging,
+ # returning an array of alternative names to match
+
+ def potentially_referenced_list(array)
+ res = []
+ array.each do |i|
+ ref = AllReferences[i.name]
+ if !ref && block_given?
+ possibles = yield(i.name)
+ while !ref and !possibles.empty?
+ ref = AllReferences[possibles.shift]
+ end
+ end
+ h_name = CGI.escapeHTML(i.name)
+ if ref and ref.document_self
+ path = url(ref.path)
+ res << { "name" => h_name, "aref" => path }
+ else
+ res << { "name" => h_name }
+ end
+ end
+ res
+ end
+
+ # Build an array of arrays of method details. The outer array has up
+ # to six entries, public, private, and protected for both class
+ # methods, the other for instance methods. The inner arrays contain
+ # a hash for each method
+
+ def build_method_detail_list
+ outer = []
+
+ for singleton in [true, false]
+ for vis in [ :public, :protected, :private ]
+ res = []
+ @methods.each do |m|
+ if m.document_self and m.visibility == vis and m.singleton == singleton
+ row = {}
+ row["name"] = CGI.escapeHTML(m.name)
+ desc = m.description.strip
+ row["m_desc"] = desc unless desc.empty?
+ row["params"] = m.params
+ row["aref"] = m.aref
+ row["visibility"] = m.visibility.to_s
+
+ unless m.aliases.empty?
+ row["aka"] = m.aliases.map do |other|
+ {
+ 'name' => other.name,
+ 'aref' => other.viewer.as_href(path)
+ }
+ end
+ end
+
+ if @options.inline_source
+ code = m.source_code
+ row["sourcecode"] = code if code
+ else
+ code = m.src_url
+ if code
+ row["codeurl"] = code
+ row["imgurl"] = m.img_url
+ end
+ end
+ res << row
+ end
+ end
+ if res.size > 0
+ outer << {
+ "type" => vis.to_s.capitalize,
+ "category" => singleton ? "Class" : "Instance",
+ "methods" => res
+ }
+ end
+ end
+ end
+ outer
+ end
+
+ # Build the structured list of classes and modules contained
+ # in this context.
+
+ def build_class_list(level, from, infile=nil)
+ res = ""
+ prefix = "&nbsp;&nbsp;::" * level;
+
+ from.modules.sort.each do |mod|
+ next if infile && !mod.defined_in?(infile)
+ if mod.document_self
+ res <<
+ prefix <<
+ "Module " <<
+ href(url(mod.viewer.path), "link", mod.full_name) <<
+ "<br />\n" <<
+ build_class_list(level + 1, mod, infile)
+ end
+ end
+
+ from.classes.sort.each do |cls|
+ next if infile && !cls.defined_in?(infile)
+ if cls.document_self
+ res <<
+ prefix <<
+ "Class " <<
+ href(url(cls.viewer.path), "link", cls.full_name) <<
+ "<br />\n" <<
+ build_class_list(level + 1, cls, infile)
+ end
+ end
+
+ res
+ end
+
+ def url(target)
+ HTMLGenerator.gen_url(path, target)
+ end
+
+ def aref_to(target)
+ if @options.all_one_file
+ "#" + target
+ else
+ url(target)
+ end
+ end
+
+ def document_self
+ @context.document_self
+ end
+
+ def diagram_reference(diagram)
+ res = diagram.gsub(/((?:src|href)=")(.*?)"/) {
+ $1 + url($2) + '"'
+ }
+ res
+ end
+
+
+ # Find a symbol in ourselves or our parent
+ def find_symbol(symbol, method=nil)
+ res = @context.find_symbol(symbol, method)
+ if res
+ res = res.viewer
+ end
+ res
+ end
+ end
+
+ #####################################################################
+ #
+ # Wrap a ClassModule context
+
+ class HtmlClass < ContextUser
+
+ attr_reader :path
+
+ def initialize(context, html_file, prefix, options)
+ super(context, options)
+
+ @html_file = html_file
+ @is_module = context.is_module?
+ @values = {}
+
+ context.viewer = self
+
+ if options.all_one_file
+ @path = context.full_name
+ else
+ @path = http_url(context.full_name, prefix)
+ end
+
+ collect_methods
+
+ AllReferences.add(name, self)
+ end
+
+ # return the relative file name to store this class in,
+ # which is also its url
+ def http_url(full_name, prefix)
+ path = full_name.dup
+ if path['<<']
+ path.gsub!(/<<\s*(\w*)/) { "from-#$1" }
+ end
+ File.join(prefix, path.split("::")) + ".html"
+ end
+
+
+ def name
+ @context.full_name
+ end
+
+ def parent_name
+ @context.parent.full_name
+ end
+
+ def index_name
+ name
+ end
+
+ def write_on(f)
+ value_hash
+ template = TemplatePage.new(RDoc::Page::BODY,
+ RDoc::Page::CLASS_PAGE,
+ RDoc::Page::METHOD_LIST)
+ template.write_html_on(f, @values)
+ end
+
+ def value_hash
+ class_attribute_values
+
+ @values["charset"] = @options.charset
+ @values["style_url"] = style_url(path, @options.css)
+
+ d = markup(@context.comment)
+ @values["description"] = d unless d.empty?
+
+ ml = build_method_summary_list
+ @values["methods"] = ml unless ml.empty?
+
+ al = build_alias_summary_list
+ @values["aliases"] = al unless al.empty?
+
+ co = build_constants_summary_list
+ @values["constants"] = co unless co.empty?
+
+ il = build_include_list(@context)
+ @values["includes"] = il unless il.empty?
+
+ al = build_attribute_list
+ @values["attributes"] = al unless al.empty?
+
+ cl = build_class_list(0, @context)
+ @values["classlist"] = cl unless cl.empty?
+
+ mdl = build_method_detail_list
+ @values["method_list"] = mdl unless mdl.empty?
+ @values
+ end
+
+ def build_attribute_list
+ atts = @context.attributes.sort
+ res = []
+ atts.each do |att|
+ res << {
+ "name" => CGI.escapeHTML(att.name),
+ "rw" => att.rw,
+ "a_desc" => markup(att.comment, true)
+ }
+ end
+ res
+ end
+
+ def class_attribute_values
+ h_name = CGI.escapeHTML(name)
+
+ @values["classmod"] = @is_module ? "Module" : "Class"
+ @values["title"] = "#{@values['classmod']}: #{h_name}"
+
+ c = @context
+ c = c.parent while c and !c.diagram
+ if c && c.diagram
+ @values["diagram"] = diagram_reference(c.diagram)
+ end
+
+ @values["full_name"] = h_name
+
+ parent_class = @context.superclass
+
+ if parent_class
+ @values["parent"] = CGI.escapeHTML(parent_class)
+
+ if parent_name
+ lookup = parent_name + "::" + parent_class
+ else
+ lookup = parent_class
+ end
+
+ parent_url = AllReferences[lookup] || AllReferences[parent_class]
+
+ if parent_url and parent_url.document_self
+ @values["par_url"] = aref_to(parent_url.path)
+ end
+ end
+
+ files = []
+ @context.in_files.each do |f|
+ res = {}
+ full_path = CGI.escapeHTML(f.file_absolute_name)
+
+ res["full_path"] = full_path
+ res["full_path_url"] = aref_to(f.viewer.path) if f.document_self
+
+ if @options.webcvs
+ res["cvsurl"] = cvs_url( @options.webcvs, full_path )
+ end
+
+ files << res
+ end
+
+ @values['infiles'] = files
+
+ end
+
+ def <=>(other)
+ self.name <=> other.name
+ end
+
+ end
+
+ #####################################################################
+ #
+ # Handles the mapping of a file's information to HTML. In reality,
+ # a file corresponds to a +TopLevel+ object, containing modules,
+ # classes, and top-level methods. In theory it _could_ contain
+ # attributes and aliases, but we ignore these for now.
+
+ class HtmlFile < ContextUser
+
+ attr_reader :path
+ attr_reader :name
+
+ def initialize(context, options, file_dir)
+ super(context, options)
+
+ @values = {}
+
+ if options.all_one_file
+ @path = filename_to_label
+ else
+ @path = http_url(file_dir)
+ end
+
+ @name = @context.file_relative_name
+
+ collect_methods
+ AllReferences.add(name, self)
+ context.viewer = self
+ end
+
+ def http_url(file_dir)
+ File.join(file_dir, @context.file_relative_name.tr('.', '_')) +
+ ".html"
+ end
+
+ def filename_to_label
+ @context.file_relative_name.gsub(/%|\/|\?|\#/) {|s| '%' + ("%x" % s[0]) }
+ end
+
+ def index_name
+ name
+ end
+
+ def parent_name
+ nil
+ end
+
+ def value_hash
+ file_attribute_values
+
+ @values["charset"] = @options.charset
+ @values["href"] = path
+ @values["style_url"] = style_url(path, @options.css)
+
+ if @context.comment
+ d = markup(@context.comment)
+ @values["description"] = d if d.size > 0
+ end
+
+ ml = build_method_summary_list
+ @values["methods"] = ml unless ml.empty?
+
+ il = build_include_list(@context)
+ @values["includes"] = il unless il.empty?
+
+ rl = build_requires_list(@context)
+ @values["requires"] = rl unless rl.empty?
+
+ co = build_constants_summary_list
+ @values["constants"] = co unless co.empty?
+
+ if @options.promiscuous
+ file_context = nil
+ else
+ file_context = @context
+ end
+
+ cl = build_class_list(0, @context, file_context)
+ @values["classlist"] = cl unless cl.empty?
+
+ mdl = build_method_detail_list
+ @values["method_list"] = mdl unless mdl.empty?
+ @values
+ end
+
+ def write_on(f)
+ value_hash
+ template = TemplatePage.new(RDoc::Page::BODY,
+ RDoc::Page::FILE_PAGE,
+ RDoc::Page::METHOD_LIST)
+ template.write_html_on(f, @values)
+ end
+
+ def file_attribute_values
+ full_path = @context.file_absolute_name
+ short_name = File.basename(full_path)
+
+ @values["title"] = CGI.escapeHTML("File: #{short_name}")
+
+ if @context.diagram
+ @values["diagram"] = diagram_reference(@context.diagram)
+ end
+
+ @values["short_name"] = CGI.escapeHTML(short_name)
+ @values["full_path"] = CGI.escapeHTML(full_path)
+ @values["dtm_modified"] = @context.file_stat.mtime.to_s
+
+ if @options.webcvs
+ @values["cvsurl"] = cvs_url( @options.webcvs, @values["full_path"] )
+ end
+ end
+
+ def <=>(other)
+ self.name <=> other.name
+ end
+ end
+
+ #####################################################################
+
+ class HtmlMethod
+ include MarkUp
+
+ attr_reader :context
+ attr_reader :src_url
+ attr_reader :img_url
+ attr_reader :source_code
+
+ @@seq = "M000000"
+
+ @@all_methods = []
+
+ def HtmlMethod::reset
+ @@all_methods = []
+ end
+
+ def initialize(context, html_class, options)
+ @context = context
+ @html_class = html_class
+ @options = options
+ @@seq = @@seq.succ
+ @seq = @@seq
+ @@all_methods << self
+
+ context.viewer = self
+
+ if (ts = @context.token_stream)
+ @source_code = markup_code(ts)
+ unless @options.inline_source
+ @src_url = create_source_code_file(@source_code)
+ @img_url = HTMLGenerator.gen_url(path, 'source.png')
+ end
+ end
+
+ AllReferences.add(name, self)
+ end
+
+ # return a reference to outselves to be used as an href=
+ # the form depends on whether we're all in one file
+ # or in multiple files
+
+ def as_href(from_path)
+ if @options.all_one_file
+ "#" + path
+ else
+ HTMLGenerator.gen_url(from_path, path)
+ end
+ end
+
+ def name
+ @context.name
+ end
+
+ def index_name
+ "#{@context.name} (#{@html_class.name})"
+ end
+
+ def parent_name
+ if @context.parent.parent
+ @context.parent.parent.full_name
+ else
+ nil
+ end
+ end
+
+ def aref
+ @seq
+ end
+
+ def path
+ if @options.all_one_file
+ aref
+ else
+ @html_class.path + "#" + aref
+ end
+ end
+
+ def description
+ markup(@context.comment)
+ end
+
+ def visibility
+ @context.visibility
+ end
+
+ def singleton
+ @context.singleton
+ end
+
+ def params
+ p = @context.params.gsub(/\s*\#.*/, '')
+ p = p.tr("\n", " ").squeeze(" ")
+ p = "(" + p + ")" unless p[0] == ?(
+
+ if (block = @context.block_params)
+ block.gsub!(/\s*\#.*/, '')
+ block = block.tr("\n", " ").squeeze(" ")
+ if block[0] == ?(
+ block.sub!(/^\(/, '').sub!(/\)/, '')
+ end
+ p << " {|#{block.strip}| ...}"
+ end
+
+ CGI.escapeHTML(p)
+ end
+
+ def create_source_code_file(code_body)
+ meth_path = @html_class.path.sub(/\.html$/, '.src')
+ File.makedirs(meth_path)
+ file_path = File.join(meth_path, @seq) + ".html"
+
+ template = TemplatePage.new(RDoc::Page::SRC_PAGE)
+ File.open(file_path, "w") do |f|
+ values = {
+ 'title' => CGI.escapeHTML(index_name),
+ 'code' => code_body,
+ 'style_url' => style_url(path, @options.css),
+ 'charset' => @options.charset
+ }
+ template.write_html_on(f, values)
+ end
+ HTMLGenerator.gen_url(path, file_path)
+ end
+
+ def HtmlMethod.all_methods
+ @@all_methods
+ end
+
+ def <=>(other)
+ @context <=> other.context
+ end
+
+ ##
+ # Given a sequence of source tokens, mark up the source code
+ # to make it look purty.
+
+
+ def markup_code(tokens)
+ src = ""
+ tokens.each do |t|
+ next unless t
+ # p t.class
+# style = STYLE_MAP[t.class]
+ style = case t
+ when RubyToken::TkCONSTANT then "ruby-constant"
+ when RubyToken::TkKW then "ruby-keyword kw"
+ when RubyToken::TkIVAR then "ruby-ivar"
+ when RubyToken::TkOp then "ruby-operator"
+ when RubyToken::TkId then "ruby-identifier"
+ when RubyToken::TkNode then "ruby-node"
+ when RubyToken::TkCOMMENT then "ruby-comment cmt"
+ when RubyToken::TkREGEXP then "ruby-regexp re"
+ when RubyToken::TkSTRING then "ruby-value str"
+ when RubyToken::TkVal then "ruby-value"
+ else
+ nil
+ end
+
+ text = CGI.escapeHTML(t.text)
+# case t
+# when RubyToken::TkKW
+# style = "kw"
+# when RubyToken::TkCOMMENT
+# style = "cmt"
+# when RubyToken::TkSTRING
+# style = "str"
+# when RubyToken::TkREGEXP
+# style = "re"
+# end
+ if style
+ src << "<span class=\"#{style}\">#{text}</span>"
+ else
+ src << text
+ end
+ end
+
+ add_line_numbers(src) if Options.instance.include_line_numbers
+ src
+ end
+
+ # we rely on the fact that the first line of a source code
+ # listing has
+ # # File xxxxx, line dddd
+
+ def add_line_numbers(src)
+ if src =~ /\A.*, line (\d+)/
+ first = $1.to_i - 1
+ last = first + src.count("\n")
+ size = last.to_s.length
+ real_fmt = "%#{size}d: "
+ fmt = " " * (size+2)
+ src.gsub!(/^/) do
+ res = sprintf(fmt, first)
+ first += 1
+ fmt = real_fmt
+ res
+ end
+ end
+ end
+
+ def document_self
+ @context.document_self
+ end
+
+ def aliases
+ @context.aliases
+ end
+
+ def find_symbol(symbol, method=nil)
+ res = @context.parent.find_symbol(symbol, method)
+ if res
+ res = res.viewer
+ end
+ res
+ end
+ end
+
+ #####################################################################
+
+ class HTMLGenerator
+
+ include MarkUp
+
+ ##
+ # convert a target url to one that is relative to a given
+ # path
+
+ def HTMLGenerator.gen_url(path, target)
+ from = File.dirname(path)
+ to, to_file = File.split(target)
+
+ from = from.split("/")
+ to = to.split("/")
+
+ while from.size > 0 and to.size > 0 and from[0] == to[0]
+ from.shift
+ to.shift
+ end
+
+ from.fill("..")
+ from.concat(to)
+ from << to_file
+ File.join(*from)
+ end
+
+ # 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)
+ AllReferences::reset
+ HtmlMethod::reset
+
+ if options.all_one_file
+ HTMLGeneratorInOne.new(options)
+ else
+ HTMLGenerator.new(options)
+ end
+ end
+
+ class <<self
+ protected :new
+ 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
+ load_html_template
+ end
+
+
+ ##
+ # Build the initial indices and output objects
+ # based on an array of TopLevel objects containing
+ # the extracted information.
+
+ def generate(toplevels)
+ @toplevels = toplevels
+ @files = []
+ @classes = []
+
+ write_style_sheet
+ gen_sub_directories()
+ build_indices
+ generate_html
+ end
+
+ private
+
+ ##
+ # Load up the HTML template specified in the options
+ #
+ def load_html_template
+ template = File.join("rdoc/generators/template",
+ @options.generator.key, @options.template)
+ require template
+ extend RDoc::Page
+ rescue LoadError
+ $stderr.puts "Could not find HTML template '#{template}'"
+ exit 99
+ end
+
+ ##
+ # Write out the style sheet used by the main frames
+ #
+
+ def write_style_sheet
+ template = TemplatePage.new(RDoc::Page::STYLE)
+ unless @options.css
+ File.open(CSS_NAME, "w") do |f|
+ values = { "fonts" => RDoc::Page::FONTS }
+ template.write_html_on(f, values)
+ end
+ end
+ end
+
+ ##
+ # See the comments at the top for a description of the
+ # directory structure
+
+ def gen_sub_directories
+ File.makedirs(FILE_DIR, CLASS_DIR)
+ rescue
+ $stderr.puts $!.message
+ exit 1
+ 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
+
+ @toplevels.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
+ 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
+ #
+ def generate_html
+ # the individual descriptions for files and classes
+ gen_into(@files)
+ gen_into(@classes)
+ # and the index files
+ gen_file_index
+ gen_class_index
+ gen_method_index
+ gen_main_index
+
+ # this method is defined in the template file
+ write_extra_pages if defined? write_extra_pages
+ end
+
+ def gen_into(list)
+ list.each do |item|
+ if item.document_self
+ op_file = item.path
+ File.makedirs(File.dirname(op_file))
+ File.open(op_file, "w") { |file| item.write_on(file) }
+ end
+ end
+
+ end
+
+ def gen_file_index
+ gen_an_index(@files, 'Files',
+ RDoc::Page::FILE_INDEX,
+ "fr_file_index.html")
+ end
+
+ def gen_class_index
+ gen_an_index(@classes, 'Classes',
+ RDoc::Page::CLASS_INDEX,
+ "fr_class_index.html")
+ end
+
+ def gen_method_index
+ gen_an_index(HtmlMethod.all_methods, 'Methods',
+ RDoc::Page::METHOD_INDEX,
+ "fr_method_index.html")
+ end
+
+
+ def gen_an_index(collection, title, template, filename)
+ template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)
+ res = []
+ collection.sort.each do |f|
+ if f.document_self
+ res << { "href" => f.path, "name" => f.index_name }
+ end
+ end
+
+ values = {
+ "entries" => res,
+ 'list_title' => CGI.escapeHTML(title),
+ 'index_url' => main_url,
+ 'charset' => @options.charset,
+ 'style_url' => style_url('', @options.css),
+ }
+
+ File.open(filename, "w") do |f|
+ template.write_html_on(f, values)
+ end
+ end
+
+ # The main index page is mostly a template frameset, but includes
+ # the initial page. If the <tt>--main</tt> option was given,
+ # we use this as our main page, otherwise we use the
+ # first file specified on the command line.
+
+ def gen_main_index
+ template = TemplatePage.new(RDoc::Page::INDEX)
+ File.open("index.html", "w") do |f|
+ values = {
+ "initial_page" => main_url,
+ 'title' => CGI.escapeHTML(@options.title),
+ 'charset' => @options.charset
+ }
+ template.write_html_on(f, values)
+ end
+ end
+
+ # return the url of the main page
+ def main_url
+ main_page = @options.main_page
+ ref = nil
+ if main_page
+ ref = AllReferences[main_page]
+ if ref
+ ref = ref.path
+ else
+ $stderr.puts "Could not find main page #{main_page}"
+ end
+ end
+
+ ref = @files[0].path unless ref
+
+ ref
+ end
+
+
+ end
+
+
+ ######################################################################
+
+
+ class HTMLGeneratorInOne < HTMLGenerator
+
+ def initialize(*args)
+ super
+ end
+
+ ##
+ # Build the initial indices and output objects
+ # based on an array of TopLevel objects containing
+ # the extracted information.
+
+ def generate(info)
+ @toplevels = 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
+
+ @toplevels.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
+ 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),
+ 'title' => CGI.escapeHTML(@options.title),
+ }
+
+ # 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
+
+ end
+end
diff --git a/lib/rdoc/generators/template/chm/chm.rb b/lib/rdoc/generators/template/chm/chm.rb
new file mode 100644
index 0000000000..6df83a7773
--- /dev/null
+++ b/lib/rdoc/generators/template/chm/chm.rb
@@ -0,0 +1,86 @@
+module RDoc
+module Page
+
+require "rdoc/generators/template/html/html"
+
+# This is a nasty little hack, but hhc doesn't support the <?xml
+# tag, so...
+
+BODY.sub!(/<\?xml.*\?>/, '')
+
+HPP_FILE = %{
+[OPTIONS]
+Auto Index = Yes
+Compatibility=1.1 or later
+Compiled file=%opname%.chm
+Contents file=contents.hhc
+Full-text search=Yes
+Index file=index.hhk
+Language=0x409 English(United States)
+Title=%title%
+
+[FILES]
+START:all_html_files
+%html_file_name%
+END:all_html_files
+}
+
+CONTENTS = %{
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="Foreground" value="0x80">
+ <param name="Window Styles" value="0x800025">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+START:contents
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="%c_name%">
+ <param name="Local" value="%ref%">
+ </OBJECT>
+IF:methods
+<ul>
+START:methods
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="%name%">
+ <param name="Local" value="%aref%">
+ </OBJECT>
+END:methods
+</ul>
+ENDIF:methods
+ </LI>
+END:contents
+</UL>
+</BODY></HTML>
+}
+
+
+CHM_INDEX = %{
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="Foreground" value="0x80">
+ <param name="Window Styles" value="0x800025">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+START:index
+ <LI> <OBJECT type="text/sitemap">
+ <param name="Name" value="%name%">
+ <param name="Local" value="%aref%">
+ </OBJECT>
+END:index
+</UL>
+</BODY></HTML>
+}
+end
+end
diff --git a/lib/rdoc/generators/template/html/css2.rb b/lib/rdoc/generators/template/html/css2.rb
new file mode 100644
index 0000000000..0109ae3e7f
--- /dev/null
+++ b/lib/rdoc/generators/template/html/css2.rb
@@ -0,0 +1,631 @@
+#
+# = CSS2 RDoc HTML template
+#
+# This is a template for RDoc that uses XHTML 1.0 Transitional and dictates a
+# bit more of the appearance of the output to cascading stylesheets than the
+# default. It was designed for clean inline code display, and uses DHTMl to
+# toggle the visbility of each method's source with each click on the '[source]'
+# link.
+#
+# == Authors
+#
+# * Michael Granger <ged@FaerieMUD.org>
+#
+# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved.
+#
+# This work is licensed under the Creative Commons Attribution License. To view
+# a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or
+# send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
+# 94305, USA.
+#
+
+module RDoc
+ module Page
+
+ FONTS = "Verdana,Arial,Helvetica,sans-serif"
+
+STYLE = %{
+body {
+ margin: 0;
+ padding: 0;
+}
+
+h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
+h1 { font-size: 120%; }
+h2,h3,h4 { margin-top: 1em; }
+
+a { background: #eef; color: #039; text-decoration: none; }
+a:hover { background: #039; color: #eef; }
+
+/* Override the base stylesheet's Anchor inside a table cell */
+td > a {
+ background: transparent;
+ color: #039;
+ text-decoration: none;
+}
+
+/* === Structural elements =================================== */
+
+div#index {
+ margin: 0;
+ padding: 0;
+ font-size: 0.9em;
+}
+
+div#index a {
+ margin-left: 0.7em;
+}
+
+div#classHeader {
+ width: auto;
+ background: #039;
+ color: white;
+ padding: 0.5em 1.5em 0.5em 1.5em;
+ margin: 0;
+ border-bottom: 3px solid #006;
+}
+
+div#classHeader a {
+ background: inherit;
+ color: white;
+}
+
+div#classHeader td {
+ background: inherit;
+ color: white;
+}
+
+div#fileHeader {
+ width: auto;
+ background: #039;
+ color: white;
+ padding: 0.5em 1.5em 0.5em 1.5em;
+ margin: 0;
+ border-bottom: 3px solid #006;
+}
+
+div#fileHeader a {
+ background: inherit;
+ color: white;
+}
+
+div#fileHeader td {
+ background: inherit;
+ color: white;
+}
+
+div#bodyContent {
+ padding: 0 1.5em 0 1.5em;
+}
+
+div#description {
+ padding: 0.5em 1.5em;
+ background: #efefef;
+ border: 1px dotted #999;
+}
+
+div#description h1,h2,h3,h4,h5,h6 {
+ color: black;
+ background: transparent;
+}
+
+div#validator-badges {
+ text-align: center;
+}
+div#validator-badges img { border: 0; }
+
+div#copyright {
+ color: #333;
+ background: #efefef;
+ font: 0.75em sans-serif;
+ margin-top: 5em;
+ margin-bottom: 0;
+ padding: 0.5em 2em;
+}
+
+
+/* === Classes =================================== */
+
+table.header-table {
+ color: white;
+ font-size: small;
+}
+
+.type-note {
+ font-size: small;
+ color: #DEDEDE;
+}
+
+.section-bar {
+ background: #eee;
+ color: #333;
+ padding: 3px;
+ border: 1px solid #999;
+}
+
+.top-aligned-row { vertical-align: vertical-align: top }
+
+/* --- Context section classes ----------------------- */
+
+.context-row { }
+.context-item-name { font-family: monospace; font-weight: bold; color: black; }
+.context-item-value { font-size: x-small; color: #448; }
+.context-item-desc { background: #efefef; }
+
+/* --- Method classes -------------------------- */
+.method-detail {
+ background: #EFEFEF;
+ padding: 0;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ border: 1px dotted #DDD;
+}
+.method-heading {
+ color: black;
+ background: #AAA;
+ border-bottom: 1px solid #666;
+ padding: 0.2em 0.5em 0 0.5em;
+}
+.method-signature { color: black; background: inherit; }
+.method-name { font-weight: bold; }
+.method-args { font-style: italic; }
+.method-description { padding: 0 0.5em 0 0.5em; }
+
+/* --- Source code sections -------------------- */
+
+a.source-toggle { font-size: 90%; }
+div.method-source-code {
+ background: #262626;
+ color: #ffdead;
+ margin: 1em;
+ padding: 0.5em;
+ border: 1px dashed #999;
+ overflow: hidden;
+}
+
+div.method-source-code pre { color: #ffdead; overflow: hidden; }
+
+/* --- Ruby keyword styles --------------------- */
+/* (requires a hacked html_generator.rb to add more class-types) */
+.ruby-constant { color: #7fffd4; background: transparent; }
+.ruby-keyword { color: #00ffff; background: transparent; }
+.ruby-ivar { color: #eedd82; background: transparent; }
+.ruby-operator { color: #00ffee; background: transparent; }
+.ruby-identifier { color: #ffdead; background: transparent; }
+.ruby-node { color: #ffa07a; background: transparent; }
+.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
+.ruby-regexp { color: #ffa07a; background: transparent; }
+.ruby-value { color: #7fffd4; background: transparent; }
+}
+
+
+#####################################################################
+### H E A D E R T E M P L A T E
+#####################################################################
+
+XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "DTD/xhtml1-transitional.dtd">
+}
+
+HEADER = XHTML_PREAMBLE + %{
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
+ <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
+ <script type="text/javascript">
+ // <![CDATA[
+
+ function popupCode( url ) {
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
+ }
+
+ function toggleCode( id ) {
+ if ( document.getElementById )
+ elem = document.getElementById( id );
+ else if ( document.all )
+ elem = eval( "document.all." + id );
+ else
+ return false;
+
+ elemStyle = elem.style;
+
+ if ( elemStyle.display != "block" ) {
+ elemStyle.display = "block"
+ } else {
+ elemStyle.display = "none"
+ }
+
+ return true;
+ }
+
+ // Make codeblocks hidden by default
+ document.writeln( "<style type=\\"text/css\\">div.method-source-code { display: none }</style>" )
+
+ // ]]>
+ </script>
+
+</head>
+<body>
+}
+
+
+#####################################################################
+### C O N T E X T C O N T E N T T E M P L A T E
+#####################################################################
+
+CONTEXT_CONTENT = %{
+ <div id="contextContent">
+IF:diagram
+ <div id="diagram">
+ %diagram%
+ </div>
+ENDIF:diagram
+
+IF:description
+ <div id="description">
+ %description%
+ </div>
+ENDIF:description
+
+IF:requires
+ <div id="requires-list">
+ <h2 class="section-bar">Required files</h2>
+
+ <div class="name-list">
+START:requires
+ HREF:aref:name:&nbsp;&nbsp;
+END:requires
+ </div>
+ </div>
+ENDIF:requires
+
+IF:methods
+ <div id="method-list">
+ <h2 class="section-bar">Methods</h2>
+
+ <div class="name-list">
+START:methods
+ HREF:aref:name:&nbsp;&nbsp;
+END:methods
+ </div>
+ </div>
+ENDIF:methods
+
+IF:constants
+ <div id="constants-list">
+ <h2 class="section-bar">Constants</h2>
+
+ <div class="name-list">
+ <table summary="Constants">
+START:constants
+ <tr class="top-aligned-row context-row">
+ <td class="context-item-name">%name%</td>
+ <td>=</td>
+ <td class="context-item-value">%value%</td>
+ </tr>
+IF:desc
+ <tr class="top-aligned-row context-row">
+ <td>&nbsp;</td>
+ <td colspan="2" class="context-item-desc">%desc%</td>
+ </tr>
+ENDIF:desc
+END:constants
+ </table>
+ </div>
+ </div>
+ENDIF:constants
+
+IF:aliases
+ <div id="aliases-list">
+ <h2 class="section-bar">External Aliases</h2>
+
+ <div class="name-list">
+START:aliases
+ %old_name% -> %new_name% <br />
+END:aliases
+ </div>
+ </div>
+ENDIF:aliases
+
+
+IF:attributes
+ <div id="attribute-list">
+ <h2 class="section-bar">Attributes</h2>
+
+ <div class="name-list">
+ <table>
+START:attributes
+ <tr class="top-aligned-row context-row">
+ <td class="context-item-name">%name%</td>
+ <td class="context-item-value">&nbsp;[%rw%]&nbsp;</td>
+ <td class="context-item-desc">%a_desc%</td>
+ </tr>
+END:attributes
+ </table>
+ </div>
+ </div>
+ENDIF:attributes
+
+IF:classlist
+ <div id="class-list">
+ <h2 class="section-bar">Classes and Modules</h2>
+
+ %classlist%
+ </div>
+ENDIF:classlist
+
+ </div>
+
+}
+
+
+#####################################################################
+### F O O T E R T E M P L A T E
+#####################################################################
+FOOTER = %{
+<div id="validator-badges">
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
+</div>
+
+</body>
+</html>
+}
+
+
+#####################################################################
+### F I L E P A G E H E A D E R T E M P L A T E
+#####################################################################
+
+FILE_PAGE = %{
+ <div id="fileHeader">
+ <h1>%short_name%</h1>
+ <table class="header-table">
+ <tr class="top-aligned-row">
+ <td><strong>Path:</strong></td>
+ <td>%full_path%
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+ </td>
+ </tr>
+ <tr class="top-aligned-row">
+ <td><strong>Last Update:</strong></td>
+ <td>%dtm_modified%</td>
+ </tr>
+ </table>
+ </div>
+}
+
+
+#####################################################################
+### C L A S S P A G E H E A D E R T E M P L A T E
+#####################################################################
+
+CLASS_PAGE = %{
+ <div id="classHeader">
+ <h1>%full_name% <sup class="type-note">(%classmod%)</sup></h1>
+ <table class="header-table">
+ <tr class="top-aligned-row">
+ <td><strong>In:</strong></td>
+ <td>
+START:infiles
+IF:full_path_url
+ <a href="%full_path_url%">
+ENDIF:full_path_url
+ %full_path%
+IF:full_path_url
+ </a>
+ENDIF:full_path_url
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+ <br />
+END:infiles
+ </td>
+ </tr>
+
+IF:parent
+ <tr class="top-aligned-row">
+ <td><strong>Parent:</strong></td>
+ <td>
+IF:par_url
+ <a href="%par_url%">
+ENDIF:par_url
+ %parent%
+IF:par_url
+ </a>
+ENDIF:par_url
+ </td>
+ </tr>
+ENDIF:parent
+ </table>
+ </div>
+}
+
+
+#####################################################################
+### M E T H O D L I S T T E M P L A T E
+#####################################################################
+
+METHOD_LIST = %{
+
+ <!-- if includes -->
+IF:includes
+ <div id="includes">
+ <h2 class="section-bar">Included Modules</h2>
+
+ <div id="includes-list">
+START:includes
+ <span class="include-name">HREF:aref:name:</span>
+END:includes
+ </div>
+ </div>
+ENDIF:includes
+
+
+ <!-- if method_list -->
+IF:method_list
+ <div id="methods">
+START:method_list
+IF:methods
+ <h2 class="section-bar">%type% %category% methods</h2>
+
+START:methods
+ <!-- %name%%params% -->
+ <div id="method-%aref%" class="method-detail">
+ <a name="%aref%"></a>
+
+ <div class="method-heading">
+IF:codeurl
+ <a href="%codeurl%" target="Code" class="method-signature"
+ onclick="popupCode('%codeurl%');return false;">
+ENDIF:codeurl
+IF:sourcecode
+ <a href="#%aref%" class="method-signature">
+ENDIF:sourcecode
+ <span class="method-name">%name%</span><span class="method-args">%params%</span>
+IF:codeurl
+ </a>
+ENDIF:codeurl
+IF:sourcecode
+ </a>
+ENDIF:sourcecode
+ </div>
+
+ <div class="method-description">
+IF:m_desc
+ %m_desc%
+ENDIF:m_desc
+IF:sourcecode
+ <p><a class="source-toggle" href="#"
+ onclick="toggleCode('%aref%-source');return false;">[Source]</a></p>
+ <div class="method-source-code" id="%aref%-source">
+<pre>
+%sourcecode%
+</pre>
+ </div>
+ENDIF:sourcecode
+ </div>
+ </div>
+
+END:methods
+ENDIF:methods
+END:method_list
+
+ </div>
+ENDIF:method_list
+}
+
+
+#####################################################################
+### B O D Y T E M P L A T E
+#####################################################################
+
+BODY = HEADER + %{
+
+!INCLUDE! <!-- banner header -->
+
+ <div id="bodyContent">
+
+} + CONTEXT_CONTENT + METHOD_LIST + %{
+
+ </div>
+
+} + FOOTER
+
+
+
+#####################################################################
+### S O U R C E C O D E T E M P L A T E
+#####################################################################
+
+SRC_PAGE = XHTML_PREAMBLE + %{
+<!--
+
+ %title%
+
+ -->
+<html>
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+ <link rel="stylesheet" href="http://www.FaerieMUD.org/stylesheets/rdoc.css" type="text/css" />
+</head>
+<body>
+ <pre>%code%</pre>
+</body>
+</html>
+}
+
+
+#####################################################################
+### I N D E X F I L E T E M P L A T E S
+#####################################################################
+
+FR_INDEX_BODY = %{
+!INCLUDE!
+}
+
+FILE_INDEX = XHTML_PREAMBLE + %{
+<!--
+
+ %list_title%
+
+ -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>%list_title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+ <link rel="stylesheet" href="%style_url%" type="text/css" />
+ <base target="docwin" />
+</head>
+<body>
+<div id="index">
+ <h1 class="section-bar">%list_title%</h1>
+ <div id="index-entries">
+START:entries
+ <a href="%href%">%name%</a><br />
+END:entries
+ </div>
+</div>
+</body>
+</html>
+}
+
+CLASS_INDEX = FILE_INDEX
+METHOD_INDEX = FILE_INDEX
+
+INDEX = %{<?xml version="1.0" encoding="%charset%"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+ "DTD/xhtml1-frameset.dtd">
+
+<!--
+
+ %title%
+
+ -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+</head>
+<frameset rows="20%, 80%">
+ <frameset cols="25%,35%,45%">
+ <frame src="fr_file_index.html" title="Files" name="Files" />
+ <frame src="fr_class_index.html" name="Classes" />
+ <frame src="fr_method_index.html" name="Methods" />
+ </frameset>
+ <frame src="%initial_page%" name="docwin" />
+</frameset>
+</html>
+}
+
+
+ end # module Page
+end # class RDoc
+
diff --git a/lib/rdoc/generators/template/html/hefss.rb b/lib/rdoc/generators/template/html/hefss.rb
new file mode 100644
index 0000000000..ff4f557b71
--- /dev/null
+++ b/lib/rdoc/generators/template/html/hefss.rb
@@ -0,0 +1,418 @@
+module RDoc
+module Page
+
+
+FONTS = "Verdana, Arial, Helvetica, sans-serif"
+
+STYLE = %{
+body,p { font-family: Verdana, Arial, Helvetica, sans-serif;
+ color: #000040; background: #BBBBBB;
+}
+
+td { font-family: Verdana, Arial, Helvetica, sans-serif;
+ color: #000040;
+}
+
+.attr-rw { font-size: small; color: #444488 }
+
+.title-row {color: #eeeeff;
+ background: #BBBBDD;
+}
+
+.big-title-font { color: white;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: large;
+ height: 50px}
+
+.small-title-font { color: purple;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: small; }
+
+.aqua { color: purple }
+
+.method-name, attr-name {
+ font-family: monospace; font-weight: bold;
+}
+
+.tablesubtitle {
+ width: 100%;
+ margin-top: 1ex;
+ margin-bottom: .5ex;
+ padding: 5px 0px 5px 20px;
+ font-size: large;
+ color: purple;
+ background: #BBBBCC;
+}
+
+.tablesubsubtitle {
+ width: 100%;
+ margin-top: 1ex;
+ margin-bottom: .5ex;
+ padding: 5px 0px 5px 20px;
+ font-size: medium;
+ color: white;
+ background: #BBBBCC;
+}
+
+.name-list {
+ font-family: monospace;
+ margin-left: 40px;
+ margin-bottom: 2ex;
+ line-height: 140%;
+}
+
+.description {
+ margin-left: 40px;
+ margin-bottom: 2ex;
+ line-height: 140%;
+}
+
+.methodtitle {
+ font-size: medium;
+ text_decoration: none;
+ padding: 3px 3px 3px 20px;
+ color: #0000AA;
+}
+
+.column-title {
+ font-size: medium;
+ font-weight: bold;
+ text_decoration: none;
+ padding: 3px 3px 3px 20px;
+ color: #3333CC;
+ }
+
+.variable-name {
+ font-family: monospace;
+ font-size: medium;
+ text_decoration: none;
+ padding: 3px 3px 3px 20px;
+ color: #0000AA;
+}
+
+.row-name {
+ font-size: medium;
+ font-weight: medium;
+ font-family: monospace;
+ text_decoration: none;
+ padding: 3px 3px 3px 20px;
+}
+
+.paramsig {
+ font-size: small;
+}
+
+.srcbut { float: right }
+
+}
+
+
+############################################################################
+
+
+BODY = %{
+<html><head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+ <link rel=StyleSheet href="%style_url%" type="text/css" media=screen>
+ <script type="text/javascript" language="JavaScript">
+ <!--
+ function popCode(url) {
+ parent.frames.source.location = url
+ }
+ //-->
+ </script>
+</head>
+<body bgcolor="#BBBBBB">
+
+!INCLUDE! <!-- banner header -->
+
+IF:diagram
+<table width="100%"><tr><td align="center">
+%diagram%
+</td></tr></table>
+ENDIF:diagram
+
+IF:description
+<div class="description">%description%</div>
+ENDIF:description
+
+IF:requires
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Required files</td></tr>
+</table><br>
+<div class="name-list">
+START:requires
+HREF:aref:name:
+END:requires
+ENDIF:requires
+</div>
+
+IF:methods
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Subroutines and Functions</td></tr>
+</table><br>
+<div class="name-list">
+START:methods
+HREF:aref:name:,
+END:methods
+</div>
+ENDIF:methods
+
+IF:attributes
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Arguments</td></tr>
+</table><br>
+<table cellspacing=5>
+START:attributes
+ <tr valign="top">
+IF:rw
+ <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
+ENDIF:rw
+IFNOT:rw
+ <td></td>
+ENDIF:rw
+ <td class="attr-name">%name%</td>
+ <td>%a_desc%</td>
+ </tr>
+END:attributes
+</table>
+ENDIF:attributes
+
+IF:classlist
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Modules</td></tr>
+</table><br>
+%classlist%<br>
+ENDIF:classlist
+
+ !INCLUDE! <!-- method descriptions -->
+
+</body>
+</html>
+}
+
+###############################################################################
+
+FILE_PAGE = <<_FILE_PAGE_
+<table width="100%">
+ <tr class="title-row">
+ <td><table width="100%"><tr>
+ <td class="big-title-font" colspan=2><font size=-3><B>File</B><BR></font>%short_name%</td>
+ <td align="right"><table cellspacing=0 cellpadding=2>
+ <tr>
+ <td class="small-title-font">Path:</td>
+ <td class="small-title-font">%full_path%
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+ </td>
+ </tr>
+ <tr>
+ <td class="small-title-font">Modified:</td>
+ <td class="small-title-font">%dtm_modified%</td>
+ </tr>
+ </table>
+ </td></tr></table></td>
+ </tr>
+</table><br>
+_FILE_PAGE_
+
+###################################################################
+
+CLASS_PAGE = %{
+<table width="100%" border=0 cellspacing=0>
+ <tr class="title-row">
+ <td class="big-title-font">
+ <font size=-3><B>%classmod%</B><BR></font>%full_name%
+ </td>
+ <td align="right">
+ <table cellspacing=0 cellpadding=2>
+ <tr valign="top">
+ <td class="small-title-font">In:</td>
+ <td class="small-title-font">
+START:infiles
+HREF:full_path_url:full_path:
+IF:cvsurl
+&nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+END:infiles
+ </td>
+ </tr>
+IF:parent
+ <tr>
+ <td class="small-title-font">Parent:</td>
+ <td class="small-title-font">
+IF:par_url
+ <a href="%par_url%" class="cyan">
+ENDIF:par_url
+%parent%
+IF:par_url
+ </a>
+ENDIF:par_url
+ </td>
+ </tr>
+ENDIF:parent
+ </table>
+ </td>
+ </tr>
+</table><br>
+}
+
+###################################################################
+
+METHOD_LIST = %{
+IF:includes
+<div class="tablesubsubtitle">Uses</div><br>
+<div class="name-list">
+START:includes
+ <span class="method-name">HREF:aref:name:</span>
+END:includes
+</div>
+ENDIF:includes
+
+IF:method_list
+START:method_list
+IF:methods
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
+</table>
+START:methods
+<table width="100%" cellspacing = 0 cellpadding=5 border=0>
+<tr><td class="methodtitle">
+<a name="%aref%">
+<b>%name%</b>%params%
+IF:codeurl
+<a href="%codeurl%" target="source" class="srclink">src</a>
+ENDIF:codeurl
+</a></td></tr>
+</table>
+IF:m_desc
+<div class="description">
+%m_desc%
+</div>
+ENDIF:m_desc
+END:methods
+ENDIF:methods
+END:method_list
+ENDIF:method_list
+}
+
+=begin
+=end
+
+########################## Source code ##########################
+
+SRC_PAGE = %{
+<html>
+<head><title>%title%</title>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<style>
+ .kw { color: #3333FF; font-weight: bold }
+ .cmt { color: green; font-style: italic }
+ .str { color: #662222; font-style: italic }
+ .re { color: #662222; }
+.ruby-comment { color: green; font-style: italic }
+.ruby-constant { color: #4433aa; font-weight: bold; }
+.ruby-identifier { color: #222222; }
+.ruby-ivar { color: #2233dd; }
+.ruby-keyword { color: #3333FF; font-weight: bold }
+.ruby-node { color: #777777; }
+.ruby-operator { color: #111111; }
+.ruby-regexp { color: #662222; }
+.ruby-value { color: #662222; font-style: italic }
+</style>
+</head>
+<body bgcolor="#BBBBBB">
+<pre>%code%</pre>
+</body>
+</html>
+}
+
+########################## Index ################################
+
+FR_INDEX_BODY = %{
+!INCLUDE!
+}
+
+FILE_INDEX = %{
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<style>
+<!--
+ body {
+background-color: #bbbbbb;
+ font-family: #{FONTS};
+ font-size: 11px;
+ font-style: normal;
+ line-height: 14px;
+ color: #000040;
+ }
+div.banner {
+ background: #bbbbcc;
+ color: white;
+ padding: 1;
+ margin: 0;
+ font-size: 90%;
+ font-weight: bold;
+ line-height: 1.1;
+ text-align: center;
+ width: 100%;
+}
+
+-->
+</style>
+<base target="docwin">
+</head>
+<body>
+<div class="banner">%list_title%</div>
+START:entries
+<a href="%href%">%name%</a><br>
+END:entries
+</body></html>
+}
+
+CLASS_INDEX = FILE_INDEX
+METHOD_INDEX = FILE_INDEX
+
+INDEX = %{
+<html>
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+</head>
+
+<frameset cols="20%,*">
+ <frameset rows="15%,35%,50%">
+ <frame src="fr_file_index.html" title="Files" name="Files">
+ <frame src="fr_class_index.html" name="Modules">
+ <frame src="fr_method_index.html" name="Subroutines and Functions">
+ </frameset>
+ <frameset rows="80%,20%">
+ <frame src="%initial_page%" name="docwin">
+ <frame src="blank.html" name="source">
+ </frameset>
+ <noframes>
+ <body bgcolor="#BBBBBB">
+ Click <a href="html/index.html">here</a> for a non-frames
+ version of this page.
+ </body>
+ </noframes>
+</frameset>
+
+</html>
+}
+
+# and a blank page to use as a target
+BLANK = %{
+<html><body bgcolor="#BBBBBB"></body></html>
+}
+
+def write_extra_pages
+ template = TemplatePage.new(BLANK)
+ File.open("blank.html", "w") { |f| template.write_html_on(f, {}) }
+end
+
+end
+end
diff --git a/lib/rdoc/generators/template/html/html.rb b/lib/rdoc/generators/template/html/html.rb
new file mode 100644
index 0000000000..18ad9dcb3b
--- /dev/null
+++ b/lib/rdoc/generators/template/html/html.rb
@@ -0,0 +1,762 @@
+module RDoc
+
+# This is how you define the HTML that RDoc generates. Simply create
+# a file in rdoc/generators/html_templates that creates the
+# module RDoc::Page and populate it as described below. Then invoke
+# rdoc using the --template <name of your file> option, and
+# your template will be used.
+#
+# The constants defining pages use a simple templating system:
+#
+# * The templating system is passed a hash. Keys in the hash correspond
+# to tags on this page. The tag %abc% is looked up in the hash,
+# and is replaced by the corresponding hash value.
+#
+# * Some tags are optional. You can detect this using IF/ENDIF
+#
+# IF: title
+# The value of title is %title%
+# ENDIF: title
+#
+# * Some entries in the hash have values that are arrays, where each
+# entry in the array is itself a hash. These are used to generate
+# lists using the START: construct. For example, given a hash
+# containing
+#
+# { 'people' => [ { 'name' => 'Fred', 'age' => '12' },
+# { 'name' => 'Mary', 'age' => '21' } ]
+#
+# You could generate a simple table using
+#
+# <table>
+# START:people
+# <tr><td>%name%<td>%age%</tr>
+# END:people
+# </table>
+#
+# These lists can be nested to an arbitrary depth
+#
+# * the construct HREF:url:name: generates <a href="%url%">%name%</a>
+# if +url+ is defined in the hash, or %name% otherwise.
+#
+#
+# Your file must contain the following constants
+#
+# [*FONTS*] a list of fonts to be used
+# [*STYLE*] a CSS section (without the <style> or comments). This is
+# used to generate a style.css file
+#
+# [*BODY*]
+# The main body of all non-index RDoc pages. BODY will contain
+# two !INCLUDE!s. The first is used to include a document-type
+# specific header (FILE_PAGE or CLASS_PAGE). The second include
+# is for the method list (METHOD_LIST). THe body is passed:
+#
+# %title%::
+# the page's title
+#
+# %style_url%::
+# the url of a style sheet for this page
+#
+# %diagram%::
+# the optional URL of a diagram for this page
+#
+# %description%::
+# a (potentially multi-paragraph) string containing the
+# description for th file/class/module.
+#
+# %requires%::
+# an optional list of %aref%/%name% pairs, one for each module
+# required by this file.
+#
+# %methods%::
+# an optional list of %aref%/%name%, one for each method
+# documented on this page. This is intended to be an index.
+#
+# %attributes%::
+# An optional list. For each attribute it contains:
+# %name%:: the attribute name
+# %rw%:: r/o, w/o, or r/w
+# %a_desc%:: description of the attribute
+#
+# %classlist%::
+# An optional string containing an already-formatted list of
+# classes and modules documented in this file
+#
+# For FILE_PAGE entries, the body will be passed
+#
+# %short_name%::
+# The name of the file
+#
+# %full_path%::
+# The full path to the file
+#
+# %dtm_modified%::
+# The date/time the file was last changed
+#
+# For class and module pages, the body will be passed
+#
+# %classmod%::
+# The name of the class or module
+#
+# %files%::
+# A list. For each file this class is defined in, it contains:
+# %full_path_url%:: an (optional) URL of the RDoc page
+# for this file
+# %full_path%:: the name of the file
+#
+# %par_url%::
+# The (optional) URL of the RDoc page documenting this class's
+# parent class
+#
+# %parent%::
+# The name of this class's parent.
+#
+# For both files and classes, the body is passed the following information
+# on includes and methods:
+#
+# %includes%::
+# Optional list of included modules. For each, it receives
+# %aref%:: optional URL to RDoc page for the module
+# %name%:: the name of the module
+#
+# %method_list%::
+# Optional list of methods of a particular class and category.
+#
+# Each method list entry contains:
+#
+# %type%:: public/private/protected
+# %category%:: instance/class
+# %methods%:: a list of method descriptions
+#
+# Each method description contains:
+#
+# %aref%:: a target aref, used when referencing this method
+# description. You should code this as <a name="%aref%">
+# %codeurl%:: the optional URL to the page containing this method's
+# source code.
+# %name%:: the method's name
+# %params%:: the method's parameters
+# %m_desc%:: the (potentially multi-paragraph) description of
+# this method.
+#
+# [*CLASS_PAGE*]
+# Header for pages documenting classes and modules. See
+# BODY above for the available parameters.
+#
+# [*FILE_PAGE*]
+# Header for pages documenting files. See
+# BODY above for the available parameters.
+#
+# [*METHOD_LIST*]
+# Controls the display of the listing of methods. See BODY for
+# parameters.
+#
+# [*INDEX*]
+# The top-level index page. For a browser-like environment
+# define a frame set that includes the file, class, and
+# method indices. Passed
+# %title%:: title of page
+# %initial_page% :: url of initial page to display
+#
+# [*CLASS_INDEX*]
+# Individual files for the three indexes. Passed:
+# %index_url%:: URL of main index page
+# %entries%:: List of
+# %name%:: name of an index entry
+# %href%:: url of corresponding page
+# [*METHOD_INDEX*]
+# Same as CLASS_INDEX for methods
+#
+# [*FILE_INDEX*]
+# Same as CLASS_INDEX for methods
+#
+# [*FR_INDEX_BODY*]
+# A wrapper around CLASS_INDEX, METHOD_INDEX, and FILE_INDEX.
+# If those index strings contain the complete HTML for the
+# output, then FR_INDEX_BODY can simply be !INCLUDE!
+#
+# [*SRC_PAGE*]
+# Page used to display source code. Passed %title% and %code%,
+# the latter being a multi-line string of code.
+
+module Page
+
+FONTS = "Verdana, Arial, Helvetica, sans-serif"
+
+STYLE = %{
+body,td,p { font-family: %fonts%;
+ color: #000040;
+}
+
+.attr-rw { font-size: x-small; color: #444488 }
+
+.title-row { background: #0000aa;
+ color: #eeeeff;
+}
+
+.big-title-font { color: white;
+ font-family: %fonts%;
+ font-size: large;
+ height: 50px}
+
+.small-title-font { color: aqua;
+ font-family: %fonts%;
+ font-size: xx-small; }
+
+.aqua { color: aqua }
+
+.method-name, attr-name {
+ font-family: monospace; font-weight: bold;
+}
+
+.tablesubtitle, .tablesubsubtitle {
+ width: 100%;
+ margin-top: 1ex;
+ margin-bottom: .5ex;
+ padding: 5px 0px 5px 20px;
+ font-size: large;
+ color: aqua;
+ background: #3333cc;
+}
+
+.name-list {
+ font-family: monospace;
+ margin-left: 40px;
+ margin-bottom: 2ex;
+ line-height: 140%;
+}
+
+.description {
+ margin-left: 40px;
+ margin-top: -2ex;
+ margin-bottom: 2ex;
+}
+
+.description p {
+ line-height: 140%;
+}
+
+.aka {
+ margin-left: 40px;
+ margin-bottom: 2ex;
+ line-height: 100%;
+ font-size: small;
+ color: #808080;
+}
+
+.methodtitle {
+ font-size: medium;
+ text-decoration: none;
+ color: #0000AA;
+ background: white;
+}
+
+.paramsig {
+ font-size: small;
+}
+
+.srcbut { float: right }
+
+pre { font-size: 1.2em; }
+tt { font-size: 1.2em; }
+
+pre.source {
+ border-style: groove;
+ background-color: #ddddff;
+ margin-left: 40px;
+ padding: 1em 0em 1em 2em;
+}
+
+.classlist {
+ margin-left: 40px;
+ margin-bottom: 2ex;
+ line-height: 140%;
+}
+
+li {
+ display: list-item;
+ margin-top: .6em;
+}
+
+.ruby-comment { color: green; font-style: italic }
+.ruby-constant { color: #4433aa; font-weight: bold; }
+.ruby-identifier { color: #222222; }
+.ruby-ivar { color: #2233dd; }
+.ruby-keyword { color: #3333FF; font-weight: bold }
+.ruby-node { color: #777777; }
+.ruby-operator { color: #111111; }
+.ruby-regexp { color: #662222; }
+.ruby-value { color: #662222; font-style: italic }
+
+}
+
+
+############################################################################
+
+
+HEADER = %{
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+ <link rel=StyleSheet href="%style_url%" type="text/css" media="screen" />
+ <script type="text/javascript" language="JavaScript">
+ <!--
+ function popCode(url) {
+ window.open(url, "Code",
+ "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
+ }
+ //-->
+ </script>
+</head>
+}
+
+
+###################################################################
+
+METHOD_LIST = %{
+IF:includes
+<table summary="Included modules" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Included modules</td></tr>
+</table>
+<div class="name-list">
+START:includes
+ <span class="method-name">HREF:aref:name:</span>
+END:includes
+</div>
+ENDIF:includes
+
+IF:method_list
+START:method_list
+IF:methods
+<table summary="Method list" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
+</table>
+START:methods
+<table summary="method" width="100%" cellspacing="0" cellpadding="5" border="0">
+<tr><td class="methodtitle">
+<a name="%aref%"></a>
+IF:codeurl
+<a href="%codeurl%" target="Code" class="methodtitle"
+ onClick="popCode('%codeurl%');return false;">
+ENDIF:codeurl
+<b>%name%</b>%params%
+IF:codeurl
+</a>
+ENDIF:codeurl
+</td></tr>
+</table>
+IF:m_desc
+<div class="description">
+%m_desc%
+</div>
+ENDIF:m_desc
+IF:aka
+<div class="aka">
+This method is also aliased as
+START:aka
+<a href="%aref%">%name%</a>
+END:aka
+</div>
+ENDIF:aka
+IF:sourcecode
+<pre class="source">
+%sourcecode%
+</pre>
+ENDIF:sourcecode
+END:methods
+ENDIF:methods
+END:method_list
+ENDIF:method_list
+}
+
+###################################################################
+
+CONTEXT_CONTENT = %{
+IF:diagram
+<table summary="Diagram of classes and modules" width="100%">
+<tr><td align="center">
+%diagram%
+</td></tr></table>
+ENDIF:diagram
+
+
+IF:description
+<div class="description">%description%</div>
+ENDIF:description
+
+IF:requires
+<table summary="Requires" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Required files</td></tr>
+</table>
+<div class="name-list">
+START:requires
+HREF:aref:name:&nbsp; &nbsp;
+END:requires
+</div>
+ENDIF:requires
+
+IF:methods
+<table summary="Methods" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Methods</td></tr>
+</table>
+<div class="name-list">
+START:methods
+HREF:aref:name:&nbsp; &nbsp;
+END:methods
+</div>
+ENDIF:methods
+
+IF:constants
+<table summary="Constants" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Constants</td></tr>
+</table>
+<table cellpadding="5">
+START:constants
+<tr valign="top"><td>%name%</td><td>=</td><td>%value%</td></tr>
+IF:desc
+<tr><td></td><td></td><td>%desc%</td></tr>
+ENDIF:desc
+END:constants
+</table>
+ENDIF:constants
+
+IF:aliases
+<table summary="Aliases" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">External Aliases</td></tr>
+</table>
+<div class="name-list">
+START:aliases
+%old_name% -> %new_name%<br />
+END:aliases
+</div>
+ENDIF:aliases
+
+IF:attributes
+<table summary="Attributes" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Attributes</td></tr>
+</table>
+<table summary="Attribute details" cellspacing="5">
+START:attributes
+ <tr valign="top">
+ <td class="attr-name">%name%</td>
+IF:rw
+ <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
+ENDIF:rw
+IFNOT:rw
+ <td></td>
+ENDIF:rw
+ <td>%a_desc%</td>
+ </tr>
+END:attributes
+</table>
+ENDIF:attributes
+
+IF:classlist
+<table summary="List of classes" cellpadding="5" width="100%">
+<tr><td class="tablesubtitle">Classes and Modules</td></tr>
+</table>
+<div class="classlist">
+%classlist%
+</div>
+ENDIF:classlist
+}
+
+###############################################################################
+
+BODY = HEADER + %{
+<body bgcolor="white">
+!INCLUDE! <!-- banner header -->
+} +
+CONTEXT_CONTENT + METHOD_LIST +
+%{
+</body>
+</html>
+}
+
+
+###############################################################################
+
+FILE_PAGE = <<_FILE_PAGE_
+<table summary="Information on file" width="100%">
+ <tr class="title-row">
+ <td><table summary="layout" width="100%"><tr>
+ <td class="big-title-font" colspan="2">%short_name%</td>
+ <td align="right"><table summary="layout" cellspacing="0" cellpadding="2">
+ <tr>
+ <td class="small-title-font">Path:</td>
+ <td class="small-title-font">%full_path%
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+ </td>
+ </tr>
+ <tr>
+ <td class="small-title-font">Modified:</td>
+ <td class="small-title-font">%dtm_modified%</td>
+ </tr>
+ </table>
+ </td></tr></table></td>
+ </tr>
+</table>
+_FILE_PAGE_
+
+###################################################################
+
+CLASS_PAGE = %{
+<table summary="Information on class" width="100%" border="0" cellspacing="0">
+ <tr class="title-row">
+ <td class="big-title-font">
+ <sup><font color="aqua">%classmod%</font></sup> %full_name%
+ </td>
+ <td align="right">
+ <table summary="layout" cellspacing="0" cellpadding="2">
+ <tr valign="top">
+ <td class="small-title-font">In:</td>
+ <td class="small-title-font">
+START:infiles
+IF:full_path_url
+ <a href="%full_path_url%" class="aqua">
+ENDIF:full_path_url
+%full_path%
+IF:full_path_url
+ </a>
+ENDIF:full_path_url
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+<br />
+END:infiles
+ </td>
+ </tr>
+IF:parent
+ <tr>
+ <td class="small-title-font">Parent:</td>
+ <td class="small-title-font">
+IF:par_url
+ <a href="%par_url%" class="aqua">
+ENDIF:par_url
+%parent%
+IF:par_url
+ </a>
+ENDIF:par_url
+ </td>
+ </tr>
+ENDIF:parent
+ </table>
+ </td>
+ </tr>
+</table>
+}
+
+=begin
+=end
+
+########################## Source code ##########################
+
+SRC_PAGE = %{
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<title>%title%</title>
+<link rel=StyleSheet href="%style_url%" type="text/css" media="screen" />
+</head>
+<body bgcolor="white">
+<pre>%code%</pre>
+</body>
+</html>
+}
+
+########################## Index ################################
+
+FR_INDEX_BODY = %{
+!INCLUDE!
+}
+
+FILE_INDEX = %{
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<title>%list_title%</title>
+<style type="text/css">
+<!--
+ body {
+background-color: #ddddff;
+ font-family: #{FONTS};
+ font-size: 11px;
+ font-style: normal;
+ line-height: 14px;
+ color: #000040;
+ }
+div.banner {
+ background: #0000aa;
+ color: white;
+ padding: 1;
+ margin: 0;
+ font-size: 90%;
+ font-weight: bold;
+ line-height: 1.1;
+ text-align: center;
+ width: 100%;
+}
+
+A.xx { color: white; font-weight: bold; }
+-->
+</style>
+<base target="docwin">
+</head>
+<body>
+<div class="banner"><a href="%index_url%" class="xx">%list_title%</a></div>
+START:entries
+<a href="%href%">%name%</a><br />
+END:entries
+</body></html>
+}
+
+CLASS_INDEX = FILE_INDEX
+METHOD_INDEX = FILE_INDEX
+
+INDEX = %{
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<title>%title%</title></head>
+
+<frameset rows="20%, 80%">
+ <frameset cols="25%,35%,45%">
+ <frame src="fr_file_index.html" title="Files" name="Files">
+ <frame src="fr_class_index.html" name="Classes">
+ <frame src="fr_method_index.html" name="Methods">
+ </frameset>
+ <frame src="%initial_page%" name="docwin">
+ <noframes>
+ <body bgcolor="white">
+ Sorry, RDoc currently only generates HTML using frames.
+ </body>
+ </noframes>
+</frameset>
+
+</html>
+}
+
+######################################################################
+#
+# The following is used for the -1 option
+#
+
+CONTENTS_XML = %{
+IF:description
+%description%
+ENDIF:description
+
+IF:requires
+<h4>Requires:</h4>
+<ul>
+START:requires
+IF:aref
+<li><a href="%aref%">%name%</a></li>
+ENDIF:aref
+IFNOT:aref
+<li>%name%</li>
+ENDIF:aref
+END:requires
+</ul>
+ENDIF:requires
+
+IF:attributes
+<h4>Attributes</h4>
+<table>
+START:attributes
+<tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>
+END:attributes
+</table>
+ENDIF:attributes
+
+IF:includes
+<h4>Includes</h4>
+<ul>
+START:includes
+IF:aref
+<li><a href="%aref%">%name%</a></li>
+ENDIF:aref
+IFNOT:aref
+<li>%name%</li>
+ENDIF:aref
+END:includes
+</ul>
+ENDIF:includes
+
+IF:method_list
+<h3>Methods</h3>
+START:method_list
+IF:methods
+START:methods
+<h4>%type% %category% method: <a name="%aref%">%name%%params%</a></h4>
+
+IF:m_desc
+%m_desc%
+ENDIF:m_desc
+
+IF:sourcecode
+<blockquote><pre>
+%sourcecode%
+</pre></blockquote>
+ENDIF:sourcecode
+END:methods
+ENDIF:methods
+END:method_list
+ENDIF:method_list
+}
+
+########################################################################
+
+ONE_PAGE = %{
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
+</head>
+<body>
+START:files
+<h2>File: %short_name%</h2>
+<table>
+ <tr><td>Path:</td><td>%full_path%</td></tr>
+ <tr><td>Modified:</td><td>%dtm_modified%</td></tr>
+</table>
+} + CONTENTS_XML + %{
+END:files
+
+IF:classes
+<h2>Classes</h2>
+START:classes
+IF:parent
+<h3>%classmod% %full_name% &lt; HREF:par_url:parent:</h3>
+ENDIF:parent
+IFNOT:parent
+<h3>%classmod% %full_name%</h3>
+ENDIF:parent
+
+IF:infiles
+(in files
+START:infiles
+HREF:full_path_url:full_path:
+END:infiles
+)
+ENDIF:infiles
+} + CONTENTS_XML + %{
+END:classes
+ENDIF:classes
+</body>
+</html>
+}
+
+end
+end
diff --git a/lib/rdoc/generators/template/html/kilmer.rb b/lib/rdoc/generators/template/html/kilmer.rb
new file mode 100644
index 0000000000..27fde1d29f
--- /dev/null
+++ b/lib/rdoc/generators/template/html/kilmer.rb
@@ -0,0 +1,398 @@
+module RDoc
+module Page
+
+
+FONTS = "Verdana, Arial, Helvetica, sans-serif"
+
+STYLE = %{
+body,td,p { font-family: %fonts%;
+ color: #000040;
+}
+
+.attr-rw { font-size: xx-small; color: #444488 }
+
+.title-row { background-color: #CCCCFF;
+ color: #000010;
+}
+
+.big-title-font {
+ color: black;
+ font-weight: bold;
+ font-family: %fonts%;
+ font-size: large;
+ height: 60px;
+ padding: 10px 3px 10px 3px;
+}
+
+.small-title-font { color: black;
+ font-family: %fonts%;
+ font-size:10; }
+
+.aqua { color: black }
+
+.method-name, .attr-name {
+ font-family: font-family: %fonts%;
+ font-weight: bold;
+ font-size: small;
+ margin-left: 20px;
+ color: #000033;
+}
+
+.tablesubtitle, .tablesubsubtitle {
+ width: 100%;
+ margin-top: 1ex;
+ margin-bottom: .5ex;
+ padding: 5px 0px 5px 3px;
+ font-size: large;
+ color: black;
+ background-color: #CCCCFF;
+ border: thin;
+}
+
+.name-list {
+ margin-left: 5px;
+ margin-bottom: 2ex;
+ line-height: 105%;
+}
+
+.description {
+ margin-left: 5px;
+ margin-bottom: 2ex;
+ line-height: 105%;
+ font-size: small;
+}
+
+.methodtitle {
+ font-size: small;
+ font-weight: bold;
+ text-decoration: none;
+ color: #000033;
+ background-color: white;
+}
+
+.srclink {
+ font-size: small;
+ font-weight: bold;
+ text-decoration: none;
+ color: #0000DD;
+ background-color: white;
+}
+
+.paramsig {
+ font-size: small;
+}
+
+.srcbut { float: right }
+
+}
+
+
+############################################################################
+
+
+BODY = %{
+<html><head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+ <link rel=StyleSheet href="%style_url%" type="text/css" media=screen>
+ <script type="text/javascript" language="JavaScript">
+ <!--
+ function popCode(url) {
+ parent.frames.source.location = url
+ }
+ //-->
+ </script>
+</head>
+<body bgcolor="white">
+
+!INCLUDE! <!-- banner header -->
+
+IF:diagram
+<table width="100%"><tr><td align="center">
+%diagram%
+</td></tr></table>
+ENDIF:diagram
+
+IF:description
+<div class="description">%description%</div>
+ENDIF:description
+
+IF:requires
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Required files</td></tr>
+</table><br>
+<div class="name-list">
+START:requires
+HREF:aref:name:
+END:requires
+ENDIF:requires
+</div>
+
+IF:methods
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Methods</td></tr>
+</table><br>
+<div class="name-list">
+START:methods
+HREF:aref:name:,
+END:methods
+</div>
+ENDIF:methods
+
+IF:attributes
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Attributes</td></tr>
+</table><br>
+<table cellspacing=5>
+START:attributes
+ <tr valign="top">
+IF:rw
+ <td align="center" class="attr-rw">&nbsp;[%rw%]&nbsp;</td>
+ENDIF:rw
+IFNOT:rw
+ <td></td>
+ENDIF:rw
+ <td class="attr-name">%name%</td>
+ <td>%a_desc%</td>
+ </tr>
+END:attributes
+</table>
+ENDIF:attributes
+
+IF:classlist
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">Classes and Modules</td></tr>
+</table><br>
+%classlist%<br>
+ENDIF:classlist
+
+ !INCLUDE! <!-- method descriptions -->
+
+</body>
+</html>
+}
+
+###############################################################################
+
+FILE_PAGE = <<_FILE_PAGE_
+<table width="100%">
+ <tr class="title-row">
+ <td><table width="100%"><tr>
+ <td class="big-title-font" colspan=2><font size=-3><B>File</B><BR></font>%short_name%</td>
+ <td align="right"><table cellspacing=0 cellpadding=2>
+ <tr>
+ <td class="small-title-font">Path:</td>
+ <td class="small-title-font">%full_path%
+IF:cvsurl
+ &nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+ </td>
+ </tr>
+ <tr>
+ <td class="small-title-font">Modified:</td>
+ <td class="small-title-font">%dtm_modified%</td>
+ </tr>
+ </table>
+ </td></tr></table></td>
+ </tr>
+</table><br>
+_FILE_PAGE_
+
+###################################################################
+
+CLASS_PAGE = %{
+<table width="100%" border=0 cellspacing=0>
+ <tr class="title-row">
+ <td class="big-title-font">
+ <font size=-3><B>%classmod%</B><BR></font>%full_name%
+ </td>
+ <td align="right">
+ <table cellspacing=0 cellpadding=2>
+ <tr valign="top">
+ <td class="small-title-font">In:</td>
+ <td class="small-title-font">
+START:infiles
+HREF:full_path_url:full_path:
+IF:cvsurl
+&nbsp;(<a href="%cvsurl%">CVS</a>)
+ENDIF:cvsurl
+END:infiles
+ </td>
+ </tr>
+IF:parent
+ <tr>
+ <td class="small-title-font">Parent:</td>
+ <td class="small-title-font">
+IF:par_url
+ <a href="%par_url%" class="cyan">
+ENDIF:par_url
+%parent%
+IF:par_url
+ </a>
+ENDIF:par_url
+ </td>
+ </tr>
+ENDIF:parent
+ </table>
+ </td>
+ </tr>
+</table><br>
+}
+
+###################################################################
+
+METHOD_LIST = %{
+IF:includes
+<div class="tablesubsubtitle">Included modules</div><br>
+<div class="name-list">
+START:includes
+ <span class="method-name">HREF:aref:name:</span>
+END:includes
+</div>
+ENDIF:includes
+
+IF:method_list
+START:method_list
+IF:methods
+<table cellpadding=5 width="100%">
+<tr><td class="tablesubtitle">%type% %category% methods</td></tr>
+</table>
+START:methods
+<table width="100%" cellspacing = 0 cellpadding=5 border=0>
+<tr><td class="methodtitle">
+<a name="%aref%">
+<b>%name%</b>%params%
+IF:codeurl
+<a href="%codeurl%" target="source" class="srclink">src</a>
+ENDIF:codeurl
+</a></td></tr>
+</table>
+IF:m_desc
+<div class="description">
+%m_desc%
+</div>
+ENDIF:m_desc
+END:methods
+ENDIF:methods
+END:method_list
+ENDIF:method_list
+}
+
+=begin
+=end
+
+########################## Source code ##########################
+
+SRC_PAGE = %{
+<html>
+<head><title>%title%</title>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<style>
+.ruby-comment { color: green; font-style: italic }
+.ruby-constant { color: #4433aa; font-weight: bold; }
+.ruby-identifier { color: #222222; }
+.ruby-ivar { color: #2233dd; }
+.ruby-keyword { color: #3333FF; font-weight: bold }
+.ruby-node { color: #777777; }
+.ruby-operator { color: #111111; }
+.ruby-regexp { color: #662222; }
+.ruby-value { color: #662222; font-style: italic }
+ .kw { color: #3333FF; font-weight: bold }
+ .cmt { color: green; font-style: italic }
+ .str { color: #662222; font-style: italic }
+ .re { color: #662222; }
+</style>
+</head>
+<body bgcolor="white">
+<pre>%code%</pre>
+</body>
+</html>
+}
+
+########################## Index ################################
+
+FR_INDEX_BODY = %{
+!INCLUDE!
+}
+
+FILE_INDEX = %{
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+<style>
+<!--
+ body {
+background-color: #ddddff;
+ font-family: #{FONTS};
+ font-size: 11px;
+ font-style: normal;
+ line-height: 14px;
+ color: #000040;
+ }
+div.banner {
+ background: #0000aa;
+ color: white;
+ padding: 1;
+ margin: 0;
+ font-size: 90%;
+ font-weight: bold;
+ line-height: 1.1;
+ text-align: center;
+ width: 100%;
+}
+
+-->
+</style>
+<base target="docwin">
+</head>
+<body>
+<div class="banner">%list_title%</div>
+START:entries
+<a href="%href%">%name%</a><br>
+END:entries
+</body></html>
+}
+
+CLASS_INDEX = FILE_INDEX
+METHOD_INDEX = FILE_INDEX
+
+INDEX = %{
+<html>
+<head>
+ <title>%title%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
+</head>
+
+<frameset cols="20%,*">
+ <frameset rows="15%,35%,50%">
+ <frame src="fr_file_index.html" title="Files" name="Files">
+ <frame src="fr_class_index.html" name="Classes">
+ <frame src="fr_method_index.html" name="Methods">
+ </frameset>
+ <frameset rows="80%,20%">
+ <frame src="%initial_page%" name="docwin">
+ <frame src="blank.html" name="source">
+ </frameset>
+ <noframes>
+ <body bgcolor="white">
+ Click <a href="html/index.html">here</a> for a non-frames
+ version of this page.
+ </body>
+ </noframes>
+</frameset>
+
+</html>
+}
+
+# and a blank page to use as a target
+BLANK = %{
+<html><body bgcolor="white"></body></html>
+}
+
+def write_extra_pages
+ template = TemplatePage.new(BLANK)
+ File.open("blank.html", "w") { |f| template.write_html_on(f, {}) }
+end
+
+end
+end
diff --git a/lib/rdoc/generators/template/xml/rdf.rb b/lib/rdoc/generators/template/xml/rdf.rb
new file mode 100644
index 0000000000..1545d81a2f
--- /dev/null
+++ b/lib/rdoc/generators/template/xml/rdf.rb
@@ -0,0 +1,112 @@
+module RDoc
+module Page
+
+
+
+CONTENTS_RDF = %{
+IF:description
+ <description rd:parseType="Literal">
+%description%
+ </description>
+ENDIF:description
+
+IF:requires
+START:requires
+ <rd:required-file rd:name="%name%" />
+END:requires
+ENDIF:requires
+
+IF:attributes
+START:attributes
+ <contents>
+ <Attribute rd:name="%name%">
+IF:rw
+ <attribute-rw>%rw%</attribute-rw>
+ENDIF:rw
+ <description rdf:parseType="Literal">%a_desc%</description>
+ </Attribute>
+ </contents>
+END:attributes
+ENDIF:attributes
+
+IF:includes
+ <IncludedModuleList>
+START:includes
+ <included-module rd:name="%name%" />
+END:includes
+ </IncludedModuleList>
+ENDIF:includes
+
+IF:method_list
+START:method_list
+IF:methods
+START:methods
+ <contents>
+ <Method rd:name="%name%" rd:visibility="%type%"
+ rd:category="%category%" rd:id="%aref%">
+ <parameters>%params%</parameters>
+IF:m_desc
+ <description rdf:parseType="Literal">
+%m_desc%
+ </description>
+ENDIF:m_desc
+IF:sourcecode
+ <source-code-listing rdf:parseType="Literal">
+%sourcecode%
+ </source-code-listing>
+ENDIF:sourcecode
+ </Method>
+ </contents>
+END:methods
+ENDIF:methods
+END:method_list
+ENDIF:method_list
+ <!-- end method list -->
+}
+
+########################################################################
+
+ONE_PAGE = %{<?xml version="1.0" encoding="utf-8"?>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://pragprog.com/rdoc/rdoc.rdf#"
+ xmlns:rd="http://pragprog.com/rdoc/rdoc.rdf#">
+
+<!-- RDoc -->
+START:files
+ <rd:File rd:name="%short_name%" rd:id="%href%">
+ <path>%full_path%</path>
+ <dtm-modified>%dtm_modified%</dtm-modified>
+} + CONTENTS_RDF + %{
+ </rd:File>
+END:files
+START:classes
+ <%classmod% rd:name="%full_name%" rd:id="%full_name%">
+ <classmod-info>
+IF:infiles
+ <InFiles>
+START:infiles
+ <infile>
+ <File rd:name="%full_path%"
+IF:full_path_url
+ rdf:about="%full_path_url%"
+ENDIF:full_path_url
+ />
+ </infile>
+END:infiles
+ </InFiles>
+ENDIF:infiles
+IF:parent
+ <superclass>HREF:par_url:parent:</superclass>
+ENDIF:parent
+ </classmod-info>
+} + CONTENTS_RDF + %{
+ </%classmod%>
+END:classes
+<!-- /RDoc -->
+</rdf:RDF>
+}
+
+
+end
+end
+
diff --git a/lib/rdoc/generators/template/xml/xml.rb b/lib/rdoc/generators/template/xml/xml.rb
new file mode 100644
index 0000000000..4a0c8c9ac4
--- /dev/null
+++ b/lib/rdoc/generators/template/xml/xml.rb
@@ -0,0 +1,112 @@
+module RDoc
+module Page
+
+
+
+CONTENTS_XML = %{
+IF:description
+ <description>
+%description%
+ </description>
+ENDIF:description
+ <contents>
+IF:requires
+ <required-file-list>
+START:requires
+ <required-file name="%name%"
+IF:aref
+ href="%aref%"
+ENDIF:aref
+ />
+END:requires
+ </required-file-list>
+ENDIF:requires
+IF:attributes
+ <attribute-list>
+START:attributes
+ <attribute name="%name%">
+IF:rw
+ <attribute-rw>%rw%</attribute-rw>
+ENDIF:rw
+ <description>%a_desc%</description>
+ </attribute>
+END:attributes
+ </attribute-list>
+ENDIF:attributes
+IF:includes
+ <included-module-list>
+START:includes
+ <included-module name="%name%"
+IF:aref
+ href="%aref%"
+ENDIF:aref
+ />
+END:includes
+ </included-module-list>
+ENDIF:includes
+IF:method_list
+ <method-list>
+START:method_list
+IF:methods
+START:methods
+ <method name="%name%" type="%type%" category="%category%" id="%aref%">
+ <parameters>%params%</parameters>
+IF:m_desc
+ <description>
+%m_desc%
+ </description>
+ENDIF:m_desc
+IF:sourcecode
+ <source-code-listing>
+%sourcecode%
+ </source-code-listing>
+ENDIF:sourcecode
+ </method>
+END:methods
+ENDIF:methods
+END:method_list
+ </method-list>
+ENDIF:method_list
+ </contents>
+}
+
+########################################################################
+
+ONE_PAGE = %{<?xml version="1.0" encoding="utf-8"?>
+<rdoc>
+<file-list>
+START:files
+ <file name="%short_name%" id="%href%">
+ <file-info>
+ <path>%full_path%</path>
+ <dtm-modified>%dtm_modified%</dtm-modified>
+ </file-info>
+} + CONTENTS_XML + %{
+ </file>
+END:files
+</file-list>
+<class-module-list>
+START:classes
+ <%classmod% name="%full_name%" id="%full_name%">
+ <classmod-info>
+IF:infiles
+ <infiles>
+START:infiles
+ <infile>HREF:full_path_url:full_path:</infile>
+END:infiles
+ </infiles>
+ENDIF:infiles
+IF:parent
+ <superclass>HREF:par_url:parent:</superclass>
+ENDIF:parent
+ </classmod-info>
+} + CONTENTS_XML + %{
+ </%classmod%>
+END:classes
+</class-module-list>
+</rdoc>
+}
+
+
+end
+end
diff --git a/lib/rdoc/generators/xml_generator.rb b/lib/rdoc/generators/xml_generator.rb
new file mode 100644
index 0000000000..8c1a76d62b
--- /dev/null
+++ b/lib/rdoc/generators/xml_generator.rb
@@ -0,0 +1,130 @@
+
+require 'ftools'
+
+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 XMLGenerator < HTMLGenerator
+
+ # Standard generator factory
+ def XMLGenerator.for(options)
+ XMLGenerator.new(options)
+ end
+
+
+ def initialize(*args)
+ super
+ 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
+ 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
+ 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
+
+ end
+
+end