mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Import RDoc r101.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0af4a490b4
commit
fd25f74d64
45 changed files with 6952 additions and 4397 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Fri Jul 18 09:44:30 2008
|
||||||
|
|
||||||
|
* lib/rdoc/*: Import RDoc r101.
|
||||||
|
|
||||||
Thu Jul 17 23:45:55 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
Thu Jul 17 23:45:55 2008 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* test/rdoc/test_rdoc_c_parser.rb (teardown): close tempfile.
|
* test/rdoc/test_rdoc_c_parser.rb (teardown): close tempfile.
|
||||||
|
|
134
lib/rdoc.rb
134
lib/rdoc.rb
|
@ -1,8 +1,8 @@
|
||||||
$DEBUG_RDOC = nil
|
$DEBUG_RDOC = nil
|
||||||
|
|
||||||
##
|
##
|
||||||
# = RDOC - Ruby Documentation System
|
# RDoc - Ruby Documentation System
|
||||||
#
|
#
|
||||||
# This package contains RDoc and RDoc::Markup. RDoc is an application that
|
# This package contains RDoc and RDoc::Markup. RDoc is an application that
|
||||||
# produces documentation for one or more Ruby source files. We work similarly
|
# produces documentation for one or more Ruby source files. We work similarly
|
||||||
# to JavaDoc, parsing the source, and extracting the definition for classes,
|
# to JavaDoc, parsing the source, and extracting the definition for classes,
|
||||||
|
@ -12,12 +12,12 @@ $DEBUG_RDOC = nil
|
||||||
# RDoc::Markup is a library that converts plain text into various output
|
# RDoc::Markup is a library that converts plain text into various output
|
||||||
# formats. The markup library is used to interpret the comment blocks that
|
# formats. The markup library is used to interpret the comment blocks that
|
||||||
# RDoc uses to document methods, classes, and so on.
|
# RDoc uses to document methods, classes, and so on.
|
||||||
#
|
#
|
||||||
# == Roadmap
|
# == Roadmap
|
||||||
#
|
#
|
||||||
# * If you want to use RDoc to create documentation for your Ruby source files,
|
# * If you want to use RDoc to create documentation for your Ruby source files,
|
||||||
# read on.
|
# read on.
|
||||||
# * If you want to include extensions written in C, see RDoc::C_Parser
|
# * If you want to include extensions written in C, see RDoc::Parser::C
|
||||||
# * For information on the various markups available in comment blocks, see
|
# * For information on the various markups available in comment blocks, see
|
||||||
# RDoc::Markup.
|
# RDoc::Markup.
|
||||||
# * If you want to drive RDoc programmatically, see RDoc::RDoc.
|
# * If you want to drive RDoc programmatically, see RDoc::RDoc.
|
||||||
|
@ -25,63 +25,63 @@ $DEBUG_RDOC = nil
|
||||||
# at RDoc::Markup.
|
# at RDoc::Markup.
|
||||||
# * If you want to try writing your own HTML output template, see
|
# * If you want to try writing your own HTML output template, see
|
||||||
# RDoc::Generator::HTML
|
# RDoc::Generator::HTML
|
||||||
#
|
#
|
||||||
# == Summary
|
# == Summary
|
||||||
#
|
#
|
||||||
# Once installed, you can create documentation using the 'rdoc' command
|
# Once installed, you can create documentation using the 'rdoc' command
|
||||||
# (the command is 'rdoc.bat' under Windows)
|
# (the command is 'rdoc.bat' under Windows)
|
||||||
#
|
#
|
||||||
# % rdoc [options] [names...]
|
# % rdoc [options] [names...]
|
||||||
#
|
#
|
||||||
# Type "rdoc --help" for an up-to-date option summary.
|
# Type "rdoc --help" for an up-to-date option summary.
|
||||||
#
|
#
|
||||||
# A typical use might be to generate documentation for a package of Ruby
|
# A typical use might be to generate documentation for a package of Ruby
|
||||||
# source (such as rdoc itself).
|
# source (such as rdoc itself).
|
||||||
#
|
#
|
||||||
# % rdoc
|
# % rdoc
|
||||||
#
|
#
|
||||||
# This command generates documentation for all the Ruby and C source
|
# This command generates documentation for all the Ruby and C source
|
||||||
# files in and below the current directory. These will be stored in a
|
# files in and below the current directory. These will be stored in a
|
||||||
# documentation tree starting in the subdirectory 'doc'.
|
# documentation tree starting in the subdirectory 'doc'.
|
||||||
#
|
#
|
||||||
# You can make this slightly more useful for your readers by having the
|
# You can make this slightly more useful for your readers by having the
|
||||||
# index page contain the documentation for the primary file. In our
|
# index page contain the documentation for the primary file. In our
|
||||||
# case, we could type
|
# case, we could type
|
||||||
#
|
#
|
||||||
# % rdoc --main rdoc.rb
|
# % rdoc --main rdoc.rb
|
||||||
#
|
#
|
||||||
# You'll find information on the various formatting tricks you can use
|
# You'll find information on the various formatting tricks you can use
|
||||||
# in comment blocks in the documentation this generates.
|
# in comment blocks in the documentation this generates.
|
||||||
#
|
#
|
||||||
# RDoc uses file extensions to determine how to process each file. File names
|
# RDoc uses file extensions to determine how to process each file. File names
|
||||||
# ending +.rb+ and <tt>.rbw</tt> are assumed to be Ruby source. Files
|
# ending +.rb+ and <tt>.rbw</tt> are assumed to be Ruby source. Files
|
||||||
# ending +.c+ are parsed as C files. All other files are assumed to
|
# ending +.c+ are parsed as C files. All other files are assumed to
|
||||||
# contain just Markup-style markup (with or without leading '#' comment
|
# contain just Markup-style markup (with or without leading '#' comment
|
||||||
# markers). If directory names are passed to RDoc, they are scanned
|
# markers). If directory names are passed to RDoc, they are scanned
|
||||||
# recursively for C and Ruby source files only.
|
# recursively for C and Ruby source files only.
|
||||||
#
|
#
|
||||||
# = Markup
|
# = Markup
|
||||||
#
|
#
|
||||||
# For information on how to make lists, hyperlinks, etc. with RDoc, see
|
# For information on how to make lists, hyperlinks, etc. with RDoc, see
|
||||||
# RDoc::Markup.
|
# RDoc::Markup.
|
||||||
#
|
#
|
||||||
# Comment blocks can be written fairly naturally, either using '#' on
|
# Comment blocks can be written fairly naturally, either using '#' on
|
||||||
# successive lines of the comment, or by including the comment in
|
# successive lines of the comment, or by including the comment in
|
||||||
# an =begin/=end block. If you use the latter form, the =begin line must be
|
# an =begin/=end block. If you use the latter form, the =begin line must be
|
||||||
# flagged with an RDoc tag:
|
# flagged with an RDoc tag:
|
||||||
#
|
#
|
||||||
# =begin rdoc
|
# =begin rdoc
|
||||||
# Documentation to be processed by RDoc.
|
# Documentation to be processed by RDoc.
|
||||||
#
|
#
|
||||||
# ...
|
# ...
|
||||||
# =end
|
# =end
|
||||||
#
|
#
|
||||||
# RDoc stops processing comments if it finds a comment line containing
|
# RDoc stops processing comments if it finds a comment line containing
|
||||||
# a <tt>--</tt>. This can be used to separate external from internal
|
# a <tt>--</tt>. This can be used to separate external from internal
|
||||||
# comments, or to stop a comment being associated with a method, class, or
|
# comments, or to stop a comment being associated with a method, class, or
|
||||||
# module. Commenting can be turned back on with a line that starts with a
|
# module. Commenting can be turned back on with a line that starts with a
|
||||||
# <tt>++</tt>.
|
# <tt>++</tt>.
|
||||||
#
|
#
|
||||||
# ##
|
# ##
|
||||||
# # Extract the age and calculate the date-of-birth.
|
# # Extract the age and calculate the date-of-birth.
|
||||||
# #--
|
# #--
|
||||||
|
@ -92,40 +92,40 @@ $DEBUG_RDOC = nil
|
||||||
# def get_dob(person)
|
# def get_dob(person)
|
||||||
# # ...
|
# # ...
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# Names of classes, source files, and any method names containing an
|
# Names of classes, source files, and any method names containing an
|
||||||
# underscore or preceded by a hash character are automatically hyperlinked
|
# underscore or preceded by a hash character are automatically hyperlinked
|
||||||
# from comment text to their description.
|
# from comment text to their description.
|
||||||
#
|
#
|
||||||
# Method parameter lists are extracted and displayed with the method
|
# Method parameter lists are extracted and displayed with the method
|
||||||
# description. If a method calls +yield+, then the parameters passed to yield
|
# description. If a method calls +yield+, then the parameters passed to yield
|
||||||
# will also be displayed:
|
# will also be displayed:
|
||||||
#
|
#
|
||||||
# def fred
|
# def fred
|
||||||
# ...
|
# ...
|
||||||
# yield line, address
|
# yield line, address
|
||||||
#
|
#
|
||||||
# This will get documented as:
|
# This will get documented as:
|
||||||
#
|
#
|
||||||
# fred() { |line, address| ... }
|
# fred() { |line, address| ... }
|
||||||
#
|
#
|
||||||
# You can override this using a comment containing ':yields: ...' immediately
|
# You can override this using a comment containing ':yields: ...' immediately
|
||||||
# after the method definition
|
# after the method definition
|
||||||
#
|
#
|
||||||
# def fred # :yields: index, position
|
# def fred # :yields: index, position
|
||||||
# # ...
|
# # ...
|
||||||
#
|
#
|
||||||
# yield line, address
|
# yield line, address
|
||||||
#
|
#
|
||||||
# which will get documented as
|
# which will get documented as
|
||||||
#
|
#
|
||||||
# fred() { |index, position| ... }
|
# fred() { |index, position| ... }
|
||||||
#
|
#
|
||||||
# +:yields:+ is an example of a documentation directive. These appear
|
# +:yields:+ is an example of a documentation directive. These appear
|
||||||
# immediately after the start of the document element they are modifying.
|
# immediately after the start of the document element they are modifying.
|
||||||
#
|
#
|
||||||
# == Directives
|
# == Directives
|
||||||
#
|
#
|
||||||
# [+:nodoc:+ / +:nodoc:+ all]
|
# [+:nodoc:+ / +:nodoc:+ all]
|
||||||
# Don't include this element in the documentation. For classes
|
# Don't include this element in the documentation. For classes
|
||||||
# and modules, the methods, aliases, constants, and attributes
|
# and modules, the methods, aliases, constants, and attributes
|
||||||
|
@ -143,27 +143,27 @@ $DEBUG_RDOC = nil
|
||||||
# class Output
|
# class Output
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# In the above code, only class +MyModule::Input+ will be documented.
|
# In the above code, only class +MyModule::Input+ will be documented.The
|
||||||
# :nodoc: is global across all files the class or module appears in, so use
|
# The :nodoc: directive is global across all files the class or module
|
||||||
# :stopdoc:/:startdoc: to only omit documentation for a particular set of
|
# appears in, so use :stopdoc:/:startdoc: to only omit documentation for a
|
||||||
# methods, etc.
|
# particular set of methods, etc.
|
||||||
#
|
#
|
||||||
# [+:doc:+]
|
# [+:doc:+]
|
||||||
# Force a method or attribute to be documented even if it wouldn't otherwise
|
# Force a method or attribute to be documented even if it wouldn't otherwise
|
||||||
# be. Useful if, for example, you want to include documentation of a
|
# be. Useful if, for example, you want to include documentation of a
|
||||||
# particular private method.
|
# particular private method.
|
||||||
#
|
#
|
||||||
# [+:notnew:+]
|
# [+:notnew:+]
|
||||||
# Only applicable to the +initialize+ instance method. Normally RDoc
|
# Only applicable to the +initialize+ instance method. Normally RDoc
|
||||||
# assumes that the documentation and parameters for #initialize are
|
# assumes that the documentation and parameters for #initialize are
|
||||||
# actually for the ::new method, and so fakes out a ::new for the class.
|
# actually for the ::new method, and so fakes out a ::new for the class.
|
||||||
# The :notnew: modifier stops this. Remember that #initialize is protected,
|
# The :notnew: modifier stops this. Remember that #initialize is protected,
|
||||||
# so you won't see the documentation unless you use the -a command line
|
# so you won't see the documentation unless you use the -a command line
|
||||||
# option.
|
# option.
|
||||||
#
|
#
|
||||||
# Comment blocks can contain other directives:
|
# Comment blocks can contain other directives:
|
||||||
#
|
#
|
||||||
# [<tt>:section: title</tt>]
|
# [<tt>:section: title</tt>]
|
||||||
# Starts a new section in the output. The title following +:section:+ is
|
# Starts a new section in the output. The title following +:section:+ is
|
||||||
# used as the section heading, and the remainder of the comment containing
|
# used as the section heading, and the remainder of the comment containing
|
||||||
|
@ -178,66 +178,66 @@ $DEBUG_RDOC = nil
|
||||||
# # This is the section that I wrote.
|
# # This is the section that I wrote.
|
||||||
# # See it glisten in the noon-day sun.
|
# # See it glisten in the noon-day sun.
|
||||||
# # ----------------------------------------
|
# # ----------------------------------------
|
||||||
#
|
#
|
||||||
# [+:call-seq:+]
|
# [+:call-seq:+]
|
||||||
# Lines up to the next blank line in the comment are treated as the method's
|
# Lines up to the next blank line in the comment are treated as the method's
|
||||||
# calling sequence, overriding the default parsing of method parameters and
|
# calling sequence, overriding the default parsing of method parameters and
|
||||||
# yield arguments.
|
# yield arguments.
|
||||||
#
|
#
|
||||||
# [+:include:+ _filename_]
|
# [+:include:+ _filename_]
|
||||||
# \Include the contents of the named file at this point. The file will be
|
# \Include the contents of the named file at this point. The file will be
|
||||||
# searched for in the directories listed by the +--include+ option, or in
|
# searched for in the directories listed by the +--include+ option, or in
|
||||||
# the current directory by default. The contents of the file will be
|
# the current directory by default. The contents of the file will be
|
||||||
# shifted to have the same indentation as the ':' at the start of the
|
# shifted to have the same indentation as the ':' at the start of
|
||||||
# :include: directive.
|
# the :include: directive.
|
||||||
#
|
#
|
||||||
# [+:title:+ _text_]
|
# [+:title:+ _text_]
|
||||||
# Sets the title for the document. Equivalent to the <tt>--title</tt>
|
# Sets the title for the document. Equivalent to the <tt>--title</tt>
|
||||||
# command line parameter. (The command line parameter overrides any :title:
|
# command line parameter. (The command line parameter overrides any :title:
|
||||||
# directive in the source).
|
# directive in the source).
|
||||||
#
|
#
|
||||||
# [+:enddoc:+]
|
# [+:enddoc:+]
|
||||||
# Document nothing further at the current level.
|
# Document nothing further at the current level.
|
||||||
#
|
#
|
||||||
# [+:main:+ _name_]
|
# [+:main:+ _name_]
|
||||||
# Equivalent to the <tt>--main</tt> command line parameter.
|
# Equivalent to the <tt>--main</tt> command line parameter.
|
||||||
#
|
#
|
||||||
# [+:stopdoc:+ / +:startdoc:+]
|
# [+:stopdoc:+ / +:startdoc:+]
|
||||||
# Stop and start adding new documentation elements to the current container.
|
# Stop and start adding new documentation elements to the current container.
|
||||||
# For example, if a class has a number of constants that you don't want to
|
# For example, if a class has a number of constants that you don't want to
|
||||||
# document, put a +:stopdoc:+ before the first, and a +:startdoc:+ after the
|
# document, put a +:stopdoc:+ before the first, and a +:startdoc:+ after the
|
||||||
# last. If you don't specify a +:startdoc:+ by the end of the container,
|
# last. If you don't specify a +:startdoc:+ by the end of the container,
|
||||||
# disables documentation for the entire class or module.
|
# disables documentation for the entire class or module.
|
||||||
#
|
#
|
||||||
# = Other stuff
|
# = Other stuff
|
||||||
#
|
#
|
||||||
# RDoc is currently being maintained by Eric Hodel <drbrain@segment7.net>
|
# RDoc is currently being maintained by Eric Hodel <drbrain@segment7.net>
|
||||||
#
|
#
|
||||||
# Dave Thomas <dave@pragmaticprogrammer.com> is the original author of RDoc.
|
# Dave Thomas <dave@pragmaticprogrammer.com> is the original author of RDoc.
|
||||||
#
|
#
|
||||||
# == Credits
|
# == Credits
|
||||||
#
|
#
|
||||||
# * The Ruby parser in rdoc/parse.rb is based heavily on the outstanding
|
# * The Ruby parser in rdoc/parse.rb is based heavily on the outstanding
|
||||||
# work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby
|
# work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby
|
||||||
# parser for irb and the rtags package.
|
# parser for irb and the rtags package.
|
||||||
#
|
#
|
||||||
# * Code to diagram classes and modules was written by Sergey A Yanovitsky
|
# * Code to diagram classes and modules was written by Sergey A Yanovitsky
|
||||||
# (Jah) of Enticla.
|
# (Jah) of Enticla.
|
||||||
#
|
#
|
||||||
# * Charset patch from MoonWolf.
|
# * Charset patch from MoonWolf.
|
||||||
#
|
#
|
||||||
# * Rich Kilmer wrote the kilmer.rb output template.
|
# * Rich Kilmer wrote the kilmer.rb output template.
|
||||||
#
|
#
|
||||||
# * Dan Brickley led the design of the RDF format.
|
# * Dan Brickley led the design of the RDF format.
|
||||||
#
|
#
|
||||||
# == License
|
# == License
|
||||||
#
|
#
|
||||||
# RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers. It
|
# RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers. It
|
||||||
# is free software, and may be redistributed under the terms specified
|
# is free software, and may be redistributed under the terms specified
|
||||||
# in the README file of the Ruby distribution.
|
# in the README file of the Ruby distribution.
|
||||||
#
|
#
|
||||||
# == Warranty
|
# == Warranty
|
||||||
#
|
#
|
||||||
# This software is provided "as is" and without any express or implied
|
# This software is provided "as is" and without any express or implied
|
||||||
# warranties, including, without limitation, the implied warranties of
|
# warranties, including, without limitation, the implied warranties of
|
||||||
# merchantibility and fitness for a particular purpose.
|
# merchantibility and fitness for a particular purpose.
|
||||||
|
@ -254,7 +254,7 @@ module RDoc
|
||||||
##
|
##
|
||||||
# RDoc version you are using
|
# RDoc version you are using
|
||||||
|
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.0"
|
||||||
|
|
||||||
##
|
##
|
||||||
# Name of the dotfile that contains the description of files to be processed
|
# Name of the dotfile that contains the description of files to be processed
|
||||||
|
|
|
@ -6,8 +6,8 @@ require 'rdoc/tokenstream'
|
||||||
module RDoc
|
module RDoc
|
||||||
|
|
||||||
##
|
##
|
||||||
# We contain the common stuff for contexts (which are containers)
|
# We contain the common stuff for contexts (which are containers) and other
|
||||||
# and other elements (methods, attributes and so on)
|
# elements (methods, attributes and so on)
|
||||||
|
|
||||||
class CodeObject
|
class CodeObject
|
||||||
|
|
||||||
|
@ -31,6 +31,13 @@ module RDoc
|
||||||
|
|
||||||
attr_reader :document_self
|
attr_reader :document_self
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@document_self = true
|
||||||
|
@document_children = true
|
||||||
|
@force_documentation = false
|
||||||
|
@done_documenting = false
|
||||||
|
end
|
||||||
|
|
||||||
def document_self=(val)
|
def document_self=(val)
|
||||||
@document_self = val
|
@document_self = val
|
||||||
if !val
|
if !val
|
||||||
|
@ -72,13 +79,6 @@ module RDoc
|
||||||
def remove_methods_etc
|
def remove_methods_etc
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize
|
|
||||||
@document_self = true
|
|
||||||
@document_children = true
|
|
||||||
@force_documentation = false
|
|
||||||
@done_documenting = false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Access the code object's comment
|
# Access the code object's comment
|
||||||
attr_reader :comment
|
attr_reader :comment
|
||||||
|
|
||||||
|
@ -106,15 +106,24 @@ module RDoc
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A Context is something that can hold modules, classes, methods,
|
##
|
||||||
# attributes, aliases, requires, and includes. Classes, modules, and
|
# A Context is something that can hold modules, classes, methods,
|
||||||
# files are all Contexts.
|
# attributes, aliases, requires, and includes. Classes, modules, and files
|
||||||
|
# are all Contexts.
|
||||||
|
|
||||||
class Context < CodeObject
|
class Context < CodeObject
|
||||||
attr_reader :name, :method_list, :attributes, :aliases, :constants
|
|
||||||
attr_reader :requires, :includes, :in_files, :visibility
|
|
||||||
|
|
||||||
attr_reader :sections
|
attr_reader :aliases
|
||||||
|
attr_reader :attributes
|
||||||
|
attr_reader :constants
|
||||||
|
attr_reader :current_section
|
||||||
|
attr_reader :in_files
|
||||||
|
attr_reader :includes
|
||||||
|
attr_reader :method_list
|
||||||
|
attr_reader :name
|
||||||
|
attr_reader :requires
|
||||||
|
attr_reader :sections
|
||||||
|
attr_reader :visibility
|
||||||
|
|
||||||
class Section
|
class Section
|
||||||
attr_reader :title, :comment, :sequence
|
attr_reader :title, :comment, :sequence
|
||||||
|
@ -129,12 +138,22 @@ module RDoc
|
||||||
set_comment(comment)
|
set_comment(comment)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def ==(other)
|
||||||
|
self.class === other and @sequence == other.sequence
|
||||||
|
end
|
||||||
|
|
||||||
# Set the comment for this section from the original comment block
|
def inspect
|
||||||
# If the first line contains :section:, strip it and use the rest. Otherwise
|
"#<%s:0x%x %s %p>" % [
|
||||||
# remove lines up to the line containing :section:, and look for
|
self.class, object_id,
|
||||||
# those lines again at the end and remove them. This lets us write
|
@sequence, title
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Set the comment for this section from the original comment block If
|
||||||
|
# the first line contains :section:, strip it and use the rest.
|
||||||
|
# Otherwise remove lines up to the line containing :section:, and look
|
||||||
|
# for those lines again at the end and remove them. This lets us write
|
||||||
#
|
#
|
||||||
# # ---------------------
|
# # ---------------------
|
||||||
# # :SECTION: The title
|
# # :SECTION: The title
|
||||||
|
@ -144,9 +163,10 @@ module RDoc
|
||||||
def set_comment(comment)
|
def set_comment(comment)
|
||||||
return unless comment
|
return unless comment
|
||||||
|
|
||||||
if comment =~ /^.*?:section:.*$/
|
if comment =~ /^#[ \t]*:section:.*\n/
|
||||||
start = $`
|
start = $`
|
||||||
rest = $'
|
rest = $'
|
||||||
|
|
||||||
if start.empty?
|
if start.empty?
|
||||||
@comment = rest
|
@comment = rest
|
||||||
else
|
else
|
||||||
|
@ -157,13 +177,13 @@ module RDoc
|
||||||
end
|
end
|
||||||
@comment = nil if @comment.empty?
|
@comment = nil if @comment.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super()
|
super
|
||||||
|
|
||||||
@in_files = []
|
@in_files = []
|
||||||
|
|
||||||
@name ||= "unknown"
|
@name ||= "unknown"
|
||||||
@comment ||= ""
|
@comment ||= ""
|
||||||
|
@ -177,29 +197,37 @@ module RDoc
|
||||||
initialize_classes_and_modules
|
initialize_classes_and_modules
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# map the class hash to an array externally
|
# map the class hash to an array externally
|
||||||
|
|
||||||
def classes
|
def classes
|
||||||
@classes.values
|
@classes.values
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# map the module hash to an array externally
|
# map the module hash to an array externally
|
||||||
|
|
||||||
def modules
|
def modules
|
||||||
@modules.values
|
@modules.values
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Change the default visibility for new methods
|
# Change the default visibility for new methods
|
||||||
|
|
||||||
def ongoing_visibility=(vis)
|
def ongoing_visibility=(vis)
|
||||||
@visibility = vis
|
@visibility = vis
|
||||||
end
|
end
|
||||||
|
|
||||||
# Given an array +methods+ of method names, set the
|
##
|
||||||
# visibility of the corresponding AnyMethod object
|
# Yields Method and Attr entries matching the list of names in +methods+.
|
||||||
|
# Attributes are only returned when +singleton+ is false.
|
||||||
|
|
||||||
def set_visibility_for(methods, vis, singleton=false)
|
def methods_matching(methods, singleton = false)
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
@method_list.each do |m|
|
@method_list.each do |m|
|
||||||
if methods.include?(m.name) && m.singleton == singleton
|
if methods.include? m.name and m.singleton == singleton then
|
||||||
m.visibility = vis
|
yield m
|
||||||
count += 1
|
count += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -209,14 +237,23 @@ module RDoc
|
||||||
# perhaps we need to look at attributes
|
# perhaps we need to look at attributes
|
||||||
|
|
||||||
@attributes.each do |a|
|
@attributes.each do |a|
|
||||||
if methods.include?(a.name)
|
yield a if methods.include? a.name
|
||||||
a.visibility = vis
|
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Given an array +methods+ of method names, set the visibility of the
|
||||||
|
# corresponding AnyMethod object
|
||||||
|
|
||||||
|
def set_visibility_for(methods, vis, singleton = false)
|
||||||
|
methods_matching methods, singleton do |m|
|
||||||
|
m.visibility = vis
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Record the file that we happen to find it in
|
# Record the file that we happen to find it in
|
||||||
|
|
||||||
def record_location(toplevel)
|
def record_location(toplevel)
|
||||||
@in_files << toplevel unless @in_files.include?(toplevel)
|
@in_files << toplevel unless @in_files.include?(toplevel)
|
||||||
end
|
end
|
||||||
|
@ -269,10 +306,10 @@ module RDoc
|
||||||
|
|
||||||
# Requires always get added to the top-level (file) context
|
# Requires always get added to the top-level (file) context
|
||||||
def add_require(a_require)
|
def add_require(a_require)
|
||||||
if self.kind_of? TopLevel
|
if TopLevel === self then
|
||||||
add_to(@requires, a_require)
|
add_to @requires, a_require
|
||||||
else
|
else
|
||||||
parent.add_require(a_require)
|
parent.add_require a_require
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -292,7 +329,7 @@ module RDoc
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_to(array, thing)
|
def add_to(array, thing)
|
||||||
array << thing if @document_self && !@done_documenting
|
array << thing if @document_self and not @done_documenting
|
||||||
thing.parent = self
|
thing.parent = self
|
||||||
thing.section = @current_section
|
thing.section = @current_section
|
||||||
end
|
end
|
||||||
|
@ -371,26 +408,30 @@ module RDoc
|
||||||
name <=> other.name
|
name <=> other.name
|
||||||
end
|
end
|
||||||
|
|
||||||
# Look up the given symbol. If method is non-nil, then
|
##
|
||||||
# we assume the symbol references a module that
|
# Look up +symbol+. If +method+ is non-nil, then we assume the symbol
|
||||||
# contains that method
|
# references a module that contains that method.
|
||||||
def find_symbol(symbol, method=nil)
|
|
||||||
|
def find_symbol(symbol, method = nil)
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
case symbol
|
case symbol
|
||||||
when /^::(.*)/
|
when /^::(.*)/ then
|
||||||
result = toplevel.find_symbol($1)
|
result = toplevel.find_symbol($1)
|
||||||
when /::/
|
when /::/ then
|
||||||
modules = symbol.split(/::/)
|
modules = symbol.split(/::/)
|
||||||
unless modules.empty?
|
|
||||||
|
unless modules.empty? then
|
||||||
module_name = modules.shift
|
module_name = modules.shift
|
||||||
result = find_module_named(module_name)
|
result = find_module_named(module_name)
|
||||||
if result
|
if result then
|
||||||
modules.each do |name|
|
modules.each do |name|
|
||||||
result = result.find_module_named(name)
|
result = result.find_module_named(name)
|
||||||
break unless result
|
break unless result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
# if a method is specified, then we're definitely looking for
|
# if a method is specified, then we're definitely looking for
|
||||||
# a module, otherwise it could be any symbol
|
# a module, otherwise it could be any symbol
|
||||||
|
@ -408,22 +449,21 @@ module RDoc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if result && method
|
|
||||||
if !result.respond_to?(:find_local_symbol)
|
if result and method then
|
||||||
#p result.name
|
fail unless result.respond_to? :find_local_symbol
|
||||||
#p method
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
result = result.find_local_symbol(method)
|
result = result.find_local_symbol(method)
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_local_symbol(symbol)
|
def find_local_symbol(symbol)
|
||||||
res = find_method_named(symbol) ||
|
res = find_method_named(symbol) ||
|
||||||
find_constant_named(symbol) ||
|
find_constant_named(symbol) ||
|
||||||
find_attribute_named(symbol) ||
|
find_attribute_named(symbol) ||
|
||||||
find_module_named(symbol)
|
find_module_named(symbol) ||
|
||||||
|
find_file_named(symbol)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Handle sections
|
# Handle sections
|
||||||
|
@ -454,7 +494,14 @@ module RDoc
|
||||||
def find_attribute_named(name)
|
def find_attribute_named(name)
|
||||||
@attributes.find {|m| m.name == name}
|
@attributes.find {|m| m.name == name}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Find a named file, or return nil
|
||||||
|
|
||||||
|
def find_file_named(name)
|
||||||
|
toplevel.class.find_file_named(name)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -465,22 +512,29 @@ module RDoc
|
||||||
attr_accessor :file_relative_name
|
attr_accessor :file_relative_name
|
||||||
attr_accessor :file_absolute_name
|
attr_accessor :file_absolute_name
|
||||||
attr_accessor :diagram
|
attr_accessor :diagram
|
||||||
|
|
||||||
@@all_classes = {}
|
@@all_classes = {}
|
||||||
@@all_modules = {}
|
@@all_modules = {}
|
||||||
|
@@all_files = {}
|
||||||
|
|
||||||
def self.reset
|
def self.reset
|
||||||
@@all_classes = {}
|
@@all_classes = {}
|
||||||
@@all_modules = {}
|
@@all_modules = {}
|
||||||
|
@@all_files = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(file_name)
|
def initialize(file_name)
|
||||||
super()
|
super()
|
||||||
@name = "TopLevel"
|
@name = "TopLevel"
|
||||||
@file_relative_name = file_name
|
@file_relative_name = file_name
|
||||||
@file_absolute_name = file_name
|
@file_absolute_name = file_name
|
||||||
@file_stat = File.stat(file_name)
|
@file_stat = File.stat(file_name)
|
||||||
@diagram = nil
|
@diagram = nil
|
||||||
|
@@all_files[file_name] = self
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_base_name
|
||||||
|
File.basename @file_absolute_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def full_name
|
def full_name
|
||||||
|
@ -497,7 +551,7 @@ module RDoc
|
||||||
cls = collection[name]
|
cls = collection[name]
|
||||||
|
|
||||||
if cls
|
if cls
|
||||||
puts "Reusing class/module #{name}" if $DEBUG_RDOC
|
puts "Reusing class/module #{name}" #if $DEBUG_RDOC
|
||||||
else
|
else
|
||||||
if class_type == NormalModule
|
if class_type == NormalModule
|
||||||
all = @@all_modules
|
all = @@all_modules
|
||||||
|
@ -534,6 +588,10 @@ module RDoc
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.find_file_named(name)
|
||||||
|
@@all_files[name]
|
||||||
|
end
|
||||||
|
|
||||||
def find_local_symbol(symbol)
|
def find_local_symbol(symbol)
|
||||||
find_class_or_module_named(symbol) || super
|
find_class_or_module_named(symbol) || super
|
||||||
end
|
end
|
||||||
|
@ -553,8 +611,9 @@ module RDoc
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# ClassModule is the base class for objects representing either a
|
##
|
||||||
# class or a module.
|
# ClassModule is the base class for objects representing either a class or a
|
||||||
|
# module.
|
||||||
|
|
||||||
class ClassModule < Context
|
class ClassModule < Context
|
||||||
|
|
||||||
|
@ -603,29 +662,63 @@ module RDoc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Anonymous classes
|
# Anonymous classes
|
||||||
|
|
||||||
class AnonClass < ClassModule
|
class AnonClass < ClassModule
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Normal classes
|
# Normal classes
|
||||||
|
|
||||||
class NormalClass < ClassModule
|
class NormalClass < ClassModule
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
superclass = @superclass ? " < #{@superclass}" : nil
|
||||||
|
"<%s:0x%x class %s%s includes: %p attributes: %p methods: %p aliases: %p>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
@name, superclass, @includes, @attributes, @method_list, @aliases
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Singleton classes
|
# Singleton classes
|
||||||
|
|
||||||
class SingleClass < ClassModule
|
class SingleClass < ClassModule
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Module
|
# Module
|
||||||
|
|
||||||
class NormalModule < ClassModule
|
class NormalModule < ClassModule
|
||||||
|
|
||||||
|
def comment=(comment)
|
||||||
|
return if comment.empty?
|
||||||
|
comment = @comment << "# ---\n" << comment unless @comment.empty?
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<%s:0x%x module %s includes: %p attributes: %p methods: %p aliases: %p>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
@name, @includes, @attributes, @method_list, @aliases
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
def is_module?
|
def is_module?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# AnyMethod is the base class for objects representing methods
|
# AnyMethod is the base class for objects representing methods
|
||||||
|
|
||||||
class AnyMethod < CodeObject
|
class AnyMethod < CodeObject
|
||||||
|
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
attr_accessor :visibility
|
attr_accessor :visibility
|
||||||
attr_accessor :block_params
|
attr_accessor :block_params
|
||||||
|
@ -663,10 +756,20 @@ module RDoc
|
||||||
@name <=> other.name
|
@name <=> other.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def add_alias(method)
|
||||||
res = self.class.name + ": " + @name + " (" + @text + ")\n"
|
@aliases << method
|
||||||
res << @comment.to_s
|
end
|
||||||
res
|
|
||||||
|
def inspect
|
||||||
|
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
|
||||||
|
"#<%s:0x%x %s%s%s (%s)%s>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
@parent.name,
|
||||||
|
singleton ? '::' : '#',
|
||||||
|
name,
|
||||||
|
visibility,
|
||||||
|
alias_for,
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
def param_seq
|
def param_seq
|
||||||
|
@ -691,16 +794,34 @@ $stderr.puts p
|
||||||
p
|
p
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_alias(method)
|
def to_s
|
||||||
@aliases << method
|
res = self.class.name + ": " + @name + " (" + @text + ")\n"
|
||||||
|
res << @comment.to_s
|
||||||
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Represent an alias, which is an old_name/ new_name pair associated
|
##
|
||||||
# with a particular context
|
# GhostMethod represents a method referenced only by a comment
|
||||||
|
|
||||||
|
class GhostMethod < AnyMethod
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# MetaMethod represents a meta-programmed method
|
||||||
|
|
||||||
|
class MetaMethod < AnyMethod
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Represent an alias, which is an old_name/ new_name pair associated with a
|
||||||
|
# particular context
|
||||||
|
|
||||||
class Alias < CodeObject
|
class Alias < CodeObject
|
||||||
|
|
||||||
attr_accessor :text, :old_name, :new_name, :comment
|
attr_accessor :text, :old_name, :new_name, :comment
|
||||||
|
|
||||||
def initialize(text, old_name, new_name, comment)
|
def initialize(text, old_name, new_name, comment)
|
||||||
super()
|
super()
|
||||||
@text = text
|
@text = text
|
||||||
|
@ -709,12 +830,22 @@ $stderr.puts p
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<%s:0x%x %s.alias_method %s, %s>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
parent.name, @old_name, @new_name,
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"alias: #{self.old_name} -> #{self.new_name}\n#{self.comment}"
|
"alias: #{self.old_name} -> #{self.new_name}\n#{self.comment}"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Represent a constant
|
# Represent a constant
|
||||||
|
|
||||||
class Constant < CodeObject
|
class Constant < CodeObject
|
||||||
attr_accessor :name, :value
|
attr_accessor :name, :value
|
||||||
|
|
||||||
|
@ -726,7 +857,9 @@ $stderr.puts p
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
# Represent attributes
|
# Represent attributes
|
||||||
|
|
||||||
class Attr < CodeObject
|
class Attr < CodeObject
|
||||||
attr_accessor :text, :name, :rw, :visibility
|
attr_accessor :text, :name, :rw, :visibility
|
||||||
|
|
||||||
|
@ -739,16 +872,33 @@ $stderr.puts p
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def <=>(other)
|
||||||
|
self.name <=> other.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
attr = case rw
|
||||||
|
when 'RW' then :attr_accessor
|
||||||
|
when 'R' then :attr_reader
|
||||||
|
when 'W' then :attr_writer
|
||||||
|
else
|
||||||
|
" (#{rw})"
|
||||||
|
end
|
||||||
|
|
||||||
|
"#<%s:0x%x %s.%s :%s>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
@parent.name, attr, @name,
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"attr: #{self.name} #{self.rw}\n#{self.comment}"
|
"attr: #{self.name} #{self.rw}\n#{self.comment}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def <=>(other)
|
|
||||||
self.name <=> other.name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# a required file
|
##
|
||||||
|
# A required file
|
||||||
|
|
||||||
class Require < CodeObject
|
class Require < CodeObject
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
@ -759,16 +909,38 @@ $stderr.puts p
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<%s:0x%x require '%s' in %s>" % [
|
||||||
|
self.class,
|
||||||
|
object_id,
|
||||||
|
@name,
|
||||||
|
@parent.file_base_name,
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# an included module
|
##
|
||||||
|
# An included module
|
||||||
|
|
||||||
class Include < CodeObject
|
class Include < CodeObject
|
||||||
|
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
|
||||||
def initialize(name, comment)
|
def initialize(name, comment)
|
||||||
super()
|
super()
|
||||||
@name = name
|
@name = name
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"#<%s:0x%x %s.include %s>" % [
|
||||||
|
self.class,
|
||||||
|
object_id,
|
||||||
|
@parent.name,
|
||||||
|
@name,
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,27 +21,6 @@ module RDoc::Generator
|
||||||
|
|
||||||
CSS_NAME = "rdoc-style.css"
|
CSS_NAME = "rdoc-style.css"
|
||||||
|
|
||||||
##
|
|
||||||
# Converts a target url to one that is relative to a given path
|
|
||||||
|
|
||||||
def self.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] do
|
|
||||||
from.shift
|
|
||||||
to.shift
|
|
||||||
end
|
|
||||||
|
|
||||||
from.fill ".."
|
|
||||||
from.concat to
|
|
||||||
from << to_file
|
|
||||||
::File.join(*from)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Build a hash of all items that can be cross-referenced. This is used when
|
# 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 output required and included names: if the names appear in this hash,
|
||||||
|
@ -80,11 +59,6 @@ module RDoc::Generator
|
||||||
def markup(str, remove_para = false)
|
def markup(str, remove_para = false)
|
||||||
return '' unless str
|
return '' unless str
|
||||||
|
|
||||||
unless defined? @formatter then
|
|
||||||
@formatter = RDoc::Markup::ToHtmlCrossref.new(path, self,
|
|
||||||
@options.show_hash)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Convert leading comment markers to spaces, but only if all non-blank
|
# Convert leading comment markers to spaces, but only if all non-blank
|
||||||
# lines have them
|
# lines have them
|
||||||
if str =~ /^(?>\s*)[^\#]/ then
|
if str =~ /^(?>\s*)[^\#]/ then
|
||||||
|
@ -93,7 +67,7 @@ module RDoc::Generator
|
||||||
content = str.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }
|
content = str.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }
|
||||||
end
|
end
|
||||||
|
|
||||||
res = @formatter.convert content
|
res = formatter.convert content
|
||||||
|
|
||||||
if remove_para then
|
if remove_para then
|
||||||
res.sub!(/^<p>/, '')
|
res.sub!(/^<p>/, '')
|
||||||
|
@ -114,7 +88,7 @@ module RDoc::Generator
|
||||||
if %r{^(https?:/)?/} =~ css_name
|
if %r{^(https?:/)?/} =~ css_name
|
||||||
css_name
|
css_name
|
||||||
else
|
else
|
||||||
RDoc::Generator.gen_url path, css_name
|
RDoc::Markup::ToHtml.gen_relative_url path, css_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -186,6 +160,11 @@ module RDoc::Generator
|
||||||
@template = options.template_class
|
@template = options.template_class
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def formatter
|
||||||
|
@formatter ||= @options.formatter ||
|
||||||
|
RDoc::Markup::ToHtmlCrossref.new(path, self, @options.show_hash)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# convenience method to build a hyperlink
|
# convenience method to build a hyperlink
|
||||||
|
|
||||||
|
@ -201,7 +180,7 @@ module RDoc::Generator
|
||||||
if @options.all_one_file
|
if @options.all_one_file
|
||||||
"#" + path
|
"#" + path
|
||||||
else
|
else
|
||||||
RDoc::Generator.gen_url from_path, path
|
RDoc::Markup::ToHtml.gen_relative_url from_path, path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -215,7 +194,7 @@ module RDoc::Generator
|
||||||
list = @context.method_list
|
list = @context.method_list
|
||||||
|
|
||||||
unless @options.show_all then
|
unless @options.show_all then
|
||||||
list = list.find_all do |m|
|
list = list.select do |m|
|
||||||
m.visibility == :public or
|
m.visibility == :public or
|
||||||
m.visibility == :protected or
|
m.visibility == :protected or
|
||||||
m.force_documentation
|
m.force_documentation
|
||||||
|
@ -230,17 +209,15 @@ module RDoc::Generator
|
||||||
##
|
##
|
||||||
# Build a summary list of all the methods in this context
|
# Build a summary list of all the methods in this context
|
||||||
|
|
||||||
def build_method_summary_list(path_prefix="")
|
def build_method_summary_list(path_prefix = "")
|
||||||
collect_methods unless @methods
|
collect_methods unless @methods
|
||||||
meths = @methods.sort
|
|
||||||
res = []
|
@methods.sort.map do |meth|
|
||||||
meths.each do |meth|
|
{
|
||||||
res << {
|
|
||||||
"name" => CGI.escapeHTML(meth.name),
|
"name" => CGI.escapeHTML(meth.name),
|
||||||
"aref" => "#{path_prefix}\##{meth.aref}"
|
"aref" => "#{path_prefix}\##{meth.aref}"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
res
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -248,36 +225,40 @@ module RDoc::Generator
|
||||||
# corresponding method
|
# corresponding method
|
||||||
|
|
||||||
def build_alias_summary_list(section)
|
def build_alias_summary_list(section)
|
||||||
values = []
|
@context.aliases.map do |al|
|
||||||
@context.aliases.each do |al|
|
|
||||||
next unless al.section == section
|
next unless al.section == section
|
||||||
|
|
||||||
res = {
|
res = {
|
||||||
'old_name' => al.old_name,
|
'old_name' => al.old_name,
|
||||||
'new_name' => al.new_name,
|
'new_name' => al.new_name,
|
||||||
}
|
}
|
||||||
if al.comment && !al.comment.empty?
|
|
||||||
res['desc'] = markup(al.comment, true)
|
if al.comment and not al.comment.empty? then
|
||||||
|
res['desc'] = markup al.comment, true
|
||||||
end
|
end
|
||||||
values << res
|
|
||||||
end
|
res
|
||||||
values
|
end.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Build a list of constants
|
# Build a list of constants
|
||||||
|
|
||||||
def build_constants_summary_list(section)
|
def build_constants_summary_list(section)
|
||||||
values = []
|
@context.constants.map do |co|
|
||||||
@context.constants.each do |co|
|
|
||||||
next unless co.section == section
|
next unless co.section == section
|
||||||
|
|
||||||
res = {
|
res = {
|
||||||
'name' => co.name,
|
'name' => co.name,
|
||||||
'value' => CGI.escapeHTML(co.value)
|
'value' => CGI.escapeHTML(co.value)
|
||||||
}
|
}
|
||||||
res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty?
|
|
||||||
values << res
|
if co.comment and not co.comment.empty? then
|
||||||
end
|
res['desc'] = markup co.comment, true
|
||||||
values
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_requires_list(context)
|
def build_requires_list(context)
|
||||||
|
@ -339,54 +320,58 @@ module RDoc::Generator
|
||||||
def build_method_detail_list(section)
|
def build_method_detail_list(section)
|
||||||
outer = []
|
outer = []
|
||||||
|
|
||||||
methods = @methods.sort
|
methods = @methods.sort.select do |m|
|
||||||
|
m.document_self and m.section == section
|
||||||
|
end
|
||||||
|
|
||||||
for singleton in [true, false]
|
for singleton in [true, false]
|
||||||
for vis in [ :public, :protected, :private ]
|
for vis in [ :public, :protected, :private ]
|
||||||
res = []
|
res = []
|
||||||
methods.each do |m|
|
methods.each do |m|
|
||||||
if m.section == section and
|
next unless m.visibility == vis and m.singleton == singleton
|
||||||
m.document_self and
|
|
||||||
m.visibility == vis and
|
|
||||||
m.singleton == singleton
|
|
||||||
row = {}
|
|
||||||
if m.call_seq
|
|
||||||
row["callseq"] = m.call_seq.gsub(/->/, '→')
|
|
||||||
else
|
|
||||||
row["name"] = CGI.escapeHTML(m.name)
|
|
||||||
row["params"] = m.params
|
|
||||||
end
|
|
||||||
desc = m.description.strip
|
|
||||||
row["m_desc"] = desc unless desc.empty?
|
|
||||||
row["aref"] = m.aref
|
|
||||||
row["visibility"] = m.visibility.to_s
|
|
||||||
|
|
||||||
alias_names = []
|
row = {}
|
||||||
m.aliases.each do |other|
|
|
||||||
if other.viewer # won't be if the alias is private
|
|
||||||
alias_names << {
|
|
||||||
'name' => other.name,
|
|
||||||
'aref' => other.viewer.as_href(path)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
unless alias_names.empty?
|
|
||||||
row["aka"] = alias_names
|
|
||||||
end
|
|
||||||
|
|
||||||
if @options.inline_source
|
if m.call_seq then
|
||||||
code = m.source_code
|
row["callseq"] = m.call_seq.gsub(/->/, '→')
|
||||||
row["sourcecode"] = code if code
|
else
|
||||||
else
|
row["name"] = CGI.escapeHTML(m.name)
|
||||||
code = m.src_url
|
row["params"] = m.params
|
||||||
if code
|
|
||||||
row["codeurl"] = code
|
|
||||||
row["imgurl"] = m.img_url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
res << row
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc = m.description.strip
|
||||||
|
row["m_desc"] = desc unless desc.empty?
|
||||||
|
row["aref"] = m.aref
|
||||||
|
row["visibility"] = m.visibility.to_s
|
||||||
|
|
||||||
|
alias_names = []
|
||||||
|
|
||||||
|
m.aliases.each do |other|
|
||||||
|
if other.viewer then # won't be if the alias is private
|
||||||
|
alias_names << {
|
||||||
|
'name' => other.name,
|
||||||
|
'aref' => other.viewer.as_href(path)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
row["aka"] = alias_names unless alias_names.empty?
|
||||||
|
|
||||||
|
if @options.inline_source then
|
||||||
|
code = m.source_code
|
||||||
|
row["sourcecode"] = code if code
|
||||||
|
else
|
||||||
|
code = m.src_url
|
||||||
|
if code then
|
||||||
|
row["codeurl"] = code
|
||||||
|
row["imgurl"] = m.img_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
res << row
|
||||||
end
|
end
|
||||||
if res.size > 0
|
|
||||||
|
if res.size > 0 then
|
||||||
outer << {
|
outer << {
|
||||||
"type" => vis.to_s.capitalize,
|
"type" => vis.to_s.capitalize,
|
||||||
"category" => singleton ? "Class" : "Instance",
|
"category" => singleton ? "Class" : "Instance",
|
||||||
|
@ -395,6 +380,7 @@ module RDoc::Generator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
outer
|
outer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -403,8 +389,8 @@ module RDoc::Generator
|
||||||
# in this context.
|
# in this context.
|
||||||
|
|
||||||
def build_class_list(level, from, section, infile=nil)
|
def build_class_list(level, from, section, infile=nil)
|
||||||
res = ""
|
prefix = ' ::' * level;
|
||||||
prefix = " ::" * level;
|
res = ''
|
||||||
|
|
||||||
from.modules.sort.each do |mod|
|
from.modules.sort.each do |mod|
|
||||||
next unless mod.section == section
|
next unless mod.section == section
|
||||||
|
@ -412,8 +398,8 @@ module RDoc::Generator
|
||||||
if mod.document_self
|
if mod.document_self
|
||||||
res <<
|
res <<
|
||||||
prefix <<
|
prefix <<
|
||||||
"Module " <<
|
'Module ' <<
|
||||||
href(url(mod.viewer.path), "link", mod.full_name) <<
|
href(url(mod.viewer.path), 'link', mod.full_name) <<
|
||||||
"<br />\n" <<
|
"<br />\n" <<
|
||||||
build_class_list(level + 1, mod, section, infile)
|
build_class_list(level + 1, mod, section, infile)
|
||||||
end
|
end
|
||||||
|
@ -421,12 +407,13 @@ module RDoc::Generator
|
||||||
|
|
||||||
from.classes.sort.each do |cls|
|
from.classes.sort.each do |cls|
|
||||||
next unless cls.section == section
|
next unless cls.section == section
|
||||||
next if infile && !cls.defined_in?(infile)
|
next if infile and not cls.defined_in?(infile)
|
||||||
|
|
||||||
if cls.document_self
|
if cls.document_self
|
||||||
res <<
|
res <<
|
||||||
prefix <<
|
prefix <<
|
||||||
"Class " <<
|
'Class ' <<
|
||||||
href(url(cls.viewer.path), "link", cls.full_name) <<
|
href(url(cls.viewer.path), 'link', cls.full_name) <<
|
||||||
"<br />\n" <<
|
"<br />\n" <<
|
||||||
build_class_list(level + 1, cls, section, infile)
|
build_class_list(level + 1, cls, section, infile)
|
||||||
end
|
end
|
||||||
|
@ -436,7 +423,7 @@ module RDoc::Generator
|
||||||
end
|
end
|
||||||
|
|
||||||
def url(target)
|
def url(target)
|
||||||
RDoc::Generator.gen_url path, target
|
RDoc::Markup::ToHtml.gen_relative_url path, target
|
||||||
end
|
end
|
||||||
|
|
||||||
def aref_to(target)
|
def aref_to(target)
|
||||||
|
@ -475,7 +462,7 @@ module RDoc::Generator
|
||||||
def add_table_of_sections
|
def add_table_of_sections
|
||||||
toc = []
|
toc = []
|
||||||
@context.sections.each do |section|
|
@context.sections.each do |section|
|
||||||
if section.title
|
if section.title then
|
||||||
toc << {
|
toc << {
|
||||||
'secname' => section.title,
|
'secname' => section.title,
|
||||||
'href' => section.sequence
|
'href' => section.sequence
|
||||||
|
@ -495,11 +482,13 @@ module RDoc::Generator
|
||||||
|
|
||||||
attr_reader :methods
|
attr_reader :methods
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
attr_reader :values
|
||||||
|
|
||||||
def initialize(context, html_file, prefix, options)
|
def initialize(context, html_file, prefix, options)
|
||||||
super(context, options)
|
super context, options
|
||||||
|
|
||||||
@html_file = html_file
|
@html_file = html_file
|
||||||
|
@html_class = self
|
||||||
@is_module = context.is_module?
|
@is_module = context.is_module?
|
||||||
@values = {}
|
@values = {}
|
||||||
|
|
||||||
|
@ -540,11 +529,19 @@ module RDoc::Generator
|
||||||
name
|
name
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_on(f)
|
def write_on(f, file_list, class_list, method_list, overrides = {})
|
||||||
value_hash
|
value_hash
|
||||||
|
|
||||||
|
@values['file_list'] = file_list
|
||||||
|
@values['class_list'] = class_list
|
||||||
|
@values['method_list'] = method_list
|
||||||
|
|
||||||
|
@values.update overrides
|
||||||
|
|
||||||
template = RDoc::TemplatePage.new(@template::BODY,
|
template = RDoc::TemplatePage.new(@template::BODY,
|
||||||
@template::CLASS_PAGE,
|
@template::CLASS_PAGE,
|
||||||
@template::METHOD_LIST)
|
@template::METHOD_LIST)
|
||||||
|
|
||||||
template.write_html_on(f, @values)
|
template.write_html_on(f, @values)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -561,30 +558,29 @@ module RDoc::Generator
|
||||||
ml = build_method_summary_list @path
|
ml = build_method_summary_list @path
|
||||||
@values["methods"] = ml unless ml.empty?
|
@values["methods"] = ml unless ml.empty?
|
||||||
|
|
||||||
il = build_include_list(@context)
|
il = build_include_list @context
|
||||||
@values["includes"] = il unless il.empty?
|
@values["includes"] = il unless il.empty?
|
||||||
|
|
||||||
@values["sections"] = @context.sections.map do |section|
|
@values["sections"] = @context.sections.map do |section|
|
||||||
|
|
||||||
secdata = {
|
secdata = {
|
||||||
"sectitle" => section.title,
|
"sectitle" => section.title,
|
||||||
"secsequence" => section.sequence,
|
"secsequence" => section.sequence,
|
||||||
"seccomment" => markup(section.comment)
|
"seccomment" => markup(section.comment),
|
||||||
}
|
}
|
||||||
|
|
||||||
al = build_alias_summary_list(section)
|
al = build_alias_summary_list section
|
||||||
secdata["aliases"] = al unless al.empty?
|
secdata["aliases"] = al unless al.empty?
|
||||||
|
|
||||||
co = build_constants_summary_list(section)
|
co = build_constants_summary_list section
|
||||||
secdata["constants"] = co unless co.empty?
|
secdata["constants"] = co unless co.empty?
|
||||||
|
|
||||||
al = build_attribute_list(section)
|
al = build_attribute_list section
|
||||||
secdata["attributes"] = al unless al.empty?
|
secdata["attributes"] = al unless al.empty?
|
||||||
|
|
||||||
cl = build_class_list(0, @context, section)
|
cl = build_class_list 0, @context, section
|
||||||
secdata["classlist"] = cl unless cl.empty?
|
secdata["classlist"] = cl unless cl.empty?
|
||||||
|
|
||||||
mdl = build_method_detail_list(section)
|
mdl = build_method_detail_list section
|
||||||
secdata["method_list"] = mdl unless mdl.empty?
|
secdata["method_list"] = mdl unless mdl.empty?
|
||||||
|
|
||||||
secdata
|
secdata
|
||||||
|
@ -594,23 +590,25 @@ module RDoc::Generator
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_attribute_list(section)
|
def build_attribute_list(section)
|
||||||
atts = @context.attributes.sort
|
@context.attributes.sort.map do |att|
|
||||||
res = []
|
|
||||||
atts.each do |att|
|
|
||||||
next unless att.section == section
|
next unless att.section == section
|
||||||
if att.visibility == :public || att.visibility == :protected || @options.show_all
|
|
||||||
|
if att.visibility == :public or att.visibility == :protected or
|
||||||
|
@options.show_all then
|
||||||
|
|
||||||
entry = {
|
entry = {
|
||||||
"name" => CGI.escapeHTML(att.name),
|
"name" => CGI.escapeHTML(att.name),
|
||||||
"rw" => att.rw,
|
"rw" => att.rw,
|
||||||
"a_desc" => markup(att.comment, true)
|
"a_desc" => markup(att.comment, true)
|
||||||
}
|
}
|
||||||
unless att.visibility == :public || att.visibility == :protected
|
|
||||||
|
unless att.visibility == :public or att.visibility == :protected then
|
||||||
entry["rw"] << "-"
|
entry["rw"] << "-"
|
||||||
end
|
end
|
||||||
res << entry
|
|
||||||
|
entry
|
||||||
end
|
end
|
||||||
end
|
end.compact
|
||||||
res
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def class_attribute_values
|
def class_attribute_values
|
||||||
|
@ -680,9 +678,10 @@ module RDoc::Generator
|
||||||
|
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
attr_reader :values
|
||||||
|
|
||||||
def initialize(context, options, file_dir)
|
def initialize(context, options, file_dir)
|
||||||
super(context, options)
|
super context, options
|
||||||
|
|
||||||
@values = {}
|
@values = {}
|
||||||
|
|
||||||
|
@ -755,7 +754,7 @@ module RDoc::Generator
|
||||||
}
|
}
|
||||||
|
|
||||||
cl = build_class_list(0, @context, section, file_context)
|
cl = build_class_list(0, @context, section, file_context)
|
||||||
@values["classlist"] = cl unless cl.empty?
|
secdata["classlist"] = cl unless cl.empty?
|
||||||
|
|
||||||
mdl = build_method_detail_list(section)
|
mdl = build_method_detail_list(section)
|
||||||
secdata["method_list"] = mdl unless mdl.empty?
|
secdata["method_list"] = mdl unless mdl.empty?
|
||||||
|
@ -764,7 +763,7 @@ module RDoc::Generator
|
||||||
secdata["aliases"] = al unless al.empty?
|
secdata["aliases"] = al unless al.empty?
|
||||||
|
|
||||||
co = build_constants_summary_list(section)
|
co = build_constants_summary_list(section)
|
||||||
@values["constants"] = co unless co.empty?
|
secdata["constants"] = co unless co.empty?
|
||||||
|
|
||||||
secdata
|
secdata
|
||||||
end
|
end
|
||||||
|
@ -772,9 +771,15 @@ module RDoc::Generator
|
||||||
@values
|
@values
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_on(f)
|
def write_on(f, file_list, class_list, method_list, overrides = {})
|
||||||
value_hash
|
value_hash
|
||||||
|
|
||||||
|
@values['file_list'] = file_list
|
||||||
|
@values['class_list'] = class_list
|
||||||
|
@values['method_list'] = method_list
|
||||||
|
|
||||||
|
@values.update overrides
|
||||||
|
|
||||||
template = RDoc::TemplatePage.new(@template::BODY,
|
template = RDoc::TemplatePage.new(@template::BODY,
|
||||||
@template::FILE_PAGE,
|
@template::FILE_PAGE,
|
||||||
@template::METHOD_LIST)
|
@template::METHOD_LIST)
|
||||||
|
@ -829,15 +834,17 @@ module RDoc::Generator
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(context, html_class, options)
|
def initialize(context, html_class, options)
|
||||||
|
# TODO: rethink the class hierarchy here...
|
||||||
@context = context
|
@context = context
|
||||||
@html_class = html_class
|
@html_class = html_class
|
||||||
@options = options
|
@options = options
|
||||||
|
|
||||||
|
@@seq = @@seq.succ
|
||||||
|
@seq = @@seq
|
||||||
|
|
||||||
# HACK ugly
|
# HACK ugly
|
||||||
@template = options.template_class
|
@template = options.template_class
|
||||||
|
|
||||||
@@seq = @@seq.succ
|
|
||||||
@seq = @@seq
|
|
||||||
@@all_methods << self
|
@@all_methods << self
|
||||||
|
|
||||||
context.viewer = self
|
context.viewer = self
|
||||||
|
@ -846,7 +853,7 @@ module RDoc::Generator
|
||||||
@source_code = markup_code(ts)
|
@source_code = markup_code(ts)
|
||||||
unless @options.inline_source
|
unless @options.inline_source
|
||||||
@src_url = create_source_code_file(@source_code)
|
@src_url = create_source_code_file(@source_code)
|
||||||
@img_url = RDoc::Generator.gen_url path, 'source.png'
|
@img_url = RDoc::Markup::ToHtml.gen_relative_url path, 'source.png'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -861,10 +868,32 @@ module RDoc::Generator
|
||||||
if @options.all_one_file
|
if @options.all_one_file
|
||||||
"#" + path
|
"#" + path
|
||||||
else
|
else
|
||||||
RDoc::Generator.gen_url from_path, path
|
RDoc::Markup::ToHtml.gen_relative_url from_path, path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def formatter
|
||||||
|
@formatter ||= @options.formatter ||
|
||||||
|
RDoc::Markup::ToHtmlCrossref.new(path, self, @options.show_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
alias_for = if @context.is_alias_for then
|
||||||
|
" (alias_for #{@context.is_alias_for})"
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
"#<%s:0x%x %s%s%s (%s)%s>" % [
|
||||||
|
self.class, object_id,
|
||||||
|
@context.parent.name,
|
||||||
|
@context.singleton ? '::' : '#',
|
||||||
|
name,
|
||||||
|
@context.visibility,
|
||||||
|
alias_for
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
@context.name
|
@context.name
|
||||||
end
|
end
|
||||||
|
@ -961,7 +990,7 @@ module RDoc::Generator
|
||||||
template.write_html_on(f, values)
|
template.write_html_on(f, values)
|
||||||
end
|
end
|
||||||
|
|
||||||
RDoc::Generator.gen_url path, file_path
|
RDoc::Markup::ToHtml.gen_relative_url path, file_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def <=>(other)
|
def <=>(other)
|
||||||
|
@ -976,19 +1005,18 @@ module RDoc::Generator
|
||||||
src = ""
|
src = ""
|
||||||
tokens.each do |t|
|
tokens.each do |t|
|
||||||
next unless t
|
next unless t
|
||||||
# p t.class
|
|
||||||
# style = STYLE_MAP[t.class]
|
# style = STYLE_MAP[t.class]
|
||||||
style = case t
|
style = case t
|
||||||
when RubyToken::TkCONSTANT then "ruby-constant"
|
when RDoc::RubyToken::TkCONSTANT then "ruby-constant"
|
||||||
when RubyToken::TkKW then "ruby-keyword kw"
|
when RDoc::RubyToken::TkKW then "ruby-keyword kw"
|
||||||
when RubyToken::TkIVAR then "ruby-ivar"
|
when RDoc::RubyToken::TkIVAR then "ruby-ivar"
|
||||||
when RubyToken::TkOp then "ruby-operator"
|
when RDoc::RubyToken::TkOp then "ruby-operator"
|
||||||
when RubyToken::TkId then "ruby-identifier"
|
when RDoc::RubyToken::TkId then "ruby-identifier"
|
||||||
when RubyToken::TkNode then "ruby-node"
|
when RDoc::RubyToken::TkNode then "ruby-node"
|
||||||
when RubyToken::TkCOMMENT then "ruby-comment cmt"
|
when RDoc::RubyToken::TkCOMMENT then "ruby-comment cmt"
|
||||||
when RubyToken::TkREGEXP then "ruby-regexp re"
|
when RDoc::RubyToken::TkREGEXP then "ruby-regexp re"
|
||||||
when RubyToken::TkSTRING then "ruby-value str"
|
when RDoc::RubyToken::TkSTRING then "ruby-value str"
|
||||||
when RubyToken::TkVal then "ruby-value"
|
when RDoc::RubyToken::TkVal then "ruby-value"
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -82,7 +82,7 @@ class RDoc::Generator::HTML
|
||||||
@classes = []
|
@classes = []
|
||||||
|
|
||||||
write_style_sheet
|
write_style_sheet
|
||||||
gen_sub_directories()
|
gen_sub_directories
|
||||||
build_indices
|
build_indices
|
||||||
generate_html
|
generate_html
|
||||||
end
|
end
|
||||||
|
@ -157,6 +157,7 @@ class RDoc::Generator::HTML
|
||||||
# the individual descriptions for files and classes
|
# the individual descriptions for files and classes
|
||||||
gen_into(@files)
|
gen_into(@files)
|
||||||
gen_into(@classes)
|
gen_into(@classes)
|
||||||
|
|
||||||
# and the index files
|
# and the index files
|
||||||
gen_file_index
|
gen_file_index
|
||||||
gen_class_index
|
gen_class_index
|
||||||
|
@ -168,14 +169,21 @@ class RDoc::Generator::HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
def gen_into(list)
|
def gen_into(list)
|
||||||
|
@file_list ||= index_to_links @files
|
||||||
|
@class_list ||= index_to_links @classes
|
||||||
|
@method_list ||= index_to_links RDoc::Generator::Method.all_methods
|
||||||
|
|
||||||
list.each do |item|
|
list.each do |item|
|
||||||
if item.document_self
|
next unless item.document_self
|
||||||
op_file = item.path
|
|
||||||
FileUtils.mkdir_p(File.dirname(op_file))
|
op_file = item.path
|
||||||
open(op_file, "w") { |file| item.write_on(file) }
|
|
||||||
|
FileUtils.mkdir_p File.dirname(op_file)
|
||||||
|
|
||||||
|
open op_file, 'w' do |io|
|
||||||
|
item.write_on io, @file_list, @class_list, @method_list
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def gen_file_index
|
def gen_file_index
|
||||||
|
@ -221,9 +229,23 @@ class RDoc::Generator::HTML
|
||||||
# line.
|
# line.
|
||||||
|
|
||||||
def gen_main_index
|
def gen_main_index
|
||||||
template = RDoc::TemplatePage.new @template::INDEX
|
if @template.const_defined? :FRAMELESS then
|
||||||
|
main = @files.find do |file|
|
||||||
|
@main_page == file.name
|
||||||
|
end
|
||||||
|
|
||||||
|
if main.nil? then
|
||||||
|
main = @classes.find do |klass|
|
||||||
|
main_page == klass.context.full_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
main = RDoc::TemplatePage.new @template::INDEX
|
||||||
|
end
|
||||||
|
|
||||||
open 'index.html', 'w' do |f|
|
open 'index.html', 'w' do |f|
|
||||||
|
style_url = style_url '', @options.css
|
||||||
|
|
||||||
classes = @classes.sort.map { |klass| klass.value_hash }
|
classes = @classes.sort.map { |klass| klass.value_hash }
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
|
@ -237,18 +259,31 @@ class RDoc::Generator::HTML
|
||||||
|
|
||||||
values['inline_source'] = @options.inline_source
|
values['inline_source'] = @options.inline_source
|
||||||
|
|
||||||
template.write_html_on f, values
|
if main.respond_to? :write_on then
|
||||||
|
main.write_on f, @file_list, @class_list, @method_list, values
|
||||||
|
else
|
||||||
|
main.write_html_on f, values
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_to_links(collection)
|
||||||
|
collection.sort.map do |f|
|
||||||
|
next unless f.document_self
|
||||||
|
{ "href" => f.path, "name" => f.index_name }
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns the url of the main page
|
# Returns the url of the main page
|
||||||
|
|
||||||
def main_url
|
def main_url
|
||||||
@main_page = @options.main_page
|
@main_page = @options.main_page
|
||||||
@main_page_ref = nil
|
@main_page_ref = nil
|
||||||
if @main_page
|
|
||||||
|
if @main_page then
|
||||||
@main_page_ref = RDoc::Generator::AllReferences[@main_page]
|
@main_page_ref = RDoc::Generator::AllReferences[@main_page]
|
||||||
|
|
||||||
if @main_page_ref then
|
if @main_page_ref then
|
||||||
@main_page_path = @main_page_ref.path
|
@main_page_path = @main_page_ref.path
|
||||||
else
|
else
|
||||||
|
@ -351,15 +386,8 @@ class RDoc::Generator::HTMLInOne < RDoc::Generator::HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
def gen_an_index(collection, title)
|
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 {
|
return {
|
||||||
"entries" => res,
|
"entries" => index_to_links(collection),
|
||||||
'list_title' => title,
|
'list_title' => title,
|
||||||
'index_url' => main_url,
|
'index_url' => main_url,
|
||||||
}
|
}
|
||||||
|
@ -367,4 +395,3 @@ class RDoc::Generator::HTMLInOne < RDoc::Generator::HTML
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
795
lib/rdoc/generator/html/frameless.rb
Normal file
795
lib/rdoc/generator/html/frameless.rb
Normal file
|
@ -0,0 +1,795 @@
|
||||||
|
require 'rdoc/generator/html'
|
||||||
|
require 'rdoc/generator/html/one_page_html'
|
||||||
|
|
||||||
|
##
|
||||||
|
# = 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::Generator::HTML::FRAMELESS
|
||||||
|
|
||||||
|
FRAMELESS = true
|
||||||
|
|
||||||
|
FONTS = "Verdana,Arial,Helvetica,sans-serif"
|
||||||
|
|
||||||
|
STYLE = <<-EOF
|
||||||
|
body {
|
||||||
|
font-family: #{FONTS};
|
||||||
|
font-size: 90%;
|
||||||
|
margin: 0;
|
||||||
|
margin-left: 40px;
|
||||||
|
padding: 0;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4 {
|
||||||
|
margin: 0;
|
||||||
|
color: #efefef;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2,h3,h4 {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:link, :visited {
|
||||||
|
background: #eef;
|
||||||
|
color: #039;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:link:hover, :visited:hover {
|
||||||
|
background: #039;
|
||||||
|
color: #eef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override the base stylesheet's Anchor inside a table cell */
|
||||||
|
td > :link, td > :visited {
|
||||||
|
background: transparent;
|
||||||
|
color: #039;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and inside a section title */
|
||||||
|
.section-title > :link, .section-title > :visited {
|
||||||
|
background: transparent;
|
||||||
|
color: #eee;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === Structural elements =================================== */
|
||||||
|
|
||||||
|
.index {
|
||||||
|
margin: 0;
|
||||||
|
margin-left: -40px;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.index :link, .index :visited {
|
||||||
|
margin-left: 0.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.index .section-bar {
|
||||||
|
margin-left: 0px;
|
||||||
|
padding-left: 0.7em;
|
||||||
|
background: #ccc;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
#classHeader, #fileHeader {
|
||||||
|
width: auto;
|
||||||
|
color: white;
|
||||||
|
padding: 0.5em 1.5em 0.5em 1.5em;
|
||||||
|
margin: 0;
|
||||||
|
margin-left: -40px;
|
||||||
|
border-bottom: 3px solid #006;
|
||||||
|
}
|
||||||
|
|
||||||
|
#classHeader :link, #fileHeader :link,
|
||||||
|
#classHeader :visited, #fileHeader :visited {
|
||||||
|
background: inherit;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#classHeader td, #fileHeader td {
|
||||||
|
background: inherit;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileHeader {
|
||||||
|
background: #057;
|
||||||
|
}
|
||||||
|
|
||||||
|
#classHeader {
|
||||||
|
background: #048;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-name-in-header {
|
||||||
|
font-size: 180%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bodyContent {
|
||||||
|
padding: 0 1.5em 0 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#description {
|
||||||
|
padding: 0.5em 1.5em;
|
||||||
|
background: #efefef;
|
||||||
|
border: 1px dotted #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#description h1, #description h2, #description h3,
|
||||||
|
#description h4, #description h5, #description h6 {
|
||||||
|
color: #125;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xxsection-bar {
|
||||||
|
background: #eee;
|
||||||
|
color: #333;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-bar {
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
margin-left: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
background: #79a;
|
||||||
|
color: #eee;
|
||||||
|
padding: 3px;
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-left: -30px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-aligned-row {
|
||||||
|
vertical-align: top
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-aligned-row {
|
||||||
|
vertical-align: bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Context section classes ----------------------- */
|
||||||
|
|
||||||
|
.context-row { }
|
||||||
|
|
||||||
|
.context-item-name {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-item-value {
|
||||||
|
font-size: small;
|
||||||
|
color: #448;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-item-desc {
|
||||||
|
color: #333;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Method classes -------------------------- */
|
||||||
|
|
||||||
|
.method-detail {
|
||||||
|
background: #efefef;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
border: 1px dotted #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-heading {
|
||||||
|
color: black;
|
||||||
|
background: #ccc;
|
||||||
|
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 -------------------- */
|
||||||
|
|
||||||
|
:link.source-toggle, :visited.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 --------------------- */
|
||||||
|
|
||||||
|
.standalone-code {
|
||||||
|
background: #221111;
|
||||||
|
color: #ffdead;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Header template
|
||||||
|
|
||||||
|
XHTML_PREAMBLE = <<-EOF
|
||||||
|
<?xml version="1.0" encoding="<%= values["charset"] %>"?>
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
EOF
|
||||||
|
|
||||||
|
HEADER = XHTML_PREAMBLE + <<-EOF
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<title><%= values["title"] %></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=<%= values["charset"] %>" />
|
||||||
|
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||||
|
<link rel="stylesheet" href="<%= values["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>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Context content template
|
||||||
|
|
||||||
|
CONTEXT_CONTENT = %{
|
||||||
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Footer template
|
||||||
|
|
||||||
|
FOOTER = <<-EOF
|
||||||
|
<div id="popupmenu" class="index">
|
||||||
|
<ul>
|
||||||
|
<li class="index-entries section-bar">Classes
|
||||||
|
<ul>
|
||||||
|
<% values["class_list"].each do |klass| %>
|
||||||
|
<li><a href="<%= klass["href"] %>"><%= klass["name"] %></a>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="index-entries section-bar">Methods
|
||||||
|
<ul>
|
||||||
|
<% values["method_list"].each do |file| %>
|
||||||
|
<li><a href="<%= file["href"] %>"><%= file["name"] %></a>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="index-entries section-bar">Files
|
||||||
|
<ul>
|
||||||
|
<% values["file_list"].each do |file| %>
|
||||||
|
<li><a href="<%= file["href"] %>"><%= file["name"] %></a>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# File page header template
|
||||||
|
|
||||||
|
FILE_PAGE = <<-EOF
|
||||||
|
<div id="fileHeader">
|
||||||
|
<h1><%= values["short_name"] %></h1>
|
||||||
|
|
||||||
|
<table class="header-table">
|
||||||
|
<tr class="top-aligned-row">
|
||||||
|
<td><strong>Path:</strong></td>
|
||||||
|
<td><%= values["full_path"] %>
|
||||||
|
<% if values["cvsurl"] then %>
|
||||||
|
(<a href="<%= values["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="top-aligned-row">
|
||||||
|
<td><strong>Last Update:</strong></td>
|
||||||
|
<td><%= values["dtm_modified"] %></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Class page header template
|
||||||
|
|
||||||
|
CLASS_PAGE = <<-EOF
|
||||||
|
<div id="classHeader">
|
||||||
|
<table class="header-table">
|
||||||
|
<tr class="top-aligned-row">
|
||||||
|
<td><strong><%= values["classmod"] %></strong></td>
|
||||||
|
<td class="class-name-in-header"><%= values["full_name"] %></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="top-aligned-row">
|
||||||
|
<td><strong>In:</strong></td>
|
||||||
|
<td>
|
||||||
|
<% values["infiles"].each do |infiles| %>
|
||||||
|
<% if infiles["full_path_url"] then %>
|
||||||
|
<a href="<%= infiles["full_path_url"] %>">
|
||||||
|
<% end %>
|
||||||
|
<%= infiles["full_path"] %>
|
||||||
|
<% if infiles["full_path_url"] then %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
<% if infiles["cvsurl"] then %>
|
||||||
|
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
||||||
|
<% end %>
|
||||||
|
<br />
|
||||||
|
<% end %><%# values["infiles"] %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<% if values["parent"] then %>
|
||||||
|
<tr class="top-aligned-row">
|
||||||
|
<td><strong>Parent:</strong></td>
|
||||||
|
<td>
|
||||||
|
<% if values["par_url"] then %>
|
||||||
|
<a href="<%= values["par_url"] %>">
|
||||||
|
<% end %>
|
||||||
|
<%= values["parent"] %>
|
||||||
|
<% if values["par_url"] then %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Method list template
|
||||||
|
|
||||||
|
METHOD_LIST = <<-EOF
|
||||||
|
|
||||||
|
<div id="contextContent">
|
||||||
|
<% if values["diagram"] then %>
|
||||||
|
<div id="diagram">
|
||||||
|
<%= values["diagram"] %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["description"] then %>
|
||||||
|
<div id="description">
|
||||||
|
<%= values["description"] %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["requires"] then %>
|
||||||
|
<div id="requires-list">
|
||||||
|
<h3 class="section-bar">Required files</h3>
|
||||||
|
|
||||||
|
<div class="name-list">
|
||||||
|
<% values["requires"].each do |requires| %>
|
||||||
|
<%= href requires["aref"], requires["name"] %>
|
||||||
|
<% end %><%# values["requires"] %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["toc"] then %>
|
||||||
|
<div id="contents-list">
|
||||||
|
<h3 class="section-bar">Contents</h3>
|
||||||
|
<ul>
|
||||||
|
<% values["toc"].each do |toc| %>
|
||||||
|
<li><a href="#<%= values["href"] %>"><%= values["secname"] %></a></li>
|
||||||
|
<% end %><%# values["toc"] %>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if values["methods"] then %>
|
||||||
|
<div id="method-list">
|
||||||
|
<h3 class="section-bar">Methods</h3>
|
||||||
|
|
||||||
|
<div class="name-list">
|
||||||
|
<% values["methods"].each do |methods| %>
|
||||||
|
<%= href methods["aref"], methods["name"] %>
|
||||||
|
<% end %><%# values["methods"] %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- if includes -->
|
||||||
|
<% if values["includes"] then %>
|
||||||
|
<div id="includes">
|
||||||
|
<h3 class="section-bar">Included Modules</h3>
|
||||||
|
|
||||||
|
<div id="includes-list">
|
||||||
|
<% values["includes"].each do |includes| %>
|
||||||
|
<span class="include-name"><%= href includes["aref"], includes["name"] %></span>
|
||||||
|
<% end %><%# values["includes"] %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% values["sections"].each do |sections| %>
|
||||||
|
<div id="section">
|
||||||
|
<% if sections["sectitle"] then %>
|
||||||
|
<h2 class="section-title"><a name="<%= sections["secsequence"] %>"><%= sections["sectitle"] %></a></h2>
|
||||||
|
<% if sections["seccomment"] then %>
|
||||||
|
<div class="section-comment">
|
||||||
|
<%= sections["seccomment"] %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["classlist"] then %>
|
||||||
|
<div id="class-list">
|
||||||
|
<h3 class="section-bar">Classes and Modules</h3>
|
||||||
|
|
||||||
|
<%= values["classlist"] %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["constants"] then %>
|
||||||
|
<div id="constants-list">
|
||||||
|
<h3 class="section-bar">Constants</h3>
|
||||||
|
|
||||||
|
<div class="name-list">
|
||||||
|
<table summary="Constants">
|
||||||
|
<% values["constants"].each do |constants| %>
|
||||||
|
<tr class="top-aligned-row context-row">
|
||||||
|
<td class="context-item-name"><%= constants["name"] %></td>
|
||||||
|
<td>=</td>
|
||||||
|
<td class="context-item-value"><%= constants["value"] %></td>
|
||||||
|
<% if values["desc"] then %>
|
||||||
|
<td width="3em"> </td>
|
||||||
|
<td class="context-item-desc"><%= constants["desc"] %></td>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
<% end %><%# values["constants"] %>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if values["aliases"] then %>
|
||||||
|
<div id="aliases-list">
|
||||||
|
<h3 class="section-bar">External Aliases</h3>
|
||||||
|
|
||||||
|
<div class="name-list">
|
||||||
|
<table summary="aliases">
|
||||||
|
<% values["aliases"].each do |aliases| $stderr.puts({ :aliases => aliases }.inspect) %>
|
||||||
|
<tr class="top-aligned-row context-row">
|
||||||
|
<td class="context-item-name"><%= values["old_name"] %></td>
|
||||||
|
<td>-></td>
|
||||||
|
<td class="context-item-value"><%= values["new_name"] %></td>
|
||||||
|
</tr>
|
||||||
|
<% if values["desc"] then %>
|
||||||
|
<tr class="top-aligned-row context-row">
|
||||||
|
<td> </td>
|
||||||
|
<td colspan="2" class="context-item-desc"><%= values["desc"] %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% end %><%# values["aliases"] %>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
<% if values["attributes"] then %>
|
||||||
|
<div id="attribute-list">
|
||||||
|
<h3 class="section-bar">Attributes</h3>
|
||||||
|
|
||||||
|
<div class="name-list">
|
||||||
|
<table>
|
||||||
|
<% values["attributes"].each do |attributes| $stderr.puts({ :attributes => attributes }.inspect) %>
|
||||||
|
<tr class="top-aligned-row context-row">
|
||||||
|
<td class="context-item-name"><%= values["name"] %></td>
|
||||||
|
<% if values["rw"] then %>
|
||||||
|
<td class="context-item-value"> [<%= values["rw"] %>] </td>
|
||||||
|
<% end %>
|
||||||
|
<% unless values["rw"] then %>
|
||||||
|
<td class="context-item-value"> </td>
|
||||||
|
<% end %>
|
||||||
|
<td class="context-item-desc"><%= values["a_desc"] %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %><%# values["attributes"] %>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- if method_list -->
|
||||||
|
<% if sections["method_list"] then %>
|
||||||
|
<div id="methods">
|
||||||
|
<% sections["method_list"].each do |method_list| %>
|
||||||
|
<% if method_list["methods"] then %>
|
||||||
|
<h3 class="section-bar"><%= method_list["type"] %> <%= method_list["category"] %> methods</h3>
|
||||||
|
|
||||||
|
<% method_list["methods"].each do |methods| %>
|
||||||
|
<div id="method-<%= methods["aref"] %>" class="method-detail">
|
||||||
|
<a name="<%= methods["aref"] %>"></a>
|
||||||
|
|
||||||
|
<div class="method-heading">
|
||||||
|
<% if methods["codeurl"] then %>
|
||||||
|
<a href="<%= methods["codeurl"] %>" target="Code" class="method-signature"
|
||||||
|
onclick="popupCode('<%= methods["codeurl"] %>');return false;">
|
||||||
|
<% end %>
|
||||||
|
<% if methods["sourcecode"] then %>
|
||||||
|
<a href="#<%= methods["aref"] %>" class="method-signature">
|
||||||
|
<% end %>
|
||||||
|
<% if methods["callseq"] then %>
|
||||||
|
<span class="method-name"><%= methods["callseq"] %></span>
|
||||||
|
<% end %>
|
||||||
|
<% unless methods["callseq"] then %>
|
||||||
|
<span class="method-name"><%= methods["name"] %></span><span class="method-args"><%= methods["params"] %></span>
|
||||||
|
<% end %>
|
||||||
|
<% if methods["codeurl"] then %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
<% if methods["sourcecode"] then %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="method-description">
|
||||||
|
<% if methods["m_desc"] then %>
|
||||||
|
<%= methods["m_desc"] %>
|
||||||
|
<% end %>
|
||||||
|
<% if methods["sourcecode"] then %>
|
||||||
|
<p><a class="source-toggle" href="#"
|
||||||
|
onclick="toggleCode('<%= methods["aref"] %>-source');return false;">[Source]</a></p>
|
||||||
|
<div class="method-source-code" id="<%= methods["aref"] %>-source">
|
||||||
|
<pre>
|
||||||
|
<%= methods["sourcecode"] %>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% end %><%# method_list["methods"] %>
|
||||||
|
<% end %>
|
||||||
|
<% end %><%# sections["method_list"] %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %><%# values["sections"] %>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Body template
|
||||||
|
|
||||||
|
BODY = HEADER + %{
|
||||||
|
|
||||||
|
<%= template_include %> <!-- banner header -->
|
||||||
|
|
||||||
|
<div id="bodyContent">
|
||||||
|
|
||||||
|
} + METHOD_LIST + %{
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
} + FOOTER
|
||||||
|
|
||||||
|
##
|
||||||
|
# Source code template
|
||||||
|
|
||||||
|
SRC_PAGE = XHTML_PREAMBLE + <<-EOF
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%= values["title"] %></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=<%= values["charset"] %>" />
|
||||||
|
<link rel="stylesheet" href="<%= values["style_url"] %>" type="text/css" media="screen" />
|
||||||
|
</head>
|
||||||
|
<body class="standalone-code">
|
||||||
|
<pre><%= values["code"] %></pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
##
|
||||||
|
# Index file templates
|
||||||
|
|
||||||
|
FR_INDEX_BODY = %{
|
||||||
|
<%= template_include %>
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_INDEX = XHTML_PREAMBLE + <<-EOF
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<title><%= values["list_title"] %></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=<%= values["charset"] %>" />
|
||||||
|
<link rel="stylesheet" href="<%= values["style_url"] %>" type="text/css" />
|
||||||
|
<base target="docwin" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="index">
|
||||||
|
<h1 class="section-bar"><%= values["list_title"] %></h1>
|
||||||
|
<div class="index-entries">
|
||||||
|
<% values["entries"].each do |entries| %>
|
||||||
|
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
||||||
|
<% end %><%# values["entries"] %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
CLASS_INDEX = FILE_INDEX
|
||||||
|
METHOD_INDEX = FILE_INDEX
|
||||||
|
|
||||||
|
INDEX = <<-EOF
|
||||||
|
<?xml version="1.0" encoding="<%= values["charset"] %>"?>
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<title><%= values["title"] %></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=<%= values["charset"] %>" />
|
||||||
|
</head>
|
||||||
|
<frameset rows="20%, 80%">
|
||||||
|
<frameset cols="45%,55%">
|
||||||
|
<frame src="fr_class_index.html" name="Classes" />
|
||||||
|
<frame src="fr_method_index.html" name="Methods" />
|
||||||
|
</frameset>
|
||||||
|
<frame src="<%= values["initial_page"] %>" name="docwin" />
|
||||||
|
</frameset>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -141,7 +141,7 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["requires"].each do |requires| %>
|
<% values["requires"].each do |requires| %>
|
||||||
<%= href requires["aref"], requires["name"] %>
|
<%= href requires["aref"], requires["name"] %>
|
||||||
<% end # values["requires"] %>
|
<% end %><%# values["requires"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -156,10 +156,10 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% method_list["methods"].each do |methods| %>
|
<% method_list["methods"].each do |methods| %>
|
||||||
<a href="<%= methods["codeurl"] %>" target="source"><%= methods["name"] %></a>
|
<a href="<%= methods["codeurl"] %>" target="source"><%= methods["name"] %></a>
|
||||||
<% end # values["methods"] %>
|
<% end %><%# values["methods"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["method_list"] %>
|
<% end %><%# values["method_list"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if sections["attributes"] then %>
|
<% if sections["attributes"] then %>
|
||||||
|
@ -178,10 +178,10 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<td class="attr-name"><%= attributes["name"] %></td>
|
<td class="attr-name"><%= attributes["name"] %></td>
|
||||||
<td><%= attributes["a_desc"] %></td>
|
<td><%= attributes["a_desc"] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end # values["attributes"] %>
|
<% end %><%# values["attributes"] %>
|
||||||
</table>
|
</table>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["sections"] %>
|
<% end %><%# values["sections"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if values["classlist"] then %>
|
<% if values["classlist"] then %>
|
||||||
|
@ -237,7 +237,7 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<% if infiles["cvsurl"] then %>
|
<% if infiles["cvsurl"] then %>
|
||||||
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["infiles"] %>
|
<% end %><%# values["infiles"] %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% if values["parent"] then %>
|
<% if values["parent"] then %>
|
||||||
|
@ -266,7 +266,7 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["includes"].each do |includes| %>
|
<% values["includes"].each do |includes| %>
|
||||||
<span class="method-name"><%= href includes["aref"], includes["name"] %></span>
|
<span class="method-name"><%= href includes["aref"], includes["name"] %></span>
|
||||||
<% end # values["includes"] %>
|
<% end %><%# values["includes"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -293,11 +293,11 @@ td { font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||||
<%= method_list["m_desc"] %>
|
<%= method_list["m_desc"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # method_list["methods"] %>
|
<% end %><%# method_list["methods"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # sections["method_list"] %>
|
<% end %><%# sections["method_list"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["sections"] %>
|
<% end %><%# values["sections"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ div.banner {
|
||||||
<div class="banner"><%= values["list_title"] %></div>
|
<div class="banner"><%= values["list_title"] %></div>
|
||||||
<% values["entries"].each do |entries| %>
|
<% values["entries"].each do |entries| %>
|
||||||
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
||||||
<% end # values["entries"] %>
|
<% end %><%# values["entries"] %>
|
||||||
</body></html>
|
</body></html>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ require 'rdoc/generator/html/one_page_html'
|
||||||
# This is a template for RDoc that uses XHTML 1.0 Transitional and dictates a
|
# 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
|
# 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
|
# default. It was designed for clean inline code display, and uses DHTMl to
|
||||||
# toggle the visibility of each method's source with each click on the '[source]'
|
# toggle the visibility of each method's source with each click on the
|
||||||
# link.
|
# '[source]' link.
|
||||||
#
|
#
|
||||||
# == Authors
|
# == Authors
|
||||||
#
|
#
|
||||||
|
@ -16,10 +16,10 @@ require 'rdoc/generator/html/one_page_html'
|
||||||
#
|
#
|
||||||
# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved.
|
# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved.
|
||||||
#
|
#
|
||||||
# This work is licensed under the Creative Commons Attribution License. To view
|
# This work is licensed under the Creative Commons Attribution License. To
|
||||||
# a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or
|
# view a copy of this license, visit
|
||||||
# send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
|
# http://creativecommons.org/licenses/by/1.0/ or send a letter to Creative
|
||||||
# 94305, USA.
|
# Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||||
|
|
||||||
module RDoc::Generator::HTML::HTML
|
module RDoc::Generator::HTML::HTML
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ EOF
|
||||||
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
||||||
<% end %>
|
<% end %>
|
||||||
<br />
|
<br />
|
||||||
<% end # values["infiles"] %>
|
<% end %><%# values["infiles"] %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@ -388,39 +388,38 @@ EOF
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
|
||||||
METHOD_LIST = <<-EOF
|
METHOD_LIST = <<-EOF
|
||||||
|
|
||||||
<div id="contextContent">
|
<div id="contextContent">
|
||||||
<% if values["diagram"] then %>
|
<% if values["diagram"] then %>
|
||||||
<div id="diagram">
|
<div id="diagram">
|
||||||
<%= values["diagram"] %>
|
<%= values["diagram"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% if values["description"] then %>
|
if values["description"] then %>
|
||||||
<div id="description">
|
<div id="description">
|
||||||
<%= values["description"] %>
|
<%= values["description"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% if values["requires"] then %>
|
if values["requires"] then %>
|
||||||
<div id="requires-list">
|
<div id="requires-list">
|
||||||
<h3 class="section-bar">Required files</h3>
|
<h3 class="section-bar">Required files</h3>
|
||||||
|
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["requires"].each do |requires| %>
|
<% values["requires"].each do |requires| %>
|
||||||
<%= href requires["aref"], requires["name"] %>
|
<%= href requires["aref"], requires["name"] %>
|
||||||
<% end # values["requires"] %>
|
<% end %><%# values["requires"] %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% if values["toc"] then %>
|
if values["toc"] then %>
|
||||||
<div id="contents-list">
|
<div id="contents-list">
|
||||||
<h3 class="section-bar">Contents</h3>
|
<h3 class="section-bar">Contents</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<% values["toc"].each do |toc| %>
|
<% values["toc"].each do |toc| %>
|
||||||
<li><a href="#<%= values["href"] %>"><%= values["secname"] %></a></li>
|
<li><a href="#<%= toc["href"] %>"><%= toc["secname"] %></a></li>
|
||||||
<% end # values["toc"] %>
|
<% end %><%# values["toc"] %>
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
@ -430,16 +429,14 @@ EOF
|
||||||
<h3 class="section-bar">Methods</h3>
|
<h3 class="section-bar">Methods</h3>
|
||||||
|
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["methods"].each do |methods| %>
|
<% values["methods"].each do |methods| %>
|
||||||
<%= href methods["aref"], methods["name"] %>
|
<%= href methods["aref"], methods["name"] %>
|
||||||
<% end # values["methods"] %>
|
<% end %><%# values["methods"] %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- if includes -->
|
<!-- if includes -->
|
||||||
<% if values["includes"] then %>
|
<% if values["includes"] then %>
|
||||||
<div id="includes">
|
<div id="includes">
|
||||||
|
@ -448,140 +445,137 @@ EOF
|
||||||
<div id="includes-list">
|
<div id="includes-list">
|
||||||
<% values["includes"].each do |includes| %>
|
<% values["includes"].each do |includes| %>
|
||||||
<span class="include-name"><%= href includes["aref"], includes["name"] %></span>
|
<span class="include-name"><%= href includes["aref"], includes["name"] %></span>
|
||||||
<% end # values["includes"] %>
|
<% end %><%# values["includes"] %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% values["sections"].each do |sections| %>
|
values["sections"].each do |sections| %>
|
||||||
<div id="section">
|
<div id="section">
|
||||||
<% if sections["sectitle"] then %>
|
<% if sections["sectitle"] then %>
|
||||||
<h2 class="section-title"><a name="<%= sections["secsequence"] %>"><%= sections["sectitle"] %></a></h2>
|
<h2 class="section-title"><a name="<%= sections["secsequence"] %>"><%= sections["sectitle"] %></a></h2>
|
||||||
<% if sections["seccomment"] then %>
|
<% if sections["seccomment"] then %>
|
||||||
<div class="section-comment">
|
<div class="section-comment">
|
||||||
<%= sections["seccomment"] %>
|
<%= sections["seccomment"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
<% end %>
|
end
|
||||||
|
|
||||||
<% if values["classlist"] then %>
|
if sections["classlist"] then %>
|
||||||
<div id="class-list">
|
<div id="class-list">
|
||||||
<h3 class="section-bar">Classes and Modules</h3>
|
<h3 class="section-bar">Classes and Modules</h3>
|
||||||
|
|
||||||
<%= values["classlist"] %>
|
<%= sections["classlist"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% if values["constants"] then %>
|
if sections["constants"] then %>
|
||||||
<div id="constants-list">
|
<div id="constants-list">
|
||||||
<h3 class="section-bar">Constants</h3>
|
<h3 class="section-bar">Constants</h3>
|
||||||
|
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<table summary="Constants">
|
<table summary="Constants">
|
||||||
<% values["constants"].each do |constants| %>
|
<% sections["constants"].each do |constants| %>
|
||||||
<tr class="top-aligned-row context-row">
|
<tr class="top-aligned-row context-row">
|
||||||
<td class="context-item-name"><%= constants["name"] %></td>
|
<td class="context-item-name"><%= constants["name"] %></td>
|
||||||
<td>=</td>
|
<td>=</td>
|
||||||
<td class="context-item-value"><%= constants["value"] %></td>
|
<td class="context-item-value"><%= constants["value"] %></td>
|
||||||
<% if values["desc"] then %>
|
<% if sections["desc"] then %>
|
||||||
<td width="3em"> </td>
|
<td width="3em"> </td>
|
||||||
<td class="context-item-desc"><%= constants["desc"] %></td>
|
<td class="context-item-desc"><%= constants["desc"] %></td>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tr>
|
</tr>
|
||||||
<% end # values["constants"] %>
|
<% end %><%# sections["constants"] %>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end
|
||||||
|
|
||||||
<% if values["aliases"] then %>
|
if sections["aliases"] then %>
|
||||||
<div id="aliases-list">
|
<div id="aliases-list">
|
||||||
<h3 class="section-bar">External Aliases</h3>
|
<h3 class="section-bar">External Aliases</h3>
|
||||||
|
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<table summary="aliases">
|
<table summary="aliases">
|
||||||
<% values["aliases"].each do |aliases| $stderr.puts({ :aliases => aliases }.inspect) %>
|
<% sections["aliases"].each do |aliases| %>
|
||||||
<tr class="top-aligned-row context-row">
|
<tr class="top-aligned-row context-row">
|
||||||
<td class="context-item-name"><%= values["old_name"] %></td>
|
<td class="context-item-name"><%= aliases["old_name"] %></td>
|
||||||
<td>-></td>
|
<td>-></td>
|
||||||
<td class="context-item-value"><%= values["new_name"] %></td>
|
<td class="context-item-value"><%= aliases["new_name"] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% if values["desc"] then %>
|
<% if aliases["desc"] then %>
|
||||||
<tr class="top-aligned-row context-row">
|
<tr class="top-aligned-row context-row">
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<td colspan="2" class="context-item-desc"><%= values["desc"] %></td>
|
<td colspan="2" class="context-item-desc"><%= aliases["desc"] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end
|
||||||
<% end # values["aliases"] %>
|
end %><%# sections["aliases"] %>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% if sections["attributes"] then %>
|
||||||
<% if values["attributes"] then %>
|
|
||||||
<div id="attribute-list">
|
<div id="attribute-list">
|
||||||
<h3 class="section-bar">Attributes</h3>
|
<h3 class="section-bar">Attributes</h3>
|
||||||
|
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<table>
|
<table>
|
||||||
<% values["attributes"].each do |attributes| $stderr.puts({ :attributes => attributes }.inspect) %>
|
<% sections["attributes"].each do |attribute| %>
|
||||||
<tr class="top-aligned-row context-row">
|
<tr class="top-aligned-row context-row">
|
||||||
<td class="context-item-name"><%= values["name"] %></td>
|
<td class="context-item-name"><%= attribute["name"] %></td>
|
||||||
<% if values["rw"] then %>
|
<% if attribute["rw"] then %>
|
||||||
<td class="context-item-value"> [<%= values["rw"] %>] </td>
|
<td class="context-item-value"> [<%= attribute["rw"] %>] </td>
|
||||||
<% end %>
|
<% end
|
||||||
<% unless values["rw"] then %>
|
unless attribute["rw"] then %>
|
||||||
<td class="context-item-value"> </td>
|
<td class="context-item-value"> </td>
|
||||||
<% end %>
|
<% end %>
|
||||||
<td class="context-item-desc"><%= values["a_desc"] %></td>
|
<td class="context-item-desc"><%= attribute["a_desc"] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end # values["attributes"] %>
|
<% end %><%# sections["attributes"] %>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- if method_list -->
|
<!-- if method_list -->
|
||||||
<% if sections["method_list"] then %>
|
<% if sections["method_list"] then %>
|
||||||
<div id="methods">
|
<div id="methods">
|
||||||
<% sections["method_list"].each do |method_list| %>
|
<% sections["method_list"].each do |method_list|
|
||||||
<% if method_list["methods"] then %>
|
if method_list["methods"] then %>
|
||||||
<h3 class="section-bar"><%= method_list["type"] %> <%= method_list["category"] %> methods</h3>
|
<h3 class="section-bar"><%= method_list["type"] %> <%= method_list["category"] %> methods</h3>
|
||||||
|
|
||||||
<% method_list["methods"].each do |methods| %>
|
<% method_list["methods"].each do |methods| %>
|
||||||
<div id="method-<%= methods["aref"] %>" class="method-detail">
|
<div id="method-<%= methods["aref"] %>" class="method-detail">
|
||||||
<a name="<%= methods["aref"] %>"></a>
|
<a name="<%= methods["aref"] %>"></a>
|
||||||
|
|
||||||
<div class="method-heading">
|
<div class="method-heading">
|
||||||
<% if methods["codeurl"] then %>
|
<% if methods["codeurl"] then %>
|
||||||
<a href="<%= methods["codeurl"] %>" target="Code" class="method-signature"
|
<a href="<%= methods["codeurl"] %>" target="Code" class="method-signature"
|
||||||
onclick="popupCode('<%= methods["codeurl"] %>');return false;">
|
onclick="popupCode('<%= methods["codeurl"] %>');return false;">
|
||||||
<% end %>
|
<% end
|
||||||
<% if methods["sourcecode"] then %>
|
if methods["sourcecode"] then %>
|
||||||
<a href="#<%= methods["aref"] %>" class="method-signature">
|
<a href="#<%= methods["aref"] %>" class="method-signature">
|
||||||
<% end %>
|
<% end
|
||||||
<% if methods["callseq"] then %>
|
if methods["callseq"] then %>
|
||||||
<span class="method-name"><%= methods["callseq"] %></span>
|
<span class="method-name"><%= methods["callseq"] %></span>
|
||||||
<% end %>
|
<% end
|
||||||
<% unless methods["callseq"] then %>
|
unless methods["callseq"] then %>
|
||||||
<span class="method-name"><%= methods["name"] %></span><span class="method-args"><%= methods["params"] %></span>
|
<span class="method-name"><%= methods["name"] %></span><span class="method-args"><%= methods["params"] %></span>
|
||||||
<% end %>
|
<% end
|
||||||
<% if methods["codeurl"] then %>
|
if methods["codeurl"] then %>
|
||||||
</a>
|
</a>
|
||||||
<% end %>
|
<% end
|
||||||
<% if methods["sourcecode"] then %>
|
if methods["sourcecode"] then %>
|
||||||
</a>
|
</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="method-description">
|
<div class="method-description">
|
||||||
<% if methods["m_desc"] then %>
|
<% if methods["m_desc"] then %>
|
||||||
<%= methods["m_desc"] %>
|
<%= methods["m_desc"] %>
|
||||||
<% end %>
|
<% end
|
||||||
<% if methods["sourcecode"] then %>
|
if methods["sourcecode"] then %>
|
||||||
<p><a class="source-toggle" href="#"
|
<p><a class="source-toggle" href="#"
|
||||||
onclick="toggleCode('<%= methods["aref"] %>-source');return false;">[Source]</a></p>
|
onclick="toggleCode('<%= methods["aref"] %>-source');return false;">[Source]</a></p>
|
||||||
<div class="method-source-code" id="<%= methods["aref"] %>-source">
|
<div class="method-source-code" id="<%= methods["aref"] %>-source">
|
||||||
|
@ -589,17 +583,17 @@ EOF
|
||||||
<%= methods["sourcecode"] %>
|
<%= methods["sourcecode"] %>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% end # method_list["methods"] %>
|
<% end %><%# method_list["methods"] %><%
|
||||||
<% end %>
|
end
|
||||||
<% end # sections["method_list"] %>
|
end %><%# sections["method_list"] %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["sections"] %>
|
<% end %><%# values["sections"] %>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
@ -663,7 +657,7 @@ EOF
|
||||||
<div id="index-entries">
|
<div id="index-entries">
|
||||||
<% values["entries"].each do |entries| %>
|
<% values["entries"].each do |entries| %>
|
||||||
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
||||||
<% end # values["entries"] %>
|
<% end %><%# values["entries"] %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -119,7 +119,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["requires"].each do |requires| %>
|
<% values["requires"].each do |requires| %>
|
||||||
<%= href requires["aref"], requires["name"] %>
|
<%= href requires["aref"], requires["name"] %>
|
||||||
<% end # values["requires"] %>
|
<% end %><%# values["requires"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["methods"].each do |methods| %>
|
<% values["methods"].each do |methods| %>
|
||||||
<%= href methods["aref"], methods["name"] %>,
|
<%= href methods["aref"], methods["name"] %>,
|
||||||
<% end # values["methods"] %>
|
<% end %><%# values["methods"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
<td class="attr-name"><%= attributes["name"] %></td>
|
<td class="attr-name"><%= attributes["name"] %></td>
|
||||||
<td><%= attributes["a_desc"] %></td>
|
<td><%= attributes["a_desc"] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end # sections["attributes"] %>
|
<% end %><%# sections["attributes"] %>
|
||||||
</table>
|
</table>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
|
|
||||||
<%= template_include %> <!-- method descriptions -->
|
<%= template_include %> <!-- method descriptions -->
|
||||||
|
|
||||||
<% end # values["sections"] %>
|
<% end %><%# values["sections"] %>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -221,7 +221,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
<% if infiles["cvsurl"] then %>
|
<% if infiles["cvsurl"] then %>
|
||||||
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
(<a href="<%= infiles["cvsurl"] %>"><acronym title="Concurrent Versioning System">CVS</acronym></a>)
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["infiles"] %>
|
<% end %><%# values["infiles"] %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% if values["parent"] then %>
|
<% if values["parent"] then %>
|
||||||
|
@ -250,7 +250,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
<div class="name-list">
|
<div class="name-list">
|
||||||
<% values["includes"].each do |includes| %>
|
<% values["includes"].each do |includes| %>
|
||||||
<span class="method-name"><%= href includes["aref"], includes["name"] %></span>
|
<span class="method-name"><%= href includes["aref"], includes["name"] %></span>
|
||||||
<% end # values["includes"] %>
|
<% end %><%# values["includes"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ body,td,p { font-family: <%= values["fonts"] %>;
|
||||||
This method is also aliased as
|
This method is also aliased as
|
||||||
<% values["aka"].each do |aka| $stderr.puts({ :aka => aka }.inspect) %>
|
<% values["aka"].each do |aka| $stderr.puts({ :aka => aka }.inspect) %>
|
||||||
<a href="<%= values["aref"] %>"><%= values["name"] %></a>
|
<a href="<%= values["aref"] %>"><%= values["name"] %></a>
|
||||||
<% end # values["aka"] %>
|
<% end %><%# values["aka"] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if values["sourcecode"] then %>
|
<% if values["sourcecode"] then %>
|
||||||
|
@ -293,9 +293,9 @@ This method is also aliased as
|
||||||
<%= values["sourcecode"] %>
|
<%= values["sourcecode"] %>
|
||||||
</pre>
|
</pre>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["methods"] %>
|
<% end %><%# values["methods"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # values["method_list"] %>
|
<% end %><%# values["method_list"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ div.banner {
|
||||||
<div class="banner"><%= values["list_title"] %></div>
|
<div class="banner"><%= values["list_title"] %></div>
|
||||||
<% values["entries"].each do |entries| %>
|
<% values["entries"].each do |entries| %>
|
||||||
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
<a href="<%= entries["href"] %>"><%= entries["name"] %></a><br />
|
||||||
<% end # values["entries"] %>
|
<% end %><%# values["entries"] %>
|
||||||
</body></html>
|
</body></html>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
<% unless requires["aref"] then %>
|
<% unless requires["aref"] then %>
|
||||||
<li><%= requires["name"] %></li>
|
<li><%= requires["name"] %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # files["requires"] %>
|
<% end %><%# files["requires"] %>
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
<% unless includes["aref"] then %>
|
<% unless includes["aref"] then %>
|
||||||
<li><%= includes["name"] %></li>
|
<li><%= includes["name"] %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # classes["includes"] %>
|
<% end %><%# classes["includes"] %>
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
<table>
|
<table>
|
||||||
<% sections["attributes"].each do |attributes| %>
|
<% sections["attributes"].each do |attributes| %>
|
||||||
<tr><td><%= attributes["name"] %></td><td><%= attributes["rw"] %></td><td><%= attributes["a_desc"] %></td></tr>
|
<tr><td><%= attributes["name"] %></td><td><%= attributes["rw"] %></td><td><%= attributes["a_desc"] %></td></tr>
|
||||||
<% end # sections["attributes"] %>
|
<% end %><%# sections["attributes"] %>
|
||||||
</table>
|
</table>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
@ -68,11 +68,11 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
<%= methods["sourcecode"] %>
|
<%= methods["sourcecode"] %>
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # method_list["methods"] %>
|
<% end %><%# method_list["methods"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # sections["method_list"] %>
|
<% end %><%# sections["method_list"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end # classes["sections"] %>
|
<% end %><%# classes["sections"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
<tr><td>Modified:</td><td><%= files["dtm_modified"] %></td></tr>
|
<tr><td>Modified:</td><td><%= files["dtm_modified"] %></td></tr>
|
||||||
</table>
|
</table>
|
||||||
} + CONTENTS_XML + %{
|
} + CONTENTS_XML + %{
|
||||||
<% end # values["files"] %>
|
<% end %><%# values["files"] %>
|
||||||
|
|
||||||
<% if values["classes"] then %>
|
<% if values["classes"] then %>
|
||||||
<h2>Classes</h2>
|
<h2>Classes</h2>
|
||||||
|
@ -107,11 +107,11 @@ module RDoc::Generator::HTML::ONE_PAGE_HTML
|
||||||
(in files
|
(in files
|
||||||
<% classes["infiles"].each do |infiles| %>
|
<% classes["infiles"].each do |infiles| %>
|
||||||
<%= href infiles["full_path_url"], infiles["full_path"] %>
|
<%= href infiles["full_path_url"], infiles["full_path"] %>
|
||||||
<% end # classes["infiles"] %>
|
<% end %><%# classes["infiles"] %>
|
||||||
)
|
)
|
||||||
<% end %>
|
<% end %>
|
||||||
} + CONTENTS_XML + %{
|
} + CONTENTS_XML + %{
|
||||||
<% end # values["classes"] %>
|
<% end %><%# values["classes"] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -45,7 +45,7 @@ class RDoc::Generator::RI
|
||||||
def process_class(from_class)
|
def process_class(from_class)
|
||||||
generate_class_info(from_class)
|
generate_class_info(from_class)
|
||||||
|
|
||||||
# now recurse into this classes constituent classes
|
# now recurse into this class' constituent classes
|
||||||
from_class.each_classmodule do |mod|
|
from_class.each_classmodule do |mod|
|
||||||
process_class(mod)
|
process_class(mod)
|
||||||
end
|
end
|
||||||
|
|
84
lib/rdoc/generator/texinfo.rb
Normal file
84
lib/rdoc/generator/texinfo.rb
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
require 'rdoc/rdoc'
|
||||||
|
require 'rdoc/generator'
|
||||||
|
require 'rdoc/markup/to_texinfo'
|
||||||
|
|
||||||
|
module RDoc
|
||||||
|
RDoc::GENERATORS['texinfo'] = RDoc::Generator.new("rdoc/generator/texinfo",
|
||||||
|
:Texinfo,
|
||||||
|
'texinfo')
|
||||||
|
module Generator
|
||||||
|
# This generates Texinfo files for viewing with GNU Info or Emacs
|
||||||
|
# from RDoc extracted from Ruby source files.
|
||||||
|
class Texinfo
|
||||||
|
# What should the .info file be named by default?
|
||||||
|
DEFAULT_INFO_FILENAME = 'rdoc.info'
|
||||||
|
|
||||||
|
include Generator::MarkUp
|
||||||
|
|
||||||
|
# Accept some options
|
||||||
|
def initialize(options)
|
||||||
|
@options = options
|
||||||
|
@options.inline_source = true
|
||||||
|
@options.op_name ||= 'rdoc.texinfo'
|
||||||
|
@options.formatter = ::RDoc::Markup::ToTexInfo.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate the +texinfo+ files
|
||||||
|
def generate(toplevels)
|
||||||
|
@toplevels = toplevels
|
||||||
|
@files, @classes = ::RDoc::Generator::Context.build_indicies(@toplevels,
|
||||||
|
@options)
|
||||||
|
|
||||||
|
(@files + @classes).each { |x| x.value_hash }
|
||||||
|
|
||||||
|
open(@options.op_name, 'w') do |f|
|
||||||
|
f.puts TexinfoTemplate.new('files' => @files,
|
||||||
|
'classes' => @classes,
|
||||||
|
'filename' => @options.op_name.gsub(/texinfo/, 'info'),
|
||||||
|
'title' => @options.title).render
|
||||||
|
end
|
||||||
|
# TODO: create info files and install?
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
# Factory? We don't need no stinkin' factory!
|
||||||
|
alias_method :for, :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Basically just a wrapper around ERB.
|
||||||
|
# Should probably use RDoc::TemplatePage instead
|
||||||
|
class TexinfoTemplate
|
||||||
|
BASE_DIR = ::File.expand_path(::File.dirname(__FILE__)) # have to calculate this when the file's loaded.
|
||||||
|
|
||||||
|
def initialize(values, file = 'texinfo.erb')
|
||||||
|
@v, @file = [values, file]
|
||||||
|
end
|
||||||
|
|
||||||
|
def template
|
||||||
|
::File.read(::File.join(BASE_DIR, 'texinfo', @file))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Go!
|
||||||
|
def render
|
||||||
|
ERB.new(template).result binding
|
||||||
|
end
|
||||||
|
|
||||||
|
def href(location, text)
|
||||||
|
text # TODO: how does texinfo do hyperlinks?
|
||||||
|
end
|
||||||
|
|
||||||
|
def target(name, text)
|
||||||
|
text # TODO: how do hyperlink targets work?
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: this is probably implemented elsewhere?
|
||||||
|
def method_prefix(section)
|
||||||
|
{ 'Class' => '.',
|
||||||
|
'Module' => '::',
|
||||||
|
'Instance' => '#',
|
||||||
|
}[section['category']]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
44
lib/rdoc/generator/texinfo/class.texinfo.erb
Normal file
44
lib/rdoc/generator/texinfo/class.texinfo.erb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
@node <%= @v['class']['full_name'].gsub(/::/, '-') %>
|
||||||
|
@chapter <%= @v['class']["classmod"] %> <%= @v['class']['full_name'] %>
|
||||||
|
|
||||||
|
<% if @v['class']["parent"] and @v['class']['par_url'] %>
|
||||||
|
Inherits <%= href @v['class']["par_url"], @v['class']["parent"] %><% end %>
|
||||||
|
|
||||||
|
<%= @v['class']["description"] %>
|
||||||
|
|
||||||
|
<% if @v['class']["includes"] %>
|
||||||
|
Includes
|
||||||
|
<% @v['class']["includes"].each do |include| %>
|
||||||
|
* <%= href include["aref"], include["name"] %>
|
||||||
|
<% end # @v['class']["includes"] %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @v['class']["sections"] %>
|
||||||
|
<% @v['class']["sections"].each do |section| %>
|
||||||
|
<% if section["attributes"] %>
|
||||||
|
Attributes
|
||||||
|
<% section["attributes"].each do |attributes| %>
|
||||||
|
* <%= attributes["name"] %> <%= attributes["rw"] %> <%= attributes["a_desc"] %>
|
||||||
|
<% end # section["attributes"] %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% @v['class']["sections"].each do |section| %>
|
||||||
|
<% if section["method_list"] %>
|
||||||
|
Methods
|
||||||
|
@menu
|
||||||
|
<% section["method_list"].each_with_index do |method_list, i| %>
|
||||||
|
<%= i %>
|
||||||
|
<% (method_list["methods"] || []).each do |method| %>
|
||||||
|
* <%= @v['class']['full_name'].gsub(/::/, '-') %><%= method_prefix method_list %><%= method['name'] %>::<% end %>
|
||||||
|
<% end %>
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
<% section["method_list"].each do |method_list| %>
|
||||||
|
<% (method_list["methods"] || []).uniq.each do |method| %>
|
||||||
|
<%= TexinfoTemplate.new(@v.merge({'method' => method, 'list' => method_list}),
|
||||||
|
'method.texinfo.erb').render %><% end %>
|
||||||
|
<% end # section["method_list"] %>
|
||||||
|
<% end %>
|
||||||
|
<% end # @v['class']["sections"] %>
|
||||||
|
<% end %>
|
6
lib/rdoc/generator/texinfo/file.texinfo.erb
Normal file
6
lib/rdoc/generator/texinfo/file.texinfo.erb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<% if false %>
|
||||||
|
<h2>File: <%= @v['file']["short_name"] %></h2>
|
||||||
|
Path: <%= @v['file']["full_path"] %>
|
||||||
|
|
||||||
|
<%= TexinfoTemplate.new(@v, 'content.texinfo.erb').render %>
|
||||||
|
<% end %>
|
6
lib/rdoc/generator/texinfo/method.texinfo.erb
Normal file
6
lib/rdoc/generator/texinfo/method.texinfo.erb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
@node <%= @v['class']['full_name'].gsub(/::/, '-') %><%= method_prefix @v['list'] %><%= @v['method']['name'] %>
|
||||||
|
@section <%= @v['class']["classmod"] %> <%= @v['class']['full_name'] %><%= method_prefix @v['list'] %><%= @v['method']['name'] %>
|
||||||
|
<%= @v['method']["type"] %> <%= @v['method']["category"] %> method:
|
||||||
|
<%= target @v['method']["aref"], @v['method']['callseq'] ||
|
||||||
|
@v['method']["name"] + @v['method']["params"] %>
|
||||||
|
<%= @v['method']["m_desc"] %>
|
28
lib/rdoc/generator/texinfo/texinfo.erb
Normal file
28
lib/rdoc/generator/texinfo/texinfo.erb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
\input texinfo @c -*-texinfo-*-
|
||||||
|
@c %**start of header
|
||||||
|
@setfilename <%= @v['filename'] %>
|
||||||
|
@settitle <%= @v['title'] %>
|
||||||
|
@c %**end of header
|
||||||
|
|
||||||
|
@contents @c TODO: whitespace is a mess... =\
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
|
@node Top
|
||||||
|
|
||||||
|
@top <%= @v['title'] %>
|
||||||
|
@end ifnottex
|
||||||
|
|
||||||
|
<% if @f = @v['files'].detect { |f| f.name =~ /Readme/i } %>
|
||||||
|
<%= @f.values['description'] %><% end %>
|
||||||
|
|
||||||
|
@menu
|
||||||
|
<% @v['classes'].each do |klass| %>
|
||||||
|
* <%= klass.name.gsub(/::/, '-') %>::<% end %>
|
||||||
|
@c TODO: add files
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
<% (@v['classes'] || []).each_with_index do |klass, i| %>
|
||||||
|
<%= TexinfoTemplate.new(@v.merge('class' => klass.values),
|
||||||
|
'class.texinfo.erb').render %><% end %>
|
||||||
|
|
||||||
|
@bye
|
69
lib/rdoc/known_classes.rb
Normal file
69
lib/rdoc/known_classes.rb
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
module RDoc
|
||||||
|
|
||||||
|
##
|
||||||
|
# Ruby's built-in classes, modules and exceptions
|
||||||
|
|
||||||
|
KNOWN_CLASSES = {
|
||||||
|
"rb_cArray" => "Array",
|
||||||
|
"rb_cBignum" => "Bignum",
|
||||||
|
"rb_cClass" => "Class",
|
||||||
|
"rb_cData" => "Data",
|
||||||
|
"rb_cDir" => "Dir",
|
||||||
|
"rb_cFalseClass" => "FalseClass",
|
||||||
|
"rb_cFile" => "File",
|
||||||
|
"rb_cFixnum" => "Fixnum",
|
||||||
|
"rb_cFloat" => "Float",
|
||||||
|
"rb_cHash" => "Hash",
|
||||||
|
"rb_cIO" => "IO",
|
||||||
|
"rb_cInteger" => "Integer",
|
||||||
|
"rb_cModule" => "Module",
|
||||||
|
"rb_cNilClass" => "NilClass",
|
||||||
|
"rb_cNumeric" => "Numeric",
|
||||||
|
"rb_cObject" => "Object",
|
||||||
|
"rb_cProc" => "Proc",
|
||||||
|
"rb_cRange" => "Range",
|
||||||
|
"rb_cRegexp" => "Regexp",
|
||||||
|
"rb_cRubyVM" => "RubyVM",
|
||||||
|
"rb_cString" => "String",
|
||||||
|
"rb_cStruct" => "Struct",
|
||||||
|
"rb_cSymbol" => "Symbol",
|
||||||
|
"rb_cThread" => "Thread",
|
||||||
|
"rb_cTime" => "Time",
|
||||||
|
"rb_cTrueClass" => "TrueClass",
|
||||||
|
|
||||||
|
"rb_eArgError" => "ArgError",
|
||||||
|
"rb_eEOFError" => "EOFError",
|
||||||
|
"rb_eException" => "Exception",
|
||||||
|
"rb_eFatal" => "Fatal",
|
||||||
|
"rb_eFloatDomainError" => "FloatDomainError",
|
||||||
|
"rb_eIOError" => "IOError",
|
||||||
|
"rb_eIndexError" => "IndexError",
|
||||||
|
"rb_eInterrupt" => "Interrupt",
|
||||||
|
"rb_eLoadError" => "LoadError",
|
||||||
|
"rb_eNameError" => "NameError",
|
||||||
|
"rb_eNoMemError" => "NoMemError",
|
||||||
|
"rb_eNotImpError" => "NotImpError",
|
||||||
|
"rb_eRangeError" => "RangeError",
|
||||||
|
"rb_eRuntimeError" => "RuntimeError",
|
||||||
|
"rb_eScriptError" => "ScriptError",
|
||||||
|
"rb_eSecurityError" => "SecurityError",
|
||||||
|
"rb_eSignal" => "Signal",
|
||||||
|
"rb_eStandardError" => "StandardError",
|
||||||
|
"rb_eSyntaxError" => "SyntaxError",
|
||||||
|
"rb_eSystemCallError" => "SystemCallError",
|
||||||
|
"rb_eSystemExit" => "SystemExit",
|
||||||
|
"rb_eTypeError" => "TypeError",
|
||||||
|
"rb_eZeroDivError" => "ZeroDivError",
|
||||||
|
|
||||||
|
"rb_mComparable" => "Comparable",
|
||||||
|
"rb_mEnumerable" => "Enumerable",
|
||||||
|
"rb_mErrno" => "Errno",
|
||||||
|
"rb_mFileTest" => "FileTest",
|
||||||
|
"rb_mGC" => "GC",
|
||||||
|
"rb_mKernel" => "Kernel",
|
||||||
|
"rb_mMath" => "Math",
|
||||||
|
"rb_mPrecision" => "Precision",
|
||||||
|
"rb_mProcess" => "Process"
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
|
@ -144,8 +144,6 @@ class RDoc::Markup::AttributeManager
|
||||||
add_html("b", :BOLD)
|
add_html("b", :BOLD)
|
||||||
add_html("tt", :TT)
|
add_html("tt", :TT)
|
||||||
add_html("code", :TT)
|
add_html("code", :TT)
|
||||||
|
|
||||||
add_special(/<!--(.*?)-->/, :COMMENT)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_word_pair(start, stop, name)
|
def add_word_pair(start, stop, name)
|
||||||
|
|
|
@ -11,8 +11,8 @@ class RDoc::Markup
|
||||||
attr_reader :level, :param, :txt
|
attr_reader :level, :param, :txt
|
||||||
attr_accessor :type
|
attr_accessor :type
|
||||||
|
|
||||||
######
|
##
|
||||||
# This is a simple factory system that lets us associate fragment
|
# This is a simple factory system that lets us associate fragement
|
||||||
# types (a string) with a subclass of fragment
|
# types (a string) with a subclass of fragment
|
||||||
|
|
||||||
TYPE_MAP = {}
|
TYPE_MAP = {}
|
||||||
|
|
|
@ -14,21 +14,25 @@ class RDoc::Markup::PreProcess
|
||||||
|
|
||||||
##
|
##
|
||||||
# Look for common options in a chunk of text. Options that we don't handle
|
# Look for common options in a chunk of text. Options that we don't handle
|
||||||
# are passed back to our caller as |directive, param|
|
# are yielded to the caller.
|
||||||
|
|
||||||
def handle(text)
|
def handle(text)
|
||||||
text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do
|
text.gsub!(/^([ \t]*#?[ \t]*):(\w+):([ \t]*)(.+)?\n/) do
|
||||||
|
next $& if $3.empty? and $4 and $4[0, 1] == ':'
|
||||||
|
|
||||||
prefix = $1
|
prefix = $1
|
||||||
directive = $2.downcase
|
directive = $2.downcase
|
||||||
param = $3
|
param = $4
|
||||||
|
|
||||||
case directive
|
case directive
|
||||||
when "include"
|
when 'include' then
|
||||||
filename = param.split[0]
|
filename = param.split[0]
|
||||||
include_file(filename, prefix)
|
include_file filename, prefix
|
||||||
|
|
||||||
else
|
else
|
||||||
yield(directive, param)
|
result = yield directive, param
|
||||||
|
result = "#{prefix}:#{directive}: #{param}\n" unless result
|
||||||
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
require 'rdoc/markup/formatter'
|
require 'rdoc/markup/formatter'
|
||||||
require 'rdoc/markup/fragments'
|
require 'rdoc/markup/fragments'
|
||||||
require 'rdoc/markup/inline'
|
require 'rdoc/markup/inline'
|
||||||
require 'rdoc/generator'
|
|
||||||
|
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
|
||||||
|
@ -21,6 +20,11 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
|
|
||||||
|
# @in_tt - tt nested levels count
|
||||||
|
# @tt_bit - cache
|
||||||
|
@in_tt = 0
|
||||||
|
@tt_bit = RDoc::Markup::Attribute.bitmap_for :TT
|
||||||
|
|
||||||
# external hyperlinks
|
# external hyperlinks
|
||||||
@markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
|
@markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
|
||||||
|
|
||||||
|
@ -30,6 +34,27 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
init_tags
|
init_tags
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Converts a target url to one that is relative to a given path
|
||||||
|
|
||||||
|
def self.gen_relative_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] do
|
||||||
|
from.shift
|
||||||
|
to.shift
|
||||||
|
end
|
||||||
|
|
||||||
|
from.fill ".."
|
||||||
|
from.concat to
|
||||||
|
from << to_file
|
||||||
|
File.join(*from)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Generate a hyperlink for url, labeled with text. Handle the
|
# Generate a hyperlink for url, labeled with text. Handle the
|
||||||
# special cases for img: and link: described under handle_special_HYPEDLINK
|
# special cases for img: and link: described under handle_special_HYPEDLINK
|
||||||
|
@ -48,7 +73,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
url = if path[0, 1] == '#' then # is this meaningful?
|
url = if path[0, 1] == '#' then # is this meaningful?
|
||||||
path
|
path
|
||||||
else
|
else
|
||||||
RDoc::Generator.gen_url @from_path, path
|
self.class.gen_relative_url @from_path, path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -87,6 +112,20 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
gen_url url, label
|
gen_url url, label
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# are we currently inside <tt> tags?
|
||||||
|
|
||||||
|
def in_tt?
|
||||||
|
@in_tt > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# is +tag+ a <tt> tag?
|
||||||
|
|
||||||
|
def tt?(tag)
|
||||||
|
tag.bit == @tt_bit
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Set up the standard mapping of attributes to HTML tags
|
# Set up the standard mapping of attributes to HTML tags
|
||||||
|
|
||||||
|
@ -216,6 +255,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
@attr_tags.each do |tag|
|
@attr_tags.each do |tag|
|
||||||
if attr_mask & tag.bit != 0
|
if attr_mask & tag.bit != 0
|
||||||
res << annotate(tag.on)
|
res << annotate(tag.on)
|
||||||
|
@in_tt += 1 if tt?(tag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -226,6 +266,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
|
|
||||||
@attr_tags.reverse_each do |tag|
|
@attr_tags.reverse_each do |tag|
|
||||||
if attr_mask & tag.bit != 0
|
if attr_mask & tag.bit != 0
|
||||||
|
@in_tt -= 1 if tt?(tag)
|
||||||
res << annotate(tag.off)
|
res << annotate(tag.off)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -251,27 +292,33 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def convert_string(item)
|
||||||
|
in_tt? ? convert_string_simple(item) : convert_string_fancy(item)
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_string_simple(item)
|
||||||
|
CGI.escapeHTML item
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# some of these patterns are taken from SmartyPants...
|
# some of these patterns are taken from SmartyPants...
|
||||||
|
|
||||||
def convert_string(item)
|
def convert_string_fancy(item)
|
||||||
CGI.escapeHTML(item).
|
|
||||||
|
|
||||||
# convert -- to em-dash, (-- to en-dash)
|
# convert -- to em-dash, (-- to en-dash)
|
||||||
gsub(/---?/, '—'). #gsub(/--/, '–').
|
item.gsub(/---?/, '—'). #gsub(/--/, '–').
|
||||||
|
|
||||||
# convert ... to elipsis (and make sure .... becomes .<elipsis>)
|
# convert ... to elipsis (and make sure .... becomes .<elipsis>)
|
||||||
gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…').
|
gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…').
|
||||||
|
|
||||||
# convert single closing quote
|
# convert single closing quote
|
||||||
gsub(%r{([^ \t\r\n\[\{\(])\'}, '\1’').
|
gsub(%r{([^ \t\r\n\[\{\(])\'}, '\1’'). # }
|
||||||
gsub(%r{\'(?=\W|s\b)}, '’').
|
gsub(%r{\'(?=\W|s\b)}, '’').
|
||||||
|
|
||||||
# convert single opening quote
|
# convert single opening quote
|
||||||
gsub(/'/, '‘').
|
gsub(/'/, '‘').
|
||||||
|
|
||||||
# convert double closing quote
|
# convert double closing quote
|
||||||
gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}, '\1”').
|
gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}, '\1”'). # }
|
||||||
|
|
||||||
# convert double opening quote
|
# convert double opening quote
|
||||||
gsub(/'/, '“').
|
gsub(/'/, '“').
|
||||||
|
@ -281,7 +328,6 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||||
|
|
||||||
# convert and registered trademark
|
# convert and registered trademark
|
||||||
gsub(/\(r\)/, '®')
|
gsub(/\(r\)/, '®')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_special(special)
|
def convert_special(special)
|
||||||
|
|
|
@ -14,6 +14,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
||||||
# correct relative paths for any hyperlinks that we find
|
# correct relative paths for any hyperlinks that we find
|
||||||
|
|
||||||
def initialize(from_path, context, show_hash)
|
def initialize(from_path, context, show_hash)
|
||||||
|
raise ArgumentError, 'from_path cannot be nil' if from_path.nil?
|
||||||
super()
|
super()
|
||||||
|
|
||||||
# class names, variable names, or instance variables
|
# class names, variable names, or instance variables
|
||||||
|
@ -47,28 +48,43 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
||||||
def handle_special_CROSSREF(special)
|
def handle_special_CROSSREF(special)
|
||||||
name = special.text
|
name = special.text
|
||||||
|
|
||||||
|
return name if name =~ /\A[a-z]*\z/
|
||||||
|
|
||||||
return @seen[name] if @seen.include? name
|
return @seen[name] if @seen.include? name
|
||||||
|
|
||||||
if name[0,1] == '#' then
|
if name[0, 1] == '#' then
|
||||||
lookup = name[1..-1]
|
lookup = name[1..-1]
|
||||||
name = lookup unless @show_hash
|
name = lookup unless @show_hash
|
||||||
else
|
else
|
||||||
lookup = name
|
lookup = name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Find class, module, or method in class or module.
|
# Find class, module, or method in class or module.
|
||||||
if /([A-Z]\w*)[.\#](\w+[!?=]?)/ =~ lookup then
|
#
|
||||||
|
# Do not, however, use an if/elsif/else chain to do so. Instead, test
|
||||||
|
# each possible pattern until one matches. The reason for this is that a
|
||||||
|
# string like "YAML.txt" could be the txt() class method of class YAML (in
|
||||||
|
# which case it would match the first pattern, which splits the string
|
||||||
|
# into container and method components and looks up both) or a filename
|
||||||
|
# (in which case it would match the last pattern, which just checks
|
||||||
|
# whether the string as a whole is a known symbol).
|
||||||
|
|
||||||
|
if /([A-Z][\w:]*)[.\#](\w+[!?=]?)/ =~ lookup then
|
||||||
container = $1
|
container = $1
|
||||||
method = $2
|
method = $2
|
||||||
ref = @context.find_symbol container, method
|
ref = @context.find_symbol container, method
|
||||||
elsif /([A-Za-z]\w*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup then
|
|
||||||
container = $1
|
|
||||||
method = $2
|
|
||||||
ref = @context.find_symbol container, method
|
|
||||||
else
|
|
||||||
ref = @context.find_symbol lookup
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if !ref and
|
||||||
|
/([A-Za-z][\w:]*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup then
|
||||||
|
container = $1
|
||||||
|
method = $2
|
||||||
|
ref = @context.find_symbol container, method
|
||||||
|
end
|
||||||
|
|
||||||
|
ref = @context.find_symbol lookup unless ref
|
||||||
|
|
||||||
out = if lookup =~ /^\\/ then
|
out = if lookup =~ /^\\/ then
|
||||||
$'
|
$'
|
||||||
elsif ref and ref.document_self then
|
elsif ref and ref.document_self then
|
||||||
|
|
69
lib/rdoc/markup/to_texinfo.rb
Normal file
69
lib/rdoc/markup/to_texinfo.rb
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
require 'rdoc/markup/formatter'
|
||||||
|
require 'rdoc/markup/fragments'
|
||||||
|
require 'rdoc/markup/inline'
|
||||||
|
|
||||||
|
require 'rdoc/markup'
|
||||||
|
require 'rdoc/markup/formatter'
|
||||||
|
|
||||||
|
##
|
||||||
|
# Convert SimpleMarkup to basic TexInfo format
|
||||||
|
#
|
||||||
|
# TODO: WTF is AttributeManager for?
|
||||||
|
#
|
||||||
|
class RDoc::Markup::ToTexInfo < RDoc::Markup::Formatter
|
||||||
|
|
||||||
|
def start_accepting
|
||||||
|
@text = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_accepting
|
||||||
|
@text.join("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_paragraph(attributes, text)
|
||||||
|
@text << format(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_verbatim(attributes, text)
|
||||||
|
@text << "@verb{|#{format(text)}|}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_heading(attributes, text)
|
||||||
|
heading = ['@majorheading', '@chapheading'][text.head_level - 1] || '@heading'
|
||||||
|
@text << "#{heading}{#{format(text)}}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_list_start(attributes, text)
|
||||||
|
@text << '@itemize @bullet'
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_list_end(attributes, text)
|
||||||
|
@text << '@end itemize'
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_list_item(attributes, text)
|
||||||
|
@text << "@item\n#{format(text)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_blank_line(attributes, text)
|
||||||
|
@text << "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept_rule(attributes, text)
|
||||||
|
@text << '-----'
|
||||||
|
end
|
||||||
|
|
||||||
|
def format(text)
|
||||||
|
text.txt.
|
||||||
|
gsub(/@/, "@@").
|
||||||
|
gsub(/\{/, "@{").
|
||||||
|
gsub(/\}/, "@}").
|
||||||
|
# gsub(/,/, "@,"). # technically only required in cross-refs
|
||||||
|
gsub(/\+([\w]+)\+/, "@code{\\1}").
|
||||||
|
gsub(/\<tt\>([^<]+)\<\/tt\>/, "@code{\\1}").
|
||||||
|
gsub(/\*([\w]+)\*/, "@strong{\\1}").
|
||||||
|
gsub(/\<b\>([^<]+)\<\/b\>/, "@strong{\\1}").
|
||||||
|
gsub(/_([\w]+)_/, "@emph{\\1}").
|
||||||
|
gsub(/\<em\>([^<]+)\<\/em\>/, "@emph{\\1}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -39,7 +39,7 @@ class RDoc::Options
|
||||||
##
|
##
|
||||||
# Pattern for additional attr_... style methods
|
# Pattern for additional attr_... style methods
|
||||||
|
|
||||||
attr_reader :extra_accessors
|
attr_accessor :extra_accessors
|
||||||
|
|
||||||
##
|
##
|
||||||
# Should we draw fileboxes in diagrams
|
# Should we draw fileboxes in diagrams
|
||||||
|
@ -61,6 +61,11 @@ class RDoc::Options
|
||||||
|
|
||||||
attr_accessor :generator
|
attr_accessor :generator
|
||||||
|
|
||||||
|
##
|
||||||
|
# Formatter to mark up text with
|
||||||
|
|
||||||
|
attr_accessor :formatter
|
||||||
|
|
||||||
##
|
##
|
||||||
# image format for diagrams
|
# image format for diagrams
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@ class RDoc::Options
|
||||||
##
|
##
|
||||||
# The name to use for the output
|
# The name to use for the output
|
||||||
|
|
||||||
attr_reader :op_name
|
attr_accessor :op_name
|
||||||
|
|
||||||
##
|
##
|
||||||
# Are we promiscuous about showing module contents across multiple files
|
# Are we promiscuous about showing module contents across multiple files
|
||||||
|
@ -105,7 +110,7 @@ class RDoc::Options
|
||||||
##
|
##
|
||||||
# Don't display progress as we process the files
|
# Don't display progress as we process the files
|
||||||
|
|
||||||
attr_reader :quiet
|
attr_accessor :quiet
|
||||||
|
|
||||||
##
|
##
|
||||||
# Array of directories to search for files to satisfy an :include:
|
# Array of directories to search for files to satisfy an :include:
|
||||||
|
@ -175,7 +180,6 @@ class RDoc::Options
|
||||||
@extra_accessor_flags = {}
|
@extra_accessor_flags = {}
|
||||||
@promiscuous = false
|
@promiscuous = false
|
||||||
@force_update = false
|
@force_update = false
|
||||||
@title = "RDoc Documentation"
|
|
||||||
|
|
||||||
@css = nil
|
@css = nil
|
||||||
@webcvs = nil
|
@webcvs = nil
|
||||||
|
@ -513,6 +517,8 @@ Usage: #{opt.program_name} [options] [names...]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT']
|
||||||
|
|
||||||
opts.parse! argv
|
opts.parse! argv
|
||||||
|
|
||||||
@files = argv.dup
|
@files = argv.dup
|
||||||
|
|
109
lib/rdoc/parser.rb
Normal file
109
lib/rdoc/parser.rb
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
require 'rdoc'
|
||||||
|
require 'rdoc/code_objects'
|
||||||
|
require 'rdoc/markup/preprocess'
|
||||||
|
require 'rdoc/stats'
|
||||||
|
|
||||||
|
##
|
||||||
|
# A parser is simple a class that implements
|
||||||
|
#
|
||||||
|
# #initialize(file_name, body, options)
|
||||||
|
#
|
||||||
|
# and
|
||||||
|
#
|
||||||
|
# #scan
|
||||||
|
#
|
||||||
|
# The initialize method takes a file name to be used, the body of the file,
|
||||||
|
# and an RDoc::Options object. The scan method is then called to return an
|
||||||
|
# appropriately parsed TopLevel code object.
|
||||||
|
#
|
||||||
|
# The ParseFactory is used to redirect to the correct parser given a
|
||||||
|
# filename extension. This magic works because individual parsers have to
|
||||||
|
# register themselves with us as they are loaded in. The do this using the
|
||||||
|
# following incantation
|
||||||
|
#
|
||||||
|
# require "rdoc/parser"
|
||||||
|
#
|
||||||
|
# class RDoc::Parser::Xyz < RDoc::Parser
|
||||||
|
# parse_files_matching /\.xyz$/ # <<<<
|
||||||
|
#
|
||||||
|
# def initialize(file_name, body, options)
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def scan
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Just to make life interesting, if we suspect a plain text file, we also
|
||||||
|
# look for a shebang line just in case it's a potential shell script
|
||||||
|
|
||||||
|
class RDoc::Parser
|
||||||
|
|
||||||
|
@parsers = []
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr_reader :parsers
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_writer :progress
|
||||||
|
|
||||||
|
##
|
||||||
|
# Alias an extension to another extension. After this call, files ending
|
||||||
|
# "new_ext" will be parsed using the same parser as "old_ext"
|
||||||
|
|
||||||
|
def self.alias_extension(old_ext, new_ext)
|
||||||
|
parser = can_parse "xxx.#{old_ext}"
|
||||||
|
return false unless parser
|
||||||
|
|
||||||
|
RDoc::Parser.parsers.unshift [/\.#{new_ext}$/, parser.last]
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return a parser that can handle a particular extension
|
||||||
|
|
||||||
|
def self.can_parse(file_name)
|
||||||
|
RDoc::Parser.parsers.find { |regexp, parser| regexp =~ file_name }.last
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Find the correct parser for a particular file name. Return a SimpleParser
|
||||||
|
# for ones that we don't know
|
||||||
|
|
||||||
|
def self.for(top_level, file_name, body, options, stats)
|
||||||
|
# If no extension, look for shebang
|
||||||
|
if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)} then
|
||||||
|
shebang = $1
|
||||||
|
case shebang
|
||||||
|
when %r{env\s+ruby}, %r{/ruby}
|
||||||
|
file_name = "dummy.rb"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parser = can_parse file_name
|
||||||
|
|
||||||
|
parser.new top_level, file_name, body, options, stats
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Record which file types this parser can understand.
|
||||||
|
|
||||||
|
def self.parse_files_matching(regexp)
|
||||||
|
RDoc::Parser.parsers.unshift [regexp, self]
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(top_level, file_name, content, options, stats)
|
||||||
|
@top_level = top_level
|
||||||
|
@file_name = file_name
|
||||||
|
@content = content
|
||||||
|
@options = options
|
||||||
|
@stats = stats
|
||||||
|
@progress = $stderr unless options.quiet
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'rdoc/parser/simple'
|
||||||
|
|
666
lib/rdoc/parser/c.rb
Normal file
666
lib/rdoc/parser/c.rb
Normal file
|
@ -0,0 +1,666 @@
|
||||||
|
require 'rdoc/parser'
|
||||||
|
require 'rdoc/known_classes'
|
||||||
|
|
||||||
|
##
|
||||||
|
# We attempt to parse C extension files. Basically we look for
|
||||||
|
# the standard patterns that you find in extensions: <tt>rb_define_class,
|
||||||
|
# rb_define_method</tt> and so on. We also try to find the corresponding
|
||||||
|
# C source for the methods and extract comments, but if we fail
|
||||||
|
# we don't worry too much.
|
||||||
|
#
|
||||||
|
# The comments associated with a Ruby method are extracted from the C
|
||||||
|
# comment block associated with the routine that _implements_ that
|
||||||
|
# method, that is to say the method whose name is given in the
|
||||||
|
# <tt>rb_define_method</tt> call. For example, you might write:
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * Returns a new array that is a one-dimensional flattening of this
|
||||||
|
# * array (recursively). That is, for every element that is an array,
|
||||||
|
# * extract its elements into the new array.
|
||||||
|
# *
|
||||||
|
# * s = [ 1, 2, 3 ] #=> [1, 2, 3]
|
||||||
|
# * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
|
||||||
|
# * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
|
||||||
|
# * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||||
|
# */
|
||||||
|
# static VALUE
|
||||||
|
# rb_ary_flatten(ary)
|
||||||
|
# VALUE ary;
|
||||||
|
# {
|
||||||
|
# ary = rb_obj_dup(ary);
|
||||||
|
# rb_ary_flatten_bang(ary);
|
||||||
|
# return ary;
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# void
|
||||||
|
# Init_Array()
|
||||||
|
# {
|
||||||
|
# ...
|
||||||
|
# rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
|
||||||
|
#
|
||||||
|
# Here RDoc will determine from the rb_define_method line that there's a
|
||||||
|
# method called "flatten" in class Array, and will look for the implementation
|
||||||
|
# in the method rb_ary_flatten. It will then use the comment from that
|
||||||
|
# method in the HTML output. This method must be in the same source file
|
||||||
|
# as the rb_define_method.
|
||||||
|
#
|
||||||
|
# C classes can be diagrammed (see /tc/dl/ruby/ruby/error.c), and RDoc
|
||||||
|
# integrates C and Ruby source into one tree
|
||||||
|
#
|
||||||
|
# The comment blocks may include special directives:
|
||||||
|
#
|
||||||
|
# [Document-class: <i>name</i>]
|
||||||
|
# This comment block is documentation for the given class. Use this
|
||||||
|
# when the <tt>Init_xxx</tt> method is not named after the class.
|
||||||
|
#
|
||||||
|
# [Document-method: <i>name</i>]
|
||||||
|
# This comment documents the named method. Use when RDoc cannot
|
||||||
|
# automatically find the method from it's declaration
|
||||||
|
#
|
||||||
|
# [call-seq: <i>text up to an empty line</i>]
|
||||||
|
# Because C source doesn't give descripive names to Ruby-level parameters,
|
||||||
|
# you need to document the calling sequence explicitly
|
||||||
|
#
|
||||||
|
# In addition, RDoc assumes by default that the C method implementing a
|
||||||
|
# Ruby function is in the same source file as the rb_define_method call.
|
||||||
|
# If this isn't the case, add the comment:
|
||||||
|
#
|
||||||
|
# rb_define_method(....); // in: filename
|
||||||
|
#
|
||||||
|
# As an example, we might have an extension that defines multiple classes
|
||||||
|
# in its Init_xxx method. We could document them using
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * Document-class: MyClass
|
||||||
|
# *
|
||||||
|
# * Encapsulate the writing and reading of the configuration
|
||||||
|
# * file. ...
|
||||||
|
# */
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * Document-method: read_value
|
||||||
|
# *
|
||||||
|
# * call-seq:
|
||||||
|
# * cfg.read_value(key) -> value
|
||||||
|
# * cfg.read_value(key} { |key| } -> value
|
||||||
|
# *
|
||||||
|
# * Return the value corresponding to +key+ from the configuration.
|
||||||
|
# * In the second form, if the key isn't found, invoke the
|
||||||
|
# * block and return its value.
|
||||||
|
# */
|
||||||
|
|
||||||
|
class RDoc::Parser::C < RDoc::Parser
|
||||||
|
|
||||||
|
parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
|
||||||
|
|
||||||
|
attr_writer :progress
|
||||||
|
|
||||||
|
@@enclosure_classes = {}
|
||||||
|
@@known_bodies = {}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Prepare to parse a C file
|
||||||
|
|
||||||
|
def initialize(top_level, file_name, content, options, stats)
|
||||||
|
super
|
||||||
|
|
||||||
|
@known_classes = RDoc::KNOWN_CLASSES.dup
|
||||||
|
@content = handle_tab_width handle_ifdefs_in(@content)
|
||||||
|
@classes = Hash.new
|
||||||
|
@file_dir = File.dirname(@file_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_aliases
|
||||||
|
@content.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do
|
||||||
|
|var_name, new_name, old_name|
|
||||||
|
@stats.num_methods += 1
|
||||||
|
class_name = @known_classes[var_name] || var_name
|
||||||
|
class_obj = find_class(var_name, class_name)
|
||||||
|
|
||||||
|
class_obj.add_alias RDoc::Alias.new("", old_name, new_name, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_classes
|
||||||
|
@content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
|
||||||
|
|var_name, class_name|
|
||||||
|
handle_class_module(var_name, "module", class_name, nil, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# The '.' lets us handle SWIG-generated files
|
||||||
|
@content.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
|
||||||
|
\(
|
||||||
|
\s*"(\w+)",
|
||||||
|
\s*(\w+)\s*
|
||||||
|
\)/mx) do |var_name, class_name, parent|
|
||||||
|
handle_class_module(var_name, "class", class_name, parent, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
|
||||||
|
|var_name, class_name, parent|
|
||||||
|
parent = nil if parent == "0"
|
||||||
|
handle_class_module(var_name, "class", class_name, parent, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(/(\w+)\s* = \s*rb_define_module_under\s*
|
||||||
|
\(
|
||||||
|
\s*(\w+),
|
||||||
|
\s*"(\w+)"
|
||||||
|
\s*\)/mx) do |var_name, in_module, class_name|
|
||||||
|
handle_class_module(var_name, "module", class_name, nil, in_module)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s*
|
||||||
|
\(
|
||||||
|
\s*(\w+),
|
||||||
|
\s*"(\w+)",
|
||||||
|
\s*(\w+)\s*
|
||||||
|
\s*\)/mx) do |var_name, in_module, class_name, parent|
|
||||||
|
handle_class_module(var_name, "class", class_name, parent, in_module)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_constants
|
||||||
|
@content.scan(%r{\Wrb_define_
|
||||||
|
(
|
||||||
|
variable |
|
||||||
|
readonly_variable |
|
||||||
|
const |
|
||||||
|
global_const |
|
||||||
|
)
|
||||||
|
\s*\(
|
||||||
|
(?:\s*(\w+),)?
|
||||||
|
\s*"(\w+)",
|
||||||
|
\s*(.*?)\s*\)\s*;
|
||||||
|
}xm) do |type, var_name, const_name, definition|
|
||||||
|
var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
|
||||||
|
handle_constants(type, var_name, const_name, definition)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Look for includes of the form:
|
||||||
|
#
|
||||||
|
# rb_include_module(rb_cArray, rb_mEnumerable);
|
||||||
|
|
||||||
|
def do_includes
|
||||||
|
@content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
|
||||||
|
if cls = @classes[c]
|
||||||
|
m = @known_classes[m] || m
|
||||||
|
cls.add_include RDoc::Include.new(m, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_methods
|
||||||
|
@content.scan(%r{rb_define_
|
||||||
|
(
|
||||||
|
singleton_method |
|
||||||
|
method |
|
||||||
|
module_function |
|
||||||
|
private_method
|
||||||
|
)
|
||||||
|
\s*\(\s*([\w\.]+),
|
||||||
|
\s*"([^"]+)",
|
||||||
|
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
||||||
|
\s*(-?\w+)\s*\)
|
||||||
|
(?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
|
||||||
|
}xm) do
|
||||||
|
|type, var_name, meth_name, meth_body, param_count, source_file|
|
||||||
|
|
||||||
|
# Ignore top-object and weird struct.c dynamic stuff
|
||||||
|
next if var_name == "ruby_top_self"
|
||||||
|
next if var_name == "nstr"
|
||||||
|
next if var_name == "envtbl"
|
||||||
|
next if var_name == "argf" # it'd be nice to handle this one
|
||||||
|
|
||||||
|
var_name = "rb_cObject" if var_name == "rb_mKernel"
|
||||||
|
handle_method(type, var_name, meth_name,
|
||||||
|
meth_body, param_count, source_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(%r{rb_define_attr\(
|
||||||
|
\s*([\w\.]+),
|
||||||
|
\s*"([^"]+)",
|
||||||
|
\s*(\d+),
|
||||||
|
\s*(\d+)\s*\);
|
||||||
|
}xm) do |var_name, attr_name, attr_reader, attr_writer|
|
||||||
|
#var_name = "rb_cObject" if var_name == "rb_mKernel"
|
||||||
|
handle_attr(var_name, attr_name,
|
||||||
|
attr_reader.to_i != 0,
|
||||||
|
attr_writer.to_i != 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(%r{rb_define_global_function\s*\(
|
||||||
|
\s*"([^"]+)",
|
||||||
|
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
||||||
|
\s*(-?\w+)\s*\)
|
||||||
|
(?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
|
||||||
|
}xm) do |meth_name, meth_body, param_count, source_file|
|
||||||
|
handle_method("method", "rb_mKernel", meth_name,
|
||||||
|
meth_body, param_count, source_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
@content.scan(/define_filetest_function\s*\(
|
||||||
|
\s*"([^"]+)",
|
||||||
|
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
||||||
|
\s*(-?\w+)\s*\)/xm) do
|
||||||
|
|meth_name, meth_body, param_count|
|
||||||
|
|
||||||
|
handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count)
|
||||||
|
handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_attr_comment(attr_name)
|
||||||
|
if @content =~ %r{((?>/\*.*?\*/\s+))
|
||||||
|
rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi
|
||||||
|
$1
|
||||||
|
elsif @content =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m
|
||||||
|
$1
|
||||||
|
else
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Find the C code corresponding to a Ruby method
|
||||||
|
|
||||||
|
def find_body(meth_name, meth_obj, body, quiet = false)
|
||||||
|
case body
|
||||||
|
when %r"((?>/\*.*?\*/\s*))(?:static\s+)?VALUE\s+#{meth_name}
|
||||||
|
\s*(\([^)]*\))\s*\{.*?^\}"xm
|
||||||
|
comment, params = $1, $2
|
||||||
|
body_text = $&
|
||||||
|
|
||||||
|
remove_private_comments(comment) if comment
|
||||||
|
|
||||||
|
# see if we can find the whole body
|
||||||
|
|
||||||
|
re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}'
|
||||||
|
if Regexp.new(re, Regexp::MULTILINE).match(body)
|
||||||
|
body_text = $&
|
||||||
|
end
|
||||||
|
|
||||||
|
# The comment block may have been overridden with a 'Document-method'
|
||||||
|
# block. This happens in the interpreter when multiple methods are
|
||||||
|
# vectored through to the same C method but those methods are logically
|
||||||
|
# distinct (for example Kernel.hash and Kernel.object_id share the same
|
||||||
|
# implementation
|
||||||
|
|
||||||
|
override_comment = find_override_comment(meth_obj.name)
|
||||||
|
comment = override_comment if override_comment
|
||||||
|
|
||||||
|
find_modifiers(comment, meth_obj) if comment
|
||||||
|
|
||||||
|
# meth_obj.params = params
|
||||||
|
meth_obj.start_collecting_tokens
|
||||||
|
meth_obj.add_token(RDoc::RubyToken::Token.new(1,1).set_text(body_text))
|
||||||
|
meth_obj.comment = mangle_comment(comment)
|
||||||
|
when %r{((?>/\*.*?\*/\s*))^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
|
||||||
|
comment = $1
|
||||||
|
find_body($2, meth_obj, body, true)
|
||||||
|
find_modifiers(comment, meth_obj)
|
||||||
|
meth_obj.comment = mangle_comment(comment) + meth_obj.comment
|
||||||
|
when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
|
||||||
|
unless find_body($1, meth_obj, body, true)
|
||||||
|
warn "No definition for #{meth_name}" unless quiet
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
|
# No body, but might still have an override comment
|
||||||
|
comment = find_override_comment(meth_obj.name)
|
||||||
|
|
||||||
|
if comment
|
||||||
|
find_modifiers(comment, meth_obj)
|
||||||
|
meth_obj.comment = mangle_comment(comment)
|
||||||
|
else
|
||||||
|
warn "No definition for #{meth_name}" unless quiet
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_class(raw_name, name)
|
||||||
|
unless @classes[raw_name]
|
||||||
|
if raw_name =~ /^rb_m/
|
||||||
|
container = @top_level.add_module RDoc::NormalModule, name
|
||||||
|
else
|
||||||
|
container = @top_level.add_class RDoc::NormalClass, name, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
container.record_location @top_level
|
||||||
|
@classes[raw_name] = container
|
||||||
|
end
|
||||||
|
@classes[raw_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Look for class or module documentation above Init_+class_name+(void),
|
||||||
|
# in a Document-class +class_name+ (or module) comment or above an
|
||||||
|
# rb_define_class (or module). If a comment is supplied above a matching
|
||||||
|
# Init_ and a rb_define_class the Init_ comment is used.
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * This is a comment for Foo
|
||||||
|
# */
|
||||||
|
# Init_Foo(void) {
|
||||||
|
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * Document-class: Foo
|
||||||
|
# * This is a comment for Foo
|
||||||
|
# */
|
||||||
|
# Init_foo(void) {
|
||||||
|
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# /*
|
||||||
|
# * This is a comment for Foo
|
||||||
|
# */
|
||||||
|
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
||||||
|
|
||||||
|
def find_class_comment(class_name, class_meth)
|
||||||
|
comment = nil
|
||||||
|
if @content =~ %r{((?>/\*.*?\*/\s+))
|
||||||
|
(static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)\)}xmi
|
||||||
|
comment = $1
|
||||||
|
elsif @content =~ %r{Document-(class|module):\s#{class_name}\s*?\n((?>.*?\*/))}m
|
||||||
|
comment = $2
|
||||||
|
else
|
||||||
|
if @content =~ /rb_define_(class|module)/m then
|
||||||
|
class_name = class_name.split("::").last
|
||||||
|
comments = []
|
||||||
|
@content.split(/(\/\*.*?\*\/)\s*?\n/m).each_with_index do |chunk, index|
|
||||||
|
comments[index] = chunk
|
||||||
|
if chunk =~ /rb_define_(class|module).*?"(#{class_name})"/m then
|
||||||
|
comment = comments[index-1]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class_meth.comment = mangle_comment(comment) if comment
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds a comment matching +type+ and +const_name+ either above the
|
||||||
|
# comment or in the matching Document- section.
|
||||||
|
|
||||||
|
def find_const_comment(type, const_name)
|
||||||
|
if @content =~ %r{((?>^\s*/\*.*?\*/\s+))
|
||||||
|
rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi
|
||||||
|
$1
|
||||||
|
elsif @content =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m
|
||||||
|
$1
|
||||||
|
else
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# If the comment block contains a section that looks like:
|
||||||
|
#
|
||||||
|
# call-seq:
|
||||||
|
# Array.new
|
||||||
|
# Array.new(10)
|
||||||
|
#
|
||||||
|
# use it for the parameters.
|
||||||
|
|
||||||
|
def find_modifiers(comment, meth_obj)
|
||||||
|
if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or
|
||||||
|
comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '')
|
||||||
|
meth_obj.document_self = false
|
||||||
|
end
|
||||||
|
if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or
|
||||||
|
comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '')
|
||||||
|
seq = $1
|
||||||
|
seq.gsub!(/^\s*\*\s*/, '')
|
||||||
|
meth_obj.call_seq = seq
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_override_comment(meth_name)
|
||||||
|
name = Regexp.escape(meth_name)
|
||||||
|
if @content =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m
|
||||||
|
$1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_attr(var_name, attr_name, reader, writer)
|
||||||
|
rw = ''
|
||||||
|
if reader
|
||||||
|
#@stats.num_methods += 1
|
||||||
|
rw << 'R'
|
||||||
|
end
|
||||||
|
if writer
|
||||||
|
#@stats.num_methods += 1
|
||||||
|
rw << 'W'
|
||||||
|
end
|
||||||
|
|
||||||
|
class_name = @known_classes[var_name]
|
||||||
|
|
||||||
|
return unless class_name
|
||||||
|
|
||||||
|
class_obj = find_class(var_name, class_name)
|
||||||
|
|
||||||
|
if class_obj
|
||||||
|
comment = find_attr_comment(attr_name)
|
||||||
|
unless comment.empty?
|
||||||
|
comment = mangle_comment(comment)
|
||||||
|
end
|
||||||
|
att = RDoc::Attr.new '', attr_name, rw, comment
|
||||||
|
class_obj.add_attribute(att)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_class_module(var_name, class_mod, class_name, parent, in_module)
|
||||||
|
progress(class_mod[0, 1])
|
||||||
|
|
||||||
|
parent_name = @known_classes[parent] || parent
|
||||||
|
|
||||||
|
if in_module
|
||||||
|
enclosure = @classes[in_module] || @@enclosure_classes[in_module]
|
||||||
|
unless enclosure
|
||||||
|
if enclosure = @known_classes[in_module]
|
||||||
|
handle_class_module(in_module, (/^rb_m/ =~ in_module ? "module" : "class"),
|
||||||
|
enclosure, nil, nil)
|
||||||
|
enclosure = @classes[in_module]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unless enclosure
|
||||||
|
warn("Enclosing class/module '#{in_module}' for " +
|
||||||
|
"#{class_mod} #{class_name} not known")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
enclosure = @top_level
|
||||||
|
end
|
||||||
|
|
||||||
|
if class_mod == "class"
|
||||||
|
cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
|
||||||
|
@stats.num_classes += 1
|
||||||
|
else
|
||||||
|
cm = enclosure.add_module RDoc::NormalModule, class_name
|
||||||
|
@stats.num_modules += 1
|
||||||
|
end
|
||||||
|
cm.record_location(enclosure.toplevel)
|
||||||
|
|
||||||
|
find_class_comment(cm.full_name, cm)
|
||||||
|
@classes[var_name] = cm
|
||||||
|
@@enclosure_classes[var_name] = cm
|
||||||
|
@known_classes[var_name] = cm.full_name
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Adds constant comments. By providing some_value: at the start ofthe
|
||||||
|
# comment you can override the C value of the comment to give a friendly
|
||||||
|
# definition.
|
||||||
|
#
|
||||||
|
# /* 300: The perfect score in bowling */
|
||||||
|
# rb_define_const(cFoo, "PERFECT", INT2FIX(300);
|
||||||
|
#
|
||||||
|
# Will override +INT2FIX(300)+ with the value +300+ in the output RDoc.
|
||||||
|
# Values may include quotes and escaped colons (\:).
|
||||||
|
|
||||||
|
def handle_constants(type, var_name, const_name, definition)
|
||||||
|
#@stats.num_constants += 1
|
||||||
|
class_name = @known_classes[var_name]
|
||||||
|
|
||||||
|
return unless class_name
|
||||||
|
|
||||||
|
class_obj = find_class(var_name, class_name)
|
||||||
|
|
||||||
|
unless class_obj
|
||||||
|
warn("Enclosing class/module '#{const_name}' for not known")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
comment = find_const_comment(type, const_name)
|
||||||
|
|
||||||
|
# In the case of rb_define_const, the definition and comment are in
|
||||||
|
# "/* definition: comment */" form. The literal ':' and '\' characters
|
||||||
|
# can be escaped with a backslash.
|
||||||
|
if type.downcase == 'const' then
|
||||||
|
elements = mangle_comment(comment).split(':')
|
||||||
|
if elements.nil? or elements.empty? then
|
||||||
|
con = RDoc::Constant.new(const_name, definition,
|
||||||
|
mangle_comment(comment))
|
||||||
|
else
|
||||||
|
new_definition = elements[0..-2].join(':')
|
||||||
|
if new_definition.empty? then # Default to literal C definition
|
||||||
|
new_definition = definition
|
||||||
|
else
|
||||||
|
new_definition.gsub!("\:", ":")
|
||||||
|
new_definition.gsub!("\\", '\\')
|
||||||
|
end
|
||||||
|
new_definition.sub!(/\A(\s+)/, '')
|
||||||
|
new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}"
|
||||||
|
con = RDoc::Constant.new(const_name, new_definition,
|
||||||
|
mangle_comment(new_comment))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
con = RDoc::Constant.new const_name, definition, mangle_comment(comment)
|
||||||
|
end
|
||||||
|
|
||||||
|
class_obj.add_constant(con)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Removes #ifdefs that would otherwise confuse us
|
||||||
|
|
||||||
|
def handle_ifdefs_in(body)
|
||||||
|
body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_method(type, var_name, meth_name, meth_body, param_count,
|
||||||
|
source_file = nil)
|
||||||
|
progress(".")
|
||||||
|
|
||||||
|
@stats.num_methods += 1
|
||||||
|
class_name = @known_classes[var_name]
|
||||||
|
|
||||||
|
return unless class_name
|
||||||
|
|
||||||
|
class_obj = find_class(var_name, class_name)
|
||||||
|
|
||||||
|
if class_obj
|
||||||
|
if meth_name == "initialize"
|
||||||
|
meth_name = "new"
|
||||||
|
type = "singleton_method"
|
||||||
|
end
|
||||||
|
meth_obj = RDoc::AnyMethod.new("", meth_name)
|
||||||
|
meth_obj.singleton =
|
||||||
|
%w{singleton_method module_function}.include?(type)
|
||||||
|
|
||||||
|
p_count = (Integer(param_count) rescue -1)
|
||||||
|
|
||||||
|
if p_count < 0
|
||||||
|
meth_obj.params = "(...)"
|
||||||
|
elsif p_count == 0
|
||||||
|
meth_obj.params = "()"
|
||||||
|
else
|
||||||
|
meth_obj.params = "(" + (1..p_count).map{|i| "p#{i}"}.join(", ") + ")"
|
||||||
|
end
|
||||||
|
|
||||||
|
if source_file
|
||||||
|
file_name = File.join(@file_dir, source_file)
|
||||||
|
body = (@@known_bodies[source_file] ||= File.read(file_name))
|
||||||
|
else
|
||||||
|
body = @content
|
||||||
|
end
|
||||||
|
if find_body(meth_body, meth_obj, body) and meth_obj.document_self
|
||||||
|
class_obj.add_method(meth_obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_tab_width(body)
|
||||||
|
if /\t/ =~ body
|
||||||
|
tab_width = @options.tab_width
|
||||||
|
body.split(/\n/).map do |line|
|
||||||
|
1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #`
|
||||||
|
line
|
||||||
|
end .join("\n")
|
||||||
|
else
|
||||||
|
body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Remove the /*'s and leading asterisks from C comments
|
||||||
|
|
||||||
|
def mangle_comment(comment)
|
||||||
|
comment.sub!(%r{/\*+}) { " " * $&.length }
|
||||||
|
comment.sub!(%r{\*+/}) { " " * $&.length }
|
||||||
|
comment.gsub!(/^[ \t]*\*/m) { " " * $&.length }
|
||||||
|
comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def progress(char)
|
||||||
|
unless @options.quiet
|
||||||
|
@progress.print(char)
|
||||||
|
@progress.flush
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Removes lines that are commented out that might otherwise get picked up
|
||||||
|
# when scanning for classes and methods
|
||||||
|
|
||||||
|
def remove_commented_out_lines
|
||||||
|
@content.gsub!(%r{//.*rb_define_}, '//')
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_private_comments(comment)
|
||||||
|
comment.gsub!(/\/?\*--(.*?)\/?\*\+\+/m, '')
|
||||||
|
comment.sub!(/\/?\*--.*/m, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Extract the classes/modules and methods from a C file and return the
|
||||||
|
# corresponding top-level object
|
||||||
|
|
||||||
|
def scan
|
||||||
|
remove_commented_out_lines
|
||||||
|
do_classes
|
||||||
|
do_constants
|
||||||
|
do_methods
|
||||||
|
do_includes
|
||||||
|
do_aliases
|
||||||
|
@top_level
|
||||||
|
end
|
||||||
|
|
||||||
|
def warn(msg)
|
||||||
|
$stderr.puts
|
||||||
|
$stderr.puts msg
|
||||||
|
$stderr.flush
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
1837
lib/rdoc/parser/f95.rb
Normal file
1837
lib/rdoc/parser/f95.rb
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
38
lib/rdoc/parser/simple.rb
Normal file
38
lib/rdoc/parser/simple.rb
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
require 'rdoc/parser'
|
||||||
|
|
||||||
|
##
|
||||||
|
# Parse a non-source file. We basically take the whole thing as one big
|
||||||
|
# comment. If the first character in the file is '#', we strip leading pound
|
||||||
|
# signs.
|
||||||
|
|
||||||
|
class RDoc::Parser::Simple < RDoc::Parser
|
||||||
|
|
||||||
|
parse_files_matching(//)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Prepare to parse a plain file
|
||||||
|
|
||||||
|
def initialize(top_level, file_name, content, options, stats)
|
||||||
|
super
|
||||||
|
|
||||||
|
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||||
|
|
||||||
|
preprocess.handle @content do |directive, param|
|
||||||
|
warn "Unrecognized directive '#{directive}' in #{@file_name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Extract the file contents and attach them to the toplevel as a comment
|
||||||
|
|
||||||
|
def scan
|
||||||
|
@top_level.comment = remove_private_comments(@content)
|
||||||
|
@top_level
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_private_comments(comment)
|
||||||
|
comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -1,775 +0,0 @@
|
||||||
# Classes and modules built in to the interpreter. We need
|
|
||||||
# these to define superclasses of user objects
|
|
||||||
|
|
||||||
require "rdoc/code_objects"
|
|
||||||
require "rdoc/parsers/parserfactory"
|
|
||||||
require "rdoc/rdoc"
|
|
||||||
|
|
||||||
module RDoc
|
|
||||||
|
|
||||||
##
|
|
||||||
# Ruby's built-in classes.
|
|
||||||
|
|
||||||
KNOWN_CLASSES = {
|
|
||||||
"rb_cObject" => "Object",
|
|
||||||
"rb_cArray" => "Array",
|
|
||||||
"rb_cBignum" => "Bignum",
|
|
||||||
"rb_cClass" => "Class",
|
|
||||||
"rb_cDir" => "Dir",
|
|
||||||
"rb_cData" => "Data",
|
|
||||||
"rb_cFalseClass" => "FalseClass",
|
|
||||||
"rb_cFile" => "File",
|
|
||||||
"rb_cFixnum" => "Fixnum",
|
|
||||||
"rb_cFloat" => "Float",
|
|
||||||
"rb_cHash" => "Hash",
|
|
||||||
"rb_cInteger" => "Integer",
|
|
||||||
"rb_cIO" => "IO",
|
|
||||||
"rb_cModule" => "Module",
|
|
||||||
"rb_cNilClass" => "NilClass",
|
|
||||||
"rb_cNumeric" => "Numeric",
|
|
||||||
"rb_cProc" => "Proc",
|
|
||||||
"rb_cRange" => "Range",
|
|
||||||
"rb_cRegexp" => "Regexp",
|
|
||||||
"rb_cString" => "String",
|
|
||||||
"rb_cSymbol" => "Symbol",
|
|
||||||
"rb_cThread" => "Thread",
|
|
||||||
"rb_cTime" => "Time",
|
|
||||||
"rb_cTrueClass" => "TrueClass",
|
|
||||||
"rb_cStruct" => "Struct",
|
|
||||||
"rb_cRubyVM" => "RubyVM",
|
|
||||||
"rb_eException" => "Exception",
|
|
||||||
"rb_eStandardError" => "StandardError",
|
|
||||||
"rb_eSystemExit" => "SystemExit",
|
|
||||||
"rb_eInterrupt" => "Interrupt",
|
|
||||||
"rb_eSignal" => "Signal",
|
|
||||||
"rb_eFatal" => "Fatal",
|
|
||||||
"rb_eArgError" => "ArgError",
|
|
||||||
"rb_eEOFError" => "EOFError",
|
|
||||||
"rb_eIndexError" => "IndexError",
|
|
||||||
"rb_eRangeError" => "RangeError",
|
|
||||||
"rb_eIOError" => "IOError",
|
|
||||||
"rb_eRuntimeError" => "RuntimeError",
|
|
||||||
"rb_eSecurityError" => "SecurityError",
|
|
||||||
"rb_eSystemCallError" => "SystemCallError",
|
|
||||||
"rb_eTypeError" => "TypeError",
|
|
||||||
"rb_eZeroDivError" => "ZeroDivError",
|
|
||||||
"rb_eNotImpError" => "NotImpError",
|
|
||||||
"rb_eNoMemError" => "NoMemError",
|
|
||||||
"rb_eFloatDomainError" => "FloatDomainError",
|
|
||||||
"rb_eScriptError" => "ScriptError",
|
|
||||||
"rb_eNameError" => "NameError",
|
|
||||||
"rb_eSyntaxError" => "SyntaxError",
|
|
||||||
"rb_eLoadError" => "LoadError",
|
|
||||||
|
|
||||||
"rb_mKernel" => "Kernel",
|
|
||||||
"rb_mComparable" => "Comparable",
|
|
||||||
"rb_mEnumerable" => "Enumerable",
|
|
||||||
"rb_mPrecision" => "Precision",
|
|
||||||
"rb_mErrno" => "Errno",
|
|
||||||
"rb_mFileTest" => "FileTest",
|
|
||||||
"rb_mGC" => "GC",
|
|
||||||
"rb_mMath" => "Math",
|
|
||||||
"rb_mProcess" => "Process"
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# We attempt to parse C extension files. Basically we look for
|
|
||||||
# the standard patterns that you find in extensions: <tt>rb_define_class,
|
|
||||||
# rb_define_method</tt> and so on. We also try to find the corresponding
|
|
||||||
# C source for the methods and extract comments, but if we fail
|
|
||||||
# we don't worry too much.
|
|
||||||
#
|
|
||||||
# The comments associated with a Ruby method are extracted from the C
|
|
||||||
# comment block associated with the routine that _implements_ that
|
|
||||||
# method, that is to say the method whose name is given in the
|
|
||||||
# <tt>rb_define_method</tt> call. For example, you might write:
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * Returns a new array that is a one-dimensional flattening of this
|
|
||||||
# * array (recursively). That is, for every element that is an array,
|
|
||||||
# * extract its elements into the new array.
|
|
||||||
# *
|
|
||||||
# * s = [ 1, 2, 3 ] #=> [1, 2, 3]
|
|
||||||
# * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
|
|
||||||
# * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
|
|
||||||
# * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
||||||
# */
|
|
||||||
# static VALUE
|
|
||||||
# rb_ary_flatten(ary)
|
|
||||||
# VALUE ary;
|
|
||||||
# {
|
|
||||||
# ary = rb_obj_dup(ary);
|
|
||||||
# rb_ary_flatten_bang(ary);
|
|
||||||
# return ary;
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# ...
|
|
||||||
#
|
|
||||||
# void
|
|
||||||
# Init_Array()
|
|
||||||
# {
|
|
||||||
# ...
|
|
||||||
# rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
|
|
||||||
#
|
|
||||||
# Here RDoc will determine from the rb_define_method line that there's a
|
|
||||||
# method called "flatten" in class Array, and will look for the implementation
|
|
||||||
# in the method rb_ary_flatten. It will then use the comment from that
|
|
||||||
# method in the HTML output. This method must be in the same source file
|
|
||||||
# as the rb_define_method.
|
|
||||||
#
|
|
||||||
# C classes can be diagrammed (see /tc/dl/ruby/ruby/error.c), and RDoc
|
|
||||||
# integrates C and Ruby source into one tree
|
|
||||||
#
|
|
||||||
# The comment blocks may include special directives:
|
|
||||||
#
|
|
||||||
# [Document-class: <i>name</i>]
|
|
||||||
# This comment block is documentation for the given class. Use this
|
|
||||||
# when the <tt>Init_xxx</tt> method is not named after the class.
|
|
||||||
#
|
|
||||||
# [Document-method: <i>name</i>]
|
|
||||||
# This comment documents the named method. Use when RDoc cannot
|
|
||||||
# automatically find the method from it's declaration
|
|
||||||
#
|
|
||||||
# [call-seq: <i>text up to an empty line</i>]
|
|
||||||
# Because C source doesn't give descriptive names to Ruby-level parameters,
|
|
||||||
# you need to document the calling sequence explicitly
|
|
||||||
#
|
|
||||||
# In addition, RDoc assumes by default that the C method implementing a
|
|
||||||
# Ruby function is in the same source file as the rb_define_method call.
|
|
||||||
# If this isn't the case, add the comment
|
|
||||||
#
|
|
||||||
# rb_define_method(....); // in: filename
|
|
||||||
#
|
|
||||||
# As an example, we might have an extension that defines multiple classes
|
|
||||||
# in its Init_xxx method. We could document them using
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * Document-class: MyClass
|
|
||||||
# *
|
|
||||||
# * Encapsulate the writing and reading of the configuration
|
|
||||||
# * file. ...
|
|
||||||
# */
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * Document-method: read_value
|
|
||||||
# *
|
|
||||||
# * call-seq:
|
|
||||||
# * cfg.read_value(key) -> value
|
|
||||||
# * cfg.read_value(key} { |key| } -> value
|
|
||||||
# *
|
|
||||||
# * Return the value corresponding to +key+ from the configuration.
|
|
||||||
# * In the second form, if the key isn't found, invoke the
|
|
||||||
# * block and return its value.
|
|
||||||
# */
|
|
||||||
#
|
|
||||||
|
|
||||||
class C_Parser
|
|
||||||
|
|
||||||
attr_writer :progress
|
|
||||||
|
|
||||||
extend ParserFactory
|
|
||||||
parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
|
|
||||||
|
|
||||||
@@enclosure_classes = {}
|
|
||||||
@@known_bodies = {}
|
|
||||||
|
|
||||||
# prepare to parse a C file
|
|
||||||
def initialize(top_level, file_name, body, options, stats)
|
|
||||||
@known_classes = KNOWN_CLASSES.dup
|
|
||||||
@options = options
|
|
||||||
@body = handle_tab_width(handle_ifdefs_in(body))
|
|
||||||
@stats = stats
|
|
||||||
@top_level = top_level
|
|
||||||
@classes = Hash.new
|
|
||||||
@file_dir = File.dirname(file_name)
|
|
||||||
@progress = $stderr unless @options.quiet
|
|
||||||
end
|
|
||||||
|
|
||||||
# Extract the classes/modules and methods from a C file
|
|
||||||
# and return the corresponding top-level object
|
|
||||||
def scan
|
|
||||||
remove_commented_out_lines
|
|
||||||
do_classes
|
|
||||||
do_constants
|
|
||||||
do_methods
|
|
||||||
do_includes
|
|
||||||
do_aliases
|
|
||||||
@top_level
|
|
||||||
end
|
|
||||||
|
|
||||||
#######
|
|
||||||
private
|
|
||||||
#######
|
|
||||||
|
|
||||||
def progress(char)
|
|
||||||
unless @options.quiet
|
|
||||||
@progress.print(char)
|
|
||||||
@progress.flush
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def warn(msg)
|
|
||||||
$stderr.puts
|
|
||||||
$stderr.puts msg
|
|
||||||
$stderr.flush
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_private_comments(comment)
|
|
||||||
comment.gsub!(/\/?\*--(.*?)\/?\*\+\+/m, '')
|
|
||||||
comment.sub!(/\/?\*--.*/m, '')
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# removes lines that are commented out that might otherwise get picked up
|
|
||||||
# when scanning for classes and methods
|
|
||||||
|
|
||||||
def remove_commented_out_lines
|
|
||||||
@body.gsub!(%r{//.*rb_define_}, '//')
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_class_module(var_name, class_mod, class_name, parent, in_module)
|
|
||||||
progress(class_mod[0, 1])
|
|
||||||
|
|
||||||
parent_name = @known_classes[parent] || parent
|
|
||||||
|
|
||||||
if in_module
|
|
||||||
enclosure = @classes[in_module] || @@enclosure_classes[in_module]
|
|
||||||
unless enclosure
|
|
||||||
if enclosure = @known_classes[in_module]
|
|
||||||
handle_class_module(in_module, (/^rb_m/ =~ in_module ? "module" : "class"),
|
|
||||||
enclosure, nil, nil)
|
|
||||||
enclosure = @classes[in_module]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
unless enclosure
|
|
||||||
warn("Enclosing class/module '#{in_module}' for " +
|
|
||||||
"#{class_mod} #{class_name} not known")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
else
|
|
||||||
enclosure = @top_level
|
|
||||||
end
|
|
||||||
|
|
||||||
if class_mod == "class"
|
|
||||||
cm = enclosure.add_class(NormalClass, class_name, parent_name)
|
|
||||||
@stats.num_classes += 1
|
|
||||||
else
|
|
||||||
cm = enclosure.add_module(NormalModule, class_name)
|
|
||||||
@stats.num_modules += 1
|
|
||||||
end
|
|
||||||
cm.record_location(enclosure.toplevel)
|
|
||||||
|
|
||||||
find_class_comment(cm.full_name, cm)
|
|
||||||
@classes[var_name] = cm
|
|
||||||
@@enclosure_classes[var_name] = cm
|
|
||||||
@known_classes[var_name] = cm.full_name
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Look for class or module documentation above Init_+class_name+(void),
|
|
||||||
# in a Document-class +class_name+ (or module) comment or above an
|
|
||||||
# rb_define_class (or module). If a comment is supplied above a matching
|
|
||||||
# Init_ and a rb_define_class the Init_ comment is used.
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * This is a comment for Foo
|
|
||||||
# */
|
|
||||||
# Init_Foo(void) {
|
|
||||||
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * Document-class: Foo
|
|
||||||
# * This is a comment for Foo
|
|
||||||
# */
|
|
||||||
# Init_foo(void) {
|
|
||||||
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# /*
|
|
||||||
# * This is a comment for Foo
|
|
||||||
# */
|
|
||||||
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
||||||
|
|
||||||
def find_class_comment(class_name, class_meth)
|
|
||||||
comment = nil
|
|
||||||
if @body =~ %r{((?>/\*.*?\*/\s+))
|
|
||||||
(static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)\)}xmi
|
|
||||||
comment = $1
|
|
||||||
elsif @body =~ %r{Document-(class|module):\s#{class_name}\s*?\n((?>.*?\*/))}m
|
|
||||||
comment = $2
|
|
||||||
else
|
|
||||||
if @body =~ /rb_define_(class|module)/m then
|
|
||||||
class_name = class_name.split("::").last
|
|
||||||
comments = []
|
|
||||||
@body.split(/(\/\*.*?\*\/)\s*?\n/m).each_with_index do |chunk, index|
|
|
||||||
comments[index] = chunk
|
|
||||||
if chunk =~ /rb_define_(class|module).*?"(#{class_name})"/m then
|
|
||||||
comment = comments[index-1]
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class_meth.comment = mangle_comment(comment) if comment
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def do_classes
|
|
||||||
@body.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
|
|
||||||
|var_name, class_name|
|
|
||||||
handle_class_module(var_name, "module", class_name, nil, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# The '.' lets us handle SWIG-generated files
|
|
||||||
@body.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
|
|
||||||
\(
|
|
||||||
\s*"(\w+)",
|
|
||||||
\s*(\w+)\s*
|
|
||||||
\)/mx) do
|
|
||||||
|
|
||||||
|var_name, class_name, parent|
|
|
||||||
handle_class_module(var_name, "class", class_name, parent, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
|
|
||||||
|var_name, class_name, parent|
|
|
||||||
parent = nil if parent == "0"
|
|
||||||
handle_class_module(var_name, "class", class_name, parent, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(/(\w+)\s* = \s*rb_define_module_under\s*
|
|
||||||
\(
|
|
||||||
\s*(\w+),
|
|
||||||
\s*"(\w+)"
|
|
||||||
\s*\)/mx) do
|
|
||||||
|
|
||||||
|var_name, in_module, class_name|
|
|
||||||
handle_class_module(var_name, "module", class_name, nil, in_module)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s*
|
|
||||||
\(
|
|
||||||
\s*(\w+),
|
|
||||||
\s*"(\w+)",
|
|
||||||
\s*(\w+)\s*
|
|
||||||
\s*\)/mx) do
|
|
||||||
|
|
||||||
|var_name, in_module, class_name, parent|
|
|
||||||
handle_class_module(var_name, "class", class_name, parent, in_module)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
|
|
||||||
def do_constants
|
|
||||||
@body.scan(%r{\Wrb_define_
|
|
||||||
(
|
|
||||||
variable |
|
|
||||||
readonly_variable |
|
|
||||||
const |
|
|
||||||
global_const |
|
|
||||||
)
|
|
||||||
\s*\(
|
|
||||||
(?:\s*(\w+),)?
|
|
||||||
\s*"(\w+)",
|
|
||||||
\s*(.*?)\s*\)\s*;
|
|
||||||
}xm) do
|
|
||||||
|
|
||||||
|type, var_name, const_name, definition|
|
|
||||||
var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
|
|
||||||
handle_constants(type, var_name, const_name, definition)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def do_methods
|
|
||||||
|
|
||||||
@body.scan(%r{rb_define_
|
|
||||||
(
|
|
||||||
singleton_method |
|
|
||||||
method |
|
|
||||||
module_function |
|
|
||||||
private_method
|
|
||||||
)
|
|
||||||
\s*\(\s*([\w\.]+),
|
|
||||||
\s*"([^"]+)",
|
|
||||||
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
|
||||||
\s*(-?\w+)\s*\)
|
|
||||||
(?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
|
|
||||||
}xm) do
|
|
||||||
|type, var_name, meth_name, meth_body, param_count, source_file|
|
|
||||||
#"
|
|
||||||
|
|
||||||
# Ignore top-object and weird struct.c dynamic stuff
|
|
||||||
next if var_name == "ruby_top_self"
|
|
||||||
next if var_name == "nstr"
|
|
||||||
next if var_name == "envtbl"
|
|
||||||
next if var_name == "argf" # it'd be nice to handle this one
|
|
||||||
|
|
||||||
var_name = "rb_cObject" if var_name == "rb_mKernel"
|
|
||||||
handle_method(type, var_name, meth_name,
|
|
||||||
meth_body, param_count, source_file)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(%r{rb_define_attr\(
|
|
||||||
\s*([\w\.]+),
|
|
||||||
\s*"([^"]+)",
|
|
||||||
\s*(\d+),
|
|
||||||
\s*(\d+)\s*\);
|
|
||||||
}xm) do #"
|
|
||||||
|var_name, attr_name, attr_reader, attr_writer|
|
|
||||||
|
|
||||||
#var_name = "rb_cObject" if var_name == "rb_mKernel"
|
|
||||||
handle_attr(var_name, attr_name,
|
|
||||||
attr_reader.to_i != 0,
|
|
||||||
attr_writer.to_i != 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(%r{rb_define_global_function\s*\(
|
|
||||||
\s*"([^"]+)",
|
|
||||||
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
|
||||||
\s*(-?\w+)\s*\)
|
|
||||||
(?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
|
|
||||||
}xm) do #"
|
|
||||||
|meth_name, meth_body, param_count, source_file|
|
|
||||||
handle_method("method", "rb_mKernel", meth_name,
|
|
||||||
meth_body, param_count, source_file)
|
|
||||||
end
|
|
||||||
|
|
||||||
@body.scan(/define_filetest_function\s*\(
|
|
||||||
\s*"([^"]+)",
|
|
||||||
\s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
|
|
||||||
\s*(-?\w+)\s*\)/xm) do #"
|
|
||||||
|meth_name, meth_body, param_count|
|
|
||||||
|
|
||||||
handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count)
|
|
||||||
handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def do_aliases
|
|
||||||
@body.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do
|
|
||||||
|var_name, new_name, old_name|
|
|
||||||
@stats.num_methods += 1
|
|
||||||
class_name = @known_classes[var_name] || var_name
|
|
||||||
class_obj = find_class(var_name, class_name)
|
|
||||||
|
|
||||||
class_obj.add_alias(Alias.new("", old_name, new_name, ""))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Adds constant comments. By providing some_value: at the start ofthe
|
|
||||||
# comment you can override the C value of the comment to give a friendly
|
|
||||||
# definition.
|
|
||||||
#
|
|
||||||
# /* 300: The perfect score in bowling */
|
|
||||||
# rb_define_const(cFoo, "PERFECT", INT2FIX(300);
|
|
||||||
#
|
|
||||||
# Will override +INT2FIX(300)+ with the value +300+ in the output RDoc.
|
|
||||||
# Values may include quotes and escaped colons (\:).
|
|
||||||
|
|
||||||
def handle_constants(type, var_name, const_name, definition)
|
|
||||||
#@stats.num_constants += 1
|
|
||||||
class_name = @known_classes[var_name]
|
|
||||||
|
|
||||||
return unless class_name
|
|
||||||
|
|
||||||
class_obj = find_class(var_name, class_name)
|
|
||||||
|
|
||||||
unless class_obj
|
|
||||||
warn("Enclosing class/module '#{const_name}' for not known")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
comment = find_const_comment(type, const_name)
|
|
||||||
|
|
||||||
# In the case of rb_define_const, the definition and comment are in
|
|
||||||
# "/* definition: comment */" form. The literal ':' and '\' characters
|
|
||||||
# can be escaped with a backslash.
|
|
||||||
if type.downcase == 'const' then
|
|
||||||
elements = mangle_comment(comment).split(':')
|
|
||||||
if elements.nil? or elements.empty? then
|
|
||||||
con = Constant.new(const_name, definition, mangle_comment(comment))
|
|
||||||
else
|
|
||||||
new_definition = elements[0..-2].join(':')
|
|
||||||
if new_definition.empty? then # Default to literal C definition
|
|
||||||
new_definition = definition
|
|
||||||
else
|
|
||||||
new_definition.gsub!("\:", ":")
|
|
||||||
new_definition.gsub!("\\", '\\')
|
|
||||||
end
|
|
||||||
new_definition.sub!(/\A(\s+)/, '')
|
|
||||||
new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}"
|
|
||||||
con = Constant.new(const_name, new_definition,
|
|
||||||
mangle_comment(new_comment))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
con = Constant.new(const_name, definition, mangle_comment(comment))
|
|
||||||
end
|
|
||||||
|
|
||||||
class_obj.add_constant(con)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Finds a comment matching +type+ and +const_name+ either above the
|
|
||||||
# comment or in the matching Document- section.
|
|
||||||
|
|
||||||
def find_const_comment(type, const_name)
|
|
||||||
if @body =~ %r{((?>^\s*/\*.*?\*/\s+))
|
|
||||||
rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi
|
|
||||||
$1
|
|
||||||
elsif @body =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m
|
|
||||||
$1
|
|
||||||
else
|
|
||||||
''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
|
|
||||||
def handle_attr(var_name, attr_name, reader, writer)
|
|
||||||
rw = ''
|
|
||||||
if reader
|
|
||||||
#@stats.num_methods += 1
|
|
||||||
rw << 'R'
|
|
||||||
end
|
|
||||||
if writer
|
|
||||||
#@stats.num_methods += 1
|
|
||||||
rw << 'W'
|
|
||||||
end
|
|
||||||
|
|
||||||
class_name = @known_classes[var_name]
|
|
||||||
|
|
||||||
return unless class_name
|
|
||||||
|
|
||||||
class_obj = find_class(var_name, class_name)
|
|
||||||
|
|
||||||
if class_obj
|
|
||||||
comment = find_attr_comment(attr_name)
|
|
||||||
unless comment.empty?
|
|
||||||
comment = mangle_comment(comment)
|
|
||||||
end
|
|
||||||
att = Attr.new('', attr_name, rw, comment)
|
|
||||||
class_obj.add_attribute(att)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
|
|
||||||
def find_attr_comment(attr_name)
|
|
||||||
if @body =~ %r{((?>/\*.*?\*/\s+))
|
|
||||||
rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi
|
|
||||||
$1
|
|
||||||
elsif @body =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m
|
|
||||||
$1
|
|
||||||
else
|
|
||||||
''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
|
|
||||||
def handle_method(type, var_name, meth_name,
|
|
||||||
meth_body, param_count, source_file = nil)
|
|
||||||
progress(".")
|
|
||||||
|
|
||||||
@stats.num_methods += 1
|
|
||||||
class_name = @known_classes[var_name]
|
|
||||||
|
|
||||||
return unless class_name
|
|
||||||
|
|
||||||
class_obj = find_class(var_name, class_name)
|
|
||||||
|
|
||||||
if class_obj
|
|
||||||
if meth_name == "initialize"
|
|
||||||
meth_name = "new"
|
|
||||||
type = "singleton_method"
|
|
||||||
end
|
|
||||||
meth_obj = AnyMethod.new("", meth_name)
|
|
||||||
meth_obj.singleton =
|
|
||||||
%w{singleton_method module_function}.include?(type)
|
|
||||||
|
|
||||||
p_count = (Integer(param_count) rescue -1)
|
|
||||||
|
|
||||||
if p_count < 0
|
|
||||||
meth_obj.params = "(...)"
|
|
||||||
elsif p_count == 0
|
|
||||||
meth_obj.params = "()"
|
|
||||||
else
|
|
||||||
meth_obj.params = "(" +
|
|
||||||
(1..p_count).map{|i| "p#{i}"}.join(", ") +
|
|
||||||
")"
|
|
||||||
end
|
|
||||||
|
|
||||||
if source_file
|
|
||||||
file_name = File.join(@file_dir, source_file)
|
|
||||||
body = (@@known_bodies[source_file] ||= File.read(file_name))
|
|
||||||
else
|
|
||||||
body = @body
|
|
||||||
end
|
|
||||||
if find_body(meth_body, meth_obj, body) and meth_obj.document_self
|
|
||||||
class_obj.add_method(meth_obj)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
# Find the C code corresponding to a Ruby method
|
|
||||||
def find_body(meth_name, meth_obj, body, quiet = false)
|
|
||||||
case body
|
|
||||||
when %r"((?>/\*.*?\*/\s*))(?:static\s+)?VALUE\s+#{meth_name}
|
|
||||||
\s*(\([^)]*\))\s*\{.*?^\}"xm
|
|
||||||
comment, params = $1, $2
|
|
||||||
body_text = $&
|
|
||||||
|
|
||||||
remove_private_comments(comment) if comment
|
|
||||||
|
|
||||||
# see if we can find the whole body
|
|
||||||
|
|
||||||
re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}'
|
|
||||||
if Regexp.new(re, Regexp::MULTILINE).match(body)
|
|
||||||
body_text = $&
|
|
||||||
end
|
|
||||||
|
|
||||||
# The comment block may have been overridden with a
|
|
||||||
# 'Document-method' block. This happens in the interpreter
|
|
||||||
# when multiple methods are vectored through to the same
|
|
||||||
# C method but those methods are logically distinct (for
|
|
||||||
# example Kernel.hash and Kernel.object_id share the same
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
override_comment = find_override_comment(meth_obj.name)
|
|
||||||
comment = override_comment if override_comment
|
|
||||||
|
|
||||||
find_modifiers(comment, meth_obj) if comment
|
|
||||||
|
|
||||||
# meth_obj.params = params
|
|
||||||
meth_obj.start_collecting_tokens
|
|
||||||
meth_obj.add_token(RubyToken::Token.new(1,1).set_text(body_text))
|
|
||||||
meth_obj.comment = mangle_comment(comment)
|
|
||||||
when %r{((?>/\*.*?\*/\s*))^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
|
|
||||||
comment = $1
|
|
||||||
find_body($2, meth_obj, body, true)
|
|
||||||
find_modifiers(comment, meth_obj)
|
|
||||||
meth_obj.comment = mangle_comment(comment) + meth_obj.comment
|
|
||||||
when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
|
|
||||||
unless find_body($1, meth_obj, body, true)
|
|
||||||
warn "No definition for #{meth_name}" unless quiet
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
else
|
|
||||||
|
|
||||||
# No body, but might still have an override comment
|
|
||||||
comment = find_override_comment(meth_obj.name)
|
|
||||||
|
|
||||||
if comment
|
|
||||||
find_modifiers(comment, meth_obj)
|
|
||||||
meth_obj.comment = mangle_comment(comment)
|
|
||||||
else
|
|
||||||
warn "No definition for #{meth_name}" unless quiet
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# If the comment block contains a section that looks like:
|
|
||||||
#
|
|
||||||
# call-seq:
|
|
||||||
# Array.new
|
|
||||||
# Array.new(10)
|
|
||||||
#
|
|
||||||
# use it for the parameters.
|
|
||||||
|
|
||||||
def find_modifiers(comment, meth_obj)
|
|
||||||
if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or
|
|
||||||
comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '')
|
|
||||||
meth_obj.document_self = false
|
|
||||||
end
|
|
||||||
if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or
|
|
||||||
comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '')
|
|
||||||
seq = $1
|
|
||||||
seq.gsub!(/^\s*\*\s*/, '')
|
|
||||||
meth_obj.call_seq = seq
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def find_override_comment(meth_name)
|
|
||||||
name = Regexp.escape(meth_name)
|
|
||||||
if @body =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m
|
|
||||||
$1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Look for includes of the form:
|
|
||||||
#
|
|
||||||
# rb_include_module(rb_cArray, rb_mEnumerable);
|
|
||||||
|
|
||||||
def do_includes
|
|
||||||
@body.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
|
|
||||||
if cls = @classes[c]
|
|
||||||
m = @known_classes[m] || m
|
|
||||||
cls.add_include(Include.new(m, ""))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Remove the /*'s and leading asterisks from C comments
|
|
||||||
|
|
||||||
def mangle_comment(comment)
|
|
||||||
comment.sub!(%r{/\*+}) { " " * $&.length }
|
|
||||||
comment.sub!(%r{\*+/}) { " " * $&.length }
|
|
||||||
comment.gsub!(/^[ \t]*\*/m) { " " * $&.length }
|
|
||||||
comment
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_class(raw_name, name)
|
|
||||||
unless @classes[raw_name]
|
|
||||||
if raw_name =~ /^rb_m/
|
|
||||||
@classes[raw_name] = @top_level.add_module(NormalModule, name)
|
|
||||||
else
|
|
||||||
@classes[raw_name] = @top_level.add_class(NormalClass, name, nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@classes[raw_name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_tab_width(body)
|
|
||||||
if /\t/ =~ body
|
|
||||||
tab_width = @options.tab_width
|
|
||||||
body.split(/\n/).map do |line|
|
|
||||||
1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #`
|
|
||||||
line
|
|
||||||
end .join("\n")
|
|
||||||
else
|
|
||||||
body
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Removes #ifdefs that would otherwise confuse us
|
|
||||||
|
|
||||||
def handle_ifdefs_in(body)
|
|
||||||
body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,40 +0,0 @@
|
||||||
require 'rdoc'
|
|
||||||
require 'rdoc/code_objects'
|
|
||||||
require 'rdoc/markup/preprocess'
|
|
||||||
|
|
||||||
##
|
|
||||||
# Parse a non-source file. We basically take the whole thing as one big
|
|
||||||
# comment. If the first character in the file is '#', we strip leading pound
|
|
||||||
# signs.
|
|
||||||
|
|
||||||
class RDoc::SimpleParser
|
|
||||||
|
|
||||||
##
|
|
||||||
# Prepare to parse a plain file
|
|
||||||
|
|
||||||
def initialize(top_level, file_name, body, options, stats)
|
|
||||||
preprocess = RDoc::Markup::PreProcess.new(file_name, options.rdoc_include)
|
|
||||||
|
|
||||||
preprocess.handle(body) do |directive, param|
|
|
||||||
warn "Unrecognized directive '#{directive}' in #{file_name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
@body = body
|
|
||||||
@options = options
|
|
||||||
@top_level = top_level
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Extract the file contents and attach them to the toplevel as a comment
|
|
||||||
|
|
||||||
def scan
|
|
||||||
@top_level.comment = remove_private_comments(@body)
|
|
||||||
@top_level
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_private_comments(comment)
|
|
||||||
comment.gsub(/^--[^-].*?^\+\+/m, '').sub(/^--.*/m, '')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
require "rdoc/parsers/parse_simple"
|
|
||||||
|
|
||||||
module RDoc
|
|
||||||
|
|
||||||
# A parser is simple a class that implements
|
|
||||||
#
|
|
||||||
# #initialize(file_name, body, options)
|
|
||||||
#
|
|
||||||
# and
|
|
||||||
#
|
|
||||||
# #scan
|
|
||||||
#
|
|
||||||
# The initialize method takes a file name to be used, the body of the
|
|
||||||
# file, and an RDoc::Options object. The scan method is then called
|
|
||||||
# to return an appropriately parsed TopLevel code object.
|
|
||||||
#
|
|
||||||
# The ParseFactory is used to redirect to the correct parser given a filename
|
|
||||||
# extension. This magic works because individual parsers have to register
|
|
||||||
# themselves with us as they are loaded in. The do this using the following
|
|
||||||
# incantation
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# require "rdoc/parsers/parsefactory"
|
|
||||||
#
|
|
||||||
# module RDoc
|
|
||||||
#
|
|
||||||
# class XyzParser
|
|
||||||
# extend ParseFactory <<<<
|
|
||||||
# parse_files_matching /\.xyz$/ <<<<
|
|
||||||
#
|
|
||||||
# def initialize(file_name, body, options)
|
|
||||||
# ...
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# def scan
|
|
||||||
# ...
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# Just to make life interesting, if we suspect a plain text file, we
|
|
||||||
# also look for a shebang line just in case it's a potential
|
|
||||||
# shell script
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module ParserFactory
|
|
||||||
|
|
||||||
@@parsers = []
|
|
||||||
|
|
||||||
Parsers = Struct.new(:regexp, :parser)
|
|
||||||
|
|
||||||
# Record the fact that a particular class parses files that
|
|
||||||
# match a given extension
|
|
||||||
|
|
||||||
def parse_files_matching(regexp)
|
|
||||||
@@parsers.unshift Parsers.new(regexp, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return a parser that can handle a particular extension
|
|
||||||
|
|
||||||
def ParserFactory.can_parse(file_name)
|
|
||||||
@@parsers.find {|p| p.regexp.match(file_name) }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Alias an extension to another extension. After this call,
|
|
||||||
# files ending "new_ext" will be parsed using the same parser
|
|
||||||
# as "old_ext"
|
|
||||||
|
|
||||||
def ParserFactory.alias_extension(old_ext, new_ext)
|
|
||||||
parser = ParserFactory.can_parse("xxx.#{old_ext}")
|
|
||||||
return false unless parser
|
|
||||||
@@parsers.unshift Parsers.new(Regexp.new("\\.#{new_ext}$"), parser.parser)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
# Find the correct parser for a particular file name. Return a
|
|
||||||
# SimpleParser for ones that we don't know
|
|
||||||
|
|
||||||
def ParserFactory.parser_for(top_level, file_name, body, options, stats)
|
|
||||||
# If no extension, look for shebang
|
|
||||||
if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)}
|
|
||||||
shebang = $1
|
|
||||||
case shebang
|
|
||||||
when %r{env\s+ruby}, %r{/ruby}
|
|
||||||
file_name = "dummy.rb"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
parser_description = can_parse(file_name)
|
|
||||||
if parser_description
|
|
||||||
parser = parser_description.parser
|
|
||||||
else
|
|
||||||
parser = SimpleParser
|
|
||||||
end
|
|
||||||
|
|
||||||
parser.new(top_level, file_name, body, options, stats)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,9 +1,12 @@
|
||||||
require 'rdoc'
|
require 'rdoc'
|
||||||
|
|
||||||
require 'rdoc/parsers/parse_rb.rb'
|
require 'rdoc/parser'
|
||||||
require 'rdoc/parsers/parse_c.rb'
|
|
||||||
require 'rdoc/parsers/parse_f95.rb'
|
# Simple must come first
|
||||||
require 'rdoc/parsers/parse_simple.rb'
|
require 'rdoc/parser/simple'
|
||||||
|
require 'rdoc/parser/ruby'
|
||||||
|
require 'rdoc/parser/c'
|
||||||
|
require 'rdoc/parser/f95'
|
||||||
|
|
||||||
require 'rdoc/stats'
|
require 'rdoc/stats'
|
||||||
require 'rdoc/options'
|
require 'rdoc/options'
|
||||||
|
@ -146,7 +149,10 @@ module RDoc
|
||||||
case type = stat.ftype
|
case type = stat.ftype
|
||||||
when "file"
|
when "file"
|
||||||
next if @last_created and stat.mtime < @last_created
|
next if @last_created and stat.mtime < @last_created
|
||||||
file_list << rel_file_name.sub(/^\.\//, '') if force_doc || ParserFactory.can_parse(rel_file_name)
|
|
||||||
|
if force_doc or ::RDoc::Parser.can_parse(rel_file_name) then
|
||||||
|
file_list << rel_file_name.sub(/^\.\//, '')
|
||||||
|
end
|
||||||
when "directory"
|
when "directory"
|
||||||
next if rel_file_name == "CVS" || rel_file_name == ".svn"
|
next if rel_file_name == "CVS" || rel_file_name == ".svn"
|
||||||
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
|
dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)
|
||||||
|
@ -198,14 +204,18 @@ module RDoc
|
||||||
File.read fn
|
File.read fn
|
||||||
end
|
end
|
||||||
|
|
||||||
if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
|
if defined? Encoding then
|
||||||
if enc = Encoding.find($1)
|
if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/]
|
||||||
content.force_encoding(enc)
|
if enc = ::Encoding.find($1)
|
||||||
|
content.force_encoding(enc)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
top_level = TopLevel.new(fn)
|
top_level = ::RDoc::TopLevel.new fn
|
||||||
parser = ParserFactory.parser_for(top_level, fn, content, options, @stats)
|
|
||||||
|
parser = ::RDoc::Parser.for top_level, fn, content, options, @stats
|
||||||
|
|
||||||
file_info << parser.scan
|
file_info << parser.scan
|
||||||
@stats.num_files += 1
|
@stats.num_files += 1
|
||||||
end
|
end
|
||||||
|
@ -241,17 +251,19 @@ module RDoc
|
||||||
|
|
||||||
file_info = parse_files @options
|
file_info = parse_files @options
|
||||||
|
|
||||||
|
@options.title = "RDoc Documentation"
|
||||||
|
|
||||||
if file_info.empty?
|
if file_info.empty?
|
||||||
$stderr.puts "\nNo newer files." unless @options.quiet
|
$stderr.puts "\nNo newer files." unless @options.quiet
|
||||||
else
|
else
|
||||||
gen = @options.generator
|
@gen = @options.generator
|
||||||
|
|
||||||
$stderr.puts "\nGenerating #{gen.key.upcase}..." unless @options.quiet
|
$stderr.puts "\nGenerating #{@gen.key.upcase}..." unless @options.quiet
|
||||||
|
|
||||||
require gen.file_name
|
require @gen.file_name
|
||||||
|
|
||||||
gen_class = ::RDoc::Generator.const_get gen.class_name
|
gen_class = ::RDoc::Generator.const_get @gen.class_name
|
||||||
gen = gen_class.for @options
|
@gen = gen_class.for @options
|
||||||
|
|
||||||
pwd = Dir.pwd
|
pwd = Dir.pwd
|
||||||
|
|
||||||
|
@ -259,7 +271,7 @@ module RDoc
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Diagram.new(file_info, @options).draw if @options.diagram
|
Diagram.new(file_info, @options).draw if @options.diagram
|
||||||
gen.generate(file_info)
|
@gen.generate(file_info)
|
||||||
update_output_dir(".", start_time)
|
update_output_dir(".", start_time)
|
||||||
ensure
|
ensure
|
||||||
Dir.chdir(pwd)
|
Dir.chdir(pwd)
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
require 'rdoc'
|
require 'rdoc'
|
||||||
|
|
||||||
module RDoc::RI; end
|
module RDoc::RI
|
||||||
|
|
||||||
|
class Error < RDoc::Error; end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,10 @@ require 'yaml'
|
||||||
require 'rdoc/markup/fragments'
|
require 'rdoc/markup/fragments'
|
||||||
require 'rdoc/ri'
|
require 'rdoc/ri'
|
||||||
|
|
||||||
#--
|
##
|
||||||
# Descriptions are created by RDoc (in ri_generator) and written out in
|
# Descriptions are created by RDoc (in ri_generator) and written out in
|
||||||
# serialized form into the documentation tree. ri then reads these to generate
|
# serialized form into the documentation tree. ri then reads these to generate
|
||||||
# the documentation
|
# the documentation
|
||||||
#++
|
|
||||||
|
|
||||||
class RDoc::RI::NamedThing
|
class RDoc::RI::NamedThing
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
|
@ -11,6 +11,64 @@ require 'rdoc/markup/to_flow'
|
||||||
|
|
||||||
class RDoc::RI::Driver
|
class RDoc::RI::Driver
|
||||||
|
|
||||||
|
class Hash < ::Hash
|
||||||
|
def self.convert(hash)
|
||||||
|
hash = new.update hash
|
||||||
|
|
||||||
|
hash.each do |key, value|
|
||||||
|
hash[key] = case value
|
||||||
|
when ::Hash then
|
||||||
|
convert value
|
||||||
|
when Array then
|
||||||
|
value = value.map do |v|
|
||||||
|
::Hash === v ? convert(v) : v
|
||||||
|
end
|
||||||
|
value
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing method, *args
|
||||||
|
self[method.to_s]
|
||||||
|
end
|
||||||
|
|
||||||
|
def merge_enums(other)
|
||||||
|
other.each do |k, v|
|
||||||
|
if self[k] then
|
||||||
|
case v
|
||||||
|
when Array then
|
||||||
|
# HACK dunno
|
||||||
|
if String === self[k] and self[k].empty? then
|
||||||
|
self[k] = v
|
||||||
|
else
|
||||||
|
self[k] += v
|
||||||
|
end
|
||||||
|
when Hash then
|
||||||
|
self[k].update v
|
||||||
|
else
|
||||||
|
# do nothing
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Error < RDoc::RI::Error; end
|
||||||
|
|
||||||
|
class NotFoundError < Error
|
||||||
|
def message
|
||||||
|
"Nothing known about #{super}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_accessor :homepath # :nodoc:
|
||||||
|
|
||||||
def self.process_args(argv)
|
def self.process_args(argv)
|
||||||
options = {}
|
options = {}
|
||||||
options[:use_stdout] = !$stdout.tty?
|
options[:use_stdout] = !$stdout.tty?
|
||||||
|
@ -234,7 +292,7 @@ Options may also be set in the 'RI' environment variable.
|
||||||
@class_cache = if up_to_date then
|
@class_cache = if up_to_date then
|
||||||
load_cache_for @class_cache_name
|
load_cache_for @class_cache_name
|
||||||
else
|
else
|
||||||
class_cache = {}
|
class_cache = RDoc::RI::Driver::Hash.new
|
||||||
|
|
||||||
classes = map_dirs('**/cdesc*.yaml', :sys) { |f| Dir[f] }
|
classes = map_dirs('**/cdesc*.yaml', :sys) { |f| Dir[f] }
|
||||||
populate_class_cache class_cache, classes
|
populate_class_cache class_cache, classes
|
||||||
|
@ -261,16 +319,24 @@ Options may also be set in the 'RI' environment variable.
|
||||||
|
|
||||||
def display_class(name)
|
def display_class(name)
|
||||||
klass = class_cache[name]
|
klass = class_cache[name]
|
||||||
|
klass = RDoc::RI::Driver::Hash.convert klass
|
||||||
@display.display_class_info klass, class_cache
|
@display.display_class_info klass, class_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_info_for(arg)
|
||||||
|
@names = [arg]
|
||||||
|
run
|
||||||
|
end
|
||||||
|
|
||||||
def load_cache_for(klassname)
|
def load_cache_for(klassname)
|
||||||
path = cache_file_for klassname
|
path = cache_file_for klassname
|
||||||
|
|
||||||
|
cache = nil
|
||||||
|
|
||||||
if File.exist? path and
|
if File.exist? path and
|
||||||
File.mtime(path) >= File.mtime(class_cache_file_path) then
|
File.mtime(path) >= File.mtime(class_cache_file_path) then
|
||||||
File.open path, 'rb' do |fp|
|
File.open path, 'rb' do |fp|
|
||||||
Marshal.load fp.read
|
cache = Marshal.load fp.read
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
class_cache = nil
|
class_cache = nil
|
||||||
|
@ -283,7 +349,7 @@ Options may also be set in the 'RI' environment variable.
|
||||||
return nil unless klass
|
return nil unless klass
|
||||||
|
|
||||||
method_files = klass["sources"]
|
method_files = klass["sources"]
|
||||||
cache = {}
|
cache = RDoc::RI::Driver::Hash.new
|
||||||
|
|
||||||
sys_dir = @sys_dirs.first
|
sys_dir = @sys_dirs.first
|
||||||
method_files.each do |f|
|
method_files.each do |f|
|
||||||
|
@ -296,12 +362,28 @@ Options may also be set in the 'RI' environment variable.
|
||||||
ext_path = f
|
ext_path = f
|
||||||
ext_path = "gem #{$1}" if f =~ %r%gems/[\d.]+/doc/([^/]+)%
|
ext_path = "gem #{$1}" if f =~ %r%gems/[\d.]+/doc/([^/]+)%
|
||||||
method["source_path"] = ext_path unless system_file
|
method["source_path"] = ext_path unless system_file
|
||||||
cache[name] = method
|
cache[name] = RDoc::RI::Driver::Hash.convert method
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
write_cache cache, path
|
write_cache cache, path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RDoc::RI::Driver::Hash.convert cache
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds the method
|
||||||
|
|
||||||
|
def lookup_method(name, klass)
|
||||||
|
cache = load_cache_for klass
|
||||||
|
raise NotFoundError, name unless cache
|
||||||
|
|
||||||
|
method = cache[name.gsub('.', '#')]
|
||||||
|
method = cache[name.gsub('.', '::')] unless method
|
||||||
|
raise NotFoundError, name unless method
|
||||||
|
|
||||||
|
method
|
||||||
end
|
end
|
||||||
|
|
||||||
def map_dirs(file_name, system=false)
|
def map_dirs(file_name, system=false)
|
||||||
|
@ -318,6 +400,22 @@ Options may also be set in the 'RI' environment variable.
|
||||||
dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact
|
dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Extract the class and method name parts from +name+ like Foo::Bar#baz
|
||||||
|
|
||||||
|
def parse_name(name)
|
||||||
|
parts = name.split(/(::|\#|\.)/)
|
||||||
|
|
||||||
|
if parts[-2] != '::' or parts.last !~ /^[A-Z]/ then
|
||||||
|
meth = parts.pop
|
||||||
|
parts.pop
|
||||||
|
end
|
||||||
|
|
||||||
|
klass = parts.join
|
||||||
|
|
||||||
|
[klass, meth]
|
||||||
|
end
|
||||||
|
|
||||||
def populate_class_cache(class_cache, classes, extension = false)
|
def populate_class_cache(class_cache, classes, extension = false)
|
||||||
classes.each do |cdesc|
|
classes.each do |cdesc|
|
||||||
desc = read_yaml cdesc
|
desc = read_yaml cdesc
|
||||||
|
@ -351,11 +449,6 @@ Options may also be set in the 'RI' environment variable.
|
||||||
YAML.load data
|
YAML.load data
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_info_for(arg)
|
|
||||||
@names = [arg]
|
|
||||||
run
|
|
||||||
end
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
if @names.empty? then
|
if @names.empty? then
|
||||||
@display.list_known_classes class_cache.keys.sort
|
@display.list_known_classes class_cache.keys.sort
|
||||||
|
@ -368,15 +461,10 @@ Options may also be set in the 'RI' environment variable.
|
||||||
else
|
else
|
||||||
meth = nil
|
meth = nil
|
||||||
|
|
||||||
parts = name.split(/::|\#|\./)
|
klass, meth = parse_name name
|
||||||
meth = parts.pop unless parts.last =~ /^[A-Z]/
|
|
||||||
klass = parts.join '::'
|
method = lookup_method name, klass
|
||||||
|
|
||||||
cache = load_cache_for klass
|
|
||||||
# HACK Does not support F.n
|
|
||||||
abort "Nothing known about #{name}" unless cache
|
|
||||||
method = cache[name.gsub(/\./, '#')]
|
|
||||||
abort "Nothing known about #{name}" unless method
|
|
||||||
@display.display_method_info method
|
@display.display_method_info method
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -385,7 +473,7 @@ Options may also be set in the 'RI' environment variable.
|
||||||
else
|
else
|
||||||
methods = select_methods(/^#{name}/)
|
methods = select_methods(/^#{name}/)
|
||||||
if methods.size == 0
|
if methods.size == 0
|
||||||
abort "Nothing known about #{name}"
|
raise NotFoundError, name
|
||||||
elsif methods.size == 1
|
elsif methods.size == 1
|
||||||
@display.display_method_info methods.first
|
@display.display_method_info methods.first
|
||||||
else
|
else
|
||||||
|
@ -395,6 +483,8 @@ Options may also be set in the 'RI' environment variable.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue NotFoundError => e
|
||||||
|
abort e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_methods(pattern)
|
def select_methods(pattern)
|
||||||
|
@ -422,31 +512,3 @@ Options may also be set in the 'RI' environment variable.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Hash # HACK don't add stuff to Hash.
|
|
||||||
def method_missing method, *args
|
|
||||||
self[method.to_s]
|
|
||||||
end
|
|
||||||
|
|
||||||
def merge_enums(other)
|
|
||||||
other.each do |k,v|
|
|
||||||
if self[k] then
|
|
||||||
case v
|
|
||||||
when Array then
|
|
||||||
# HACK dunno
|
|
||||||
if String === self[k] and self[k].empty? then
|
|
||||||
self[k] = v
|
|
||||||
else
|
|
||||||
self[k] += v
|
|
||||||
end
|
|
||||||
when Hash then
|
|
||||||
self[k].merge! v
|
|
||||||
else
|
|
||||||
# do nothing
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self[k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
179
test/rdoc/test_rdoc_info_formatting.rb
Normal file
179
test/rdoc/test_rdoc_info_formatting.rb
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib/'
|
||||||
|
require 'fileutils'
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rdoc/generator/texinfo'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
# From chapter 18 of the Pickaxe 3rd ed. and the TexInfo manual.
|
||||||
|
class TestRdocInfoFormatting < Test::Unit::TestCase
|
||||||
|
OUTPUT_DIR = "/tmp/rdoc-#{$$}"
|
||||||
|
|
||||||
|
def setup
|
||||||
|
# supress stdout
|
||||||
|
$stdout = File.new('/dev/null','w')
|
||||||
|
$stderr = File.new('/dev/null','w')
|
||||||
|
|
||||||
|
RDoc::RDoc.new.document(['--fmt=texinfo',
|
||||||
|
File.expand_path(__FILE__),
|
||||||
|
"--op=#{OUTPUT_DIR}"])
|
||||||
|
@text = File.read(OUTPUT_DIR + '/rdoc.texinfo')
|
||||||
|
# File.open('rdoc.texinfo', 'w') { |f| f.puts @text }
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
$stdout = STDOUT
|
||||||
|
$stderr = STDERR
|
||||||
|
FileUtils.rm_rf OUTPUT_DIR
|
||||||
|
end
|
||||||
|
|
||||||
|
# Make sure tags like *this* do not make HTML
|
||||||
|
def test_descriptions_are_not_html
|
||||||
|
assert_no_match Regexp.new("\<b\>this\<\/b\>"), @text, "We had some HTML; icky!"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensure we get a reasonable amount
|
||||||
|
#
|
||||||
|
# of space in between paragraphs.
|
||||||
|
def test_paragraphs_are_spaced
|
||||||
|
assert_match(/amount\n\n\nof space/, @text)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @ and {} should be at-sign-prefixed
|
||||||
|
def test_escaping
|
||||||
|
assert_match(/@@ and @\{@\} should be at-sign-prefixed/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# This tests that *bold* and <b>bold me</b> become @strong{bolded}
|
||||||
|
def test_bold
|
||||||
|
# Seems like a limitation of the Info format: @strong{bold}
|
||||||
|
# becomes *bold* when read in Info or M-x info. highly lame!
|
||||||
|
assert_match(/@strong\{bold\}/)
|
||||||
|
assert_match(/@strong\{bold me\}/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Test that _italics_ and <em>italicize me</em> becomes @emph{italicized}
|
||||||
|
def test_italics
|
||||||
|
assert_match(/@emph\{italics\}/)
|
||||||
|
assert_match(/@emph\{italicize me\}/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# And that typewriter +text+ and <tt>typewriter me</tt> becomes @code{typewriter}
|
||||||
|
def test_tt
|
||||||
|
assert_match(/@code\{text\}/)
|
||||||
|
assert_match(/@code\{typewriter me\}/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check that
|
||||||
|
# anything indented is
|
||||||
|
# verbatim @verb{|foo bar baz|}
|
||||||
|
def test_literal_code
|
||||||
|
assert_match("@verb{| anything indented is
|
||||||
|
verbatim @@verb@{|foo bar baz|@}
|
||||||
|
|}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# = Huge heading should be a @majorheading
|
||||||
|
# == There is also @chapheading
|
||||||
|
# === Everything deeper becomes a regular @heading
|
||||||
|
# ====== Regardless of its nesting level
|
||||||
|
def test_headings
|
||||||
|
assert_match(/@majorheading\{Huge heading should be a @@majorheading\}/)
|
||||||
|
assert_match(/@chapheading\{There is also @@chapheading\}/)
|
||||||
|
assert_match(/@heading\{Everything deeper becomes a regular @@heading\}/)
|
||||||
|
assert_match(/@heading\{Regardless of its nesting level\}/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# * list item
|
||||||
|
# * list item2
|
||||||
|
#
|
||||||
|
# with a paragraph in between
|
||||||
|
#
|
||||||
|
# - hyphen lists
|
||||||
|
# - are also allowed
|
||||||
|
# and items may flow over lines
|
||||||
|
def test_bullet_lists
|
||||||
|
assert_match("@itemize @bullet
|
||||||
|
@item
|
||||||
|
list item
|
||||||
|
@item
|
||||||
|
list item2
|
||||||
|
@end itemize")
|
||||||
|
assert_match("@itemize @bullet
|
||||||
|
@item
|
||||||
|
hyphen lists
|
||||||
|
@item
|
||||||
|
are also allowed and items may flow over lines
|
||||||
|
@end itemize")
|
||||||
|
end
|
||||||
|
|
||||||
|
# 2. numbered lists
|
||||||
|
# 8. are made by
|
||||||
|
# 9. a digit followed by a period
|
||||||
|
def test_numbered_lists
|
||||||
|
end
|
||||||
|
|
||||||
|
# a. alpha lists
|
||||||
|
# b. should be parsed too
|
||||||
|
def test_alpha_lists
|
||||||
|
end
|
||||||
|
|
||||||
|
# [cat] small domestic animal
|
||||||
|
# [+cat+] command to copy standard input
|
||||||
|
# to standard output
|
||||||
|
def test_labelled_lists
|
||||||
|
end
|
||||||
|
|
||||||
|
# * First item.
|
||||||
|
# * Inner item.
|
||||||
|
# * Second inner item.
|
||||||
|
# * Second outer item.
|
||||||
|
def test_nested_lists
|
||||||
|
assert_match("@itemize @bullet
|
||||||
|
@item
|
||||||
|
First item.
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Inner item.
|
||||||
|
@item
|
||||||
|
Second inner item.
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
Second outer item.
|
||||||
|
@end itemize")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_internal_hyperlinks
|
||||||
|
# be sure to test multi-word hyperlinks as well.
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hyperlink_targets
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_web_links
|
||||||
|
# An example of the two-argument form: The official
|
||||||
|
# @uref{ftp://ftp.gnu.org/gnu, GNU ftp site} holds programs and texts.
|
||||||
|
|
||||||
|
# produces:
|
||||||
|
# The official GNU ftp site (ftp://ftp.gnu.org/gnu)
|
||||||
|
# holds programs and texts.
|
||||||
|
# and the HTML output is this:
|
||||||
|
# The official <a href="ftp://ftp.gnu.org/gnu">GNU ftp site</a>
|
||||||
|
# holds programs and texts.
|
||||||
|
end
|
||||||
|
|
||||||
|
# three or more hyphens
|
||||||
|
# ----
|
||||||
|
# should produce a horizontal rule
|
||||||
|
def test_horizontal_rule
|
||||||
|
# gah; not sure texinfo supports horizontal rules
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# We don't want the whole string inspected if we pass our own
|
||||||
|
# message in.
|
||||||
|
def assert_match(regex, string = @text,
|
||||||
|
message = "Didn't find #{regex.inspect} in #{string}.")
|
||||||
|
assert string[regex] #, message
|
||||||
|
end
|
||||||
|
end
|
93
test/rdoc/test_rdoc_info_sections.rb
Normal file
93
test/rdoc/test_rdoc_info_sections.rb
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib/'
|
||||||
|
require 'fileutils'
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rdoc/generator/texinfo'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
# give us access to check this stuff before it's rendered
|
||||||
|
class RDoc::Generator::Texinfo; attr_reader :files, :classes; end
|
||||||
|
class RDoc::RDoc; attr_reader :options; attr_reader :gen; end
|
||||||
|
|
||||||
|
class TestRdocInfoSections < Test::Unit::TestCase
|
||||||
|
OUTPUT_DIR = "/tmp/rdoc-#{$$}"
|
||||||
|
|
||||||
|
def setup
|
||||||
|
# supress stdout
|
||||||
|
$stdout = File.new('/dev/null','w')
|
||||||
|
$stderr = File.new('/dev/null','w')
|
||||||
|
|
||||||
|
@rdoc = RDoc::RDoc.new
|
||||||
|
@rdoc.document(['--fmt=texinfo',
|
||||||
|
File.expand_path(File.dirname(__FILE__) + '/../lib/rdoc/generator/texinfo.rb'),
|
||||||
|
File.expand_path(File.dirname(__FILE__) + '/../README.txt'),
|
||||||
|
"--op=#{OUTPUT_DIR}"])
|
||||||
|
@text = File.read(OUTPUT_DIR + '/rdoc.texinfo')
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
$stdout = STDOUT
|
||||||
|
$stderr = STDERR
|
||||||
|
FileUtils.rm_rf OUTPUT_DIR
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_output_exists
|
||||||
|
assert ! @text.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_each_class_has_a_chapter
|
||||||
|
assert_section "Class RDoc::Generator::Texinfo", '@chapter'
|
||||||
|
assert_section "Class RDoc::Generator::TexinfoTemplate", '@chapter'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_class_descriptions_are_given
|
||||||
|
assert_match(/This generates .*Texinfo.* files for viewing with GNU Info or Emacs from .*RDoc.* extracted from Ruby source files/, @text.gsub("\n", ' '))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_included_modules_are_given
|
||||||
|
assert_match(/Includes.* Generator::MarkUp/m, @text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_class_methods_are_given
|
||||||
|
assert_match(/new\(options\)/, @text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_classes_instance_methods_are_given
|
||||||
|
assert_section 'Class RDoc::Generator::Texinfo#generate'
|
||||||
|
assert_match(/generate\(toplevels\)/, @text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_each_module_has_a_chapter
|
||||||
|
assert_section "RDoc", '@chapter'
|
||||||
|
assert_section "Generator", '@chapter'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_methods_are_shown_only_once
|
||||||
|
methods = @rdoc.gen.classes.map { |c| c.methods.map{ |m| c.name + '#' + m.name } }.flatten
|
||||||
|
assert_equal methods, methods.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
# if system "makeinfo --version > /dev/null"
|
||||||
|
# def test_compiles_to_info
|
||||||
|
# makeinfo_output = `cd #{OUTPUT_DIR} && makeinfo rdoc.texinfo`
|
||||||
|
# assert(File.exist?(File.join(OUTPUT_DIR, 'rdoc.info')),
|
||||||
|
# "Info file was not compiled: #{makeinfo_output}")
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# def test_constants_are_documented_somehow
|
||||||
|
# assert_section 'DEFAULT_FILENAME' # what kind of section?
|
||||||
|
# assert_section 'DEFAULT_INFO_FILENAME'
|
||||||
|
# end
|
||||||
|
|
||||||
|
# def test_oh_yeah_dont_forget_files
|
||||||
|
# end
|
||||||
|
|
||||||
|
private
|
||||||
|
def assert_section(name, command = '@section')
|
||||||
|
assert_match Regexp.new("^#{command}.*#{Regexp.escape name}"), @text, "Could not find a #{command} #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# def puts(*args)
|
||||||
|
# @real_stdout.puts(*args)
|
||||||
|
# end
|
||||||
|
end
|
30
test/rdoc/test_rdoc_markup_to_html.rb
Normal file
30
test/rdoc/test_rdoc_markup_to_html.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rdoc/markup'
|
||||||
|
require 'rdoc/markup/to_html'
|
||||||
|
|
||||||
|
class TestRdocMarkupToHtml < Test::Unit::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@am = RDoc::Markup::AttributeManager.new
|
||||||
|
@th = RDoc::Markup::ToHtml.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_tt_formatting
|
||||||
|
assert_equal "<p>\n<tt>--</tt> — <tt>(c)</tt> ©\n</p>\n",
|
||||||
|
util_format("<tt>--</tt> -- <tt>(c)</tt> (c)")
|
||||||
|
assert_equal "<p>\n<b>—</b>\n</p>\n", util_format("<b>--</b>")
|
||||||
|
end
|
||||||
|
|
||||||
|
def util_fragment(text)
|
||||||
|
RDoc::Markup::Fragment.new 0, nil, nil, text
|
||||||
|
end
|
||||||
|
|
||||||
|
def util_format(text)
|
||||||
|
fragment = util_fragment text
|
||||||
|
|
||||||
|
@th.start_accepting
|
||||||
|
@th.accept_paragraph @am, fragment
|
||||||
|
@th.end_accepting
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
18
test/rdoc/test_rdoc_markup_to_html_crossref.rb
Normal file
18
test/rdoc/test_rdoc_markup_to_html_crossref.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rdoc/generator'
|
||||||
|
require 'rdoc/markup/to_html_crossref'
|
||||||
|
|
||||||
|
class TestRdocMarkupToHtmlCrossref < Test::Unit::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_handle_special_CROSSREF_no_underscore
|
||||||
|
out = @xref.convert 'foo'
|
||||||
|
|
||||||
|
assert_equal "<p>\nfoo\n</p>\n", out
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
require 'stringio'
|
require 'stringio'
|
||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
require 'rdoc/parsers/parse_c'
|
require 'rdoc/options'
|
||||||
|
require 'rdoc/parser/c'
|
||||||
|
|
||||||
class RDoc::C_Parser
|
class RDoc::Parser::C
|
||||||
attr_accessor :classes
|
attr_accessor :classes
|
||||||
|
|
||||||
public :do_classes, :do_constants
|
public :do_classes, :do_constants
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestRdocC_Parser < Test::Unit::TestCase
|
class TestRdocParserC < Test::Unit::TestCase
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@tempfile = Tempfile.new self.class.name
|
@tempfile = Tempfile.new self.class.name
|
||||||
|
@ -252,7 +253,7 @@ Init_Foo(void) {
|
||||||
end
|
end
|
||||||
|
|
||||||
def util_parser(content)
|
def util_parser(content)
|
||||||
parser = RDoc::C_Parser.new @top_level, @fn, content, @options, @stats
|
parser = RDoc::Parser::C.new @top_level, @fn, content, @options, @stats
|
||||||
parser.progress = @progress
|
parser.progress = @progress
|
||||||
parser
|
parser
|
||||||
end
|
end
|
500
test/rdoc/test_rdoc_parser_ruby.rb
Normal file
500
test/rdoc/test_rdoc_parser_ruby.rb
Normal file
|
@ -0,0 +1,500 @@
|
||||||
|
require 'stringio'
|
||||||
|
require 'tempfile'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
require 'rdoc/options'
|
||||||
|
require 'rdoc/parser/ruby'
|
||||||
|
require 'rdoc/stats'
|
||||||
|
|
||||||
|
class TestRdocParserRuby < Test::Unit::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@tempfile = Tempfile.new self.class.name
|
||||||
|
@filename = @tempfile.path
|
||||||
|
|
||||||
|
util_toplevel
|
||||||
|
@options = RDoc::Options.new Hash.new
|
||||||
|
@options.quiet = true
|
||||||
|
@stats = RDoc::Stats.new
|
||||||
|
|
||||||
|
@progress = StringIO.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
@tempfile.unlink
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_commented
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
comment = "# how to make a section:\n# # :section: new section\n"
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, comment
|
||||||
|
|
||||||
|
section = @top_level.current_section
|
||||||
|
assert_equal nil, section.title
|
||||||
|
assert_equal nil, section.comment
|
||||||
|
|
||||||
|
assert_equal "# how to make a section:\n# # :section: new section\n",
|
||||||
|
comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_enddoc
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
assert_throws :enddoc do
|
||||||
|
@parser.look_for_directives_in @top_level, "# :enddoc:\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_main
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, "# :main: new main page\n"
|
||||||
|
|
||||||
|
assert_equal 'new main page', @options.main_page
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_method
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
comment = "# :method: my_method\n"
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, comment
|
||||||
|
|
||||||
|
assert_equal "# :method: my_method\n", comment
|
||||||
|
|
||||||
|
comment = "# :singleton-method: my_method\n"
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, comment
|
||||||
|
|
||||||
|
assert_equal "# :singleton-method: my_method\n", comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_startdoc
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
@top_level.stop_doc
|
||||||
|
assert !@top_level.document_self
|
||||||
|
assert !@top_level.document_children
|
||||||
|
assert !@top_level.force_documentation
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, "# :startdoc:\n"
|
||||||
|
|
||||||
|
assert @top_level.document_self
|
||||||
|
assert @top_level.document_children
|
||||||
|
assert @top_level.force_documentation
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_stopdoc
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
assert @top_level.document_self
|
||||||
|
assert @top_level.document_children
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, "# :stopdoc:\n"
|
||||||
|
|
||||||
|
assert !@top_level.document_self
|
||||||
|
assert !@top_level.document_children
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_section
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
comment = "# :section: new section\n# woo stuff\n"
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, comment
|
||||||
|
|
||||||
|
section = @top_level.current_section
|
||||||
|
assert_equal 'new section', section.title
|
||||||
|
assert_equal "# woo stuff\n", section.comment
|
||||||
|
|
||||||
|
assert_equal '', comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_title
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, "# :title: new title\n"
|
||||||
|
|
||||||
|
assert_equal 'new title', @options.title
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_look_for_directives_in_unhandled
|
||||||
|
util_parser ""
|
||||||
|
|
||||||
|
comment = "# :unhandled: \n# :title: hi\n"
|
||||||
|
|
||||||
|
@parser.look_for_directives_in @top_level, comment
|
||||||
|
|
||||||
|
assert_equal "# :unhandled: \n", comment
|
||||||
|
|
||||||
|
assert_equal 'hi', @options.title
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_meta_method
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal comment, foo.comment
|
||||||
|
|
||||||
|
assert_equal [], foo.aliases
|
||||||
|
assert_equal nil, foo.block_params
|
||||||
|
assert_equal nil, foo.call_seq
|
||||||
|
assert_equal true, foo.document_children
|
||||||
|
assert_equal true, foo.document_self
|
||||||
|
assert_equal false, foo.done_documenting
|
||||||
|
assert_equal false, foo.dont_rename_initialize
|
||||||
|
assert_equal false, foo.force_documentation
|
||||||
|
assert_equal nil, foo.is_alias_for
|
||||||
|
assert_equal '', foo.params
|
||||||
|
assert_equal klass, foo.parent
|
||||||
|
assert_equal false, foo.singleton
|
||||||
|
assert_equal 'add_my_method :foo', foo.text
|
||||||
|
assert_equal nil, foo.viewer
|
||||||
|
assert_equal :public, foo.visibility
|
||||||
|
assert_equal klass.current_section, foo.section
|
||||||
|
|
||||||
|
stream = [
|
||||||
|
tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"),
|
||||||
|
RDoc::Parser::Ruby::NEWLINE_TOKEN,
|
||||||
|
tk(:SPACE, 1, 1, nil, ''),
|
||||||
|
tk(:IDENTIFIER, 1, 0, 'add_my_method', 'add_my_method'),
|
||||||
|
tk(:SPACE, 1, 13, nil, ' '),
|
||||||
|
tk(:SYMBOL, 1, 14, nil, ':foo'),
|
||||||
|
tk(:COMMA, 1, 18, nil, ','),
|
||||||
|
tk(:SPACE, 1, 19, nil, ' '),
|
||||||
|
tk(:SYMBOL, 1, 20, nil, ':bar'),
|
||||||
|
tk(:NL, 1, 24, nil, "\n"),
|
||||||
|
]
|
||||||
|
|
||||||
|
assert_equal stream, foo.token_stream
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_meta_method_name
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# :method: woo_hoo!\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'woo_hoo!', foo.name
|
||||||
|
assert_equal "##\n# my method\n", foo.comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_meta_method_singleton
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# :singleton-method:\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal true, foo.singleton, 'singleton method'
|
||||||
|
assert_equal "##\n# my method\n", foo.comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_meta_method_singleton_name
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# :singleton-method: woo_hoo!\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'woo_hoo!', foo.name
|
||||||
|
assert_equal true, foo.singleton, 'singleton method'
|
||||||
|
assert_equal "##\n# my method\n", foo.comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_meta_method_string_name
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
comment = "##\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "add_my_method 'foo'"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal comment, foo.comment
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_method
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "def foo() :bar end"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal comment, foo.comment
|
||||||
|
|
||||||
|
assert_equal [], foo.aliases
|
||||||
|
assert_equal nil, foo.block_params
|
||||||
|
assert_equal nil, foo.call_seq
|
||||||
|
assert_equal nil, foo.is_alias_for
|
||||||
|
assert_equal nil, foo.viewer
|
||||||
|
assert_equal true, foo.document_children
|
||||||
|
assert_equal true, foo.document_self
|
||||||
|
assert_equal '()', foo.params
|
||||||
|
assert_equal false, foo.done_documenting
|
||||||
|
assert_equal false, foo.dont_rename_initialize
|
||||||
|
assert_equal false, foo.force_documentation
|
||||||
|
assert_equal klass, foo.parent
|
||||||
|
assert_equal false, foo.singleton
|
||||||
|
assert_equal :public, foo.visibility
|
||||||
|
assert_equal 'def foo', foo.text
|
||||||
|
assert_equal klass.current_section, foo.section
|
||||||
|
|
||||||
|
stream = [
|
||||||
|
tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"),
|
||||||
|
RDoc::Parser::Ruby::NEWLINE_TOKEN,
|
||||||
|
tk(:SPACE, 1, 1, nil, ''),
|
||||||
|
tk(:DEF, 1, 0, 'def', 'def'),
|
||||||
|
tk(:SPACE, 1, 3, nil, ' '),
|
||||||
|
tk(:IDENTIFIER, 1, 4, 'foo', 'foo'),
|
||||||
|
tk(:LPAREN, 1, 7, nil, '('),
|
||||||
|
tk(:RPAREN, 1, 8, nil, ')'),
|
||||||
|
tk(:SPACE, 1, 9, nil, ' '),
|
||||||
|
tk(:COLON, 1, 10, nil, ':'),
|
||||||
|
tk(:IDENTIFIER, 1, 11, 'bar', 'bar'),
|
||||||
|
tk(:SPACE, 1, 14, nil, ' '),
|
||||||
|
tk(:END, 1, 15, 'end', 'end'),
|
||||||
|
]
|
||||||
|
|
||||||
|
assert_equal stream, foo.token_stream
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_comment
|
||||||
|
content = <<-EOF
|
||||||
|
class Foo
|
||||||
|
##
|
||||||
|
# :method: my_method
|
||||||
|
# my method comment
|
||||||
|
|
||||||
|
end
|
||||||
|
EOF
|
||||||
|
klass = RDoc::NormalClass.new 'Foo'
|
||||||
|
klass.parent = @top_level
|
||||||
|
|
||||||
|
comment = "##\n# :method: foo\n# my method\n"
|
||||||
|
|
||||||
|
util_parser "\n"
|
||||||
|
|
||||||
|
tk = @parser.get_tk
|
||||||
|
|
||||||
|
@parser.parse_comment klass, tk, comment
|
||||||
|
|
||||||
|
foo = klass.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal comment, foo.comment
|
||||||
|
|
||||||
|
assert_equal [], foo.aliases
|
||||||
|
assert_equal nil, foo.block_params
|
||||||
|
assert_equal nil, foo.call_seq
|
||||||
|
assert_equal nil, foo.is_alias_for
|
||||||
|
assert_equal nil, foo.viewer
|
||||||
|
assert_equal true, foo.document_children
|
||||||
|
assert_equal true, foo.document_self
|
||||||
|
assert_equal '', foo.params
|
||||||
|
assert_equal false, foo.done_documenting
|
||||||
|
assert_equal false, foo.dont_rename_initialize
|
||||||
|
assert_equal false, foo.force_documentation
|
||||||
|
assert_equal klass, foo.parent
|
||||||
|
assert_equal false, foo.singleton
|
||||||
|
assert_equal :public, foo.visibility
|
||||||
|
assert_equal "\n", foo.text
|
||||||
|
assert_equal klass.current_section, foo.section
|
||||||
|
|
||||||
|
stream = [
|
||||||
|
tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"),
|
||||||
|
RDoc::Parser::Ruby::NEWLINE_TOKEN,
|
||||||
|
tk(:SPACE, 1, 1, nil, ''),
|
||||||
|
]
|
||||||
|
|
||||||
|
assert_equal stream, foo.token_stream
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_meta_method
|
||||||
|
content = <<-EOF
|
||||||
|
class Foo
|
||||||
|
##
|
||||||
|
# this is my method
|
||||||
|
add_my_method :foo
|
||||||
|
end
|
||||||
|
EOF
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_alias_method
|
||||||
|
content = "class Foo def foo() end; alias_method :foo2, :foo end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo2 = @top_level.classes.first.method_list.last
|
||||||
|
assert_equal 'foo2', foo2.name
|
||||||
|
assert_equal 'foo', foo2.is_alias_for.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_attr
|
||||||
|
content = "class Foo; attr :foo; end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first.attributes.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal 'R', foo.rw
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_attr_accessor
|
||||||
|
content = "class Foo; attr_accessor :foo; end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first.attributes.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal 'RW', foo.rw
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_extra_accessors
|
||||||
|
@options.extra_accessors = /^my_accessor$/
|
||||||
|
|
||||||
|
content = "class Foo; my_accessor :foo; end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first.attributes.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal '?', foo.rw
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_include
|
||||||
|
content = "class Foo; include Bar; end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first
|
||||||
|
assert_equal 'Foo', foo.name
|
||||||
|
assert_equal 1, foo.includes.length
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_module_function
|
||||||
|
content = "module Foo def foo() end; module_function :foo; end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo, s_foo = @top_level.modules.first.method_list
|
||||||
|
assert_equal 'foo', foo.name, 'instance method name'
|
||||||
|
assert_equal :private, foo.visibility, 'instance method visibility'
|
||||||
|
assert_equal false, foo.singleton, 'instance method singleton'
|
||||||
|
|
||||||
|
assert_equal 'foo', s_foo.name, 'module function name'
|
||||||
|
assert_equal :public, s_foo.visibility, 'module function visibility'
|
||||||
|
assert_equal true, s_foo.singleton, 'module function singleton'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_private
|
||||||
|
content = "class Foo private; def foo() end end"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
foo = @top_level.classes.first.method_list.first
|
||||||
|
assert_equal 'foo', foo.name
|
||||||
|
assert_equal :private, foo.visibility
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_statements_identifier_require
|
||||||
|
content = "require 'bar'"
|
||||||
|
|
||||||
|
util_parser content
|
||||||
|
|
||||||
|
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||||
|
|
||||||
|
assert_equal 1, @top_level.requires.length
|
||||||
|
end
|
||||||
|
|
||||||
|
def tk(klass, line, char, name, text)
|
||||||
|
klass = RDoc::RubyToken.const_get "Tk#{klass.to_s.upcase}"
|
||||||
|
|
||||||
|
token = if klass.instance_method(:initialize).arity == 2 then
|
||||||
|
raise ArgumentError, "name not used for #{klass}" unless name.nil?
|
||||||
|
klass.new line, char
|
||||||
|
else
|
||||||
|
klass.new line, char, name
|
||||||
|
end
|
||||||
|
|
||||||
|
token.set_text text
|
||||||
|
|
||||||
|
token
|
||||||
|
end
|
||||||
|
|
||||||
|
def util_parser(content)
|
||||||
|
@parser = RDoc::Parser::Ruby.new @top_level, @filename, content, @options,
|
||||||
|
@stats
|
||||||
|
@parser.progress = @progress
|
||||||
|
@parser
|
||||||
|
end
|
||||||
|
|
||||||
|
def util_toplevel
|
||||||
|
RDoc::TopLevel.reset
|
||||||
|
@top_level = RDoc::TopLevel.new @filename
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'rdoc/ri/formatter'
|
||||||
require 'rdoc/ri/display'
|
require 'rdoc/ri/display'
|
||||||
require 'rdoc/ri/driver'
|
require 'rdoc/ri/driver'
|
||||||
|
|
||||||
class TestRDocRIDefaultDisplay < Test::Unit::TestCase
|
class TestRdocRiDefaultDisplay < Test::Unit::TestCase
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@output = StringIO.new
|
@output = StringIO.new
|
||||||
|
@ -14,7 +14,7 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase
|
||||||
@dd = RDoc::RI::DefaultDisplay.new RDoc::RI::Formatter, @width, true,
|
@dd = RDoc::RI::DefaultDisplay.new RDoc::RI::Formatter, @width, true,
|
||||||
@output
|
@output
|
||||||
|
|
||||||
@some_method = {
|
@some_method = h \
|
||||||
'aliases' => [{'name' => 'some_method_alias'}],
|
'aliases' => [{'name' => 'some_method_alias'}],
|
||||||
'block_params' => 'block_param',
|
'block_params' => 'block_param',
|
||||||
'comment' => [RDoc::Markup::Flow::P.new('some comment')],
|
'comment' => [RDoc::Markup::Flow::P.new('some comment')],
|
||||||
|
@ -23,13 +23,12 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase
|
||||||
'name' => 'some_method',
|
'name' => 'some_method',
|
||||||
'params' => '(arg1, arg2) {|block_param| ...}',
|
'params' => '(arg1, arg2) {|block_param| ...}',
|
||||||
'source_path' => '/nonexistent',
|
'source_path' => '/nonexistent',
|
||||||
'visibility' => 'public',
|
'visibility' => 'public'
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_display_class_info
|
def test_display_class_info
|
||||||
ri_reader = nil
|
ri_reader = nil
|
||||||
klass = {
|
klass = h \
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
{ 'name' => 'attribute', 'rw' => 'RW',
|
{ 'name' => 'attribute', 'rw' => 'RW',
|
||||||
'comment' => [RDoc::Markup::Flow::P.new('attribute comment')] },
|
'comment' => [RDoc::Markup::Flow::P.new('attribute comment')] },
|
||||||
|
@ -58,8 +57,7 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase
|
||||||
'instance_method_extensions' => [
|
'instance_method_extensions' => [
|
||||||
{ 'name' => 'instance_method_extension' },
|
{ 'name' => 'instance_method_extension' },
|
||||||
],
|
],
|
||||||
'superclass_string' => 'Object',
|
'superclass_string' => 'Object'
|
||||||
}
|
|
||||||
|
|
||||||
@dd.display_class_info klass, ri_reader
|
@dd.display_class_info klass, ri_reader
|
||||||
|
|
||||||
|
@ -154,7 +152,7 @@ Attributes:
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_display_method_info_singleton
|
def test_display_method_info_singleton
|
||||||
method = {
|
method = RDoc::RI::Driver::Hash.new.update \
|
||||||
'aliases' => [],
|
'aliases' => [],
|
||||||
'block_params' => nil,
|
'block_params' => nil,
|
||||||
'comment' => nil,
|
'comment' => nil,
|
||||||
|
@ -162,8 +160,7 @@ Attributes:
|
||||||
'is_singleton' => true,
|
'is_singleton' => true,
|
||||||
'name' => 'some_method',
|
'name' => 'some_method',
|
||||||
'params' => '(arg1, arg2)',
|
'params' => '(arg1, arg2)',
|
||||||
'visibility' => 'public',
|
'visibility' => 'public'
|
||||||
}
|
|
||||||
|
|
||||||
@dd.display_method_info method
|
@dd.display_method_info method
|
||||||
|
|
||||||
|
@ -179,7 +176,7 @@ Attributes:
|
||||||
|
|
||||||
def test_display_method_list
|
def test_display_method_list
|
||||||
methods = [
|
methods = [
|
||||||
{
|
RDoc::RI::Driver::Hash.new.update(
|
||||||
"aliases" => [],
|
"aliases" => [],
|
||||||
"block_params" => nil,
|
"block_params" => nil,
|
||||||
"comment" => nil,
|
"comment" => nil,
|
||||||
|
@ -187,9 +184,9 @@ Attributes:
|
||||||
"is_singleton" => false,
|
"is_singleton" => false,
|
||||||
"name" => "some_method",
|
"name" => "some_method",
|
||||||
"params" => "()",
|
"params" => "()",
|
||||||
"visibility" => "public",
|
"visibility" => "public"
|
||||||
},
|
),
|
||||||
{
|
RDoc::RI::Driver::Hash.new.update(
|
||||||
"aliases" => [],
|
"aliases" => [],
|
||||||
"block_params" => nil,
|
"block_params" => nil,
|
||||||
"comment" => nil,
|
"comment" => nil,
|
||||||
|
@ -197,8 +194,8 @@ Attributes:
|
||||||
"is_singleton" => false,
|
"is_singleton" => false,
|
||||||
"name" => "some_other_method",
|
"name" => "some_other_method",
|
||||||
"params" => "()",
|
"params" => "()",
|
||||||
"visibility" => "public",
|
"visibility" => "public"
|
||||||
},
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@dd.display_method_list methods
|
@dd.display_method_list methods
|
||||||
|
@ -291,5 +288,9 @@ install an additional package, or ask the packager to enable ri generation.
|
||||||
assert_equal expected, @output.string
|
assert_equal expected, @output.string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def h(hash)
|
||||||
|
RDoc::RI::Driver::Hash.convert hash
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
100
test/rdoc/test_rdoc_ri_driver.rb
Normal file
100
test/rdoc/test_rdoc_ri_driver.rb
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'tmpdir'
|
||||||
|
require 'rdoc/ri/driver'
|
||||||
|
|
||||||
|
class TestRDocRIDriver < Test::Unit::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}"
|
||||||
|
@home_ri = File.join @tmpdir, 'dot_ri'
|
||||||
|
@cache_dir = File.join @home_ri, 'cache'
|
||||||
|
@class_cache = File.join @cache_dir, 'classes'
|
||||||
|
|
||||||
|
FileUtils.mkdir_p @tmpdir
|
||||||
|
FileUtils.mkdir_p @home_ri
|
||||||
|
FileUtils.mkdir_p @cache_dir
|
||||||
|
|
||||||
|
@driver = RDoc::RI::Driver.new
|
||||||
|
@driver.homepath = @home_ri
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.rm_rf @tmpdir
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method
|
||||||
|
def @driver.load_cache_for(klassname)
|
||||||
|
{ 'Foo#bar' => :found }
|
||||||
|
end
|
||||||
|
|
||||||
|
assert @driver.lookup_method('Foo#bar', 'Foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method_class_method
|
||||||
|
def @driver.load_cache_for(klassname)
|
||||||
|
{ 'Foo::Bar' => :found }
|
||||||
|
end
|
||||||
|
|
||||||
|
assert @driver.lookup_method('Foo::Bar', 'Foo::Bar')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method_class_missing
|
||||||
|
def @driver.load_cache_for(klassname) end
|
||||||
|
|
||||||
|
e = assert_raise RDoc::RI::Driver::NotFoundError do
|
||||||
|
@driver.lookup_method 'Foo#bar', 'Foo'
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 'Nothing known about Foo#bar', e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method_dot_instance
|
||||||
|
def @driver.load_cache_for(klassname)
|
||||||
|
{ 'Foo#bar' => :instance, 'Foo::bar' => :klass }
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal :instance, @driver.lookup_method('Foo.bar', 'Foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method_dot_class
|
||||||
|
def @driver.load_cache_for(klassname)
|
||||||
|
{ 'Foo::bar' => :found }
|
||||||
|
end
|
||||||
|
|
||||||
|
assert @driver.lookup_method('Foo.bar', 'Foo')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lookup_method_method_missing
|
||||||
|
def @driver.load_cache_for(klassname) {} end
|
||||||
|
|
||||||
|
e = assert_raise RDoc::RI::Driver::NotFoundError do
|
||||||
|
@driver.lookup_method 'Foo#bar', 'Foo'
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 'Nothing known about Foo#bar', e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parse_name
|
||||||
|
klass, meth = @driver.parse_name 'Foo::Bar'
|
||||||
|
|
||||||
|
assert_equal 'Foo::Bar', klass, 'Foo::Bar class'
|
||||||
|
assert_equal nil, meth, 'Foo::Bar method'
|
||||||
|
|
||||||
|
klass, meth = @driver.parse_name 'Foo#Bar'
|
||||||
|
|
||||||
|
assert_equal 'Foo', klass, 'Foo#Bar class'
|
||||||
|
assert_equal 'Bar', meth, 'Foo#Bar method'
|
||||||
|
|
||||||
|
klass, meth = @driver.parse_name 'Foo.Bar'
|
||||||
|
|
||||||
|
assert_equal 'Foo', klass, 'Foo#Bar class'
|
||||||
|
assert_equal 'Bar', meth, 'Foo#Bar method'
|
||||||
|
|
||||||
|
klass, meth = @driver.parse_name 'Foo::bar'
|
||||||
|
|
||||||
|
assert_equal 'Foo', klass, 'Foo::bar class'
|
||||||
|
assert_equal 'bar', meth, 'Foo::bar method'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue