зеркало из https://github.com/github/ruby.git
Import RDoc 3
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
d7effd506f
Коммит
2ef9c50c6e
|
@ -1,3 +1,7 @@
|
|||
Mon Dec 20 12:15:32 2010 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* lib/rdoc: Import RDoc 3.0.
|
||||
|
||||
Mon Dec 20 01:55:03 2010 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* io.c (Init_IO): Added O_DIRECT. This feature was propsed by Run Paint Run Run.
|
||||
|
|
313
lib/rdoc.rb
313
lib/rdoc.rb
|
@ -18,14 +18,16 @@ $DEBUG_RDOC = nil
|
|||
# == Roadmap
|
||||
#
|
||||
# * If you want to use RDoc to create documentation for your Ruby source files,
|
||||
# read on.
|
||||
# read the summary below, and refer to <tt>rdoc --help</tt> for command line
|
||||
# usage, and RDoc::Markup for a detailed description of RDoc's markup.
|
||||
# * If you want to generate documentation for extensions written in C, see
|
||||
# RDoc::Parser::C
|
||||
# * If you want to drive RDoc programmatically, see RDoc::RDoc.
|
||||
# * If you want to use the library to format text blocks into HTML, have a look
|
||||
# at RDoc::Markup.
|
||||
# * If you want to try writing your own HTML output template, see
|
||||
# RDoc::Generator::HTML
|
||||
# * If you want to use the library to format text blocks into HTML, look at
|
||||
# RDoc::Markup.
|
||||
# * If you want to make an RDoc plugin such as a generator or directive
|
||||
# handler see RDoc::RDoc.
|
||||
# * If you want to try writing your own output generator see RDoc::Generator.
|
||||
#
|
||||
# == Summary
|
||||
#
|
||||
|
@ -50,7 +52,7 @@ $DEBUG_RDOC = nil
|
|||
# index page contain the documentation for the primary file. In our
|
||||
# case, we could type
|
||||
#
|
||||
# % rdoc --main rdoc.rb
|
||||
# % rdoc --main README.txt
|
||||
#
|
||||
# You'll find information on the various formatting tricks you can use
|
||||
# in comment blocks in the documentation this generates.
|
||||
|
@ -62,281 +64,9 @@ $DEBUG_RDOC = nil
|
|||
# markers). If directory names are passed to RDoc, they are scanned
|
||||
# recursively for C and Ruby source files only.
|
||||
#
|
||||
# == \Options
|
||||
#
|
||||
# rdoc can be passed a variety of command-line options. In addition,
|
||||
# options can be specified via the +RDOCOPT+ environment variable, which
|
||||
# functions similarly to the +RUBYOPT+ environment variable.
|
||||
#
|
||||
# % export RDOCOPT="-S"
|
||||
#
|
||||
# will make rdoc default to inline method source code. Command-line options
|
||||
# always will override those in +RDOCOPT+.
|
||||
#
|
||||
# Run:
|
||||
#
|
||||
# rdoc --help
|
||||
#
|
||||
# for full details on rdoc's options.
|
||||
#
|
||||
# == Documenting Source Code
|
||||
#
|
||||
# Comment blocks can be written fairly naturally, either using <tt>#</tt> on
|
||||
# successive lines of the comment, or by including the comment in
|
||||
# a =begin/=end block. If you use the latter form, the =begin line must be
|
||||
# flagged with an RDoc tag:
|
||||
#
|
||||
# =begin rdoc
|
||||
# Documentation to be processed by RDoc.
|
||||
#
|
||||
# ...
|
||||
# =end
|
||||
#
|
||||
# RDoc stops processing comments if it finds a comment line containing
|
||||
# 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
|
||||
# module. Commenting can be turned back on with a line that starts with a
|
||||
# <tt>++</tt>.
|
||||
#
|
||||
# ##
|
||||
# # Extract the age and calculate the date-of-birth.
|
||||
# #--
|
||||
# # FIXME: fails if the birthday falls on February 29th
|
||||
# #++
|
||||
# # The DOB is returned as a Time object.
|
||||
#
|
||||
# def get_dob(person)
|
||||
# # ...
|
||||
# end
|
||||
#
|
||||
# Names of classes, files, and any method names containing an
|
||||
# underscore or preceded by a hash character are automatically hyperlinked
|
||||
# from comment text to their description.
|
||||
#
|
||||
# Method parameter lists are extracted and displayed with the method
|
||||
# description. If a method calls +yield+, then the parameters passed to yield
|
||||
# will also be displayed:
|
||||
#
|
||||
# def fred
|
||||
# ...
|
||||
# yield line, address
|
||||
#
|
||||
# This will get documented as:
|
||||
#
|
||||
# fred() { |line, address| ... }
|
||||
#
|
||||
# You can override this using a comment containing ':yields: ...' immediately
|
||||
# after the method definition
|
||||
#
|
||||
# def fred # :yields: index, position
|
||||
# # ...
|
||||
#
|
||||
# yield line, address
|
||||
#
|
||||
# which will get documented as
|
||||
#
|
||||
# fred() { |index, position| ... }
|
||||
#
|
||||
# +:yields:+ is an example of a documentation directive. These appear
|
||||
# immediately after the start of the document element they are modifying.
|
||||
#
|
||||
# RDoc automatically cross-references words with underscores or camel-case.
|
||||
# To suppress cross-references, prefix the word with a \\ character. To
|
||||
# include special characters like "\\n", you'll need to use two \\
|
||||
# characters like "\\\\\\n".
|
||||
#
|
||||
# == \Markup
|
||||
#
|
||||
# * The markup engine looks for a document's natural left margin. This is
|
||||
# used as the initial margin for the document.
|
||||
#
|
||||
# * Consecutive lines starting at this margin are considered to be a
|
||||
# paragraph.
|
||||
#
|
||||
# * If a paragraph starts with a "*", "-", or with "<digit>.", then it is
|
||||
# taken to be the start of a list. The margin in increased to be the first
|
||||
# non-space following the list start flag. Subsequent lines should be
|
||||
# indented to this new margin until the list ends. For example:
|
||||
#
|
||||
# * this is a list with three paragraphs in
|
||||
# the first item. This is the first paragraph.
|
||||
#
|
||||
# And this is the second paragraph.
|
||||
#
|
||||
# 1. This is an indented, numbered list.
|
||||
# 2. This is the second item in that list
|
||||
#
|
||||
# This is the third conventional paragraph in the
|
||||
# first list item.
|
||||
#
|
||||
# * This is the second item in the original list
|
||||
#
|
||||
# * You can also construct labeled lists, sometimes called description
|
||||
# or definition lists. Do this by putting the label in square brackets
|
||||
# and indenting the list body:
|
||||
#
|
||||
# [cat] a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# [ant] a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# A minor variation on labeled lists uses two colons to separate the
|
||||
# label from the list body:
|
||||
#
|
||||
# cat:: a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# ant:: a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# This latter style guarantees that the list bodies' left margins are
|
||||
# aligned: think of them as a two column table.
|
||||
#
|
||||
# * Any line that starts to the right of the current margin is treated
|
||||
# as verbatim text. This is useful for code listings. The example of a
|
||||
# list above is also verbatim text.
|
||||
#
|
||||
# * A line starting with an equals sign (=) is treated as a
|
||||
# heading. Level one headings have one equals sign, level two headings
|
||||
# have two,and so on.
|
||||
#
|
||||
# * A line starting with three or more hyphens (at the current indent)
|
||||
# generates a horizontal rule. The more hyphens, the thicker the rule
|
||||
# (within reason, and if supported by the output device)
|
||||
#
|
||||
# * You can use markup within text (except verbatim) to change the
|
||||
# appearance of parts of that text. Out of the box, RDoc::Markup
|
||||
# supports word-based and general markup.
|
||||
#
|
||||
# Word-based markup uses flag characters around individual words:
|
||||
#
|
||||
# [<tt>\*word*</tt>] displays word in a *bold* font
|
||||
# [<tt>\_word_</tt>] displays word in an _emphasized_ font
|
||||
# [<tt>\+word+</tt>] displays word in a +code+ font
|
||||
#
|
||||
# General markup affects text between a start delimiter and and end
|
||||
# delimiter. Not surprisingly, these delimiters look like HTML markup.
|
||||
#
|
||||
# [<tt>\<b>text...</b></tt>] displays word in a *bold* font
|
||||
# [<tt>\<em>text...</em></tt>] displays word in an _emphasized_ font
|
||||
# [<tt>\<i>text...</i></tt>] displays word in an <i>italicized</i> font
|
||||
# [<tt>\<tt>text...\</tt></tt>] displays word in a +code+ font
|
||||
#
|
||||
# Unlike conventional Wiki markup, general markup can cross line
|
||||
# boundaries. You can turn off the interpretation of markup by
|
||||
# preceding the first character with a backslash. This only works for
|
||||
# simple markup, not HTML-style markup.
|
||||
#
|
||||
# * Hyperlinks to the web starting http:, mailto:, ftp:, or www. are
|
||||
# recognized. An HTTP url that references an external image file is
|
||||
# converted into an inline \<IMG..>. Hyperlinks starting 'link:' are
|
||||
# assumed to refer to local files whose path is relative to the --op
|
||||
# directory.
|
||||
#
|
||||
# Hyperlinks can also be of the form <tt>label</tt>[url], in which
|
||||
# case the label is used in the displayed text, and +url+ is
|
||||
# used as the target. If +label+ contains multiple words,
|
||||
# put it in braces: <em>{multi word label}[</em>url<em>]</em>.
|
||||
#
|
||||
# Example hyperlinks:
|
||||
#
|
||||
# link:RDoc.html
|
||||
# http://rdoc.rubyforge.org
|
||||
# mailto:user@example.com
|
||||
# {RDoc Documentation}[http://rdoc.rubyforge.org]
|
||||
# {RDoc Markup}[link:RDoc/Markup.html]
|
||||
#
|
||||
# == Directives
|
||||
#
|
||||
# [+:nodoc:+ / +:nodoc:+ all]
|
||||
# This directive prevents documentation for the element from
|
||||
# being generated. For classes and modules, the methods, aliases,
|
||||
# constants, and attributes directly within the affected class or
|
||||
# module also will be omitted. By default, though, modules and
|
||||
# classes within that class of module _will_ be documented. This is
|
||||
# turned off by adding the +all+ modifier.
|
||||
#
|
||||
# module MyModule # :nodoc:
|
||||
# class Input
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# module OtherModule # :nodoc: all
|
||||
# class Output
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# In the above code, only class <tt>MyModule::Input</tt> will be documented.
|
||||
# The +:nodoc:+ directive is global across all files for the class or module
|
||||
# to which it applies, so use +:stopdoc:+/+:startdoc:+ to suppress
|
||||
# documentation only for a particular set of methods, etc.
|
||||
#
|
||||
# [+:doc:+]
|
||||
# Forces a method or attribute to be documented even if it wouldn't be
|
||||
# otherwise. Useful if, for example, you want to include documentation of a
|
||||
# particular private method.
|
||||
#
|
||||
# [+:notnew:+]
|
||||
# Only applicable to the +initialize+ instance method. Normally RDoc
|
||||
# assumes that the documentation and parameters for +initialize+ are
|
||||
# actually for the +new+ method, and so fakes out a +new+ for the class.
|
||||
# The +:notnew:+ modifier stops this. Remember that +initialize+ is private,
|
||||
# so you won't see the documentation unless you use the +-a+ command line
|
||||
# option.
|
||||
#
|
||||
# Comment blocks can contain other directives:
|
||||
#
|
||||
# [<tt>:section: title</tt>]
|
||||
# Starts a new section in the output. The title following +:section:+ is
|
||||
# used as the section heading, and the remainder of the comment containing
|
||||
# the section is used as introductory text. Subsequent methods, aliases,
|
||||
# attributes, and classes will be documented in this section. A :section:
|
||||
# comment block may have one or more lines before the :section: directive.
|
||||
# These will be removed, and any identical lines at the end of the block are
|
||||
# also removed. This allows you to add visual cues such as:
|
||||
#
|
||||
# # ----------------------------------------
|
||||
# # :section: My Section
|
||||
# # This is the section that I wrote.
|
||||
# # See it glisten in the noon-day sun.
|
||||
# # ----------------------------------------
|
||||
#
|
||||
# [+:call-seq:+]
|
||||
# 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
|
||||
# yield arguments.
|
||||
#
|
||||
# [+:include:+ _filename_]
|
||||
# \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
|
||||
# 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 :include: directive.
|
||||
#
|
||||
# [+:title:+ _text_]
|
||||
# Sets the title for the document. Equivalent to the <tt>--title</tt>
|
||||
# command line parameter. (The command line parameter overrides any :title:
|
||||
# directive in the source).
|
||||
#
|
||||
# [+:enddoc:+]
|
||||
# Document nothing further at the current level.
|
||||
#
|
||||
# [+:main:+ _name_]
|
||||
# Equivalent to the <tt>--main</tt> command line parameter.
|
||||
#
|
||||
# [+:stopdoc:+ / +:startdoc:+]
|
||||
# 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
|
||||
# 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,
|
||||
# disables documentation for the entire class or module.
|
||||
#
|
||||
# Further directives can be found in RDoc::Parser::Ruby and RDoc::Parser::C
|
||||
#
|
||||
# == 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.
|
||||
#
|
||||
|
@ -345,24 +75,6 @@ $DEBUG_RDOC = nil
|
|||
# * 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
|
||||
# parser for irb and the rtags package.
|
||||
#
|
||||
# * Charset patch from MoonWolf.
|
||||
#
|
||||
# * Rich Kilmer wrote the kilmer.rb output template.
|
||||
#
|
||||
# * Dan Brickley led the design of the RDF format.
|
||||
#
|
||||
# == License
|
||||
#
|
||||
# RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers. It
|
||||
# is free software, and may be redistributed under the terms specified
|
||||
# in the README file of the Ruby distribution.
|
||||
#
|
||||
# == Warranty
|
||||
#
|
||||
# This software is provided "as is" and without any express or implied
|
||||
# warranties, including, without limitation, the implied warranties of
|
||||
# merchantibility and fitness for a particular purpose.
|
||||
|
||||
module RDoc
|
||||
|
||||
|
@ -383,7 +95,12 @@ module RDoc
|
|||
##
|
||||
# RDoc version you are using
|
||||
|
||||
VERSION = '2.5.8'
|
||||
VERSION = '3.0'
|
||||
|
||||
##
|
||||
# Method visibilities
|
||||
|
||||
VISIBILITIES = [:public, :protected, :private]
|
||||
|
||||
##
|
||||
# Name of the dotfile that contains the description of files to be processed
|
||||
|
|
|
@ -3,41 +3,77 @@ require 'rdoc/code_object'
|
|||
##
|
||||
# Represent an alias, which is an old_name/new_name pair associated with a
|
||||
# particular context
|
||||
#--
|
||||
# TODO implement Alias as a proxy to a method/attribute, inheriting from
|
||||
# MethodAttr
|
||||
|
||||
class RDoc::Alias < RDoc::CodeObject
|
||||
|
||||
##
|
||||
# Allow comments to be overridden
|
||||
# Aliased method's name
|
||||
|
||||
attr_writer :comment
|
||||
attr_reader :new_name
|
||||
|
||||
alias name new_name
|
||||
|
||||
##
|
||||
# Aliased name
|
||||
# Aliasee method's name
|
||||
|
||||
attr_accessor :new_name
|
||||
attr_reader :old_name
|
||||
|
||||
##
|
||||
# Aliasee's name
|
||||
# Is this an alias declared in a singleton context?
|
||||
|
||||
attr_accessor :old_name
|
||||
attr_accessor :singleton
|
||||
|
||||
##
|
||||
# Source file token stream
|
||||
|
||||
attr_accessor :text
|
||||
attr_reader :text
|
||||
|
||||
##
|
||||
# Creates a new Alias with a token stream of +text+ that aliases +old_name+
|
||||
# to +new_name+ and has +comment+
|
||||
# to +new_name+, has +comment+ and is a +singleton+ context.
|
||||
|
||||
def initialize(text, old_name, new_name, comment)
|
||||
def initialize(text, old_name, new_name, comment, singleton = false)
|
||||
super()
|
||||
|
||||
@text = text
|
||||
@singleton = singleton
|
||||
@old_name = old_name
|
||||
@new_name = new_name
|
||||
self.comment = comment
|
||||
end
|
||||
|
||||
##
|
||||
# Order by #singleton then #new_name
|
||||
|
||||
def <=>(other)
|
||||
[@singleton ? 0 : 1, new_name] <=> [other.singleton ? 0 : 1, other.new_name]
|
||||
end
|
||||
|
||||
##
|
||||
# HTML fragment reference for this alias
|
||||
|
||||
def aref
|
||||
type = singleton ? 'c' : 'i'
|
||||
"#alias-#{type}-#{html_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# Full old name including namespace
|
||||
|
||||
def full_old_name
|
||||
@full_name || "#{parent.name}#{pretty_old_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# HTML id-friendly version of +#new_name+.
|
||||
|
||||
def html_name
|
||||
CGI.escape(@new_name.gsub('-', '-2D')).gsub('%','-').sub(/^-/, '')
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
parent_name = parent ? parent.name : '(unknown)'
|
||||
"#<%s:0x%x %s.alias_method %s, %s>" % [
|
||||
|
@ -46,8 +82,31 @@ class RDoc::Alias < RDoc::CodeObject
|
|||
]
|
||||
end
|
||||
|
||||
##
|
||||
# '::' for the alias of a singleton method/attribute, '#' for instance-level.
|
||||
|
||||
def name_prefix
|
||||
singleton ? '::' : '#'
|
||||
end
|
||||
|
||||
##
|
||||
# Old name with prefix '::' or '#'.
|
||||
|
||||
def pretty_old_name
|
||||
"#{singleton ? '::' : '#'}#{@old_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# New name with prefix '::' or '#'.
|
||||
|
||||
def pretty_new_name
|
||||
"#{singleton ? '::' : '#'}#{@new_name}"
|
||||
end
|
||||
|
||||
alias pretty_name pretty_new_name
|
||||
|
||||
def to_s # :nodoc:
|
||||
"alias: #{self.old_name} -> #{self.new_name}\n#{self.comment}"
|
||||
"alias: #{self.new_name} -> #{self.pretty_old_name} in: #{parent}"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,29 +1,12 @@
|
|||
require 'rdoc/code_object'
|
||||
require 'rdoc/tokenstream'
|
||||
require 'rdoc/method_attr'
|
||||
require 'rdoc/token_stream'
|
||||
|
||||
##
|
||||
# AnyMethod is the base class for objects representing methods
|
||||
|
||||
class RDoc::AnyMethod < RDoc::CodeObject
|
||||
class RDoc::AnyMethod < RDoc::MethodAttr
|
||||
|
||||
MARSHAL_VERSION = 1 # :nodoc:
|
||||
|
||||
include Comparable
|
||||
|
||||
##
|
||||
# Method name
|
||||
|
||||
attr_writer :name
|
||||
|
||||
##
|
||||
# public, protected, private
|
||||
|
||||
attr_accessor :visibility
|
||||
|
||||
##
|
||||
# Parameters yielded by the called block
|
||||
|
||||
attr_accessor :block_params
|
||||
MARSHAL_VERSION = 0 # :nodoc:
|
||||
|
||||
##
|
||||
# Don't rename \#initialize to \::new
|
||||
|
@ -31,76 +14,49 @@ class RDoc::AnyMethod < RDoc::CodeObject
|
|||
attr_accessor :dont_rename_initialize
|
||||
|
||||
##
|
||||
# Is this a singleton method?
|
||||
# Different ways to call this method
|
||||
|
||||
attr_accessor :singleton
|
||||
|
||||
##
|
||||
# Source file token stream
|
||||
|
||||
attr_reader :text
|
||||
|
||||
##
|
||||
# Array of other names for this method
|
||||
|
||||
attr_reader :aliases
|
||||
|
||||
##
|
||||
# The method we're aliasing
|
||||
|
||||
attr_accessor :is_alias_for
|
||||
attr_accessor :call_seq
|
||||
|
||||
##
|
||||
# Parameters for this method
|
||||
|
||||
attr_accessor :params
|
||||
|
||||
##
|
||||
# Different ways to call this method
|
||||
|
||||
attr_accessor :call_seq
|
||||
|
||||
include RDoc::TokenStream
|
||||
|
||||
def initialize(text, name)
|
||||
super()
|
||||
##
|
||||
# Creates a new AnyMethod with a token stream +text+ and +name+
|
||||
|
||||
@text = text
|
||||
@name = name
|
||||
def initialize text, name
|
||||
super
|
||||
|
||||
@aliases = []
|
||||
@block_params = nil
|
||||
@call_seq = nil
|
||||
@dont_rename_initialize = false
|
||||
@is_alias_for = nil
|
||||
@params = nil
|
||||
@parent_name = nil
|
||||
@singleton = nil
|
||||
@token_stream = nil
|
||||
@visibility = :public
|
||||
end
|
||||
|
||||
##
|
||||
# Order by #singleton then #name
|
||||
# Adds +an_alias+ as an alias for this method in +context+.
|
||||
|
||||
def <=>(other)
|
||||
[@singleton ? 0 : 1, @name] <=> [other.singleton ? 0 : 1, other.name]
|
||||
end
|
||||
def add_alias(an_alias, context)
|
||||
method = self.class.new an_alias.text, an_alias.new_name
|
||||
|
||||
##
|
||||
# Adds +method+ as an alias for this method
|
||||
|
||||
def add_alias(method)
|
||||
method.record_location an_alias.file
|
||||
method.singleton = self.singleton
|
||||
method.params = self.params
|
||||
method.visibility = self.visibility
|
||||
method.comment = an_alias.comment
|
||||
method.is_alias_for = self
|
||||
@aliases << method
|
||||
context.add_method method
|
||||
method
|
||||
end
|
||||
|
||||
##
|
||||
# HTML fragment reference for this method
|
||||
# Prefix for +aref+ is 'method'.
|
||||
|
||||
def aref
|
||||
type = singleton ? 'c' : 'i'
|
||||
|
||||
"method-#{type}-#{CGI.escape name}"
|
||||
def aref_prefix
|
||||
'method'
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -116,30 +72,6 @@ class RDoc::AnyMethod < RDoc::CodeObject
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# HTML id-friendly method name
|
||||
|
||||
def html_name
|
||||
@name.gsub(/[^a-z]+/, '-')
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
|
||||
"#<%s:0x%x %s (%s)%s>" % [
|
||||
self.class, object_id,
|
||||
full_name,
|
||||
visibility,
|
||||
alias_for,
|
||||
]
|
||||
end
|
||||
|
||||
##
|
||||
# Full method name including namespace
|
||||
|
||||
def full_name
|
||||
@full_name ||= "#{@parent ? @parent.full_name : '(unknown)'}#{pretty_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# Dumps this AnyMethod for use by ri. See also #marshal_load
|
||||
|
||||
|
@ -192,12 +124,14 @@ class RDoc::AnyMethod < RDoc::CodeObject
|
|||
end
|
||||
|
||||
array[8].each do |new_name, comment|
|
||||
add_alias RDoc::Alias.new(nil, @name, new_name, comment)
|
||||
add_alias RDoc::Alias.new(nil, @name, new_name, comment, @singleton)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Method name
|
||||
#
|
||||
# If the method has no assigned name, it extracts it from #call_seq.
|
||||
|
||||
def name
|
||||
return @name if @name
|
||||
|
@ -229,62 +163,5 @@ class RDoc::AnyMethod < RDoc::CodeObject
|
|||
params
|
||||
end
|
||||
|
||||
##
|
||||
# Name of our parent with special handling for un-marshaled methods
|
||||
|
||||
def parent_name
|
||||
@parent_name || super
|
||||
end
|
||||
|
||||
##
|
||||
# Path to this method
|
||||
|
||||
def path
|
||||
"#{@parent.path}##{aref}"
|
||||
end
|
||||
|
||||
##
|
||||
# Method name with class/instance indicator
|
||||
|
||||
def pretty_name
|
||||
"#{singleton ? '::' : '#'}#{@name}"
|
||||
end
|
||||
|
||||
def pretty_print q # :nodoc:
|
||||
alias_for = @is_alias_for ? "alias for #{@is_alias_for.name}" : nil
|
||||
|
||||
q.group 2, "[#{self.class.name} #{full_name} #{visibility}", "]" do
|
||||
if alias_for then
|
||||
q.breakable
|
||||
q.text alias_for
|
||||
end
|
||||
|
||||
if text then
|
||||
q.breakable
|
||||
q.text "text:"
|
||||
q.breakable
|
||||
q.pp @text
|
||||
end
|
||||
|
||||
unless comment.empty? then
|
||||
q.breakable
|
||||
q.text "comment:"
|
||||
q.breakable
|
||||
q.pp @comment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"#{self.class.name}: #{full_name} (#{@text})\n#{@comment}"
|
||||
end
|
||||
|
||||
##
|
||||
# Type of method (class or instance)
|
||||
|
||||
def type
|
||||
singleton ? 'class' : 'instance'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
144
lib/rdoc/attr.rb
144
lib/rdoc/attr.rb
|
@ -1,104 +1,71 @@
|
|||
require 'rdoc/code_object'
|
||||
require 'rdoc/method_attr'
|
||||
|
||||
##
|
||||
# An attribute created by \#attr, \#attr_reader, \#attr_writer or
|
||||
# \#attr_accessor
|
||||
|
||||
class RDoc::Attr < RDoc::CodeObject
|
||||
class RDoc::Attr < RDoc::MethodAttr
|
||||
|
||||
MARSHAL_VERSION = 0 # :nodoc:
|
||||
MARSHAL_VERSION = 1 # :nodoc:
|
||||
|
||||
##
|
||||
# Name of the attribute
|
||||
|
||||
attr_accessor :name
|
||||
|
||||
##
|
||||
# Is the attribute readable, writable or both?
|
||||
# Is the attribute readable ('R'), writable ('W') or both ('RW')?
|
||||
|
||||
attr_accessor :rw
|
||||
|
||||
##
|
||||
# Source file token stream
|
||||
# Creates a new Attr with body +text+, +name+, read/write status +rw+ and
|
||||
# +comment+. +singleton+ marks this as a class attribute.
|
||||
|
||||
attr_accessor :text
|
||||
def initialize(text, name, rw, comment, singleton = false)
|
||||
super text, name
|
||||
|
||||
##
|
||||
# public, protected, private
|
||||
|
||||
attr_accessor :visibility
|
||||
|
||||
def initialize(text, name, rw, comment)
|
||||
super()
|
||||
@text = text
|
||||
@name = name
|
||||
@rw = rw
|
||||
@visibility = :public
|
||||
@singleton = singleton
|
||||
self.comment = comment
|
||||
end
|
||||
|
||||
##
|
||||
# Attributes are ordered by name
|
||||
|
||||
def <=>(other)
|
||||
self.name <=> other.name
|
||||
end
|
||||
|
||||
##
|
||||
# Attributes are equal when their names and rw is identical
|
||||
# Attributes are equal when their names, singleton and rw are identical
|
||||
|
||||
def == other
|
||||
self.class == other.class and
|
||||
self.name == other.name and
|
||||
self.rw == other.rw
|
||||
self.rw == other.rw and
|
||||
self.singleton == other.singleton
|
||||
end
|
||||
|
||||
##
|
||||
# Returns nil, for duck typing with RDoc::AnyMethod
|
||||
# Add +an_alias+ as an attribute in +context+.
|
||||
|
||||
def arglists
|
||||
def add_alias(an_alias, context)
|
||||
new_attr = self.class.new(self.text, an_alias.new_name, self.rw,
|
||||
self.comment, self.singleton)
|
||||
|
||||
new_attr.record_location an_alias.file
|
||||
new_attr.visibility = self.visibility
|
||||
new_attr.is_alias_for = self
|
||||
@aliases << new_attr
|
||||
context.add_attribute new_attr
|
||||
new_attr
|
||||
end
|
||||
|
||||
##
|
||||
# Returns nil, for duck typing with RDoc::AnyMethod
|
||||
# The #aref prefix for attributes
|
||||
|
||||
def block_params
|
||||
def aref_prefix
|
||||
'attribute'
|
||||
end
|
||||
|
||||
##
|
||||
# Returns nil, for duck typing with RDoc::AnyMethod
|
||||
# Returns attr_reader, attr_writer or attr_accessor as appropriate.
|
||||
|
||||
def call_seq
|
||||
end
|
||||
|
||||
##
|
||||
# Partially bogus as Attr has no parent. For duck typing with
|
||||
# RDoc::AnyMethod.
|
||||
|
||||
def full_name
|
||||
@full_name ||= "#{@parent ? @parent.full_name : '(unknown)'}##{name}"
|
||||
end
|
||||
|
||||
##
|
||||
# An HTML id-friendly representation of #name
|
||||
|
||||
def html_name
|
||||
@name.gsub(/[^a-z]+/, '-')
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
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,
|
||||
]
|
||||
def definition
|
||||
case @rw
|
||||
when 'RW' then 'attr_accessor'
|
||||
when 'R' then 'attr_reader'
|
||||
when 'W' then 'attr_writer'
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -111,11 +78,12 @@ class RDoc::Attr < RDoc::CodeObject
|
|||
@rw,
|
||||
@visibility,
|
||||
parse(@comment),
|
||||
singleton,
|
||||
]
|
||||
end
|
||||
|
||||
##
|
||||
# Loads this AnyMethod from +array+. For a loaded AnyMethod the following
|
||||
# Loads this Attr from +array+. For a loaded Attr the following
|
||||
# methods will return cached values:
|
||||
#
|
||||
# * #full_name
|
||||
|
@ -127,51 +95,13 @@ class RDoc::Attr < RDoc::CodeObject
|
|||
@rw = array[3]
|
||||
@visibility = array[4]
|
||||
@comment = array[5]
|
||||
@singleton = array[6] || false # MARSHAL_VERSION == 0
|
||||
|
||||
@parent_name = @full_name
|
||||
end
|
||||
|
||||
##
|
||||
# Name of our parent with special handling for un-marshaled methods
|
||||
|
||||
def parent_name
|
||||
@parent_name || super
|
||||
end
|
||||
|
||||
##
|
||||
# For duck typing with RDoc::AnyMethod, returns nil
|
||||
|
||||
def params
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# URL path for this attribute
|
||||
|
||||
def path
|
||||
"#{@parent.path}##{@name}"
|
||||
end
|
||||
|
||||
##
|
||||
# For duck typing with RDoc::AnyMethod
|
||||
|
||||
def singleton
|
||||
false
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"#{type} #{name}\n#{comment}"
|
||||
end
|
||||
|
||||
##
|
||||
# Returns attr_reader, attr_writer or attr_accessor as appropriate
|
||||
|
||||
def type
|
||||
case @rw
|
||||
when 'RW' then 'attr_accessor'
|
||||
when 'R' then 'attr_reader'
|
||||
when 'W' then 'attr_writer'
|
||||
end
|
||||
"#{definition} #{name} in: #{parent}"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -8,31 +8,114 @@ class RDoc::ClassModule < RDoc::Context
|
|||
|
||||
MARSHAL_VERSION = 0 # :nodoc:
|
||||
|
||||
attr_accessor :diagram
|
||||
##
|
||||
# Constants that are aliases for this class or module
|
||||
|
||||
attr_accessor :constant_aliases
|
||||
|
||||
attr_accessor :diagram # :nodoc:
|
||||
|
||||
##
|
||||
# Class or module this constant is an alias for
|
||||
|
||||
attr_accessor :is_alias_for
|
||||
|
||||
##
|
||||
# Return a RDoc::ClassModule of class +class_type+ that is a copy
|
||||
# of module +module+. Used to promote modules to classes.
|
||||
|
||||
def self.from_module(class_type, mod)
|
||||
klass = class_type.new(mod.name)
|
||||
klass.comment = mod.comment
|
||||
klass.parent = mod.parent
|
||||
klass.section = mod.section
|
||||
klass.viewer = mod.viewer
|
||||
|
||||
klass.attributes.concat mod.attributes
|
||||
klass.method_list.concat mod.method_list
|
||||
klass.aliases.concat mod.aliases
|
||||
klass.external_aliases.concat mod.external_aliases
|
||||
klass.constants.concat mod.constants
|
||||
klass.includes.concat mod.includes
|
||||
|
||||
klass.methods_hash.update mod.methods_hash
|
||||
klass.constants_hash.update mod.constants_hash
|
||||
|
||||
klass.current_section = mod.current_section
|
||||
klass.in_files.concat mod.in_files
|
||||
klass.sections.concat mod.sections
|
||||
klass.unmatched_alias_lists = mod.unmatched_alias_lists
|
||||
klass.current_section = mod.current_section
|
||||
klass.visibility = mod.visibility
|
||||
|
||||
klass.classes_hash.update mod.classes_hash
|
||||
klass.modules_hash.update mod.modules_hash
|
||||
klass.metadata.update mod.metadata
|
||||
|
||||
klass.document_self = mod.received_nodoc ? nil : mod.document_self
|
||||
klass.document_children = mod.document_children
|
||||
klass.force_documentation = mod.force_documentation
|
||||
klass.done_documenting = mod.done_documenting
|
||||
|
||||
# update the parent of all children
|
||||
|
||||
(klass.attributes +
|
||||
klass.method_list +
|
||||
klass.aliases +
|
||||
klass.external_aliases +
|
||||
klass.constants +
|
||||
klass.includes +
|
||||
klass.classes +
|
||||
klass.modules).each do |obj|
|
||||
obj.parent = klass
|
||||
obj.full_name = nil
|
||||
end
|
||||
|
||||
klass
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a new ClassModule with +name+ with optional +superclass+
|
||||
#
|
||||
# This is a constructor for subclasses, and must never be called directly.
|
||||
|
||||
def initialize(name, superclass = 'Object')
|
||||
@diagram = nil
|
||||
@full_name = nil
|
||||
@name = name
|
||||
@superclass = superclass
|
||||
def initialize(name, superclass = nil)
|
||||
@constant_aliases = []
|
||||
@diagram = nil
|
||||
@is_alias_for = nil
|
||||
@name = name
|
||||
@superclass = superclass
|
||||
super()
|
||||
end
|
||||
|
||||
##
|
||||
# Ancestors list for this ClassModule (abstract)
|
||||
# Ancestors list for this ClassModule: the list of included modules
|
||||
# (classes will add their superclass if any).
|
||||
#
|
||||
# Returns the included classes or modules, not the includes
|
||||
# themselves. The returned values are either String or
|
||||
# RDoc::NormalModule instances (see RDoc::Include#module).
|
||||
#
|
||||
# The values are returned in reverse order of their inclusion,
|
||||
# which is the order suitable for searching methods/attributes
|
||||
# in the ancestors. The superclass, if any, comes last.
|
||||
|
||||
def ancestors
|
||||
raise NotImplementedError
|
||||
includes.map { |i| i.module }.reverse
|
||||
end
|
||||
|
||||
##
|
||||
# Clears the comment. Used by the ruby parser.
|
||||
|
||||
def clear_comment
|
||||
@comment = ''
|
||||
end
|
||||
|
||||
##
|
||||
# Appends +comment+ to the current comment, but separated by a rule. Works
|
||||
# more like <tt>+=</tt>.
|
||||
|
||||
def comment=(comment)
|
||||
def comment= comment
|
||||
return if comment.empty?
|
||||
|
||||
comment = "#{@comment}\n---\n#{normalize_comment comment}" unless
|
||||
|
@ -41,10 +124,35 @@ class RDoc::ClassModule < RDoc::Context
|
|||
super
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares this ClassModule for use by a generator.
|
||||
#
|
||||
# See RDoc::TopLevel::complete
|
||||
|
||||
def complete min_visibility
|
||||
update_aliases
|
||||
remove_nodoc_children
|
||||
update_includes
|
||||
remove_invisible min_visibility
|
||||
end
|
||||
|
||||
##
|
||||
# Looks for a symbol in the #ancestors. See Context#find_local_symbol.
|
||||
|
||||
def find_ancestor_local_symbol symbol
|
||||
ancestors.each do |m|
|
||||
next if m.is_a?(String)
|
||||
res = m.find_local_symbol(symbol)
|
||||
return res if res
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Finds a class or module with +name+ in this namespace or its descendents
|
||||
|
||||
def find_class_named(name)
|
||||
def find_class_named name
|
||||
return self if full_name == name
|
||||
return self if @name == name
|
||||
|
||||
|
@ -65,14 +173,8 @@ class RDoc::ClassModule < RDoc::Context
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# 'module' or 'class'
|
||||
|
||||
def type
|
||||
module? ? 'module' : 'class'
|
||||
end
|
||||
|
||||
def marshal_dump # :nodoc:
|
||||
# TODO must store the singleton attribute
|
||||
attrs = attributes.sort.map do |attr|
|
||||
[attr.name, attr.rw]
|
||||
end
|
||||
|
@ -106,10 +208,13 @@ class RDoc::ClassModule < RDoc::Context
|
|||
end
|
||||
|
||||
def marshal_load array # :nodoc:
|
||||
# TODO must restore the singleton attribute
|
||||
initialize_methods_etc
|
||||
@document_self = true
|
||||
@done_documenting = false
|
||||
@current_section = nil
|
||||
@parent = nil
|
||||
@visibility = nil
|
||||
|
||||
@name = array[1]
|
||||
@full_name = array[2]
|
||||
|
@ -183,6 +288,15 @@ class RDoc::ClassModule < RDoc::Context
|
|||
false
|
||||
end
|
||||
|
||||
##
|
||||
# Allows overriding the initial name.
|
||||
#
|
||||
# Used for modules and classes that are constant aliases.
|
||||
|
||||
def name= new_name
|
||||
@name = new_name
|
||||
end
|
||||
|
||||
##
|
||||
# Path to this class or module
|
||||
|
||||
|
@ -190,12 +304,52 @@ class RDoc::ClassModule < RDoc::Context
|
|||
http_url RDoc::RDoc.current.generator.class_dir
|
||||
end
|
||||
|
||||
##
|
||||
# Name to use to generate the url:
|
||||
# modules and classes that are aliases for another
|
||||
# module or classe return the name of the latter.
|
||||
|
||||
def name_for_path
|
||||
is_alias_for ? is_alias_for.full_name : full_name
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the classes and modules that are not constants
|
||||
# aliasing another class or module. For use by formatters
|
||||
# only (caches its result).
|
||||
|
||||
def non_aliases
|
||||
@non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
|
||||
end
|
||||
|
||||
##
|
||||
# Updates the child modules or classes of class/module +parent+ by
|
||||
# deleting the ones that have been removed from the documentation.
|
||||
#
|
||||
# +parent_hash+ is either <tt>parent.modules_hash</tt> or
|
||||
# <tt>parent.classes_hash</tt> and +all_hash+ is ::all_modules_hash or
|
||||
# ::all_classes_hash.
|
||||
|
||||
def remove_nodoc_children
|
||||
prefix = self.full_name + '::'
|
||||
|
||||
modules_hash.each_key do |name|
|
||||
full_name = prefix + name
|
||||
modules_hash.delete name unless RDoc::TopLevel.all_modules_hash[full_name]
|
||||
end
|
||||
|
||||
classes_hash.each_key do |name|
|
||||
full_name = prefix + name
|
||||
classes_hash.delete name unless RDoc::TopLevel.all_classes_hash[full_name]
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Get the superclass of this class. Attempts to retrieve the superclass
|
||||
# object, returns the name if it is not known.
|
||||
|
||||
def superclass
|
||||
RDoc::TopLevel.find_class_named_from(@superclass, parent) || @superclass
|
||||
RDoc::TopLevel.find_class_named(@superclass) || @superclass
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -203,12 +357,72 @@ class RDoc::ClassModule < RDoc::Context
|
|||
|
||||
def superclass=(superclass)
|
||||
raise NoMethodError, "#{full_name} is a module" if module?
|
||||
|
||||
@superclass = superclass if @superclass.nil? or @superclass == 'Object'
|
||||
@superclass = superclass
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"#{self.class}: #{full_name} #{@comment} #{super}"
|
||||
if is_alias_for then
|
||||
"#{self.class.name} #{self.full_name} -> #{is_alias_for}"
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# 'module' or 'class'
|
||||
|
||||
def type
|
||||
module? ? 'module' : 'class'
|
||||
end
|
||||
|
||||
##
|
||||
# Updates the child modules & classes by replacing the ones that are
|
||||
# aliases through a constant.
|
||||
#
|
||||
# The aliased module/class is replaced in the children and in
|
||||
# RDoc::TopLevel::all_modules_hash or RDoc::TopLevel::all_classes_hash
|
||||
# by a copy that has <tt>RDoc::ClassModule#is_alias_for</tt> set to
|
||||
# the aliased module/class, and this copy is added to <tt>#aliases</tt>
|
||||
# of the aliased module/class.
|
||||
#
|
||||
# Formatters can use the #non_aliases method to retrieve children that
|
||||
# are not aliases, for instance to list the namespace content, since
|
||||
# the aliased modules are included in the constants of the class/module,
|
||||
# that are listed separately.
|
||||
|
||||
def update_aliases
|
||||
constants.each do |const|
|
||||
next unless cm = const.is_alias_for
|
||||
cm_alias = cm.dup
|
||||
cm_alias.name = const.name
|
||||
cm_alias.parent = self
|
||||
cm_alias.full_name = nil # force update for new parent
|
||||
cm_alias.aliases.clear
|
||||
cm_alias.is_alias_for = cm
|
||||
|
||||
if cm.module? then
|
||||
RDoc::TopLevel.all_modules_hash[cm_alias.full_name] = cm_alias
|
||||
modules_hash[const.name] = cm_alias
|
||||
else
|
||||
RDoc::TopLevel.all_classes_hash[cm_alias.full_name] = cm_alias
|
||||
classes_hash[const.name] = cm_alias
|
||||
end
|
||||
|
||||
cm.aliases << cm_alias
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Deletes from #includes those whose module has been removed from the
|
||||
# documentation.
|
||||
#--
|
||||
# FIXME: includes are not reliably removed, see _possible_bug test case
|
||||
|
||||
def update_includes
|
||||
includes.reject! do |include|
|
||||
mod = include.module
|
||||
!(String === mod) && RDoc::TopLevel.all_modules_hash[mod.full_name].nil?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,15 +12,16 @@ require 'rdoc/text'
|
|||
# * RDoc::Context
|
||||
# * RDoc::TopLevel
|
||||
# * RDoc::ClassModule
|
||||
# * RDoc::AnonClass
|
||||
# * RDoc::AnonClass (never used so far)
|
||||
# * RDoc::NormalClass
|
||||
# * RDoc::NormalModule
|
||||
# * RDoc::SingleClass
|
||||
# * RDoc::AnyMethod
|
||||
# * RDoc::GhostMethod
|
||||
# * RDoc::MetaMethod
|
||||
# * RDoc::MethodAttr
|
||||
# * RDoc::Attr
|
||||
# * RDoc::AnyMethod
|
||||
# * RDoc::GhostMethod
|
||||
# * RDoc::MetaMethod
|
||||
# * RDoc::Alias
|
||||
# * RDoc::Attr
|
||||
# * RDoc::Constant
|
||||
# * RDoc::Require
|
||||
# * RDoc::Include
|
||||
|
@ -47,12 +48,17 @@ class RDoc::CodeObject
|
|||
##
|
||||
# Are we done documenting (ie, did we come across a :enddoc:)?
|
||||
|
||||
attr_accessor :done_documenting
|
||||
attr_reader :done_documenting
|
||||
|
||||
##
|
||||
# Which file this code object was defined in
|
||||
|
||||
attr_reader :file
|
||||
|
||||
##
|
||||
# Force documentation of this CodeObject
|
||||
|
||||
attr_accessor :force_documentation
|
||||
attr_reader :force_documentation
|
||||
|
||||
##
|
||||
# Hash of arbitrary metadata for this CodeObject
|
||||
|
@ -64,6 +70,11 @@ class RDoc::CodeObject
|
|||
|
||||
attr_accessor :parent
|
||||
|
||||
##
|
||||
# Did we ever receive a +:nodoc:+ directive?
|
||||
|
||||
attr_reader :received_nodoc
|
||||
|
||||
##
|
||||
# Which section are we in
|
||||
|
||||
|
@ -80,15 +91,17 @@ class RDoc::CodeObject
|
|||
# Creates a new CodeObject that will document itself and its children
|
||||
|
||||
def initialize
|
||||
@metadata = {}
|
||||
@comment = ''
|
||||
@metadata = {}
|
||||
@comment = ''
|
||||
@parent = nil
|
||||
@file = nil
|
||||
@full_name = nil
|
||||
|
||||
@document_children = true
|
||||
@document_self = true
|
||||
@done_documenting = false
|
||||
@force_documentation = false
|
||||
|
||||
@parent = nil
|
||||
@received_nodoc = false
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -108,28 +121,64 @@ class RDoc::CodeObject
|
|||
end
|
||||
|
||||
##
|
||||
# Enables or disables documentation of this CodeObject's children. Calls
|
||||
# remove_classes_and_modules when disabling.
|
||||
# Enables or disables documentation of this CodeObject's children unless it
|
||||
# has been turned off by :enddoc:
|
||||
|
||||
def document_children=(document_children)
|
||||
@document_children = document_children
|
||||
remove_classes_and_modules unless document_children
|
||||
@document_children = document_children unless @done_documenting
|
||||
end
|
||||
|
||||
##
|
||||
# Enables or disables documentation of this CodeObject. Calls
|
||||
# remove_methods_etc when disabling.
|
||||
# Enables or disables documentation of this CodeObject unless it has been
|
||||
# turned off by :enddoc:. If the argument is +nil+ it means the
|
||||
# documentation is turned off by +:nodoc:+.
|
||||
|
||||
def document_self=(document_self)
|
||||
return if @done_documenting
|
||||
|
||||
@document_self = document_self
|
||||
remove_methods_etc unless document_self
|
||||
@received_nodoc = true if document_self.nil?
|
||||
end
|
||||
|
||||
##
|
||||
# Does this class have a comment with content or is document_self false.
|
||||
# Does this object have a comment with content or is #received_nodoc true?
|
||||
|
||||
def documented?
|
||||
!(@document_self and @comment.empty?)
|
||||
@received_nodoc or !@comment.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Turns documentation on/off, and turns on/off #document_self
|
||||
# and #document_children.
|
||||
#
|
||||
# Once documentation has been turned off (by +:enddoc:+),
|
||||
# the object will refuse to turn #document_self or
|
||||
# #document_children on, so +:doc:+ and +:start_doc:+ directives
|
||||
# will have no effect in the current file.
|
||||
|
||||
def done_documenting=(value)
|
||||
@done_documenting = value
|
||||
@document_self = !value
|
||||
@document_children = @document_self
|
||||
end
|
||||
|
||||
##
|
||||
# Force the documentation of this object unless documentation
|
||||
# has been turned off by :endoc:
|
||||
#--
|
||||
# HACK untested, was assigning to an ivar
|
||||
|
||||
def force_documentation=(value)
|
||||
@force_documentation = value unless @done_documenting
|
||||
end
|
||||
|
||||
##
|
||||
# Sets the full_name overriding any computed full name.
|
||||
#
|
||||
# Set to +nil+ to clear RDoc's cached value
|
||||
|
||||
def full_name= full_name
|
||||
@full_name = full_name
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -147,23 +196,19 @@ class RDoc::CodeObject
|
|||
end
|
||||
|
||||
##
|
||||
# Callback called upon disabling documentation of children. See
|
||||
# #document_children=
|
||||
# Records the RDoc::TopLevel (file) where this code object was defined
|
||||
|
||||
def remove_classes_and_modules
|
||||
def record_location top_level
|
||||
@file = top_level
|
||||
end
|
||||
|
||||
##
|
||||
# Callback called upon disabling documentation of ourself. See
|
||||
# #document_self=
|
||||
|
||||
def remove_methods_etc
|
||||
end
|
||||
|
||||
##
|
||||
# Enable capture of documentation
|
||||
# Enable capture of documentation unless documentation has been
|
||||
# turned off by :endoc:
|
||||
|
||||
def start_doc
|
||||
return if @done_documenting
|
||||
|
||||
@document_self = true
|
||||
@document_children = true
|
||||
end
|
||||
|
|
|
@ -5,6 +5,13 @@ require 'rdoc/code_object'
|
|||
|
||||
class RDoc::Constant < RDoc::CodeObject
|
||||
|
||||
##
|
||||
# If this constant is an alias for a module or class,
|
||||
# this is the RDoc::ClassModule it is an alias for.
|
||||
# +nil+ otherwise.
|
||||
|
||||
attr_accessor :is_alias_for
|
||||
|
||||
##
|
||||
# The constant's name
|
||||
|
||||
|
@ -22,6 +29,7 @@ class RDoc::Constant < RDoc::CodeObject
|
|||
super()
|
||||
@name = name
|
||||
@value = value
|
||||
@is_alias_for = nil
|
||||
self.comment = comment
|
||||
end
|
||||
|
||||
|
@ -34,17 +42,28 @@ class RDoc::Constant < RDoc::CodeObject
|
|||
[parent_name, name] <=> [other.parent_name, other.name]
|
||||
end
|
||||
|
||||
##
|
||||
# Constants are equal when their #parent and #name is the same
|
||||
|
||||
def == other
|
||||
self.class == other.class and
|
||||
@parent == other.parent and
|
||||
@name == other.name
|
||||
end
|
||||
|
||||
##
|
||||
# A constant is documented if it has a comment, or is an alias
|
||||
# for a documented class or module.
|
||||
|
||||
def documented?
|
||||
super or is_alias_for && is_alias_for.documented?
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
"#<%s:0x%x %s::%s>" % [
|
||||
self.class, object_id,
|
||||
parent_name, @name,
|
||||
]
|
||||
"#<%s:0x%x %s::%s>" % [
|
||||
self.class, object_id,
|
||||
parent_name, @name,
|
||||
]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -54,5 +73,14 @@ class RDoc::Constant < RDoc::CodeObject
|
|||
"#{@parent.path}##{@name}"
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
parent_name = parent ? parent.full_name : '(unknown)'
|
||||
if is_alias_for
|
||||
"constant #{parent_name}::#@name -> #{is_alias_for}"
|
||||
else
|
||||
"constant #{parent_name}::#@name"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,79 @@
|
|||
require 'rdoc'
|
||||
|
||||
##
|
||||
# This class is a wrapper around File IO and Encoding that helps RDoc load
|
||||
# files and convert them to the correct encoding.
|
||||
|
||||
module RDoc::Encoding
|
||||
|
||||
##
|
||||
# Reads the contents of +filename+ and handles any encoding directives in
|
||||
# the file.
|
||||
#
|
||||
# The content will be converted to the +encoding+. If the file cannot be
|
||||
# converted a warning will be printed and nil will be returned.
|
||||
|
||||
def self.read_file filename, encoding
|
||||
content = open filename, "rb" do |f| f.read end
|
||||
|
||||
utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
|
||||
|
||||
RDoc::Encoding.set_encoding content
|
||||
|
||||
if Object.const_defined? :Encoding then
|
||||
encoding ||= Encoding.default_external
|
||||
orig_encoding = content.encoding
|
||||
|
||||
if utf8 then
|
||||
content.force_encoding Encoding::UTF_8
|
||||
content.encode! encoding
|
||||
else
|
||||
# assume the content is in our output encoding
|
||||
content.force_encoding encoding
|
||||
end
|
||||
|
||||
unless content.valid_encoding? then
|
||||
# revert and try to transcode
|
||||
content.force_encoding orig_encoding
|
||||
content.encode! encoding
|
||||
end
|
||||
|
||||
unless content.valid_encoding? then
|
||||
warn "unable to convert #{filename} to #{encoding}, skipping"
|
||||
content = nil
|
||||
end
|
||||
end
|
||||
|
||||
content
|
||||
rescue ArgumentError => e
|
||||
raise unless e.message =~ /unknown encoding name - (.*)/
|
||||
warn "unknown encoding name \"#{$1}\" for #{filename}, skipping"
|
||||
nil
|
||||
rescue Encoding::UndefinedConversionError => e
|
||||
warn "unable to convert #{e.message} for #{filename}, skipping"
|
||||
nil
|
||||
rescue Errno::EISDIR, Errno::ENOENT
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Sets the encoding of +string+ based on the magic comment
|
||||
|
||||
def self.set_encoding string
|
||||
return unless Object.const_defined? :Encoding
|
||||
|
||||
first_line = string[/\A(?:#!.*\n)?.*\n/]
|
||||
|
||||
name = case first_line
|
||||
when /^<\?xml[^?]*encoding=(["'])(.*?)\1/ then $2
|
||||
when /\b(?:en)?coding[=:]\s*([^\s;]+)/i then $1
|
||||
else return
|
||||
end
|
||||
|
||||
enc = Encoding.find name
|
||||
string.force_encoding enc if enc
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
require 'erb'
|
||||
|
||||
##
|
||||
# A subclass of ERB that writes directly to an IO. Credit to Aaron Patterson
|
||||
# and Masatoshi SEKI.
|
||||
#
|
||||
# To use:
|
||||
#
|
||||
# erbio = RDoc::ERBIO.new '<%= "hello world" %>', nil, nil
|
||||
#
|
||||
# open 'hello.txt', 'w' do |io|
|
||||
# erbio.result binding
|
||||
# end
|
||||
#
|
||||
# Note that binding must enclose the io you wish to output on.
|
||||
|
||||
class RDoc::ERBIO < ERB
|
||||
|
||||
##
|
||||
# Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize
|
||||
|
||||
def initialize str, safe_level = nil, trim_mode = nil, eoutvar = 'io'
|
||||
super
|
||||
end
|
||||
|
||||
##
|
||||
# Instructs +compiler+ how to write to +io_variable+
|
||||
|
||||
def set_eoutvar compiler, io_variable
|
||||
compiler.put_cmd = "#{io_variable}.write"
|
||||
compiler.insert_cmd = "#{io_variable}.write"
|
||||
compiler.pre_cmd = []
|
||||
compiler.post_cmd = []
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,7 +1,39 @@
|
|||
require 'rdoc'
|
||||
|
||||
##
|
||||
# Namespace for generators
|
||||
# RDoc uses generators to turn parsed source code in the form of an
|
||||
# RDoc::CodeObject tree into some form of output. RDoc comes with the HTML
|
||||
# generator RDoc::Generator::Darkfish and an ri data generator
|
||||
# RDoc::Generator::RI.
|
||||
#
|
||||
# = Registering a Generator
|
||||
#
|
||||
# Generators are registered by calling RDoc::RDoc.add_generator with the class
|
||||
# of the generator:
|
||||
#
|
||||
# class My::Awesome::Generator
|
||||
# RDoc::RDoc.add_generator self
|
||||
# end
|
||||
#
|
||||
# = Adding Options to +rdoc+
|
||||
#
|
||||
# Before option processing in +rdoc+, RDoc::Options will call ::setup_options
|
||||
# on the generator class with an RDoc::Options instance. The generator can
|
||||
# use RDoc::Options#option_parser to add command-line options to the +rdoc+
|
||||
# tool. See OptionParser for details on how to add options.
|
||||
#
|
||||
# You can extend the RDoc::Options instance with additional accesors for your
|
||||
# generator.
|
||||
#
|
||||
# = Generator Instantiation
|
||||
#
|
||||
# After parsing, RDoc::RDoc will instantiate a generator by calling
|
||||
# #initialize with an RDoc::Options instance.
|
||||
#
|
||||
# RDoc will then call #generate on the generator instance and pass in an Array
|
||||
# of RDoc::TopLevel instances, each representing a parsed file. You can use
|
||||
# the various class methods on RDoc::TopLevel and in the RDoc::CodeObject tree
|
||||
# to create your desired output format.
|
||||
|
||||
module RDoc::Generator
|
||||
end
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
# -*- mode: ruby; ruby-indent-level: 2; tab-width: 2 -*-
|
||||
# vim: noet ts=2 sts=8 sw=2
|
||||
|
||||
require 'pathname'
|
||||
require 'fileutils'
|
||||
require 'erb'
|
||||
require 'rdoc/erbio'
|
||||
|
||||
require 'rdoc/generator/markup'
|
||||
|
||||
$DARKFISH_DRYRUN = false # TODO make me non-global
|
||||
|
||||
#
|
||||
##
|
||||
# Darkfish RDoc HTML Generator
|
||||
#
|
||||
# $Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $
|
||||
|
@ -52,401 +49,314 @@ $DARKFISH_DRYRUN = false # TODO make me non-global
|
|||
#
|
||||
class RDoc::Generator::Darkfish
|
||||
|
||||
RDoc::RDoc.add_generator( self )
|
||||
RDoc::RDoc.add_generator self
|
||||
|
||||
include ERB::Util
|
||||
include ERB::Util
|
||||
|
||||
# Subversion rev
|
||||
SVNRev = %$Rev: 52 $
|
||||
# Path to this file's parent directory. Used to find templates and other
|
||||
# resources.
|
||||
|
||||
# Subversion ID
|
||||
SVNId = %$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $
|
||||
GENERATOR_DIR = File.join 'rdoc', 'generator'
|
||||
|
||||
# Path to this file's parent directory. Used to find templates and other
|
||||
# resources.
|
||||
GENERATOR_DIR = File.join 'rdoc', 'generator'
|
||||
##
|
||||
# Release Version
|
||||
|
||||
# Release Version
|
||||
VERSION = '1.1.6'
|
||||
VERSION = '2'
|
||||
|
||||
# Directory where generated classes live relative to the root
|
||||
CLASS_DIR = nil
|
||||
##
|
||||
# Initialize a few instance variables before we start
|
||||
|
||||
# Directory where generated files live relative to the root
|
||||
FILE_DIR = nil
|
||||
def initialize options
|
||||
@options = options
|
||||
|
||||
@template_dir = Pathname.new options.template_dir
|
||||
@template_cache = {}
|
||||
|
||||
#################################################################
|
||||
### C L A S S M E T H O D S
|
||||
#################################################################
|
||||
@files = nil
|
||||
@classes = nil
|
||||
|
||||
### Standard generator factory method
|
||||
def self::for( options )
|
||||
new( options )
|
||||
end
|
||||
@basedir = Pathname.pwd.expand_path
|
||||
end
|
||||
|
||||
##
|
||||
# The output directory
|
||||
|
||||
#################################################################
|
||||
### I N S T A N C E M E T H O D S
|
||||
#################################################################
|
||||
attr_reader :outputdir
|
||||
|
||||
### Initialize a few instance variables before we start
|
||||
def initialize( options )
|
||||
@options = options
|
||||
##
|
||||
# Output progress information if debugging is enabled
|
||||
|
||||
template = @options.template || 'darkfish'
|
||||
def debug_msg *msg
|
||||
return unless $DEBUG_RDOC
|
||||
$stderr.puts(*msg)
|
||||
end
|
||||
|
||||
template_dir = $LOAD_PATH.map do |path|
|
||||
File.join File.expand_path(path), GENERATOR_DIR, 'template', template
|
||||
end.find do |dir|
|
||||
File.directory? dir
|
||||
end
|
||||
##
|
||||
# Directory where generated class HTML files live relative to the output
|
||||
# dir.
|
||||
|
||||
raise RDoc::Error, "could not find template #{template.inspect}" unless
|
||||
template_dir
|
||||
def class_dir
|
||||
nil
|
||||
end
|
||||
|
||||
@template_dir = Pathname.new File.expand_path(template_dir)
|
||||
##
|
||||
# Directory where generated class HTML files live relative to the output
|
||||
# dir.
|
||||
|
||||
@files = nil
|
||||
@classes = nil
|
||||
def file_dir
|
||||
nil
|
||||
end
|
||||
|
||||
@basedir = Pathname.pwd.expand_path
|
||||
end
|
||||
##
|
||||
# Create the directories the generated docs will live in if they don't
|
||||
# already exist.
|
||||
|
||||
######
|
||||
public
|
||||
######
|
||||
def gen_sub_directories
|
||||
@outputdir.mkpath
|
||||
end
|
||||
|
||||
# The output directory
|
||||
attr_reader :outputdir
|
||||
##
|
||||
# Copy over the stylesheet into the appropriate place in the output
|
||||
# directory.
|
||||
|
||||
def write_style_sheet
|
||||
debug_msg "Copying static files"
|
||||
options = { :verbose => $DEBUG_RDOC, :noop => @options.dry_run }
|
||||
|
||||
### Output progress information if debugging is enabled
|
||||
def debug_msg( *msg )
|
||||
return unless $DEBUG_RDOC
|
||||
$stderr.puts( *msg )
|
||||
end
|
||||
FileUtils.cp @template_dir + 'rdoc.css', '.', options
|
||||
|
||||
def class_dir
|
||||
CLASS_DIR
|
||||
end
|
||||
Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path|
|
||||
next if File.directory? path
|
||||
next if File.basename(path) =~ /^\./
|
||||
|
||||
def file_dir
|
||||
FILE_DIR
|
||||
end
|
||||
dst = Pathname.new(path).relative_path_from @template_dir
|
||||
|
||||
# I suck at glob
|
||||
dst_dir = dst.dirname
|
||||
FileUtils.mkdir_p dst_dir, options unless File.exist? dst_dir
|
||||
|
||||
FileUtils.cp @template_dir + path, dst, options
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Build the initial indices and output objects based on an array of TopLevel
|
||||
# objects containing the extracted information.
|
||||
|
||||
def generate top_levels
|
||||
@outputdir = Pathname.new(@options.op_dir).expand_path(@basedir)
|
||||
|
||||
@files = top_levels.sort
|
||||
@classes = RDoc::TopLevel.all_classes_and_modules.sort
|
||||
@methods = @classes.map { |m| m.method_list }.flatten.sort
|
||||
@modsort = get_sorted_module_list(@classes)
|
||||
|
||||
# Now actually write the output
|
||||
write_style_sheet
|
||||
generate_index
|
||||
generate_class_files
|
||||
generate_file_files
|
||||
|
||||
rescue StandardError => err
|
||||
debug_msg "%s: %s\n %s" % [
|
||||
err.class.name, err.message, err.backtrace.join("\n ")
|
||||
]
|
||||
|
||||
raise
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
##
|
||||
# Return a list of the documented modules sorted by salience first, then
|
||||
# by name.
|
||||
|
||||
def get_sorted_module_list(classes)
|
||||
nscounts = classes.inject({}) do |counthash, klass|
|
||||
top_level = klass.full_name.gsub(/::.*/, '')
|
||||
counthash[top_level] ||= 0
|
||||
counthash[top_level] += 1
|
||||
|
||||
counthash
|
||||
end
|
||||
|
||||
# Sort based on how often the top level namespace occurs, and then on the
|
||||
# name of the module -- this works for projects that put their stuff into
|
||||
# a namespace, of course, but doesn't hurt if they don't.
|
||||
classes.sort_by do |klass|
|
||||
top_level = klass.full_name.gsub( /::.*/, '' )
|
||||
[nscounts[top_level] * -1, klass.full_name]
|
||||
end.select do |klass|
|
||||
klass.document_self
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Generate an index page which lists all the classes which are documented.
|
||||
|
||||
def generate_index
|
||||
template_file = @template_dir + 'index.rhtml'
|
||||
return unless template_file.exist?
|
||||
|
||||
debug_msg "Rendering the index page..."
|
||||
|
||||
out_file = @basedir + @options.op_dir + 'index.html'
|
||||
|
||||
render_template template_file, out_file do |io| binding end
|
||||
end
|
||||
|
||||
##
|
||||
# Generate a documentation file for each class
|
||||
|
||||
def generate_class_files
|
||||
template_file = @template_dir + 'classpage.rhtml'
|
||||
return unless template_file.exist?
|
||||
debug_msg "Generating class documentation in #@outputdir"
|
||||
|
||||
@classes.each do |klass|
|
||||
debug_msg " working on %s (%s)" % [klass.full_name, klass.path]
|
||||
out_file = @outputdir + klass.path
|
||||
# suppress 1.9.3 warning
|
||||
rel_prefix = rel_prefix = @outputdir.relative_path_from(out_file.dirname)
|
||||
svninfo = svninfo = self.get_svninfo(klass)
|
||||
|
||||
debug_msg " rendering #{out_file}"
|
||||
render_template template_file, out_file do |io| binding end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Generate a documentation file for each file
|
||||
|
||||
def generate_file_files
|
||||
template_file = @template_dir + 'filepage.rhtml'
|
||||
return unless template_file.exist?
|
||||
debug_msg "Generating file documentation in #@outputdir"
|
||||
|
||||
@files.each do |file|
|
||||
out_file = @outputdir + file.path
|
||||
debug_msg " working on %s (%s)" % [ file.full_name, out_file ]
|
||||
# suppress 1.9.3 warning
|
||||
rel_prefix = rel_prefix = @outputdir.relative_path_from(out_file.dirname)
|
||||
|
||||
debug_msg " rendering #{out_file}"
|
||||
render_template template_file, out_file do |io| binding end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Return a string describing the amount of time in the given number of
|
||||
# seconds in terms a human can understand easily.
|
||||
|
||||
def time_delta_string seconds
|
||||
return 'less than a minute' if seconds < 60
|
||||
return "#{seconds / 60} minute#{seconds / 60 == 1 ? '' : 's'}" if
|
||||
seconds < 3000 # 50 minutes
|
||||
return 'about one hour' if seconds < 5400 # 90 minutes
|
||||
return "#{seconds / 3600} hours" if seconds < 64800 # 18 hours
|
||||
return 'one day' if seconds < 86400 # 1 day
|
||||
return 'about one day' if seconds < 172800 # 2 days
|
||||
return "#{seconds / 86400} days" if seconds < 604800 # 1 week
|
||||
return 'about one week' if seconds < 1209600 # 2 week
|
||||
return "#{seconds / 604800} weeks" if seconds < 7257600 # 3 months
|
||||
return "#{seconds / 2419200} months" if seconds < 31536000 # 1 year
|
||||
return "#{seconds / 31536000} years"
|
||||
end
|
||||
|
||||
# %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $"
|
||||
SVNID_PATTERN = /
|
||||
\$Id:\s
|
||||
(\S+)\s # filename
|
||||
(\d+)\s # rev
|
||||
(\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD)
|
||||
(\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ)
|
||||
(\w+)\s # committer
|
||||
\$$
|
||||
/x
|
||||
|
||||
##
|
||||
# Try to extract Subversion information out of the first constant whose
|
||||
# value looks like a subversion Id tag. If no matching constant is found,
|
||||
# and empty hash is returned.
|
||||
|
||||
def get_svninfo klass
|
||||
constants = klass.constants or return {}
|
||||
|
||||
constants.find { |c| c.value =~ SVNID_PATTERN } or return {}
|
||||
|
||||
filename, rev, date, time, committer = $~.captures
|
||||
commitdate = Time.parse "#{date} #{time}"
|
||||
|
||||
return {
|
||||
:filename => filename,
|
||||
:rev => Integer(rev),
|
||||
:commitdate => commitdate,
|
||||
:commitdelta => time_delta_string(Time.now - commitdate),
|
||||
:committer => committer,
|
||||
}
|
||||
end
|
||||
|
||||
##
|
||||
# Load and render the erb template in the given +template_file+ and write
|
||||
# it out to +out_file+.
|
||||
#
|
||||
# Both +template_file+ and +out_file+ should be Pathname-like objects.
|
||||
#
|
||||
# An io will be yielded which must be captured by binding in the caller.
|
||||
|
||||
def render_template template_file, out_file # :yield: io
|
||||
template = template_for template_file
|
||||
|
||||
unless @options.dry_run then
|
||||
debug_msg "Outputting to %s" % [out_file.expand_path]
|
||||
|
||||
out_file.dirname.mkpath
|
||||
out_file.open 'w', 0644 do |io|
|
||||
io.set_encoding @options.encoding if Object.const_defined? :Encoding
|
||||
|
||||
context = yield io
|
||||
|
||||
template_result template, context, template_file
|
||||
end
|
||||
else
|
||||
context = yield nil
|
||||
|
||||
output = template_result template, context, template_file
|
||||
|
||||
debug_msg " would have written %d characters to %s" % [
|
||||
output.length, out_file.expand_path
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Creates the result for +template+ with +context+. If an error is raised a
|
||||
# Pathname +template_file+ will indicate the file where the error occurred.
|
||||
|
||||
def template_result template, context, template_file
|
||||
template.filename = template_file.to_s
|
||||
template.result context
|
||||
rescue NoMethodError => e
|
||||
raise RDoc::Error, "Error while evaluating %s: %s" % [
|
||||
template_file.expand_path,
|
||||
e.message,
|
||||
], e.backtrace
|
||||
end
|
||||
|
||||
##
|
||||
# Retrieves a cache template for +file+, if present, or fills the cache.
|
||||
|
||||
def template_for file
|
||||
template = @template_cache[file]
|
||||
|
||||
return template if template
|
||||
|
||||
klass = @options.dry_run ? ERB : RDoc::ERBIO
|
||||
|
||||
template = klass.new file.read, nil, '<>'
|
||||
@template_cache[file] = template
|
||||
template
|
||||
end
|
||||
|
||||
### Create the directories the generated docs will live in if
|
||||
### they don't already exist.
|
||||
def gen_sub_directories
|
||||
@outputdir.mkpath
|
||||
end
|
||||
|
||||
### Copy over the stylesheet into the appropriate place in the output
|
||||
### directory.
|
||||
def write_style_sheet
|
||||
debug_msg "Copying static files"
|
||||
options = { :verbose => $DEBUG_RDOC, :noop => $DARKFISH_DRYRUN }
|
||||
|
||||
FileUtils.cp @template_dir + 'rdoc.css', '.', options
|
||||
|
||||
Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path|
|
||||
next if File.directory? path
|
||||
next if path =~ /#{File::SEPARATOR}\./
|
||||
|
||||
dst = Pathname.new(path).relative_path_from @template_dir
|
||||
|
||||
# I suck at glob
|
||||
dst_dir = dst.dirname
|
||||
FileUtils.mkdir_p dst_dir, options unless File.exist? dst_dir
|
||||
|
||||
FileUtils.cp @template_dir + path, dst, options
|
||||
end
|
||||
end
|
||||
|
||||
### Build the initial indices and output objects
|
||||
### based on an array of TopLevel objects containing
|
||||
### the extracted information.
|
||||
def generate( top_levels )
|
||||
@outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir )
|
||||
|
||||
@files = top_levels.sort
|
||||
@classes = RDoc::TopLevel.all_classes_and_modules.sort
|
||||
@methods = @classes.map { |m| m.method_list }.flatten.sort
|
||||
@modsort = get_sorted_module_list( @classes )
|
||||
|
||||
# Now actually write the output
|
||||
write_style_sheet
|
||||
generate_index
|
||||
generate_class_files
|
||||
generate_file_files
|
||||
|
||||
rescue StandardError => err
|
||||
debug_msg "%s: %s\n %s" % [ err.class.name, err.message, err.backtrace.join("\n ") ]
|
||||
raise
|
||||
end
|
||||
|
||||
#########
|
||||
protected
|
||||
#########
|
||||
|
||||
### Return a list of the documented modules sorted by salience first, then
|
||||
### by name.
|
||||
def get_sorted_module_list( classes )
|
||||
nscounts = classes.inject({}) do |counthash, klass|
|
||||
top_level = klass.full_name.gsub( /::.*/, '' )
|
||||
counthash[top_level] ||= 0
|
||||
counthash[top_level] += 1
|
||||
|
||||
counthash
|
||||
end
|
||||
|
||||
# Sort based on how often the top level namespace occurs, and then on the
|
||||
# name of the module -- this works for projects that put their stuff into
|
||||
# a namespace, of course, but doesn't hurt if they don't.
|
||||
classes.sort_by do |klass|
|
||||
top_level = klass.full_name.gsub( /::.*/, '' )
|
||||
[
|
||||
nscounts[ top_level ] * -1,
|
||||
klass.full_name
|
||||
]
|
||||
end.select do |klass|
|
||||
klass.document_self
|
||||
end
|
||||
end
|
||||
|
||||
### Generate an index page which lists all the classes which
|
||||
### are documented.
|
||||
def generate_index
|
||||
template_file = @template_dir + 'index.rhtml'
|
||||
return unless template_file.exist?
|
||||
|
||||
debug_msg "Rendering the index page..."
|
||||
|
||||
template_src = template_file.read
|
||||
template = ERB.new( template_src, nil, '<>' )
|
||||
template.filename = template_file.to_s
|
||||
context = binding()
|
||||
|
||||
output = nil
|
||||
|
||||
begin
|
||||
output = template.result( context )
|
||||
rescue NoMethodError => err
|
||||
raise RDoc::Error, "Error while evaluating %s: %s (at %p)" % [
|
||||
template_file,
|
||||
err.message,
|
||||
eval( "_erbout[-50,50]", context )
|
||||
], err.backtrace
|
||||
end
|
||||
|
||||
outfile = @basedir + @options.op_dir + 'index.html'
|
||||
unless $DARKFISH_DRYRUN
|
||||
debug_msg "Outputting to %s" % [outfile.expand_path]
|
||||
outfile.open( 'w', 0644 ) do |fh|
|
||||
fh.print( output )
|
||||
end
|
||||
else
|
||||
debug_msg "Would have output to %s" % [outfile.expand_path]
|
||||
end
|
||||
end
|
||||
|
||||
### Generate a documentation file for each class
|
||||
def generate_class_files
|
||||
template_file = @template_dir + 'classpage.rhtml'
|
||||
return unless template_file.exist?
|
||||
debug_msg "Generating class documentation in #@outputdir"
|
||||
|
||||
@classes.each do |klass|
|
||||
debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ]
|
||||
outfile = @outputdir + klass.path
|
||||
rel_prefix = @outputdir.relative_path_from( outfile.dirname )
|
||||
svninfo = self.get_svninfo( klass )
|
||||
|
||||
debug_msg " rendering #{outfile}"
|
||||
self.render_template( template_file, binding(), outfile )
|
||||
end
|
||||
end
|
||||
|
||||
### Generate a documentation file for each file
|
||||
def generate_file_files
|
||||
template_file = @template_dir + 'filepage.rhtml'
|
||||
return unless template_file.exist?
|
||||
debug_msg "Generating file documentation in #@outputdir"
|
||||
|
||||
@files.each do |file|
|
||||
outfile = @outputdir + file.path
|
||||
debug_msg " working on %s (%s)" % [ file.full_name, outfile ]
|
||||
rel_prefix = @outputdir.relative_path_from( outfile.dirname )
|
||||
|
||||
debug_msg " rendering #{outfile}"
|
||||
self.render_template( template_file, binding(), outfile )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
### Return a string describing the amount of time in the given number of
|
||||
### seconds in terms a human can understand easily.
|
||||
def time_delta_string( seconds )
|
||||
return 'less than a minute' if seconds < 1.minute
|
||||
return (seconds / 1.minute).to_s + ' minute' + (seconds/60 == 1 ? '' : 's') if seconds < 50.minutes
|
||||
return 'about one hour' if seconds < 90.minutes
|
||||
return (seconds / 1.hour).to_s + ' hours' if seconds < 18.hours
|
||||
return 'one day' if seconds < 1.day
|
||||
return 'about one day' if seconds < 2.days
|
||||
return (seconds / 1.day).to_s + ' days' if seconds < 1.week
|
||||
return 'about one week' if seconds < 2.week
|
||||
return (seconds / 1.week).to_s + ' weeks' if seconds < 3.months
|
||||
return (seconds / 1.month).to_s + ' months' if seconds < 1.year
|
||||
return (seconds / 1.year).to_s + ' years'
|
||||
end
|
||||
|
||||
|
||||
# %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $"
|
||||
SVNID_PATTERN = /
|
||||
\$Id:\s
|
||||
(\S+)\s # filename
|
||||
(\d+)\s # rev
|
||||
(\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD)
|
||||
(\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ)
|
||||
(\w+)\s # committer
|
||||
\$$
|
||||
/x
|
||||
|
||||
### Try to extract Subversion information out of the first constant whose value looks like
|
||||
### a subversion Id tag. If no matching constant is found, and empty hash is returned.
|
||||
def get_svninfo( klass )
|
||||
constants = klass.constants or return {}
|
||||
|
||||
constants.find {|c| c.value =~ SVNID_PATTERN } or return {}
|
||||
|
||||
filename, rev, date, time, committer = $~.captures
|
||||
commitdate = Time.parse( date + ' ' + time )
|
||||
|
||||
return {
|
||||
:filename => filename,
|
||||
:rev => Integer( rev ),
|
||||
:commitdate => commitdate,
|
||||
:commitdelta => time_delta_string( Time.now.to_i - commitdate.to_i ),
|
||||
:committer => committer,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
### Load and render the erb template in the given +template_file+ within the
|
||||
### specified +context+ (a Binding object) and write it out to +outfile+.
|
||||
### Both +template_file+ and +outfile+ should be Pathname-like objects.
|
||||
|
||||
def render_template( template_file, context, outfile )
|
||||
template_src = template_file.read
|
||||
template = ERB.new( template_src, nil, '<>' )
|
||||
template.filename = template_file.to_s
|
||||
|
||||
output = begin
|
||||
template.result( context )
|
||||
rescue NoMethodError => err
|
||||
raise RDoc::Error, "Error while evaluating %s: %s (at %p)" % [
|
||||
template_file.to_s,
|
||||
err.message,
|
||||
eval( "_erbout[-50,50]", context )
|
||||
], err.backtrace
|
||||
end
|
||||
|
||||
unless $DARKFISH_DRYRUN
|
||||
outfile.dirname.mkpath
|
||||
outfile.open( 'w', 0644 ) do |ofh|
|
||||
ofh.print( output )
|
||||
end
|
||||
else
|
||||
debug_msg " would have written %d bytes to %s" %
|
||||
[ output.length, outfile ]
|
||||
end
|
||||
end
|
||||
|
||||
end # Roc::Generator::Darkfish
|
||||
|
||||
# :stopdoc:
|
||||
|
||||
### Time constants
|
||||
module TimeConstantMethods # :nodoc:
|
||||
|
||||
### Number of seconds (returns receiver unmodified)
|
||||
def seconds
|
||||
return self
|
||||
end
|
||||
alias_method :second, :seconds
|
||||
|
||||
### Returns number of seconds in <receiver> minutes
|
||||
def minutes
|
||||
return self * 60
|
||||
end
|
||||
alias_method :minute, :minutes
|
||||
|
||||
### Returns the number of seconds in <receiver> hours
|
||||
def hours
|
||||
return self * 60.minutes
|
||||
end
|
||||
alias_method :hour, :hours
|
||||
|
||||
### Returns the number of seconds in <receiver> days
|
||||
def days
|
||||
return self * 24.hours
|
||||
end
|
||||
alias_method :day, :days
|
||||
|
||||
### Return the number of seconds in <receiver> weeks
|
||||
def weeks
|
||||
return self * 7.days
|
||||
end
|
||||
alias_method :week, :weeks
|
||||
|
||||
### Returns the number of seconds in <receiver> fortnights
|
||||
def fortnights
|
||||
return self * 2.weeks
|
||||
end
|
||||
alias_method :fortnight, :fortnights
|
||||
|
||||
### Returns the number of seconds in <receiver> months (approximate)
|
||||
def months
|
||||
return self * 30.days
|
||||
end
|
||||
alias_method :month, :months
|
||||
|
||||
### Returns the number of seconds in <receiver> years (approximate)
|
||||
def years
|
||||
return (self * 365.25.days).to_i
|
||||
end
|
||||
alias_method :year, :years
|
||||
|
||||
|
||||
### Returns the Time <receiver> number of seconds before the
|
||||
### specified +time+. E.g., 2.hours.before( header.expiration )
|
||||
def before( time )
|
||||
return time - self
|
||||
end
|
||||
|
||||
|
||||
### Returns the Time <receiver> number of seconds ago. (e.g.,
|
||||
### expiration > 2.hours.ago )
|
||||
def ago
|
||||
return self.before( ::Time.now )
|
||||
end
|
||||
|
||||
|
||||
### Returns the Time <receiver> number of seconds after the given +time+.
|
||||
### E.g., 10.minutes.after( header.expiration )
|
||||
def after( time )
|
||||
return time + self
|
||||
end
|
||||
|
||||
# Reads best without arguments: 10.minutes.from_now
|
||||
def from_now
|
||||
return self.after( ::Time.now )
|
||||
end
|
||||
end # module TimeConstantMethods
|
||||
|
||||
|
||||
# Extend Numeric with time constants
|
||||
class Numeric # :nodoc:
|
||||
include TimeConstantMethods
|
||||
end
|
||||
|
||||
|
|
|
@ -36,8 +36,9 @@ module RDoc::Generator::Markup
|
|||
return @formatter if defined? @formatter
|
||||
|
||||
show_hash = RDoc::RDoc.current.options.show_hash
|
||||
hyperlink_all = RDoc::RDoc.current.options.hyperlink_all
|
||||
this = RDoc::Context === self ? self : @parent
|
||||
@formatter = RDoc::Markup::ToHtmlCrossref.new this.path, this, show_hash
|
||||
@formatter = RDoc::Markup::ToHtmlCrossref.new this.path, this, show_hash, hyperlink_all
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -57,36 +58,65 @@ end
|
|||
|
||||
class RDoc::AnyMethod
|
||||
|
||||
##
|
||||
# Maps RDoc::RubyToken classes to CSS class names
|
||||
|
||||
STYLE_MAP = {
|
||||
RDoc::RubyToken::TkCONSTANT => 'ruby-constant',
|
||||
RDoc::RubyToken::TkKW => 'ruby-keyword',
|
||||
RDoc::RubyToken::TkIVAR => 'ruby-ivar',
|
||||
RDoc::RubyToken::TkOp => 'ruby-operator',
|
||||
RDoc::RubyToken::TkId => 'ruby-identifier',
|
||||
RDoc::RubyToken::TkNode => 'ruby-node',
|
||||
RDoc::RubyToken::TkCOMMENT => 'ruby-comment',
|
||||
RDoc::RubyToken::TkREGEXP => 'ruby-regexp',
|
||||
RDoc::RubyToken::TkSTRING => 'ruby-string',
|
||||
RDoc::RubyToken::TkVal => 'ruby-value',
|
||||
}
|
||||
|
||||
include RDoc::Generator::Markup
|
||||
|
||||
@add_line_numbers = false
|
||||
|
||||
class << self
|
||||
##
|
||||
# Allows controlling whether <tt>#markup_code</tt> adds line numbers to
|
||||
# the source code.
|
||||
|
||||
attr_accessor :add_line_numbers
|
||||
end
|
||||
|
||||
##
|
||||
# Prepend +src+ with line numbers. Relies on the first line of a source
|
||||
# code listing having:
|
||||
#
|
||||
# # File xxxxx, line dddd
|
||||
# # File xxxxx, line dddd
|
||||
#
|
||||
# If it has, line numbers are added an ', line dddd' is removed.
|
||||
|
||||
def add_line_numbers(src)
|
||||
if src =~ /\A.*, line (\d+)/ then
|
||||
first = $1.to_i - 1
|
||||
last = first + src.count("\n")
|
||||
size = last.to_s.length
|
||||
return unless src.sub!(/\A(.*)(, line (\d+))/, '\1')
|
||||
first = $3.to_i - 1
|
||||
last = first + src.count("\n")
|
||||
size = last.to_s.length
|
||||
|
||||
line = first
|
||||
src.gsub!(/^/) do
|
||||
res = if line == first then
|
||||
" " * (size + 2)
|
||||
else
|
||||
"%2$*1$d: " % [size, line]
|
||||
end
|
||||
line = first
|
||||
src.gsub!(/^/) do
|
||||
res = if line == first then
|
||||
" " * (size + 1)
|
||||
else
|
||||
"<span class=\"line-num\">%2$*1$d</span> " % [size, line]
|
||||
end
|
||||
|
||||
line += 1
|
||||
res
|
||||
end
|
||||
line += 1
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Turns the method's token stream into HTML
|
||||
# Turns the method's token stream into HTML.
|
||||
#
|
||||
# Prepends line numbers if +add_line_numbers+ is true.
|
||||
|
||||
def markup_code
|
||||
return '' unless @token_stream
|
||||
|
@ -95,32 +125,32 @@ class RDoc::AnyMethod
|
|||
|
||||
@token_stream.each do |t|
|
||||
next unless t
|
||||
# style = STYLE_MAP[t.class]
|
||||
style = case t
|
||||
when RDoc::RubyToken::TkCONSTANT then "ruby-constant"
|
||||
when RDoc::RubyToken::TkKW then "ruby-keyword kw"
|
||||
when RDoc::RubyToken::TkIVAR then "ruby-ivar"
|
||||
when RDoc::RubyToken::TkOp then "ruby-operator"
|
||||
when RDoc::RubyToken::TkId then "ruby-identifier"
|
||||
when RDoc::RubyToken::TkNode then "ruby-node"
|
||||
when RDoc::RubyToken::TkCOMMENT then "ruby-comment cmt"
|
||||
when RDoc::RubyToken::TkREGEXP then "ruby-regexp re"
|
||||
when RDoc::RubyToken::TkSTRING then "ruby-value str"
|
||||
when RDoc::RubyToken::TkVal then "ruby-value"
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
style = STYLE_MAP[t.class]
|
||||
|
||||
text = CGI.escapeHTML t.text
|
||||
|
||||
if style
|
||||
if style then
|
||||
src << "<span class=\"#{style}\">#{text}</span>"
|
||||
else
|
||||
src << text
|
||||
end
|
||||
end
|
||||
|
||||
add_line_numbers src
|
||||
# dedent the source
|
||||
indent = src.length
|
||||
lines = src.lines.to_a
|
||||
lines.shift if src =~ /\A.*#\ *File/i # remove '# File' comment
|
||||
lines.each do |line|
|
||||
if line =~ /^ *(?=\S)/
|
||||
n = $&.length
|
||||
indent = n if n < indent
|
||||
break if n == 0
|
||||
end
|
||||
end
|
||||
src.gsub!(/^#{' ' * indent}/, '') if indent > 0
|
||||
|
||||
add_line_numbers(src) if self.class.add_line_numbers
|
||||
|
||||
src
|
||||
end
|
||||
|
@ -133,6 +163,12 @@ class RDoc::Attr
|
|||
|
||||
end
|
||||
|
||||
class RDoc::Alias
|
||||
|
||||
include RDoc::Generator::Markup
|
||||
|
||||
end
|
||||
|
||||
class RDoc::Constant
|
||||
|
||||
include RDoc::Generator::Markup
|
||||
|
|
|
@ -8,10 +8,6 @@ class RDoc::Generator::RI
|
|||
|
||||
RDoc::RDoc.add_generator self
|
||||
|
||||
def self.for options
|
||||
new options
|
||||
end
|
||||
|
||||
##
|
||||
# Set up a new ri generator
|
||||
|
||||
|
@ -20,6 +16,8 @@ class RDoc::Generator::RI
|
|||
@store = RDoc::RI::Store.new '.'
|
||||
@old_siginfo = nil
|
||||
@current = nil
|
||||
|
||||
@store.dry_run = @options.dry_run
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -1,296 +1,289 @@
|
|||
<?xml version="1.0" encoding="<%= @options.charset %>"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
|
||||
<title><%= klass.type.capitalize %>: <%= klass.full_name %></title>
|
||||
<title><%= klass.type.capitalize %>: <%= klass.full_name %></title>
|
||||
|
||||
<link rel="stylesheet" href="<%= rel_prefix %>/rdoc.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="<%= rel_prefix %>/rdoc.css" type="text/css" media="screen" />
|
||||
|
||||
<script src="<%= rel_prefix %>/js/jquery.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/thickbox-compressed.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/quicksearch.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/darkfish.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/jquery.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/thickbox-compressed.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/quicksearch.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/darkfish.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
|
||||
</head>
|
||||
<body class="<%= klass.type %>">
|
||||
|
||||
<div id="metadata">
|
||||
<div id="home-metadata">
|
||||
<div id="home-section" class="section">
|
||||
<div id="metadata">
|
||||
<div id="home-metadata">
|
||||
<div id="home-section" class="section">
|
||||
<h3 class="section-header">
|
||||
<a href="<%= rel_prefix %>/index.html">Home</a>
|
||||
<a href="<%= rel_prefix %>/index.html#classes">Classes</a>
|
||||
<a href="<%= rel_prefix %>/index.html#methods">Methods</a>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="file-metadata">
|
||||
<div id="file-list-section" class="section">
|
||||
<h3 class="section-header">In Files</h3>
|
||||
<div class="section-body">
|
||||
<ul>
|
||||
<% klass.in_files.each do |tl| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= h tl.path %>?TB_iframe=true&height=550&width=785"
|
||||
class="thickbox" title="<%= h tl.absolute_name %>"><%= h tl.absolute_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="file-metadata">
|
||||
<div id="file-list-section" class="section">
|
||||
<h3 class="section-header">In Files</h3>
|
||||
<div class="section-body">
|
||||
<ul>
|
||||
<% klass.in_files.each do |tl| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= h tl.path %>?TB_iframe=true&height=550&width=785"
|
||||
class="thickbox" title="<%= h tl.absolute_name %>"><%= h tl.absolute_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if !svninfo.empty? %>
|
||||
<div id="file-svninfo-section" class="section">
|
||||
<h3 class="section-header">Subversion Info</h3>
|
||||
<div class="section-body">
|
||||
<dl class="svninfo">
|
||||
<dt>Rev</dt>
|
||||
<dd><%= svninfo[:rev] %></dd>
|
||||
<% if !svninfo.empty? %>
|
||||
<div id="file-svninfo-section" class="section">
|
||||
<h3 class="section-header">Subversion Info</h3>
|
||||
<div class="section-body">
|
||||
<dl class="svninfo">
|
||||
<dt>Rev</dt>
|
||||
<dd><%= svninfo[:rev] %></dd>
|
||||
|
||||
<dt>Last Checked In</dt>
|
||||
<dd><%= svninfo[:commitdate].strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
(<%= svninfo[:commitdelta] %> ago)</dd>
|
||||
<dt>Last Checked In</dt>
|
||||
<dd><%= svninfo[:commitdate].strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
(<%= svninfo[:commitdelta] %> ago)</dd>
|
||||
|
||||
<dt>Checked in by</dt>
|
||||
<dd><%= svninfo[:committer] %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<dt>Checked in by</dt>
|
||||
<dd><%= svninfo[:committer] %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div id="class-metadata">
|
||||
<div id="class-metadata">
|
||||
|
||||
<!-- Parent Class -->
|
||||
<% if klass.type == 'class' %>
|
||||
<div id="parent-class-section" class="section">
|
||||
<h3 class="section-header">Parent</h3>
|
||||
<% unless String === klass.superclass %>
|
||||
<p class="link"><a href="<%= klass.aref_to klass.superclass.path %>"><%= klass.superclass.full_name %></a></p>
|
||||
<% else %>
|
||||
<p class="link"><%= klass.superclass %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Parent Class -->
|
||||
<% if klass.type == 'class' %>
|
||||
<div id="parent-class-section" class="section">
|
||||
<h3 class="section-header">Parent</h3>
|
||||
<% if klass.superclass and not String === klass.superclass then %>
|
||||
<p class="link"><a href="<%= klass.aref_to klass.superclass.path %>"><%= klass.superclass.full_name %></a></p>
|
||||
<% else %>
|
||||
<p class="link"><%= klass.superclass %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Namespace Contents -->
|
||||
<% unless klass.classes_and_modules.empty? %>
|
||||
<div id="namespace-list-section" class="section">
|
||||
<h3 class="section-header">Namespace</h3>
|
||||
<ul class="link-list">
|
||||
<% (klass.modules.sort + klass.classes.sort).each do |mod| %>
|
||||
<li><span class="type"><%= mod.type.upcase %></span> <a href="<%= klass.aref_to mod.path %>"><%= mod.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Namespace Contents -->
|
||||
<% unless klass.classes_and_modules.empty? %>
|
||||
<div id="namespace-list-section" class="section">
|
||||
<h3 class="section-header">Namespace</h3>
|
||||
<ul class="link-list">
|
||||
<% (klass.modules.sort + klass.classes.sort).each do |mod| %>
|
||||
<li><span class="type"><%= mod.type.upcase %></span> <a href="<%= klass.aref_to mod.path %>"><%= mod.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Method Quickref -->
|
||||
<% unless klass.method_list.empty? %>
|
||||
<div id="method-list-section" class="section">
|
||||
<h3 class="section-header">Methods</h3>
|
||||
<ul class="link-list">
|
||||
<% klass.each_method do |meth| %>
|
||||
<li><a href="#<%= meth.aref %>"><%= meth.singleton ? '::' : '#' %><%= meth.name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Method Quickref -->
|
||||
<% unless klass.method_list.empty? %>
|
||||
<div id="method-list-section" class="section">
|
||||
<h3 class="section-header">Methods</h3>
|
||||
<ul class="link-list">
|
||||
<% klass.each_method do |meth| %>
|
||||
<li><a href="#<%= meth.aref %>"><%= meth.singleton ? '::' : '#' %><%= meth.name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Included Modules -->
|
||||
<% unless klass.includes.empty? %>
|
||||
<div id="includes-section" class="section">
|
||||
<h3 class="section-header">Included Modules</h3>
|
||||
<ul class="link-list">
|
||||
<% klass.each_include do |inc| %>
|
||||
<% unless String === inc.module %>
|
||||
<li><a class="include" href="<%= klass.aref_to inc.module.path %>"><%= inc.module.full_name %></a></li>
|
||||
<% else %>
|
||||
<li><span class="include"><%= inc.name %></span></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<!-- Included Modules -->
|
||||
<% unless klass.includes.empty? %>
|
||||
<div id="includes-section" class="section">
|
||||
<h3 class="section-header">Included Modules</h3>
|
||||
<ul class="link-list">
|
||||
<% klass.each_include do |inc| %>
|
||||
<% unless String === inc.module %>
|
||||
<li><a class="include" href="<%= klass.aref_to inc.module.path %>"><%= inc.module.full_name %></a></li>
|
||||
<% else %>
|
||||
<li><span class="include"><%= inc.name %></span></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div id="project-metadata">
|
||||
<% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<div id="fileindex-section" class="section project-section">
|
||||
<h3 class="section-header">Files</h3>
|
||||
<ul>
|
||||
<% simple_files.each do |file| %>
|
||||
<li class="file"><a href="<%= rel_prefix %>/<%= file.path %>"><%= h file.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="project-metadata">
|
||||
<% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<div id="fileindex-section" class="section project-section">
|
||||
<h3 class="section-header">Files</h3>
|
||||
<ul>
|
||||
<% simple_files.each do |file| %>
|
||||
<li class="file"><a href="<%= rel_prefix %>/<%= file.path %>"><%= h file.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="classindex-section" class="section project-section">
|
||||
<h3 class="section-header">Class Index
|
||||
<span class="search-toggle"><img src="<%= rel_prefix %>/images/find.png"
|
||||
height="16" width="16" alt="[+]"
|
||||
title="show/hide quicksearch" /></span></h3>
|
||||
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
||||
<fieldset>
|
||||
<legend>Quicksearch</legend>
|
||||
<input type="text" name="quicksearch" value=""
|
||||
class="quicksearch-field" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<div id="classindex-section" class="section project-section">
|
||||
<h3 class="section-header">Class Index
|
||||
<span class="search-toggle"><img src="<%= rel_prefix %>/images/find.png"
|
||||
height="16" width="16" alt="[+]"
|
||||
title="show/hide quicksearch" /></span></h3>
|
||||
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
||||
<fieldset>
|
||||
<legend>Quicksearch</legend>
|
||||
<input type="text" name="quicksearch" value=""
|
||||
class="quicksearch-field" />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<ul class="link-list">
|
||||
<% @modsort.each do |index_klass| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
||||
</div>
|
||||
<ul class="link-list">
|
||||
<% @modsort.each do |index_klass| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
||||
</div>
|
||||
|
||||
<% if $DEBUG_RDOC %>
|
||||
<div id="debugging-toggle"><img src="<%= rel_prefix %>/images/bug.png"
|
||||
alt="toggle debugging" height="16" width="16" /></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% if $DEBUG_RDOC %>
|
||||
<div id="debugging-toggle"><img src="<%= rel_prefix %>/images/bug.png"
|
||||
alt="toggle debugging" height="16" width="16" /></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="documentation">
|
||||
<h1 class="<%= klass.type %>"><%= klass.full_name %></h1>
|
||||
<div id="documentation">
|
||||
<h1 class="<%= klass.type %>"><%= klass.full_name %></h1>
|
||||
|
||||
<div id="description">
|
||||
<%= klass.description %>
|
||||
</div>
|
||||
<div id="description">
|
||||
<%= klass.description %>
|
||||
</div>
|
||||
|
||||
<!-- Constants -->
|
||||
<% unless klass.constants.empty? %>
|
||||
<div id="constants-list" class="section">
|
||||
<h3 class="section-header">Constants</h3>
|
||||
<dl>
|
||||
<% klass.each_constant do |const| %>
|
||||
<dt><a name="<%= const.name %>"><%= const.name %></a></dt>
|
||||
<% if const.comment %>
|
||||
<dd class="description"><%= const.description.strip %></dd>
|
||||
<% else %>
|
||||
<dd class="description missing-docs">(Not documented)</dd>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Constants -->
|
||||
<% unless klass.constants.empty? %>
|
||||
<div id="constants-list" class="section">
|
||||
<h3 class="section-header">Constants</h3>
|
||||
<dl>
|
||||
<% klass.each_constant do |const| %>
|
||||
<dt><a name="<%= const.name %>"><%= const.name %></a></dt>
|
||||
<% if const.comment %>
|
||||
<dd class="description"><%= const.description.strip %></dd>
|
||||
<% else %>
|
||||
<dd class="description missing-docs">(Not documented)</dd>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Attributes -->
|
||||
<% unless klass.attributes.empty? %>
|
||||
<div id="attribute-method-details" class="method-section section">
|
||||
<h3 class="section-header">Attributes</h3>
|
||||
<!-- Attributes -->
|
||||
<% unless klass.attributes.empty? %>
|
||||
<div id="attribute-method-details" class="method-section section">
|
||||
<h3 class="section-header">Attributes</h3>
|
||||
|
||||
<% klass.each_attribute do |attrib| %>
|
||||
<div id="<%= attrib.html_name %>-attribute-method" class="method-detail">
|
||||
<a name="<%= h attrib.name %>"></a>
|
||||
<% if attrib.rw =~ /w/i %>
|
||||
<a name="<%= h attrib.name %>="></a>
|
||||
<% end %>
|
||||
<div class="method-heading attribute-method-heading">
|
||||
<span class="method-name"><%= h attrib.name %></span><span
|
||||
class="attribute-access-type">[<%= attrib.rw %>]</span>
|
||||
</div>
|
||||
<% klass.each_attribute do |attrib| %>
|
||||
<div id="<%= attrib.html_name %>-attribute-method" class="method-detail">
|
||||
<a name="<%= h attrib.name %>"></a>
|
||||
<% if attrib.rw =~ /w/i %>
|
||||
<a name="<%= h attrib.name %>="></a>
|
||||
<% end %>
|
||||
<div class="method-heading attribute-method-heading">
|
||||
<span class="method-name"><%= h attrib.name %></span><span
|
||||
class="attribute-access-type">[<%= attrib.rw %>]</span>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<% if attrib.comment %>
|
||||
<%= attrib.description.strip %>
|
||||
<% else %>
|
||||
<p class="missing-docs">(Not documented)</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="method-description">
|
||||
<% if attrib.comment %>
|
||||
<%= attrib.description.strip %>
|
||||
<% else %>
|
||||
<p class="missing-docs">(Not documented)</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Methods -->
|
||||
<% klass.methods_by_type.each do |type, visibilities|
|
||||
next if visibilities.empty?
|
||||
visibilities.each do |visibility, methods|
|
||||
next if methods.empty? %>
|
||||
<div id="<%= visibility %>-<%= type %>-method-details" class="method-section section">
|
||||
<h3 class="section-header"><%= visibility.to_s.capitalize %> <%= type.capitalize %> Methods</h3>
|
||||
<!-- Methods -->
|
||||
<% klass.methods_by_type.each do |type, visibilities|
|
||||
next if visibilities.empty?
|
||||
visibilities.each do |visibility, methods|
|
||||
next if methods.empty? %>
|
||||
<div id="<%= visibility %>-<%= type %>-method-details" class="method-section section">
|
||||
<h3 class="section-header"><%= visibility.to_s.capitalize %> <%= type.capitalize %> Methods</h3>
|
||||
|
||||
<% methods.each do |method| %>
|
||||
<div id="<%= method.html_name %>-method" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>">
|
||||
<a name="<%= h method.aref %>"></a>
|
||||
<% methods.each do |method| %>
|
||||
<div id="<%= method.html_name %>-method" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>">
|
||||
<a name="<%= h method.aref %>"></a>
|
||||
|
||||
<div class="method-heading">
|
||||
<% if method.call_seq %>
|
||||
<span class="method-callseq"><%= method.call_seq.strip.gsub(/->/, '→').gsub( /^\w.+\./m, '') %></span>
|
||||
<span class="method-click-advice">click to toggle source</span>
|
||||
<% else %>
|
||||
<span class="method-name"><%= h method.name %></span><span
|
||||
class="method-args"><%= method.params %></span>
|
||||
<span class="method-click-advice">click to toggle source</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="method-heading">
|
||||
<% if method.call_seq %>
|
||||
<span class="method-callseq"><%= method.call_seq.strip.gsub(/->/, '→').gsub( /^\w.+\./m, '') %></span>
|
||||
<span class="method-click-advice">click to toggle source</span>
|
||||
<% else %>
|
||||
<span class="method-name"><%= h method.name %></span><span
|
||||
class="method-args"><%= method.params %></span>
|
||||
<span class="method-click-advice">click to toggle source</span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="method-description">
|
||||
<% if method.comment %>
|
||||
<%= method.description.strip %>
|
||||
<% else %>
|
||||
<p class="missing-docs">(Not documented)</p>
|
||||
<% end %>
|
||||
<div class="method-description">
|
||||
<% if method.comment %>
|
||||
<%= method.description.strip %>
|
||||
<% else %>
|
||||
<p class="missing-docs">(Not documented)</p>
|
||||
<% end %>
|
||||
|
||||
<% if method.token_stream %>
|
||||
<div class="method-source-code"
|
||||
id="<%= method.html_name %>-source">
|
||||
<% if method.token_stream %>
|
||||
<div class="method-source-code"
|
||||
id="<%= method.html_name %>-source">
|
||||
<pre>
|
||||
<%= method.markup_code %>
|
||||
</pre>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% unless method.aliases.empty? %>
|
||||
<div class="aliases">
|
||||
Also aliased as: <%= method.aliases.map do |aka|
|
||||
%{<a href="#{ klass.aref_to aka.path}">#{h aka.name}</a>}
|
||||
end.join(", ") %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% unless method.aliases.empty? %>
|
||||
<div class="aliases">
|
||||
Also aliased as: <%= method.aliases.map do |aka|
|
||||
if aka.parent then # HACK lib/rexml/encodings
|
||||
%{<a href="#{klass.aref_to aka.path}">#{h aka.name}</a>}
|
||||
else
|
||||
h aka.name
|
||||
end
|
||||
end.join ", " %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if method.is_alias_for then %>
|
||||
<div class="aliases">
|
||||
<% if method.is_alias_for then %>
|
||||
<div class="aliases">
|
||||
Alias for: <a href="<%= klass.aref_to method.is_alias_for.path %>"><%= h method.is_alias_for.name %></a>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
<% end
|
||||
end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end
|
||||
end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="rdoc-debugging-section-dump" class="debugging-section">
|
||||
<% if $DEBUG_RDOC
|
||||
require 'pp' %>
|
||||
<pre><%= h PP.pp(klass, _erbout) %></pre>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>Disabled; run with --debug to generate this.</p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,123 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
|
||||
<title>File: <%= file.base_name %> [<%= @options.title %>]</title>
|
||||
<title>File: <%= file.base_name %> [<%= @options.title %>]</title>
|
||||
|
||||
<link type="text/css" media="screen" href="<%= rel_prefix %>/rdoc.css" rel="stylesheet" />
|
||||
<link type="text/css" media="screen" href="<%= rel_prefix %>/rdoc.css" rel="stylesheet" />
|
||||
|
||||
<script src="<%= rel_prefix %>/js/jquery.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/thickbox-compressed.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/quicksearch.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/darkfish.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/jquery.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/thickbox-compressed.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/quicksearch.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
<script src="<%= rel_prefix %>/js/darkfish.js" type="text/javascript"
|
||||
charset="utf-8"></script>
|
||||
</head>
|
||||
|
||||
<% if file.parser == RDoc::Parser::Simple %>
|
||||
<body class="file">
|
||||
<div id="metadata">
|
||||
<div id="home-metadata">
|
||||
<div id="home-section" class="section">
|
||||
<div id="metadata">
|
||||
<div id="home-metadata">
|
||||
<div id="home-section" class="section">
|
||||
<h3 class="section-header">
|
||||
<a href="<%= rel_prefix %>/index.html">Home</a>
|
||||
<a href="<%= rel_prefix %>/index.html#classes">Classes</a>
|
||||
<a href="<%= rel_prefix %>/index.html#methods">Methods</a>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="project-metadata">
|
||||
<% simple_files = @files.select { |f| f.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<div id="fileindex-section" class="section project-section">
|
||||
<h3 class="section-header">Files</h3>
|
||||
<ul>
|
||||
<% simple_files.each do |f| %>
|
||||
<li class="file"><a href="<%= rel_prefix %>/<%= f.path %>"><%= h f.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="project-metadata">
|
||||
<% simple_files = @files.select { |f| f.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<div id="fileindex-section" class="section project-section">
|
||||
<h3 class="section-header">Files</h3>
|
||||
<ul>
|
||||
<% simple_files.each do |f| %>
|
||||
<li class="file"><a href="<%= rel_prefix %>/<%= f.path %>"><%= h f.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div id="classindex-section" class="section project-section">
|
||||
<h3 class="section-header">Class Index
|
||||
<span class="search-toggle"><img src="<%= rel_prefix %>/images/find.png"
|
||||
height="16" width="16" alt="[+]"
|
||||
title="show/hide quicksearch" /></span></h3>
|
||||
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
||||
<fieldset>
|
||||
<legend>Quicksearch</legend>
|
||||
<input type="text" name="quicksearch" value=""
|
||||
class="quicksearch-field" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<div id="classindex-section" class="section project-section">
|
||||
<h3 class="section-header">Class Index
|
||||
<span class="search-toggle"><img src="<%= rel_prefix %>/images/find.png"
|
||||
height="16" width="16" alt="[+]"
|
||||
title="show/hide quicksearch" /></span></h3>
|
||||
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
||||
<fieldset>
|
||||
<legend>Quicksearch</legend>
|
||||
<input type="text" name="quicksearch" value=""
|
||||
class="quicksearch-field" />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<ul class="link-list">
|
||||
<% @modsort.each do |index_klass| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
||||
</div>
|
||||
<ul class="link-list">
|
||||
<% @modsort.each do |index_klass| %>
|
||||
<li><a href="<%= rel_prefix %>/<%= index_klass.path %>"><%= index_klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
||||
</div>
|
||||
|
||||
<% if $DEBUG_RDOC %>
|
||||
<div id="debugging-toggle"><img src="<%= rel_prefix %>/images/bug.png"
|
||||
alt="toggle debugging" height="16" width="16" /></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% if $DEBUG_RDOC %>
|
||||
<div id="debugging-toggle"><img src="<%= rel_prefix %>/images/bug.png"
|
||||
alt="toggle debugging" height="16" width="16" /></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="documentation">
|
||||
<%= file.description %>
|
||||
</div>
|
||||
<div id="documentation">
|
||||
<%= file.description %>
|
||||
</div>
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
</body>
|
||||
<% else %>
|
||||
<body class="file file-popup">
|
||||
<div id="metadata">
|
||||
<dl>
|
||||
<dt class="modified-date">Last Modified</dt>
|
||||
<dd class="modified-date"><%= file.last_modified %></dd>
|
||||
<div id="metadata">
|
||||
<dl>
|
||||
<dt class="modified-date">Last Modified</dt>
|
||||
<dd class="modified-date"><%= file.last_modified %></dd>
|
||||
|
||||
<% if file.requires %>
|
||||
<dt class="requires">Requires</dt>
|
||||
<dd class="requires">
|
||||
<ul>
|
||||
<% file.requires.each do |require| %>
|
||||
<li><%= require.name %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</dd>
|
||||
<% end %>
|
||||
<% if file.requires %>
|
||||
<dt class="requires">Requires</dt>
|
||||
<dd class="requires">
|
||||
<ul>
|
||||
<% file.requires.each do |require| %>
|
||||
<li><%= require.name %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</dd>
|
||||
<% end %>
|
||||
|
||||
<% if @options.webcvs %>
|
||||
<dt class="scs-url">Trac URL</dt>
|
||||
<dd class="scs-url"><a target="_top"
|
||||
href="<%= file.cvs_url %>"><%= file.cvs_url %></a></dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
<% if @options.webcvs %>
|
||||
<dt class="scs-url">Trac URL</dt>
|
||||
<dd class="scs-url"><a target="_top"
|
||||
href="<%= file.cvs_url %>"><%= file.cvs_url %></a></dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div id="documentation">
|
||||
<% if file.comment %>
|
||||
<div class="description">
|
||||
<h2>Description</h2>
|
||||
<%= file.description %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div id="documentation">
|
||||
<% if file.comment %>
|
||||
<div class="description">
|
||||
<h2>Description</h2>
|
||||
<%= file.description %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</body>
|
||||
<% end %>
|
||||
</html>
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
<meta content="text/html; charset=<%= @options.charset %>" http-equiv="Content-Type" />
|
||||
|
||||
<title><%= h @options.title %></title>
|
||||
<title><%= h @options.title %></title>
|
||||
|
||||
<link type="text/css" media="screen" href="rdoc.css" rel="stylesheet" />
|
||||
<link type="text/css" media="screen" href="rdoc.css" rel="stylesheet" />
|
||||
|
||||
<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/thickbox-compressed.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/quicksearch.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/darkfish.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/thickbox-compressed.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/quicksearch.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="js/darkfish.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
</head>
|
||||
<body class="indexpage">
|
||||
|
||||
<% $stderr.sync = true %>
|
||||
<h1><%= h @options.title %></h1>
|
||||
<% $stderr.sync = true %>
|
||||
<h1><%= h @options.title %></h1>
|
||||
|
||||
<% if @options.main_page && main_page = @files.find { |f| f.full_name == @options.main_page } %>
|
||||
<div id="main">
|
||||
<%= main_page.description.sub(%r{^\s*<h1.*?/h1>}i, '') %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>This is the API documentation for '<%= @options.title %>'.</p>
|
||||
<% end %>
|
||||
<% if @options.main_page && main_page = @files.find { |f| f.full_name == @options.main_page } then %>
|
||||
<div id="main">
|
||||
<%= main_page.description.sub(%r{^\s*<h1.*?/h1>}i, '') %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>This is the API documentation for '<%= @options.title %>'.</p>
|
||||
<% end %>
|
||||
|
||||
<% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<h2>Files</h2>
|
||||
<ul>
|
||||
<% simple_files.sort.each do |file| %>
|
||||
<li class="file"><a href="<%= file.path %>"><%= h file.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %>
|
||||
<% unless simple_files.empty? then %>
|
||||
<h2>Files</h2>
|
||||
<ul>
|
||||
<% simple_files.sort.each do |file| %>
|
||||
<li class="file"><a href="<%= file.path %>"><%= h file.base_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<h2 id="classes">Classes/Modules</h2>
|
||||
<ul>
|
||||
<% @modsort.each do |klass| %>
|
||||
<li class="<%= klass.type %>"><a href="<%= klass.path %>"><%= klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<h2 id="classes">Classes/Modules</h2>
|
||||
<ul>
|
||||
<% @modsort.each do |klass| %>
|
||||
<li class="<%= klass.type %>"><a href="<%= klass.path %>"><%= klass.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<h2 id="methods">Methods</h2>
|
||||
<ul>
|
||||
<% RDoc::TopLevel.all_classes_and_modules.map do |mod|
|
||||
mod.method_list
|
||||
end.flatten.sort.each do |method| %>
|
||||
<li><a href="<%= method.path %>"><%= method.pretty_name %> — <%= method.parent.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<h2 id="methods">Methods</h2>
|
||||
<ul>
|
||||
<% RDoc::TopLevel.all_classes_and_modules.map do |mod|
|
||||
mod.method_list
|
||||
end.flatten.sort.each do |method| %>
|
||||
<li><a href="<%= method.path %>"><%= method.pretty_name %> — <%= method.parent.full_name %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
<div id="validator-badges">
|
||||
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
||||
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
||||
Rdoc Generator</a> <%= RDoc::Generator::Darkfish::VERSION %></small>.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -12,76 +12,76 @@
|
|||
|
||||
body {
|
||||
background: #efefef;
|
||||
font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif;
|
||||
font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif;
|
||||
}
|
||||
body.class, body.module, body.file {
|
||||
margin-left: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
body.file-popup {
|
||||
font-size: 90%;
|
||||
margin-left: 0;
|
||||
font-size: 90%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 300%;
|
||||
text-shadow: rgba(135,145,135,0.65) 2px 2px 3px;
|
||||
color: #6C8C22;
|
||||
font-size: 300%;
|
||||
text-shadow: rgba(135,145,135,0.65) 2px 2px 3px;
|
||||
color: #6C8C22;
|
||||
}
|
||||
h2,h3,h4 { margin-top: 1.5em; }
|
||||
|
||||
:link,
|
||||
:visited {
|
||||
color: #6C8C22;
|
||||
text-decoration: none;
|
||||
color: #6C8C22;
|
||||
text-decoration: none;
|
||||
}
|
||||
:link:hover,
|
||||
:visited:hover {
|
||||
border-bottom: 1px dotted #6C8C22;
|
||||
border-bottom: 1px dotted #6C8C22;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #ddd;
|
||||
padding: 0.5em 0;
|
||||
background: #ddd;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
|
||||
/* @group Generic Classes */
|
||||
|
||||
.initially-hidden {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.quicksearch-field {
|
||||
width: 98%;
|
||||
background: #ddd;
|
||||
border: 1px solid #aaa;
|
||||
height: 1.5em;
|
||||
-webkit-border-radius: 4px;
|
||||
width: 98%;
|
||||
background: #ddd;
|
||||
border: 1px solid #aaa;
|
||||
height: 1.5em;
|
||||
-webkit-border-radius: 4px;
|
||||
}
|
||||
.quicksearch-field:focus {
|
||||
background: #f1edba;
|
||||
background: #f1edba;
|
||||
}
|
||||
|
||||
.missing-docs {
|
||||
font-size: 120%;
|
||||
background: white url(images/wrench_orange.png) no-repeat 4px center;
|
||||
color: #ccc;
|
||||
line-height: 2em;
|
||||
border: 1px solid #d00;
|
||||
opacity: 1;
|
||||
padding-left: 20px;
|
||||
text-indent: 24px;
|
||||
letter-spacing: 3px;
|
||||
font-weight: bold;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
font-size: 120%;
|
||||
background: white url(images/wrench_orange.png) no-repeat 4px center;
|
||||
color: #ccc;
|
||||
line-height: 2em;
|
||||
border: 1px solid #d00;
|
||||
opacity: 1;
|
||||
padding-left: 20px;
|
||||
text-indent: 24px;
|
||||
letter-spacing: 3px;
|
||||
font-weight: bold;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
}
|
||||
|
||||
.target-section {
|
||||
border: 2px solid #dcce90;
|
||||
border-left-width: 8px;
|
||||
padding: 0 1em;
|
||||
background: #fff3c2;
|
||||
border: 2px solid #dcce90;
|
||||
border-left-width: 8px;
|
||||
padding: 0 1em;
|
||||
background: #fff3c2;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -89,37 +89,37 @@ pre {
|
|||
|
||||
/* @group Index Page, Standalone file pages */
|
||||
body.indexpage {
|
||||
margin: 1em 3em;
|
||||
margin: 1em 3em;
|
||||
}
|
||||
body.indexpage p,
|
||||
body.indexpage div,
|
||||
body.file p {
|
||||
margin: 1em 0;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.indexpage ul,
|
||||
.file #documentation ul {
|
||||
line-height: 160%;
|
||||
list-style: none;
|
||||
line-height: 160%;
|
||||
list-style: none;
|
||||
}
|
||||
.indexpage ul :link,
|
||||
.indexpage ul :visited {
|
||||
font-size: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.indexpage li,
|
||||
.file #documentation li {
|
||||
padding-left: 20px;
|
||||
background: url(images/bullet_black.png) no-repeat left 4px;
|
||||
padding-left: 20px;
|
||||
background: url(images/bullet_black.png) no-repeat left 4px;
|
||||
}
|
||||
.indexpage li.module {
|
||||
background: url(images/package.png) no-repeat left 4px;
|
||||
background: url(images/package.png) no-repeat left 4px;
|
||||
}
|
||||
.indexpage li.class {
|
||||
background: url(images/ruby.png) no-repeat left 4px;
|
||||
background: url(images/ruby.png) no-repeat left 4px;
|
||||
}
|
||||
.indexpage li.file {
|
||||
background: url(images/page_white_text.png) no-repeat left 4px;
|
||||
background: url(images/page_white_text.png) no-repeat left 4px;
|
||||
}
|
||||
.file li p,
|
||||
.indexpage li p {
|
||||
|
@ -133,48 +133,48 @@ body.file p {
|
|||
.class #metadata,
|
||||
.file #metadata,
|
||||
.module #metadata {
|
||||
float: left;
|
||||
width: 260px;
|
||||
float: left;
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.class #documentation,
|
||||
.file #documentation,
|
||||
.module #documentation {
|
||||
margin: 2em 1em 5em 300px;
|
||||
min-width: 340px;
|
||||
margin: 2em 1em 5em 300px;
|
||||
min-width: 340px;
|
||||
}
|
||||
|
||||
.file #metadata {
|
||||
margin: 0.8em;
|
||||
margin: 0.8em;
|
||||
}
|
||||
|
||||
#validator-badges {
|
||||
clear: both;
|
||||
margin: 1em 1em 2em;
|
||||
clear: both;
|
||||
margin: 1em 1em 2em;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Metadata Section */
|
||||
#metadata .section {
|
||||
background-color: #dedede;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border: 1px solid #aaa;
|
||||
margin: 0 8px 16px;
|
||||
font-size: 90%;
|
||||
overflow: hidden;
|
||||
background-color: #dedede;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border: 1px solid #aaa;
|
||||
margin: 0 8px 16px;
|
||||
font-size: 90%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#metadata h3.section-header {
|
||||
margin: 0;
|
||||
padding: 2px 8px;
|
||||
background: #ccc;
|
||||
color: #666;
|
||||
-moz-border-radius-topleft: 4px;
|
||||
-moz-border-radius-topright: 4px;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
border-bottom: 1px solid #aaa;
|
||||
margin: 0;
|
||||
padding: 2px 8px;
|
||||
background: #ccc;
|
||||
color: #666;
|
||||
-moz-border-radius-topleft: 4px;
|
||||
-moz-border-radius-topright: 4px;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
#metadata #home-section h3.section-header {
|
||||
border-bottom: 0;
|
||||
|
@ -183,33 +183,33 @@ body.file p {
|
|||
#metadata ul,
|
||||
#metadata dl,
|
||||
#metadata p {
|
||||
padding: 8px;
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#file-metadata ul {
|
||||
padding-left: 28px;
|
||||
list-style-image: url(images/page_green.png);
|
||||
padding-left: 28px;
|
||||
list-style-image: url(images/page_green.png);
|
||||
}
|
||||
|
||||
dl.svninfo {
|
||||
color: #666;
|
||||
margin: 0;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
dl.svninfo dt {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.link-list li {
|
||||
white-space: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
ul.link-list .type {
|
||||
font-size: 8px;
|
||||
text-transform: uppercase;
|
||||
color: white;
|
||||
background: #969696;
|
||||
padding: 2px 4px;
|
||||
-webkit-border-radius: 5px;
|
||||
font-size: 8px;
|
||||
text-transform: uppercase;
|
||||
color: white;
|
||||
background: #969696;
|
||||
padding: 2px 4px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -217,7 +217,7 @@ ul.link-list .type {
|
|||
|
||||
/* @group Project Metadata Section */
|
||||
#project-metadata {
|
||||
margin-top: 3em;
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
.file #project-metadata {
|
||||
|
@ -225,34 +225,34 @@ ul.link-list .type {
|
|||
}
|
||||
|
||||
#project-metadata .section {
|
||||
border: 1px solid #aaa;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
#project-metadata h3.section-header {
|
||||
border-bottom: 1px solid #aaa;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #aaa;
|
||||
position: relative;
|
||||
}
|
||||
#project-metadata h3.section-header .search-toggle {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
|
||||
#project-metadata form {
|
||||
color: #777;
|
||||
background: #ccc;
|
||||
padding: 8px 8px 16px;
|
||||
border-bottom: 1px solid #bbb;
|
||||
color: #777;
|
||||
background: #ccc;
|
||||
padding: 8px 8px 16px;
|
||||
border-bottom: 1px solid #bbb;
|
||||
}
|
||||
#project-metadata fieldset {
|
||||
border: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#no-class-search-results {
|
||||
margin: 0 auto 1em;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #aaa;
|
||||
margin: 0 auto 1em;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -260,12 +260,12 @@ ul.link-list .type {
|
|||
|
||||
/* @group Documentation Section */
|
||||
#description {
|
||||
font-size: 100%;
|
||||
color: #333;
|
||||
font-size: 100%;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#description p {
|
||||
margin: 1em 0.4em;
|
||||
margin: 1em 0.4em;
|
||||
}
|
||||
|
||||
#description li p {
|
||||
|
@ -273,152 +273,152 @@ ul.link-list .type {
|
|||
}
|
||||
|
||||
#description ul {
|
||||
margin-left: 1.5em;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
#description ul li {
|
||||
line-height: 1.4em;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
#description dl,
|
||||
#documentation dl {
|
||||
margin: 8px 1.5em;
|
||||
border: 1px solid #ccc;
|
||||
margin: 8px 1.5em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
#description dl {
|
||||
font-size: 14px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#description dt,
|
||||
#documentation dt {
|
||||
padding: 2px 4px;
|
||||
font-weight: bold;
|
||||
background: #ddd;
|
||||
padding: 2px 4px;
|
||||
font-weight: bold;
|
||||
background: #ddd;
|
||||
}
|
||||
#description dd,
|
||||
#documentation dd {
|
||||
padding: 2px 12px;
|
||||
padding: 2px 12px;
|
||||
}
|
||||
#description dd + dt,
|
||||
#documentation dd + dt {
|
||||
margin-top: 0.7em;
|
||||
margin-top: 0.7em;
|
||||
}
|
||||
|
||||
#documentation .section {
|
||||
font-size: 90%;
|
||||
font-size: 90%;
|
||||
}
|
||||
#documentation h3.section-header {
|
||||
margin-top: 2em;
|
||||
padding: 0.75em 0.5em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
font-size: 150%;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
margin-top: 2em;
|
||||
padding: 0.75em 0.5em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
font-size: 150%;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
#constants-list > dl,
|
||||
#attributes-list > dl {
|
||||
margin: 1em 0 2em;
|
||||
border: 0;
|
||||
margin: 1em 0 2em;
|
||||
border: 0;
|
||||
}
|
||||
#constants-list > dl dt,
|
||||
#attributes-list > dl dt {
|
||||
padding-left: 0;
|
||||
font-weight: bold;
|
||||
font-family: Monaco, "Andale Mono";
|
||||
background: inherit;
|
||||
padding-left: 0;
|
||||
font-weight: bold;
|
||||
font-family: Monaco, "Andale Mono";
|
||||
background: inherit;
|
||||
}
|
||||
#constants-list > dl dt a,
|
||||
#attributes-list > dl dt a {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
#constants-list > dl dd,
|
||||
#attributes-list > dl dd {
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* @group Method Details */
|
||||
|
||||
#documentation .method-source-code {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#documentation .method-detail {
|
||||
margin: 0.5em 0;
|
||||
padding: 0.5em 0;
|
||||
cursor: pointer;
|
||||
margin: 0.5em 0;
|
||||
padding: 0.5em 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
#documentation .method-detail:hover {
|
||||
background-color: #f1edba;
|
||||
background-color: #f1edba;
|
||||
}
|
||||
#documentation .method-heading {
|
||||
position: relative;
|
||||
padding: 2px 4px 0 20px;
|
||||
font-size: 125%;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
background: url(images/brick.png) no-repeat left bottom;
|
||||
position: relative;
|
||||
padding: 2px 4px 0 20px;
|
||||
font-size: 125%;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
background: url(images/brick.png) no-repeat left bottom;
|
||||
}
|
||||
#documentation .method-heading :link,
|
||||
#documentation .method-heading :visited {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
#documentation .method-click-advice {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 5px;
|
||||
font-size: 10px;
|
||||
color: #9b9877;
|
||||
visibility: hidden;
|
||||
padding-right: 20px;
|
||||
line-height: 20px;
|
||||
background: url(images/zoom.png) no-repeat right top;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 5px;
|
||||
font-size: 10px;
|
||||
color: #9b9877;
|
||||
visibility: hidden;
|
||||
padding-right: 20px;
|
||||
line-height: 20px;
|
||||
background: url(images/zoom.png) no-repeat right top;
|
||||
}
|
||||
#documentation .method-detail:hover .method-click-advice {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#documentation .method-alias .method-heading {
|
||||
color: #666;
|
||||
background: url(images/brick_link.png) no-repeat left bottom;
|
||||
color: #666;
|
||||
background: url(images/brick_link.png) no-repeat left bottom;
|
||||
}
|
||||
|
||||
#documentation .method-description,
|
||||
#documentation .aliases {
|
||||
margin: 0 20px;
|
||||
line-height: 1.2em;
|
||||
color: #666;
|
||||
margin: 0 20px;
|
||||
line-height: 1.2em;
|
||||
color: #666;
|
||||
}
|
||||
#documentation .aliases {
|
||||
padding-top: 4px;
|
||||
font-style: italic;
|
||||
cursor: default;
|
||||
padding-top: 4px;
|
||||
font-style: italic;
|
||||
cursor: default;
|
||||
}
|
||||
#documentation .method-description p {
|
||||
padding: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#documentation .method-description p + p {
|
||||
margin-bottom: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
#documentation .method-description ul {
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
#documentation .attribute-method-heading {
|
||||
background: url(images/tag_green.png) no-repeat left bottom;
|
||||
background: url(images/tag_green.png) no-repeat left bottom;
|
||||
}
|
||||
#documentation #attribute-method-details .method-detail:hover {
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
#documentation .attribute-access-type {
|
||||
font-size: 60%;
|
||||
text-transform: uppercase;
|
||||
vertical-align: super;
|
||||
padding: 0 2px;
|
||||
font-size: 60%;
|
||||
text-transform: uppercase;
|
||||
vertical-align: super;
|
||||
padding: 0 2px;
|
||||
}
|
||||
/* @end */
|
||||
|
||||
|
@ -429,19 +429,19 @@ ul.link-list .type {
|
|||
/* @group Source Code */
|
||||
|
||||
div.method-source-code {
|
||||
background: #262626;
|
||||
color: #efefef;
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
border: 1px dashed #999;
|
||||
overflow: hidden;
|
||||
background: #262626;
|
||||
color: #efefef;
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
border: 1px dashed #999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.method-source-code pre {
|
||||
background: inherit;
|
||||
padding: 0;
|
||||
color: white;
|
||||
overflow: auto;
|
||||
background: inherit;
|
||||
padding: 0;
|
||||
color: white;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* @group Ruby keyword styles */
|
||||
|
@ -467,51 +467,51 @@ div.method-source-code pre {
|
|||
}
|
||||
|
||||
.file-popup dl {
|
||||
font-size: 80%;
|
||||
padding: 0.75em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
font-size: 80%;
|
||||
padding: 0.75em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
.file dt {
|
||||
font-weight: bold;
|
||||
padding-left: 22px;
|
||||
line-height: 20px;
|
||||
background: url(images/page_white_width.png) no-repeat left top;
|
||||
font-weight: bold;
|
||||
padding-left: 22px;
|
||||
line-height: 20px;
|
||||
background: url(images/page_white_width.png) no-repeat left top;
|
||||
}
|
||||
.file dt.modified-date {
|
||||
background: url(images/date.png) no-repeat left top;
|
||||
background: url(images/date.png) no-repeat left top;
|
||||
}
|
||||
.file dt.requires {
|
||||
background: url(images/plugin.png) no-repeat left top;
|
||||
background: url(images/plugin.png) no-repeat left top;
|
||||
}
|
||||
.file dt.scs-url {
|
||||
background: url(images/wrench.png) no-repeat left top;
|
||||
background: url(images/wrench.png) no-repeat left top;
|
||||
}
|
||||
|
||||
.file dl dd {
|
||||
margin: 0 0 1em 0;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
.file #metadata dl dd ul {
|
||||
list-style: circle;
|
||||
margin-left: 20px;
|
||||
padding-top: 0;
|
||||
list-style: circle;
|
||||
margin-left: 20px;
|
||||
padding-top: 0;
|
||||
}
|
||||
.file #metadata dl dd ul li {
|
||||
}
|
||||
|
||||
|
||||
.file h2 {
|
||||
margin-top: 2em;
|
||||
padding: 0.75em 0.5em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
font-size: 120%;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
margin-top: 2em;
|
||||
padding: 0.75em 0.5em;
|
||||
background-color: #dedede;
|
||||
color: #333;
|
||||
font-size: 120%;
|
||||
border: 1px solid #bbb;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -521,13 +521,13 @@ div.method-source-code pre {
|
|||
|
||||
/* @group ThickBox Styles */
|
||||
#TB_window {
|
||||
font: 12px Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
font: 12px Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
#TB_secondLine {
|
||||
font: 10px Arial, Helvetica, sans-serif;
|
||||
color:#666666;
|
||||
font: 10px Arial, Helvetica, sans-serif;
|
||||
color:#666666;
|
||||
}
|
||||
|
||||
#TB_window :link,
|
||||
|
@ -540,147 +540,147 @@ div.method-source-code pre {
|
|||
#TB_window :visited:focus { color: #666666; }
|
||||
|
||||
#TB_overlay {
|
||||
position: fixed;
|
||||
z-index:100;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height:100%;
|
||||
width:100%;
|
||||
position: fixed;
|
||||
z-index:100;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height:100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.TB_overlayMacFFBGHack {background: url(images/macFFBgHack.png) repeat;}
|
||||
.TB_overlayBG {
|
||||
background-color:#000;
|
||||
filter:alpha(opacity=75);
|
||||
-moz-opacity: 0.75;
|
||||
opacity: 0.75;
|
||||
background-color:#000;
|
||||
filter:alpha(opacity=75);
|
||||
-moz-opacity: 0.75;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
* html #TB_overlay { /* ie6 hack */
|
||||
position: absolute;
|
||||
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
||||
position: absolute;
|
||||
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
||||
}
|
||||
|
||||
#TB_window {
|
||||
position: fixed;
|
||||
background: #ffffff;
|
||||
z-index: 102;
|
||||
color:#000000;
|
||||
display:none;
|
||||
border: 4px solid #525252;
|
||||
text-align:left;
|
||||
top:50%;
|
||||
left:50%;
|
||||
position: fixed;
|
||||
background: #ffffff;
|
||||
z-index: 102;
|
||||
color:#000000;
|
||||
display:none;
|
||||
border: 4px solid #525252;
|
||||
text-align:left;
|
||||
top:50%;
|
||||
left:50%;
|
||||
}
|
||||
|
||||
* html #TB_window { /* ie6 hack */
|
||||
position: absolute;
|
||||
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
||||
position: absolute;
|
||||
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
||||
}
|
||||
|
||||
#TB_window img#TB_Image {
|
||||
display:block;
|
||||
margin: 15px 0 0 15px;
|
||||
border-right: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #666;
|
||||
border-left: 1px solid #666;
|
||||
display:block;
|
||||
margin: 15px 0 0 15px;
|
||||
border-right: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #666;
|
||||
border-left: 1px solid #666;
|
||||
}
|
||||
|
||||
#TB_caption{
|
||||
height:25px;
|
||||
padding:7px 30px 10px 25px;
|
||||
float:left;
|
||||
height:25px;
|
||||
padding:7px 30px 10px 25px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
#TB_closeWindow{
|
||||
height:25px;
|
||||
padding:11px 25px 10px 0;
|
||||
float:right;
|
||||
height:25px;
|
||||
padding:11px 25px 10px 0;
|
||||
float:right;
|
||||
}
|
||||
|
||||
#TB_closeAjaxWindow{
|
||||
padding:7px 10px 5px 0;
|
||||
margin-bottom:1px;
|
||||
text-align:right;
|
||||
float:right;
|
||||
padding:7px 10px 5px 0;
|
||||
margin-bottom:1px;
|
||||
text-align:right;
|
||||
float:right;
|
||||
}
|
||||
|
||||
#TB_ajaxWindowTitle{
|
||||
float:left;
|
||||
padding:7px 0 5px 10px;
|
||||
margin-bottom:1px;
|
||||
font-size: 22px;
|
||||
float:left;
|
||||
padding:7px 0 5px 10px;
|
||||
margin-bottom:1px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
#TB_title{
|
||||
background-color: #6C8C22;
|
||||
color: #dedede;
|
||||
height:40px;
|
||||
background-color: #6C8C22;
|
||||
color: #dedede;
|
||||
height:40px;
|
||||
}
|
||||
#TB_title :link,
|
||||
#TB_title :visited {
|
||||
color: white !important;
|
||||
border-bottom: 1px dotted #dedede;
|
||||
color: white !important;
|
||||
border-bottom: 1px dotted #dedede;
|
||||
}
|
||||
|
||||
#TB_ajaxContent{
|
||||
clear:both;
|
||||
padding:2px 15px 15px 15px;
|
||||
overflow:auto;
|
||||
text-align:left;
|
||||
line-height:1.4em;
|
||||
clear:both;
|
||||
padding:2px 15px 15px 15px;
|
||||
overflow:auto;
|
||||
text-align:left;
|
||||
line-height:1.4em;
|
||||
}
|
||||
|
||||
#TB_ajaxContent.TB_modal{
|
||||
padding:15px;
|
||||
padding:15px;
|
||||
}
|
||||
|
||||
#TB_ajaxContent p{
|
||||
padding:5px 0px 5px 0px;
|
||||
padding:5px 0px 5px 0px;
|
||||
}
|
||||
|
||||
#TB_load{
|
||||
position: fixed;
|
||||
display:none;
|
||||
height:13px;
|
||||
width:208px;
|
||||
z-index:103;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */
|
||||
position: fixed;
|
||||
display:none;
|
||||
height:13px;
|
||||
width:208px;
|
||||
z-index:103;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */
|
||||
}
|
||||
|
||||
* html #TB_load { /* ie6 hack */
|
||||
position: absolute;
|
||||
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
||||
position: absolute;
|
||||
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
||||
}
|
||||
|
||||
#TB_HideSelect{
|
||||
z-index:99;
|
||||
position:fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color:#fff;
|
||||
border:none;
|
||||
filter:alpha(opacity=0);
|
||||
-moz-opacity: 0;
|
||||
opacity: 0;
|
||||
height:100%;
|
||||
width:100%;
|
||||
z-index:99;
|
||||
position:fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color:#fff;
|
||||
border:none;
|
||||
filter:alpha(opacity=0);
|
||||
-moz-opacity: 0;
|
||||
opacity: 0;
|
||||
height:100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
* html #TB_HideSelect { /* ie6 hack */
|
||||
position: absolute;
|
||||
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
||||
position: absolute;
|
||||
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
||||
}
|
||||
|
||||
#TB_iframeContent{
|
||||
clear:both;
|
||||
border:none;
|
||||
margin-bottom:-1px;
|
||||
margin-top:1px;
|
||||
_margin-bottom:1px;
|
||||
clear:both;
|
||||
border:none;
|
||||
margin-bottom:-1px;
|
||||
margin-top:1px;
|
||||
_margin-bottom:1px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
@ -688,17 +688,17 @@ margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = d
|
|||
/* @group Debugging Section */
|
||||
|
||||
#debugging-toggle {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
#debugging-toggle img {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#rdoc-debugging-section-dump {
|
||||
display: none;
|
||||
margin: 0 2em 2em;
|
||||
background: #ccc;
|
||||
border: 1px solid #999;
|
||||
display: none;
|
||||
margin: 0 2em 2em;
|
||||
background: #ccc;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ class RDoc::Include < RDoc::CodeObject
|
|||
super()
|
||||
@name = name
|
||||
self.comment = comment
|
||||
@module = nil # cache for module if found
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -52,9 +53,47 @@ class RDoc::Include < RDoc::CodeObject
|
|||
##
|
||||
# Attempts to locate the included module object. Returns the name if not
|
||||
# known.
|
||||
#
|
||||
# The scoping rules of Ruby to resolve the name of an included module are:
|
||||
# - first look into the children of the current context;
|
||||
# - if not found, look into the children of included modules,
|
||||
# in reverse inclusion order;
|
||||
# - if still not found, go up the hierarchy of names.
|
||||
|
||||
def module
|
||||
RDoc::TopLevel.find_module_named(@name) || @name
|
||||
return @module if @module
|
||||
|
||||
# search the current context
|
||||
return @name unless parent
|
||||
full_name = parent.child_name(@name)
|
||||
@module = RDoc::TopLevel.modules_hash[full_name]
|
||||
return @module if @module
|
||||
return @name if @name =~ /^::/
|
||||
|
||||
# search the includes before this one, in reverse order
|
||||
searched = parent.includes.take_while { |i| i != self }.reverse
|
||||
searched.each do |i|
|
||||
inc = i.module
|
||||
next if String === inc
|
||||
full_name = inc.child_name(@name)
|
||||
@module = RDoc::TopLevel.modules_hash[full_name]
|
||||
return @module if @module
|
||||
end
|
||||
|
||||
# go up the hierarchy of names
|
||||
p = parent.parent
|
||||
while p
|
||||
full_name = p.child_name(@name)
|
||||
@module = RDoc::TopLevel.modules_hash[full_name]
|
||||
return @module if @module
|
||||
p = p.parent
|
||||
end
|
||||
|
||||
@name
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"include #@name in: #{parent}"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -59,12 +59,477 @@ require 'rdoc'
|
|||
#
|
||||
# puts "<body>#{wh.convert ARGF.read}</body>"
|
||||
#
|
||||
# == Encoding
|
||||
#
|
||||
# Where Encoding support is available RDoc will automatically convert all
|
||||
# documents to the same output encoding. The output encoding can be set via
|
||||
# RDoc::Options#encoding and defaults to Encoding.default_external.
|
||||
#
|
||||
# = \RDoc Markup Reference
|
||||
#
|
||||
# == Block Markup
|
||||
#
|
||||
# === Paragraphs and Verbatim
|
||||
#
|
||||
# The markup engine looks for a document's natural left margin. This is
|
||||
# used as the initial margin for the document.
|
||||
#
|
||||
# Consecutive lines starting at this margin are considered to be a
|
||||
# paragraph. Empty lines separate paragraphs.
|
||||
#
|
||||
# Any line that starts to the right of the current margin is treated
|
||||
# as verbatim text. This is useful for code listings:
|
||||
#
|
||||
# 3.times { puts "Ruby" }
|
||||
#
|
||||
# In verbatim text, two or more blank lines are collapsed into one,
|
||||
# and trailing blank lines are removed:
|
||||
#
|
||||
# This is the first line
|
||||
#
|
||||
#
|
||||
# This is the second non-blank line,
|
||||
# after 2 blank lines in the source markup.
|
||||
#
|
||||
#
|
||||
# There were two trailing blank lines right above this paragraph, that
|
||||
# have been removed. In addition, the verbatim text has been shifted
|
||||
# left, so the amount of indentation of verbatim text is unimportant.
|
||||
#
|
||||
# === Headers and Rules
|
||||
#
|
||||
# A line starting with an equal sign (=) is treated as a
|
||||
# heading. Level one headings have one equals sign, level two headings
|
||||
# have two, and so on until level six, which is the maximum
|
||||
# (seven hyphens or more result in a level six heading).
|
||||
#
|
||||
# For example, the above header was obtained with:
|
||||
# == Headers and Rules
|
||||
#
|
||||
# A line starting with three or more hyphens (at the current indent)
|
||||
# generates a horizontal rule. The more hyphens, the thicker the rule
|
||||
# (within reason, and if supported by the output device).
|
||||
#
|
||||
# In the case of HTML output, three dashes generate a 1-pixel high rule,
|
||||
# four dashes result in 2 pixels, and so on. The actual height is limited
|
||||
# to 10 pixels:
|
||||
#
|
||||
# ---
|
||||
# -----
|
||||
# -----------------------------------------------------
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# ---
|
||||
# -----
|
||||
# -----------------------------------------------------
|
||||
#
|
||||
# === Simple Lists
|
||||
#
|
||||
# If a paragraph starts with a "*", "-", "<digit>." or "<letter>.",
|
||||
# then it is taken to be the start of a list. The margin in increased to be
|
||||
# the first non-space following the list start flag. Subsequent lines
|
||||
# should be indented to this new margin until the list ends. For example:
|
||||
#
|
||||
# * this is a list with three paragraphs in
|
||||
# the first item. This is the first paragraph.
|
||||
#
|
||||
# And this is the second paragraph.
|
||||
#
|
||||
# 1. This is an indented, numbered list.
|
||||
# 2. This is the second item in that list
|
||||
#
|
||||
# This is the third conventional paragraph in the
|
||||
# first list item.
|
||||
#
|
||||
# * This is the second item in the original list
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# * this is a list with three paragraphs in
|
||||
# the first item. This is the first paragraph.
|
||||
#
|
||||
# And this is the second paragraph.
|
||||
#
|
||||
# 1. This is an indented, numbered list.
|
||||
# 2. This is the second item in that list
|
||||
#
|
||||
# This is the third conventional paragraph in the
|
||||
# first list item.
|
||||
#
|
||||
# * This is the second item in the original list
|
||||
#
|
||||
# === Labeled Lists
|
||||
#
|
||||
# You can also construct labeled lists, sometimes called description
|
||||
# or definition lists. Do this by putting the label in square brackets
|
||||
# and indenting the list body:
|
||||
#
|
||||
# [cat] a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# [ant] a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# [cat] a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# [ant] a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# If you want the list bodies to line up to the left of the labels,
|
||||
# use two colons:
|
||||
#
|
||||
# cat:: a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# ant:: a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# cat:: a small furry mammal
|
||||
# that seems to sleep a lot
|
||||
#
|
||||
# ant:: a little insect that is known
|
||||
# to enjoy picnics
|
||||
#
|
||||
# Notice that blank lines right after the label are ignored in labeled lists:
|
||||
#
|
||||
# [one]
|
||||
#
|
||||
# definition 1
|
||||
#
|
||||
# [two]
|
||||
#
|
||||
# definition 2
|
||||
#
|
||||
# produces the same output as
|
||||
#
|
||||
# [one] definition 1
|
||||
# [two] definition 2
|
||||
#
|
||||
#
|
||||
# === Lists and Verbatim
|
||||
#
|
||||
# If you want to introduce a verbatim section right after a list, it has to be
|
||||
# less indented than the list item bodies, but more indented than the list
|
||||
# label, letter, digit or bullet. For instance:
|
||||
#
|
||||
# * point 1
|
||||
#
|
||||
# * point 2, first paragraph
|
||||
#
|
||||
# point 2, second paragraph
|
||||
# verbatim text inside point 2
|
||||
# point 2, third paragraph
|
||||
# verbatim text outside of the list (the list is therefore closed)
|
||||
# regular paragraph after the list
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# * point 1
|
||||
#
|
||||
# * point 2, first paragraph
|
||||
#
|
||||
# point 2, second paragraph
|
||||
# verbatim text inside point 2
|
||||
# point 2, third paragraph
|
||||
# verbatim text outside of the list (the list is therefore closed)
|
||||
# regular paragraph after the list
|
||||
#
|
||||
#
|
||||
# == Text Markup
|
||||
#
|
||||
# === Bold, Italic, Typewriter Text
|
||||
#
|
||||
# You can use markup within text (except verbatim) to change the
|
||||
# appearance of parts of that text. Out of the box, RDoc::Markup
|
||||
# supports word-based and general markup.
|
||||
#
|
||||
# Word-based markup uses flag characters around individual words:
|
||||
#
|
||||
# <tt>\*_word_\*</tt>:: displays _word_ in a *bold* font
|
||||
# <tt>\__word_\_</tt>:: displays _word_ in an _emphasized_ font
|
||||
# <tt>\+_word_\+</tt>:: displays _word_ in a +code+ font
|
||||
#
|
||||
# General markup affects text between a start delimiter and an end
|
||||
# delimiter. Not surprisingly, these delimiters look like HTML markup.
|
||||
#
|
||||
# <tt>\<b>_text_</b></tt>:: displays _text_ in a *bold* font
|
||||
# <tt>\<em>_text_</em></tt>:: displays _text_ in an _emphasized_ font
|
||||
# (alternate tag: <tt>\<i></tt>)
|
||||
# <tt>\<tt>_text_\</tt></tt>:: displays _text_ in a +code+ font
|
||||
# (alternate tag: <tt>\<code></tt>)
|
||||
#
|
||||
# Unlike conventional Wiki markup, general markup can cross line
|
||||
# boundaries. You can turn off the interpretation of markup by
|
||||
# preceding the first character with a backslash (see <i>Escaping
|
||||
# Text Markup</i>, below).
|
||||
#
|
||||
# === Hyperlinks
|
||||
#
|
||||
# Hyperlinks to the web starting with +http:+, +mailto:+, +ftp:+ or +www.+
|
||||
# are recognized. An HTTP url that references an external image file is
|
||||
# converted into an inline <img...>. Hyperlinks starting with +link:+ are
|
||||
# assumed to refer to local files whose path is relative to the <tt>--op</tt>
|
||||
# directory.
|
||||
#
|
||||
# Hyperlinks can also be of the form _label_[_url_], in which
|
||||
# case _label_ is used in the displayed text, and _url_ is
|
||||
# used as the target. If _label_ contains multiple words,
|
||||
# put it in braces: {<em>multi word label</em>}[url].
|
||||
#
|
||||
# Example hyperlinks:
|
||||
#
|
||||
# link:RDoc.html
|
||||
# http://rdoc.rubyforge.org
|
||||
# mailto:user@example.com
|
||||
# {RDoc Documentation}[http://rdoc.rubyforge.org]
|
||||
# {RDoc Markup}[link:RDoc/Markup.html]
|
||||
#
|
||||
# === Escaping Text Markup
|
||||
#
|
||||
# Text markup can be escaped with a backslash, as in \<tt>, which was obtained
|
||||
# with "<tt>\\<tt></tt>". Except in verbatim sections and between \<tt> tags,
|
||||
# to produce a backslash, you have to double it unless it is followed by a
|
||||
# space, tab or newline. Otherwise, the HTML formatter will discard it, as it
|
||||
# is used to escape potential hyperlinks:
|
||||
#
|
||||
# * The \ must be doubled if not followed by white space: \\.
|
||||
# * But not in \<tt> tags: in a Regexp, <tt>\S</tt> matches non-space.
|
||||
# * This is a link to {ruby-lang}[www.ruby-lang.org].
|
||||
# * This is not a link, however: \{ruby-lang.org}[www.ruby-lang.org].
|
||||
# * This will not be hyperlinked to \RDoc::RDoc#document
|
||||
#
|
||||
# generates:
|
||||
#
|
||||
# * The \ must be doubled if not followed by white space: \\.
|
||||
# * But not in \<tt> tags: in a Regexp, <tt>\S</tt> matches non-space.
|
||||
# * This is a link to {ruby-lang}[www.ruby-lang.org]
|
||||
# * This is not a link, however: \{ruby-lang.org}[www.ruby-lang.org]
|
||||
# * This will not be hyperlinked to \RDoc::RDoc#document
|
||||
#
|
||||
# Inside \<tt> tags, more precisely, leading backslashes are removed
|
||||
# only if followed by a markup character (<tt><*_+</tt>), a backslash,
|
||||
# or a known hyperlink reference (a known class or method). So in the
|
||||
# example above, the backslash of <tt>\S</tt> would be removed
|
||||
# if there was a class or module named +S+ in the current context.
|
||||
#
|
||||
# This behavior is inherited from RDoc version 1, and has been kept
|
||||
# for compatibility with existing RDoc documentation.
|
||||
#
|
||||
# === Conversion of characters
|
||||
#
|
||||
# HTML will convert two/three dashes to an em-dash. Other common characters are
|
||||
# converted as well:
|
||||
#
|
||||
# em-dash:: -- or ---
|
||||
# ellipsis:: ...
|
||||
#
|
||||
# single quotes:: 'text' or `text'
|
||||
# double quotes:: "text" or ``text''
|
||||
#
|
||||
# copyright:: (c)
|
||||
# registered trademark:: (r)
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# em-dash:: -- or ---
|
||||
# ellipsis:: ...
|
||||
#
|
||||
# single quotes:: 'text' or `text'
|
||||
# double quotes:: "text" or ``text''
|
||||
#
|
||||
# copyright:: (c)
|
||||
# registered trademark:: (r)
|
||||
#
|
||||
#
|
||||
# == Documenting Source Code
|
||||
#
|
||||
# Comment blocks can be written fairly naturally, either using <tt>#</tt> on
|
||||
# successive lines of the comment, or by including the comment in
|
||||
# a <tt>=begin</tt>/<tt>=end</tt> block. If you use the latter form,
|
||||
# the <tt>=begin</tt> line _must_ be flagged with an +rdoc+ tag:
|
||||
#
|
||||
# =begin rdoc
|
||||
# Documentation to be processed by RDoc.
|
||||
#
|
||||
# ...
|
||||
# =end
|
||||
#
|
||||
# RDoc stops processing comments if it finds a comment line starting
|
||||
# with <tt>--</tt> right after the <tt>#</tt> character (otherwise,
|
||||
# it will be treated as a rule if it has three dashes or more).
|
||||
# This can be used to separate external from internal 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 <tt>++</tt>.
|
||||
#
|
||||
# ##
|
||||
# # Extract the age and calculate the date-of-birth.
|
||||
# #--
|
||||
# # FIXME: fails if the birthday falls on February 29th
|
||||
# #++
|
||||
# # The DOB is returned as a Time object.
|
||||
#
|
||||
# def get_dob(person)
|
||||
# # ...
|
||||
# end
|
||||
#
|
||||
# Names of classes, files, and any method names containing an
|
||||
# underscore or preceded by a hash character are automatically hyperlinked
|
||||
# from comment text to their description. This hyperlinking works inside
|
||||
# the current class or module, and with ancestor methods (in included modules
|
||||
# or in the superclass).
|
||||
#
|
||||
# Method parameter lists are extracted and displayed with the method
|
||||
# description. If a method calls +yield+, then the parameters passed to yield
|
||||
# will also be displayed:
|
||||
#
|
||||
# def fred
|
||||
# ...
|
||||
# yield line, address
|
||||
#
|
||||
# This will get documented as:
|
||||
#
|
||||
# fred() { |line, address| ... }
|
||||
#
|
||||
# You can override this using a comment containing ':yields: ...' immediately
|
||||
# after the method definition
|
||||
#
|
||||
# def fred # :yields: index, position
|
||||
# # ...
|
||||
#
|
||||
# yield line, address
|
||||
#
|
||||
# which will get documented as
|
||||
#
|
||||
# fred() { |index, position| ... }
|
||||
#
|
||||
# +:yields:+ is an example of a documentation directive. These appear
|
||||
# immediately after the start of the document element they are modifying.
|
||||
#
|
||||
# RDoc automatically cross-references words with underscores or camel-case.
|
||||
# To suppress cross-references, prefix the word with a \ character. To
|
||||
# include special characters like "<tt>\n</tt>", you'll need to use
|
||||
# two \ characters in normal text, but only one in \<tt> text:
|
||||
#
|
||||
# "\\n" or "<tt>\n</tt>"
|
||||
#
|
||||
# produces:
|
||||
#
|
||||
# "\\n" or "<tt>\n</tt>"
|
||||
#
|
||||
# == Directives
|
||||
#
|
||||
# Directives are keywords surrounded by ":" characters.
|
||||
#
|
||||
# === Controlling what is documented
|
||||
#
|
||||
# [+:nodoc:+ / <tt>:nodoc: all</tt>]
|
||||
# This directive prevents documentation for the element from
|
||||
# being generated. For classes and modules, the methods, aliases,
|
||||
# constants, and attributes directly within the affected class or
|
||||
# module also will be omitted. By default, though, modules and
|
||||
# classes within that class of module _will_ be documented. This is
|
||||
# turned off by adding the +all+ modifier.
|
||||
#
|
||||
# module MyModule # :nodoc:
|
||||
# class Input
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# module OtherModule # :nodoc: all
|
||||
# class Output
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# In the above code, only class <tt>MyModule::Input</tt> will be documented.
|
||||
#
|
||||
# The +:nodoc:+ directive, like +:enddoc:+, +:stopdoc:+ and +:startdoc:+
|
||||
# presented below, is local to the current file: if you do not want to
|
||||
# document a module that appears in several files, specify +:nodoc:+ on each
|
||||
# appearance, at least once per file.
|
||||
#
|
||||
# [+:stopdoc:+ / +:startdoc:+]
|
||||
# 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
|
||||
# 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,
|
||||
# disables documentation for the rest of the current file.
|
||||
#
|
||||
# [+:doc:+]
|
||||
# Forces a method or attribute to be documented even if it wouldn't be
|
||||
# otherwise. Useful if, for example, you want to include documentation of a
|
||||
# particular private method.
|
||||
#
|
||||
# [+:enddoc:+]
|
||||
# Document nothing further at the current level: directives +:startdoc:+ and
|
||||
# +:doc:+ that appear after this will not be honored for the current container
|
||||
# (file, class or module), in the current file.
|
||||
#
|
||||
# [+:notnew:+ / +:not_new:+ / +:not-new:+ ]
|
||||
# Only applicable to the +initialize+ instance method. Normally RDoc
|
||||
# assumes that the documentation and parameters for +initialize+ are
|
||||
# actually for the +new+ method, and so fakes out a +new+ for the class.
|
||||
# The +:notnew:+ directive stops this. Remember that +initialize+ is private,
|
||||
# so you won't see the documentation unless you use the +-a+ command line
|
||||
# option.
|
||||
#
|
||||
# === Other directives
|
||||
#
|
||||
# [+:include:+ _filename_]
|
||||
# Include the contents of the named file at this point. This directive
|
||||
# must appear alone on one line, possibly preceded by spaces. In this
|
||||
# position, it can be escapd with a \ in front of the first colon.
|
||||
#
|
||||
# The file will be searched for in the directories listed by the +--include+
|
||||
# option, or in 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 +:include:+ directive.
|
||||
#
|
||||
# [+:title:+ _text_]
|
||||
# Sets the title for the document. Equivalent to the <tt>--title</tt>
|
||||
# command line parameter. (The command line parameter overrides any :title:
|
||||
# directive in the source).
|
||||
#
|
||||
# [+:main:+ _name_]
|
||||
# Equivalent to the <tt>--main</tt> command line parameter.
|
||||
#
|
||||
# [<tt>:section: title</tt>]
|
||||
# Starts a new section in the output. The title following +:section:+ is
|
||||
# used as the section heading, and the remainder of the comment containing
|
||||
# the section is used as introductory text. Subsequent methods, aliases,
|
||||
# attributes, and classes will be documented in this section. A :section:
|
||||
# comment block may have one or more lines before the :section: directive.
|
||||
# These will be removed, and any identical lines at the end of the block are
|
||||
# also removed. This allows you to add visual cues such as:
|
||||
#
|
||||
# # ----------------------------------------
|
||||
# # :section: My Section
|
||||
# # This is the section that I wrote.
|
||||
# # See it glisten in the noon-day sun.
|
||||
# # ----------------------------------------
|
||||
#
|
||||
# <i>Note: Current formatters to not take sections into account.</i>
|
||||
#
|
||||
# [+:call-seq:+]
|
||||
# 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
|
||||
# yield arguments.
|
||||
#
|
||||
# Further directives can be found in RDoc::Parser::Ruby and RDoc::Parser::C.
|
||||
#--
|
||||
# Author:: Dave Thomas, dave@pragmaticprogrammer.com
|
||||
# License:: Ruby license
|
||||
# Original Author:: Dave Thomas, dave@pragmaticprogrammer.com
|
||||
# License:: Ruby license
|
||||
|
||||
class RDoc::Markup
|
||||
|
||||
##
|
||||
# An AttributeManager which handles inline markup.
|
||||
|
||||
attr_reader :attribute_manager
|
||||
|
||||
##
|
||||
|
|
|
@ -15,9 +15,12 @@ class RDoc::Markup::AttributeManager
|
|||
# optimistic
|
||||
#++
|
||||
|
||||
A_PROTECT = 004 # :nodoc:
|
||||
A_PROTECT = 004 # :nodoc:
|
||||
|
||||
PROTECT_ATTR = A_PROTECT.chr # :nodoc:
|
||||
##
|
||||
# Special mask character to prevent inline markup handling
|
||||
|
||||
PROTECT_ATTR = A_PROTECT.chr # :nodoc:
|
||||
|
||||
##
|
||||
# This maps delimiters that occur around words (such as *bold* or +tt+)
|
||||
|
@ -56,7 +59,7 @@ class RDoc::Markup::AttributeManager
|
|||
def initialize
|
||||
@html_tags = {}
|
||||
@matching_word_pairs = {}
|
||||
@protectable = %w[<\\]
|
||||
@protectable = %w[<]
|
||||
@special = {}
|
||||
@word_pair_map = {}
|
||||
|
||||
|
@ -79,12 +82,19 @@ class RDoc::Markup::AttributeManager
|
|||
RDoc::Markup::AttrChanger.new turn_on, turn_off
|
||||
end
|
||||
|
||||
def change_attribute(current, new)
|
||||
##
|
||||
# Changes the current attribute from +current+ to +new+
|
||||
|
||||
def change_attribute current, new
|
||||
diff = current ^ new
|
||||
attribute(new & diff, current & diff)
|
||||
end
|
||||
|
||||
def changed_attribute_by_name(current_set, new_set)
|
||||
##
|
||||
# Used by the tests to change attributes by name from +current_set+ to
|
||||
# +new_set+
|
||||
|
||||
def changed_attribute_by_name current_set, new_set
|
||||
current = new = 0
|
||||
current_set.each do |name|
|
||||
current |= RDoc::Markup::Attribute.bitmap_for(name)
|
||||
|
@ -97,6 +107,9 @@ class RDoc::Markup::AttributeManager
|
|||
change_attribute(current, new)
|
||||
end
|
||||
|
||||
##
|
||||
# Copies +start_pos+ to +end_pos+ from the current string
|
||||
|
||||
def copy_string(start_pos, end_pos)
|
||||
res = @str[start_pos...end_pos]
|
||||
res.gsub!(/\000/, '')
|
||||
|
@ -112,7 +125,7 @@ class RDoc::Markup::AttributeManager
|
|||
# first do matching ones
|
||||
tags = @matching_word_pairs.keys.join("")
|
||||
|
||||
re = /(^|[^\w#{NULL}])([#{tags}])([#:\\]?[\w.\/-]+?\S?)\2(\W|$)/
|
||||
re = /(^|\W)([#{tags}])([#:\\]?[\w.\/-]+?\S?)\2(\W|$)/
|
||||
|
||||
1 while str.gsub!(re) do
|
||||
attr = @matching_word_pairs[$2]
|
||||
|
@ -164,6 +177,9 @@ class RDoc::Markup::AttributeManager
|
|||
# Escapes special sequences of text to prevent conversion to RDoc
|
||||
|
||||
def mask_protected_sequences
|
||||
# protect __send__, __FILE__, etc.
|
||||
@str.gsub!(/__([a-z]+)__/i,
|
||||
"_#{PROTECT_ATTR}_#{PROTECT_ATTR}\\1_#{PROTECT_ATTR}_#{PROTECT_ATTR}")
|
||||
@str.gsub!(/\\([#{Regexp.escape @protectable.join('')}])/,
|
||||
"\\1#{PROTECT_ATTR}")
|
||||
end
|
||||
|
@ -228,8 +244,8 @@ class RDoc::Markup::AttributeManager
|
|||
|
||||
@attrs = RDoc::Markup::AttrSpan.new @str.length
|
||||
|
||||
convert_html @str, @attrs
|
||||
convert_attrs @str, @attrs
|
||||
convert_html @str, @attrs
|
||||
convert_specials @str, @attrs
|
||||
|
||||
unmask_protected_sequences
|
||||
|
@ -262,6 +278,9 @@ class RDoc::Markup::AttributeManager
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Splits the string into chunks by attribute change
|
||||
|
||||
def split_into_flow
|
||||
res = []
|
||||
current_attr = 0
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
##
|
||||
# An empty line
|
||||
# An empty line. This class is a singleton.
|
||||
|
||||
class RDoc::Markup::BlankLine
|
||||
|
||||
def == other # :nodoc:
|
||||
self.class == other.class
|
||||
@instance = new
|
||||
|
||||
##
|
||||
# RDoc::Markup::BlankLine is a singleton
|
||||
|
||||
def self.new
|
||||
@instance
|
||||
end
|
||||
|
||||
##
|
||||
# Calls #accept_blank_line on +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_blank_line self
|
||||
end
|
||||
|
|
|
@ -39,6 +39,9 @@ class RDoc::Markup::Document
|
|||
self.class == other.class and @parts == other.parts
|
||||
end
|
||||
|
||||
##
|
||||
# Runs this document and all its #items through +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.start_accepting
|
||||
|
||||
|
@ -49,6 +52,9 @@ class RDoc::Markup::Document
|
|||
visitor.end_accepting
|
||||
end
|
||||
|
||||
##
|
||||
# Does this document have no parts?
|
||||
|
||||
def empty?
|
||||
@parts.empty?
|
||||
end
|
||||
|
|
|
@ -7,6 +7,10 @@ require 'rdoc/markup'
|
|||
|
||||
class RDoc::Markup::Formatter
|
||||
|
||||
##
|
||||
# Tag for inline markup containing a +bit+ for the bitmask and the +on+ and
|
||||
# +off+ triggers.
|
||||
|
||||
InlineTag = Struct.new(:bit, :on, :off)
|
||||
|
||||
##
|
||||
|
@ -101,6 +105,9 @@ class RDoc::Markup::Formatter
|
|||
@in_tt > 0
|
||||
end
|
||||
|
||||
##
|
||||
# Turns on tags for +item+ on +res+
|
||||
|
||||
def on_tags res, item
|
||||
attr_mask = item.turn_on
|
||||
return if attr_mask.zero?
|
||||
|
@ -113,6 +120,9 @@ class RDoc::Markup::Formatter
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Turns off tags for +item+ on +res+
|
||||
|
||||
def off_tags res, item
|
||||
attr_mask = item.turn_off
|
||||
return if attr_mask.zero?
|
||||
|
|
|
@ -4,14 +4,57 @@ require 'rdoc/markup/formatter'
|
|||
##
|
||||
# Test case for creating new RDoc::Markup formatters. See
|
||||
# test/test_rdoc_markup_to_*.rb for examples.
|
||||
#
|
||||
# This test case adds a variety of tests to your subclass when
|
||||
# #add_visitor_tests is called. Most tests set up a scenario then call a
|
||||
# method you will provide to perform the assertion on the output.
|
||||
#
|
||||
# Your subclass must instantiate a visitor and assign it to <tt>@to</tt>.
|
||||
#
|
||||
# For example, test_accept_blank_line sets up a RDoc::Markup::BlockLine then
|
||||
# calls accept_blank_line on your visitor. You are responsible for asserting
|
||||
# that the output is correct.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# class TestRDocMarkupToNewFormat < RDoc::Markup::FormatterTestCase
|
||||
#
|
||||
# add_visitor_tests
|
||||
#
|
||||
# def setup
|
||||
# super
|
||||
#
|
||||
# @to = RDoc::Markup::ToNewFormat.new
|
||||
# end
|
||||
#
|
||||
# def accept_blank_line
|
||||
# assert_equal :junk, @to.res.join
|
||||
# end
|
||||
#
|
||||
# # ...
|
||||
#
|
||||
# end
|
||||
|
||||
class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
||||
|
||||
##
|
||||
# Call #setup when inheriting from this test case.
|
||||
#
|
||||
# Provides the following instance variables:
|
||||
#
|
||||
# +@m+:: RDoc::Markup.new
|
||||
# +@RM+:: RDoc::Markup # to reduce typing
|
||||
# +@bullet_list+:: @RM::List.new :BULLET, # ...
|
||||
# +@label_list+:: @RM::List.new :LABEL, # ...
|
||||
# +@lalpha_list+:: @RM::List.new :LALPHA, # ...
|
||||
# +@note_list+:: @RM::List.new :NOTE, # ...
|
||||
# +@number_list+:: @RM::List.new :NUMBER, # ...
|
||||
# +@ualpha_list+:: @RM::List.new :UALPHA, # ...
|
||||
|
||||
def setup
|
||||
super
|
||||
|
||||
@m = RDoc::Markup.new
|
||||
@am = RDoc::Markup::AttributeManager.new
|
||||
@RM = RDoc::Markup
|
||||
|
||||
@bullet_list = @RM::List.new(:BULLET,
|
||||
|
@ -39,14 +82,25 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
@RM::ListItem.new(nil, @RM::Paragraph.new('l2')))
|
||||
end
|
||||
|
||||
##
|
||||
# Call to add the visitor tests to your test case
|
||||
|
||||
def self.add_visitor_tests
|
||||
self.class_eval do
|
||||
|
||||
##
|
||||
# Calls start_accepting which needs to verify startup state
|
||||
|
||||
def test_start_accepting
|
||||
@to.start_accepting
|
||||
|
||||
start_accepting
|
||||
end
|
||||
|
||||
##
|
||||
# Calls end_accepting on your test case which needs to call
|
||||
# <tt>@to.end_accepting</tt> and verify document generation
|
||||
|
||||
def test_end_accepting
|
||||
@to.start_accepting
|
||||
@to.res << 'hi'
|
||||
|
@ -54,6 +108,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
end_accepting
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_blank_line
|
||||
|
||||
def test_accept_blank_line
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -62,6 +119,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_blank_line
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading with a level 5 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -70,6 +130,79 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_heading
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_1 with a level 1 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading_1
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
accept_heading_1
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_2 with a level 2 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading_2
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(2, 'Hello')
|
||||
|
||||
accept_heading_2
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_3 with a level 3 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading_3
|
||||
# HACK this doesn't belong here
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(3, 'Hello')
|
||||
|
||||
accept_heading_3
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_4 with a level 4 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading_4
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(4, 'Hello')
|
||||
|
||||
accept_heading_4
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_b with a bold level 1 RDoc::Markup::Heading
|
||||
|
||||
def test_accept_heading_b
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(1, '*Hello*')
|
||||
|
||||
accept_heading_b
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_heading_suppressed_crossref with a level 1
|
||||
# RDoc::Markup::Heading containing a suppressed crossref
|
||||
|
||||
def test_accept_heading_suppressed_crossref # HACK to_html_crossref test
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_heading @RM::Heading.new(1, '\\Hello')
|
||||
|
||||
accept_heading_suppressed_crossref
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph
|
||||
|
||||
def test_accept_paragraph
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -78,15 +211,80 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_paragraph
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph_b with a RDoc::Markup::Paragraph containing
|
||||
# bold words
|
||||
|
||||
def test_accept_paragraph_b
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
|
||||
|
||||
accept_paragraph_b
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph_i with a RDoc::Markup::Paragraph containing
|
||||
# emphasized words
|
||||
|
||||
def test_accept_paragraph_i
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
|
||||
|
||||
accept_paragraph_i
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph_plus with a RDoc::Markup::Paragraph containing
|
||||
# teletype words
|
||||
|
||||
def test_accept_paragraph_plus
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg +teletype+ reg')
|
||||
|
||||
accept_paragraph_plus
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph_star with a RDoc::Markup::Paragraph containing
|
||||
# bold words
|
||||
|
||||
def test_accept_paragraph_star
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg *bold* reg')
|
||||
|
||||
accept_paragraph_star
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_paragraph_underscore with a RDoc::Markup::Paragraph
|
||||
# containing emphasized words
|
||||
|
||||
def test_accept_paragraph_underscore
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg _italic_ reg')
|
||||
|
||||
accept_paragraph_underscore
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_verbatim with a RDoc::Markup::Verbatim
|
||||
|
||||
def test_accept_verbatim
|
||||
@to.start_accepting
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
@to.accept_verbatim @RM::Verbatim.new("hi\n", " world\n")
|
||||
|
||||
accept_verbatim
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_raw with a RDoc::Markup::Raw
|
||||
|
||||
def test_accept_raw
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -99,6 +297,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_raw
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_rule with a RDoc::Markup::Rule
|
||||
|
||||
def test_accept_rule
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -107,6 +308,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_rule
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_bullet
|
||||
|
||||
def test_accept_list_item_start_bullet
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -117,6 +321,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_bullet
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_label
|
||||
|
||||
def test_accept_list_item_start_label
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -127,6 +334,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_label
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_lalpha
|
||||
|
||||
def test_accept_list_item_start_lalpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -137,6 +347,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_lalpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_note
|
||||
|
||||
def test_accept_list_item_start_note
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -147,6 +360,26 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_note
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_note_2
|
||||
|
||||
def test_accept_list_item_start_note_2
|
||||
list = @RM::List.new(:NOTE,
|
||||
@RM::ListItem.new('<tt>teletype</tt>',
|
||||
@RM::Paragraph.new('teletype description')))
|
||||
|
||||
@to.start_accepting
|
||||
|
||||
list.accept @to
|
||||
|
||||
@to.end_accepting
|
||||
|
||||
accept_list_item_start_note_2
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_number
|
||||
|
||||
def test_accept_list_item_start_number
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -157,6 +390,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_number
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_start_ualpha
|
||||
|
||||
def test_accept_list_item_start_ualpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -167,6 +403,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_start_ualpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_bullet
|
||||
|
||||
def test_accept_list_item_end_bullet
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -179,6 +418,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_bullet
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_label
|
||||
|
||||
def test_accept_list_item_end_label
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -191,6 +433,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_label
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_lalpha
|
||||
|
||||
def test_accept_list_item_end_lalpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -203,6 +448,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_lalpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_note
|
||||
|
||||
def test_accept_list_item_end_note
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -215,6 +463,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_note
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_number
|
||||
|
||||
def test_accept_list_item_end_number
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -227,6 +478,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_number
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_item_end_ualpha
|
||||
|
||||
def test_accept_list_item_end_ualpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -239,6 +493,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_item_end_ualpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_bullet
|
||||
|
||||
def test_accept_list_start_bullet
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -247,6 +504,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_bullet
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_label
|
||||
|
||||
def test_accept_list_start_label
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -255,6 +515,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_label
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_lalpha
|
||||
|
||||
def test_accept_list_start_lalpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -263,6 +526,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_lalpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_note
|
||||
|
||||
def test_accept_list_start_note
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -271,6 +537,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_note
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_number
|
||||
|
||||
def test_accept_list_start_number
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -279,6 +548,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_number
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_start_ualpha
|
||||
|
||||
def test_accept_list_start_ualpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -287,6 +559,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_start_ualpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_bullet
|
||||
|
||||
def test_accept_list_end_bullet
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -297,6 +572,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_end_bullet
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_label
|
||||
|
||||
def test_accept_list_end_label
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -307,6 +585,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_end_label
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_lalpha
|
||||
|
||||
def test_accept_list_end_lalpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -317,6 +598,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_end_lalpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_number
|
||||
|
||||
def test_accept_list_end_number
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -327,6 +611,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_end_number
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_note
|
||||
|
||||
def test_accept_list_end_note
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -337,6 +624,9 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
accept_list_end_note
|
||||
end
|
||||
|
||||
##
|
||||
# Calls accept_list_end_ulpha
|
||||
|
||||
def test_accept_list_end_ualpha
|
||||
@to.start_accepting
|
||||
|
||||
|
@ -346,6 +636,52 @@ class RDoc::Markup::FormatterTestCase < MiniTest::Unit::TestCase
|
|||
|
||||
accept_list_end_ualpha
|
||||
end
|
||||
|
||||
##
|
||||
# Calls list_nested with a two-level list
|
||||
|
||||
def test_list_nested
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1'),
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1.1')))),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l2'))))
|
||||
|
||||
doc.accept @to
|
||||
|
||||
list_nested
|
||||
end
|
||||
|
||||
##
|
||||
# Calls list_verbatim with a list containing a verbatim block
|
||||
|
||||
def test_list_verbatim # HACK overblown
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('list', 'stuff'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new("* list\n",
|
||||
" with\n",
|
||||
"\n",
|
||||
" second\n",
|
||||
"\n",
|
||||
" 1. indented\n",
|
||||
" 2. numbered\n",
|
||||
"\n",
|
||||
" third\n",
|
||||
"\n",
|
||||
"* second\n"))))
|
||||
|
||||
doc.accept @to
|
||||
|
||||
list_verbatim
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
class RDoc::Markup::Heading < Struct.new :level, :text
|
||||
|
||||
##
|
||||
# Calls #accept_heading on +wisitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_heading self
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'rdoc'
|
||||
class RDoc::Markup
|
||||
|
||||
##
|
||||
|
@ -14,6 +15,9 @@ class RDoc::Markup
|
|||
@@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
|
||||
@@next_bitmap = 2
|
||||
|
||||
##
|
||||
# Returns a unique bit for +name+
|
||||
|
||||
def self.bitmap_for(name)
|
||||
bitmap = @@name_to_bitmap[name]
|
||||
unless bitmap then
|
||||
|
@ -24,6 +28,9 @@ class RDoc::Markup
|
|||
bitmap
|
||||
end
|
||||
|
||||
##
|
||||
# Returns a string reperesentation of +bitmap+
|
||||
|
||||
def self.as_string(bitmap)
|
||||
return "none" if bitmap.zero?
|
||||
res = []
|
||||
|
@ -33,6 +40,9 @@ class RDoc::Markup
|
|||
res.join(",")
|
||||
end
|
||||
|
||||
##
|
||||
# yields each attribute name in +bitmap+
|
||||
|
||||
def self.each_name_of(bitmap)
|
||||
@@name_to_bitmap.each do |name, bit|
|
||||
next if bit == SPECIAL
|
||||
|
@ -75,7 +85,7 @@ class RDoc::Markup
|
|||
end
|
||||
|
||||
##
|
||||
# Acccesses flags for character +n+
|
||||
# Accesses flags for character +n+
|
||||
|
||||
def [](n)
|
||||
@attrs[n]
|
||||
|
|
|
@ -35,6 +35,9 @@ class RDoc::Markup::List
|
|||
@items == other.items
|
||||
end
|
||||
|
||||
##
|
||||
# Runs this list and all its #items through +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_list_start self
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@ class RDoc::Markup::ListItem
|
|||
@parts == other.parts
|
||||
end
|
||||
|
||||
##
|
||||
# Runs this list item and all its #parts through +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_list_item_start self
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
class RDoc::Markup::Paragraph < RDoc::Markup::Raw
|
||||
|
||||
##
|
||||
# Calls #accept_paragraph on +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_paragraph self
|
||||
end
|
||||
|
|
|
@ -52,13 +52,13 @@ class RDoc::Markup::Parser
|
|||
attr_reader :tokens
|
||||
|
||||
##
|
||||
# Parsers +str+ into a Document
|
||||
# Parses +str+ into a Document
|
||||
|
||||
def self.parse str
|
||||
parser = new
|
||||
#parser.debug = true
|
||||
parser.tokenize str
|
||||
RDoc::Markup::Document.new(*parser.parse)
|
||||
doc = RDoc::Markup::Document.new
|
||||
parser.parse doc
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -86,6 +86,7 @@ class RDoc::Markup::Parser
|
|||
# Builds a Heading of +level+
|
||||
|
||||
def build_heading level
|
||||
_, text, = get # TEXT
|
||||
heading = RDoc::Markup::Heading.new level, text
|
||||
skip :NEWLINE
|
||||
|
||||
|
@ -105,38 +106,69 @@ class RDoc::Markup::Parser
|
|||
|
||||
case type
|
||||
when :BULLET, :LABEL, :LALPHA, :NOTE, :NUMBER, :UALPHA then
|
||||
list_type = type
|
||||
|
||||
if column < margin then
|
||||
if column < margin || (list.type && list.type != type) then
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
if list.type and list.type != list_type then
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
list.type = list_type
|
||||
list.type = type
|
||||
peek_type, _, column, = peek_token
|
||||
|
||||
case type
|
||||
when :NOTE, :LABEL then
|
||||
_, indent, = get # SPACE
|
||||
if :NEWLINE == peek_token.first then
|
||||
get
|
||||
peek_type, new_indent, peek_column, = peek_token
|
||||
indent = new_indent if
|
||||
peek_type == :INDENT and peek_column >= column
|
||||
unget
|
||||
if peek_type == :NEWLINE then
|
||||
# description not on the same line as LABEL/NOTE
|
||||
# skip the trailing newline & any blank lines below
|
||||
while peek_type == :NEWLINE
|
||||
get
|
||||
peek_type, _, column, = peek_token
|
||||
end
|
||||
|
||||
# we may be:
|
||||
# - at end of stream
|
||||
# - at a column < margin:
|
||||
# [text]
|
||||
# blah blah blah
|
||||
# - at the same column, but with a different type of list item
|
||||
# [text]
|
||||
# * blah blah
|
||||
# - at the same column, with the same type of list item
|
||||
# [one]
|
||||
# [two]
|
||||
# In all cases, we have an empty description.
|
||||
# In the last case only, we continue.
|
||||
if peek_type.nil? || column < margin then
|
||||
empty = 1
|
||||
elsif column == margin then
|
||||
case peek_type
|
||||
when type
|
||||
empty = 2 # continue
|
||||
when *LIST_TOKENS
|
||||
empty = 1
|
||||
else
|
||||
empty = 0
|
||||
end
|
||||
else
|
||||
empty = 0
|
||||
end
|
||||
|
||||
if empty > 0 then
|
||||
item = RDoc::Markup::ListItem.new(data)
|
||||
item << RDoc::Markup::BlankLine.new
|
||||
list << item
|
||||
break if empty == 1
|
||||
next
|
||||
end
|
||||
end
|
||||
else
|
||||
data = nil
|
||||
_, indent, = get
|
||||
end
|
||||
|
||||
list_item = build_list_item(margin + indent, data)
|
||||
list_item = RDoc::Markup::ListItem.new data
|
||||
parse list_item, column
|
||||
list << list_item
|
||||
|
||||
list << list_item if list_item
|
||||
else
|
||||
unget
|
||||
break
|
||||
|
@ -150,54 +182,6 @@ class RDoc::Markup::Parser
|
|||
list
|
||||
end
|
||||
|
||||
##
|
||||
# Builds a ListItem that is flush to +indent+ with type +item_type+
|
||||
|
||||
def build_list_item indent, item_type = nil
|
||||
p :list_item_start => [indent, item_type] if @debug
|
||||
|
||||
list_item = RDoc::Markup::ListItem.new item_type
|
||||
|
||||
until @tokens.empty? do
|
||||
type, data, column = get
|
||||
|
||||
if column < indent and
|
||||
not type == :NEWLINE and
|
||||
(type != :INDENT or data < indent) then
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
case type
|
||||
when :INDENT then
|
||||
unget
|
||||
list_item.push(*parse(indent))
|
||||
when :TEXT then
|
||||
unget
|
||||
list_item << build_paragraph(indent)
|
||||
when :HEADER then
|
||||
list_item << build_heading(data)
|
||||
when :NEWLINE then
|
||||
list_item << RDoc::Markup::BlankLine.new
|
||||
when *LIST_TOKENS then
|
||||
unget
|
||||
list_item << build_list(column)
|
||||
else
|
||||
raise ParseError, "Unhandled token #{@current_token.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
p :list_item_end => [indent, item_type] if @debug
|
||||
|
||||
return nil if list_item.empty?
|
||||
|
||||
list_item.parts.shift if
|
||||
RDoc::Markup::BlankLine === list_item.parts.first and
|
||||
list_item.length > 1
|
||||
|
||||
list_item
|
||||
end
|
||||
|
||||
##
|
||||
# Builds a Paragraph that is flush to +margin+
|
||||
|
||||
|
@ -209,18 +193,7 @@ class RDoc::Markup::Parser
|
|||
until @tokens.empty? do
|
||||
type, data, column, = get
|
||||
|
||||
case type
|
||||
when :INDENT then
|
||||
next if data == margin and peek_token[0] == :TEXT
|
||||
|
||||
unget
|
||||
break
|
||||
when :TEXT then
|
||||
if column != margin then
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
if type == :TEXT && column == margin then
|
||||
paragraph << data
|
||||
skip :NEWLINE
|
||||
else
|
||||
|
@ -235,67 +208,81 @@ class RDoc::Markup::Parser
|
|||
end
|
||||
|
||||
##
|
||||
# Builds a Verbatim that is flush to +margin+
|
||||
# Builds a Verbatim that is indented from +margin+.
|
||||
#
|
||||
# The verbatim block is shifted left (the least indented lines start in
|
||||
# column 0). Each part of the verbatim is one line of text, always
|
||||
# terminated by a newline. Blank lines always consist of a single newline
|
||||
# character, and there is never a single newline at the end of the verbatim.
|
||||
|
||||
def build_verbatim margin
|
||||
p :verbatim_begin => margin if @debug
|
||||
verbatim = RDoc::Markup::Verbatim.new
|
||||
|
||||
min_indent = nil
|
||||
generate_leading_spaces = true
|
||||
line = ''
|
||||
|
||||
until @tokens.empty? do
|
||||
type, data, column, = get
|
||||
|
||||
case type
|
||||
when :INDENT then
|
||||
if margin >= data then
|
||||
unget
|
||||
break
|
||||
end
|
||||
if type == :NEWLINE then
|
||||
line << data
|
||||
verbatim << line
|
||||
line = ''
|
||||
generate_leading_spaces = true
|
||||
next
|
||||
end
|
||||
|
||||
indent = data - margin
|
||||
|
||||
verbatim << ' ' * indent
|
||||
when :HEADER then
|
||||
verbatim << '=' * data
|
||||
|
||||
_, _, peek_column, = peek_token
|
||||
peek_column ||= column + data
|
||||
verbatim << ' ' * (peek_column - column - data)
|
||||
when :RULE then
|
||||
width = 2 + data
|
||||
verbatim << '-' * width
|
||||
|
||||
_, _, peek_column, = peek_token
|
||||
peek_column ||= column + data + 2
|
||||
verbatim << ' ' * (peek_column - column - width)
|
||||
when :TEXT then
|
||||
verbatim << data
|
||||
when *LIST_TOKENS then
|
||||
if column <= margin then
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
list_marker = case type
|
||||
when :BULLET then '*'
|
||||
when :LABEL then "[#{data}]"
|
||||
when :LALPHA, :NUMBER, :UALPHA then "#{data}."
|
||||
when :NOTE then "#{data}::"
|
||||
end
|
||||
|
||||
verbatim << list_marker
|
||||
|
||||
_, data, = get
|
||||
|
||||
verbatim << ' ' * (data - list_marker.length)
|
||||
when :NEWLINE then
|
||||
verbatim << data
|
||||
break unless [:INDENT, :NEWLINE].include? peek_token[0]
|
||||
else
|
||||
if column <= margin
|
||||
unget
|
||||
break
|
||||
end
|
||||
|
||||
if generate_leading_spaces then
|
||||
indent = column - margin
|
||||
line << ' ' * indent
|
||||
min_indent = indent if min_indent.nil? || indent < min_indent
|
||||
generate_leading_spaces = false
|
||||
end
|
||||
|
||||
case type
|
||||
when :HEADER then
|
||||
line << '=' * data
|
||||
_, _, peek_column, = peek_token
|
||||
peek_column ||= column + data
|
||||
indent = peek_column - column - data
|
||||
line << ' ' * indent
|
||||
when :RULE then
|
||||
width = 2 + data
|
||||
line << '-' * width
|
||||
_, _, peek_column, = peek_token
|
||||
peek_column ||= column + width
|
||||
indent = peek_column - column - width
|
||||
line << ' ' * indent
|
||||
when :TEXT then
|
||||
line << data
|
||||
else # *LIST_TOKENS
|
||||
list_marker = case type
|
||||
when :BULLET then data
|
||||
when :LABEL then "[#{data}]"
|
||||
when :NOTE then "#{data}::"
|
||||
else # :LALPHA, :NUMBER, :UALPHA
|
||||
"#{data}."
|
||||
end
|
||||
line << list_marker
|
||||
peek_type, _, peek_column = peek_token
|
||||
unless peek_type == :NEWLINE then
|
||||
peek_column ||= column + list_marker.length
|
||||
indent = peek_column - column - list_marker.length
|
||||
line << ' ' * indent
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
verbatim << line << "\n" unless line.empty?
|
||||
verbatim.parts.each { |p| p.slice!(0, min_indent) unless p == "\n" } if min_indent > 0
|
||||
verbatim.normalize
|
||||
|
||||
p :verbatim_end => margin if @debug
|
||||
|
@ -313,65 +300,60 @@ class RDoc::Markup::Parser
|
|||
end
|
||||
|
||||
##
|
||||
# Parses the tokens into a Document
|
||||
# Parses the tokens into an array of RDoc::Markup::XXX objects,
|
||||
# and appends them to the passed +parent+ RDoc::Markup::YYY object.
|
||||
#
|
||||
# Exits at the end of the token stream, or when it encounters a token
|
||||
# in a column less than +indent+ (unless it is a NEWLINE).
|
||||
#
|
||||
# Returns +parent+.
|
||||
|
||||
def parse indent = 0
|
||||
def parse parent, indent = 0
|
||||
p :parse_start => indent if @debug
|
||||
|
||||
document = []
|
||||
|
||||
until @tokens.empty? do
|
||||
type, data, column, = get
|
||||
|
||||
if type != :INDENT and column < indent then
|
||||
unget
|
||||
break
|
||||
if type == :NEWLINE then
|
||||
# trailing newlines are skipped below, so this is a blank line
|
||||
parent << RDoc::Markup::BlankLine.new
|
||||
skip :NEWLINE, false
|
||||
next
|
||||
end
|
||||
|
||||
# indentation change: break or verbattim
|
||||
if column < indent then
|
||||
unget
|
||||
break
|
||||
elsif column > indent then
|
||||
unget
|
||||
parent << build_verbatim(indent)
|
||||
next
|
||||
end
|
||||
|
||||
# indentation is the same
|
||||
case type
|
||||
when :HEADER then
|
||||
document << build_heading(data)
|
||||
when :INDENT then
|
||||
if indent > data then
|
||||
unget
|
||||
break
|
||||
elsif indent == data then
|
||||
next
|
||||
end
|
||||
|
||||
unget
|
||||
document << build_verbatim(indent)
|
||||
when :NEWLINE then
|
||||
document << RDoc::Markup::BlankLine.new
|
||||
skip :NEWLINE, false
|
||||
parent << build_heading(data)
|
||||
when :RULE then
|
||||
document << RDoc::Markup::Rule.new(data)
|
||||
parent << RDoc::Markup::Rule.new(data)
|
||||
skip :NEWLINE
|
||||
when :TEXT then
|
||||
unget
|
||||
document << build_paragraph(indent)
|
||||
|
||||
# we're done with this paragraph (indent mismatch)
|
||||
break if peek_token[0] == :TEXT
|
||||
parent << build_paragraph(indent)
|
||||
when *LIST_TOKENS then
|
||||
unget
|
||||
|
||||
list = build_list(indent)
|
||||
|
||||
document << list if list
|
||||
|
||||
# we're done with this list (indent mismatch)
|
||||
break if LIST_TOKENS.include? peek_token.first and indent > 0
|
||||
parent << build_list(indent)
|
||||
else
|
||||
type, data, column, line = @current_token
|
||||
raise ParseError,
|
||||
"Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}"
|
||||
raise ParseError, "Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}"
|
||||
end
|
||||
end
|
||||
|
||||
p :parse_end => indent if @debug
|
||||
|
||||
document
|
||||
parent
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -384,63 +366,16 @@ class RDoc::Markup::Parser
|
|||
end
|
||||
|
||||
##
|
||||
# Skips a token of +token_type+, optionally raising an error.
|
||||
# Skips the next token if its type is +token_type+.
|
||||
#
|
||||
# Optionally raises an error if the next token is not of the expected type.
|
||||
|
||||
def skip token_type, error = true
|
||||
type, = get
|
||||
|
||||
return unless type # end of stream
|
||||
|
||||
return @current_token if token_type == type
|
||||
|
||||
unget
|
||||
|
||||
raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if
|
||||
error
|
||||
end
|
||||
|
||||
##
|
||||
# Consumes tokens until NEWLINE and turns them back into text
|
||||
|
||||
def text
|
||||
text = ''
|
||||
|
||||
loop do
|
||||
type, data, = get
|
||||
|
||||
text << case type
|
||||
when :BULLET then
|
||||
_, space, = get # SPACE
|
||||
"*#{' ' * (space - 1)}"
|
||||
when :LABEL then
|
||||
_, space, = get # SPACE
|
||||
"[#{data}]#{' ' * (space - data.length - 2)}"
|
||||
when :LALPHA, :NUMBER, :UALPHA then
|
||||
_, space, = get # SPACE
|
||||
"#{data}.#{' ' * (space - 2)}"
|
||||
when :NOTE then
|
||||
_, space = get # SPACE
|
||||
"#{data}::#{' ' * (space - data.length - 2)}"
|
||||
when :TEXT then
|
||||
data
|
||||
when :NEWLINE then
|
||||
unget
|
||||
break
|
||||
when nil then
|
||||
break
|
||||
else
|
||||
raise ParseError, "unhandled token #{@current_token.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
text
|
||||
end
|
||||
|
||||
##
|
||||
# Calculates the column and line of the current token based on +offset+.
|
||||
|
||||
def token_pos offset
|
||||
[offset - @line_pos, @line]
|
||||
raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if error
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -455,51 +390,62 @@ class RDoc::Markup::Parser
|
|||
until s.eos? do
|
||||
pos = s.pos
|
||||
|
||||
# leading spaces will be reflected by the column of the next token
|
||||
# the only thing we loose are trailing spaces at the end of the file
|
||||
next if s.scan(/ +/)
|
||||
|
||||
# note: after BULLET, LABEL, etc.,
|
||||
# indent will be the column of the next non-newline token
|
||||
|
||||
@tokens << case
|
||||
# [CR]LF => :NEWLINE
|
||||
when s.scan(/\r?\n/) then
|
||||
token = [:NEWLINE, s.matched, *token_pos(pos)]
|
||||
@line_pos = s.pos
|
||||
@line += 1
|
||||
token
|
||||
when s.scan(/ +/) then
|
||||
[:INDENT, s.matched_size, *token_pos(pos)]
|
||||
# === text => :HEADER then :TEXT
|
||||
when s.scan(/(=+)\s*/) then
|
||||
level = s[1].length
|
||||
level = 6 if level > 6
|
||||
@tokens << [:HEADER, level, *token_pos(pos)]
|
||||
|
||||
pos = s.pos
|
||||
s.scan(/.*/)
|
||||
[:TEXT, s.matched, *token_pos(pos)]
|
||||
when s.scan(/^(-{3,}) *$/) then
|
||||
[:TEXT, s.matched.sub(/\r$/, ''), *token_pos(pos)]
|
||||
# --- (at least 3) and nothing else on the line => :RULE
|
||||
when s.scan(/(-{3,}) *$/) then
|
||||
[:RULE, s[1].length - 2, *token_pos(pos)]
|
||||
when s.scan(/([*-])\s+/) then
|
||||
@tokens << [:BULLET, :BULLET, *token_pos(pos)]
|
||||
[:SPACE, s.matched_size, *token_pos(pos)]
|
||||
when s.scan(/([a-z]|\d+)\.[ \t]+\S/i) then
|
||||
# * or - followed by white space and text => :BULLET
|
||||
when s.scan(/([*-]) +(\S)/) then
|
||||
s.pos -= s[2].bytesize # unget \S
|
||||
[:BULLET, s[1], *token_pos(pos)]
|
||||
# A. text, a. text, 12. text => :UALPHA, :LALPHA, :NUMBER
|
||||
when s.scan(/([a-z]|\d+)\. +(\S)/i) then
|
||||
# FIXME if tab(s), the column will be wrong
|
||||
# either support tabs everywhere by first expanding them to
|
||||
# spaces, or assume that they will have been replaced
|
||||
# before (and provide a check for that at least in debug
|
||||
# mode)
|
||||
list_label = s[1]
|
||||
width = s.matched_size - 1
|
||||
|
||||
s.pos -= 1 # unget \S
|
||||
|
||||
list_type = case list_label
|
||||
when /[a-z]/ then :LALPHA
|
||||
when /[A-Z]/ then :UALPHA
|
||||
when /\d/ then :NUMBER
|
||||
else
|
||||
raise ParseError, "BUG token #{list_label}"
|
||||
end
|
||||
|
||||
@tokens << [list_type, list_label, *token_pos(pos)]
|
||||
[:SPACE, width, *token_pos(pos)]
|
||||
s.pos -= s[2].bytesize # unget \S
|
||||
list_type =
|
||||
case list_label
|
||||
when /[a-z]/ then :LALPHA
|
||||
when /[A-Z]/ then :UALPHA
|
||||
when /\d/ then :NUMBER
|
||||
else
|
||||
raise ParseError, "BUG token #{list_label}"
|
||||
end
|
||||
[list_type, list_label, *token_pos(pos)]
|
||||
# [text] followed by spaces or end of line => :LABEL
|
||||
when s.scan(/\[(.*?)\]( +|$)/) then
|
||||
@tokens << [:LABEL, s[1], *token_pos(pos)]
|
||||
[:SPACE, s.matched_size, *token_pos(pos)]
|
||||
[:LABEL, s[1], *token_pos(pos)]
|
||||
# text:: followed by spaces or end of line => :NOTE
|
||||
when s.scan(/(.*?)::( +|$)/) then
|
||||
@tokens << [:NOTE, s[1], *token_pos(pos)]
|
||||
[:SPACE, s.matched_size, *token_pos(pos)]
|
||||
[:NOTE, s[1], *token_pos(pos)]
|
||||
# anything else: :TEXT
|
||||
else s.scan(/.*/)
|
||||
[:TEXT, s.matched, *token_pos(pos)]
|
||||
[:TEXT, s.matched.sub(/\r$/, ''), *token_pos(pos)]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -507,9 +453,17 @@ class RDoc::Markup::Parser
|
|||
end
|
||||
|
||||
##
|
||||
# Returns the current token or +token+ to the token stream
|
||||
# Calculates the column and line of the current token based on +offset+.
|
||||
|
||||
def unget token = @current_token
|
||||
def token_pos offset
|
||||
[offset - @line_pos, @line]
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the current token to the token stream
|
||||
|
||||
def unget
|
||||
token = @current_token
|
||||
p :unget => token if @debug
|
||||
raise Error, 'too many #ungets' if token == @tokens.first
|
||||
@tokens.unshift token if token
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
require 'rdoc/markup'
|
||||
require 'rdoc/encoding'
|
||||
|
||||
##
|
||||
# Handle common directives that can occur in a block of text:
|
||||
#
|
||||
# : include : filename
|
||||
# \:include: filename
|
||||
#
|
||||
# RDoc plugin authors can register additional directives to be handled through
|
||||
# RDoc::Markup::PreProcess::register
|
||||
# Directives can be escaped by preceding them with a backslash.
|
||||
#
|
||||
# RDoc plugin authors can register additional directives to be handled by
|
||||
# using RDoc::Markup::PreProcess::register
|
||||
|
||||
class RDoc::Markup::PreProcess
|
||||
|
||||
|
@ -52,18 +55,25 @@ class RDoc::Markup::PreProcess
|
|||
# +code_object+. See RDoc::CodeObject#metadata
|
||||
|
||||
def handle text, code_object = nil
|
||||
text.gsub!(/^([ \t]*#?[ \t]*):(\w+):([ \t]*)(.+)?\n/) do
|
||||
next $& if $3.empty? and $4 and $4[0, 1] == ':'
|
||||
# regexp helper (square brackets for optional)
|
||||
# $1 $2 $3 $4 $5
|
||||
# [prefix][\]:directive:[spaces][param]newline
|
||||
text.gsub!(/^([ \t]*#?[ \t]*)(\\?):(\w+):([ \t]*)(.+)?\n/) do
|
||||
# skip something like ':toto::'
|
||||
next $& if $4.empty? and $5 and $5[0, 1] == ':'
|
||||
|
||||
# skip if escaped
|
||||
next "#$1:#$3:#$4#$5\n" unless $2.empty?
|
||||
|
||||
prefix = $1
|
||||
directive = $2.downcase
|
||||
param = $4
|
||||
directive = $3.downcase
|
||||
param = $5
|
||||
|
||||
case directive
|
||||
when 'include' then
|
||||
filename = param.split[0]
|
||||
include_file filename, prefix
|
||||
|
||||
encoding = if defined?(Encoding) then text.encoding else nil end
|
||||
include_file filename, prefix, encoding
|
||||
else
|
||||
result = yield directive, param if block_given?
|
||||
|
||||
|
@ -88,27 +98,38 @@ class RDoc::Markup::PreProcess
|
|||
end
|
||||
|
||||
##
|
||||
# Include a file, indenting it correctly.
|
||||
# Handles the <tt>:include: _filename_</tt> directive.
|
||||
#
|
||||
# If the first line of the included file starts with '#', and contains
|
||||
# an encoding information in the form 'coding:' or 'coding=', it is
|
||||
# removed.
|
||||
#
|
||||
# If all lines in the included file start with a '#', this leading '#'
|
||||
# is removed before inclusion. The included content is indented like
|
||||
# the <tt>:include:</tt> directive.
|
||||
#--
|
||||
# so all content will be verbatim because of the likely space after '#'?
|
||||
# TODO shift left the whole file content in that case
|
||||
# TODO comment stop/start #-- and #++ in included file must be processed here
|
||||
|
||||
def include_file(name, indent)
|
||||
if full_name = find_include_file(name) then
|
||||
content = if defined?(Encoding) then
|
||||
File.binread full_name
|
||||
else
|
||||
File.read full_name
|
||||
end
|
||||
# HACK determine content type and force encoding
|
||||
content = content.sub(/\A# .*coding[=:].*$/, '').lstrip
|
||||
def include_file name, indent, encoding
|
||||
full_name = find_include_file name
|
||||
|
||||
# strip leading '#'s, but only if all lines start with them
|
||||
if content =~ /^[^#]/ then
|
||||
content.gsub(/^/, indent)
|
||||
else
|
||||
content.gsub(/^#?/, indent)
|
||||
end
|
||||
else
|
||||
unless full_name then
|
||||
warn "Couldn't find file to include '#{name}' from #{@input_file_name}"
|
||||
''
|
||||
return ''
|
||||
end
|
||||
|
||||
content = RDoc::Encoding.read_file full_name, encoding
|
||||
|
||||
# strip magic comment
|
||||
content = content.sub(/\A# .*coding[=:].*$/, '').lstrip
|
||||
|
||||
# strip leading '#'s, but only if all lines start with them
|
||||
if content =~ /^[^#]/ then
|
||||
content.gsub(/^/, indent)
|
||||
else
|
||||
content.gsub(/^#?/, indent)
|
||||
end
|
||||
end
|
||||
|
|
@ -27,6 +27,9 @@ class RDoc::Markup::Raw
|
|||
self.class == other.class and text == other.text
|
||||
end
|
||||
|
||||
##
|
||||
# Calls #accept_raw+ on +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_raw self
|
||||
end
|
||||
|
@ -63,3 +66,4 @@ class RDoc::Markup::Raw
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
class RDoc::Markup::Rule < Struct.new :weight
|
||||
|
||||
##
|
||||
# Calls #accept_rule on +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_rule self
|
||||
end
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
require 'rdoc/markup/formatter_test_case'
|
||||
|
||||
##
|
||||
# Test case for creating new plain-text RDoc::Markup formatters. See also
|
||||
# RDoc::Markup::FormatterTestCase
|
||||
#
|
||||
# See test_rdoc_markup_to_rdoc.rb for a complete example.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# class TestRDocMarkupToNewTextFormat < RDoc::Markup::TextFormatterTestCase
|
||||
#
|
||||
# add_visitor_tests
|
||||
# add_text_tests
|
||||
#
|
||||
# def setup
|
||||
# super
|
||||
#
|
||||
# @to = RDoc::Markup::ToNewTextFormat.new
|
||||
# end
|
||||
#
|
||||
# def accept_blank_line
|
||||
# assert_equal :junk, @to.res.join
|
||||
# end
|
||||
#
|
||||
# # ...
|
||||
#
|
||||
# end
|
||||
|
||||
class RDoc::Markup::TextFormatterTestCase < RDoc::Markup::FormatterTestCase
|
||||
|
||||
##
|
||||
# Adds test cases to the calling TestCase.
|
||||
|
||||
def self.add_text_tests
|
||||
self.class_eval do
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_heading</tt>
|
||||
|
||||
def test_accept_heading_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
accept_heading_indent
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_rule</tt>
|
||||
|
||||
def test_accept_rule_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_rule @RM::Rule.new(1)
|
||||
|
||||
accept_rule_indent
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_verbatim</tt>
|
||||
|
||||
def test_accept_verbatim_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 2
|
||||
@to.accept_verbatim @RM::Verbatim.new("hi\n", " world\n")
|
||||
|
||||
accept_verbatim_indent
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_verbatim</tt> with a big indent
|
||||
|
||||
def test_accept_verbatim_big_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 2
|
||||
@to.accept_verbatim @RM::Verbatim.new("hi\n", "world\n")
|
||||
|
||||
accept_verbatim_big_indent
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_paragraph</tt> with an indent
|
||||
|
||||
def test_accept_paragraph_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_paragraph @RM::Paragraph.new(('words ' * 30).strip)
|
||||
|
||||
accept_paragraph_indent
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.accept_paragraph</tt> with a long line
|
||||
|
||||
def test_accept_paragraph_wrap
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new(('words ' * 30).strip)
|
||||
|
||||
accept_paragraph_wrap
|
||||
end
|
||||
|
||||
##
|
||||
# Test case that calls <tt>@to.attributes</tt> with an escaped
|
||||
# cross-reference. If this test doesn't pass something may be very
|
||||
# wrong.
|
||||
|
||||
def test_attributes
|
||||
assert_equal 'Dog', @to.attributes("\\Dog")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
require 'rdoc/markup/inline'
|
||||
require 'rdoc/markup/to_rdoc'
|
||||
|
||||
##
|
||||
# Outputs RDoc markup with vibrant ANSI color!
|
||||
|
||||
class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
|
||||
|
||||
##
|
||||
# Creates a new ToAnsi visitor that is ready to output vibrant ANSI color!
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
||||
|
@ -23,12 +26,15 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
|
|||
add_tag :EM, "\e[4m", "\e[m"
|
||||
end
|
||||
|
||||
##
|
||||
# Overrides indent width to ensure output lines up correctly.
|
||||
|
||||
def accept_list_item_end list_item
|
||||
width = case @list_type.last
|
||||
when :BULLET then
|
||||
2
|
||||
when :NOTE, :LABEL then
|
||||
@res << "\n"
|
||||
@res << "\n" unless res.length == 1
|
||||
2
|
||||
else
|
||||
bullet = @list_index.last.to_s
|
||||
|
@ -39,6 +45,9 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
|
|||
@indent -= width
|
||||
end
|
||||
|
||||
##
|
||||
# Adds coloring to note and label list items
|
||||
|
||||
def accept_list_item_start list_item
|
||||
bullet = case @list_type.last
|
||||
when :BULLET then
|
||||
|
@ -62,6 +71,9 @@ class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Starts accepting with a reset screen
|
||||
|
||||
def start_accepting
|
||||
super
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'rdoc/markup/inline'
|
||||
require 'rdoc/markup/to_rdoc'
|
||||
|
||||
##
|
||||
# Outputs RDoc markup with hot backspace action! You will probably need a
|
||||
|
@ -8,6 +8,9 @@ require 'rdoc/markup/inline'
|
|||
|
||||
class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
|
||||
|
||||
##
|
||||
# Returns a new ToBs that is ready for hot backspace action!
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
||||
|
@ -22,8 +25,12 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
|
|||
def init_tags
|
||||
add_tag :BOLD, '+b', '-b'
|
||||
add_tag :EM, '+_', '-_'
|
||||
add_tag :TT, '' , '' # we need in_tt information maintained
|
||||
end
|
||||
|
||||
##
|
||||
# Makes heading text bold.
|
||||
|
||||
def accept_heading heading
|
||||
use_prefix or @res << ' ' * @indent
|
||||
@res << @headings[heading.level][0]
|
||||
|
@ -44,7 +51,6 @@ class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc
|
|||
when '+_' then @in_em = true
|
||||
when '-_' then @in_em = false
|
||||
end
|
||||
|
||||
''
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ require 'cgi'
|
|||
|
||||
class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
||||
|
||||
include RDoc::Text
|
||||
|
||||
##
|
||||
# Maps RDoc::Markup::Parser::LIST_TOKENS types to HTML tags
|
||||
|
||||
|
@ -15,7 +17,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
:BULLET => ['<ul>', '</ul>'],
|
||||
:LABEL => ['<dl>', '</dl>'],
|
||||
:LALPHA => ['<ol style="display: lower-alpha">', '</ol>'],
|
||||
:NOTE => ['<table>', '</table>'],
|
||||
:NOTE => ['<table class="rdoc-list">', '</table>'],
|
||||
:NUMBER => ['<ol>', '</ol>'],
|
||||
:UALPHA => ['<ol style="display: upper-alpha">', '</ol>'],
|
||||
}
|
||||
|
@ -48,6 +50,9 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
File.join(*from)
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a new formatter that will output HTML
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
||||
|
@ -103,13 +108,15 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
end
|
||||
end
|
||||
|
||||
# :section: Special handling
|
||||
|
||||
##
|
||||
# And we're invoked with a potential external hyperlink mailto:
|
||||
# just gets inserted. http: links are checked to see if they
|
||||
# And we're invoked with a potential external hyperlink. <tt>mailto:</tt>
|
||||
# just gets inserted. <tt>http:</tt> links are checked to see if they
|
||||
# reference an image. If so, that image gets inserted using an
|
||||
# <img> tag. Otherwise a conventional <a href> is used. We also
|
||||
# support a special type of hyperlink, link:, which is a reference
|
||||
# to a local file whose path is relative to the --op directory.
|
||||
# <tt><img></tt> tag. Otherwise a conventional <tt><a href></tt> is used.
|
||||
# We also support a special type of hyperlink, <tt>link:</tt>, which is a
|
||||
# reference to a local file whose path is relative to the --op directory.
|
||||
|
||||
def handle_special_HYPERLINK(special)
|
||||
url = special.text
|
||||
|
@ -118,7 +125,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
|
||||
##
|
||||
# Here's a hypedlink where the label is different to the URL
|
||||
# <label>[url] or {long label}[url]
|
||||
# <label>[url] or {long label}[url]
|
||||
|
||||
def handle_special_TIDYLINK(special)
|
||||
text = special.text
|
||||
|
@ -130,8 +137,10 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
gen_url url, label
|
||||
end
|
||||
|
||||
# :section: Utilities
|
||||
|
||||
##
|
||||
# This is a higher speed (if messier) version of wrap
|
||||
# Wraps +txt+ to +line_len+
|
||||
|
||||
def wrap(txt, line_len = 76)
|
||||
res = []
|
||||
|
@ -159,173 +168,150 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
sp += 1 while sp < ep and txt[sp] == ?\s
|
||||
end
|
||||
|
||||
res.join
|
||||
res.join.strip
|
||||
end
|
||||
|
||||
##
|
||||
# :section: Visitor
|
||||
|
||||
##
|
||||
# Prepares the visitor for HTML generation
|
||||
|
||||
def start_accepting
|
||||
@res = []
|
||||
@in_list_entry = []
|
||||
@list = []
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the generated output
|
||||
|
||||
def end_accepting
|
||||
@res.join
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +paragraph+ to the output
|
||||
|
||||
def accept_paragraph(paragraph)
|
||||
@res << annotate("<p>") + "\n"
|
||||
@res << wrap(convert_flow(@am.flow(paragraph.text)))
|
||||
@res << annotate("</p>") + "\n"
|
||||
@res << "\n<p>"
|
||||
@res << wrap(to_html(paragraph.text))
|
||||
@res << "</p>\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +verbatim+ to the output
|
||||
|
||||
def accept_verbatim(verbatim)
|
||||
@res << annotate("<pre>") << "\n"
|
||||
@res << CGI.escapeHTML(verbatim.text)
|
||||
@res << annotate("</pre>") << "\n"
|
||||
@res << "\n<pre>"
|
||||
@res << CGI.escapeHTML(verbatim.text.rstrip)
|
||||
@res << "</pre>\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +rule+ to the output
|
||||
|
||||
def accept_rule(rule)
|
||||
size = rule.weight
|
||||
size = 10 if size > 10
|
||||
@res << "<hr style=\"height: #{size}px\"></hr>"
|
||||
@res << "<hr style=\"height: #{size}px\">\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the visitor for consuming +list+
|
||||
|
||||
def accept_list_start(list)
|
||||
@list << list.type
|
||||
@res << html_list_name(list.type, true) << "\n"
|
||||
@res << html_list_name(list.type, true)
|
||||
@in_list_entry.push false
|
||||
end
|
||||
|
||||
##
|
||||
# Finishes consumption of +list+
|
||||
|
||||
def accept_list_end(list)
|
||||
@list.pop
|
||||
if tag = @in_list_entry.pop
|
||||
@res << annotate(tag) << "\n"
|
||||
@res << tag
|
||||
end
|
||||
@res << html_list_name(list.type, false) << "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the visitor for consuming +list_item+
|
||||
|
||||
def accept_list_item_start(list_item)
|
||||
if tag = @in_list_entry.last
|
||||
@res << annotate(tag) << "\n"
|
||||
@res << tag
|
||||
end
|
||||
|
||||
@res << list_item_start(list_item, @list.last)
|
||||
end
|
||||
|
||||
##
|
||||
# Finishes consumption of +list_item+
|
||||
|
||||
def accept_list_item_end(list_item)
|
||||
@in_list_entry[-1] = list_end_for(@list.last)
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +blank_line+ to the output
|
||||
|
||||
def accept_blank_line(blank_line)
|
||||
# @res << annotate("<p />") << "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +heading+ to the output
|
||||
|
||||
def accept_heading(heading)
|
||||
@res << convert_heading(heading.level, @am.flow(heading.text))
|
||||
@res << "\n<h#{heading.level}>"
|
||||
@res << to_html(heading.text)
|
||||
@res << "</h#{heading.level}>\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +raw+ to the output
|
||||
|
||||
def accept_raw raw
|
||||
@res << raw.parts.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Converts string +item+
|
||||
# CGI escapes +text+
|
||||
|
||||
def convert_string(item)
|
||||
in_tt? ? convert_string_simple(item) : convert_string_fancy(item)
|
||||
def convert_string(text)
|
||||
CGI.escapeHTML text
|
||||
end
|
||||
|
||||
##
|
||||
# Escapes HTML in +item+
|
||||
|
||||
def convert_string_simple(item)
|
||||
CGI.escapeHTML item
|
||||
end
|
||||
|
||||
##
|
||||
# Converts ampersand, dashes, elipsis, quotes, copyright and registered
|
||||
# trademark symbols to HTML escaped Unicode.
|
||||
|
||||
def convert_string_fancy(item)
|
||||
# convert ampersand before doing anything else
|
||||
item.gsub(/&/, '&').
|
||||
|
||||
# convert -- to em-dash, (-- to en-dash)
|
||||
gsub(/---?/, '—'). #gsub(/--/, '–').
|
||||
|
||||
# convert ... to elipsis (and make sure .... becomes .<elipsis>)
|
||||
gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…').
|
||||
|
||||
# convert single closing quote
|
||||
gsub(%r{([^ \t\r\n\[\{\(])\'}, '\1’'). # }
|
||||
gsub(%r{\'(?=\W|s\b)}, '’').
|
||||
|
||||
# convert single opening quote
|
||||
gsub(/'/, '‘').
|
||||
|
||||
# convert double closing quote
|
||||
gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}, '\1”'). # }
|
||||
|
||||
# convert double opening quote
|
||||
gsub(/"/, '“').
|
||||
|
||||
# convert copyright
|
||||
gsub(/\(c\)/, '©').
|
||||
|
||||
# convert registered trademark
|
||||
gsub(/\(r\)/, '®')
|
||||
end
|
||||
|
||||
##
|
||||
# Converts headings to hN elements
|
||||
|
||||
def convert_heading(level, flow)
|
||||
[annotate("<h#{level}>"),
|
||||
convert_flow(flow),
|
||||
annotate("</h#{level}>\n")].join
|
||||
end
|
||||
|
||||
##
|
||||
# Determins the HTML list element for +list_type+ and +open_tag+
|
||||
# Determines the HTML list element for +list_type+ and +open_tag+
|
||||
|
||||
def html_list_name(list_type, open_tag)
|
||||
tags = LIST_TYPE_TO_HTML[list_type]
|
||||
raise RDoc::Error, "Invalid list type: #{list_type.inspect}" unless tags
|
||||
annotate tags[open_tag ? 0 : 1]
|
||||
tags[open_tag ? 0 : 1]
|
||||
end
|
||||
|
||||
##
|
||||
# Starts a list item
|
||||
# Returns the HTML tag for +list_type+, possible using a label from
|
||||
# +list_item+
|
||||
|
||||
def list_item_start(list_item, list_type)
|
||||
case list_type
|
||||
when :BULLET, :LALPHA, :NUMBER, :UALPHA then
|
||||
annotate("<li>")
|
||||
|
||||
"<li>"
|
||||
when :LABEL then
|
||||
annotate("<dt>") +
|
||||
convert_flow(@am.flow(list_item.label)) +
|
||||
annotate("</dt>") +
|
||||
annotate("<dd>")
|
||||
|
||||
"<dt>#{to_html list_item.label}</dt>\n<dd>"
|
||||
when :NOTE then
|
||||
annotate("<tr>") +
|
||||
annotate("<td valign=\"top\">") +
|
||||
convert_flow(@am.flow(list_item.label)) +
|
||||
annotate("</td>") +
|
||||
annotate("<td>")
|
||||
"<tr><td class=\"rdoc-term\"><p>#{to_html list_item.label}</p></td>\n<td>"
|
||||
else
|
||||
raise RDoc::Error, "Invalid list type: #{list_type.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Ends a list item
|
||||
# Returns the HTML end-tag for +list_type+
|
||||
|
||||
def list_end_for(list_type)
|
||||
case list_type
|
||||
|
@ -340,5 +326,12 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Converts +item+ to HTML using RDoc::Text#to_html
|
||||
|
||||
def to_html item
|
||||
super convert_flow @am.flow item
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
##
|
||||
# Regular expression to match class references
|
||||
#
|
||||
# 1) There can be a '\' in front of text to suppress any cross-references
|
||||
# 2) There can be a '::' in front of class names to reference from the
|
||||
# 1. There can be a '\\' in front of text to suppress the cross-reference
|
||||
# 2. There can be a '::' in front of class names to reference from the
|
||||
# top-level namespace.
|
||||
# 3) The method can be followed by parenthesis
|
||||
# 3. The method can be followed by parenthesis (not recommended)
|
||||
|
||||
CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)'
|
||||
|
||||
|
@ -34,10 +34,10 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
# A::B::C.meth
|
||||
#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
|
||||
|
||||
# Stand-alone method (proceeded by a #)
|
||||
# Stand-alone method (preceeded by a #)
|
||||
| \\?\##{METHOD_REGEXP_STR}
|
||||
|
||||
# Stand-alone method (proceeded by ::)
|
||||
# Stand-alone method (preceeded by ::)
|
||||
| ::#{METHOD_REGEXP_STR}
|
||||
|
||||
# A::B::C
|
||||
|
@ -51,9 +51,10 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
# In order that words like "can't" not
|
||||
# be flagged as potential cross-references, only
|
||||
# flag potential class cross-references if the character
|
||||
# after the cross-referece is a space or sentence
|
||||
# punctuation.
|
||||
| #{CLASS_REGEXP_STR}(?=[\s\)\.\?\!\,\;]|\z)
|
||||
# after the cross-referece is a space, sentence
|
||||
# punctuation, tag start character, or attribute
|
||||
# marker.
|
||||
| #{CLASS_REGEXP_STR}(?=[\s\)\.\?\!\,\;<\000]|\z)
|
||||
|
||||
# Things that look like filenames
|
||||
# The key thing is that there must be at least
|
||||
|
@ -62,7 +63,29 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
| (?:\.\.\/)*[-\/\w]+[_\/\.][-\w\/\.]+
|
||||
|
||||
# Things that have markup suppressed
|
||||
| \\[^\s]
|
||||
# Don't process things like '\<' in \<tt>, though.
|
||||
# TODO: including < is a hack, not very satisfying.
|
||||
| \\[^\s<]
|
||||
)/x
|
||||
|
||||
##
|
||||
# Version of CROSSREF_REGEXP used when <tt>--hyperlink-all</tt> is specified.
|
||||
|
||||
ALL_CROSSREF_REGEXP = /(
|
||||
# A::B::C.meth
|
||||
#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
|
||||
|
||||
# Stand-alone method
|
||||
| \\?#{METHOD_REGEXP_STR}
|
||||
|
||||
# A::B::C
|
||||
| #{CLASS_REGEXP_STR}(?=[\s\)\.\?\!\,\;<\000]|\z)
|
||||
|
||||
# Things that look like filenames
|
||||
| (?:\.\.\/)*[-\/\w]+[_\/\.][-\w\/\.]+
|
||||
|
||||
# Things that have markup suppressed
|
||||
| \\[^\s<]
|
||||
)/x
|
||||
|
||||
##
|
||||
|
@ -70,20 +93,29 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
|
||||
attr_accessor :context
|
||||
|
||||
##
|
||||
# Should we show '#' characters on method references?
|
||||
|
||||
attr_accessor :show_hash
|
||||
|
||||
##
|
||||
# Creates a new crossref resolver that generates links relative to +context+
|
||||
# which lives at +from_path+ in the generated files. '#' characters on
|
||||
# references are removed unless +show_hash+ is true.
|
||||
# references are removed unless +show_hash+ is true. Only method names
|
||||
# preceded by '#' or '::' are hyperlinked, unless +hyperlink_all+ is true.
|
||||
|
||||
def initialize(from_path, context, show_hash)
|
||||
def initialize(from_path, context, show_hash, hyperlink_all = false)
|
||||
raise ArgumentError, 'from_path cannot be nil' if from_path.nil?
|
||||
super()
|
||||
|
||||
@markup.add_special(CROSSREF_REGEXP, :CROSSREF)
|
||||
crossref_re = hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
||||
|
||||
@markup.add_special crossref_re, :CROSSREF
|
||||
|
||||
@from_path = from_path
|
||||
@context = context
|
||||
@show_hash = show_hash
|
||||
@hyperlink_all = hyperlink_all
|
||||
|
||||
@seen = {}
|
||||
end
|
||||
|
@ -92,22 +124,24 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
# We're invoked when any text matches the CROSSREF pattern. If we find the
|
||||
# corresponding reference, generate a hyperlink. If the name we're looking
|
||||
# for contains no punctuation, we look for it up the module/class chain.
|
||||
# For example, HyperlinkHtml is found, even without the Generator:: prefix,
|
||||
# because we look for it in module Generator first.
|
||||
# For example, ToHtml is found, even without the <tt>RDoc::Markup::</tt>
|
||||
# prefix, because we look for it in module Markup first.
|
||||
|
||||
def handle_special_CROSSREF(special)
|
||||
name = special.text
|
||||
|
||||
# This ensures that words entirely consisting of lowercase letters will
|
||||
# not have cross-references generated (to suppress lots of erroneous
|
||||
# cross-references to "new" in text, for instance)
|
||||
return name if name =~ /\A[a-z]*\z/
|
||||
unless @hyperlink_all then
|
||||
# This ensures that words entirely consisting of lowercase letters will
|
||||
# not have cross-references generated (to suppress lots of erroneous
|
||||
# cross-references to "new" in text, for instance)
|
||||
return name if name =~ /\A[a-z]*\z/
|
||||
end
|
||||
|
||||
return @seen[name] if @seen.include? name
|
||||
|
||||
lookup = name
|
||||
|
||||
name = name[0, 1] unless @show_hash if name[0, 1] == '#'
|
||||
name = name[1..-1] unless @show_hash if name[0, 1] == '#'
|
||||
|
||||
# Find class, module, or method in class or module.
|
||||
#
|
||||
|
@ -120,26 +154,47 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
# whether the string as a whole is a known symbol).
|
||||
|
||||
if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/ =~ lookup then
|
||||
container = $1
|
||||
type = $2
|
||||
type = '#' if type == '.'
|
||||
type = '' if type == '.' # will find either #method or ::method
|
||||
method = "#{type}#{$3}"
|
||||
ref = @context.find_symbol container, method
|
||||
container = @context.find_symbol_module($1)
|
||||
elsif /^([.#]|::)#{METHOD_REGEXP_STR}/ =~ lookup then
|
||||
type = $1
|
||||
type = '' if type == '.'
|
||||
method = "#{type}#{$2}"
|
||||
container = @context
|
||||
else
|
||||
container = nil
|
||||
end
|
||||
|
||||
if container then
|
||||
ref = container.find_local_symbol method
|
||||
|
||||
unless ref || RDoc::TopLevel === container then
|
||||
ref = container.find_ancestor_local_symbol method
|
||||
end
|
||||
end
|
||||
|
||||
ref = @context.find_symbol lookup unless ref
|
||||
ref = nil if RDoc::Alias === ref # external alias: can't link to it
|
||||
|
||||
out = if lookup == '\\' then
|
||||
lookup
|
||||
elsif lookup =~ /^\\/ then
|
||||
$'
|
||||
elsif ref and ref.document_self then
|
||||
"<a href=\"#{ref.as_href @from_path}\">#{name}</a>"
|
||||
# we remove the \ only in front of what we know:
|
||||
# other backslashes are treated later, only outside of <tt>
|
||||
ref ? $' : lookup
|
||||
elsif ref then
|
||||
if ref.document_self then
|
||||
"<a href=\"#{ref.as_href @from_path}\">#{name}</a>"
|
||||
else
|
||||
name
|
||||
end
|
||||
else
|
||||
name
|
||||
lookup
|
||||
end
|
||||
|
||||
@seen[name] = out
|
||||
@seen[lookup] = out
|
||||
|
||||
out
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'rdoc/markup/formatter'
|
||||
require 'rdoc/markup/inline'
|
||||
|
||||
##
|
||||
|
@ -5,21 +6,49 @@ require 'rdoc/markup/inline'
|
|||
|
||||
class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
||||
|
||||
##
|
||||
# Current indent amount for output in characters
|
||||
|
||||
attr_accessor :indent
|
||||
|
||||
##
|
||||
# Output width in characters
|
||||
|
||||
attr_accessor :width
|
||||
|
||||
##
|
||||
# Stack of current list indexes for alphabetic and numeric lists
|
||||
|
||||
attr_reader :list_index
|
||||
|
||||
##
|
||||
# Stack of list types
|
||||
|
||||
attr_reader :list_type
|
||||
|
||||
##
|
||||
# Stack of list widths for indentation
|
||||
|
||||
attr_reader :list_width
|
||||
|
||||
##
|
||||
# Prefix for the next list item. See #use_prefix
|
||||
|
||||
attr_reader :prefix
|
||||
|
||||
##
|
||||
# Output accumulator
|
||||
|
||||
attr_reader :res
|
||||
|
||||
##
|
||||
# Creates a new formatter that will output (mostly) \RDoc markup
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
||||
@markup.add_special(/\\[^\s]/, :SUPPRESSED_CROSSREF)
|
||||
|
||||
@markup.add_special(/\\\S/, :SUPPRESSED_CROSSREF)
|
||||
@width = 78
|
||||
@prefix = ''
|
||||
|
||||
init_tags
|
||||
|
||||
@headings = {}
|
||||
|
@ -34,7 +63,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
end
|
||||
|
||||
##
|
||||
# Maps attributes to ANSI sequences
|
||||
# Maps attributes to HTML sequences
|
||||
|
||||
def init_tags
|
||||
add_tag :BOLD, "<b>", "</b>"
|
||||
|
@ -42,10 +71,16 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
add_tag :EM, "<em>", "</em>"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +blank_line+ to the output
|
||||
|
||||
def accept_blank_line blank_line
|
||||
@res << "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +heading+ to the output
|
||||
|
||||
def accept_heading heading
|
||||
use_prefix or @res << ' ' * @indent
|
||||
@res << @headings[heading.level][0]
|
||||
|
@ -54,12 +89,18 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
@res << "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Finishes consumption of +list+
|
||||
|
||||
def accept_list_end list
|
||||
@list_index.pop
|
||||
@list_type.pop
|
||||
@list_width.pop
|
||||
end
|
||||
|
||||
##
|
||||
# Finishes consumption of +list_item+
|
||||
|
||||
def accept_list_item_end list_item
|
||||
width = case @list_type.last
|
||||
when :BULLET then
|
||||
|
@ -76,29 +117,29 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
@indent -= width
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the visitor for consuming +list_item+
|
||||
|
||||
def accept_list_item_start list_item
|
||||
bullet = case @list_type.last
|
||||
when :BULLET then
|
||||
'*'
|
||||
when :NOTE, :LABEL then
|
||||
attributes(list_item.label) + ":\n"
|
||||
else
|
||||
@list_index.last.to_s + '.'
|
||||
end
|
||||
type = @list_type.last
|
||||
|
||||
case @list_type.last
|
||||
case type
|
||||
when :NOTE, :LABEL then
|
||||
bullet = attributes(list_item.label) + ":\n"
|
||||
@prefix = ' ' * @indent
|
||||
@indent += 2
|
||||
@prefix = bullet + (' ' * @indent)
|
||||
@prefix << bullet + (' ' * @indent)
|
||||
else
|
||||
bullet = type == :BULLET ? '*' : @list_index.last.to_s + '.'
|
||||
@prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1)
|
||||
|
||||
width = bullet.length + 1
|
||||
|
||||
@indent += width
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the visitor for consuming +list+
|
||||
|
||||
def accept_list_start list
|
||||
case list.type
|
||||
when :BULLET then
|
||||
|
@ -123,14 +164,23 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
@list_type << list.type
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +paragraph+ to the output
|
||||
|
||||
def accept_paragraph paragraph
|
||||
wrap attributes(paragraph.text)
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +raw+ to the output
|
||||
|
||||
def accept_raw raw
|
||||
@res << raw.parts.join("\n")
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +rule+ to the output
|
||||
|
||||
def accept_rule rule
|
||||
use_prefix or @res << ' ' * @indent
|
||||
@res << '-' * (@width - @indent)
|
||||
|
@ -138,58 +188,46 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
end
|
||||
|
||||
##
|
||||
# Outputs +verbatim+ flush left and indented 2 columns
|
||||
# Outputs +verbatim+ indented 2 columns
|
||||
|
||||
def accept_verbatim verbatim
|
||||
indent = ' ' * (@indent + 2)
|
||||
|
||||
lines = []
|
||||
current_line = []
|
||||
|
||||
# split into lines
|
||||
verbatim.parts.each do |part|
|
||||
current_line << part
|
||||
|
||||
if part == "\n" then
|
||||
lines << current_line
|
||||
current_line = []
|
||||
end
|
||||
@res << indent unless part == "\n"
|
||||
@res << part
|
||||
end
|
||||
|
||||
lines << current_line unless current_line.empty?
|
||||
|
||||
# calculate margin
|
||||
indented = lines.select { |line| line != ["\n"] }
|
||||
margin = indented.map { |line| line.first.length }.min
|
||||
|
||||
# flush left
|
||||
indented.each { |line| line[0][0...margin] = '' }
|
||||
|
||||
# output
|
||||
use_prefix or @res << indent # verbatim is unlikely to have prefix
|
||||
@res << lines.shift.join
|
||||
|
||||
lines.each do |line|
|
||||
@res << indent unless line == ["\n"]
|
||||
@res << line.join
|
||||
end
|
||||
|
||||
@res << "\n"
|
||||
@res << "\n" unless @res =~ /\n\z/
|
||||
end
|
||||
|
||||
##
|
||||
# Applies attribute-specific markup to +text+ using RDoc::AttributeManager
|
||||
|
||||
def attributes text
|
||||
flow = @am.flow text.dup
|
||||
convert_flow flow
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the generated output
|
||||
|
||||
def end_accepting
|
||||
@res.join
|
||||
end
|
||||
|
||||
##
|
||||
# Removes preceeding \\ from the suppressed crossref +special+
|
||||
|
||||
def handle_special_SUPPRESSED_CROSSREF special
|
||||
special.text.sub(/\\/, '')
|
||||
text = special.text
|
||||
text = text.sub('\\', '') unless in_tt?
|
||||
text
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the visitor for text generation
|
||||
|
||||
def start_accepting
|
||||
@res = [""]
|
||||
@indent = 0
|
||||
|
@ -200,6 +238,10 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
@list_width = []
|
||||
end
|
||||
|
||||
##
|
||||
# Adds the stored #prefix to the output and clears it. Lists generate a
|
||||
# prefix for later consumption.
|
||||
|
||||
def use_prefix
|
||||
prefix = @prefix
|
||||
@prefix = nil
|
||||
|
@ -208,6 +250,9 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter
|
|||
prefix
|
||||
end
|
||||
|
||||
##
|
||||
# Wraps +text+ to #width
|
||||
|
||||
def wrap text
|
||||
return unless text && !text.empty?
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ require 'rdoc/markup/formatter'
|
|||
|
||||
class RDoc::Markup::ToTest < RDoc::Markup::Formatter
|
||||
|
||||
# :stopdoc:
|
||||
|
||||
##
|
||||
# :section: Visitor
|
||||
|
||||
|
@ -22,8 +24,12 @@ class RDoc::Markup::ToTest < RDoc::Markup::Formatter
|
|||
@res << paragraph.text
|
||||
end
|
||||
|
||||
def accept_raw raw
|
||||
@res << raw.parts.join
|
||||
end
|
||||
|
||||
def accept_verbatim(verbatim)
|
||||
@res << verbatim.text
|
||||
@res << verbatim.text.gsub(/^(\S)/, ' \1')
|
||||
end
|
||||
|
||||
def accept_list_start(list)
|
||||
|
@ -60,5 +66,7 @@ class RDoc::Markup::ToTest < RDoc::Markup::Formatter
|
|||
@res << '-' * rule.weight
|
||||
end
|
||||
|
||||
# :startdoc:
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
class RDoc::Markup::Verbatim < RDoc::Markup::Raw
|
||||
|
||||
##
|
||||
# Calls #accept_verbatim on +visitor+
|
||||
|
||||
def accept visitor
|
||||
visitor.accept_verbatim self
|
||||
end
|
||||
|
@ -17,16 +20,16 @@ class RDoc::Markup::Verbatim < RDoc::Markup::Raw
|
|||
|
||||
@parts.each do |part|
|
||||
case part
|
||||
when /\n/ then
|
||||
when /^\s*\n/ then
|
||||
newlines += 1
|
||||
parts << part if newlines <= 2
|
||||
parts << part if newlines == 1
|
||||
else
|
||||
newlines = 0
|
||||
parts << part
|
||||
end
|
||||
end
|
||||
|
||||
parts.slice!(-1) if parts[-2..-1] == ["\n", "\n"]
|
||||
parts.pop if parts.last =~ /\A\r?\n\z/
|
||||
|
||||
@parts = parts
|
||||
end
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
require 'rdoc/code_object'
|
||||
|
||||
##
|
||||
# Abstract class representing either a method or an attribute.
|
||||
|
||||
class RDoc::MethodAttr < RDoc::CodeObject
|
||||
|
||||
include Comparable
|
||||
|
||||
##
|
||||
# Name of this method/attribute.
|
||||
|
||||
attr_accessor :name
|
||||
|
||||
##
|
||||
# public, protected, private
|
||||
|
||||
attr_accessor :visibility
|
||||
|
||||
##
|
||||
# Is this a singleton method/attribute?
|
||||
|
||||
attr_accessor :singleton
|
||||
|
||||
##
|
||||
# Source file token stream
|
||||
|
||||
attr_reader :text
|
||||
|
||||
##
|
||||
# Array of other names for this method/attribute
|
||||
|
||||
attr_reader :aliases
|
||||
|
||||
##
|
||||
# The method/attribute we're aliasing
|
||||
|
||||
attr_accessor :is_alias_for
|
||||
|
||||
#--
|
||||
# The attributes below are for AnyMethod only.
|
||||
# They are left here for the time being to
|
||||
# allow ri to operate.
|
||||
# TODO modify ri to avoid calling these on attributes.
|
||||
#++
|
||||
|
||||
##
|
||||
# Parameters yielded by the called block
|
||||
|
||||
attr_reader :block_params
|
||||
|
||||
##
|
||||
# Parameters for this method
|
||||
|
||||
attr_accessor :params
|
||||
|
||||
##
|
||||
# Different ways to call this method
|
||||
|
||||
attr_accessor :call_seq
|
||||
|
||||
##
|
||||
# The call_seq or the param_seq with method name, if there is no call_seq.
|
||||
|
||||
attr_reader :arglists
|
||||
|
||||
##
|
||||
# Pretty parameter list for this method
|
||||
|
||||
attr_reader :param_seq
|
||||
|
||||
|
||||
##
|
||||
# Creates a new MethodAttr from token stream +text+ and method or attribute
|
||||
# name +name+.
|
||||
#
|
||||
# Usually this is called by super from a subclass.
|
||||
|
||||
def initialize text, name
|
||||
super()
|
||||
|
||||
@text = text
|
||||
@name = name
|
||||
|
||||
@aliases = []
|
||||
@is_alias_for = nil
|
||||
@parent_name = nil
|
||||
@singleton = nil
|
||||
@visibility = :public
|
||||
@see = false
|
||||
|
||||
@arglists = nil
|
||||
@block_params = nil
|
||||
@call_seq = nil
|
||||
@param_seq = nil
|
||||
@params = nil
|
||||
end
|
||||
|
||||
##
|
||||
# Order by #singleton then #name
|
||||
|
||||
def <=>(other)
|
||||
[@singleton ? 0 : 1, name] <=> [other.singleton ? 0 : 1, other.name]
|
||||
end
|
||||
|
||||
##
|
||||
# A method/attribute is documented if any of the following is true:
|
||||
# - it was marked with :nodoc:;
|
||||
# - it has a comment;
|
||||
# - it is an alias for a documented method;
|
||||
# - it has a +#see+ method that is documented.
|
||||
|
||||
def documented?
|
||||
super or
|
||||
(is_alias_for and is_alias_for.documented?) or
|
||||
(see and see.documented?)
|
||||
end
|
||||
|
||||
##
|
||||
# A method/attribute to look at,
|
||||
# in particular if this method/attribute has no documentation.
|
||||
#
|
||||
# It can be a method/attribute of the superclass or of an included module,
|
||||
# including the Kernel module, which is always appended to the included
|
||||
# modules.
|
||||
#
|
||||
# Returns +nil+ if there is no such method/attribute.
|
||||
# The +#is_alias_for+ method/attribute, if any, is not included.
|
||||
#
|
||||
# Templates may generate a "see also ..." if this method/attribute
|
||||
# has documentation, and "see ..." if it does not.
|
||||
|
||||
def see
|
||||
@see = find_see if @see == false
|
||||
@see
|
||||
end
|
||||
|
||||
def find_see # :nodoc:
|
||||
return nil if singleton || is_alias_for
|
||||
|
||||
# look for the method
|
||||
other = find_method_or_attribute name
|
||||
return other if other
|
||||
|
||||
# if it is a setter, look for a getter
|
||||
return nil unless name =~ /[a-z_]=$/i # avoid == or ===
|
||||
return find_method_or_attribute name[0..-2]
|
||||
end
|
||||
|
||||
def find_method_or_attribute name # :nodoc:
|
||||
return nil unless parent.respond_to? :ancestors
|
||||
|
||||
searched = parent.ancestors
|
||||
kernel = RDoc::TopLevel.all_modules_hash['Kernel']
|
||||
|
||||
searched << kernel if kernel &&
|
||||
parent != kernel && !searched.include?(kernel)
|
||||
|
||||
searched.each do |ancestor|
|
||||
next if parent == ancestor
|
||||
next if String === ancestor
|
||||
|
||||
other = ancestor.find_method_named('#' << name) ||
|
||||
ancestor.find_attribute_named(name)
|
||||
|
||||
return other if other
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Abstract method. Contexts in their building phase call this
|
||||
# to register a new alias for this known method/attribute.
|
||||
#
|
||||
# - creates a new AnyMethod/Attribute +newa+ named an_alias.new_name;
|
||||
# - adds +self+ as +newa.is_alias_for+;
|
||||
# - adds +newa+ to #aliases
|
||||
# - adds +newa+ to the methods/attributes of +context+.
|
||||
|
||||
def add_alias(an_alias, context)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
##
|
||||
# HTML fragment reference for this method
|
||||
|
||||
def aref
|
||||
type = singleton ? 'c' : 'i'
|
||||
# % characters are not allowed in html names => dash instead
|
||||
"#{aref_prefix}-#{type}-#{html_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# Prefix for +aref+, defined by subclasses.
|
||||
|
||||
def aref_prefix
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
##
|
||||
# Attempts to sanitize the content passed by the ruby parser:
|
||||
# remove outer parentheses, etc.
|
||||
|
||||
def block_params=(value)
|
||||
# 'yield.to_s' or 'assert yield, msg'
|
||||
return @block_params = '' if value =~ /^[\.,]/
|
||||
|
||||
# remove trailing 'if/unless ...'
|
||||
return @block_params = '' if value =~ /^(if|unless)\s/
|
||||
|
||||
value = $1.strip if value =~ /^(.+)\s(if|unless)\s/
|
||||
|
||||
# outer parentheses
|
||||
value = $1 if value =~ /^\s*\((.*)\)\s*$/
|
||||
value = value.strip
|
||||
|
||||
# proc/lambda
|
||||
return @block_params = $1 if value =~ /^(proc|lambda)(\s*\{|\sdo)/
|
||||
|
||||
# surrounding +...+ or [...]
|
||||
value = $1.strip if value =~ /^\+(.*)\+$/
|
||||
value = $1.strip if value =~ /^\[(.*)\]$/
|
||||
|
||||
return @block_params = '' if value.empty?
|
||||
|
||||
# global variable
|
||||
return @block_params = 'str' if value =~ /^\$[&0-9]$/
|
||||
|
||||
# wipe out array/hash indices
|
||||
value.gsub!(/(\w)\[[^\[]+\]/, '\1')
|
||||
|
||||
# remove @ from class/instance variables
|
||||
value.gsub!(/@@?([a-z0-9_]+)/, '\1')
|
||||
|
||||
# method calls => method name
|
||||
value.gsub!(/([A-Z:a-z0-9_]+)\.([a-z0-9_]+)(\s*\(\s*[a-z0-9_.,\s]*\s*\)\s*)?/) do
|
||||
case $2
|
||||
when 'to_s' then $1
|
||||
when 'const_get' then 'const'
|
||||
when 'new' then
|
||||
$1.split('::').last. # ClassName => class_name
|
||||
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
||||
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
||||
downcase
|
||||
else
|
||||
$2
|
||||
end
|
||||
end
|
||||
|
||||
# class prefixes
|
||||
value.gsub!(/[A-Za-z0-9_:]+::/, '')
|
||||
|
||||
# simple expressions
|
||||
value = $1 if value =~ /^([a-z0-9_]+)\s*[-*+\/]/
|
||||
|
||||
@block_params = value.strip
|
||||
end
|
||||
|
||||
##
|
||||
# HTML id-friendly method/attribute name
|
||||
|
||||
def html_name
|
||||
CGI.escape(@name.gsub('-', '-2D')).gsub('%','-').sub(/^-/, '')
|
||||
end
|
||||
|
||||
##
|
||||
# Full method/attribute name including namespace
|
||||
|
||||
def full_name
|
||||
@full_name || "#{parent_name}#{pretty_name}"
|
||||
end
|
||||
|
||||
##
|
||||
# '::' for a class method/attribute, '#' for an instance method.
|
||||
|
||||
def name_prefix
|
||||
singleton ? '::' : '#'
|
||||
end
|
||||
|
||||
##
|
||||
# Method/attribute name with class/instance indicator
|
||||
|
||||
def pretty_name
|
||||
"#{name_prefix}#{@name}"
|
||||
end
|
||||
|
||||
##
|
||||
# Type of method/attribute (class or instance)
|
||||
|
||||
def type
|
||||
singleton ? 'class' : 'instance'
|
||||
end
|
||||
|
||||
##
|
||||
# Path to this method
|
||||
|
||||
def path
|
||||
"#{@parent.path}##{aref}"
|
||||
end
|
||||
|
||||
##
|
||||
# Name of our parent with special handling for un-marshaled methods
|
||||
|
||||
def parent_name
|
||||
@parent_name || super
|
||||
end
|
||||
|
||||
def pretty_print q # :nodoc:
|
||||
alias_for = @is_alias_for ? "alias for #{@is_alias_for.name}" : nil
|
||||
|
||||
q.group 2, "[#{self.class.name} #{full_name} #{visibility}", "]" do
|
||||
if alias_for then
|
||||
q.breakable
|
||||
q.text alias_for
|
||||
end
|
||||
|
||||
if text then
|
||||
q.breakable
|
||||
q.text "text:"
|
||||
q.breakable
|
||||
q.pp @text
|
||||
end
|
||||
|
||||
unless comment.empty? then
|
||||
q.breakable
|
||||
q.text "comment:"
|
||||
q.breakable
|
||||
q.pp @comment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
|
||||
"#<%s:0x%x %s (%s)%s>" % [
|
||||
self.class, object_id,
|
||||
full_name,
|
||||
visibility,
|
||||
alias_for,
|
||||
]
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
if @is_alias_for
|
||||
"#{self.class.name}: #{full_name} -> #{is_alias_for}"
|
||||
else
|
||||
"#{self.class.name}: #{full_name}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -6,10 +6,10 @@ require 'rdoc/class_module'
|
|||
class RDoc::NormalClass < RDoc::ClassModule
|
||||
|
||||
##
|
||||
# Ancestor ClassModules
|
||||
# Appends the superclass, if any, to the included modules.
|
||||
|
||||
def ancestors
|
||||
includes + [superclass]
|
||||
superclass ? super + [superclass] : super
|
||||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
|
@ -20,6 +20,15 @@ class RDoc::NormalClass < RDoc::ClassModule
|
|||
]
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
display = "#{self.class.name} #{self.full_name}"
|
||||
if superclass
|
||||
display << ' < ' << (superclass.is_a?(String) ? superclass : superclass.full_name)
|
||||
end
|
||||
display << ' -> ' << is_alias_for.to_s if is_alias_for
|
||||
display
|
||||
end
|
||||
|
||||
def pretty_print q # :nodoc:
|
||||
superclass = @superclass ? " < #{@superclass}" : nil
|
||||
|
||||
|
|
|
@ -5,11 +5,6 @@ require 'rdoc/class_module'
|
|||
|
||||
class RDoc::NormalModule < RDoc::ClassModule
|
||||
|
||||
##
|
||||
# Included NormalModules
|
||||
|
||||
alias ancestors includes
|
||||
|
||||
def inspect # :nodoc:
|
||||
"#<%s:0x%x module %s includes: %p attributes: %p methods: %p aliases: %p>" % [
|
||||
self.class, object_id,
|
||||
|
|
|
@ -8,9 +8,41 @@ require 'rdoc/ri/paths'
|
|||
class RDoc::Options
|
||||
|
||||
##
|
||||
# Character-set
|
||||
# The deprecated options.
|
||||
|
||||
attr_reader :charset
|
||||
DEPRECATED = {
|
||||
'--accessor' => 'support discontinued',
|
||||
'--diagram' => 'support discontinued',
|
||||
'--help-output' => 'support discontinued',
|
||||
'--image-format' => 'was an option for --diagram',
|
||||
'--inline-source' => 'source code is now always inlined',
|
||||
'--merge' => 'ri now always merges class information',
|
||||
'--one-file' => 'support discontinued',
|
||||
'--op-name' => 'support discontinued',
|
||||
'--opname' => 'support discontinued',
|
||||
'--promiscuous' => 'files always only document their content',
|
||||
'--ri-system' => 'Ruby installers use other techniques',
|
||||
}
|
||||
|
||||
##
|
||||
# Template option validator for OptionParser
|
||||
|
||||
Template = nil
|
||||
|
||||
##
|
||||
# Character-set for HTML output. #encoding is preferred over #charset
|
||||
|
||||
attr_accessor :charset
|
||||
|
||||
##
|
||||
# If true, RDoc will not write any files.
|
||||
|
||||
attr_accessor :dry_run
|
||||
|
||||
##
|
||||
# Encoding of output where. This is set via --encoding.
|
||||
|
||||
attr_accessor :encoding if Object.const_defined? :Encoding
|
||||
|
||||
##
|
||||
# Files matching this pattern will be excluded
|
||||
|
@ -22,10 +54,21 @@ class RDoc::Options
|
|||
|
||||
attr_accessor :files
|
||||
|
||||
##
|
||||
# Create the output even if the output directory does not look
|
||||
# like an rdoc output directory
|
||||
|
||||
attr_accessor :force_output
|
||||
|
||||
##
|
||||
# Scan newer sources than the flag file if true.
|
||||
|
||||
attr_reader :force_update
|
||||
attr_accessor :force_update
|
||||
|
||||
##
|
||||
# Formatter to mark up text with
|
||||
|
||||
attr_accessor :formatter
|
||||
|
||||
##
|
||||
# Description of the output generator (set with the <tt>-fmt</tt> option)
|
||||
|
@ -33,9 +76,21 @@ class RDoc::Options
|
|||
attr_accessor :generator
|
||||
|
||||
##
|
||||
# Formatter to mark up text with
|
||||
# Loaded generator options. Used to prevent --help from loading the same
|
||||
# options multiple times.
|
||||
|
||||
attr_accessor :formatter
|
||||
attr_accessor :generator_options
|
||||
|
||||
##
|
||||
# Old rdoc behavior: hyperlink all words that match a method name,
|
||||
# even if not preceded by '#' or '::'
|
||||
|
||||
attr_accessor :hyperlink_all
|
||||
|
||||
##
|
||||
# Include line numbers in the source code
|
||||
|
||||
attr_accessor :line_numbers
|
||||
|
||||
##
|
||||
# Name of the file, class or module to display in the initial index page (if
|
||||
|
@ -43,11 +98,21 @@ class RDoc::Options
|
|||
|
||||
attr_accessor :main_page
|
||||
|
||||
##
|
||||
# If true, only report on undocumented files
|
||||
|
||||
attr_accessor :coverage_report
|
||||
|
||||
##
|
||||
# The name of the output directory
|
||||
|
||||
attr_accessor :op_dir
|
||||
|
||||
##
|
||||
# The OptionParser for this instance
|
||||
|
||||
attr_accessor :option_parser
|
||||
|
||||
##
|
||||
# Is RDoc in pipe mode?
|
||||
|
||||
|
@ -56,32 +121,32 @@ class RDoc::Options
|
|||
##
|
||||
# Array of directories to search for files to satisfy an :include:
|
||||
|
||||
attr_reader :rdoc_include
|
||||
|
||||
##
|
||||
# Include private and protected methods in the output?
|
||||
|
||||
attr_accessor :show_all
|
||||
attr_accessor :rdoc_include
|
||||
|
||||
##
|
||||
# Include the '#' at the front of hyperlinked instance method names
|
||||
|
||||
attr_reader :show_hash
|
||||
attr_accessor :show_hash
|
||||
|
||||
##
|
||||
# The number of columns in a tab
|
||||
|
||||
attr_reader :tab_width
|
||||
attr_accessor :tab_width
|
||||
|
||||
##
|
||||
# Template to be used when generating output
|
||||
|
||||
attr_reader :template
|
||||
attr_accessor :template
|
||||
|
||||
##
|
||||
# Directory the template lives in
|
||||
|
||||
attr_accessor :template_dir
|
||||
|
||||
##
|
||||
# Documentation title
|
||||
|
||||
attr_reader :title
|
||||
attr_accessor :title
|
||||
|
||||
##
|
||||
# Verbosity, zero means quiet
|
||||
|
@ -91,29 +156,88 @@ class RDoc::Options
|
|||
##
|
||||
# URL of web cvs frontend
|
||||
|
||||
attr_reader :webcvs
|
||||
attr_accessor :webcvs
|
||||
|
||||
##
|
||||
# Minimum visibility of a documented method. One of +:public+,
|
||||
# +:protected+, +:private+. May be overridden on a per-method
|
||||
# basis with the :doc: directive.
|
||||
|
||||
attr_accessor :visibility
|
||||
|
||||
def initialize # :nodoc:
|
||||
require 'rdoc/rdoc'
|
||||
@op_dir = nil
|
||||
@show_all = false
|
||||
@main_page = nil
|
||||
@dry_run = false
|
||||
@exclude = []
|
||||
@generators = RDoc::RDoc::GENERATORS
|
||||
@generator = RDoc::Generator::Darkfish
|
||||
@generator_name = nil
|
||||
@rdoc_include = []
|
||||
@title = nil
|
||||
@template = nil
|
||||
@show_hash = false
|
||||
@tab_width = 8
|
||||
@force_output = false
|
||||
@force_update = true
|
||||
@verbosity = 1
|
||||
@generator = nil
|
||||
@generator_name = nil
|
||||
@generator_options = []
|
||||
@generators = RDoc::RDoc::GENERATORS
|
||||
@hyperlink_all = false
|
||||
@line_numbers = false
|
||||
@main_page = nil
|
||||
@coverage_report = false
|
||||
@op_dir = nil
|
||||
@pipe = false
|
||||
|
||||
@rdoc_include = []
|
||||
@show_hash = false
|
||||
@stylesheet_url = nil
|
||||
@tab_width = 8
|
||||
@template = nil
|
||||
@template_dir = nil
|
||||
@title = nil
|
||||
@verbosity = 1
|
||||
@visibility = :protected
|
||||
@webcvs = nil
|
||||
|
||||
@charset = 'utf-8'
|
||||
if Object.const_defined? :Encoding then
|
||||
@encoding = Encoding.default_external
|
||||
@charset = @encoding.to_s
|
||||
else
|
||||
@charset = 'UTF-8'
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Check that the files on the command line exist
|
||||
|
||||
def check_files
|
||||
@files.delete_if do |file|
|
||||
if File.exist? file then
|
||||
if File.readable? file then
|
||||
false
|
||||
else
|
||||
warn "file '#{file}' not readable"
|
||||
|
||||
true
|
||||
end
|
||||
else
|
||||
warn "file '#{file}' not found"
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Ensure only one generator is loaded
|
||||
|
||||
def check_generator
|
||||
if @generator then
|
||||
raise OptionParser::InvalidOption,
|
||||
"generator already set to #{@generator_name}"
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Set the title, but only if not already set. Used to set the title
|
||||
# from a source file, so that a title set from the command line
|
||||
# will have the priority.
|
||||
|
||||
def default_title=(string)
|
||||
@title ||= string
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -122,7 +246,10 @@ class RDoc::Options
|
|||
def parse(argv)
|
||||
ignore_invalid = true
|
||||
|
||||
argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT']
|
||||
|
||||
opts = OptionParser.new do |opt|
|
||||
@option_parser = opt
|
||||
opt.program_name = File.basename $0
|
||||
opt.version = RDoc::VERSION
|
||||
opt.release = nil
|
||||
|
@ -139,6 +266,14 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
How RDoc generates output depends on the output formatter being used, and on
|
||||
the options you give.
|
||||
|
||||
Options can be specified via the RDOCOPT environment variable, which
|
||||
functions similar to the RUBYOPT environment variable for ruby.
|
||||
|
||||
$ export RDOCOPT="--show-hash"
|
||||
|
||||
will make rdoc show hashes in method links by default. Command-line options
|
||||
always will override those in RDOCOPT.
|
||||
|
||||
- Darkfish creates frameless HTML output by Michael Granger.
|
||||
- ri creates ri data files
|
||||
|
||||
|
@ -156,14 +291,44 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
opt.banner << " - #{parser}: #{regexp.join ', '}\n"
|
||||
end
|
||||
|
||||
opt.banner << "\n The following options are deprecated:\n\n"
|
||||
|
||||
name_length = DEPRECATED.keys.sort_by { |k| k.length }.last.length
|
||||
|
||||
DEPRECATED.sort_by { |k,| k }.each do |name, reason|
|
||||
opt.banner << " %*1$2$s %3$s\n" % [-name_length, name, reason]
|
||||
end
|
||||
|
||||
opt.accept Template do |template|
|
||||
template_dir = template_dir_for template
|
||||
|
||||
unless template_dir then
|
||||
warn "could not find template #{template}"
|
||||
nil
|
||||
else
|
||||
[template, template_dir]
|
||||
end
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
opt.separator "Parsing Options:"
|
||||
opt.separator "Parsing options:"
|
||||
opt.separator nil
|
||||
|
||||
if Object.const_defined? :Encoding then
|
||||
opt.on("--encoding=ENCODING", "-e", Encoding.list.map { |e| e.name },
|
||||
"Specifies the output encoding. All files",
|
||||
"read will be converted to this encoding.",
|
||||
"Preferred over --charset") do |value|
|
||||
@encoding = Encoding.find value
|
||||
@charset = @encoding.to_s # may not be valid value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
end
|
||||
|
||||
opt.on("--all", "-a",
|
||||
"Include all methods (not just public) in",
|
||||
"the output.") do |value|
|
||||
@show_all = value
|
||||
"Synonym for --visibility=private.") do |value|
|
||||
@visibility = :private
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
@ -207,20 +372,41 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
end
|
||||
|
||||
opt.separator nil
|
||||
opt.separator "Generator Options:"
|
||||
|
||||
opt.on("--tab-width=WIDTH", "-w", OptionParser::DecimalInteger,
|
||||
"Set the width of tab characters.") do |value|
|
||||
@tab_width = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--charset=CHARSET", "-c",
|
||||
"Specifies the output HTML character-set.") do |value|
|
||||
@charset = value
|
||||
opt.on("--visibility=VISIBILITY", "-V", RDoc::VISIBILITIES,
|
||||
"Minimum visibility to document a method.",
|
||||
"One of 'public', 'protected' (the default)",
|
||||
"or 'private'. Can be abbreviated.") do |value|
|
||||
@visibility = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
opt.separator "Common generator options:"
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--force-output", "-O",
|
||||
"Forces rdoc to write the output files,",
|
||||
"even if the output directory exists",
|
||||
"and does not seem to have been created",
|
||||
"by rdoc.") do |value|
|
||||
@force_output = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
generator_text = @generators.keys.map { |name| " #{name}" }.sort
|
||||
|
||||
opt.on("--fmt=FORMAT", "--format=FORMAT", "-f", @generators.keys,
|
||||
opt.on("-f", "--fmt=FORMAT", "--format=FORMAT", @generators.keys,
|
||||
"Set the output formatter. One of:", *generator_text) do |value|
|
||||
check_generator
|
||||
|
||||
@generator_name = value.downcase
|
||||
setup_generator
|
||||
end
|
||||
|
@ -236,9 +422,11 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--main=NAME", "-m",
|
||||
"NAME will be the initial page displayed.") do |value|
|
||||
@main_page = value
|
||||
opt.on("--[no-]coverage-report", "--[no-]dcov", "-C",
|
||||
"Prints a report on undocumented items.",
|
||||
"Does not generate files.") do |value|
|
||||
@coverage_report = value
|
||||
@force_update = true if value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
@ -250,6 +438,51 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("-d",
|
||||
"Deprecated --diagram option.",
|
||||
"Prevents firing debug mode",
|
||||
"with legacy invocation.") do |value|
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
opt.separator 'HTML generator options:'
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--charset=CHARSET", "-c",
|
||||
"Specifies the output HTML character-set.",
|
||||
"Use --encoding instead of --charset if",
|
||||
"available.") do |value|
|
||||
@charset = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--hyperlink-all", "-A",
|
||||
"Generate hyperlinks for all words that",
|
||||
"correspond to known methods, even if they",
|
||||
"do not start with '#' or '::' (legacy",
|
||||
"behavior).") do |value|
|
||||
@hyperlink_all = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--main=NAME", "-m",
|
||||
"NAME will be the initial page displayed.") do |value|
|
||||
@main_page = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--[no-]line-numbers", "-N",
|
||||
"Include line numbers in the source code.",
|
||||
"By default, only the number of the first",
|
||||
"line is displayed, in a leading comment.") do |value|
|
||||
@line_numbers = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--show-hash", "-H",
|
||||
"A name of the form #name in a comment is a",
|
||||
"possible hyperlink to an instance method",
|
||||
|
@ -260,17 +493,12 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--tab-width=WIDTH", "-w", OptionParser::DecimalInteger,
|
||||
"Set the width of tab characters.") do |value|
|
||||
@tab_width = value
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--template=NAME", "-T",
|
||||
opt.on("--template=NAME", "-T", Template,
|
||||
"Set the template used when generating",
|
||||
"output.") do |value|
|
||||
@template = value
|
||||
"output. The default depends on the",
|
||||
"formatter used.") do |(template, template_dir)|
|
||||
@template = template
|
||||
@template_dir = template_dir
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
|
@ -292,11 +520,7 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
end
|
||||
|
||||
opt.separator nil
|
||||
|
||||
opt.on("-d", "--diagram", "Prevents -d from tripping --debug")
|
||||
|
||||
opt.separator nil
|
||||
opt.separator "ri Generator Options:"
|
||||
opt.separator "ri generator options:"
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--ri", "-r",
|
||||
|
@ -305,6 +529,8 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
"your home directory unless overridden by a",
|
||||
"subsequent --op parameter, so no special",
|
||||
"privileges are needed.") do |value|
|
||||
check_generator
|
||||
|
||||
@generator_name = "ri"
|
||||
@op_dir ||= RDoc::RI::Paths::HOMEDIR
|
||||
setup_generator
|
||||
|
@ -317,22 +543,30 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
"are stored in a site-wide directory,",
|
||||
"making them accessible to others, so",
|
||||
"special privileges are needed.") do |value|
|
||||
check_generator
|
||||
|
||||
@generator_name = "ri"
|
||||
@op_dir = RDoc::RI::Paths::SITEDIR
|
||||
setup_generator
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
opt.separator "Generic Options:"
|
||||
opt.separator "Generic options:"
|
||||
opt.separator nil
|
||||
|
||||
opt.on("--[no-]dry-run",
|
||||
"Don't write any files") do |value|
|
||||
@dry_run = value
|
||||
end
|
||||
|
||||
opt.on("-D", "--[no-]debug",
|
||||
"Displays lots on internal stuff.") do |value|
|
||||
$DEBUG_RDOC = value
|
||||
end
|
||||
|
||||
opt.on("--[no-]ignore-invalid",
|
||||
"Ignore invalid options and continue.") do |value|
|
||||
"Ignore invalid options and continue",
|
||||
"(default true).") do |value|
|
||||
ignore_invalid = value
|
||||
end
|
||||
|
||||
|
@ -342,38 +576,70 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
end
|
||||
|
||||
opt.on("--verbose", "-v",
|
||||
"Display extra progress as we parse.") do |value|
|
||||
"Display extra progress as RDoc parses") do |value|
|
||||
@verbosity = 2
|
||||
end
|
||||
|
||||
opt.on("--help",
|
||||
"Display this help") do
|
||||
RDoc::RDoc::GENERATORS.each_key do |generator|
|
||||
setup_generator generator
|
||||
end
|
||||
|
||||
puts opt.help
|
||||
exit
|
||||
end
|
||||
|
||||
opt.separator nil
|
||||
end
|
||||
|
||||
argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT']
|
||||
ignored = []
|
||||
setup_generator 'darkfish' if
|
||||
argv.grep(/\A(-f|--fmt|--format|-r|-R|--ri|--ri-site)\b/).empty?
|
||||
|
||||
deprecated = []
|
||||
invalid = []
|
||||
|
||||
begin
|
||||
opts.parse! argv
|
||||
rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
|
||||
if ignore_invalid then
|
||||
ignored << e.args.join(' ')
|
||||
retry
|
||||
if DEPRECATED[e.args.first] then
|
||||
deprecated << e.args.first
|
||||
elsif %w[--format --ri -r --ri-site -R].include? e.args.first then
|
||||
raise
|
||||
else
|
||||
$stderr.puts opts
|
||||
$stderr.puts
|
||||
$stderr.puts e
|
||||
exit 1
|
||||
invalid << e.args.join(' ')
|
||||
end
|
||||
|
||||
retry
|
||||
end
|
||||
|
||||
unless @generator then
|
||||
@generator = RDoc::Generator::Darkfish
|
||||
@generator_name = 'darkfish'
|
||||
end
|
||||
|
||||
if @pipe and not argv.empty? then
|
||||
@pipe = false
|
||||
ignored << '-p (with files)'
|
||||
invalid << '-p (with files)'
|
||||
end
|
||||
|
||||
unless ignored.empty? or quiet then
|
||||
$stderr.puts "invalid options: #{ignored.join ', '}"
|
||||
$stderr.puts '(invalid options are ignored)'
|
||||
unless quiet then
|
||||
deprecated.each do |opt|
|
||||
$stderr.puts 'option ' << opt << ' is deprecated: ' << DEPRECATED[opt]
|
||||
end
|
||||
|
||||
unless invalid.empty? then
|
||||
invalid = "invalid options: #{invalid.join ', '}"
|
||||
|
||||
if ignore_invalid then
|
||||
$stderr.puts invalid
|
||||
$stderr.puts '(invalid options are ignored)'
|
||||
else
|
||||
$stderr.puts opts
|
||||
$stderr.puts invalid
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@op_dir ||= 'doc'
|
||||
|
@ -392,15 +658,10 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
# If no template was specified, use the default template for the output
|
||||
# formatter
|
||||
|
||||
@template ||= @generator_name
|
||||
end
|
||||
|
||||
##
|
||||
# Set the title, but only if not already set. This means that a title set
|
||||
# from the command line trumps one set in a source file
|
||||
|
||||
def title=(string)
|
||||
@title ||= string
|
||||
unless @template then
|
||||
@template = @generator_name
|
||||
@template_dir = template_dir_for @template
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -410,30 +671,46 @@ Usage: #{opt.program_name} [options] [names...]
|
|||
@verbosity.zero?
|
||||
end
|
||||
|
||||
def quiet=(bool)
|
||||
##
|
||||
# Set quietness to +bool+
|
||||
|
||||
def quiet= bool
|
||||
@verbosity = bool ? 0 : 1
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Set up an output generator for the format in @generator_name
|
||||
# Set up an output generator for the named +generator_name+.
|
||||
#
|
||||
# If the found generator responds to :setup_options it will be called with
|
||||
# the options instance. This allows generators to add custom options or set
|
||||
# default options.
|
||||
|
||||
def setup_generator
|
||||
@generator = @generators[@generator_name]
|
||||
def setup_generator generator_name = @generator_name
|
||||
@generator = @generators[generator_name]
|
||||
|
||||
unless @generator then
|
||||
raise OptionParser::InvalidArgument, "Invalid output formatter"
|
||||
raise OptionParser::InvalidArgument,
|
||||
"Invalid output formatter #{generator_name}"
|
||||
end
|
||||
|
||||
return if @generator_options.include? @generator
|
||||
|
||||
@generator_name = generator_name
|
||||
@generator_options << @generator
|
||||
|
||||
@generator.setup_options self if @generator.respond_to? :setup_options
|
||||
end
|
||||
|
||||
##
|
||||
# Check that the files on the command line exist
|
||||
# Finds the template dir for +template+
|
||||
|
||||
def check_files
|
||||
@files.each do |f|
|
||||
stat = File.stat f rescue next
|
||||
raise RDoc::Error, "file '#{f}' not readable" unless stat.readable?
|
||||
def template_dir_for template
|
||||
template_path = File.join 'rdoc', 'generator', 'template', template
|
||||
|
||||
$LOAD_PATH.map do |path|
|
||||
File.join File.expand_path(path), template_path
|
||||
end.find do |dir|
|
||||
File.directory? dir
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'rdoc'
|
||||
require 'rdoc/code_objects'
|
||||
require 'rdoc/markup/preprocess'
|
||||
require 'rdoc/markup/pre_process'
|
||||
require 'rdoc/stats'
|
||||
|
||||
##
|
||||
|
@ -43,7 +43,15 @@ class RDoc::Parser
|
|||
@parsers = []
|
||||
|
||||
class << self
|
||||
|
||||
##
|
||||
# A Hash that maps file exetensions regular expressions to parsers that
|
||||
# will consume them.
|
||||
#
|
||||
# Use parse_files_matching to register a parser's file extensions.
|
||||
|
||||
attr_reader :parsers
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -67,18 +75,51 @@ class RDoc::Parser
|
|||
# content that an RDoc parser shouldn't try to consume.
|
||||
|
||||
def self.binary?(file)
|
||||
return false if file =~ /\.(rdoc|txt)$/
|
||||
|
||||
s = File.read(file, 1024) or return false
|
||||
|
||||
if s[0, 2] == Marshal.dump('')[0, 2] then
|
||||
true
|
||||
elsif file =~ /erb\.rb$/ then
|
||||
false
|
||||
elsif s.scan(/<%|%>/).length >= 4 || s.index("\x00") then
|
||||
true
|
||||
elsif 0.respond_to? :fdiv then
|
||||
s.count("\x00-\x7F", "^ -~\t\r\n").fdiv(s.size) > 0.3
|
||||
else # HACK 1.8.6
|
||||
(s.count("\x00-\x7F", "^ -~\t\r\n").to_f / s.size) > 0.3
|
||||
have_encoding = s.respond_to? :encoding
|
||||
|
||||
if have_encoding then
|
||||
return false if s.encoding != Encoding::ASCII_8BIT and s.valid_encoding?
|
||||
end
|
||||
|
||||
return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00")
|
||||
|
||||
if have_encoding then
|
||||
s.force_encoding Encoding.default_external
|
||||
|
||||
not s.valid_encoding?
|
||||
else
|
||||
if 0.respond_to? :fdiv then
|
||||
s.count("\x00-\x7F", "^ -~\t\r\n").fdiv(s.size) > 0.3
|
||||
else # HACK 1.8.6
|
||||
(s.count("\x00-\x7F", "^ -~\t\r\n").to_f / s.size) > 0.3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Processes common directives for CodeObjects for the C and Ruby parsers.
|
||||
#
|
||||
# Applies +directive+'s +value+ to +code_object+, if appropriate
|
||||
|
||||
def self.process_directive code_object, directive, value
|
||||
case directive
|
||||
when 'nodoc' then
|
||||
code_object.document_self = nil # notify nodoc
|
||||
code_object.document_children = value.downcase != 'all'
|
||||
when 'doc' then
|
||||
code_object.document_self = true
|
||||
code_object.force_documentation = true
|
||||
when 'yield', 'yields' then
|
||||
# remove parameter &block
|
||||
code_object.params.sub!(/,?\s*&\w+/, '') if code_object.params
|
||||
|
||||
code_object.block_params = value
|
||||
when 'arg', 'args' then
|
||||
code_object.params = value
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -143,6 +184,12 @@ class RDoc::Parser
|
|||
RDoc::Parser.parsers.unshift [regexp, self]
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a new Parser storing +top_level+, +file_name+, +content+,
|
||||
# +options+ and +stats+ in instance variables.
|
||||
#
|
||||
# Usually invoked by +super+
|
||||
|
||||
def initialize(top_level, file_name, content, options, stats)
|
||||
@top_level = top_level
|
||||
@file_name = file_name
|
||||
|
|
|
@ -3,9 +3,9 @@ require 'rdoc/parser/ruby'
|
|||
require 'rdoc/known_classes'
|
||||
|
||||
##
|
||||
# We attempt to parse C extension files. Basically we look for
|
||||
# RDoc::Parser::C attempts to parse C extension files. It looks 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
|
||||
# rb_define_method</tt> and so on. It tries to find the corresponding
|
||||
# C source for the methods and extract comments, but if we fail
|
||||
# we don't worry too much.
|
||||
#
|
||||
|
@ -49,13 +49,26 @@ require 'rdoc/known_classes'
|
|||
#
|
||||
# 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-class: +name+]
|
||||
# Documentation for the named class.
|
||||
#
|
||||
# [Document-method: <i>name</i>]
|
||||
# This comment documents the named method. Use when RDoc cannot
|
||||
# automatically find the method from it's declaration
|
||||
# [Document-module: +name+]
|
||||
# Documentation for the named module.
|
||||
#
|
||||
# [Document-const: +name+]
|
||||
# Documentation for the named +rb_define_const+.
|
||||
#
|
||||
# [Document-global: +name+]
|
||||
# Documentation for the named +rb_define_global_const+
|
||||
#
|
||||
# [Document-variable: +name+]
|
||||
# Documentation for the named +rb_define_variable+
|
||||
#
|
||||
# [Document-method: +name+]
|
||||
# Documentation for the named method.
|
||||
#
|
||||
# [Document-attr: +name+]
|
||||
# Documentation for the named attribute.
|
||||
#
|
||||
# [call-seq: <i>text up to an empty line</i>]
|
||||
# Because C source doesn't give descripive names to Ruby-level parameters,
|
||||
|
@ -120,21 +133,61 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
@known_classes = RDoc::KNOWN_CLASSES.dup
|
||||
@content = handle_tab_width handle_ifdefs_in(@content)
|
||||
@classes = Hash.new
|
||||
@singleton_classes = Hash.new
|
||||
@file_dir = File.dirname(@file_name)
|
||||
end
|
||||
|
||||
##
|
||||
# Scans #content for rb_define_alias
|
||||
|
||||
def do_aliases
|
||||
@content.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do
|
||||
|var_name, new_name, old_name|
|
||||
@content.scan(/rb_define_alias\s*\(
|
||||
\s*(\w+),
|
||||
\s*"(.+?)",
|
||||
\s*"(.+?)"
|
||||
\s*\)/xm) do |var_name, new_name, old_name|
|
||||
class_name = @known_classes[var_name] || var_name
|
||||
class_obj = find_class(var_name, class_name)
|
||||
class_obj = find_class var_name, class_name
|
||||
|
||||
as = class_obj.add_alias RDoc::Alias.new("", old_name, new_name, "")
|
||||
al = RDoc::Alias.new '', old_name, new_name, ''
|
||||
al.singleton = @singleton_classes.key?(var_name)
|
||||
|
||||
@stats.add_alias as
|
||||
comment = find_alias_comment var_name, new_name, old_name
|
||||
comment = strip_stars comment
|
||||
al.comment = comment
|
||||
|
||||
class_obj.add_alias al
|
||||
@stats.add_alias al
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Scans #content for rb_attr and rb_define_attr
|
||||
|
||||
def do_attrs
|
||||
@content.scan(/rb_attr\s*\(
|
||||
\s*(\w+),
|
||||
\s*([\w"()]+),
|
||||
\s*([01]),
|
||||
\s*([01]),
|
||||
\s*\w+\);/xm) do |var_name, attr_name, read, write|
|
||||
handle_attr var_name, attr_name, read, write
|
||||
end
|
||||
|
||||
@content.scan(%r%rb_define_attr\(
|
||||
\s*([\w\.]+),
|
||||
\s*"([^"]+)",
|
||||
\s*(\d+),
|
||||
\s*(\d+)\s*\);
|
||||
%xm) do |var_name, attr_name, read, write|
|
||||
handle_attr var_name, attr_name, read, write
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Scans #content for rb_define_module, rb_define_class, boot_defclass,
|
||||
# rb_define_module_under, rb_define_class_under and rb_singleton_class
|
||||
|
||||
def do_classes
|
||||
@content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
|
||||
|var_name, class_name|
|
||||
|
@ -165,35 +218,44 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
end
|
||||
|
||||
@content.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s*
|
||||
\(
|
||||
\s*(\w+),
|
||||
\s*"(\w+)",
|
||||
\s*([\w\*\s\(\)\.\->]+)\s* # for SWIG
|
||||
\s*\)/mx) do |var_name, in_module, class_name, parent|
|
||||
\(
|
||||
\s*(\w+),
|
||||
\s*"(\w+)",
|
||||
\s*([\w\*\s\(\)\.\->]+)\s* # for SWIG
|
||||
\s*\)/mx) do |var_name, in_module, class_name, parent|
|
||||
handle_class_module(var_name, "class", class_name, parent, in_module)
|
||||
end
|
||||
|
||||
@content.scan(/([\w\.]+)\s* = \s*rb_singleton_class\s*
|
||||
\(
|
||||
\s*(\w+)
|
||||
\s*\)/mx) do |sclass_var, class_var|
|
||||
handle_singleton sclass_var, class_var
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Scans #content for rb_define_variable, rb_define_readonly_variable,
|
||||
# rb_define_const and rb_define_global_const
|
||||
|
||||
def do_constants
|
||||
@content.scan(%r{\Wrb_define_
|
||||
@content.scan(%r%\Wrb_define_
|
||||
( variable |
|
||||
readonly_variable |
|
||||
const |
|
||||
global_const | )
|
||||
global_const )
|
||||
\s*\(
|
||||
(?:\s*(\w+),)?
|
||||
\s*"(\w+)",
|
||||
\s*(.*?)\s*\)\s*;
|
||||
}xm) do |type, var_name, const_name, definition|
|
||||
%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);
|
||||
# Scans #content for rb_include_module
|
||||
|
||||
def do_includes
|
||||
@content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
|
||||
|
@ -204,8 +266,13 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Scans #content for rb_define_method, rb_define_singleton_method,
|
||||
# rb_define_module_function, rb_define_private_method,
|
||||
# rb_define_global_function and define_filetest_function
|
||||
|
||||
def do_methods
|
||||
@content.scan(%r{rb_define_
|
||||
@content.scan(%r%rb_define_
|
||||
(
|
||||
singleton_method |
|
||||
method |
|
||||
|
@ -217,8 +284,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
\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|
|
||||
%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"
|
||||
|
@ -231,44 +297,69 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
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*\(
|
||||
@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|
|
||||
%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|
|
||||
\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
|
||||
##
|
||||
# Finds the comment for an alias on +class_name+ from +new_name+ to
|
||||
# +old_name+
|
||||
|
||||
def find_alias_comment class_name, new_name, old_name
|
||||
content =~ %r%((?>/\*.*?\*/\s+))
|
||||
rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
|
||||
\s*"#{Regexp.escape new_name}"\s*,
|
||||
\s*"#{Regexp.escape old_name}"\s*\);%xm
|
||||
|
||||
$1 || ''
|
||||
end
|
||||
|
||||
##
|
||||
# Finds a comment for rb_define_attr, rb_attr or Document-attr.
|
||||
#
|
||||
# +var_name+ is the C class variable the attribute is defined on.
|
||||
# +attr_name+ is the attribute's name.
|
||||
#
|
||||
# +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
|
||||
# neither must be provided.
|
||||
|
||||
def find_attr_comment var_name, attr_name, read = nil, write = nil
|
||||
attr_name = Regexp.escape attr_name
|
||||
|
||||
rw = if read and write then
|
||||
/\s*#{read}\s*,\s*#{write}\s*/xm
|
||||
else
|
||||
/.*?/m
|
||||
end
|
||||
|
||||
if @content =~ %r%((?>/\*.*?\*/\s+))
|
||||
rb_define_attr\((?:\s*#{var_name},)?\s*
|
||||
"#{attr_name}"\s*,
|
||||
#{rw}\)\s*;%xm then
|
||||
$1
|
||||
elsif @content =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m
|
||||
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
||||
rb_attr\(\s*#{var_name}\s*,
|
||||
\s*#{attr_name}\s*,
|
||||
#{rw},.*?\)\s*;%xm then
|
||||
$1
|
||||
elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n
|
||||
((?>.*?\*/))%xm then
|
||||
$1
|
||||
else
|
||||
''
|
||||
|
@ -280,8 +371,10 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
|
||||
def find_body(class_name, meth_name, meth_obj, body, quiet = false)
|
||||
case body
|
||||
when %r"((?>/\*.*?\*/\s*))((?:(?:static|SWIGINTERN)\s+)?(?:intern\s+)?VALUE\s+#{meth_name}
|
||||
\s*(\([^)]*\))([^;]|$))"xm
|
||||
when %r%((?>/\*.*?\*/\s*))
|
||||
((?:(?:static|SWIGINTERN)\s+)?
|
||||
(?:intern\s+)?VALUE\s+#{meth_name}
|
||||
\s*(\([^)]*\))([^;]|$))%xm then
|
||||
comment = $1
|
||||
body_text = $2
|
||||
|
||||
|
@ -303,12 +396,13 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
|
||||
find_modifiers comment, meth_obj if comment
|
||||
|
||||
#meth_obj.params = params
|
||||
meth_obj.start_collecting_tokens
|
||||
tk = RDoc::RubyToken::Token.new nil, 1, 1
|
||||
tk.set_text body_text
|
||||
meth_obj.add_token tk
|
||||
meth_obj.comment = strip_stars comment
|
||||
when %r{((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))}m
|
||||
when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m
|
||||
comment = $1
|
||||
body_text = $2
|
||||
find_body class_name, $3, meth_obj, body, true
|
||||
|
@ -319,26 +413,29 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
tk.set_text body_text
|
||||
meth_obj.add_token tk
|
||||
meth_obj.comment = strip_stars(comment) + meth_obj.comment.to_s
|
||||
when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m
|
||||
when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m
|
||||
unless find_body(class_name, $1, meth_obj, body, true)
|
||||
warn "No definition for #{meth_name}" unless @options.quiet
|
||||
warn "No definition for #{meth_name}" if @options.verbosity > 1
|
||||
return false
|
||||
end
|
||||
else
|
||||
# No body, but might still have an override comment
|
||||
comment = find_override_comment(class_name, meth_obj.name)
|
||||
else # No body, but might still have an override comment
|
||||
comment = find_override_comment class_name, meth_obj.name
|
||||
|
||||
if comment
|
||||
find_modifiers(comment, meth_obj)
|
||||
find_modifiers comment, meth_obj
|
||||
meth_obj.comment = strip_stars comment
|
||||
else
|
||||
warn "No definition for #{meth_name}" unless @options.quiet
|
||||
warn "No definition for #{meth_name}" if @options.verbosity > 1
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+
|
||||
|
||||
def find_class(raw_name, name)
|
||||
unless @classes[raw_name]
|
||||
if raw_name =~ /^rb_m/
|
||||
|
@ -382,16 +479,17 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
def find_class_comment(class_name, class_mod)
|
||||
comment = nil
|
||||
|
||||
if @content =~ %r{
|
||||
if @content =~ %r%
|
||||
((?>/\*.*?\*/\s+))
|
||||
(static\s+)?
|
||||
void\s+
|
||||
Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)}xmi then # )
|
||||
Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xmi then
|
||||
comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
|
||||
elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
|
||||
(?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
|
||||
comment = $1
|
||||
elsif @content =~ %r{Document-(?:class|module):\s+#{class_name}\s*?(?:<\s+[:,\w]+)?\n((?>.*?\*/))}m then
|
||||
comment = $1
|
||||
elsif @content =~ %r{((?>/\*.*?\*/\s+))
|
||||
([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"}xm then # "
|
||||
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
||||
([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"%xm then
|
||||
comment = $1
|
||||
end
|
||||
|
||||
|
@ -409,10 +507,13 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
# 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
|
||||
if @content =~ %r%((?>^\s*/\*.*?\*/\s+))
|
||||
rb_define_#{type}\((?:\s*(\w+),)?\s*
|
||||
"#{const_name}"\s*,
|
||||
.*?\)\s*;%xmi then
|
||||
$1
|
||||
elsif @content =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m
|
||||
elsif @content =~ %r%Document-(?:const|global|variable):\s#{const_name}
|
||||
\s*?\n((?>.*?\*/))%xm
|
||||
$1
|
||||
else
|
||||
''
|
||||
|
@ -420,56 +521,111 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
end
|
||||
|
||||
##
|
||||
# If the comment block contains a section that looks like:
|
||||
# Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
|
||||
#
|
||||
# call-seq:
|
||||
# Array.new
|
||||
# Array.new(10)
|
||||
# If <tt>:nodoc:</tt> is found, documentation on +meth_obj+ is suppressed.
|
||||
#
|
||||
# use it for the parameters.
|
||||
# If <tt>:yields:</tt> is followed by an argument list it is used for the
|
||||
# #block_params of +meth_obj+.
|
||||
#
|
||||
# If the comment block contains a <tt>call-seq:</tt> section like:
|
||||
#
|
||||
# call-seq:
|
||||
# ARGF.readlines(sep=$/) -> array
|
||||
# ARGF.readlines(limit) -> array
|
||||
# ARGF.readlines(sep, limit) -> array
|
||||
#
|
||||
# ARGF.to_a(sep=$/) -> array
|
||||
# ARGF.to_a(limit) -> array
|
||||
# ARGF.to_a(sep, limit) -> array
|
||||
#
|
||||
# it is used for the parameters of +meth_obj+.
|
||||
|
||||
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*/, '')
|
||||
def find_modifiers comment, meth_obj
|
||||
# we must handle situations like the above followed by an unindented first
|
||||
# comment. The difficulty is to make sure not to match lines starting
|
||||
# with ARGF at the same indent, but that are after the first description
|
||||
# paragraph.
|
||||
|
||||
if comment =~ /call-seq:(.*?[^\s\*].*?)^\s*\*?\s*$/m then
|
||||
all_start, all_stop = $~.offset(0)
|
||||
seq_start, seq_stop = $~.offset(1)
|
||||
|
||||
# we get the following lines that start with the leading word at the
|
||||
# same indent, even if they have blank lines before
|
||||
if $1 =~ /(^\s*\*?\s*\n)+^(\s*\*?\s*\w+)/m then
|
||||
leading = $2 # ' * ARGF' in the example above
|
||||
re = %r%
|
||||
\A(
|
||||
(^\s*\*?\s*\n)+
|
||||
(^#{Regexp.escape leading}.*?\n)+
|
||||
)+
|
||||
^\s*\*?\s*$
|
||||
%xm
|
||||
if comment[seq_stop..-1] =~ re then
|
||||
all_stop = seq_stop + $~.offset(0).last
|
||||
seq_stop = seq_stop + $~.offset(1).last
|
||||
end
|
||||
end
|
||||
|
||||
seq = comment[seq_start..seq_stop]
|
||||
seq.gsub!(/^(\s*\*?\s*?)(\S|\n)/m, '\2')
|
||||
comment.slice! all_start...all_stop
|
||||
meth_obj.call_seq = seq
|
||||
elsif comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') then
|
||||
meth_obj.call_seq = $1.strip
|
||||
end
|
||||
|
||||
if comment.sub!(/\s*:(nodoc|doc|yields?|args?):\s*(.*)/, '') then
|
||||
RDoc::Parser.process_directive meth_obj, $1, $2
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Finds a <tt>Document-method</tt> override for +meth_name+ in +class_name+
|
||||
|
||||
def find_override_comment(class_name, meth_name)
|
||||
name = Regexp.escape(meth_name)
|
||||
if @content =~ %r{Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))}m then
|
||||
|
||||
if @content =~ %r%Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))%m then
|
||||
$1
|
||||
elsif @content =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m then
|
||||
elsif @content =~ %r%Document-method:\s#{name}\s*?\n((?>.*?\*/))%m then
|
||||
$1
|
||||
end
|
||||
end
|
||||
|
||||
def handle_attr(var_name, attr_name, reader, writer)
|
||||
##
|
||||
# Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
|
||||
# +read+, +write+ or both
|
||||
|
||||
def handle_attr(var_name, attr_name, read, write)
|
||||
rw = ''
|
||||
rw << 'R' if reader
|
||||
rw << 'W' if writer
|
||||
rw << 'R' if '1' == read
|
||||
rw << 'W' if '1' == write
|
||||
|
||||
class_name = @known_classes[var_name]
|
||||
|
||||
return unless class_name
|
||||
|
||||
class_obj = find_class(var_name, class_name)
|
||||
class_obj = find_class var_name, class_name
|
||||
|
||||
if class_obj
|
||||
comment = find_attr_comment(attr_name)
|
||||
comment = strip_stars comment
|
||||
att = RDoc::Attr.new '', attr_name, rw, comment
|
||||
@stats.add_method att
|
||||
class_obj.add_attribute(att)
|
||||
end
|
||||
return unless class_obj
|
||||
|
||||
comment = find_attr_comment var_name, attr_name
|
||||
comment = strip_stars comment
|
||||
|
||||
name = attr_name.gsub(/rb_intern\("([^"]+)"\)/, '\1')
|
||||
|
||||
attr = RDoc::Attr.new '', name, rw, comment
|
||||
|
||||
class_obj.add_attribute attr
|
||||
@stats.add_attribute attr
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
|
||||
# named +class_name+ in +parent+ which was assigned to the C +var_name+.
|
||||
|
||||
def handle_class_module(var_name, type, class_name, parent, in_module)
|
||||
parent_name = @known_classes[parent] || parent
|
||||
|
||||
|
@ -497,7 +653,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
class_name
|
||||
end
|
||||
|
||||
if @content =~ %r{Document-class:\s+#{full_name}\s*<\s+([:,\w]+)} then
|
||||
if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then
|
||||
parent_name = $1
|
||||
end
|
||||
|
||||
|
@ -519,15 +675,14 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
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.
|
||||
# Adds constants. By providing some_value: at the start of the 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 (\:).
|
||||
# Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
|
||||
# RDoc. Values may include quotes and escaped colons (\:).
|
||||
|
||||
def handle_constants(type, var_name, const_name, definition)
|
||||
class_name = @known_classes[var_name]
|
||||
|
@ -588,22 +743,35 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
|
||||
end
|
||||
|
||||
##
|
||||
# Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
|
||||
# to +var_name+. +type+ is the type of method definition function used.
|
||||
# +singleton_method+ and +module_function+ create a singleton method.
|
||||
|
||||
def handle_method(type, var_name, meth_name, meth_body, param_count,
|
||||
source_file = nil)
|
||||
singleton = false
|
||||
class_name = @known_classes[var_name]
|
||||
|
||||
unless class_name then
|
||||
class_name = @singleton_classes[var_name]
|
||||
singleton = true if class_name
|
||||
end
|
||||
|
||||
return unless class_name
|
||||
|
||||
class_obj = find_class var_name, class_name
|
||||
|
||||
if class_obj then
|
||||
if meth_name == "initialize" then
|
||||
meth_name = "new"
|
||||
type = "singleton_method"
|
||||
if meth_name == 'initialize' then
|
||||
meth_name = 'new'
|
||||
singleton = true
|
||||
type = 'method' # force public
|
||||
end
|
||||
|
||||
meth_obj = RDoc::AnyMethod.new '', meth_name
|
||||
meth_obj.singleton = %w[singleton_method module_function].include? type
|
||||
meth_obj.singleton =
|
||||
singleton || %w[singleton_method module_function].include?(type)
|
||||
|
||||
p_count = Integer(param_count) rescue -1
|
||||
|
||||
|
@ -627,7 +795,8 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
body = @content
|
||||
end
|
||||
|
||||
if find_body(class_name, meth_body, meth_obj, body) and meth_obj.document_self then
|
||||
if find_body(class_name, meth_body, meth_obj, body) and
|
||||
meth_obj.document_self then
|
||||
class_obj.add_method meth_obj
|
||||
@stats.add_method meth_obj
|
||||
meth_obj.visibility = :private if 'private_method' == type
|
||||
|
@ -635,13 +804,27 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Registers a singleton class +sclass_var+ as a singleton of +class_var+
|
||||
|
||||
def handle_singleton sclass_var, class_var
|
||||
class_name = @known_classes[class_var]
|
||||
|
||||
@singleton_classes[sclass_var] = class_name
|
||||
end
|
||||
|
||||
##
|
||||
# Normalizes tabs in +body+
|
||||
|
||||
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)} && $~ #`
|
||||
1 while line.gsub!(/\t+/) do
|
||||
' ' * (tab_width * $&.length - $`.length % tab_width)
|
||||
end && $~
|
||||
line
|
||||
end .join("\n")
|
||||
end.join "\n"
|
||||
else
|
||||
body
|
||||
end
|
||||
|
@ -654,7 +837,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
# * :title: My Awesome Project
|
||||
# */
|
||||
#
|
||||
# This routine modifies it's parameter
|
||||
# This routine modifies its parameter
|
||||
|
||||
def look_for_directives_in(context, comment)
|
||||
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
|
@ -665,29 +848,33 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
@options.main_page = param
|
||||
''
|
||||
when 'title' then
|
||||
@options.title = param
|
||||
@options.default_title = param if @options.respond_to? :default_title=
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
comment
|
||||
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_}, '//')
|
||||
@content.gsub!(%r%//.*rb_define_%, '//')
|
||||
end
|
||||
|
||||
##
|
||||
# Removes private comments from +comment+
|
||||
|
||||
def remove_private_comments(comment)
|
||||
comment.gsub!(/\/?\*--\n(.*?)\/?\*\+\+/m, '')
|
||||
comment.sub!(/\/?\*--\n.*/m, '')
|
||||
end
|
||||
|
||||
##
|
||||
# Extract the classes/modules and methods from a C file and return the
|
||||
# corresponding top-level object
|
||||
# Extracts the classes, modules, methods, attributes, constants and aliases
|
||||
# from a C file and returns an RDoc::TopLevel for this file
|
||||
|
||||
def scan
|
||||
remove_commented_out_lines
|
||||
|
@ -696,6 +883,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
do_methods
|
||||
do_includes
|
||||
do_aliases
|
||||
do_attrs
|
||||
@top_level
|
||||
end
|
||||
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
require 'rdoc/parser'
|
||||
|
||||
##
|
||||
#
|
||||
# This is an attamept to write a basic parser for Perl's
|
||||
# POD (Plain old Documentation) format. Ruby code must
|
||||
# co-exist with Perl, and some tasks are easier in Perl
|
||||
# than Ruby because of existing libraries.
|
||||
#
|
||||
# One difficult is that Perl POD has no means of identifying
|
||||
# the classes (packages) and methods (subs) with which it
|
||||
# is associated, it is more like literate programming in so
|
||||
# far as it just happens to be in the same place as the code,
|
||||
# but need not be.
|
||||
#
|
||||
# We would like to support all the markup the POD provides
|
||||
# so that it will convert happily to HTML. At the moment
|
||||
# I don't think I can do that: time constraints.
|
||||
#
|
||||
|
||||
class RDoc::Parser::PerlPOD < RDoc::Parser
|
||||
|
||||
parse_files_matching(/.p[lm]$/)
|
||||
|
||||
##
|
||||
# Prepare to parse a perl 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 Pod(-like) comments from the code.
|
||||
# At its most basic there will ne no need to distinguish
|
||||
# between the different types of header, etc.
|
||||
#
|
||||
# This uses a simple finite state machine, in a very
|
||||
# procedural pattern. I could "replace case with polymorphism"
|
||||
# but I think it would obscure the intent, scatter the
|
||||
# code all over tha place. This machine is necessary
|
||||
# because POD requires that directives be preceded by
|
||||
# blank lines, so reading line by line is necessary,
|
||||
# and preserving state about what is seen is necesary.
|
||||
|
||||
def scan
|
||||
|
||||
@top_level.comment ||= ""
|
||||
state=:code_blank
|
||||
line_number = 0
|
||||
line = nil
|
||||
|
||||
# This started out as a really long nested case statement,
|
||||
# which also led to repetitive code. I'd like to avoid that
|
||||
# so I'm using a "table" instead.
|
||||
|
||||
# Firstly we need some procs to do the transition and processing
|
||||
# work. Because these are procs they are closures, and they can
|
||||
# use variables in the local scope.
|
||||
#
|
||||
# First, the "nothing to see here" stuff.
|
||||
code_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :code_blank
|
||||
end
|
||||
end
|
||||
|
||||
pod_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :pod_blank
|
||||
end
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
begin_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :begin_blank
|
||||
end
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
# Now for the blocks that process code and comments...
|
||||
|
||||
transit_to_pod = lambda do
|
||||
case line
|
||||
when /^=(?:pod|head\d+)/
|
||||
state = :pod_no_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=over/
|
||||
state = :over_no_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=(?:begin|for)/
|
||||
state = :begin_no_blank
|
||||
end
|
||||
end
|
||||
|
||||
process_pod = lambda do
|
||||
case line
|
||||
when /^\s*$/
|
||||
state = :pod_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=cut/
|
||||
state = :code_no_blank
|
||||
when /^=end/
|
||||
$stderr.puts "'=end' unexpected at #{line_number} in #{@file_name}"
|
||||
else
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
process_begin = lambda do
|
||||
case line
|
||||
when /^\s*$/
|
||||
state = :begin_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=end/
|
||||
state = :code_no_blank
|
||||
when /^=cut/
|
||||
$stderr.puts "'=cut' unexpected at #{line_number} in #{@file_name}"
|
||||
else
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
transitions = { :code_no_blank => code_noop,
|
||||
:code_blank => transit_to_pod,
|
||||
:pod_no_blank => pod_noop,
|
||||
:pod_blank => process_pod,
|
||||
:begin_no_blank => begin_noop,
|
||||
:begin_blank => process_begin}
|
||||
@content.each_line do |l|
|
||||
line = l
|
||||
line_number += 1
|
||||
transitions[state].call
|
||||
end # each line
|
||||
|
||||
@top_level
|
||||
end
|
||||
|
||||
# Filter the perl markup that does the same as the rdoc
|
||||
# filtering. Only basic for now. Will probably need a
|
||||
# proper parser to cope with C<<...>> etc
|
||||
def filter(comment)
|
||||
return '' if comment =~ /^=pod\s*$/
|
||||
comment.gsub!(/^=pod/, '==')
|
||||
comment.gsub!(/^=head(\d+)/) do
|
||||
"=" * $1.to_i
|
||||
end
|
||||
comment.gsub!(/=item/, '');
|
||||
comment.gsub!(/C<(.*?)>/, '<tt>\1</tt>');
|
||||
comment.gsub!(/I<(.*?)>/, '<i>\1</i>');
|
||||
comment.gsub!(/B<(.*?)>/, '<b>\1</b>');
|
||||
comment
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -11,8 +11,8 @@ require 'rdoc/ruby_token'
|
|||
require 'rdoc/ruby_lex'
|
||||
|
||||
require 'rdoc/code_objects'
|
||||
require 'rdoc/tokenstream'
|
||||
require 'rdoc/markup/preprocess'
|
||||
require 'rdoc/token_stream'
|
||||
require 'rdoc/markup/pre_process'
|
||||
require 'rdoc/parser'
|
||||
require 'rdoc/parser/ruby_tools'
|
||||
|
||||
|
@ -162,6 +162,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
SINGLE = "<<"
|
||||
|
||||
##
|
||||
# Creates a new Ruby parser.
|
||||
|
||||
def initialize(top_level, file_name, content, options, stats)
|
||||
super
|
||||
|
||||
|
@ -209,10 +212,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
comment
|
||||
end
|
||||
|
||||
##
|
||||
# Aborts with +msg+
|
||||
|
||||
def error(msg)
|
||||
msg = make_message msg
|
||||
$stderr.puts msg
|
||||
exit false
|
||||
|
||||
abort msg
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -229,6 +235,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
meth
|
||||
end
|
||||
|
||||
##
|
||||
# Looks for a true or false token. Returns false if TkFALSE or TkNIL are
|
||||
# found.
|
||||
|
||||
def get_bool
|
||||
skip_tkspace
|
||||
tk = get_tk
|
||||
|
@ -245,20 +255,24 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
##
|
||||
# Look for the name of a class of module (optionally with a leading :: or
|
||||
# with :: separated named) and return the ultimate name and container
|
||||
# with :: separated named) and return the ultimate name, the associated
|
||||
# container, and the given name (with the ::).
|
||||
|
||||
def get_class_or_module(container)
|
||||
skip_tkspace
|
||||
name_t = get_tk
|
||||
given_name = ''
|
||||
|
||||
# class ::A -> A is in the top level
|
||||
case name_t
|
||||
when TkCOLON2, TkCOLON3 then # bug
|
||||
name_t = get_tk
|
||||
container = @top_level
|
||||
given_name << '::'
|
||||
end
|
||||
|
||||
skip_tkspace false
|
||||
given_name << name_t.name
|
||||
|
||||
while TkCOLON2 === peek_tk do
|
||||
prev_container = container
|
||||
|
@ -268,9 +282,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
get_tk
|
||||
name_t = get_tk
|
||||
given_name << '::' << name_t.name
|
||||
end
|
||||
skip_tkspace false
|
||||
return [container, name_t]
|
||||
return [container, name_t, given_name]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -347,6 +362,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
name
|
||||
end
|
||||
|
||||
##
|
||||
# Extracts a name or symbol from the token stream.
|
||||
|
||||
def get_symbol_or_name
|
||||
tk = get_tk
|
||||
case tk
|
||||
|
@ -361,7 +379,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
text
|
||||
when TkId, TkOp then
|
||||
tk.name
|
||||
when TkSTRING, TkDSTRING then
|
||||
when TkAMPER,
|
||||
TkDSTRING,
|
||||
TkSTAR,
|
||||
TkSTRING then
|
||||
tk.text
|
||||
else
|
||||
raise RDoc::Error, "Name or symbol expected (got #{tk})"
|
||||
|
@ -374,7 +395,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
# # :stopdoc:
|
||||
# # Don't display comment from this point forward
|
||||
#
|
||||
# This routine modifies it's parameter
|
||||
# This routine modifies its +comment+ parameter.
|
||||
|
||||
def look_for_directives_in(context, comment)
|
||||
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
|
@ -382,9 +403,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
preprocess.handle comment, context do |directive, param|
|
||||
case directive
|
||||
when 'enddoc' then
|
||||
throw :enddoc
|
||||
context.done_documenting = true
|
||||
''
|
||||
when 'main' then
|
||||
@options.main_page = param
|
||||
@options.main_page = param if @options.respond_to? :main_page
|
||||
''
|
||||
when 'method', 'singleton-method',
|
||||
'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
|
||||
|
@ -401,7 +423,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
context.stop_doc
|
||||
''
|
||||
when 'title' then
|
||||
@options.title = param
|
||||
@options.default_title = param if @options.respond_to? :default_title=
|
||||
''
|
||||
end
|
||||
end
|
||||
|
@ -426,23 +448,28 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
def parse_attr(context, single, tk, comment)
|
||||
args = parse_symbol_arg 1
|
||||
if args.size > 0
|
||||
if args.size > 0 then
|
||||
name = args[0]
|
||||
rw = "R"
|
||||
skip_tkspace false
|
||||
tk = get_tk
|
||||
|
||||
if TkCOMMA === tk then
|
||||
rw = "RW" if get_bool
|
||||
else
|
||||
unget_tk tk
|
||||
end
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment
|
||||
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE
|
||||
att.record_location @top_level
|
||||
|
||||
read_documentation_modifiers att, RDoc::ATTR_MODIFIERS
|
||||
if att.document_self
|
||||
context.add_attribute(att)
|
||||
end
|
||||
|
||||
context.add_attribute att if att.document_self
|
||||
|
||||
@stats.add_attribute att
|
||||
else
|
||||
warn("'attr' ignored - looks like a variable")
|
||||
warn "'attr' ignored - looks like a variable"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -452,12 +479,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
def parse_attr_accessor(context, single, tk, comment)
|
||||
args = parse_symbol_arg
|
||||
get_tkread
|
||||
|
||||
rw = "?"
|
||||
|
||||
# TODO If nodoc is given, don't document any of them
|
||||
|
||||
tmp = RDoc::CodeObject.new
|
||||
read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
|
||||
return unless tmp.document_self
|
||||
|
@ -471,17 +494,25 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
|
||||
for name in args
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE
|
||||
att.record_location @top_level
|
||||
|
||||
context.add_attribute att
|
||||
@stats.add_attribute att
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parses an +alias+ in +context+ with +comment+
|
||||
|
||||
def parse_alias(context, single, tk, comment)
|
||||
skip_tkspace
|
||||
|
||||
if TkLPAREN === peek_tk then
|
||||
get_tk
|
||||
skip_tkspace
|
||||
end
|
||||
|
||||
new_name = get_symbol_or_name
|
||||
|
||||
@scanner.instance_eval { @lex_state = EXPR_FNAME }
|
||||
|
@ -498,11 +529,20 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
return
|
||||
end
|
||||
|
||||
al = RDoc::Alias.new get_tkread, old_name, new_name, comment
|
||||
al = RDoc::Alias.new(get_tkread, old_name, new_name, comment,
|
||||
single == SINGLE)
|
||||
al.record_location @top_level
|
||||
|
||||
read_documentation_modifiers al, RDoc::ATTR_MODIFIERS
|
||||
context.add_alias al if al.document_self
|
||||
@stats.add_alias al
|
||||
|
||||
al
|
||||
end
|
||||
|
||||
##
|
||||
# Extracts call parameters from the token stream.
|
||||
|
||||
def parse_call_parameters(tk)
|
||||
end_token = case tk
|
||||
when TkLPAREN, TkfLPAREN
|
||||
|
@ -540,28 +580,33 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
res
|
||||
end
|
||||
|
||||
##
|
||||
# Parses a class in +context+ with +comment+
|
||||
|
||||
def parse_class(container, single, tk, comment)
|
||||
container, name_t = get_class_or_module container
|
||||
declaration_context = container
|
||||
container, name_t, given_name = get_class_or_module container
|
||||
|
||||
case name_t
|
||||
when TkCONSTANT
|
||||
name = name_t.name
|
||||
superclass = "Object"
|
||||
superclass = '::Object'
|
||||
|
||||
if TkLT === peek_tk then
|
||||
get_tk
|
||||
skip_tkspace
|
||||
superclass = get_class_specification
|
||||
superclass = "<unknown>" if superclass.empty?
|
||||
superclass = '(unknown)' if superclass.empty?
|
||||
end
|
||||
|
||||
cls_type = single == SINGLE ? RDoc::SingleClass : RDoc::NormalClass
|
||||
cls = container.add_class cls_type, name, superclass
|
||||
cls = declaration_context.add_class cls_type, given_name, superclass
|
||||
|
||||
read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
|
||||
cls.record_location @top_level
|
||||
cls.comment = comment
|
||||
cls.comment = comment if cls.document_self
|
||||
|
||||
@top_level.add_to_classes_or_modules cls
|
||||
@stats.add_class cls
|
||||
|
||||
parse_statements cls
|
||||
|
@ -569,7 +614,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
case name = get_class_specification
|
||||
when "self", container.name
|
||||
parse_statements container, SINGLE
|
||||
when /\A[A-Z]/
|
||||
else
|
||||
other = RDoc::TopLevel.find_class_named name
|
||||
|
||||
unless other then
|
||||
|
@ -578,6 +623,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
other.comment = comment
|
||||
end
|
||||
|
||||
# notify :nodoc: all if not a constant-named class/module
|
||||
# (and remove any comment)
|
||||
unless name =~ /\A(::)?[A-Z]/
|
||||
other.document_self = nil
|
||||
other.document_children = false
|
||||
other.clear_comment
|
||||
end
|
||||
|
||||
@top_level.add_to_classes_or_modules other
|
||||
@stats.add_class other
|
||||
|
||||
read_documentation_modifiers other, RDoc::CLASS_MODIFIERS
|
||||
|
@ -589,9 +643,15 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parses a constant in +context+ with +comment+
|
||||
|
||||
def parse_constant(container, tk, comment)
|
||||
name = tk.name
|
||||
skip_tkspace false
|
||||
|
||||
return unless name =~ /^\w+$/
|
||||
|
||||
eq_tk = get_tk
|
||||
|
||||
unless TkASSIGN === eq_tk then
|
||||
|
@ -615,9 +675,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
loop do
|
||||
case tk
|
||||
when TkSEMICOLON then
|
||||
break
|
||||
when TkLPAREN, TkfLPAREN, TkLBRACE, TkLBRACK, TkDO, TkIF, TkUNLESS,
|
||||
TkCASE then
|
||||
break if nest <= 0
|
||||
when TkLPAREN, TkfLPAREN, TkLBRACE, TkfLBRACE, TkLBRACK, TkfLBRACK,
|
||||
TkDO, TkIF, TkUNLESS, TkCASE, TkDEF, TkBEGIN then
|
||||
nest += 1
|
||||
when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then
|
||||
nest -= 1
|
||||
|
@ -654,10 +714,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
tk = get_tk
|
||||
end
|
||||
|
||||
res = get_tkread.tr("\n", " ").strip
|
||||
res = get_tkread.gsub(/^[ \t]+/, '').strip
|
||||
res = "" if res == ";"
|
||||
|
||||
con = RDoc::Constant.new name, res, comment
|
||||
con.record_location @top_level
|
||||
read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
|
||||
|
||||
@stats.add_constant con
|
||||
|
@ -679,6 +740,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
name = $1 unless $1.empty?
|
||||
|
||||
meth = RDoc::GhostMethod.new get_tkread, name
|
||||
meth.record_location @top_level
|
||||
meth.singleton = singleton
|
||||
|
||||
meth.start_collecting_tokens
|
||||
|
@ -709,13 +771,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
name = $3 unless $3.empty?
|
||||
|
||||
# TODO authorize 'singleton-attr...'?
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment
|
||||
att.record_location @top_level
|
||||
|
||||
container.add_attribute att
|
||||
|
||||
@stats.add_method att
|
||||
@stats.add_attribute att
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parses an +include+ in +context+ with +comment+
|
||||
|
||||
def parse_include(context, comment)
|
||||
loop do
|
||||
skip_tkspace_comment
|
||||
|
@ -759,8 +827,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
def parse_meta_attr(context, single, tk, comment)
|
||||
args = parse_symbol_arg
|
||||
get_tkread
|
||||
|
||||
rw = "?"
|
||||
|
||||
# If nodoc is given, don't document any of them
|
||||
|
@ -779,12 +845,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
|
||||
if name then
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment
|
||||
att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE
|
||||
att.record_location @top_level
|
||||
|
||||
context.add_attribute att
|
||||
@stats.add_attribute att
|
||||
else
|
||||
args.each do |attr_name|
|
||||
att = RDoc::Attr.new get_tkread, attr_name, rw, comment
|
||||
att = RDoc::Attr.new(get_tkread, attr_name, rw, comment,
|
||||
single == SINGLE)
|
||||
att.record_location @top_level
|
||||
|
||||
context.add_attribute att
|
||||
@stats.add_attribute att
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -825,6 +898,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
|
||||
meth = RDoc::MetaMethod.new get_tkread, name
|
||||
meth.record_location @top_level
|
||||
meth.singleton = singleton
|
||||
|
||||
remove_token_listener self
|
||||
|
@ -882,7 +956,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
token_listener self do
|
||||
@scanner.instance_eval do @lex_state = EXPR_FNAME end
|
||||
|
||||
skip_tkspace false
|
||||
skip_tkspace
|
||||
name_t = get_tk
|
||||
back_tk = skip_tkspace
|
||||
meth = nil
|
||||
|
@ -922,11 +996,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
container.record_location @top_level
|
||||
end
|
||||
when TkIDENTIFIER, TkIVAR then
|
||||
when TkIDENTIFIER, TkIVAR, TkGVAR then
|
||||
dummy = RDoc::Context.new
|
||||
dummy.parent = container
|
||||
skip_method dummy
|
||||
return
|
||||
when TkTRUE, TkFALSE, TkNIL then
|
||||
klass_name = "#{name_t.name.capitalize}Class"
|
||||
container = RDoc::TopLevel.find_class_named klass_name
|
||||
container ||= @top_level.add_class RDoc::NormalClass, klass_name
|
||||
|
||||
name = name_t2.name
|
||||
else
|
||||
warn "unexpected method name token #{name_t.inspect}"
|
||||
# break
|
||||
|
@ -959,6 +1039,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
meth.record_location @top_level
|
||||
|
||||
meth.start_collecting_tokens
|
||||
indent = TkSPACE.new nil, 1, 1
|
||||
indent.set_text " " * column
|
||||
|
@ -1001,6 +1083,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
@stats.add_method meth
|
||||
end
|
||||
|
||||
##
|
||||
# Extracts +yield+ parameters from +method+
|
||||
|
||||
def parse_method_or_yield_parameters(method = nil,
|
||||
modifiers = RDoc::METHOD_MODIFIERS)
|
||||
skip_tkspace false
|
||||
|
@ -1024,14 +1109,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
loop do
|
||||
case tk
|
||||
when TkSEMICOLON then
|
||||
break
|
||||
when TkLBRACE then
|
||||
break if nest == 0
|
||||
when TkLBRACE, TkfLBRACE then
|
||||
nest += 1
|
||||
when TkRBRACE then
|
||||
# we might have a.each {|i| yield i }
|
||||
unget_tk(tk) if nest.zero?
|
||||
nest -= 1
|
||||
break if nest <= 0
|
||||
if nest <= 0
|
||||
# we might have a.each { |i| yield i }
|
||||
unget_tk(tk) if nest < 0
|
||||
break
|
||||
end
|
||||
when TkLPAREN, TkfLPAREN then
|
||||
nest += 1
|
||||
when end_token then
|
||||
|
@ -1041,6 +1128,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
else
|
||||
break unless @scanner.continue
|
||||
end
|
||||
when TkRPAREN then
|
||||
nest -= 1
|
||||
when method && method.block_params.nil? && TkCOMMENT then
|
||||
unget_tk tk
|
||||
read_documentation_modifiers method, modifiers
|
||||
|
@ -1078,8 +1167,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parses an RDoc::NormalModule in +container+ with +comment+
|
||||
|
||||
def parse_module(container, single, tk, comment)
|
||||
container, name_t = get_class_or_module container
|
||||
container, name_t, = get_class_or_module container
|
||||
|
||||
name = name_t.name
|
||||
|
||||
|
@ -1087,12 +1179,16 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
mod.record_location @top_level
|
||||
|
||||
read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS
|
||||
mod.comment = comment if mod.document_self
|
||||
parse_statements(mod)
|
||||
mod.comment = comment
|
||||
|
||||
@top_level.add_to_classes_or_modules mod
|
||||
@stats.add_module mod
|
||||
end
|
||||
|
||||
##
|
||||
# Parses an RDoc::Require in +context+ containing +comment+
|
||||
|
||||
def parse_require(context, comment)
|
||||
skip_tkspace_comment
|
||||
tk = get_tk
|
||||
|
@ -1105,7 +1201,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
name = tk.text if TkSTRING === tk
|
||||
|
||||
if name then
|
||||
context.add_require RDoc::Require.new(name, comment)
|
||||
@top_level.add_require RDoc::Require.new(name, comment)
|
||||
else
|
||||
unget_tk tk
|
||||
end
|
||||
|
@ -1206,7 +1302,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
# We can't solve the general case, but we can handle most occurrences by
|
||||
# ignoring a do at the end of a line.
|
||||
|
||||
when TkUNTIL, TkWHILE then
|
||||
when TkUNTIL, TkWHILE then
|
||||
nest += 1
|
||||
skip_optional_do_after_expression
|
||||
|
||||
|
@ -1275,9 +1371,14 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parse up to +no+ symbol arguments
|
||||
|
||||
def parse_symbol_arg(no = nil)
|
||||
args = []
|
||||
|
||||
skip_tkspace_comment
|
||||
|
||||
case tk = get_tk
|
||||
when TkLPAREN
|
||||
loop do
|
||||
|
@ -1320,28 +1421,40 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
args
|
||||
end
|
||||
|
||||
##
|
||||
# Returns symbol text from the next token
|
||||
|
||||
def parse_symbol_in_arg
|
||||
case tk = get_tk
|
||||
when TkSYMBOL
|
||||
tk.text.sub(/^:/, '')
|
||||
when TkSTRING
|
||||
eval @read[-1]
|
||||
when TkDSTRING, TkIDENTIFIER then
|
||||
nil # ignore
|
||||
else
|
||||
warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Parses statements at the toplevel in +container+
|
||||
|
||||
def parse_top_level_statements(container)
|
||||
comment = collect_first_comment
|
||||
look_for_directives_in(container, comment)
|
||||
container.comment = comment unless comment.empty?
|
||||
container.comment = comment if container.document_self unless comment.empty?
|
||||
parse_statements container, NORMAL, nil, comment
|
||||
end
|
||||
|
||||
##
|
||||
# Determines the visibility in +container+ from +tk+
|
||||
|
||||
def parse_visibility(container, single, tk)
|
||||
singleton = (single == SINGLE)
|
||||
|
||||
|
@ -1383,7 +1496,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
container.methods_matching args do |m|
|
||||
s_m = m.dup
|
||||
s_m.singleton = true if RDoc::AnyMethod === s_m
|
||||
s_m.record_location @top_level
|
||||
s_m.singleton = true
|
||||
s_m.visibility = :public
|
||||
module_functions << s_m
|
||||
end
|
||||
|
@ -1403,6 +1517,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Determines the block parameter for +context+
|
||||
|
||||
def parse_yield(context, single, tk, method)
|
||||
return if method.block_params
|
||||
|
||||
|
@ -1423,93 +1540,81 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
#
|
||||
# We return the directive name and any parameters as a two element array
|
||||
|
||||
def read_directive(allowed)
|
||||
def read_directive allowed
|
||||
tk = get_tk
|
||||
result = nil
|
||||
|
||||
if TkCOMMENT === tk then
|
||||
if tk.text =~ /\s*:?(\w+):\s*(.*)/ then
|
||||
directive = $1.downcase
|
||||
if allowed.include? directive then
|
||||
result = [directive, $2]
|
||||
end
|
||||
end
|
||||
return unless tk.text =~ /\s*:?(\w+):\s*(.*)/
|
||||
|
||||
directive = $1.downcase
|
||||
|
||||
return [directive, $2] if allowed.include? directive
|
||||
else
|
||||
unget_tk tk
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
##
|
||||
# Handles the directive for +context+ if the directive is listed in +allow+.
|
||||
# This method is called for directives following a definition.
|
||||
|
||||
def read_documentation_modifiers(context, allow)
|
||||
dir = read_directive(allow)
|
||||
directive, value = read_directive allow
|
||||
|
||||
case dir[0]
|
||||
when "notnew", "not_new", "not-new" then
|
||||
return unless directive
|
||||
|
||||
case directive
|
||||
when 'notnew', 'not_new', 'not-new' then
|
||||
context.dont_rename_initialize = true
|
||||
|
||||
when "nodoc" then
|
||||
context.document_self = false
|
||||
if dir[1].downcase == "all"
|
||||
context.document_children = false
|
||||
end
|
||||
|
||||
when "doc" then
|
||||
context.document_self = true
|
||||
context.force_documentation = true
|
||||
|
||||
when "yield", "yields" then
|
||||
unless context.params.nil?
|
||||
context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc
|
||||
end
|
||||
|
||||
context.block_params = dir[1]
|
||||
|
||||
when "arg", "args" then
|
||||
context.params = dir[1]
|
||||
end if dir
|
||||
else
|
||||
RDoc::Parser.process_directive context, directive, value
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Removes private comments from +comment+
|
||||
|
||||
def remove_private_comments(comment)
|
||||
comment.gsub!(/^#--\n.*?^#\+\+/m, '')
|
||||
comment.sub!(/^#--\n.*/m, '')
|
||||
comment.gsub!(/^#--\n.*?^#\+\+\n?/m, '')
|
||||
comment.sub!(/^#--\n.*\n?/m, '')
|
||||
end
|
||||
|
||||
##
|
||||
# Scans this ruby file for ruby constructs
|
||||
|
||||
def scan
|
||||
reset
|
||||
|
||||
catch :eof do
|
||||
catch :enddoc do
|
||||
begin
|
||||
parse_top_level_statements @top_level
|
||||
rescue StandardError => e
|
||||
bytes = ''
|
||||
begin
|
||||
parse_top_level_statements @top_level
|
||||
rescue StandardError => e
|
||||
bytes = ''
|
||||
|
||||
20.times do @scanner.ungetc end
|
||||
count = 0
|
||||
60.times do |i|
|
||||
count = i
|
||||
byte = @scanner.getc
|
||||
break unless byte
|
||||
bytes << byte
|
||||
end
|
||||
count -= 20
|
||||
count.times do @scanner.ungetc end
|
||||
20.times do @scanner.ungetc end
|
||||
count = 0
|
||||
60.times do |i|
|
||||
count = i
|
||||
byte = @scanner.getc
|
||||
break unless byte
|
||||
bytes << byte
|
||||
end
|
||||
count -= 20
|
||||
count.times do @scanner.ungetc end
|
||||
|
||||
$stderr.puts <<-EOF
|
||||
$stderr.puts <<-EOF
|
||||
|
||||
#{self.class} failure around line #{@scanner.line_no} of
|
||||
#{@file_name}
|
||||
|
||||
EOF
|
||||
EOF
|
||||
|
||||
unless bytes.empty? then
|
||||
$stderr.puts
|
||||
$stderr.puts bytes.inspect
|
||||
end
|
||||
|
||||
raise e
|
||||
unless bytes.empty? then
|
||||
$stderr.puts
|
||||
$stderr.puts bytes.inspect
|
||||
end
|
||||
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1574,6 +1679,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
unget_tk(tk) unless TkIN === tk
|
||||
end
|
||||
|
||||
##
|
||||
# Skips the next method in +container+
|
||||
|
||||
def skip_method container
|
||||
meth = RDoc::AnyMethod.new "", "anon"
|
||||
parse_method_parameters meth
|
||||
|
@ -1591,6 +1699,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Prints +msg+ to +$stderr+ unless we're being quiet
|
||||
|
||||
def warn(msg)
|
||||
return if @options.quiet
|
||||
msg = make_message msg
|
||||
|
|
|
@ -49,7 +49,6 @@ module RDoc::Parser::RubyTools
|
|||
obj.pop_token
|
||||
end if @token_listeners
|
||||
else
|
||||
warn("':' not followed by identifier or operator")
|
||||
tk = tk1
|
||||
end
|
||||
end
|
||||
|
@ -62,6 +61,10 @@ module RDoc::Parser::RubyTools
|
|||
tk
|
||||
end
|
||||
|
||||
##
|
||||
# Reads and returns all tokens up to one of +tokens+. Leaves the matched
|
||||
# token in the token list.
|
||||
|
||||
def get_tk_until(*tokens)
|
||||
read = []
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
##
|
||||
# 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.
|
||||
# comment.
|
||||
|
||||
class RDoc::Parser::Simple < RDoc::Parser
|
||||
|
||||
|
@ -32,10 +31,16 @@ class RDoc::Parser::Simple < RDoc::Parser
|
|||
@top_level
|
||||
end
|
||||
|
||||
def remove_private_comments(comment)
|
||||
comment.gsub(/^--\n.*?^\+\+/m, '').sub(/^--\n.*/m, '')
|
||||
##
|
||||
# Removes comments wrapped in <tt>--/++</tt>
|
||||
|
||||
def remove_private_comments text
|
||||
text.gsub(/^--\n.*?^\+\+/m, '').sub(/^--\n.*/m, '')
|
||||
end
|
||||
|
||||
##
|
||||
# Removes the encoding magic comment from +text+
|
||||
|
||||
def remove_coding_comment text
|
||||
text.sub(/\A# .*coding[=:].*$/, '')
|
||||
end
|
||||
|
|
104
lib/rdoc/rdoc.rb
104
lib/rdoc/rdoc.rb
|
@ -1,5 +1,6 @@
|
|||
require 'rdoc'
|
||||
|
||||
require 'rdoc/encoding'
|
||||
require 'rdoc/parser'
|
||||
|
||||
# Simple must come first
|
||||
|
@ -23,7 +24,28 @@ require 'time'
|
|||
# rdoc.document(args)
|
||||
#
|
||||
# Where +args+ is an array of strings, each corresponding to an argument you'd
|
||||
# give rdoc on the command line. See rdoc/rdoc.rb for details.
|
||||
# give rdoc on the command line. See <tt>rdoc --help<tt> for details.
|
||||
#
|
||||
# = Plugins
|
||||
#
|
||||
# When you <tt>require 'rdoc/rdoc'</tt> RDoc looks for 'rdoc/discover' files
|
||||
# in your installed gems. This can be used to load alternate generators or
|
||||
# add additional preprocessor directives.
|
||||
#
|
||||
# You will want to wrap your plugin loading in an RDoc version check.
|
||||
# Something like:
|
||||
#
|
||||
# begin
|
||||
# gem 'rdoc', '~> 3'
|
||||
# require 'path/to/my/awesome/rdoc/plugin'
|
||||
# rescue Gem::LoadError
|
||||
# end
|
||||
#
|
||||
# The most obvious plugin type is a new output generator. See RDoc::Generator
|
||||
# for details.
|
||||
#
|
||||
# You can also hook into RDoc::Markup to add new directives (:nodoc: is a
|
||||
# directive). See RDoc::Markup::PreProcess::register for details.
|
||||
|
||||
class RDoc::RDoc
|
||||
|
||||
|
@ -79,6 +101,10 @@ class RDoc::RDoc
|
|||
@current = rdoc
|
||||
end
|
||||
|
||||
##
|
||||
# Creates a new RDoc::RDoc instance. Call #document to parse files and
|
||||
# generate documentation.
|
||||
|
||||
def initialize
|
||||
@current = nil
|
||||
@exclude = nil
|
||||
|
@ -142,7 +168,9 @@ class RDoc::RDoc
|
|||
|
||||
last = {}
|
||||
|
||||
if File.exist? dir then
|
||||
if @options.dry_run then
|
||||
# do nothing
|
||||
elsif File.exist? dir then
|
||||
error "#{dir} exists and is not a directory" unless File.directory? dir
|
||||
|
||||
begin
|
||||
|
@ -167,7 +195,7 @@ you'll need to specify a different output directory name (using the --op <dir>
|
|||
option)
|
||||
|
||||
ERROR
|
||||
end
|
||||
end unless @options.force_output
|
||||
else
|
||||
FileUtils.mkdir_p dir
|
||||
end
|
||||
|
@ -179,6 +207,8 @@ option)
|
|||
# Update the flag file in an output directory.
|
||||
|
||||
def update_output_dir(op_dir, time, last = {})
|
||||
return if @options.dry_run
|
||||
|
||||
open output_flag_file(op_dir), "w" do |f|
|
||||
f.puts time.rfc2822
|
||||
last.each do |n, t|
|
||||
|
@ -277,7 +307,9 @@ option)
|
|||
|
||||
def parse_file filename
|
||||
@stats.add_file filename
|
||||
content = read_file_contents filename
|
||||
encoding = @options.encoding if defined?(Encoding)
|
||||
|
||||
content = RDoc::Encoding.read_file filename, encoding
|
||||
|
||||
return unless content
|
||||
|
||||
|
@ -288,11 +320,22 @@ option)
|
|||
return unless parser
|
||||
|
||||
parser.scan
|
||||
|
||||
# restart documentation for the classes & modules found
|
||||
top_level.classes_or_modules.each do |cm|
|
||||
cm.done_documenting = false
|
||||
end
|
||||
|
||||
top_level
|
||||
|
||||
rescue => e
|
||||
$stderr.puts <<-EOF
|
||||
Before reporting this, could you check that the file you're documenting
|
||||
compiles cleanly--RDoc is not a full Ruby parser, and gets confused easily if
|
||||
fed invalid programs.
|
||||
has proper syntax:
|
||||
|
||||
#{Gem.ruby} -c #{filename}
|
||||
|
||||
RDoc is not a full Ruby parser and will fail when fed invalid ruby programs.
|
||||
|
||||
The internal error was:
|
||||
|
||||
|
@ -300,7 +343,7 @@ The internal error was:
|
|||
|
||||
EOF
|
||||
|
||||
$stderr.puts e.backtrace.join("\n\t") if $RDOC_DEBUG
|
||||
$stderr.puts e.backtrace.join("\n\t") if $DEBUG_RDOC
|
||||
|
||||
raise e
|
||||
nil
|
||||
|
@ -344,11 +387,9 @@ The internal error was:
|
|||
# For simplicity, +argv+ is an array of strings, equivalent to the strings
|
||||
# that would be passed on the command line. (This isn't a coincidence, as
|
||||
# we _do_ pass in ARGV when running interactively). For a list of options,
|
||||
# see rdoc/rdoc.rb. By default, output will be stored in a directory
|
||||
# see <tt>rdoc --help</tt>. By default, output will be stored in a directory
|
||||
# called +doc+ below the current directory, so make sure you're somewhere
|
||||
# writable before invoking.
|
||||
#
|
||||
# Throws: RDoc::Error on error
|
||||
|
||||
def document(argv)
|
||||
RDoc::TopLevel.reset
|
||||
|
@ -364,29 +405,36 @@ The internal error was:
|
|||
|
||||
@exclude = @options.exclude
|
||||
|
||||
@last_modified = setup_output_dir @options.op_dir, @options.force_update
|
||||
unless @options.coverage_report then
|
||||
@last_modified = setup_output_dir @options.op_dir, @options.force_update
|
||||
end
|
||||
|
||||
start_time = Time.now
|
||||
|
||||
file_info = parse_files @options.files
|
||||
|
||||
@options.title = "RDoc Documentation"
|
||||
@options.default_title = "RDoc Documentation"
|
||||
|
||||
if file_info.empty?
|
||||
RDoc::TopLevel.complete @options.visibility
|
||||
|
||||
if @options.coverage_report then
|
||||
puts
|
||||
puts @stats.report
|
||||
elsif file_info.empty?
|
||||
$stderr.puts "\nNo newer files." unless @options.quiet
|
||||
else
|
||||
gen_klass = @options.generator
|
||||
|
||||
unless @options.quiet then
|
||||
$stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')}..."
|
||||
end
|
||||
|
||||
@generator = gen_klass.for @options
|
||||
@generator = gen_klass.new @options
|
||||
|
||||
Dir.chdir @options.op_dir do
|
||||
begin
|
||||
self.class.current = self
|
||||
|
||||
unless @options.quiet then
|
||||
$stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')} format into #{Dir.pwd}..."
|
||||
end
|
||||
|
||||
@generator.generate file_info
|
||||
update_output_dir ".", start_time, @last_modified
|
||||
ensure
|
||||
|
@ -397,26 +445,10 @@ The internal error was:
|
|||
|
||||
unless @options.quiet or not @stats then
|
||||
puts
|
||||
@stats.print
|
||||
end
|
||||
end
|
||||
|
||||
def read_file_contents(filename)
|
||||
content = open filename, "rb" do |f| f.read end
|
||||
|
||||
utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
|
||||
if defined? Encoding then
|
||||
if /coding[=:]\s*([^\s;]+)/i =~ content[%r"\A(?:#!.*\n)?.*\n"]
|
||||
enc = ::Encoding.find($1)
|
||||
end
|
||||
if enc ||= (Encoding::UTF_8 if utf8)
|
||||
content.force_encoding(enc)
|
||||
end
|
||||
puts @stats.summary
|
||||
end
|
||||
|
||||
content
|
||||
rescue Errno::EISDIR, Errno::ENOENT
|
||||
nil
|
||||
exit @stats.fully_documented? if @options.coverage_report
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -16,6 +16,7 @@ class RDoc::Require < RDoc::CodeObject
|
|||
def initialize(name, comment)
|
||||
super()
|
||||
@name = name.gsub(/'|"/, "") #'
|
||||
@top_level = nil
|
||||
self.comment = comment
|
||||
end
|
||||
|
||||
|
@ -28,5 +29,25 @@ class RDoc::Require < RDoc::CodeObject
|
|||
]
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"require #{name} in: #{parent}"
|
||||
end
|
||||
|
||||
##
|
||||
# The RDoc::TopLevel corresponding to this require, or +nil+ if not found.
|
||||
|
||||
def top_level
|
||||
@top_level ||= begin
|
||||
tl = RDoc::TopLevel.all_files_hash[name + '.rb']
|
||||
|
||||
if tl.nil? and RDoc::TopLevel.all_files.first.full_name =~ %r(^lib/) then
|
||||
# second chance
|
||||
tl = RDoc::TopLevel.all_files_hash['lib/' + name + '.rb']
|
||||
end
|
||||
|
||||
tl
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -6,6 +6,11 @@ begin
|
|||
rescue LoadError
|
||||
end
|
||||
|
||||
begin
|
||||
require 'win32console'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require 'rdoc/ri'
|
||||
require 'rdoc/ri/paths'
|
||||
require 'rdoc/markup'
|
||||
|
@ -55,6 +60,9 @@ class RDoc::RI::Driver
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# An RDoc::RI::Store for each entry in the RI path
|
||||
|
||||
attr_accessor :stores
|
||||
|
||||
##
|
||||
|
@ -97,23 +105,10 @@ class RDoc::RI::Driver
|
|||
##
|
||||
# Parses +argv+ and returns a Hash of options
|
||||
|
||||
def self.process_args argv = []
|
||||
def self.process_args argv
|
||||
options = default_options
|
||||
opts = OptionParser.new
|
||||
setup_options(opts, options)
|
||||
|
||||
argv = ENV['RI'].to_s.split.concat argv
|
||||
opts.parse!(argv)
|
||||
|
||||
fixup_options(options, argv)
|
||||
|
||||
rescue OptionParser::ParseError => e
|
||||
puts opts, nil, e
|
||||
abort
|
||||
end
|
||||
|
||||
def self.setup_options(opt, options)
|
||||
begin
|
||||
opts = OptionParser.new do |opt|
|
||||
opt.accept File do |file,|
|
||||
File.readable?(file) and not File.directory?(file) and file
|
||||
end
|
||||
|
@ -133,7 +128,7 @@ Where name can be:
|
|||
All class names may be abbreviated to their minimum unambiguous form. If a name
|
||||
is ambiguous, all valid options will be listed.
|
||||
|
||||
The form '.' method matches either class or instance methods, while #method
|
||||
A '.' matches either class or instance methods, while #method
|
||||
matches only instance and ::method matches only class methods.
|
||||
|
||||
For example:
|
||||
|
@ -143,7 +138,7 @@ For example:
|
|||
#{opt.program_name} File.new
|
||||
#{opt.program_name} zip
|
||||
|
||||
Note that shell quoting may be required for method names containing
|
||||
Note that shell quoting or escaping may be required for method names containing
|
||||
punctuation:
|
||||
|
||||
#{opt.program_name} 'Array.[]'
|
||||
|
@ -287,9 +282,11 @@ Options may also be set in the 'RI' environment variable.
|
|||
options[:dump_path] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.fixup_options(options, argv)
|
||||
argv = ENV['RI'].to_s.split.concat argv
|
||||
|
||||
opts.parse! argv
|
||||
|
||||
options[:names] = argv
|
||||
|
||||
options[:use_stdout] ||= !$stdout.tty?
|
||||
|
@ -297,6 +294,12 @@ Options may also be set in the 'RI' environment variable.
|
|||
options[:width] ||= 72
|
||||
|
||||
options
|
||||
|
||||
rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e
|
||||
puts opts
|
||||
puts
|
||||
puts e
|
||||
exit 1
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -359,7 +362,7 @@ Options may also be set in the 'RI' environment variable.
|
|||
|
||||
paths = RDoc::Markup::Verbatim.new
|
||||
also_in.each do |store|
|
||||
paths.parts.push ' ', store.friendly_path, "\n"
|
||||
paths.parts.push store.friendly_path, "\n"
|
||||
end
|
||||
out << paths
|
||||
end
|
||||
|
@ -427,7 +430,7 @@ Options may also be set in the 'RI' environment variable.
|
|||
verb = RDoc::Markup::Verbatim.new
|
||||
|
||||
wout.each do |incl|
|
||||
verb.push ' ', incl.name, "\n"
|
||||
verb.push incl.name, "\n"
|
||||
end
|
||||
|
||||
out << verb
|
||||
|
@ -446,7 +449,7 @@ Options may also be set in the 'RI' environment variable.
|
|||
out << RDoc::Markup::BlankLine.new
|
||||
|
||||
out.push(*methods.map do |method|
|
||||
RDoc::Markup::Verbatim.new ' ', method
|
||||
RDoc::Markup::Verbatim.new method
|
||||
end)
|
||||
|
||||
out << RDoc::Markup::BlankLine.new
|
||||
|
@ -664,8 +667,8 @@ Options may also be set in the 'RI' environment variable.
|
|||
|
||||
if method.arglists then
|
||||
arglists = method.arglists.chomp.split "\n"
|
||||
arglists = arglists.map { |line| [' ', line, "\n"] }
|
||||
out << RDoc::Markup::Verbatim.new(*arglists.flatten)
|
||||
arglists = arglists.map { |line| line + "\n" }
|
||||
out << RDoc::Markup::Verbatim.new(*arglists)
|
||||
out << RDoc::Markup::Rule.new(1)
|
||||
end
|
||||
|
||||
|
@ -846,6 +849,17 @@ Options may also be set in the 'RI' environment variable.
|
|||
exit
|
||||
end
|
||||
|
||||
##
|
||||
# Is +file+ in ENV['PATH']?
|
||||
|
||||
def in_path? file
|
||||
return true if file =~ %r%\A/% and File.exist? file
|
||||
|
||||
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |path|
|
||||
File.exist? File.join(path, file)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Lists classes known to ri
|
||||
|
||||
|
@ -1041,7 +1055,11 @@ Options may also be set in the 'RI' environment variable.
|
|||
pagers.compact.uniq.each do |pager|
|
||||
next unless pager
|
||||
|
||||
io = IO.popen pager, "w" rescue next
|
||||
pager_cmd = pager.split.first
|
||||
|
||||
next unless in_path? pager_cmd
|
||||
|
||||
io = IO.popen(pager, 'w') rescue next
|
||||
|
||||
next if $? and $?.exited? # pager didn't work
|
||||
|
||||
|
|
|
@ -10,10 +10,21 @@ module RDoc::RI::Paths
|
|||
|
||||
version = RbConfig::CONFIG['ruby_version']
|
||||
|
||||
base = File.join RbConfig::CONFIG['ridir'], version
|
||||
base = if RbConfig::CONFIG.key? 'ridir' then
|
||||
File.join RbConfig::CONFIG['ridir'], version
|
||||
else
|
||||
File.join RbConfig::CONFIG['datadir'], 'ri', version
|
||||
end
|
||||
|
||||
SYSDIR = File.join base, "system"
|
||||
SITEDIR = File.join base, "site"
|
||||
HOMEDIR = (File.expand_path('~/.rdoc') rescue nil)
|
||||
|
||||
homedir = File.expand_path('~') ||
|
||||
ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
|
||||
|
||||
HOMEDIR = if homedir then
|
||||
File.join homedir, ".rdoc"
|
||||
end
|
||||
#:startdoc:
|
||||
|
||||
@gemdirs = nil
|
||||
|
|
|
@ -10,6 +10,11 @@ require 'fileutils'
|
|||
|
||||
class RDoc::RI::Store
|
||||
|
||||
##
|
||||
# If true this Store will not write any files
|
||||
|
||||
attr_accessor :dry_run
|
||||
|
||||
##
|
||||
# Path this store reads or writes
|
||||
|
||||
|
@ -21,14 +26,18 @@ class RDoc::RI::Store
|
|||
|
||||
attr_accessor :type
|
||||
|
||||
##
|
||||
# The contents of the Store
|
||||
|
||||
attr_reader :cache
|
||||
|
||||
##
|
||||
# Creates a new Store of +type+ that will load or save to +path+
|
||||
|
||||
def initialize path, type = nil
|
||||
@type = type
|
||||
@path = path
|
||||
@dry_run = false
|
||||
@type = type
|
||||
@path = path
|
||||
|
||||
@cache = {
|
||||
:class_methods => {},
|
||||
|
@ -178,6 +187,8 @@ class RDoc::RI::Store
|
|||
@cache[:instance_methods].each do |_, m| m.uniq!; m.sort! end
|
||||
@cache[:modules].uniq!; @cache[:modules].sort!
|
||||
|
||||
return if @dry_run
|
||||
|
||||
open cache_path, 'wb' do |io|
|
||||
Marshal.dump @cache, io
|
||||
end
|
||||
|
@ -187,7 +198,7 @@ class RDoc::RI::Store
|
|||
# Writes the ri data for +klass+
|
||||
|
||||
def save_class klass
|
||||
FileUtils.mkdir_p class_path(klass.full_name)
|
||||
FileUtils.mkdir_p class_path(klass.full_name) unless @dry_run
|
||||
|
||||
@cache[:modules] << klass.full_name
|
||||
|
||||
|
@ -214,7 +225,7 @@ class RDoc::RI::Store
|
|||
@cache[:ancestors][klass.full_name].push(*ancestors)
|
||||
|
||||
attributes = klass.attributes.map do |attribute|
|
||||
"#{attribute.type} #{attribute.name}"
|
||||
"#{attribute.definition} #{attribute.name}"
|
||||
end
|
||||
|
||||
unless attributes.empty? then
|
||||
|
@ -222,6 +233,8 @@ class RDoc::RI::Store
|
|||
@cache[:attributes][klass.full_name].push(*attributes)
|
||||
end
|
||||
|
||||
return if @dry_run
|
||||
|
||||
open path, 'wb' do |io|
|
||||
Marshal.dump klass, io
|
||||
end
|
||||
|
@ -231,7 +244,7 @@ class RDoc::RI::Store
|
|||
# Writes the ri data for +method+ on +klass+
|
||||
|
||||
def save_method klass, method
|
||||
FileUtils.mkdir_p class_path(klass.full_name)
|
||||
FileUtils.mkdir_p class_path(klass.full_name) unless @dry_run
|
||||
|
||||
cache = if method.singleton then
|
||||
@cache[:class_methods]
|
||||
|
@ -241,6 +254,8 @@ class RDoc::RI::Store
|
|||
cache[klass.full_name] ||= []
|
||||
cache[klass.full_name] << method.name
|
||||
|
||||
return if @dry_run
|
||||
|
||||
open method_file(klass.full_name, method.full_name), 'wb' do |io|
|
||||
Marshal.dump method, io
|
||||
end
|
||||
|
|
|
@ -92,9 +92,9 @@ class RDoc::RubyLex
|
|||
end
|
||||
|
||||
def inspect # :nodoc:
|
||||
"#<%s:0x%x lex_state %p space_seen %p>" % [
|
||||
"#<%s:0x%x pos %d lex_state %p space_seen %p>" % [
|
||||
self.class, object_id,
|
||||
@lex_state, @space_seen,
|
||||
@io.pos, @lex_state, @space_seen,
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -149,6 +149,7 @@ class RDoc::RubyLex
|
|||
else
|
||||
@char_no += 1
|
||||
end
|
||||
|
||||
c
|
||||
end
|
||||
|
||||
|
@ -674,7 +675,7 @@ class RDoc::RubyLex
|
|||
tk_c = TkLPAREN
|
||||
end
|
||||
@indent_stack.push tk_c
|
||||
Token(tk_c)
|
||||
Token tk_c
|
||||
end
|
||||
|
||||
@OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do
|
||||
|
@ -822,6 +823,12 @@ class RDoc::RubyLex
|
|||
end
|
||||
end
|
||||
|
||||
IDENT_RE = if defined? Encoding then
|
||||
/[\w\u0080-\uFFFF]/u
|
||||
else
|
||||
/[\w\x80-\xFF]/
|
||||
end
|
||||
|
||||
def identify_identifier
|
||||
token = ""
|
||||
if peek(0) =~ /[$@]/
|
||||
|
@ -831,15 +838,7 @@ class RDoc::RubyLex
|
|||
end
|
||||
end
|
||||
|
||||
# HACK to avoid a warning the regexp is hidden behind an eval
|
||||
# HACK need a better way to detect oniguruma
|
||||
@identifier_re ||= if defined? Encoding then
|
||||
eval '/[\p{Alnum}_]/u'
|
||||
else
|
||||
eval '/[\w\x80-\xff]/'
|
||||
end
|
||||
|
||||
while (ch = getc) =~ @identifier_re
|
||||
while (ch = getc) =~ IDENT_RE do
|
||||
print " :#{ch}: " if RDoc::RubyLex.debug?
|
||||
token.concat ch
|
||||
end
|
||||
|
|
|
@ -178,7 +178,7 @@ module RDoc::RubyToken
|
|||
end
|
||||
|
||||
class TkUnknownChar < Token
|
||||
def initialize(seek, line_no, char_no, id)
|
||||
def initialize(seek, line_no, char_no, name)
|
||||
super(seek, line_no, char_no)
|
||||
@name = name
|
||||
end
|
||||
|
@ -253,7 +253,7 @@ module RDoc::RubyToken
|
|||
[:TkWHILE, TkKW, "while", EXPR_BEG, :TkWHILE_MOD],
|
||||
[:TkUNTIL, TkKW, "until", EXPR_BEG, :TkUNTIL_MOD],
|
||||
[:TkFOR, TkKW, "for", EXPR_BEG],
|
||||
[:TkBREAK, TkKW, "break", EXPR_END],
|
||||
[:TkBREAK, TkKW, "break", EXPR_MID],
|
||||
[:TkNEXT, TkKW, "next", EXPR_END],
|
||||
[:TkREDO, TkKW, "redo", EXPR_END],
|
||||
[:TkRETRY, TkKW, "retry", EXPR_END],
|
||||
|
|
|
@ -5,8 +5,9 @@ require 'rdoc/class_module'
|
|||
|
||||
class RDoc::SingleClass < RDoc::ClassModule
|
||||
|
||||
# Adds the superclass to the included modules.
|
||||
def ancestors
|
||||
includes + [superclass]
|
||||
superclass ? super + [superclass] : super
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,247 +1,287 @@
|
|||
require 'rdoc'
|
||||
|
||||
##
|
||||
# RDoc stats collector
|
||||
# RDoc statistics collector which prints a summary and report of a project's
|
||||
# documentation totals.
|
||||
|
||||
class RDoc::Stats
|
||||
|
||||
attr_reader :nodoc_constants
|
||||
attr_reader :nodoc_methods
|
||||
##
|
||||
# Count of files parsed during parsing
|
||||
|
||||
attr_reader :files_so_far
|
||||
|
||||
##
|
||||
# Total number of files found
|
||||
|
||||
attr_reader :num_constants
|
||||
attr_reader :num_files
|
||||
attr_reader :num_methods
|
||||
|
||||
attr_reader :total_files
|
||||
##
|
||||
# Creates a new Stats that will have +num_files+. +verbosity+ defaults to 1
|
||||
# which will create an RDoc::Stats::Normal outputter.
|
||||
|
||||
def initialize(total_files, verbosity = 1)
|
||||
@nodoc_constants = 0
|
||||
@nodoc_methods = 0
|
||||
|
||||
@num_constants = 0
|
||||
@num_files = 0
|
||||
@num_methods = 0
|
||||
|
||||
@total_files = total_files
|
||||
def initialize num_files, verbosity = 1
|
||||
@files_so_far = 0
|
||||
@num_files = num_files
|
||||
@fully_documented = nil
|
||||
|
||||
@start = Time.now
|
||||
|
||||
@display = case verbosity
|
||||
when 0 then Quiet.new total_files
|
||||
when 1 then Normal.new total_files
|
||||
else Verbose.new total_files
|
||||
when 0 then Quiet.new num_files
|
||||
when 1 then Normal.new num_files
|
||||
else Verbose.new num_files
|
||||
end
|
||||
end
|
||||
|
||||
def begin_adding
|
||||
@display.begin_adding
|
||||
end
|
||||
##
|
||||
# Records the parsing of an alias +as+.
|
||||
|
||||
def add_alias(as)
|
||||
def add_alias as
|
||||
@display.print_alias as
|
||||
@num_methods += 1
|
||||
@nodoc_methods += 1 if as.document_self and as.comment.empty?
|
||||
end
|
||||
|
||||
def add_class(klass)
|
||||
##
|
||||
# Records the parsing of an attribute +attribute+
|
||||
|
||||
def add_attribute attribute
|
||||
@display.print_attribute attribute
|
||||
end
|
||||
|
||||
##
|
||||
# Records the parsing of a class +klass+
|
||||
|
||||
def add_class klass
|
||||
@display.print_class klass
|
||||
end
|
||||
|
||||
def add_constant(constant)
|
||||
##
|
||||
# Records the parsing of +constant+
|
||||
|
||||
def add_constant constant
|
||||
@display.print_constant constant
|
||||
@num_constants += 1
|
||||
@nodoc_constants += 1 if constant.document_self and constant.comment.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Records the parsing of +file+
|
||||
|
||||
def add_file(file)
|
||||
@display.print_file @num_files, file
|
||||
@num_files += 1
|
||||
@files_so_far += 1
|
||||
@display.print_file @files_so_far, file
|
||||
end
|
||||
|
||||
##
|
||||
# Records the parsing of +method+
|
||||
|
||||
def add_method(method)
|
||||
@display.print_method method
|
||||
@num_methods += 1
|
||||
@nodoc_methods += 1 if method.document_self and method.comment.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Records the parsing of a module +mod+
|
||||
|
||||
def add_module(mod)
|
||||
@display.print_module mod
|
||||
end
|
||||
|
||||
##
|
||||
# Call this to mark the beginning of parsing for display purposes
|
||||
|
||||
def begin_adding
|
||||
@display.begin_adding
|
||||
end
|
||||
|
||||
##
|
||||
# Calculates documentation totals and percentages
|
||||
|
||||
def calculate
|
||||
return if @percent_doc
|
||||
|
||||
ucm = RDoc::TopLevel.unique_classes_and_modules
|
||||
constants = []
|
||||
ucm.each { |cm| constants.concat cm.constants }
|
||||
|
||||
methods = []
|
||||
ucm.each { |cm| methods.concat cm.method_list }
|
||||
|
||||
attributes = []
|
||||
ucm.each { |cm| attributes.concat cm.attributes }
|
||||
|
||||
@num_attributes, @undoc_attributes = doc_stats attributes
|
||||
@num_classes, @undoc_classes = doc_stats RDoc::TopLevel.unique_classes
|
||||
@num_constants, @undoc_constants = doc_stats constants
|
||||
@num_methods, @undoc_methods = doc_stats methods
|
||||
@num_modules, @undoc_modules = doc_stats RDoc::TopLevel.unique_modules
|
||||
|
||||
@num_items =
|
||||
@num_attributes +
|
||||
@num_classes +
|
||||
@num_constants +
|
||||
@num_methods +
|
||||
@num_modules
|
||||
|
||||
@undoc_items =
|
||||
@undoc_attributes +
|
||||
@undoc_classes +
|
||||
@undoc_constants +
|
||||
@undoc_methods +
|
||||
@undoc_modules
|
||||
|
||||
@doc_items = @num_items - @undoc_items
|
||||
|
||||
@fully_documented = (@num_items - @doc_items) == 0
|
||||
|
||||
@percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero?
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the length and number of undocumented items in +collection+.
|
||||
|
||||
def doc_stats collection
|
||||
[collection.length, collection.count { |item| not item.documented? }]
|
||||
end
|
||||
|
||||
##
|
||||
# Call this to mark the end of parsing for display purposes
|
||||
|
||||
def done_adding
|
||||
@display.done_adding
|
||||
end
|
||||
|
||||
def print
|
||||
classes = RDoc::TopLevel.classes
|
||||
num_classes = classes.length
|
||||
nodoc_classes = classes.select do |klass|
|
||||
klass.document_self and klass.comment.empty?
|
||||
end.length
|
||||
##
|
||||
# The documentation status of this project. +true+ when 100%, +false+ when
|
||||
# less than 100% and +nil+ when unknown.
|
||||
#
|
||||
# Set by calling #calculate
|
||||
|
||||
modules = RDoc::TopLevel.modules
|
||||
num_modules = modules.length
|
||||
nodoc_modules = modules.select do |mod|
|
||||
mod.document_self and mod.comment.empty?
|
||||
end.length
|
||||
|
||||
items = num_classes + @num_constants + num_modules + @num_methods
|
||||
doc_items = items -
|
||||
nodoc_classes - @nodoc_constants - nodoc_modules - @nodoc_methods
|
||||
|
||||
percent_doc = doc_items.to_f / items * 100 if items.nonzero?
|
||||
|
||||
puts "Files: %5d" % @num_files
|
||||
puts "Classes: %5d (%5d undocumented)" % [num_classes, nodoc_classes]
|
||||
puts "Constants: %5d (%5d undocumented)" %
|
||||
[@num_constants, @nodoc_constants]
|
||||
puts "Modules: %5d (%5d undocumented)" % [num_modules, nodoc_modules]
|
||||
puts "Methods: %5d (%5d undocumented)" % [@num_methods, @nodoc_methods]
|
||||
puts "%6.2f%% documented" % percent_doc if percent_doc
|
||||
puts
|
||||
puts "Elapsed: %0.1fs" % (Time.now - @start)
|
||||
def fully_documented?
|
||||
@fully_documented
|
||||
end
|
||||
|
||||
##
|
||||
# Stats printer that prints nothing
|
||||
# Returns a report on which items are not documented
|
||||
|
||||
class Quiet
|
||||
def report
|
||||
report = []
|
||||
|
||||
def initialize total_files
|
||||
@total_files = total_files
|
||||
calculate
|
||||
|
||||
if @num_items == @doc_items then
|
||||
report << '100% documentation!'
|
||||
report << nil
|
||||
report << 'Great Job!'
|
||||
|
||||
return report.join "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Prints a message at the beginning of parsing
|
||||
report << 'The following items are not documented:'
|
||||
report << nil
|
||||
|
||||
def begin_adding(*) end
|
||||
ucm = RDoc::TopLevel.unique_classes_and_modules
|
||||
|
||||
##
|
||||
# Prints when an alias is added
|
||||
ucm.sort.each do |cm|
|
||||
type = case cm # TODO #definition
|
||||
when RDoc::NormalClass then 'class'
|
||||
when RDoc::SingleClass then 'class <<'
|
||||
when RDoc::NormalModule then 'module'
|
||||
end
|
||||
|
||||
def print_alias(*) end
|
||||
if cm.fully_documented? then
|
||||
next
|
||||
elsif cm.in_files.empty? or
|
||||
(cm.constants.empty? and cm.method_list.empty?) then
|
||||
report << "# #{type} #{cm.full_name} is referenced but empty."
|
||||
report << '#'
|
||||
report << '# It probably came from another project. ' \
|
||||
'I\'m sorry I\'m holding it against you.'
|
||||
report << nil
|
||||
|
||||
##
|
||||
# Prints when a class is added
|
||||
next
|
||||
elsif cm.documented? then
|
||||
report << "#{type} #{cm.full_name} # is documented"
|
||||
else
|
||||
report << '# in files:'
|
||||
|
||||
def print_class(*) end
|
||||
|
||||
##
|
||||
# Prints when a constant is added
|
||||
|
||||
def print_constant(*) end
|
||||
|
||||
##
|
||||
# Prints when a file is added
|
||||
|
||||
def print_file(*) end
|
||||
|
||||
##
|
||||
# Prints when a method is added
|
||||
|
||||
def print_method(*) end
|
||||
|
||||
##
|
||||
# Prints when a module is added
|
||||
|
||||
def print_module(*) end
|
||||
|
||||
##
|
||||
# Prints when RDoc is done
|
||||
|
||||
def done_adding(*) end
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
# Stats printer that prints just the files being documented with a progress
|
||||
# bar
|
||||
|
||||
class Normal < Quiet
|
||||
|
||||
def begin_adding # :nodoc:
|
||||
puts "Parsing sources..."
|
||||
end
|
||||
|
||||
##
|
||||
# Prints a file with a progress bar
|
||||
|
||||
def print_file(files_so_far, filename)
|
||||
progress_bar = sprintf("%3d%% [%2d/%2d] ",
|
||||
100 * (files_so_far + 1) / @total_files,
|
||||
files_so_far + 1,
|
||||
@total_files)
|
||||
|
||||
if $stdout.tty?
|
||||
# Print a progress bar, but make sure it fits on a single line. Filename
|
||||
# will be truncated if necessary.
|
||||
terminal_width = (ENV['COLUMNS'] || 80).to_i
|
||||
max_filename_size = terminal_width - progress_bar.size
|
||||
if filename.size > max_filename_size
|
||||
# Turn "some_long_filename.rb" to "...ong_filename.rb"
|
||||
filename = filename[(filename.size - max_filename_size) .. -1]
|
||||
filename[0..2] = "..."
|
||||
cm.in_files.each do |file|
|
||||
report << "# #{file.full_name}"
|
||||
end
|
||||
|
||||
# Pad the line with whitespaces so that leftover output from the
|
||||
# previous line doesn't show up.
|
||||
line = "#{progress_bar}#{filename}"
|
||||
padding = terminal_width - line.size
|
||||
line << (" " * padding) if padding > 0
|
||||
report << nil
|
||||
|
||||
$stdout.print("#{line}\r")
|
||||
else
|
||||
$stdout.puts "#{progress_bar} #{filename}"
|
||||
report << "#{type} #{cm.full_name}"
|
||||
end
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
def done_adding # :nodoc:
|
||||
puts
|
||||
|
||||
unless cm.constants.empty? then
|
||||
report << nil
|
||||
|
||||
cm.each_constant do |constant|
|
||||
next if constant.documented?
|
||||
report << " # in file #{constant.file.full_name}"
|
||||
report << " #{constant.name} = nil"
|
||||
end
|
||||
end
|
||||
|
||||
unless cm.attributes.empty? then
|
||||
report << nil
|
||||
|
||||
cm.each_attribute do |attr|
|
||||
next if attr.documented?
|
||||
report << " #{attr.definition} #{attr.name} " \
|
||||
"# in file #{attr.file.full_name}"
|
||||
end
|
||||
end
|
||||
|
||||
unless cm.method_list.empty? then
|
||||
report << nil
|
||||
|
||||
cm.each_method do |method|
|
||||
next if method.documented?
|
||||
report << " # in file #{method.file.full_name}"
|
||||
report << " def #{method.name}#{method.params}; end"
|
||||
report << nil
|
||||
end
|
||||
end
|
||||
|
||||
report << 'end'
|
||||
report << nil
|
||||
end
|
||||
|
||||
report.join "\n"
|
||||
end
|
||||
|
||||
##
|
||||
# Stats printer that prints everything documented, including the documented
|
||||
# status
|
||||
# Returns a summary of the collected statistics.
|
||||
|
||||
class Verbose < Normal
|
||||
def summary
|
||||
calculate
|
||||
|
||||
##
|
||||
# Returns a marker for RDoc::CodeObject +co+ being undocumented
|
||||
report = []
|
||||
report << 'Files: %5d' % @num_files
|
||||
report << nil
|
||||
report << 'Classes: %5d (%5d undocumented)' % [@num_classes,
|
||||
@undoc_classes]
|
||||
report << 'Modules: %5d (%5d undocumented)' % [@num_modules,
|
||||
@undoc_modules]
|
||||
report << 'Constants: %5d (%5d undocumented)' % [@num_constants,
|
||||
@undoc_constants]
|
||||
report << 'Attributes: %5d (%5d undocumented)' % [@num_attributes,
|
||||
@undoc_attributes]
|
||||
report << 'Methods: %5d (%5d undocumented)' % [@num_methods,
|
||||
@undoc_methods]
|
||||
report << nil
|
||||
report << 'Total: %5d (%5d undocumented)' % [@num_items,
|
||||
@undoc_items]
|
||||
|
||||
def nodoc co
|
||||
" (undocumented)" unless co.documented?
|
||||
end
|
||||
|
||||
def print_alias as # :nodoc:
|
||||
puts "\t\talias #{as.new_name} #{as.old_name}#{nodoc as}"
|
||||
end
|
||||
|
||||
def print_class(klass) # :nodoc:
|
||||
puts "\tclass #{klass.full_name}#{nodoc klass}"
|
||||
end
|
||||
|
||||
def print_constant(constant) # :nodoc:
|
||||
puts "\t\t#{constant.name}#{nodoc constant}"
|
||||
end
|
||||
|
||||
def print_file(files_so_far, file) # :nodoc:
|
||||
super
|
||||
puts
|
||||
end
|
||||
|
||||
def print_method(method) # :nodoc:
|
||||
puts "\t\t#{method.singleton ? '::' : '#'}#{method.name}#{nodoc method}"
|
||||
end
|
||||
|
||||
def print_module(mod) # :nodoc:
|
||||
puts "\tmodule #{mod.full_name}#{nodoc mod}"
|
||||
end
|
||||
report << '%6.2f%% documented' % @percent_doc if @percent_doc
|
||||
report << nil
|
||||
report << 'Elapsed: %0.1fs' % (Time.now - @start)
|
||||
|
||||
report.join "\n"
|
||||
end
|
||||
|
||||
autoload :Quiet, 'rdoc/stats/quiet'
|
||||
autoload :Normal, 'rdoc/stats/normal'
|
||||
autoload :Verbose, 'rdoc/stats/verbose'
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
##
|
||||
# Stats printer that prints just the files being documented with a progress
|
||||
# bar
|
||||
|
||||
class RDoc::Stats::Normal < RDoc::Stats::Quiet
|
||||
|
||||
def begin_adding # :nodoc:
|
||||
puts "Parsing sources..."
|
||||
end
|
||||
|
||||
##
|
||||
# Prints a file with a progress bar
|
||||
|
||||
def print_file files_so_far, filename
|
||||
progress_bar = sprintf("%3d%% [%2d/%2d] ",
|
||||
100 * files_so_far / @num_files,
|
||||
files_so_far,
|
||||
@num_files)
|
||||
|
||||
if $stdout.tty? then
|
||||
# Print a progress bar, but make sure it fits on a single line. Filename
|
||||
# will be truncated if necessary.
|
||||
terminal_width = (ENV['COLUMNS'] || 80).to_i
|
||||
max_filename_size = terminal_width - progress_bar.size
|
||||
|
||||
if filename.size > max_filename_size then
|
||||
# Turn "some_long_filename.rb" to "...ong_filename.rb"
|
||||
filename = filename[(filename.size - max_filename_size) .. -1]
|
||||
filename[0..2] = "..."
|
||||
end
|
||||
|
||||
# Pad the line with whitespaces so that leftover output from the
|
||||
# previous line doesn't show up.
|
||||
line = "#{progress_bar}#{filename}"
|
||||
padding = terminal_width - line.size
|
||||
line << (" " * padding) if padding > 0
|
||||
|
||||
$stdout.print("#{line}\r")
|
||||
else
|
||||
$stdout.puts "#{progress_bar} #{filename}"
|
||||
end
|
||||
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
def done_adding # :nodoc:
|
||||
puts
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
##
|
||||
# Stats printer that prints nothing
|
||||
|
||||
class RDoc::Stats::Quiet
|
||||
|
||||
##
|
||||
# Creates a new Quiet that will print nothing
|
||||
|
||||
def initialize num_files
|
||||
@num_files = num_files
|
||||
end
|
||||
|
||||
##
|
||||
# Prints a message at the beginning of parsing
|
||||
|
||||
def begin_adding(*) end
|
||||
|
||||
##
|
||||
# Prints when an alias is added
|
||||
|
||||
def print_alias(*) end
|
||||
|
||||
##
|
||||
# Prints when an attribute is added
|
||||
|
||||
def print_attribute(*) end
|
||||
|
||||
##
|
||||
# Prints when a class is added
|
||||
|
||||
def print_class(*) end
|
||||
|
||||
##
|
||||
# Prints when a constant is added
|
||||
|
||||
def print_constant(*) end
|
||||
|
||||
##
|
||||
# Prints when a file is added
|
||||
|
||||
def print_file(*) end
|
||||
|
||||
##
|
||||
# Prints when a method is added
|
||||
|
||||
def print_method(*) end
|
||||
|
||||
##
|
||||
# Prints when a module is added
|
||||
|
||||
def print_module(*) end
|
||||
|
||||
##
|
||||
# Prints when RDoc is done
|
||||
|
||||
def done_adding(*) end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
##
|
||||
# Stats printer that prints everything documented, including the documented
|
||||
# status
|
||||
|
||||
class RDoc::Stats::Verbose < RDoc::Stats::Normal
|
||||
|
||||
##
|
||||
# Returns a marker for RDoc::CodeObject +co+ being undocumented
|
||||
|
||||
def nodoc co
|
||||
" (undocumented)" unless co.documented?
|
||||
end
|
||||
|
||||
def print_alias as # :nodoc:
|
||||
puts " alias #{as.new_name} #{as.old_name}#{nodoc as}"
|
||||
end
|
||||
|
||||
def print_attribute attribute # :nodoc:
|
||||
puts " #{attribute.definition} #{attribute.name}#{nodoc attribute}"
|
||||
end
|
||||
|
||||
def print_class(klass) # :nodoc:
|
||||
puts " class #{klass.full_name}#{nodoc klass}"
|
||||
end
|
||||
|
||||
def print_constant(constant) # :nodoc:
|
||||
puts " #{constant.name}#{nodoc constant}"
|
||||
end
|
||||
|
||||
def print_file(files_so_far, file) # :nodoc:
|
||||
super
|
||||
puts
|
||||
end
|
||||
|
||||
def print_method(method) # :nodoc:
|
||||
puts " #{method.singleton ? '::' : '#'}#{method.name}#{nodoc method}"
|
||||
end
|
||||
|
||||
def print_module(mod) # :nodoc:
|
||||
puts " module #{mod.full_name}#{nodoc mod}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
231
lib/rdoc/task.rb
231
lib/rdoc/task.rb
|
@ -21,13 +21,238 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#++
|
||||
|
||||
require 'rubygems'
|
||||
begin
|
||||
gem 'rdoc'
|
||||
rescue Gem::LoadError
|
||||
end
|
||||
|
||||
begin
|
||||
gem 'rake'
|
||||
rescue Gem::LoadError
|
||||
end
|
||||
|
||||
require 'rdoc'
|
||||
require 'rake'
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/tasklib'
|
||||
|
||||
##
|
||||
# Create a documentation task that will generate the RDoc files for a project.
|
||||
#
|
||||
# The RDoc::Task will create the following targets:
|
||||
#
|
||||
# [rdoc]
|
||||
# Main task for this RDoc task.
|
||||
#
|
||||
# [clobber_rdoc]
|
||||
# Delete all the rdoc files. This target is automatically added to the main
|
||||
# clobber target.
|
||||
#
|
||||
# [rerdoc]
|
||||
# Rebuild the rdoc files from scratch, even if they are not out of date.
|
||||
#
|
||||
# Simple Example:
|
||||
#
|
||||
# RDoc::Task.new do |rd|
|
||||
# rd.main = "README.rdoc"
|
||||
# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
||||
# end
|
||||
#
|
||||
# The +rd+ object passed to the block is an RDoc::Task object. See the
|
||||
# attributes list for the RDoc::Task class for available customization options.
|
||||
#
|
||||
# == Specifying different task names
|
||||
#
|
||||
# You may wish to give the task a different name, such as if you are
|
||||
# generating two sets of documentation. For instance, if you want to have a
|
||||
# development set of documentation including private methods:
|
||||
#
|
||||
# RDoc::Task.new :rdoc_dev do |rd|
|
||||
# rd.main = "README.doc"
|
||||
# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
||||
# rd.options << "--all"
|
||||
# end
|
||||
#
|
||||
# The tasks would then be named :<em>rdoc_dev</em>,
|
||||
# :clobber_<em>rdoc_dev</em>, and :re<em>rdoc_dev</em>.
|
||||
#
|
||||
# If you wish to have completely different task names, then pass a Hash as
|
||||
# first argument. With the <tt>:rdoc</tt>, <tt>:clobber_rdoc</tt> and
|
||||
# <tt>:rerdoc</tt> options, you can customize the task names to your liking.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean",
|
||||
# :rerdoc => "rdoc:force")
|
||||
#
|
||||
# This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc:clean</tt> and
|
||||
# <tt>:rdoc:force</tt>.
|
||||
|
||||
class RDoc::Task < Rake::TaskLib
|
||||
|
||||
##
|
||||
# Name of the main, top level task. (default is :rdoc)
|
||||
|
||||
attr_accessor :name
|
||||
|
||||
##
|
||||
# Name of directory to receive the html output files. (default is "html")
|
||||
|
||||
attr_accessor :rdoc_dir
|
||||
|
||||
##
|
||||
# Title of RDoc documentation. (defaults to rdoc's default)
|
||||
|
||||
attr_accessor :title
|
||||
|
||||
##
|
||||
# Name of file to be used as the main, top level file of the RDoc. (default
|
||||
# is none)
|
||||
|
||||
attr_accessor :main
|
||||
|
||||
##
|
||||
# Name of template to be used by rdoc. (defaults to rdoc's default)
|
||||
|
||||
attr_accessor :template
|
||||
|
||||
##
|
||||
# List of files to be included in the rdoc generation. (default is [])
|
||||
|
||||
attr_accessor :rdoc_files
|
||||
|
||||
##
|
||||
# Additional list of options to be passed rdoc. (default is [])
|
||||
|
||||
attr_accessor :options
|
||||
|
||||
##
|
||||
# Whether to run the rdoc process as an external shell (default is false)
|
||||
|
||||
attr_accessor :external
|
||||
|
||||
##
|
||||
# Create an RDoc task with the given name. See the RDoc::Task class overview
|
||||
# for documentation.
|
||||
|
||||
def initialize(name = :rdoc) # :yield: self
|
||||
if name.is_a? Hash then
|
||||
invalid_options = name.keys.map { |k| k.to_sym } -
|
||||
[:rdoc, :clobber_rdoc, :rerdoc]
|
||||
|
||||
unless invalid_options.empty? then
|
||||
raise ArgumentError, "invalid options: #{invalid_options.join(", ")}"
|
||||
end
|
||||
end
|
||||
|
||||
@name = name
|
||||
@rdoc_files = Rake::FileList.new
|
||||
@rdoc_dir = 'html'
|
||||
@main = nil
|
||||
@title = nil
|
||||
@template = nil
|
||||
@options = []
|
||||
yield self if block_given?
|
||||
define
|
||||
end
|
||||
|
||||
##
|
||||
# Create the tasks defined by this task lib.
|
||||
|
||||
def define
|
||||
desc "Build RDoc HTML files"
|
||||
task rdoc_task_name
|
||||
|
||||
desc "Rebuild RDoc HTML files"
|
||||
task rerdoc_task_name => [clobber_task_name, rdoc_task_name]
|
||||
|
||||
desc "Remove RDoc HTML files"
|
||||
task clobber_task_name do
|
||||
rm_r @rdoc_dir rescue nil
|
||||
end
|
||||
|
||||
task :clobber => [clobber_task_name]
|
||||
|
||||
directory @rdoc_dir
|
||||
|
||||
rdoc_target_deps = [
|
||||
@rdoc_files,
|
||||
Rake.application.rakefile
|
||||
].flatten.compact
|
||||
|
||||
task rdoc_task_name => [rdoc_target]
|
||||
file rdoc_target => rdoc_target_deps do
|
||||
@before_running_rdoc.call if @before_running_rdoc
|
||||
args = option_list + @rdoc_files
|
||||
|
||||
if Rake.application.options.trace then
|
||||
$stderr.puts "rdoc #{args.join ' '}"
|
||||
end
|
||||
require 'rdoc/rdoc'
|
||||
RDoc::RDoc.new.document(args)
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
##
|
||||
# List of options that will be supplied to RDoc
|
||||
|
||||
def option_list
|
||||
result = @options.dup
|
||||
result << "-o" << @rdoc_dir
|
||||
result << "--main" << main if main
|
||||
result << "--title" << title if title
|
||||
result << "-T" << template if template
|
||||
result
|
||||
end
|
||||
|
||||
##
|
||||
# The block passed to this method will be called just before running the
|
||||
# RDoc generator. It is allowed to modify RDoc::Task attributes inside the
|
||||
# block.
|
||||
|
||||
def before_running_rdoc(&block)
|
||||
@before_running_rdoc = block
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rdoc_target
|
||||
"#{rdoc_dir}/index.html"
|
||||
end
|
||||
|
||||
def rdoc_task_name
|
||||
case name
|
||||
when Hash then (name[:rdoc] || "rdoc").to_s
|
||||
else name.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def clobber_task_name
|
||||
case name
|
||||
when Hash then (name[:clobber_rdoc] || "clobber_rdoc").to_s
|
||||
else "clobber_#{name}"
|
||||
end
|
||||
end
|
||||
|
||||
def rerdoc_task_name
|
||||
case name
|
||||
when Hash then (name[:rerdoc] || "rerdoc").to_s
|
||||
else "re#{name}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
module RDoc
|
||||
Task = Rake::RDocTask
|
||||
module Rake
|
||||
|
||||
##
|
||||
# For backwards compatibility
|
||||
|
||||
RDocTask = RDoc::Task
|
||||
|
||||
end
|
||||
# :startdoc:
|
||||
|
||||
|
|
137
lib/rdoc/text.rb
137
lib/rdoc/text.rb
|
@ -1,8 +1,43 @@
|
|||
# coding: utf-8
|
||||
|
||||
##
|
||||
# For RDoc::Text#to_html
|
||||
|
||||
require 'strscan'
|
||||
|
||||
##
|
||||
# Methods for manipulating comment text
|
||||
|
||||
module RDoc::Text
|
||||
|
||||
##
|
||||
# Maps an encoding to a Hash of characters properly transcoded for that
|
||||
# encoding.
|
||||
#
|
||||
# See also encode_fallback.
|
||||
|
||||
TO_HTML_CHARACTERS = Hash.new do |h, encoding|
|
||||
h[encoding] = {
|
||||
:close_dquote => encode_fallback('”', encoding, '"'),
|
||||
:close_squote => encode_fallback('’', encoding, '\''),
|
||||
:copyright => encode_fallback('©', encoding, '(c)'),
|
||||
:ellipsis => encode_fallback('…', encoding, '...'),
|
||||
:em_dash => encode_fallback('—', encoding, '---'),
|
||||
:en_dash => encode_fallback('–', encoding, '--'),
|
||||
:open_dquote => encode_fallback('“', encoding, '"'),
|
||||
:open_squote => encode_fallback('‘', encoding, '\''),
|
||||
:trademark => encode_fallback('®', encoding, '(r)'),
|
||||
}
|
||||
end if Object.const_defined? :Encoding
|
||||
|
||||
##
|
||||
# Transcodes +character+ to +encoding+ with a +fallback+ character.
|
||||
|
||||
def self.encode_fallback character, encoding, fallback
|
||||
character.encode(encoding, :fallback => { character => fallback },
|
||||
:undef => :replace, :replace => fallback)
|
||||
end
|
||||
|
||||
##
|
||||
# Expands tab characters in +text+ to eight spaces
|
||||
|
||||
|
@ -43,8 +78,7 @@ module RDoc::Text
|
|||
end
|
||||
|
||||
##
|
||||
# Convert a string in markup format into HTML. Removes the first paragraph
|
||||
# tags if +remove_para+ is true.
|
||||
# Convert a string in markup format into HTML.
|
||||
#
|
||||
# Requires the including class to implement #formatter
|
||||
|
||||
|
@ -105,7 +139,7 @@ http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse
|
|||
|
||||
def strip_hashes text
|
||||
return text if text =~ /^(?>\s*)[^\#]/
|
||||
text.gsub(/^\s*(#+)/) { $1.tr '#',' ' }
|
||||
text.gsub(/^\s*(#+)/) { $1.tr '#',' ' }.gsub(/^\s+$/, '')
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -123,7 +157,102 @@ http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse
|
|||
text.sub! %r%/\*+% do " " * $&.length end
|
||||
text.sub! %r%\*+/% do " " * $&.length end
|
||||
text.gsub! %r%^[ \t]*\*%m do " " * $&.length end
|
||||
text
|
||||
text.gsub(/^\s+$/, '')
|
||||
end
|
||||
|
||||
##
|
||||
# Converts ampersand, dashes, ellipsis, quotes, copyright and registered
|
||||
# trademark symbols in +text+ to properly encoded characters.
|
||||
|
||||
def to_html text
|
||||
if Object.const_defined? :Encoding then
|
||||
html = ''.encode text.encoding
|
||||
|
||||
encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding]
|
||||
else
|
||||
html = ''
|
||||
encoded = {
|
||||
:close_dquote => '”',
|
||||
:close_squote => '’',
|
||||
:copyright => '©',
|
||||
:ellipsis => '…',
|
||||
:em_dash => '—',
|
||||
:en_dash => '–',
|
||||
:open_dquote => '“',
|
||||
:open_squote => '‘',
|
||||
:trademark => '®',
|
||||
}
|
||||
end
|
||||
|
||||
s = StringScanner.new text
|
||||
insquotes = false
|
||||
indquotes = false
|
||||
after_word = nil
|
||||
|
||||
until s.eos? do
|
||||
case
|
||||
when s.scan(/<tt>.*?<\/tt>/) then # skip contents of tt
|
||||
html << s.matched.gsub('\\\\', '\\')
|
||||
when s.scan(/<tt>.*?/) then
|
||||
warn 'mismatched <tt> tag' # TODO signal file/line
|
||||
html << s.matched
|
||||
when s.scan(/<[^>]+\/?s*>/) then # skip HTML tags
|
||||
html << s.matched
|
||||
when s.scan(/\\(\S)/) then # unhandled suppressed crossref
|
||||
html << s[1]
|
||||
after_word = nil
|
||||
when s.scan(/\.\.\.(\.?)/) then
|
||||
html << s[1] << encoded[:ellipsis]
|
||||
after_word = nil
|
||||
when s.scan(/\(c\)/) then
|
||||
html << encoded[:copyright]
|
||||
after_word = nil
|
||||
when s.scan(/\(r\)/) then
|
||||
html << encoded[:trademark]
|
||||
after_word = nil
|
||||
when s.scan(/---/) then
|
||||
html << encoded[:em_dash]
|
||||
after_word = nil
|
||||
when s.scan(/--/) then
|
||||
html << encoded[:en_dash]
|
||||
after_word = nil
|
||||
when s.scan(/"|"/) then
|
||||
html << encoded[indquotes ? :close_dquote : :open_dquote]
|
||||
indquotes = !indquotes
|
||||
after_word = nil
|
||||
when s.scan(/``/) then # backtick double quote
|
||||
html << encoded[:open_dquote]
|
||||
after_word = nil
|
||||
when s.scan(/''/) then # tick double quote
|
||||
html << encoded[:close_dquote]
|
||||
after_word = nil
|
||||
when s.scan(/'/) then # single quote
|
||||
if insquotes
|
||||
html << encoded[:close_squote]
|
||||
insquotes = false
|
||||
elsif after_word
|
||||
# Mary's dog, my parents' house: do not start paired quotes
|
||||
html << encoded[:close_squote]
|
||||
else
|
||||
html << encoded[:open_squote]
|
||||
insquotes = true
|
||||
end
|
||||
|
||||
after_word = nil
|
||||
else # advance to the next potentially significant character
|
||||
match = s.scan(/.+?(?=[<\\.("'`&-])/) #"
|
||||
|
||||
if match then
|
||||
html << match
|
||||
after_word = match =~ /\w$/
|
||||
else
|
||||
html << s.rest
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
html
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
module RDoc; end
|
||||
|
||||
##
|
||||
# A TokenStream is a list of tokens, gathered during the parse of some entity
|
||||
# (say a method). Entities populate these streams by being registered with the
|
|
@ -20,7 +20,14 @@ class RDoc::TopLevel < RDoc::Context
|
|||
|
||||
attr_accessor :absolute_name
|
||||
|
||||
attr_accessor :diagram
|
||||
##
|
||||
# All the classes or modules that were declared in
|
||||
# this file. These are assigned to either +#classes_hash+
|
||||
# or +#modules_hash+ once we know what they really are.
|
||||
|
||||
attr_reader :classes_or_modules
|
||||
|
||||
attr_accessor :diagram # :nodoc:
|
||||
|
||||
##
|
||||
# The parser that processed this file
|
||||
|
@ -28,45 +35,110 @@ class RDoc::TopLevel < RDoc::Context
|
|||
attr_accessor :parser
|
||||
|
||||
##
|
||||
# Returns all classes and modules discovered by RDoc
|
||||
# Returns all classes discovered by RDoc
|
||||
|
||||
def self.all_classes_and_modules
|
||||
classes_hash.values + modules_hash.values
|
||||
def self.all_classes
|
||||
@all_classes_hash.values
|
||||
end
|
||||
|
||||
##
|
||||
# Returns all classes discovered by RDoc
|
||||
# Returns all classes and modules discovered by RDoc
|
||||
|
||||
def self.classes
|
||||
classes_hash.values
|
||||
def self.all_classes_and_modules
|
||||
@all_classes_hash.values + @all_modules_hash.values
|
||||
end
|
||||
|
||||
##
|
||||
# Hash of all classes known to RDoc
|
||||
|
||||
def self.classes_hash
|
||||
@all_classes
|
||||
def self.all_classes_hash
|
||||
@all_classes_hash
|
||||
end
|
||||
|
||||
##
|
||||
# All TopLevels known to RDoc
|
||||
|
||||
def self.files
|
||||
@all_files.values
|
||||
def self.all_files
|
||||
@all_files_hash.values
|
||||
end
|
||||
|
||||
##
|
||||
# Hash of all files known to RDoc
|
||||
|
||||
def self.files_hash
|
||||
@all_files
|
||||
def self.all_files_hash
|
||||
@all_files_hash
|
||||
end
|
||||
|
||||
##
|
||||
# Returns all modules discovered by RDoc
|
||||
|
||||
def self.all_modules
|
||||
all_modules_hash.values
|
||||
end
|
||||
|
||||
##
|
||||
# Hash of all modules known to RDoc
|
||||
|
||||
def self.all_modules_hash
|
||||
@all_modules_hash
|
||||
end
|
||||
|
||||
##
|
||||
# Prepares the RDoc code object tree for use by a generator.
|
||||
#
|
||||
# It finds unique classes/modules defined, and replaces classes/modules that
|
||||
# are aliases for another one by a copy with RDoc::ClassModule#is_alias_for
|
||||
# set.
|
||||
#
|
||||
# It updates the RDoc::ClassModule#constant_aliases attribute of "real"
|
||||
# classes or modules.
|
||||
#
|
||||
# It also completely removes the classes and modules that should be removed
|
||||
# from the documentation and the methods that have a visibility below
|
||||
# +min_visibility+, which is the <tt>--visibility</tt> option.
|
||||
#
|
||||
# See also RDoc::Context#remove_from_documentation?
|
||||
|
||||
def self.complete min_visibility
|
||||
fix_basic_object_inheritance
|
||||
|
||||
# cache included modules before they are removed from the documentation
|
||||
all_classes_and_modules.each { |cm| cm.ancestors }
|
||||
|
||||
remove_nodoc @all_classes_hash
|
||||
remove_nodoc @all_modules_hash
|
||||
|
||||
@unique_classes = find_unique @all_classes_hash
|
||||
@unique_modules = find_unique @all_modules_hash
|
||||
|
||||
unique_classes_and_modules.each do |cm|
|
||||
cm.complete min_visibility
|
||||
end
|
||||
|
||||
@all_files_hash.each_key do |file_name|
|
||||
tl = @all_files_hash[file_name]
|
||||
|
||||
unless RDoc::Parser::Simple === tl.parser then
|
||||
tl.modules_hash.clear
|
||||
tl.classes_hash.clear
|
||||
|
||||
tl.classes_or_modules.each do |cm|
|
||||
name = cm.full_name
|
||||
if cm.type == 'class' then
|
||||
tl.classes_hash[name] = cm if @all_classes_hash[name]
|
||||
else
|
||||
tl.modules_hash[name] = cm if @all_modules_hash[name]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Finds the class with +name+ in all discovered classes
|
||||
|
||||
def self.find_class_named(name)
|
||||
classes_hash[name]
|
||||
@all_classes_hash[name]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -91,9 +163,7 @@ class RDoc::TopLevel < RDoc::Context
|
|||
# Finds the class or module with +name+
|
||||
|
||||
def self.find_class_or_module(name)
|
||||
name =~ /^::/
|
||||
name = $' || name
|
||||
|
||||
name = $' if name =~ /^::/
|
||||
RDoc::TopLevel.classes_hash[name] || RDoc::TopLevel.modules_hash[name]
|
||||
end
|
||||
|
||||
|
@ -101,7 +171,7 @@ class RDoc::TopLevel < RDoc::Context
|
|||
# Finds the file with +name+ in all discovered files
|
||||
|
||||
def self.find_file_named(name)
|
||||
@all_files[name]
|
||||
@all_files_hash[name]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -112,26 +182,98 @@ class RDoc::TopLevel < RDoc::Context
|
|||
end
|
||||
|
||||
##
|
||||
# Returns all modules discovered by RDoc
|
||||
# Finds unique classes/modules defined in +all_hash+,
|
||||
# and returns them as an array. Performs the alias
|
||||
# updates in +all_hash+: see ::complete.
|
||||
#--
|
||||
# TODO aliases should be registered by Context#add_module_alias
|
||||
|
||||
def self.modules
|
||||
modules_hash.values
|
||||
def self.find_unique(all_hash)
|
||||
unique = []
|
||||
|
||||
all_hash.each_pair do |full_name, cm|
|
||||
unique << cm if full_name == cm.full_name
|
||||
end
|
||||
|
||||
unique
|
||||
end
|
||||
|
||||
##
|
||||
# Hash of all modules known to RDoc
|
||||
# Fixes the erroneous <tt>BasicObject < Object</tt> in 1.9.
|
||||
#
|
||||
# Because we assumed all classes without a stated superclass
|
||||
# inherit from Object, we have the above wrong inheritance.
|
||||
#
|
||||
# We fix BasicObject right away if we are running in a Ruby
|
||||
# version >= 1.9. If not, we may be documenting 1.9 source
|
||||
# while running under 1.8: we search the files of BasicObject
|
||||
# for "object.c", and fix the inheritance if we find it.
|
||||
|
||||
def self.modules_hash
|
||||
@all_modules
|
||||
def self.fix_basic_object_inheritance
|
||||
basic = all_classes_hash['BasicObject']
|
||||
return unless basic
|
||||
if RUBY_VERSION >= '1.9'
|
||||
basic.superclass = nil
|
||||
elsif basic.in_files.any? { |f| File.basename(f.full_name) == 'object.c' }
|
||||
basic.superclass = nil
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Removes from +all_hash+ the contexts that are nodoc or have no content.
|
||||
#
|
||||
# See RDoc::Context#remove_from_documentation?
|
||||
|
||||
def self.remove_nodoc(all_hash)
|
||||
all_hash.keys.each do |name|
|
||||
context = all_hash[name]
|
||||
all_hash.delete(name) if context.remove_from_documentation?
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Empties RDoc of stored class, module and file information
|
||||
|
||||
def self.reset
|
||||
@all_classes = {}
|
||||
@all_modules = {}
|
||||
@all_files = {}
|
||||
@all_classes_hash = {}
|
||||
@all_modules_hash = {}
|
||||
@all_files_hash = {}
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the unique classes discovered by RDoc.
|
||||
#
|
||||
# ::complete must have been called prior to using this method.
|
||||
|
||||
def self.unique_classes
|
||||
@unique_classes
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the unique classes and modules discovered by RDoc.
|
||||
# ::complete must have been called prior to using this method.
|
||||
|
||||
def self.unique_classes_and_modules
|
||||
@unique_classes + @unique_modules
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the unique modules discovered by RDoc.
|
||||
# ::complete must have been called prior to using this method.
|
||||
|
||||
def self.unique_modules
|
||||
@unique_modules
|
||||
end
|
||||
|
||||
class << self
|
||||
alias classes all_classes
|
||||
alias classes_hash all_classes_hash
|
||||
|
||||
alias files all_files
|
||||
alias files_hash all_files_hash
|
||||
|
||||
alias modules all_modules
|
||||
alias modules_hash all_modules_hash
|
||||
end
|
||||
|
||||
reset
|
||||
|
@ -148,17 +290,49 @@ class RDoc::TopLevel < RDoc::Context
|
|||
@diagram = nil
|
||||
@parser = nil
|
||||
|
||||
@classes_or_modules = []
|
||||
|
||||
RDoc::TopLevel.files_hash[file_name] = self
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +method+ to Object instead of RDoc::TopLevel
|
||||
# Adds +an_alias+ to +Object+ instead of +self+.
|
||||
|
||||
def add_alias(an_alias)
|
||||
return an_alias unless @document_self
|
||||
object_class.add_alias an_alias
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +constant+ to +Object+ instead of +self+.
|
||||
|
||||
def add_constant(constant)
|
||||
return constant unless @document_self
|
||||
object_class.add_constant constant
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +include+ to +Object+ instead of +self+.
|
||||
|
||||
def add_include(include)
|
||||
return include unless @document_self
|
||||
object_class.add_include include
|
||||
end
|
||||
|
||||
##
|
||||
# Adds +method+ to +Object+ instead of +self+.
|
||||
|
||||
def add_method(method)
|
||||
object = self.class.find_class_named 'Object'
|
||||
object = add_class RDoc::NormalClass, 'Object' unless object
|
||||
return method unless @document_self
|
||||
object_class.add_method method
|
||||
end
|
||||
|
||||
object.add_method method
|
||||
##
|
||||
# Adds class or module +mod+. Used in the building phase
|
||||
# by the ruby parser.
|
||||
|
||||
def add_to_classes_or_modules mod
|
||||
@classes_or_modules << mod
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -168,8 +342,13 @@ class RDoc::TopLevel < RDoc::Context
|
|||
File.basename @absolute_name
|
||||
end
|
||||
|
||||
alias name base_name
|
||||
|
||||
##
|
||||
# See RDoc::TopLevel.find_class_or_module
|
||||
# See RDoc::TopLevel::find_class_or_module
|
||||
#--
|
||||
# TODO Why do we search through all classes/modules found, not just the
|
||||
# ones of this instance?
|
||||
|
||||
def find_class_or_module name
|
||||
RDoc::TopLevel.find_class_or_module name
|
||||
|
@ -186,11 +365,11 @@ class RDoc::TopLevel < RDoc::Context
|
|||
# Finds a module or class with +name+
|
||||
|
||||
def find_module_named(name)
|
||||
find_class_or_module(name) || find_enclosing_module_named(name)
|
||||
find_class_or_module(name)
|
||||
end
|
||||
|
||||
##
|
||||
# The name of this file
|
||||
# Returns the relative name of this file
|
||||
|
||||
def full_name
|
||||
@relative_name
|
||||
|
@ -215,16 +394,24 @@ class RDoc::TopLevel < RDoc::Context
|
|||
end
|
||||
|
||||
##
|
||||
# Date this file was last modified, if known
|
||||
# Time this file was last modified, if known
|
||||
|
||||
def last_modified
|
||||
@file_stat ? file_stat.mtime.to_s : 'Unknown'
|
||||
@file_stat ? file_stat.mtime : nil
|
||||
end
|
||||
|
||||
##
|
||||
# Base name of this file
|
||||
# Returns the NormalClass "Object", creating it if not found.
|
||||
#
|
||||
# Records +self+ as a location in "Object".
|
||||
|
||||
alias name base_name
|
||||
def object_class
|
||||
@object_class ||= begin
|
||||
oc = self.class.find_class_named('Object') || add_class(RDoc::NormalClass, 'Object')
|
||||
oc.record_location self
|
||||
oc
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Path to this file
|
||||
|
@ -244,5 +431,9 @@ class RDoc::TopLevel < RDoc::Context
|
|||
end
|
||||
end
|
||||
|
||||
def to_s # :nodoc:
|
||||
"file #{full_name}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
こんにちは!
|
||||
|
||||
初めまして。アーロンと申します。
|
||||
|
|
|
@ -2,29 +2,35 @@ require 'rubygems'
|
|||
require 'minitest/autorun'
|
||||
require 'rdoc'
|
||||
require 'rdoc/markup'
|
||||
require 'rdoc/markup/formatter'
|
||||
require 'rdoc/markup/attribute_manager'
|
||||
|
||||
class TestAttributeManager < MiniTest::Unit::TestCase
|
||||
class TestAttributeManager < MiniTest::Unit::TestCase # HACK fix test name
|
||||
|
||||
def setup
|
||||
@am = RDoc::Markup::AttributeManager.new
|
||||
@klass = RDoc::Markup::AttributeManager
|
||||
@formatter = RDoc::Markup::Formatter.new
|
||||
@formatter.add_tag :BOLD, '<B>', '</B>'
|
||||
@formatter.add_tag :EM, '<EM>', '</EM>'
|
||||
@formatter.add_tag :TT, '<TT>', '</TT>'
|
||||
end
|
||||
|
||||
def test_convert_attrs_ignores_code
|
||||
collector = RDoc::Markup::AttrSpan.new 10
|
||||
str = 'foo <code>__send__</code> bar'
|
||||
@am.convert_html str, collector
|
||||
@am.convert_attrs str, collector
|
||||
assert_match(/__send__/, str)
|
||||
assert_equal 'foo <TT>__send__</TT> bar', output('foo <code>__send__</code> bar')
|
||||
end
|
||||
|
||||
def test_convert_attrs_ignores_tt
|
||||
collector = RDoc::Markup::AttrSpan.new 10
|
||||
str = 'foo <tt>__send__</tt> bar'
|
||||
@am.convert_html str, collector
|
||||
@am.convert_attrs str, collector
|
||||
assert_match(/__send__/, str)
|
||||
assert_equal 'foo <TT>__send__</TT> bar', output('foo <tt>__send__</tt> bar')
|
||||
end
|
||||
|
||||
def test_convert_attrs_preserves_double
|
||||
assert_equal 'foo.__send__ :bar', output('foo.__send__ :bar')
|
||||
assert_equal 'use __FILE__ to', output('use __FILE__ to')
|
||||
end
|
||||
|
||||
def test_convert_attrs_does_not_ignore_after_tt
|
||||
assert_equal 'the <TT>IF:</TT><EM>key</EM> directive', output('the <tt>IF:</tt>_key_ directive')
|
||||
end
|
||||
|
||||
def test_initial_word_pairs
|
||||
|
@ -73,12 +79,41 @@ class TestAttributeManager < MiniTest::Unit::TestCase
|
|||
assert(specials.has_key?("WikiWord"))
|
||||
end
|
||||
|
||||
def silently(&block)
|
||||
warn_level = $VERBOSE
|
||||
$VERBOSE = nil
|
||||
result = block.call
|
||||
$VERBOSE = warn_level
|
||||
result
|
||||
def test_escapes
|
||||
assert_equal '<TT>text</TT>', output('<tt>text</tt>')
|
||||
assert_equal '<tt>text</tt>', output('\\<tt>text</tt>')
|
||||
assert_equal '<tt>', output('\\<tt>')
|
||||
assert_equal '<TT><tt></TT>', output('<tt>\\<tt></tt>')
|
||||
assert_equal '<TT>\\<tt></TT>', output('<tt>\\\\<tt></tt>')
|
||||
assert_equal '<B>text</B>', output('*text*')
|
||||
assert_equal '*text*', output('\\*text*')
|
||||
assert_equal '\\', output('\\')
|
||||
assert_equal '\\text', output('\\text')
|
||||
assert_equal '\\\\text', output('\\\\text')
|
||||
assert_equal 'text \\ text', output('text \\ text')
|
||||
|
||||
assert_equal 'and <TT>\\s</TT> matches space',
|
||||
output('and <tt>\\s</tt> matches space')
|
||||
assert_equal 'use <TT><tt>text</TT></tt> for code',
|
||||
output('use <tt>\\<tt>text</tt></tt> for code')
|
||||
assert_equal 'use <TT><tt>text</tt></TT> for code',
|
||||
output('use <tt>\\<tt>text\\</tt></tt> for code')
|
||||
assert_equal 'use <tt><tt>text</tt></tt> for code',
|
||||
output('use \\<tt>\\<tt>text</tt></tt> for code')
|
||||
assert_equal 'use <tt><TT>text</TT></tt> for code',
|
||||
output('use \\<tt><tt>text</tt></tt> for code')
|
||||
assert_equal 'use <TT>+text+</TT> for code',
|
||||
output('use <tt>\\+text+</tt> for code')
|
||||
assert_equal 'use <tt><TT>text</TT></tt> for code',
|
||||
output('use \\<tt>+text+</tt> for code')
|
||||
assert_equal 'illegal <tag>not</tag> changed',
|
||||
output('illegal <tag>not</tag> changed')
|
||||
assert_equal 'unhandled <p>tag</p> unchanged',
|
||||
output('unhandled <p>tag</p> unchanged')
|
||||
end
|
||||
|
||||
def output str
|
||||
@formatter.convert_flow @am.flow str
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
require File.expand_path '../xref_test_case', __FILE__
|
||||
|
||||
class TestRDocAlias < XrefTestCase
|
||||
|
||||
def test_to_s
|
||||
a = RDoc::Alias.new nil, 'a', 'b', ''
|
||||
a.parent = @c2
|
||||
|
||||
assert_equal 'alias: b -> #a in: RDoc::NormalClass C2 < Object', a.to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,15 +1,17 @@
|
|||
require File.expand_path '../xref_test_case', __FILE__
|
||||
require 'rdoc/code_objects'
|
||||
require 'rdoc/generator/markup'
|
||||
|
||||
class RDocAnyMethodTest < XrefTestCase
|
||||
|
||||
def test_aref
|
||||
m = RDoc::AnyMethod.new nil, 'method?'
|
||||
|
||||
assert_equal 'method-i-method%3F', m.aref
|
||||
assert_equal 'method-i-method-3F', m.aref
|
||||
|
||||
m.singleton = true
|
||||
|
||||
assert_equal 'method-c-method%3F', m.aref
|
||||
assert_equal 'method-c-method-3F', m.aref
|
||||
end
|
||||
|
||||
def test_arglists
|
||||
|
@ -36,6 +38,45 @@ method(a, b) { |c, d| ... }
|
|||
assert_equal 'C1::m', @c1.method_list.first.full_name
|
||||
end
|
||||
|
||||
def test_markup_code
|
||||
tokens = [
|
||||
RDoc::RubyToken::TkCONSTANT. new(0, 0, 0, 'CONSTANT'),
|
||||
RDoc::RubyToken::TkKW. new(0, 0, 0, 'KW'),
|
||||
RDoc::RubyToken::TkIVAR. new(0, 0, 0, 'IVAR'),
|
||||
RDoc::RubyToken::TkOp. new(0, 0, 0, 'Op'),
|
||||
RDoc::RubyToken::TkId. new(0, 0, 0, 'Id'),
|
||||
RDoc::RubyToken::TkNode. new(0, 0, 0, 'Node'),
|
||||
RDoc::RubyToken::TkCOMMENT. new(0, 0, 0, 'COMMENT'),
|
||||
RDoc::RubyToken::TkREGEXP. new(0, 0, 0, 'REGEXP'),
|
||||
RDoc::RubyToken::TkSTRING. new(0, 0, 0, 'STRING'),
|
||||
RDoc::RubyToken::TkVal. new(0, 0, 0, 'Val'),
|
||||
RDoc::RubyToken::TkBACKSLASH.new(0, 0, 0, '\\'),
|
||||
]
|
||||
|
||||
@c2_a.collect_tokens
|
||||
@c2_a.add_tokens(*tokens)
|
||||
|
||||
expected = [
|
||||
'<span class="ruby-constant">CONSTANT</span>',
|
||||
'<span class="ruby-keyword">KW</span>',
|
||||
'<span class="ruby-ivar">IVAR</span>',
|
||||
'<span class="ruby-operator">Op</span>',
|
||||
'<span class="ruby-identifier">Id</span>',
|
||||
'<span class="ruby-node">Node</span>',
|
||||
'<span class="ruby-comment">COMMENT</span>',
|
||||
'<span class="ruby-regexp">REGEXP</span>',
|
||||
'<span class="ruby-string">STRING</span>',
|
||||
'<span class="ruby-value">Val</span>',
|
||||
'\\'
|
||||
].join
|
||||
|
||||
assert_equal expected, @c2_a.markup_code
|
||||
end
|
||||
|
||||
def test_markup_code_empty
|
||||
assert_equal '', @c2_a.markup_code
|
||||
end
|
||||
|
||||
def test_marshal_load
|
||||
instance_method = Marshal.load Marshal.dump(@c1.method_list.last)
|
||||
|
||||
|
|
|
@ -8,6 +8,12 @@ class TestRDocAttr < MiniTest::Unit::TestCase
|
|||
@a = RDoc::Attr.new nil, 'attr', 'RW', ''
|
||||
end
|
||||
|
||||
def test_aref
|
||||
m = RDoc::Attr.new nil, 'attr', 'RW', nil
|
||||
|
||||
assert_equal 'attribute-i-attr', m.aref
|
||||
end
|
||||
|
||||
def test_arglists
|
||||
assert_nil @a.arglists
|
||||
end
|
||||
|
@ -20,6 +26,18 @@ class TestRDocAttr < MiniTest::Unit::TestCase
|
|||
assert_nil @a.call_seq
|
||||
end
|
||||
|
||||
def test_definition
|
||||
assert_equal 'attr_accessor', @a.definition
|
||||
|
||||
@a.rw = 'R'
|
||||
|
||||
assert_equal 'attr_reader', @a.definition
|
||||
|
||||
@a.rw = 'W'
|
||||
|
||||
assert_equal 'attr_writer', @a.definition
|
||||
end
|
||||
|
||||
def test_full_name
|
||||
assert_equal '(unknown)#attr', @a.full_name
|
||||
end
|
||||
|
@ -33,15 +51,10 @@ class TestRDocAttr < MiniTest::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_type
|
||||
assert_equal 'attr_accessor', @a.type
|
||||
assert_equal 'instance', @a.type
|
||||
|
||||
@a.rw = 'R'
|
||||
|
||||
assert_equal 'attr_reader', @a.type
|
||||
|
||||
@a.rw = 'W'
|
||||
|
||||
assert_equal 'attr_writer', @a.type
|
||||
@a.singleton = true
|
||||
assert_equal 'class', @a.type
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -92,9 +92,142 @@ class TestRDocClassModule < XrefTestCase
|
|||
assert_equal expected, cm1.method_list.sort
|
||||
end
|
||||
|
||||
def test_remove_nodoc_children
|
||||
parent = RDoc::ClassModule.new 'A'
|
||||
parent.modules_hash.replace 'B' => true, 'C' => true
|
||||
RDoc::TopLevel.all_modules_hash.replace 'A::B' => true
|
||||
|
||||
parent.classes_hash.replace 'D' => true, 'E' => true
|
||||
RDoc::TopLevel.all_classes_hash.replace 'A::D' => true
|
||||
|
||||
parent.remove_nodoc_children
|
||||
|
||||
assert_equal %w[B], parent.modules_hash.keys
|
||||
assert_equal %w[D], parent.classes_hash.keys
|
||||
end
|
||||
|
||||
def test_superclass
|
||||
assert_equal @c3_h1, @c3_h2.superclass
|
||||
end
|
||||
|
||||
def test_update_aliases_class
|
||||
n1 = @xref_data.add_module RDoc::NormalClass, 'N1'
|
||||
n1_k2 = n1.add_module RDoc::NormalClass, 'N2'
|
||||
|
||||
n1.add_module_alias n1_k2, 'A1'
|
||||
|
||||
n1_a1_c = n1.constants.find { |c| c.name == 'A1' }
|
||||
refute_nil n1_a1_c
|
||||
assert_equal n1_k2, n1_a1_c.is_alias_for, 'sanity check'
|
||||
|
||||
n1.update_aliases
|
||||
|
||||
n1_a1_k = @xref_data.find_class_or_module 'N1::A1'
|
||||
refute_nil n1_a1_k
|
||||
assert_equal n1_k2, n1_a1_k.is_alias_for
|
||||
refute_equal n1_k2, n1_a1_k
|
||||
|
||||
assert_equal 1, n1_k2.aliases.length
|
||||
assert_equal n1_a1_k, n1_k2.aliases.first
|
||||
|
||||
assert_equal 'N1::N2', n1_k2.full_name
|
||||
assert_equal 'N1::A1', n1_a1_k.full_name
|
||||
end
|
||||
|
||||
def test_update_aliases_module
|
||||
n1 = @xref_data.add_module RDoc::NormalModule, 'N1'
|
||||
n1_n2 = n1.add_module RDoc::NormalModule, 'N2'
|
||||
|
||||
n1.add_module_alias n1_n2, 'A1'
|
||||
|
||||
n1_a1_c = n1.constants.find { |c| c.name == 'A1' }
|
||||
refute_nil n1_a1_c
|
||||
assert_equal n1_n2, n1_a1_c.is_alias_for, 'sanity check'
|
||||
|
||||
n1.update_aliases
|
||||
|
||||
n1_a1_m = @xref_data.find_class_or_module 'N1::A1'
|
||||
refute_nil n1_a1_m
|
||||
assert_equal n1_n2, n1_a1_m.is_alias_for
|
||||
refute_equal n1_n2, n1_a1_m
|
||||
|
||||
assert_equal 1, n1_n2.aliases.length
|
||||
assert_equal n1_a1_m, n1_n2.aliases.first
|
||||
|
||||
assert_equal 'N1::N2', n1_n2.full_name
|
||||
assert_equal 'N1::A1', n1_a1_m.full_name
|
||||
end
|
||||
|
||||
def test_update_aliases_reparent
|
||||
l1 = @xref_data.add_module RDoc::NormalModule, 'L1'
|
||||
l1_l2 = l1.add_module RDoc::NormalModule, 'L2'
|
||||
o1 = @xref_data.add_module RDoc::NormalModule, 'O1'
|
||||
|
||||
o1.add_module_alias l1_l2, 'A1'
|
||||
|
||||
o1_a1_c = o1.constants.find { |c| c.name == 'A1' }
|
||||
refute_nil o1_a1_c
|
||||
assert_equal l1_l2, o1_a1_c.is_alias_for
|
||||
refute_equal l1_l2, o1_a1_c
|
||||
|
||||
o1.update_aliases
|
||||
|
||||
o1_a1_m = @xref_data.find_class_or_module 'O1::A1'
|
||||
refute_nil o1_a1_m
|
||||
assert_equal l1_l2, o1_a1_m.is_alias_for
|
||||
|
||||
assert_equal 1, l1_l2.aliases.length
|
||||
assert_equal o1_a1_m, l1_l2.aliases[0]
|
||||
|
||||
assert_equal 'L1::L2', l1_l2.full_name
|
||||
assert_equal 'O1::A1', o1_a1_m.full_name
|
||||
end
|
||||
|
||||
def test_update_includes
|
||||
a = RDoc::Include.new 'M1', nil
|
||||
b = RDoc::Include.new 'M2', nil
|
||||
c = RDoc::Include.new 'C', nil
|
||||
|
||||
@c1.add_include a
|
||||
@c1.add_include b
|
||||
@c1.add_include c
|
||||
@c1.ancestors # cache included modules
|
||||
|
||||
@m1_m2.document_self = nil
|
||||
assert @m1_m2.remove_from_documentation?
|
||||
|
||||
assert RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
|
||||
refute RDoc::TopLevel.all_modules_hash[@m1_m2.full_name].nil?
|
||||
RDoc::TopLevel.remove_nodoc RDoc::TopLevel.all_modules_hash
|
||||
refute RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
|
||||
|
||||
@c1.update_includes
|
||||
|
||||
assert_equal [a, c], @c1.includes
|
||||
end
|
||||
|
||||
def test_update_includes_with_colons
|
||||
a = RDoc::Include.new 'M1', nil
|
||||
b = RDoc::Include.new 'M1::M2', nil
|
||||
c = RDoc::Include.new 'C', nil
|
||||
|
||||
@c1.add_include a
|
||||
@c1.add_include b
|
||||
@c1.add_include c
|
||||
@c1.ancestors # cache included modules
|
||||
|
||||
@m1_m2.document_self = nil
|
||||
assert @m1_m2.remove_from_documentation?
|
||||
|
||||
assert RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
|
||||
refute RDoc::TopLevel.all_modules_hash[@m1_m2.full_name].nil?
|
||||
RDoc::TopLevel.remove_nodoc RDoc::TopLevel.all_modules_hash
|
||||
refute RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
|
||||
|
||||
@c1.update_includes
|
||||
|
||||
assert_equal [a, c], @c1.includes
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ class TestRDocCodeObject < XrefTestCase
|
|||
assert @co.document_children, 'document_children'
|
||||
refute @co.force_documentation, 'force_documentation'
|
||||
refute @co.done_documenting, 'done_documenting'
|
||||
refute @co.received_nodoc, 'received_nodoc'
|
||||
assert_equal '', @co.comment, 'comment is empty'
|
||||
end
|
||||
|
||||
|
@ -33,16 +34,20 @@ class TestRDocCodeObject < XrefTestCase
|
|||
@co.document_children = false
|
||||
refute @co.document_children
|
||||
|
||||
@c2.document_children = false
|
||||
assert_empty @c2.classes
|
||||
# TODO this is not true anymore:
|
||||
# test all the nodoc stuff etc...
|
||||
#@c2.document_children = false
|
||||
#assert_empty @c2.classes
|
||||
end
|
||||
|
||||
def test_document_self_equals
|
||||
@co.document_self = false
|
||||
refute @co.document_self
|
||||
|
||||
@c1.document_self = false
|
||||
assert_empty @c1.method_list
|
||||
# TODO this is not true anymore:
|
||||
# test all the nodoc stuff etc...
|
||||
#@c1.document_self = false
|
||||
#assert_empty @c1.method_list
|
||||
end
|
||||
|
||||
def test_documented_eh
|
||||
|
@ -56,11 +61,46 @@ class TestRDocCodeObject < XrefTestCase
|
|||
|
||||
refute @co.documented?
|
||||
|
||||
@co.document_self = false
|
||||
@co.document_self = nil # notify :nodoc:
|
||||
|
||||
assert @co.documented?
|
||||
end
|
||||
|
||||
def test_done_documenting
|
||||
# once done_documenting is set, other properties refuse to go to "true"
|
||||
@co.done_documenting = true
|
||||
|
||||
@co.document_self = true
|
||||
refute @co.document_self
|
||||
|
||||
@co.document_children = true
|
||||
refute @co.document_children
|
||||
|
||||
@co.force_documentation = true
|
||||
refute @co.force_documentation
|
||||
|
||||
@co.start_doc
|
||||
refute @co.document_self
|
||||
refute @co.document_children
|
||||
|
||||
# turning done_documenting on
|
||||
# resets others to true
|
||||
|
||||
@co.done_documenting = false
|
||||
assert @co.document_self
|
||||
assert @co.document_children
|
||||
end
|
||||
|
||||
def test_full_name_equals
|
||||
@co.full_name = 'hi'
|
||||
|
||||
assert_equal 'hi', @co.instance_variable_get(:@full_name)
|
||||
|
||||
@co.full_name = nil
|
||||
|
||||
assert_nil @co.instance_variable_get(:@full_name)
|
||||
end
|
||||
|
||||
def test_metadata
|
||||
assert_empty @co.metadata
|
||||
|
||||
|
@ -84,6 +124,23 @@ class TestRDocCodeObject < XrefTestCase
|
|||
assert_equal 'C2', @c2_c3.parent_name
|
||||
end
|
||||
|
||||
def test_received_ndoc
|
||||
@co.document_self = false
|
||||
refute @co.received_nodoc
|
||||
|
||||
@co.document_self = nil
|
||||
assert @co.received_nodoc
|
||||
|
||||
@co.document_self = true
|
||||
end
|
||||
|
||||
def test_record_location
|
||||
c = RDoc::CodeObject.new
|
||||
c.record_location @xref_data
|
||||
|
||||
assert_equal 'xref_data.rb', c.file.relative_name
|
||||
end
|
||||
|
||||
def test_start_doc
|
||||
@co.document_self = false
|
||||
@co.document_children = false
|
||||
|
|
|
@ -34,13 +34,38 @@ class TestRDocContext < XrefTestCase
|
|||
|
||||
@context.add_alias as
|
||||
|
||||
assert_equal [as], @context.aliases
|
||||
assert_equal [as], @context.unmatched_alias_lists['old_name']
|
||||
assert_equal [as], @context.external_aliases
|
||||
assert_equal [as], @context.unmatched_alias_lists['#old_name']
|
||||
end
|
||||
|
||||
def test_add_alias_method_attr
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
|
||||
attr = RDoc::Attr.new nil, 'old_name', 'R', ''
|
||||
|
||||
as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
|
||||
as.record_location top_level
|
||||
as.parent = @context
|
||||
|
||||
@context.add_attribute attr
|
||||
@context.add_alias as
|
||||
|
||||
assert_empty @context.aliases
|
||||
assert_empty @context.unmatched_alias_lists
|
||||
assert_equal %w[old_name new_name], @context.attributes.map { |m| m.name }
|
||||
|
||||
new = @context.attributes.last
|
||||
assert_equal top_level, new.file
|
||||
end
|
||||
|
||||
def test_add_alias_method
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
|
||||
meth = RDoc::AnyMethod.new nil, 'old_name'
|
||||
meth.singleton = false
|
||||
|
||||
as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
|
||||
as.record_location top_level
|
||||
as.parent = @context
|
||||
|
||||
@context.add_method meth
|
||||
|
@ -49,28 +74,28 @@ class TestRDocContext < XrefTestCase
|
|||
assert_empty @context.aliases
|
||||
assert_empty @context.unmatched_alias_lists
|
||||
assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
|
||||
|
||||
new = @context.method_list.last
|
||||
assert_equal top_level, new.file
|
||||
end
|
||||
|
||||
def test_add_alias_impl
|
||||
def test_add_alias_method_singleton
|
||||
meth = RDoc::AnyMethod.new nil, 'old_name'
|
||||
meth.comment = 'old comment'
|
||||
meth.singleton = false
|
||||
meth.visibility = :private
|
||||
meth.singleton = true
|
||||
|
||||
alas = RDoc::Alias.new nil, 'old_name', 'new_name', 'new comment'
|
||||
as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment'
|
||||
as.singleton = true
|
||||
|
||||
@context.add_alias_impl alas, meth
|
||||
as.parent = @context
|
||||
|
||||
assert_equal 1, @context.method_list.length
|
||||
@context.add_method meth
|
||||
@context.add_alias as
|
||||
|
||||
alas_meth = @context.method_list.first
|
||||
assert_equal 'new_name', alas_meth.name
|
||||
assert_equal 'new comment', alas_meth.comment
|
||||
assert_equal false, alas_meth.singleton
|
||||
assert_equal meth, alas_meth.is_alias_for
|
||||
assert_equal :private, alas_meth.visibility
|
||||
assert_empty @context.aliases
|
||||
assert_empty @context.unmatched_alias_lists
|
||||
assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
|
||||
|
||||
assert_equal [alas_meth], meth.aliases
|
||||
assert @context.method_list.last.singleton
|
||||
end
|
||||
|
||||
def test_add_class
|
||||
|
@ -133,11 +158,11 @@ class TestRDocContext < XrefTestCase
|
|||
meth = RDoc::AnyMethod.new nil, 'old_name'
|
||||
|
||||
@context.add_alias as
|
||||
refute_empty @context.aliases
|
||||
refute_empty @context.external_aliases
|
||||
|
||||
@context.add_method meth
|
||||
|
||||
assert_empty @context.aliases
|
||||
assert_empty @context.external_aliases
|
||||
assert_empty @context.unmatched_alias_lists
|
||||
assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
|
||||
end
|
||||
|
@ -292,6 +317,46 @@ class TestRDocContext < XrefTestCase
|
|||
assert_equal @c1__m, @c1.find_symbol('::m')
|
||||
end
|
||||
|
||||
def test_fully_documented_eh
|
||||
context = RDoc::Context.new
|
||||
|
||||
refute context.fully_documented?
|
||||
|
||||
context.comment = 'hi'
|
||||
|
||||
assert context.fully_documented?
|
||||
|
||||
m = @c1_m
|
||||
|
||||
context.add_method m
|
||||
|
||||
refute context.fully_documented?
|
||||
|
||||
m.comment = 'hi'
|
||||
|
||||
assert context.fully_documented?
|
||||
|
||||
c = RDoc::Constant.new 'C', '0', nil
|
||||
|
||||
context.add_constant c
|
||||
|
||||
refute context.fully_documented?
|
||||
|
||||
c.comment = 'hi'
|
||||
|
||||
assert context.fully_documented?
|
||||
|
||||
a = RDoc::Attr.new '', 'a', 'RW', nil
|
||||
|
||||
context.add_attribute a
|
||||
|
||||
refute context.fully_documented?
|
||||
|
||||
a.comment = 'hi'
|
||||
|
||||
assert context.fully_documented?
|
||||
end
|
||||
|
||||
def test_spaceship
|
||||
assert_equal(-1, @c2.<=>(@c3))
|
||||
assert_equal 0, @c2.<=>(@c2)
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc'
|
||||
require 'rdoc/encoding'
|
||||
|
||||
require 'tempfile'
|
||||
|
||||
class TestRDocEncoding < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@tempfile = Tempfile.new 'test_rdoc_encoding'
|
||||
end
|
||||
|
||||
def test_class_read_file
|
||||
@tempfile.write "hi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
assert_equal "hi everybody", RDoc::Encoding.read_file(@tempfile.path, nil)
|
||||
end
|
||||
|
||||
def test_class_read_file_encoding
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
expected = "# coding: utf-8\nhi everybody"
|
||||
|
||||
@tempfile.write expected
|
||||
@tempfile.flush
|
||||
|
||||
# FIXME 1.9 fix on windoze
|
||||
expected.gsub!("\n", "\r\n") if RUBY_VERSION =~ /^1.9/ && RUBY_PLATFORM =~ /mswin|mingw/
|
||||
|
||||
contents = RDoc::Encoding.read_file @tempfile.path, Encoding::UTF_8
|
||||
assert_equal expected, contents
|
||||
assert_equal Encoding::UTF_8, contents.encoding
|
||||
end
|
||||
|
||||
def test_class_read_file_encoding_convert
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
content = ""
|
||||
content.encode! 'ISO-8859-1'
|
||||
content << "# coding: ISO-8859-1\nhi \xE9verybody"
|
||||
|
||||
@tempfile.write content
|
||||
@tempfile.flush
|
||||
|
||||
contents = RDoc::Encoding.read_file @tempfile.path, Encoding::UTF_8
|
||||
assert_equal Encoding::UTF_8, contents.encoding
|
||||
assert_equal "# coding: ISO-8859-1\nhi \u00e9verybody", contents.sub("\r", '')
|
||||
end
|
||||
|
||||
def test_class_read_file_encoding_fancy
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
expected = "# -*- coding: utf-8; fill-column: 74 -*-\nhi everybody"
|
||||
expected.encode! Encoding::UTF_8
|
||||
|
||||
@tempfile.write expected
|
||||
@tempfile.flush
|
||||
|
||||
# FIXME 1.9 fix on windoze
|
||||
expected.gsub!("\n", "\r\n") if RUBY_VERSION =~ /^1.9/ && RUBY_PLATFORM =~ /win32|mingw32/
|
||||
|
||||
contents = RDoc::Encoding.read_file @tempfile.path, Encoding::UTF_8
|
||||
assert_equal expected, contents
|
||||
assert_equal Encoding::UTF_8, contents.encoding
|
||||
end
|
||||
|
||||
def test_class_read_file_encoding_guess
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
path = File.expand_path '../test.ja.txt', __FILE__
|
||||
content = RDoc::Encoding.read_file path, Encoding::UTF_8
|
||||
|
||||
assert_equal Encoding::UTF_8, content.encoding
|
||||
end
|
||||
|
||||
def test_class_read_file_encoding_with_signature
|
||||
skip "Encoding not implemented" unless defined? ::Encoding
|
||||
|
||||
@tempfile.write "\xEF\xBB\xBFhi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
bug3360 = '[ruby-dev:41452]'
|
||||
content = RDoc::Encoding.read_file @tempfile.path, Encoding::UTF_8
|
||||
assert_equal Encoding::UTF_8, content.encoding, bug3360
|
||||
assert_equal "hi everybody", content, bug3360
|
||||
end
|
||||
|
||||
def test_class_set_encoding
|
||||
s = "# coding: UTF-8\n"
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
# sanity check for 1.8
|
||||
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
assert_equal Encoding::UTF_8, s.encoding
|
||||
|
||||
s = "#!/bin/ruby\n# coding: UTF-8\n"
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal Encoding::UTF_8, s.encoding
|
||||
|
||||
s = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
expected = s.encoding
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal Encoding::UTF_8, s.encoding
|
||||
|
||||
s = "<?xml version='1.0' encoding=\"UTF-8\"?>\n"
|
||||
expected = s.encoding
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal Encoding::UTF_8, s.encoding
|
||||
end
|
||||
|
||||
def test_class_set_encoding_bad
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
s = ""
|
||||
expected = s.encoding
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal expected, s.encoding
|
||||
|
||||
s = "# vim:set fileencoding=utf-8:\n"
|
||||
expected = s.encoding
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal expected, s.encoding
|
||||
|
||||
s = "# vim:set fileencoding=utf-8:\n"
|
||||
expected = s.encoding
|
||||
RDoc::Encoding.set_encoding s
|
||||
|
||||
assert_equal expected, s.encoding
|
||||
|
||||
assert_raises ArgumentError do
|
||||
RDoc::Encoding.set_encoding "# -*- encoding: undecided -*-\n"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
require 'minitest/autorun'
|
||||
require 'rdoc/rdoc'
|
||||
require 'rdoc/generator/darkfish'
|
||||
require 'tmpdir'
|
||||
require 'fileutils'
|
||||
|
||||
class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@pwd = Dir.pwd
|
||||
@lib_dir = "#{@pwd}/lib"
|
||||
$LOAD_PATH.unshift @lib_dir # ensure we load from this RDoc
|
||||
RDoc::TopLevel.reset
|
||||
|
||||
@options = RDoc::Options.new
|
||||
@options.option_parser = OptionParser.new
|
||||
|
||||
@tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_darkfish_#{$$}"
|
||||
FileUtils.mkdir_p @tmpdir
|
||||
Dir.chdir @tmpdir
|
||||
@options.op_dir = @tmpdir
|
||||
@options.generator = RDoc::Generator::Darkfish
|
||||
|
||||
$LOAD_PATH.each do |path|
|
||||
darkfish_dir = File.join path, 'rdoc/generator/template/darkfish'
|
||||
next unless File.directory? darkfish_dir
|
||||
@options.template_dir = darkfish_dir
|
||||
break
|
||||
end
|
||||
|
||||
rd = RDoc::RDoc.new
|
||||
rd.options = @options
|
||||
RDoc::RDoc.current = rd
|
||||
|
||||
@g = @options.generator.new @options
|
||||
|
||||
rd.generator = @g
|
||||
|
||||
@top_level = RDoc::TopLevel.new 'file.rb'
|
||||
@klass = @top_level.add_class RDoc::NormalClass, 'Object'
|
||||
@meth = RDoc::AnyMethod.new nil, 'method'
|
||||
@meth_bang = RDoc::AnyMethod.new nil, 'method!'
|
||||
@attr = RDoc::Attr.new nil, 'attr', 'RW', ''
|
||||
|
||||
@klass.add_method @meth
|
||||
@klass.add_method @meth_bang
|
||||
@klass.add_attribute @attr
|
||||
end
|
||||
|
||||
def teardown
|
||||
$LOAD_PATH.shift
|
||||
Dir.chdir @pwd
|
||||
FileUtils.rm_rf @tmpdir
|
||||
end
|
||||
|
||||
def assert_file path
|
||||
assert File.file?(path), "#{path} is not a file"
|
||||
end
|
||||
|
||||
def refute_file path
|
||||
refute File.exist?(path), "#{path} exists"
|
||||
end
|
||||
|
||||
def test_generate
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
top_level.add_class @klass.class, @klass.name
|
||||
|
||||
@g.generate [top_level]
|
||||
|
||||
assert_file 'index.html'
|
||||
assert_file 'Object.html'
|
||||
assert_file 'file_rb.html'
|
||||
|
||||
encoding = if Object.const_defined? :Encoding then
|
||||
Regexp.escape Encoding.default_external.name
|
||||
else
|
||||
Regexp.escape 'UTF-8'
|
||||
end
|
||||
|
||||
assert_match(/<meta content="text\/html; charset=#{encoding}"/,
|
||||
File.read('index.html'))
|
||||
assert_match(/<meta content="text\/html; charset=#{encoding}"/,
|
||||
File.read('Object.html'))
|
||||
assert_match(/<meta content="text\/html; charset=#{encoding}"/,
|
||||
File.read('file_rb.html'))
|
||||
end
|
||||
|
||||
def test_generate_dry_run
|
||||
@options.dry_run = true
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
top_level.add_class @klass.class, @klass.name
|
||||
|
||||
@g.generate [top_level]
|
||||
|
||||
refute_file 'index.html'
|
||||
refute_file 'Object.html'
|
||||
refute_file 'file_rb.html'
|
||||
end
|
||||
|
||||
def test_template_for
|
||||
classpage = Pathname.new @options.template_dir + '/classpage.rhtml'
|
||||
|
||||
template = @g.send(:template_for, classpage)
|
||||
assert_kind_of RDoc::ERBIO, template
|
||||
|
||||
assert_same template, @g.send(:template_for, classpage)
|
||||
end
|
||||
|
||||
def test_template_for_dry_run
|
||||
classpage = Pathname.new @options.template_dir + '/classpage.rhtml'
|
||||
|
||||
template = @g.send(:template_for, classpage)
|
||||
assert_kind_of ERB, template
|
||||
|
||||
assert_same template, @g.send(:template_for, classpage)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,21 +1,23 @@
|
|||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/rdoc'
|
||||
require 'rdoc/generator/ri'
|
||||
require 'tmpdir'
|
||||
require 'fileutils'
|
||||
|
||||
class TestRDocGeneratorRI < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@options = RDoc::Options.new
|
||||
|
||||
@pwd = Dir.pwd
|
||||
RDoc::TopLevel.reset
|
||||
|
||||
@tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_ri_#{$$}"
|
||||
FileUtils.mkdir_p @tmpdir
|
||||
Dir.chdir @tmpdir
|
||||
options = RDoc::Options.new
|
||||
|
||||
@g = RDoc::Generator::RI.new options
|
||||
@g = RDoc::Generator::RI.new @options
|
||||
|
||||
@top_level = RDoc::TopLevel.new 'file.rb'
|
||||
@klass = @top_level.add_class RDoc::NormalClass, 'Object'
|
||||
|
@ -37,6 +39,10 @@ class TestRDocGeneratorRI < MiniTest::Unit::TestCase
|
|||
assert File.file?(path), "#{path} is not a file"
|
||||
end
|
||||
|
||||
def refute_file path
|
||||
refute File.exist?(path), "#{path} exists"
|
||||
end
|
||||
|
||||
def test_generate
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
top_level.add_class @klass.class, @klass.name
|
||||
|
@ -52,5 +58,19 @@ class TestRDocGeneratorRI < MiniTest::Unit::TestCase
|
|||
assert_file File.join(@tmpdir, 'Object', 'method%21-i.ri')
|
||||
end
|
||||
|
||||
def test_generate_dry_run
|
||||
@options.dry_run = true
|
||||
@g = RDoc::Generator::RI.new @options
|
||||
|
||||
top_level = RDoc::TopLevel.new 'file.rb'
|
||||
top_level.add_class @klass.class, @klass.name
|
||||
|
||||
@g.generate nil
|
||||
|
||||
refute_file File.join(@tmpdir, 'cache.ri')
|
||||
|
||||
refute_file File.join(@tmpdir, 'Object')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ class TestRDocInclude < XrefTestCase
|
|||
super
|
||||
|
||||
@inc = RDoc::Include.new 'M1', 'comment'
|
||||
@inc.parent = @m1
|
||||
end
|
||||
|
||||
def test_module
|
||||
|
@ -13,5 +14,83 @@ class TestRDocInclude < XrefTestCase
|
|||
assert_equal 'Unknown', RDoc::Include.new('Unknown', 'comment').module
|
||||
end
|
||||
|
||||
def test_module_extended
|
||||
m1 = @xref_data.add_module RDoc::NormalModule, 'Mod1'
|
||||
m1_m3 = m1.add_module RDoc::NormalModule, 'Mod3'
|
||||
m1_m2 = m1.add_module RDoc::NormalModule, 'Mod2'
|
||||
m1_m2_m3 = m1_m2.add_module RDoc::NormalModule, 'Mod3'
|
||||
m1_m2_m3_m4 = m1_m2_m3.add_module RDoc::NormalModule, 'Mod4'
|
||||
m1_m2_m4 = m1_m2.add_module RDoc::NormalModule, 'Mod4'
|
||||
m1_m2_k0 = m1_m2.add_class RDoc::NormalClass, 'Klass0'
|
||||
m1_m2_k0_m4 = m1_m2_k0.add_module RDoc::NormalModule, 'Mod4'
|
||||
#m1_m2_k0_m4_m5 = m1_m2_k0_m4.add_module RDoc::NormalModule, 'Mod5'
|
||||
m1_m2_k0_m4_m6 = m1_m2_k0_m4.add_module RDoc::NormalModule, 'Mod6'
|
||||
m1_m2_k0_m5 = m1_m2_k0.add_module RDoc::NormalModule, 'Mod5'
|
||||
|
||||
i0_m4 = RDoc::Include.new 'Mod4', nil
|
||||
i0_m5 = RDoc::Include.new 'Mod5', nil
|
||||
i0_m6 = RDoc::Include.new 'Mod6', nil
|
||||
i0_m1 = RDoc::Include.new 'Mod1', nil
|
||||
i0_m2 = RDoc::Include.new 'Mod2', nil
|
||||
i0_m3 = RDoc::Include.new 'Mod3', nil
|
||||
|
||||
m1_m2_k0.add_include i0_m4
|
||||
m1_m2_k0.add_include i0_m5
|
||||
m1_m2_k0.add_include i0_m6
|
||||
m1_m2_k0.add_include i0_m1
|
||||
m1_m2_k0.add_include i0_m2
|
||||
m1_m2_k0.add_include i0_m3
|
||||
|
||||
assert_equal [i0_m4, i0_m5, i0_m6, i0_m1, i0_m2, i0_m3], m1_m2_k0.includes
|
||||
assert_equal [m1_m2_m3, m1_m2, m1, m1_m2_k0_m4_m6, m1_m2_k0_m5,
|
||||
m1_m2_k0_m4, 'Object'], m1_m2_k0.ancestors
|
||||
|
||||
m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'
|
||||
|
||||
i1_m1 = RDoc::Include.new 'Mod1', nil
|
||||
i1_m2 = RDoc::Include.new 'Mod2', nil
|
||||
i1_m3 = RDoc::Include.new 'Mod3', nil
|
||||
i1_m4 = RDoc::Include.new 'Mod4', nil
|
||||
i1_k0_m4 = RDoc::Include.new 'Klass0::Mod4', nil
|
||||
|
||||
m1_k1.add_include i1_m1
|
||||
m1_k1.add_include i1_m2
|
||||
m1_k1.add_include i1_m3
|
||||
m1_k1.add_include i1_m4
|
||||
m1_k1.add_include i1_k0_m4
|
||||
|
||||
assert_equal [i1_m1, i1_m2, i1_m3, i1_m4, i1_k0_m4], m1_k1.includes
|
||||
assert_equal [m1_m2_k0_m4, m1_m2_m3_m4, m1_m2_m3, m1_m2, m1, 'Object'],
|
||||
m1_k1.ancestors
|
||||
|
||||
m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'
|
||||
|
||||
i2_m1 = RDoc::Include.new 'Mod1', nil
|
||||
i2_m2 = RDoc::Include.new 'Mod2', nil
|
||||
i2_m3 = RDoc::Include.new 'Mod3', nil
|
||||
i2_k0_m4 = RDoc::Include.new 'Klass0::Mod4', nil
|
||||
|
||||
m1_k2.add_include i2_m1
|
||||
m1_k2.add_include i2_m3
|
||||
m1_k2.add_include i2_m2
|
||||
m1_k2.add_include i2_k0_m4
|
||||
|
||||
assert_equal [i2_m1, i2_m3, i2_m2, i2_k0_m4], m1_k2.includes
|
||||
assert_equal [m1_m2_k0_m4, m1_m2, m1_m3, m1, 'Object'], m1_k2.ancestors
|
||||
|
||||
m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'
|
||||
|
||||
i3_m1 = RDoc::Include.new 'Mod1', nil
|
||||
i3_m2 = RDoc::Include.new 'Mod2', nil
|
||||
i3_m4 = RDoc::Include.new 'Mod4', nil
|
||||
|
||||
m1_k3.add_include i3_m1
|
||||
m1_k3.add_include i3_m2
|
||||
m1_k3.add_include i3_m4
|
||||
|
||||
assert_equal [i3_m1, i3_m2, i3_m4], m1_k3.includes
|
||||
assert_equal [m1_m2_m4, m1_m2, m1, 'Object'], m1_k3.ancestors
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
require "rubygems"
|
||||
require "minitest/autorun"
|
||||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc'
|
||||
require 'rdoc/markup'
|
||||
require "rdoc/markup/inline"
|
||||
require "rdoc/markup/to_html_crossref"
|
||||
require 'rdoc/markup/inline'
|
||||
require 'rdoc/markup/to_html_crossref'
|
||||
|
||||
class TestRDocMarkupAttributeManager < MiniTest::Unit::TestCase
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# coding: utf-8
|
||||
|
||||
require 'pp'
|
||||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/markup'
|
||||
require 'rdoc/markup/to_test'
|
||||
|
||||
class TestRDocMarkupParser < MiniTest::Unit::TestCase
|
||||
|
||||
|
@ -53,6 +54,19 @@ class TestRDocMarkupParser < MiniTest::Unit::TestCase
|
|||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_bullet_utf_8
|
||||
str = <<-STR
|
||||
* 新しい機能
|
||||
STR
|
||||
|
||||
expected = [
|
||||
@RM::List.new(:BULLET, *[
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('新しい機能'))])]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_bullet_verbatim_heading
|
||||
str = <<-STR
|
||||
* l1
|
||||
|
@ -65,7 +79,7 @@ class TestRDocMarkupParser < MiniTest::Unit::TestCase
|
|||
@RM::List.new(:BULLET, *[
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1'),
|
||||
@RM::Verbatim.new(' ', 'v', "\n"))]),
|
||||
@RM::Verbatim.new("v\n"))]),
|
||||
@RM::Heading.new(1, 'H')]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
|
@ -183,8 +197,7 @@ the time
|
|||
@RM::List.new(:BULLET, *[
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1.1', 'text'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
' ', 'code', "\n"),
|
||||
@RM::Verbatim.new("code\n", " code\n"),
|
||||
@RM::Paragraph.new('text'))])),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l2'))])]
|
||||
|
@ -400,6 +413,68 @@ A. l4
|
|||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_lalpha_utf_8
|
||||
str = <<-STR
|
||||
a. 新しい機能
|
||||
STR
|
||||
|
||||
expected = [
|
||||
@RM::List.new(:LALPHA, *[
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('新しい機能'))])]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_list_list_1
|
||||
str = <<-STR
|
||||
10. para 1
|
||||
|
||||
[label 1]
|
||||
para 1.1
|
||||
|
||||
code
|
||||
|
||||
para 1.2
|
||||
STR
|
||||
|
||||
expected = [
|
||||
@RM::List.new(:NUMBER, *[
|
||||
@RM::ListItem.new(nil, *[
|
||||
@RM::Paragraph.new('para 1'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::List.new(:LABEL, *[
|
||||
@RM::ListItem.new('label 1', *[
|
||||
@RM::Paragraph.new('para 1.1'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new("code\n"),
|
||||
@RM::Paragraph.new('para 1.2')])])])])]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_list_list_2
|
||||
str = <<-STR
|
||||
6. para
|
||||
|
||||
label 1:: text 1
|
||||
label 2:: text 2
|
||||
STR
|
||||
|
||||
expected = [
|
||||
@RM::List.new(:NUMBER, *[
|
||||
@RM::ListItem.new(nil, *[
|
||||
@RM::Paragraph.new('para'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::List.new(:NOTE, *[
|
||||
@RM::ListItem.new('label 1',
|
||||
@RM::Paragraph.new('text 1')),
|
||||
@RM::ListItem.new('label 2',
|
||||
@RM::Paragraph.new('text 2'))])])])]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_list_verbatim
|
||||
str = <<-STR
|
||||
* one
|
||||
|
@ -412,8 +487,7 @@ A. l4
|
|||
@RM::List.new(:BULLET, *[
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('one'),
|
||||
@RM::Verbatim.new(' ', 'verb1', "\n",
|
||||
' ', 'verb2', "\n")),
|
||||
@RM::Verbatim.new("verb1\n", "verb2\n")),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('two'))])]
|
||||
|
||||
|
@ -545,7 +619,7 @@ for all good men
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is the time'),
|
||||
@RM::Verbatim.new(' ', 'code _line_ here', "\n"),
|
||||
@RM::Verbatim.new("code _line_ here\n"),
|
||||
@RM::Paragraph.new('for all good men'),
|
||||
]
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
|
@ -567,6 +641,12 @@ B. l2
|
|||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_trailing_cr
|
||||
expected = [ @RM::Paragraph.new('Text') ]
|
||||
# FIXME hangs the parser:
|
||||
assert_equal expected, @RMP.parse("Text\r").parts
|
||||
end
|
||||
|
||||
def test_parse_verbatim
|
||||
str = <<-STR
|
||||
now is
|
||||
|
@ -576,7 +656,7 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n"),
|
||||
@RM::Verbatim.new("code\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -589,7 +669,18 @@ the time
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '*', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("* blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
||||
def test_parse_verbatim_dash
|
||||
str = <<-STR
|
||||
- blah
|
||||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new("- blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -607,9 +698,7 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
"\n",
|
||||
' ', 'code1', "\n"),
|
||||
@RM::Verbatim.new("code\n", "\n", "code1\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -624,7 +713,7 @@ text
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('text'),
|
||||
@RM::Verbatim.new(' ', '===', ' ', 'heading three', "\n")]
|
||||
@RM::Verbatim.new("=== heading three\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -634,7 +723,7 @@ text
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('text'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n"),
|
||||
@RM::Verbatim.new("code\n"),
|
||||
@RM::Heading.new(3, 'heading three')]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
|
@ -646,7 +735,7 @@ text
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '[blah]', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("[blah] blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -657,7 +746,7 @@ text
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', 'b.', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("b. blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -671,8 +760,7 @@ text
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('text'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
' ', '===', ' ', 'heading three', "\n")]
|
||||
@RM::Verbatim.new("code\n", "=== heading three\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -688,9 +776,7 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
"\n",
|
||||
' ', 'code1', "\n"),
|
||||
@RM::Verbatim.new("code\n", "\n", "code1\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -710,11 +796,7 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
"\n",
|
||||
' ', 'code1', "\n",
|
||||
"\n",
|
||||
' ', 'code2', "\n"),
|
||||
@RM::Verbatim.new("code\n", "\n", "code1\n", "\n", "code2\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -731,8 +813,7 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
' ', 'code1', "\n"),
|
||||
@RM::Verbatim.new("code\n", "code1\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -749,8 +830,8 @@ for all good men
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is the time'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
' ', 'more code', "\n"),
|
||||
@RM::Verbatim.new(" code\n",
|
||||
"more code\n"),
|
||||
@RM::Paragraph.new('for all good men'),
|
||||
]
|
||||
|
||||
|
@ -763,7 +844,7 @@ for all good men
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', 'blah::', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("blah:: blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -774,7 +855,7 @@ for all good men
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '2.', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("2. blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -790,8 +871,8 @@ text
|
|||
expected = [
|
||||
@RM::Paragraph.new('text'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new(' ', '---', ' ', 'lib/blah.rb.orig', "\n",
|
||||
' ', '+++', ' ', 'lib/blah.rb', "\n")]
|
||||
@RM::Verbatim.new("--- lib/blah.rb.orig\n",
|
||||
"+++ lib/blah.rb\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -806,7 +887,7 @@ text
|
|||
expected = [
|
||||
@RM::Paragraph.new('text'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new(' ', '---', '')]
|
||||
@RM::Verbatim.new("---")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -823,9 +904,9 @@ the time
|
|||
|
||||
expected = [
|
||||
@RM::Paragraph.new('now is'),
|
||||
@RM::Verbatim.new(' ', 'code', "\n",
|
||||
@RM::Verbatim.new("code\n",
|
||||
"\n",
|
||||
' ', 'code1', "\n"),
|
||||
"code1\n"),
|
||||
@RM::Paragraph.new('the time'),
|
||||
]
|
||||
|
||||
|
@ -838,7 +919,7 @@ the time
|
|||
STR
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', 'B.', ' ', 'blah', "\n")]
|
||||
@RM::Verbatim.new("B. blah\n")]
|
||||
|
||||
assert_equal expected, @RMP.parse(str).parts
|
||||
end
|
||||
|
@ -851,58 +932,57 @@ the time
|
|||
assert_equal expected, @RMP.parse('hello').parts
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', 'hello '),
|
||||
@RM::Verbatim.new('hello '),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse(' hello ').parts
|
||||
assert_equal expected, @RMP.parse(' hello ').parts
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', 'hello '),
|
||||
@RM::Verbatim.new('hello '),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse(" hello ").parts
|
||||
assert_equal expected, @RMP.parse(' hello ').parts
|
||||
|
||||
expected = [
|
||||
@RM::Paragraph.new('1'),
|
||||
@RM::Verbatim.new(' ', '2', "\n",
|
||||
' ', '3'),
|
||||
@RM::Verbatim.new("2\n", ' 3'),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse("1\n 2\n 3").parts
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '1', "\n",
|
||||
' ', '2', "\n",
|
||||
' ', '3'),
|
||||
@RM::Verbatim.new("1\n",
|
||||
" 2\n",
|
||||
" 3"),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse(" 1\n 2\n 3").parts
|
||||
|
||||
expected = [
|
||||
@RM::Paragraph.new('1'),
|
||||
@RM::Verbatim.new(' ', '2', "\n",
|
||||
' ', '3', "\n"),
|
||||
@RM::Verbatim.new("2\n",
|
||||
" 3\n"),
|
||||
@RM::Paragraph.new('1'),
|
||||
@RM::Verbatim.new(' ', '2'),
|
||||
@RM::Verbatim.new('2'),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse("1\n 2\n 3\n1\n 2").parts
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '1', "\n",
|
||||
' ', '2', "\n",
|
||||
' ', '3', "\n",
|
||||
' ', '1', "\n",
|
||||
' ', '2'),
|
||||
@RM::Verbatim.new("1\n",
|
||||
" 2\n",
|
||||
" 3\n",
|
||||
"1\n",
|
||||
' 2'),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse(" 1\n 2\n 3\n 1\n 2").parts
|
||||
|
||||
expected = [
|
||||
@RM::Verbatim.new(' ', '1', "\n",
|
||||
' ', '2', "\n",
|
||||
@RM::Verbatim.new("1\n",
|
||||
" 2\n",
|
||||
"\n",
|
||||
' ', '3'),
|
||||
' 3'),
|
||||
]
|
||||
|
||||
assert_equal expected, @RMP.parse(" 1\n 2\n\n 3").parts
|
||||
|
@ -942,8 +1022,7 @@ the time
|
|||
STR
|
||||
|
||||
expected = [
|
||||
[:BULLET, :BULLET, 0, 0],
|
||||
[:SPACE, 2, 0, 0],
|
||||
[:BULLET, '*', 0, 0],
|
||||
[:TEXT, 'l1', 2, 0],
|
||||
[:NEWLINE, "\n", 4, 0],
|
||||
]
|
||||
|
@ -958,13 +1037,10 @@ the time
|
|||
STR
|
||||
|
||||
expected = [
|
||||
[:BULLET, :BULLET, 0, 0],
|
||||
[:SPACE, 2, 0, 0],
|
||||
[:BULLET, '*', 0, 0],
|
||||
[:TEXT, 'l1', 2, 0],
|
||||
[:NEWLINE, "\n", 4, 0],
|
||||
[:INDENT, 2, 0, 1],
|
||||
[:BULLET, :BULLET, 2, 1],
|
||||
[:SPACE, 2, 2, 1],
|
||||
[:BULLET, '*', 2, 1],
|
||||
[:TEXT, 'l1.1', 4, 1],
|
||||
[:NEWLINE, "\n", 8, 1],
|
||||
]
|
||||
|
@ -1030,11 +1106,9 @@ the time
|
|||
|
||||
expected = [
|
||||
[:LABEL, 'cat', 0, 0],
|
||||
[:SPACE, 6, 0, 0],
|
||||
[:TEXT, 'l1', 6, 0],
|
||||
[:NEWLINE, "\n", 8, 0],
|
||||
[:LABEL, 'dog', 0, 1],
|
||||
[:SPACE, 6, 0, 1],
|
||||
[:TEXT, 'l1.1', 6, 1],
|
||||
[:NEWLINE, "\n", 10, 1],
|
||||
]
|
||||
|
@ -1050,11 +1124,8 @@ the time
|
|||
|
||||
expected = [
|
||||
[:LABEL, 'label', 0, 0],
|
||||
[:SPACE, 7, 0, 0],
|
||||
[:NEWLINE, "\n", 7, 0],
|
||||
[:INDENT, 2, 0, 1],
|
||||
[:NOTE, 'note', 2, 1],
|
||||
[:SPACE, 6, 2, 1],
|
||||
[:NEWLINE, "\n", 8, 1],
|
||||
]
|
||||
|
||||
|
@ -1069,11 +1140,9 @@ b. l1.1
|
|||
|
||||
expected = [
|
||||
[:LALPHA, 'a', 0, 0],
|
||||
[:SPACE, 3, 0, 0],
|
||||
[:TEXT, 'l1', 3, 0],
|
||||
[:NEWLINE, "\n", 5, 0],
|
||||
[:LALPHA, 'b', 0, 1],
|
||||
[:SPACE, 3, 0, 1],
|
||||
[:TEXT, 'l1.1', 3, 1],
|
||||
[:NEWLINE, "\n", 7, 1],
|
||||
]
|
||||
|
@ -1089,11 +1158,9 @@ dog:: l1.1
|
|||
|
||||
expected = [
|
||||
[:NOTE, 'cat', 0, 0],
|
||||
[:SPACE, 6, 0, 0],
|
||||
[:TEXT, 'l1', 6, 0],
|
||||
[:NEWLINE, "\n", 8, 0],
|
||||
[:NOTE, 'dog', 0, 1],
|
||||
[:SPACE, 6, 0, 1],
|
||||
[:TEXT, 'l1.1', 6, 1],
|
||||
[:NEWLINE, "\n", 10, 1],
|
||||
]
|
||||
|
@ -1109,10 +1176,8 @@ dog::
|
|||
|
||||
expected = [
|
||||
[:NOTE, 'cat', 0, 0],
|
||||
[:SPACE, 5, 0, 0],
|
||||
[:NEWLINE, "\n", 5, 0],
|
||||
[:NOTE, 'dog', 0, 1],
|
||||
[:SPACE, 5, 0, 1],
|
||||
[:NEWLINE, "\n", 5, 1],
|
||||
]
|
||||
|
||||
|
@ -1140,11 +1205,9 @@ Cat::Dog
|
|||
|
||||
expected = [
|
||||
[:NUMBER, '1', 0, 0],
|
||||
[:SPACE, 3, 0, 0],
|
||||
[:TEXT, 'l1', 3, 0],
|
||||
[:NEWLINE, "\n", 5, 0],
|
||||
[:NUMBER, '2', 0, 1],
|
||||
[:SPACE, 3, 0, 1],
|
||||
[:TEXT, 'l1.1', 3, 1],
|
||||
[:NEWLINE, "\n", 7, 1],
|
||||
]
|
||||
|
@ -1162,20 +1225,16 @@ Cat::Dog
|
|||
|
||||
expected = [
|
||||
[:NUMBER, "1", 0, 0],
|
||||
[:SPACE, 3, 0, 0],
|
||||
[:TEXT, "blah blah blah", 3, 0],
|
||||
[:NEWLINE, "\n", 17, 0],
|
||||
|
||||
[:INDENT, 3, 0, 1],
|
||||
[:TEXT, "l.", 3, 1],
|
||||
[:NEWLINE, "\n", 5, 1],
|
||||
|
||||
[:NUMBER, "2", 0, 2],
|
||||
[:SPACE, 3, 0, 2],
|
||||
[:TEXT, "blah blah blah blah", 3, 2],
|
||||
[:NEWLINE, "\n", 22, 2],
|
||||
|
||||
[:INDENT, 3, 0, 3],
|
||||
[:TEXT, "d.", 3, 3],
|
||||
[:NEWLINE, "\n", 5, 3]
|
||||
]
|
||||
|
@ -1193,24 +1252,18 @@ Cat::Dog
|
|||
|
||||
expected = [
|
||||
[:NUMBER, "1", 0, 0],
|
||||
[:SPACE, 3, 0, 0],
|
||||
[:TEXT, "blah blah blah", 3, 0],
|
||||
[:NEWLINE, "\n", 17, 0],
|
||||
|
||||
[:INDENT, 3, 0, 1],
|
||||
[:LALPHA, "l", 3, 1],
|
||||
[:SPACE, 4, 3, 1],
|
||||
[:TEXT, "more stuff", 7, 1],
|
||||
[:NEWLINE, "\n", 17, 1],
|
||||
|
||||
[:NUMBER, "2", 0, 2],
|
||||
[:SPACE, 3, 0, 2],
|
||||
[:TEXT, "blah blah blah blah", 3, 2],
|
||||
[:NEWLINE, "\n", 22, 2],
|
||||
|
||||
[:INDENT, 3, 0, 3],
|
||||
[:LALPHA, "d", 3, 3],
|
||||
[:SPACE, 3, 3, 3],
|
||||
[:TEXT, "other stuff", 6, 3],
|
||||
[:NEWLINE, "\n", 17, 3]
|
||||
]
|
||||
|
@ -1241,14 +1294,14 @@ for all
|
|||
|
||||
def test_tokenize_rule
|
||||
str = <<-STR
|
||||
---
|
||||
---
|
||||
|
||||
--- blah ---
|
||||
STR
|
||||
|
||||
expected = [
|
||||
[:RULE, 1, 0, 0],
|
||||
[:NEWLINE, "\n", 4, 0],
|
||||
[:NEWLINE, "\n", 3, 0],
|
||||
[:NEWLINE, "\n", 0, 1],
|
||||
[:TEXT, "--- blah ---", 0, 2],
|
||||
[:NEWLINE, "\n", 12, 2],
|
||||
|
@ -1265,11 +1318,9 @@ B. l1.1
|
|||
|
||||
expected = [
|
||||
[:UALPHA, 'A', 0, 0],
|
||||
[:SPACE, 3, 0, 0],
|
||||
[:TEXT, 'l1', 3, 0],
|
||||
[:NEWLINE, "\n", 5, 0],
|
||||
[:UALPHA, 'B', 0, 1],
|
||||
[:SPACE, 3, 0, 1],
|
||||
[:TEXT, 'l1.1', 3, 1],
|
||||
[:NEWLINE, "\n", 7, 1],
|
||||
]
|
||||
|
@ -1288,7 +1339,6 @@ Example heading:
|
|||
[:TEXT, 'Example heading:', 0, 0],
|
||||
[:NEWLINE, "\n", 16, 0],
|
||||
[:NEWLINE, "\n", 0, 1],
|
||||
[:INDENT, 3, 0, 2],
|
||||
[:HEADER, 3, 3, 2],
|
||||
[:TEXT, 'heading three', 7, 2],
|
||||
[:NEWLINE, "\n", 20, 2],
|
||||
|
@ -1299,17 +1349,17 @@ Example heading:
|
|||
|
||||
# HACK move to Verbatim test case
|
||||
def test_verbatim_normalize
|
||||
v = @RM::Verbatim.new ' ', 'foo', "\n", "\n", "\n", ' ', 'bar', "\n"
|
||||
v = @RM::Verbatim.new "foo\n", "\n", "\n", "bar\n"
|
||||
|
||||
v.normalize
|
||||
|
||||
assert_equal [' ', 'foo', "\n", "\n", ' ', 'bar', "\n"], v.parts
|
||||
assert_equal ["foo\n", "\n", "bar\n"], v.parts
|
||||
|
||||
v = @RM::Verbatim.new ' ', 'foo', "\n", "\n"
|
||||
v = @RM::Verbatim.new "foo\n", "\n"
|
||||
|
||||
v.normalize
|
||||
|
||||
assert_equal [' ', 'foo', "\n"], v.parts
|
||||
assert_equal ["foo\n"], v.parts
|
||||
end
|
||||
|
||||
def test_unget
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'tempfile'
|
||||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/markup/preprocess'
|
||||
require 'rdoc/markup/pre_process'
|
||||
require 'rdoc/code_objects'
|
||||
|
||||
class TestRDocMarkupPreProcess < MiniTest::Unit::TestCase
|
||||
|
@ -10,8 +10,7 @@ class TestRDocMarkupPreProcess < MiniTest::Unit::TestCase
|
|||
RDoc::Markup::PreProcess.registered.clear
|
||||
|
||||
@tempfile = Tempfile.new 'test_rdoc_markup_pre_process'
|
||||
@tempfile.binmode
|
||||
@name = File.basename @tempfile.path
|
||||
@file_name = File.basename @tempfile.path
|
||||
@dir = File.dirname @tempfile.path
|
||||
|
||||
@pp = RDoc::Markup::PreProcess.new __FILE__, [@dir]
|
||||
|
@ -32,13 +31,18 @@ contents of a string.
|
|||
@tempfile.flush
|
||||
@tempfile.rewind
|
||||
|
||||
content = @pp.include_file @name, ''
|
||||
content = @pp.include_file @file_name, '', nil
|
||||
|
||||
expected = <<-EXPECTED
|
||||
Regular expressions (<i>regexp</i>s) are patterns which describe the
|
||||
contents of a string.
|
||||
EXPECTED
|
||||
|
||||
# FIXME 1.9 fix on windoze
|
||||
# preprocessor uses binread, so line endings are \r\n
|
||||
expected.gsub!("\n", "\r\n") if
|
||||
RUBY_VERSION =~ /^1.9/ && RUBY_PLATFORM =~ /mswin|mingw/
|
||||
|
||||
assert_equal expected, content
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
require 'rubygems'
|
||||
require 'rdoc/markup/formatter_test_case'
|
||||
require 'rdoc/markup/text_formatter_test_case'
|
||||
require 'rdoc/markup/to_ansi'
|
||||
require 'minitest/autorun'
|
||||
|
||||
class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
|
||||
class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
|
||||
|
||||
add_visitor_tests
|
||||
add_text_tests
|
||||
|
||||
def setup
|
||||
super
|
||||
|
@ -62,7 +63,7 @@ class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_list_item_end_label
|
||||
assert_equal "\e[0m\n", @to.res.join
|
||||
assert_equal "\e[0m", @to.res.join
|
||||
assert_equal 0, @to.indent, 'indent'
|
||||
end
|
||||
|
||||
|
@ -72,7 +73,7 @@ class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_list_item_end_note
|
||||
assert_equal "\e[0m\n", @to.res.join
|
||||
assert_equal "\e[0m", @to.res.join
|
||||
assert_equal 0, @to.indent, 'indent'
|
||||
end
|
||||
|
||||
|
@ -191,8 +192,8 @@ class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
|
|||
assert_equal "\e[0m#{'-' * 78}\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
|
||||
assert_equal "\e[0m hi\n world\n\n", @to.res.join
|
||||
def accept_verbatim
|
||||
assert_equal "\e[0m hi\n world\n\n", @to.res.join
|
||||
end
|
||||
|
||||
def end_accepting
|
||||
|
@ -207,214 +208,103 @@ class TestRDocMarkupToAnsi < RDoc::Markup::FormatterTestCase
|
|||
assert_empty @to.list_width
|
||||
end
|
||||
|
||||
def test_accept_heading_1
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
def accept_heading_1
|
||||
assert_equal "\e[0m\e[1;32mHello\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_2
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(2, 'Hello')
|
||||
|
||||
def accept_heading_2
|
||||
assert_equal "\e[0m\e[4;32mHello\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_3
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(3, 'Hello')
|
||||
|
||||
def accept_heading_3
|
||||
assert_equal "\e[0m\e[32mHello\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_4
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(4, 'Hello')
|
||||
|
||||
def accept_heading_4
|
||||
assert_equal "\e[0mHello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
def accept_heading_indent
|
||||
assert_equal "\e[0m \e[1;32mHello\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_b
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, '*Hello*')
|
||||
|
||||
assert_equal "\e[0m \e[1;32m\e[1mHello\e[m\e[m\n", @to.end_accepting
|
||||
def accept_heading_b
|
||||
assert_equal "\e[0m\e[1;32m\e[1mHello\e[m\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_list_item_start_note_2
|
||||
list = @RM::List.new(:NOTE,
|
||||
@RM::ListItem.new('<tt>teletype</tt>',
|
||||
@RM::Paragraph.new('teletype description')))
|
||||
|
||||
@to.start_accepting
|
||||
|
||||
list.accept @to
|
||||
|
||||
expected = "\e[0m\e[7mteletype\e[m:\n teletype description\n\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_heading_suppressed_crossref
|
||||
assert_equal "\e[0m\e[1;32mHello\e[m\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_b
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
|
||||
|
||||
expected = "\e[0mreg \e[1mbold words\e[m reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_list_item_start_note_2
|
||||
assert_equal "\e[0m\e[7mteletype\e[m:\n teletype description\n\n",
|
||||
@to.res.join
|
||||
end
|
||||
|
||||
def test_accept_paragraph_i
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
|
||||
|
||||
expected = "\e[0mreg \e[4mitalic words\e[m reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_b
|
||||
assert_equal "\e[0mreg \e[1mbold words\e[m reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
def accept_paragraph_i
|
||||
assert_equal "\e[0mreg \e[4mitalic words\e[m reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def accept_paragraph_indent
|
||||
expected = <<-EXPECTED
|
||||
\e[0m words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words
|
||||
words words words words words words
|
||||
words words words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_plus
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
|
||||
|
||||
expected = "\e[0mregular \e[7mteletype\e[m regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_plus
|
||||
assert_equal "\e[0mreg \e[7mteletype\e[m reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_star
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
|
||||
|
||||
expected = "\e[0mregular \e[1mbold\e[m regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_star
|
||||
assert_equal "\e[0mreg \e[1mbold\e[m reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_underscore
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
|
||||
|
||||
expected = "\e[0mregular \e[4mitalic\e[m regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_underscore
|
||||
assert_equal "\e[0mreg \e[4mitalic\e[m reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_wrap
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
|
||||
def accept_paragraph_wrap
|
||||
expected = <<-EXPECTED
|
||||
\e[0mwords words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words words
|
||||
words words words words
|
||||
words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_rule_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
|
||||
@to.accept_rule @RM::Rule.new(1)
|
||||
|
||||
def accept_rule_indent
|
||||
assert_equal "\e[0m #{'-' * 75}\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_indent
|
||||
assert_equal "\e[0m hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_big_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_big_indent
|
||||
assert_equal "\e[0m hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
assert_equal 'Dog', @to.attributes("\\Dog")
|
||||
end
|
||||
|
||||
def test_list_nested
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1'),
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1.1')))),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l2'))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
def list_nested
|
||||
expected = <<-EXPECTED
|
||||
\e[0m* l1
|
||||
* l1.1
|
||||
* l2
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_list_verbatim # HACK overblown
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('list', 'stuff'),
|
||||
@RM::BlankLine.new(),
|
||||
@RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
|
||||
' ', 'with', "\n",
|
||||
"\n",
|
||||
' ', 'second', "\n",
|
||||
"\n",
|
||||
' ', '1.', ' ', 'indented', "\n",
|
||||
' ', '2.', ' ', 'numbered', "\n",
|
||||
"\n",
|
||||
' ', 'third', "\n",
|
||||
"\n",
|
||||
' ', '*', ' ', 'second', "\n"))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
expected = <<-EXPECTED
|
||||
def list_verbatim
|
||||
expected = <<-EXPECTED # HACK overblown
|
||||
\e[0m* list stuff
|
||||
|
||||
* list
|
||||
|
@ -431,7 +321,7 @@ words words words words
|
|||
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
require 'rubygems'
|
||||
require 'rdoc/markup/formatter_test_case'
|
||||
require 'rdoc/markup/text_formatter_test_case'
|
||||
require 'rdoc/markup/to_bs'
|
||||
require 'minitest/autorun'
|
||||
|
||||
class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
|
||||
class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
|
||||
|
||||
add_visitor_tests
|
||||
add_text_tests
|
||||
|
||||
def setup
|
||||
super
|
||||
|
@ -63,6 +64,7 @@ class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_list_item_end_label
|
||||
assert_equal "\n", @to.res.join
|
||||
assert_equal 0, @to.indent, 'indent'
|
||||
end
|
||||
|
||||
|
@ -72,6 +74,7 @@ class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_list_item_end_note
|
||||
assert_equal "\n", @to.res.join
|
||||
assert_equal 0, @to.indent, 'indent'
|
||||
end
|
||||
|
||||
|
@ -190,8 +193,8 @@ class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
|
|||
assert_equal "#{'-' * 78}\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
|
||||
assert_equal " hi\n world\n\n", @to.res.join
|
||||
def accept_verbatim
|
||||
assert_equal " hi\n world\n\n", @to.res.join
|
||||
end
|
||||
|
||||
def end_accepting
|
||||
|
@ -206,232 +209,115 @@ class TestRDocMarkupToBs < RDoc::Markup::FormatterTestCase
|
|||
assert_empty @to.list_width
|
||||
end
|
||||
|
||||
def test_accept_heading_1
|
||||
def accept_heading_1
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
assert_equal "= H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_2
|
||||
def accept_heading_2
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(2, 'Hello')
|
||||
|
||||
assert_equal "== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_3
|
||||
def accept_heading_3
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(3, 'Hello')
|
||||
|
||||
assert_equal "=== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_4
|
||||
def accept_heading_4
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(4, 'Hello')
|
||||
|
||||
assert_equal "==== H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_indent
|
||||
def accept_heading_indent
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
assert_equal " = H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_b
|
||||
def accept_heading_b
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, '*Hello*')
|
||||
|
||||
assert_equal " = H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_suppressed_crossref
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(1, '\\Hello')
|
||||
|
||||
assert_equal "= H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_list_item_start_note_2
|
||||
list = @RM::List.new(:NOTE,
|
||||
@RM::ListItem.new('<tt>teletype</tt>',
|
||||
@RM::Paragraph.new('teletype description')))
|
||||
|
||||
@to.start_accepting
|
||||
|
||||
list.accept @to
|
||||
|
||||
expected = "teletype:\n teletype description\n\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_b
|
||||
def accept_heading_suppressed_crossref
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
|
||||
|
||||
expected = "reg b\bbo\bol\bld\bd \b w\bwo\bor\brd\bds\bs reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
assert_equal "= H\bHe\bel\bll\blo\bo\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_i
|
||||
def accept_list_item_start_note_2
|
||||
assert_equal "teletype:\n teletype description\n\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_b
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
|
||||
|
||||
expected = "reg _\bi_\bt_\ba_\bl_\bi_\bc_\b _\bw_\bo_\br_\bd_\bs reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
assert_equal "reg b\bbo\bol\bld\bd \b w\bwo\bor\brd\bds\bs reg\n",
|
||||
@to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
def accept_paragraph_i
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
assert_equal "reg _\bi_\bt_\ba_\bl_\bi_\bc_\b _\bw_\bo_\br_\bd_\bs reg\n",
|
||||
@to.end_accepting
|
||||
end
|
||||
|
||||
def accept_paragraph_indent
|
||||
expected = <<-EXPECTED
|
||||
words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words
|
||||
words words words words words words
|
||||
words words words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_plus
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
|
||||
|
||||
expected = "regular teletype regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_plus
|
||||
assert_equal "reg teletype reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_star
|
||||
def accept_paragraph_star
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
|
||||
|
||||
expected = "regular b\bbo\bol\bld\bd regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
assert_equal "reg b\bbo\bol\bld\bd reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_underscore
|
||||
def accept_paragraph_underscore
|
||||
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
|
||||
|
||||
expected = "regular _\bi_\bt_\ba_\bl_\bi_\bc regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
assert_equal "reg _\bi_\bt_\ba_\bl_\bi_\bc reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_wrap
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
|
||||
def accept_paragraph_wrap
|
||||
expected = <<-EXPECTED
|
||||
words words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words words
|
||||
words words words words
|
||||
words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_rule_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
|
||||
@to.accept_rule @RM::Rule.new(1)
|
||||
|
||||
def accept_rule_indent
|
||||
assert_equal " #{'-' * 75}\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_indent
|
||||
assert_equal " hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_big_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_big_indent
|
||||
assert_equal " hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
assert_equal 'Dog', @to.attributes("\\Dog")
|
||||
end
|
||||
|
||||
def test_list_nested
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1'),
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1.1')))),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l2'))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
def list_nested
|
||||
expected = <<-EXPECTED
|
||||
* l1
|
||||
* l1.1
|
||||
* l2
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_list_verbatim # HACK overblown
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('list', 'stuff'),
|
||||
@RM::BlankLine.new(),
|
||||
@RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
|
||||
' ', 'with', "\n",
|
||||
"\n",
|
||||
' ', 'second', "\n",
|
||||
"\n",
|
||||
' ', '1.', ' ', 'indented', "\n",
|
||||
' ', '2.', ' ', 'numbered', "\n",
|
||||
"\n",
|
||||
' ', 'third', "\n",
|
||||
"\n",
|
||||
' ', '*', ' ', 'second', "\n"))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
expected = <<-EXPECTED
|
||||
def list_verbatim
|
||||
expected = <<-EXPECTED # HACK overblown
|
||||
* list stuff
|
||||
|
||||
* list
|
||||
|
@ -448,7 +334,7 @@ words words words words
|
|||
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -31,49 +31,73 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_heading
|
||||
assert_equal "<h5>Hello</h5>\n", @to.res.join
|
||||
assert_equal "\n<h5>Hello</h5>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_1
|
||||
assert_equal "\n<h1>Hello</h1>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_2
|
||||
assert_equal "\n<h2>Hello</h2>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_3
|
||||
assert_equal "\n<h3>Hello</h3>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_4
|
||||
assert_equal "\n<h4>Hello</h4>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_b
|
||||
assert_equal "\n<h1><b>Hello</b></h1>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_heading_suppressed_crossref
|
||||
assert_equal "\n<h1>Hello</h1>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_bullet
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<ul>\n</ul>\n", @to.res.join
|
||||
assert_equal "<ul></ul>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_label
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<dl>\n</dl>\n", @to.res.join
|
||||
assert_equal "<dl></dl>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_lalpha
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol style=\"display: lower-alpha\">\n</ol>\n", @to.res.join
|
||||
assert_equal "<ol style=\"display: lower-alpha\"></ol>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_number
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol>\n</ol>\n", @to.res.join
|
||||
assert_equal "<ol></ol>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_note
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<table>\n</table>\n", @to.res.join
|
||||
assert_equal "<table class=\"rdoc-list\"></table>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_end_ualpha
|
||||
assert_equal [], @to.list
|
||||
assert_equal [], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol style=\"display: upper-alpha\">\n</ol>\n", @to.res.join
|
||||
assert_equal "<ol style=\"display: upper-alpha\"></ol>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_end_bullet
|
||||
|
@ -101,73 +125,105 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_list_item_start_bullet
|
||||
assert_equal "<ul>\n<li>", @to.res.join
|
||||
assert_equal "<ul><li>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_label
|
||||
assert_equal "<dl>\n<dt>cat</dt><dd>", @to.res.join
|
||||
assert_equal "<dl><dt>cat</dt>\n<dd>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_lalpha
|
||||
assert_equal "<ol style=\"display: lower-alpha\">\n<li>", @to.res.join
|
||||
assert_equal "<ol style=\"display: lower-alpha\"><li>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_note
|
||||
assert_equal "<table>\n<tr><td valign=\"top\">cat</td><td>", @to.res.join
|
||||
assert_equal "<table class=\"rdoc-list\"><tr><td class=\"rdoc-term\"><p>cat</p></td>\n<td>",
|
||||
@to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_note_2
|
||||
expected = <<-EXPECTED
|
||||
<table class="rdoc-list"><tr><td class="rdoc-term"><p><tt>teletype</tt></p></td>
|
||||
<td>
|
||||
<p>teletype description</p>
|
||||
</td></tr></table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_number
|
||||
assert_equal "<ol>\n<li>", @to.res.join
|
||||
assert_equal "<ol><li>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_item_start_ualpha
|
||||
assert_equal "<ol style=\"display: upper-alpha\">\n<li>", @to.res.join
|
||||
assert_equal "<ol style=\"display: upper-alpha\"><li>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_bullet
|
||||
assert_equal [:BULLET], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<ul>\n", @to.res.join
|
||||
assert_equal "<ul>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_label
|
||||
assert_equal [:LABEL], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<dl>\n", @to.res.join
|
||||
assert_equal "<dl>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_lalpha
|
||||
assert_equal [:LALPHA], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol style=\"display: lower-alpha\">\n", @to.res.join
|
||||
assert_equal "<ol style=\"display: lower-alpha\">", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_note
|
||||
assert_equal [:NOTE], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<table>\n", @to.res.join
|
||||
assert_equal "<table class=\"rdoc-list\">", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_number
|
||||
assert_equal [:NUMBER], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol>\n", @to.res.join
|
||||
assert_equal "<ol>", @to.res.join
|
||||
end
|
||||
|
||||
def accept_list_start_ualpha
|
||||
assert_equal [:UALPHA], @to.list
|
||||
assert_equal [false], @to.in_list_entry
|
||||
|
||||
assert_equal "<ol style=\"display: upper-alpha\">\n", @to.res.join
|
||||
assert_equal "<ol style=\"display: upper-alpha\">", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph
|
||||
assert_equal "<p>\nhi\n</p>\n", @to.res.join
|
||||
assert_equal "\n<p>hi</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_b
|
||||
assert_equal "\n<p>reg <b>bold words</b> reg</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_i
|
||||
assert_equal "\n<p>reg <em>italic words</em> reg</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_plus
|
||||
assert_equal "\n<p>reg <tt>teletype</tt> reg</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_star
|
||||
assert_equal "\n<p>reg <b>bold</b> reg</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_paragraph_underscore
|
||||
assert_equal "\n<p>reg <em>italic</em> reg</p>\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_raw
|
||||
|
@ -183,11 +239,11 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
|
|||
end
|
||||
|
||||
def accept_rule
|
||||
assert_equal '<hr style="height: 4px"></hr>', @to.res.join
|
||||
assert_equal "<hr style=\"height: 4px\">\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_verbatim
|
||||
assert_equal "<pre>\n hi\n world\n</pre>\n", @to.res.join
|
||||
assert_equal "\n<pre>hi\n world</pre>\n", @to.res.join
|
||||
end
|
||||
|
||||
def end_accepting
|
||||
|
@ -200,54 +256,70 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
|
|||
assert_equal [], @to.list
|
||||
end
|
||||
|
||||
def test_list_verbatim
|
||||
def list_nested
|
||||
expected = <<-EXPECTED
|
||||
<ul><li>
|
||||
<p>l1</p>
|
||||
<ul><li>
|
||||
<p>l1.1</p>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<p>l2</p>
|
||||
</li></ul>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.res.join
|
||||
end
|
||||
|
||||
def list_verbatim
|
||||
expected = <<-EXPECTED
|
||||
<ul><li>
|
||||
<p>list stuff</p>
|
||||
|
||||
<pre>* list
|
||||
with
|
||||
|
||||
second
|
||||
|
||||
1. indented
|
||||
2. numbered
|
||||
|
||||
third
|
||||
|
||||
* second</pre>
|
||||
</li></ul>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_convert_string
|
||||
assert_equal '<>', @to.convert_string('<>')
|
||||
end
|
||||
|
||||
def test_list_verbatim_2
|
||||
str = "* one\n verb1\n verb2\n* two\n"
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<ul>
|
||||
<li><p>
|
||||
one
|
||||
</p>
|
||||
<pre>
|
||||
verb1
|
||||
verb2
|
||||
</pre>
|
||||
</li>
|
||||
<li><p>
|
||||
two
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul><li>
|
||||
<p>one</p>
|
||||
|
||||
<pre>verb1
|
||||
verb2</pre>
|
||||
</li><li>
|
||||
<p>two</p>
|
||||
</li></ul>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @m.convert(str, @to)
|
||||
end
|
||||
|
||||
def test_tt_formatting
|
||||
assert_equal "<p>\n<tt>--</tt> — <tt>cats'</tt> cats’\n</p>\n",
|
||||
util_format("<tt>--</tt> -- <tt>cats'</tt> cats'")
|
||||
|
||||
assert_equal "<p>\n<b>—</b>\n</p>\n", util_format("<b>--</b>")
|
||||
def test_to_html
|
||||
assert_equal "\n<p><tt>--</tt></p>\n", util_format("<tt>--</tt>")
|
||||
end
|
||||
|
||||
def test_convert_string_fancy
|
||||
#
|
||||
# The HTML typesetting is broken in a number of ways, but I have fixed
|
||||
# the most glaring issues for single and double quotes. Note that
|
||||
# "strange" symbols (periods or dashes) need to be at the end of the
|
||||
# test case strings in order to suppress cross-references.
|
||||
#
|
||||
assert_equal "<p>\n“cats”.\n</p>\n", util_format("\"cats\".")
|
||||
assert_equal "<p>\n‘cats’.\n</p>\n", util_format("\'cats\'.")
|
||||
assert_equal "<p>\ncat’s-\n</p>\n", util_format("cat\'s-")
|
||||
end
|
||||
|
||||
def util_paragraph(text)
|
||||
RDoc::Markup::Paragraph.new text
|
||||
end
|
||||
|
||||
def util_format(text)
|
||||
paragraph = util_paragraph text
|
||||
def util_format text
|
||||
paragraph = RDoc::Markup::Paragraph.new text
|
||||
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph paragraph
|
||||
|
|
|
@ -14,12 +14,11 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
|
|||
end
|
||||
|
||||
def assert_ref(path, ref)
|
||||
assert_equal "<p>\n<a href=\"#{path}\">#{ref}</a>\n</p>\n",
|
||||
@xref.convert(ref)
|
||||
assert_equal "\n<p><a href=\"#{path}\">#{ref}</a></p>\n", @xref.convert(ref)
|
||||
end
|
||||
|
||||
def refute_ref(body, ref)
|
||||
assert_equal "<p>\n#{body}\n</p>\n", @xref.convert(ref)
|
||||
assert_equal "\n<p>#{body}</p>\n", @xref.convert(ref)
|
||||
end
|
||||
|
||||
def test_handle_special_CROSSREF_C2
|
||||
|
@ -108,16 +107,16 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
|
|||
assert_ref 'C1.html#method-c-m', '::m'
|
||||
|
||||
assert_ref 'C1.html#method-i-m', 'C1#m'
|
||||
assert_ref 'C1.html#method-i-m', 'C1.m'
|
||||
assert_ref 'C1.html#method-c-m', 'C1.m'
|
||||
assert_ref 'C1.html#method-c-m', 'C1::m'
|
||||
|
||||
assert_ref 'C1.html#method-i-m', 'C1#m'
|
||||
assert_ref 'C1.html#method-i-m', 'C1#m()'
|
||||
assert_ref 'C1.html#method-i-m', 'C1#m(*)'
|
||||
|
||||
assert_ref 'C1.html#method-i-m', 'C1.m'
|
||||
assert_ref 'C1.html#method-i-m', 'C1.m()'
|
||||
assert_ref 'C1.html#method-i-m', 'C1.m(*)'
|
||||
assert_ref 'C1.html#method-c-m', 'C1.m'
|
||||
assert_ref 'C1.html#method-c-m', 'C1.m()'
|
||||
assert_ref 'C1.html#method-c-m', 'C1.m(*)'
|
||||
|
||||
assert_ref 'C1.html#method-c-m', 'C1::m'
|
||||
assert_ref 'C1.html#method-c-m', 'C1::m()'
|
||||
|
@ -127,7 +126,8 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
|
|||
|
||||
assert_ref 'C2/C3.html#method-i-m', 'C2::C3.m'
|
||||
|
||||
assert_ref 'C2/C3/H1.html#method-i-m%3F', 'C2::C3::H1#m?'
|
||||
# TODO stop escaping - HTML5 allows anything but space
|
||||
assert_ref 'C2/C3/H1.html#method-i-m-3F', 'C2::C3::H1#m?'
|
||||
|
||||
assert_ref 'C2/C3.html#method-i-m', '::C2::C3#m'
|
||||
assert_ref 'C2/C3.html#method-i-m', '::C2::C3#m()'
|
||||
|
@ -153,8 +153,15 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
|
|||
refute_ref '::C3::H1#n', '\::C3::H1#n'
|
||||
end
|
||||
|
||||
def test_handle_special_CROSSREF_show_hash_false
|
||||
@xref.show_hash = false
|
||||
|
||||
assert_equal "\n<p><a href=\"C1.html#method-i-m\">m</a></p>\n",
|
||||
@xref.convert('#m')
|
||||
end
|
||||
|
||||
def test_handle_special_CROSSREF_special
|
||||
assert_equal "<p>\n<a href=\"C2/C3.html\">C2::C3</a>;method(*)\n</p>\n",
|
||||
assert_equal "\n<p><a href=\"C2/C3.html\">C2::C3</a>;method(*)</p>\n",
|
||||
@xref.convert('C2::C3;method(*)')
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
require 'rubygems'
|
||||
require 'rdoc/markup/formatter_test_case'
|
||||
require 'rdoc/markup/text_formatter_test_case'
|
||||
require 'rdoc/markup/to_rdoc'
|
||||
require 'minitest/autorun'
|
||||
|
||||
class TestRDocMarkupToRdoc < RDoc::Markup::FormatterTestCase
|
||||
class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
|
||||
|
||||
add_visitor_tests
|
||||
add_text_tests
|
||||
|
||||
def setup
|
||||
super
|
||||
|
@ -191,8 +192,8 @@ class TestRDocMarkupToRdoc < RDoc::Markup::FormatterTestCase
|
|||
assert_equal "#{'-' * 78}\n", @to.res.join
|
||||
end
|
||||
|
||||
def accept_verbatim # FormatterTestCase doesn't set indent for ToAnsi
|
||||
assert_equal " hi\n world\n\n", @to.res.join
|
||||
def accept_verbatim
|
||||
assert_equal " hi\n world\n\n", @to.res.join
|
||||
end
|
||||
|
||||
def end_accepting
|
||||
|
@ -207,214 +208,102 @@ class TestRDocMarkupToRdoc < RDoc::Markup::FormatterTestCase
|
|||
assert_empty @to.list_width
|
||||
end
|
||||
|
||||
def test_accept_heading_1
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
def accept_heading_1
|
||||
assert_equal "= Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_2
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(2, 'Hello')
|
||||
|
||||
def accept_heading_2
|
||||
assert_equal "== Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_3
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(3, 'Hello')
|
||||
|
||||
def accept_heading_3
|
||||
assert_equal "=== Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_4
|
||||
@to.start_accepting
|
||||
@to.accept_heading @RM::Heading.new(4, 'Hello')
|
||||
|
||||
def accept_heading_4
|
||||
assert_equal "==== Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, 'Hello')
|
||||
|
||||
def accept_heading_indent
|
||||
assert_equal " = Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_heading_b
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_heading @RM::Heading.new(1, '*Hello*')
|
||||
|
||||
assert_equal " = <b>Hello</b>\n", @to.end_accepting
|
||||
def accept_heading_b
|
||||
assert_equal "= <b>Hello</b>\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_list_item_start_note_2
|
||||
list = @RM::List.new(:NOTE,
|
||||
@RM::ListItem.new('<tt>teletype</tt>',
|
||||
@RM::Paragraph.new('teletype description')))
|
||||
|
||||
@to.start_accepting
|
||||
|
||||
list.accept @to
|
||||
|
||||
expected = "<tt>teletype</tt>:\n teletype description\n\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_heading_suppressed_crossref
|
||||
assert_equal "= Hello\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_b
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <b>bold words</b> reg')
|
||||
|
||||
expected = "reg <b>bold words</b> reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_list_item_start_note_2
|
||||
assert_equal "<tt>teletype</tt>:\n teletype description\n\n", @to.res.join
|
||||
end
|
||||
|
||||
def test_accept_paragraph_i
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('reg <em>italic words</em> reg')
|
||||
|
||||
expected = "reg <em>italic words</em> reg\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_b
|
||||
assert_equal "reg <b>bold words</b> reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
def accept_paragraph_i
|
||||
assert_equal "reg <em>italic words</em> reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def accept_paragraph_indent
|
||||
expected = <<-EXPECTED
|
||||
words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words
|
||||
words words words words words words
|
||||
words words words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_plus
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular +teletype+ regular')
|
||||
|
||||
expected = "regular <tt>teletype</tt> regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_plus
|
||||
assert_equal "reg <tt>teletype</tt> reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_star
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular *bold* regular')
|
||||
|
||||
expected = "regular <b>bold</b> regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_star
|
||||
assert_equal "reg <b>bold</b> reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_underscore
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('regular _italic_ regular')
|
||||
|
||||
expected = "regular <em>italic</em> regular\n"
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
def accept_paragraph_underscore
|
||||
assert_equal "reg <em>italic</em> reg\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_paragraph_wrap
|
||||
@to.start_accepting
|
||||
@to.accept_paragraph @RM::Paragraph.new('words ' * 30)
|
||||
|
||||
def accept_paragraph_wrap
|
||||
expected = <<-EXPECTED
|
||||
words words words words words words words words words words words words words
|
||||
words words words words words words words words words words words words words
|
||||
words words words words
|
||||
words words words words
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_rule_indent
|
||||
@to.start_accepting
|
||||
@to.indent = 3
|
||||
|
||||
@to.accept_rule @RM::Rule.new(1)
|
||||
|
||||
def accept_rule_indent
|
||||
assert_equal " #{'-' * 75}\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_indent
|
||||
assert_equal " hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_accept_verbatim_big_indent
|
||||
@to.start_accepting
|
||||
|
||||
@to.indent = 2
|
||||
|
||||
@to.accept_verbatim @RM::Verbatim.new(' ', 'hi', "\n",
|
||||
' ', 'world', "\n")
|
||||
|
||||
def accept_verbatim_big_indent
|
||||
assert_equal " hi\n world\n\n", @to.end_accepting
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
assert_equal 'Dog', @to.attributes("\\Dog")
|
||||
end
|
||||
|
||||
def test_list_nested
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1'),
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l1.1')))),
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('l2'))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
def list_nested
|
||||
expected = <<-EXPECTED
|
||||
* l1
|
||||
* l1.1
|
||||
* l2
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
def test_list_verbatim # HACK overblown
|
||||
doc = @RM::Document.new(
|
||||
@RM::List.new(:BULLET,
|
||||
@RM::ListItem.new(nil,
|
||||
@RM::Paragraph.new('list', 'stuff'),
|
||||
@RM::BlankLine.new(),
|
||||
@RM::Verbatim.new(' ', '*', ' ', 'list', "\n",
|
||||
' ', 'with', "\n",
|
||||
"\n",
|
||||
' ', 'second', "\n",
|
||||
"\n",
|
||||
' ', '1.', ' ', 'indented', "\n",
|
||||
' ', '2.', ' ', 'numbered', "\n",
|
||||
"\n",
|
||||
' ', 'third', "\n",
|
||||
"\n",
|
||||
' ', '*', ' ', 'second', "\n"))))
|
||||
|
||||
output = doc.accept @to
|
||||
|
||||
expected = <<-EXPECTED
|
||||
def list_verbatim
|
||||
expected = <<-EXPECTED # HACK overblown
|
||||
* list stuff
|
||||
|
||||
* list
|
||||
|
@ -431,7 +320,7 @@ words words words words
|
|||
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, output
|
||||
assert_equal expected, @to.end_accepting
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
require File.expand_path '../xref_test_case', __FILE__
|
||||
|
||||
class TestRDocMethodAttr < XrefTestCase
|
||||
|
||||
def test_block_params_equal
|
||||
|
||||
m = RDoc::MethodAttr.new(nil, 'foo')
|
||||
|
||||
m.block_params = ''
|
||||
assert_equal '', m.block_params
|
||||
|
||||
m.block_params = 'a_var'
|
||||
assert_equal 'a_var', m.block_params
|
||||
|
||||
m.block_params = '()'
|
||||
assert_equal '', m.block_params
|
||||
|
||||
m.block_params = '(a_var, b_var)'
|
||||
assert_equal 'a_var, b_var', m.block_params
|
||||
|
||||
m.block_params = '.to_s + "</#{element.upcase}>"'
|
||||
assert_equal '', m.block_params
|
||||
|
||||
m.block_params = 'i.name'
|
||||
assert_equal 'name', m.block_params
|
||||
|
||||
m.block_params = 'attr.expanded_name, attr.value'
|
||||
assert_equal 'expanded_name, value', m.block_params
|
||||
|
||||
m.block_params = 'expanded_name, attr.value'
|
||||
assert_equal 'expanded_name, value', m.block_params
|
||||
|
||||
m.block_params = 'attr.expanded_name, value'
|
||||
assert_equal 'expanded_name, value', m.block_params
|
||||
|
||||
m.block_params = '(@base_notifier)'
|
||||
assert_equal 'base_notifier', m.block_params
|
||||
|
||||
m.block_params = 'if @signal_status == :IN_LOAD'
|
||||
assert_equal '', m.block_params
|
||||
|
||||
m.block_params = 'e if e.kind_of? Element'
|
||||
assert_equal 'e', m.block_params
|
||||
|
||||
m.block_params = '(e, f) if e.kind_of? Element'
|
||||
assert_equal 'e, f', m.block_params
|
||||
|
||||
m.block_params = 'back_path, back_name'
|
||||
assert_equal 'back_path, back_name', m.block_params
|
||||
|
||||
m.block_params = '(*a[1..-1])'
|
||||
assert_equal '*a', m.block_params
|
||||
|
||||
m.block_params = '@@context[:node] if defined? @@context[:node].namespace'
|
||||
assert_equal 'context', m.block_params
|
||||
|
||||
m.block_params = '(result, klass.const_get(constant_name))'
|
||||
assert_equal 'result, const', m.block_params
|
||||
|
||||
m.block_params = 'name.to_s if (bitmap & bit) != 0'
|
||||
assert_equal 'name', m.block_params
|
||||
|
||||
m.block_params = 'line unless line.deleted'
|
||||
assert_equal 'line', m.block_params
|
||||
|
||||
m.block_params = 'str + rs'
|
||||
assert_equal 'str', m.block_params
|
||||
|
||||
m.block_params = 'f+rs'
|
||||
assert_equal 'f', m.block_params
|
||||
|
||||
m.block_params = '[user, realm, hash[user]]'
|
||||
assert_equal 'user, realm, hash', m.block_params
|
||||
|
||||
m.block_params = 'proc{|rc| rc == "rc" ? irbrc : irbrc+rc| ... }'
|
||||
assert_equal 'proc', m.block_params
|
||||
|
||||
m.block_params = 'lambda { |x| x.to_i }'
|
||||
assert_equal 'lambda', m.block_params
|
||||
|
||||
m.block_params = '$&'
|
||||
assert_equal 'str', m.block_params
|
||||
|
||||
m.block_params = 'Inflections.instance'
|
||||
assert_equal 'instance', m.block_params
|
||||
|
||||
m.block_params = 'self.class::STARTED'
|
||||
assert_equal 'STARTED', m.block_params
|
||||
|
||||
m.block_params = 'Test::Unit::TestCase::STARTED'
|
||||
assert_equal 'STARTED', m.block_params
|
||||
|
||||
m.block_params = 'ActiveSupport::OptionMerger.new(self, options)'
|
||||
assert_equal 'option_merger', m.block_params
|
||||
|
||||
m.block_params = ', msg'
|
||||
assert_equal '', m.block_params
|
||||
|
||||
m.block_params = '[size.to_s(16), term, chunk, term].join'
|
||||
assert_equal '[size, term, chunk, term].join', m.block_params
|
||||
|
||||
m.block_params = 'YPath.new( path )'
|
||||
assert_equal 'y_path', m.block_params
|
||||
|
||||
end
|
||||
|
||||
def test_find_method_or_attribute_recursive
|
||||
inc = RDoc::Include.new 'M1', nil
|
||||
@m1.add_include inc # M1 now includes itself
|
||||
|
||||
assert_nil @m1_m.find_method_or_attribute 'm'
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
assert_equal 'RDoc::AnyMethod: C1#m', @c1_m.to_s
|
||||
assert_equal 'RDoc::AnyMethod: C2#b', @c2_b.to_s
|
||||
assert_equal 'RDoc::AnyMethod: C1::m', @c1__m.to_s
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@ class TestRDocNormalClass < XrefTestCase
|
|||
sub_klass = klass.add_class RDoc::NormalClass, 'SubClass', 'Klass'
|
||||
sub_klass.add_include incl
|
||||
|
||||
assert_equal [incl, klass], sub_klass.ancestors
|
||||
assert_equal [incl.name, klass], sub_klass.ancestors
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,7 +15,12 @@ class TestRDocNormalModule < XrefTestCase
|
|||
|
||||
mod.add_include incl
|
||||
|
||||
assert_equal [incl], mod.ancestors
|
||||
assert_equal [incl.name], mod.ancestors
|
||||
|
||||
mod2 = top_level.add_module RDoc::NormalModule, 'Inc2'
|
||||
inc2 = RDoc::Include.new 'Inc2', ''
|
||||
mod.add_include inc2
|
||||
assert_equal [mod2, incl.name], mod.ancestors
|
||||
end
|
||||
|
||||
def test_module_eh
|
||||
|
|
|
@ -2,12 +2,182 @@ require 'rubygems'
|
|||
require 'minitest/autorun'
|
||||
require 'rdoc/options'
|
||||
|
||||
require 'fileutils'
|
||||
require 'tmpdir'
|
||||
|
||||
class TestRDocOptions < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@options = RDoc::Options.new
|
||||
end
|
||||
|
||||
def test_check_files
|
||||
out, err = capture_io do
|
||||
Dir.mktmpdir do |dir|
|
||||
Dir.chdir dir do
|
||||
FileUtils.touch 'unreadable'
|
||||
FileUtils.chmod 0, 'unreadable'
|
||||
|
||||
@options.files = %w[nonexistent unreadable]
|
||||
|
||||
@options.check_files
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assert_empty @options.files
|
||||
|
||||
assert_equal '', out
|
||||
|
||||
expected = <<-EXPECTED
|
||||
file 'nonexistent' not found
|
||||
file 'unreadable' not readable
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, err
|
||||
end
|
||||
|
||||
def test_dry_run_default
|
||||
refute @options.dry_run
|
||||
end
|
||||
|
||||
def test_encoding_default
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
assert_equal Encoding.default_external, @options.encoding
|
||||
end
|
||||
|
||||
def test_parse_dash_p
|
||||
out, err = capture_io do
|
||||
@options.parse %w[-p]
|
||||
end
|
||||
|
||||
assert @options.pipe
|
||||
refute_match %r%^Usage: %, err
|
||||
refute_match %r%^invalid options%, err
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_dash_p_files
|
||||
out, err = capture_io do
|
||||
@options.parse ['-p', File.expand_path(__FILE__)]
|
||||
end
|
||||
|
||||
refute @options.pipe
|
||||
refute_match %r%^Usage: %, err
|
||||
assert_match %r%^invalid options: -p .with files.%, err
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_default
|
||||
@options.parse []
|
||||
|
||||
assert_equal RDoc::Generator::Darkfish, @options.generator
|
||||
assert_equal 'darkfish', @options.template
|
||||
assert_match %r%rdoc/generator/template/darkfish$%, @options.template_dir
|
||||
end
|
||||
|
||||
def test_parse_deprecated
|
||||
dep_hash = RDoc::Options::DEPRECATED
|
||||
options = dep_hash.keys.sort
|
||||
|
||||
out, err = capture_io do
|
||||
@options.parse options
|
||||
end
|
||||
|
||||
dep_hash.each_pair do |opt, message|
|
||||
assert_match %r%.*#{opt}.+#{message}%, err
|
||||
end
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_dry_run
|
||||
@options.parse %w[--dry-run]
|
||||
|
||||
assert @options.dry_run
|
||||
end
|
||||
|
||||
def test_parse_encoding
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
@options.parse %w[--encoding Big5]
|
||||
|
||||
assert_equal Encoding::Big5, @options.encoding
|
||||
assert_equal 'Big5', @options.charset
|
||||
end
|
||||
|
||||
def test_parse_encoding_invalid
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
out, err = capture_io do
|
||||
@options.parse %w[--encoding invalid]
|
||||
end
|
||||
|
||||
assert_match %r%^invalid options: --encoding invalid%, err
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_formatter
|
||||
e = assert_raises OptionParser::InvalidOption do
|
||||
@options.parse %w[--format darkfish --format ri]
|
||||
end
|
||||
|
||||
assert_equal 'invalid option: --format generator already set to darkfish',
|
||||
e.message
|
||||
end
|
||||
|
||||
def test_parse_formatter_ri
|
||||
e = assert_raises OptionParser::InvalidOption do
|
||||
@options.parse %w[--format darkfish --ri]
|
||||
end
|
||||
|
||||
assert_equal 'invalid option: --ri generator already set to darkfish',
|
||||
e.message
|
||||
|
||||
@options = RDoc::Options.new
|
||||
|
||||
e = assert_raises OptionParser::InvalidOption do
|
||||
@options.parse %w[--format darkfish -r]
|
||||
end
|
||||
|
||||
assert_equal 'invalid option: -r generator already set to darkfish',
|
||||
e.message
|
||||
end
|
||||
|
||||
def test_parse_formatter_ri_site
|
||||
e = assert_raises OptionParser::InvalidOption do
|
||||
@options.parse %w[--format darkfish --ri-site]
|
||||
end
|
||||
|
||||
assert_equal 'invalid option: --ri-site generator already set to darkfish',
|
||||
e.message
|
||||
|
||||
@options = RDoc::Options.new
|
||||
|
||||
e = assert_raises OptionParser::InvalidOption do
|
||||
@options.parse %w[--format darkfish -R]
|
||||
end
|
||||
|
||||
assert_equal 'invalid option: -R generator already set to darkfish',
|
||||
e.message
|
||||
end
|
||||
|
||||
def test_parse_help
|
||||
out, = capture_io do
|
||||
begin
|
||||
@options.parse %w[--help]
|
||||
rescue SystemExit
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal 1, out.scan(/HTML generator options:/).length
|
||||
assert_equal 1, out.scan(/ri generator options:/). length
|
||||
end
|
||||
|
||||
def test_parse_ignore_invalid
|
||||
out, err = capture_io do
|
||||
@options.parse %w[--ignore-invalid --bogus]
|
||||
|
@ -15,6 +185,8 @@ class TestRDocOptions < MiniTest::Unit::TestCase
|
|||
|
||||
refute_match %r%^Usage: %, err
|
||||
assert_match %r%^invalid options: --bogus%, err
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_ignore_invalid_default
|
||||
|
@ -26,17 +198,21 @@ class TestRDocOptions < MiniTest::Unit::TestCase
|
|||
assert_match %r%^invalid options: --bogus%, err
|
||||
|
||||
assert_equal 'BLAH', @options.main_page
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_ignore_invalid_no
|
||||
out, err = capture_io do
|
||||
assert_raises SystemExit do
|
||||
@options.parse %w[--no-ignore-invalid --bogus]
|
||||
@options.parse %w[--no-ignore-invalid --bogus=arg --bobogus --visibility=extended]
|
||||
end
|
||||
end
|
||||
|
||||
assert_match %r%^Usage: %, err
|
||||
assert_match %r%^invalid option: --bogus%, err
|
||||
assert_match %r%^invalid options: --bogus=arg, --bobogus, --visibility=extended%, err
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_parse_main
|
||||
|
@ -50,24 +226,73 @@ class TestRDocOptions < MiniTest::Unit::TestCase
|
|||
assert_equal 'MAIN', @options.main_page
|
||||
end
|
||||
|
||||
def test_parse_dash_p
|
||||
def test_parse_template
|
||||
out, err = capture_io do
|
||||
@options.parse %w[-p]
|
||||
@options.parse %w[--template darkfish]
|
||||
end
|
||||
|
||||
assert @options.pipe
|
||||
refute_match %r%^Usage: %, err
|
||||
refute_match %r%^invalid options%, err
|
||||
assert_empty out
|
||||
assert_empty err
|
||||
|
||||
assert_equal 'darkfish', @options.template
|
||||
|
||||
assert_match %r%rdoc/generator/template/darkfish$%, @options.template_dir
|
||||
end
|
||||
|
||||
def test_parse_dash_p_files
|
||||
def test_parse_template_nonexistent
|
||||
out, err = capture_io do
|
||||
@options.parse %w[-p README]
|
||||
@options.parse %w[--template NONEXISTENT]
|
||||
end
|
||||
|
||||
refute @options.pipe
|
||||
refute_match %r%^Usage: %, err
|
||||
assert_match %r%^invalid options: -p .with files.%, err
|
||||
assert_empty out
|
||||
assert_equal "could not find template NONEXISTENT\n", err
|
||||
|
||||
assert_equal 'darkfish', @options.template
|
||||
assert_match %r%rdoc/generator/template/darkfish$%, @options.template_dir
|
||||
end
|
||||
|
||||
def test_parse_template_load_path
|
||||
orig_LOAD_PATH = $LOAD_PATH.dup
|
||||
|
||||
template_dir = nil
|
||||
|
||||
Dir.mktmpdir do |dir|
|
||||
$LOAD_PATH << dir
|
||||
|
||||
template_dir = File.join dir, 'rdoc', 'generator', 'template', 'load_path'
|
||||
|
||||
FileUtils.mkdir_p template_dir
|
||||
|
||||
out, err = capture_io do
|
||||
@options.parse %w[--template load_path]
|
||||
end
|
||||
|
||||
assert_empty out
|
||||
assert_empty err
|
||||
end
|
||||
|
||||
assert_equal 'load_path', @options.template
|
||||
assert_equal template_dir, @options.template_dir
|
||||
ensure
|
||||
$LOAD_PATH.replace orig_LOAD_PATH
|
||||
end
|
||||
|
||||
def test_setup_generator
|
||||
test_generator = Object.new
|
||||
def test_generator.setup_options(op)
|
||||
@op = op
|
||||
end
|
||||
|
||||
def test_generator.op() @op end
|
||||
|
||||
RDoc::RDoc::GENERATORS['TestGenerator'] = test_generator
|
||||
|
||||
@options.setup_generator 'TestGenerator'
|
||||
|
||||
assert_equal test_generator, @options.generator
|
||||
assert_equal [test_generator], @options.generator_options
|
||||
|
||||
assert_equal @options, test_generator.op
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -11,25 +11,6 @@ class TestRDocParser < MiniTest::Unit::TestCase
|
|||
@binary_dat = File.expand_path '../binary.dat', __FILE__
|
||||
end
|
||||
|
||||
def test_class_binary_eh_erb
|
||||
erb = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.erb"
|
||||
open erb, 'wb' do |io|
|
||||
io.write 'blah blah <%= stuff %> <% more stuff %>'
|
||||
end
|
||||
|
||||
assert @RP.binary?(erb)
|
||||
|
||||
erb_rb = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.erb.rb"
|
||||
open erb_rb, 'wb' do |io|
|
||||
io.write 'blah blah <%= stuff %>'
|
||||
end
|
||||
|
||||
refute @RP.binary?(erb_rb)
|
||||
ensure
|
||||
File.unlink erb
|
||||
File.unlink erb_rb if erb_rb
|
||||
end
|
||||
|
||||
def test_class_binary_eh_marshal
|
||||
marshal = File.join Dir.tmpdir, "test_rdoc_parser_#{$$}.marshal"
|
||||
open marshal, 'wb' do |io|
|
||||
|
@ -42,6 +23,18 @@ class TestRDocParser < MiniTest::Unit::TestCase
|
|||
File.unlink marshal
|
||||
end
|
||||
|
||||
def test_class_binary_japanese_text
|
||||
file_name = File.expand_path '../test.ja.txt', __FILE__
|
||||
refute @RP.binary?(file_name)
|
||||
end
|
||||
|
||||
def test_class_binary_japanese_rdoc
|
||||
skip "Encoding not implemented" unless Object.const_defined? :Encoding
|
||||
|
||||
file_name = File.expand_path '../test.ja.rdoc', __FILE__
|
||||
refute @RP.binary?(file_name)
|
||||
end
|
||||
|
||||
def test_class_can_parse
|
||||
assert_equal @RP.can_parse(__FILE__), @RP::Ruby
|
||||
|
||||
|
@ -72,6 +65,10 @@ class TestRDocParser < MiniTest::Unit::TestCase
|
|||
def test_class_for_binary
|
||||
rp = @RP.dup
|
||||
|
||||
class << rp
|
||||
alias old_can_parse can_parse
|
||||
end
|
||||
|
||||
def rp.can_parse(*args) nil end
|
||||
|
||||
assert_nil @RP.for(nil, @binary_dat, nil, nil, nil)
|
||||
|
|
|
@ -1,12 +1,52 @@
|
|||
require 'stringio'
|
||||
require 'tempfile'
|
||||
require 'rubygems'
|
||||
require 'minitest/unit'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/options'
|
||||
require 'rdoc/parser/c'
|
||||
|
||||
=begin
|
||||
TODO: test call-seq parsing
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ARGF.readlines(sep=$/) -> array
|
||||
* ARGF.readlines(limit) -> array
|
||||
* ARGF.readlines(sep, limit) -> array
|
||||
*
|
||||
* ARGF.to_a(sep=$/) -> array
|
||||
* ARGF.to_a(limit) -> array
|
||||
* ARGF.to_a(sep, limit) -> array
|
||||
*
|
||||
* Reads +ARGF+'s current file in its entirety, returning an +Array+ of its
|
||||
* lines, one line per element. Lines are assumed to be separated by _sep_.
|
||||
*
|
||||
* lines = ARGF.readlines
|
||||
* lines[0] #=> "This is line one\n"
|
||||
*/
|
||||
|
||||
assert call-seq did not stop at first empty line
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
*
|
||||
* flt ** other -> float
|
||||
*
|
||||
* Raises <code>float</code> the <code>other</code> power.
|
||||
*
|
||||
* 2.0**3 #=> 8.0
|
||||
*/
|
||||
|
||||
assert call-seq correct (bug: was empty)
|
||||
|
||||
/* call-seq: flt ** other -> float */
|
||||
|
||||
assert call-seq correct
|
||||
|
||||
=end
|
||||
|
||||
class RDoc::Parser::C
|
||||
attr_accessor :classes
|
||||
attr_accessor :classes, :singleton_classes
|
||||
|
||||
public :do_classes, :do_constants
|
||||
end
|
||||
|
@ -30,6 +70,129 @@ class TestRDocParserC < MiniTest::Unit::TestCase
|
|||
@tempfile.close
|
||||
end
|
||||
|
||||
def test_do_attr_rb_attr
|
||||
content = <<-EOF
|
||||
void Init_Blah(void) {
|
||||
cBlah = rb_define_class("Blah", rb_cObject);
|
||||
|
||||
/*
|
||||
* This is an accessor
|
||||
*/
|
||||
rb_attr(cBlah, rb_intern("accessor"), 1, 1, Qfalse);
|
||||
|
||||
/*
|
||||
* This is a reader
|
||||
*/
|
||||
rb_attr(cBlah, rb_intern("reader"), 1, 0, Qfalse);
|
||||
|
||||
/*
|
||||
* This is a writer
|
||||
*/
|
||||
rb_attr(cBlah, rb_intern("writer"), 0, 1, Qfalse);
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'cBlah'
|
||||
|
||||
attrs = klass.attributes
|
||||
assert_equal 3, attrs.length, attrs.inspect
|
||||
|
||||
accessor = attrs.shift
|
||||
assert_equal 'accessor', accessor.name
|
||||
assert_equal 'RW', accessor.rw
|
||||
assert_equal 'This is an accessor', accessor.comment
|
||||
|
||||
reader = attrs.shift
|
||||
assert_equal 'reader', reader.name
|
||||
assert_equal 'R', reader.rw
|
||||
assert_equal 'This is a reader', reader.comment
|
||||
|
||||
writer = attrs.shift
|
||||
assert_equal 'writer', writer.name
|
||||
assert_equal 'W', writer.rw
|
||||
assert_equal 'This is a writer', writer.comment
|
||||
end
|
||||
|
||||
def test_do_attr_rb_define_attr
|
||||
content = <<-EOF
|
||||
void Init_Blah(void) {
|
||||
cBlah = rb_define_class("Blah", rb_cObject);
|
||||
|
||||
/*
|
||||
* This is an accessor
|
||||
*/
|
||||
rb_define_attr(cBlah, "accessor", 1, 1);
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'cBlah'
|
||||
|
||||
attrs = klass.attributes
|
||||
assert_equal 1, attrs.length, attrs.inspect
|
||||
|
||||
accessor = attrs.shift
|
||||
assert_equal 'accessor', accessor.name
|
||||
assert_equal 'RW', accessor.rw
|
||||
assert_equal 'This is an accessor', accessor.comment
|
||||
end
|
||||
|
||||
def test_do_aliases
|
||||
content = <<-EOF
|
||||
/*
|
||||
* This should show up as an alias with documentation
|
||||
*/
|
||||
VALUE blah(VALUE klass, VALUE year) {
|
||||
}
|
||||
|
||||
void Init_Blah(void) {
|
||||
cDate = rb_define_class("Date", rb_cObject);
|
||||
|
||||
rb_define_method(cDate, "blah", blah, 1);
|
||||
|
||||
rb_define_alias(cDate, "bleh", "blah");
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'cDate'
|
||||
|
||||
methods = klass.method_list
|
||||
assert_equal 2, methods.length
|
||||
assert_equal 'bleh', methods.last.name
|
||||
assert_equal 'blah', methods.last.is_alias_for.name
|
||||
end
|
||||
|
||||
def test_do_aliases_singleton
|
||||
content = <<-EOF
|
||||
/*
|
||||
* This should show up as a method with documentation
|
||||
*/
|
||||
VALUE blah(VALUE klass, VALUE year) {
|
||||
}
|
||||
|
||||
void Init_Blah(void) {
|
||||
cDate = rb_define_class("Date", rb_cObject);
|
||||
sDate = rb_singleton_class(cDate);
|
||||
|
||||
rb_define_method(sDate, "blah", blah, 1);
|
||||
|
||||
/*
|
||||
* This should show up as an alias
|
||||
*/
|
||||
rb_define_alias(sDate, "bleh", "blah");
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'cDate'
|
||||
|
||||
methods = klass.method_list
|
||||
|
||||
assert_equal 2, methods.length
|
||||
assert_equal 'bleh', methods.last.name
|
||||
assert methods.last.singleton
|
||||
assert_equal 'blah', methods.last.is_alias_for.name
|
||||
assert_equal 'This should show up as an alias', methods.last.comment
|
||||
end
|
||||
|
||||
def test_do_classes_boot_class
|
||||
content = <<-EOF
|
||||
/* Document-class: Foo
|
||||
|
@ -68,6 +231,17 @@ VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|||
assert_equal "this is the Foo class", klass.comment
|
||||
end
|
||||
|
||||
def test_do_classes_singleton
|
||||
content = <<-EOF
|
||||
VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
||||
VALUE cFooS = rb_singleton_class(cFoo);
|
||||
EOF
|
||||
|
||||
util_get_class content, 'cFooS'
|
||||
|
||||
assert_equal 'Foo', @parser.singleton_classes['cFooS']
|
||||
end
|
||||
|
||||
def test_do_classes_class_under
|
||||
content = <<-EOF
|
||||
/* Document-class: Kernel::Foo
|
||||
|
@ -201,6 +375,26 @@ Multiline comment goes here because this comment spans multiple lines.
|
|||
assert constants.empty?, constants.inspect
|
||||
end
|
||||
|
||||
def test_find_alias_comment
|
||||
parser = util_parser ''
|
||||
|
||||
comment = parser.find_alias_comment 'C', '[]', 'index'
|
||||
|
||||
assert_equal '', comment
|
||||
|
||||
parser = util_parser <<-C
|
||||
/*
|
||||
* comment
|
||||
*/
|
||||
|
||||
rb_define_alias(C, "[]", "index");
|
||||
C
|
||||
|
||||
comment = parser.find_alias_comment 'C', '[]', 'index'
|
||||
|
||||
assert_equal "/*\n * comment\n */\n\n", comment
|
||||
end
|
||||
|
||||
def test_find_class_comment_include
|
||||
@options.rdoc_include << File.dirname(__FILE__)
|
||||
|
||||
|
@ -406,6 +600,113 @@ Init_Foo(void) {
|
|||
assert_equal "a comment for bar", bar.comment
|
||||
end
|
||||
|
||||
def test_find_modifiers_call_seq
|
||||
comment = <<-COMMENT
|
||||
/* call-seq:
|
||||
* commercial() -> Date <br />
|
||||
* commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
|
||||
* commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
|
||||
*
|
||||
* If no arguments are given:
|
||||
* * ruby 1.8: returns a +Date+ for 1582-10-15 (the Day of Calendar Reform in
|
||||
* Italy)
|
||||
* * ruby 1.9: returns a +Date+ for julian day 0
|
||||
*
|
||||
* Otherwise, returns a +Date+ for the commercial week year, commercial week,
|
||||
* and commercial week day given. Ignores the 4th argument.
|
||||
*/
|
||||
|
||||
COMMENT
|
||||
|
||||
parser = util_parser ''
|
||||
method_obj = RDoc::AnyMethod.new nil, 'blah'
|
||||
|
||||
parser.find_modifiers comment, method_obj
|
||||
|
||||
expected = <<-CALL_SEQ.chomp
|
||||
commercial() -> Date <br />
|
||||
commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
|
||||
commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
|
||||
|
||||
CALL_SEQ
|
||||
|
||||
assert_equal expected, method_obj.call_seq
|
||||
end
|
||||
|
||||
def test_find_modifiers_nodoc
|
||||
comment = <<-COMMENT
|
||||
/* :nodoc:
|
||||
*
|
||||
* Blah
|
||||
*/
|
||||
|
||||
COMMENT
|
||||
|
||||
parser = util_parser ''
|
||||
method_obj = RDoc::AnyMethod.new nil, 'blah'
|
||||
|
||||
parser.find_modifiers comment, method_obj
|
||||
|
||||
assert_equal nil, method_obj.document_self
|
||||
end
|
||||
|
||||
def test_find_modifiers_yields
|
||||
comment = <<-COMMENT
|
||||
/* :yields: a, b
|
||||
*
|
||||
* Blah
|
||||
*/
|
||||
|
||||
COMMENT
|
||||
|
||||
parser = util_parser ''
|
||||
method_obj = RDoc::AnyMethod.new nil, 'blah'
|
||||
|
||||
parser.find_modifiers comment, method_obj
|
||||
|
||||
assert_equal 'a, b', method_obj.block_params
|
||||
|
||||
expected = <<-EXPECTED
|
||||
/*
|
||||
*
|
||||
* Blah
|
||||
*/
|
||||
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected, comment
|
||||
end
|
||||
|
||||
def test_handle_method
|
||||
parser = util_parser "Document-method: BasicObject#==\n blah */"
|
||||
|
||||
parser.handle_method 'method', 'rb_cBasicObject', '==', 'rb_obj_equal', 1
|
||||
|
||||
bo = @top_level.find_module_named 'BasicObject'
|
||||
|
||||
assert_equal 1, bo.method_list.length
|
||||
|
||||
equals2 = bo.method_list.first
|
||||
|
||||
assert_equal '==', equals2.name
|
||||
end
|
||||
|
||||
def test_handle_method_initialize
|
||||
parser = util_parser "Document-method: BasicObject::new\n blah */"
|
||||
|
||||
parser.handle_method('private_method', 'rb_cBasicObject',
|
||||
'initialize', 'rb_obj_dummy', -1)
|
||||
|
||||
bo = @top_level.find_module_named 'BasicObject'
|
||||
|
||||
assert_equal 1, bo.method_list.length
|
||||
|
||||
new = bo.method_list.first
|
||||
|
||||
assert_equal 'new', new.name
|
||||
assert_equal :public, new.visibility
|
||||
end
|
||||
|
||||
def test_look_for_directives_in
|
||||
parser = util_parser ''
|
||||
|
||||
|
@ -442,6 +743,7 @@ Init_IO(void) {
|
|||
read_method = klass.method_list.first
|
||||
assert_equal "read", read_method.name
|
||||
assert_equal "Method Comment! ", read_method.comment
|
||||
assert read_method.singleton
|
||||
end
|
||||
|
||||
def test_define_method_private
|
||||
|
@ -472,6 +774,65 @@ Init_IO(void) {
|
|||
assert_equal "Method Comment! ", read_method.comment
|
||||
end
|
||||
|
||||
def test_define_method_private_singleton
|
||||
content = <<-EOF
|
||||
/*Method Comment! */
|
||||
static VALUE
|
||||
rb_io_s_read(argc, argv, io)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE io;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Init_IO(void) {
|
||||
/*
|
||||
* a comment for class Foo on rb_define_class
|
||||
*/
|
||||
VALUE rb_cIO = rb_define_class("IO", rb_cObject);
|
||||
VALUE rb_cIO_s = rb_singleton_class(rb_cIO);
|
||||
rb_define_private_method(rb_cIO_s, "read", rb_io_s_read, -1);
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'rb_cIO'
|
||||
read_method = klass.method_list.first
|
||||
assert_equal "read", read_method.name
|
||||
assert_equal "Method Comment! ", read_method.comment
|
||||
assert_equal :private, read_method.visibility
|
||||
assert read_method.singleton
|
||||
end
|
||||
|
||||
def test_define_method_singleton
|
||||
content = <<-EOF
|
||||
/*Method Comment! */
|
||||
static VALUE
|
||||
rb_io_s_read(argc, argv, io)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE io;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Init_IO(void) {
|
||||
/*
|
||||
* a comment for class Foo on rb_define_class
|
||||
*/
|
||||
VALUE rb_cIO = rb_define_class("IO", rb_cObject);
|
||||
VALUE rb_cIO_s = rb_singleton_class(rb_cIO);
|
||||
rb_define_method(rb_cIO_s, "read", rb_io_s_read, -1);
|
||||
}
|
||||
EOF
|
||||
|
||||
klass = util_get_class content, 'rb_cIO'
|
||||
read_method = klass.method_list.first
|
||||
assert_equal "read", read_method.name
|
||||
assert_equal "Method Comment! ", read_method.comment
|
||||
assert read_method.singleton
|
||||
end
|
||||
|
||||
def util_get_class(content, name)
|
||||
@parser = util_parser content
|
||||
@parser.scan
|
||||
|
@ -484,4 +845,3 @@ Init_IO(void) {
|
|||
|
||||
end
|
||||
|
||||
MiniTest::Unit.autorun
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
require 'stringio'
|
||||
require 'tempfile'
|
||||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/options'
|
||||
require 'rdoc/parser/perl'
|
||||
|
||||
class TestRdocParserPerlPOD < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@tempfile = Tempfile.new self.class.name
|
||||
filename = @tempfile.path
|
||||
|
||||
@top_level = RDoc::TopLevel.new filename
|
||||
@fn = filename
|
||||
@options = RDoc::Options.new
|
||||
@stats = RDoc::Stats.new 0
|
||||
end
|
||||
|
||||
def teardown
|
||||
@tempfile.close
|
||||
end
|
||||
|
||||
def test_uncommented_perl
|
||||
content = <<-EOF
|
||||
while (<>) {
|
||||
tr/a-z/A-Z;
|
||||
print
|
||||
}
|
||||
EOF
|
||||
|
||||
comment = util_get_comment content
|
||||
assert_equal "", comment
|
||||
end
|
||||
|
||||
def test_perl_without_pod
|
||||
content = <<-EOF
|
||||
#!/usr/local/bin/perl
|
||||
#
|
||||
#This is a pointless perl program because it does -p.
|
||||
#
|
||||
while(<>) {print;}:
|
||||
EOF
|
||||
|
||||
comment = util_get_comment content
|
||||
assert_equal "", comment
|
||||
end
|
||||
|
||||
def test_simple_pod_no_structure
|
||||
content = <<-EOF
|
||||
=begin pod
|
||||
|
||||
This just contains plain old documentation
|
||||
|
||||
=end
|
||||
EOF
|
||||
comment = util_get_comment content
|
||||
assert_equal 'This just contains plain old documentation', comment
|
||||
end
|
||||
|
||||
# Get the comment of the @top_level when it has processed the input.
|
||||
def util_get_comment(content)
|
||||
parser = util_parser content
|
||||
parser.scan.comment
|
||||
end
|
||||
|
||||
# create a new parser with the supplied content.
|
||||
def util_parser(content)
|
||||
RDoc::Parser::PerlPOD.new @top_level, @fn, content, @options, @stats
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -22,6 +22,8 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
util_top_level
|
||||
@options = RDoc::Options.new
|
||||
@options.quiet = true
|
||||
@options.option_parser = OptionParser.new
|
||||
|
||||
@stats = RDoc::Stats.new 0
|
||||
end
|
||||
|
||||
|
@ -30,6 +32,30 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
@tempfile2.close
|
||||
end
|
||||
|
||||
def test_get_symbol_or_name
|
||||
util_parser "* & | + 5 / 4"
|
||||
|
||||
assert_equal '*', @parser.get_symbol_or_name
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal '&', @parser.get_symbol_or_name
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal '|', @parser.get_symbol_or_name
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal '+', @parser.get_symbol_or_name
|
||||
|
||||
@parser.skip_tkspace
|
||||
@parser.get_tk
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal '/', @parser.get_symbol_or_name
|
||||
end
|
||||
|
||||
def test_look_for_directives_in_attr
|
||||
util_parser ""
|
||||
|
||||
|
@ -52,6 +78,61 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal "# :attr_writer: my_method\n", comment
|
||||
end
|
||||
|
||||
def test_remove_private_comments
|
||||
util_parser ''
|
||||
|
||||
comment = <<-EOS
|
||||
# This is text
|
||||
#--
|
||||
# this is private
|
||||
EOS
|
||||
|
||||
expected = <<-EOS
|
||||
# This is text
|
||||
EOS
|
||||
|
||||
@parser.remove_private_comments(comment)
|
||||
|
||||
assert_equal expected, comment
|
||||
end
|
||||
|
||||
def test_remove_private_comments_rule
|
||||
util_parser ''
|
||||
|
||||
comment = <<-EOS
|
||||
# This is text with a rule:
|
||||
# ---
|
||||
# this is also text
|
||||
EOS
|
||||
|
||||
expected = comment.dup
|
||||
|
||||
@parser.remove_private_comments(comment)
|
||||
|
||||
assert_equal expected, comment
|
||||
end
|
||||
|
||||
def test_remove_private_comments_toggle
|
||||
util_parser ''
|
||||
|
||||
comment = <<-EOS
|
||||
# This is text
|
||||
#--
|
||||
# this is private
|
||||
#++
|
||||
# This is text again.
|
||||
EOS
|
||||
|
||||
expected = <<-EOS
|
||||
# This is text
|
||||
# This is text again.
|
||||
EOS
|
||||
|
||||
@parser.remove_private_comments(comment)
|
||||
|
||||
assert_equal expected, comment
|
||||
end
|
||||
|
||||
def test_look_for_directives_in_commented
|
||||
util_parser ""
|
||||
|
||||
|
@ -70,9 +151,9 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
def test_look_for_directives_in_enddoc
|
||||
util_parser ""
|
||||
|
||||
assert_throws :enddoc do
|
||||
@parser.look_for_directives_in @top_level, "# :enddoc:\n"
|
||||
end
|
||||
@parser.look_for_directives_in @top_level, "# :enddoc:\n"
|
||||
|
||||
assert @top_level.done_documenting
|
||||
end
|
||||
|
||||
def test_look_for_directives_in_main
|
||||
|
@ -105,13 +186,11 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
@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
|
||||
|
@ -166,10 +245,29 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
|
||||
alas = @parser.parse_alias klass, RDoc::Parser::Ruby::NORMAL, tk, 'comment'
|
||||
|
||||
assert_equal 'bar', alas.old_name
|
||||
assert_equal 'next=', alas.new_name
|
||||
assert_equal klass, alas.parent
|
||||
assert_equal 'comment', alas.comment
|
||||
assert_equal 'bar', alas.old_name
|
||||
assert_equal 'next=', alas.new_name
|
||||
assert_equal klass, alas.parent
|
||||
assert_equal 'comment', alas.comment
|
||||
assert_equal @top_level, alas.file
|
||||
end
|
||||
|
||||
def test_parse_alias_singleton
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
util_parser "alias :next= :bar"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
alas = @parser.parse_alias klass, RDoc::Parser::Ruby::SINGLE, tk, 'comment'
|
||||
|
||||
assert_equal 'bar', alas.old_name
|
||||
assert_equal 'next=', alas.new_name
|
||||
assert_equal klass, alas.parent
|
||||
assert_equal 'comment', alas.comment
|
||||
assert_equal @top_level, alas.file
|
||||
assert alas.singleton
|
||||
end
|
||||
|
||||
def test_parse_alias_meta
|
||||
|
@ -202,6 +300,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
foo = klass.attributes.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my attr', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_attr_accessor
|
||||
|
@ -222,6 +321,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal 'my attr', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
bar = klass.attributes.last
|
||||
assert_equal 'bar', bar.name
|
||||
|
@ -229,6 +329,21 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'my attr', bar.comment
|
||||
end
|
||||
|
||||
def test_parse_attr_accessor_nodoc
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my attr\n"
|
||||
|
||||
util_parser "attr_accessor :foo, :bar # :nodoc:"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_attr_accessor klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
|
||||
assert_equal 0, klass.attributes.length
|
||||
end
|
||||
|
||||
def test_parse_attr_accessor_writer
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
@ -247,6 +362,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'W', foo.rw
|
||||
assert_equal "my attr", foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
bar = klass.attributes.last
|
||||
assert_equal 'bar', bar.name
|
||||
|
@ -271,6 +387,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal "my method", foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_attr_accessor
|
||||
|
@ -290,6 +407,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_attr_named
|
||||
|
@ -309,6 +427,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_attr_reader
|
||||
|
@ -327,6 +446,7 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'R', foo.rw
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_attr_writer
|
||||
|
@ -345,12 +465,13 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal 'W', foo.rw
|
||||
assert_equal "my method", foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_class
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser 'class Foo; end'
|
||||
util_parser "class Foo\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
|
@ -379,11 +500,12 @@ end
|
|||
|
||||
blah = foo.method_list.first
|
||||
assert_equal 'Foo#blah', blah.full_name
|
||||
assert_equal @top_level, blah.file
|
||||
end
|
||||
|
||||
def test_parse_class_nested_superclass
|
||||
foo = RDoc::NormalModule.new 'Foo'
|
||||
foo.parent = @top_level
|
||||
util_top_level
|
||||
foo = @top_level.add_module RDoc::NormalModule, 'Foo'
|
||||
|
||||
util_parser "class Bar < Super\nend"
|
||||
|
||||
|
@ -398,7 +520,7 @@ end
|
|||
def test_parse_module
|
||||
comment = "##\n# my module\n"
|
||||
|
||||
util_parser 'module Foo; end'
|
||||
util_parser "module Foo\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
|
@ -430,6 +552,8 @@ class A
|
|||
class << B
|
||||
end
|
||||
class << d = Object.new
|
||||
def foo; end
|
||||
alias bar foo
|
||||
end
|
||||
end
|
||||
CODE
|
||||
|
@ -439,7 +563,40 @@ end
|
|||
@parser.parse_class @top_level, false, @parser.get_tk, ''
|
||||
|
||||
assert_equal %w[A], RDoc::TopLevel.classes.map { |c| c.full_name }
|
||||
assert_equal %w[A::B], RDoc::TopLevel.modules.map { |c| c.full_name }
|
||||
assert_equal %w[A::B A::d], RDoc::TopLevel.modules.map { |c| c.full_name }
|
||||
|
||||
# make sure method/alias was not added to enclosing class/module
|
||||
a = RDoc::TopLevel.all_classes_hash['A']
|
||||
assert_empty a.method_list
|
||||
|
||||
# make sure non-constant-named module will be removed from documentation
|
||||
d = RDoc::TopLevel.all_modules_hash['A::d']
|
||||
assert d.remove_from_documentation?
|
||||
|
||||
end
|
||||
|
||||
# TODO this is really a Context#add_class test
|
||||
def test_parse_class_object
|
||||
code = <<-CODE
|
||||
module A
|
||||
class B
|
||||
end
|
||||
class Object
|
||||
end
|
||||
class C < Object
|
||||
end
|
||||
end
|
||||
CODE
|
||||
|
||||
util_parser code
|
||||
|
||||
@parser.parse_module @top_level, false, @parser.get_tk, ''
|
||||
|
||||
assert_equal %w[A], RDoc::TopLevel.modules.map { |c| c.full_name }
|
||||
assert_equal %w[A::B A::C A::Object], RDoc::TopLevel.classes.map { |c| c.full_name }.sort
|
||||
assert_equal 'Object', RDoc::TopLevel.classes_hash['A::B'].superclass
|
||||
assert_equal 'Object', RDoc::TopLevel.classes_hash['A::Object'].superclass
|
||||
assert_equal 'A::Object', RDoc::TopLevel.classes_hash['A::C'].superclass.full_name
|
||||
end
|
||||
|
||||
def test_parse_class_mistaken_for_module
|
||||
|
@ -447,7 +604,7 @@ end
|
|||
# before Foo::Bar is encountered), but RDoc might encounter Foo::Bar
|
||||
# before Foo if they live in different files.
|
||||
|
||||
code = <<-EOF
|
||||
code = <<-RUBY
|
||||
class Foo::Bar
|
||||
end
|
||||
|
||||
|
@ -456,7 +613,7 @@ end
|
|||
|
||||
class Foo
|
||||
end
|
||||
EOF
|
||||
RUBY
|
||||
|
||||
util_parser code
|
||||
|
||||
|
@ -542,18 +699,20 @@ EOF
|
|||
@parser.parse_comment klass, tk, comment
|
||||
|
||||
foo = klass.attributes.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal 'my attr', foo.comment
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'RW', foo.rw
|
||||
assert_equal 'my attr', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
assert_equal nil, foo.viewer
|
||||
assert_equal true, foo.document_children
|
||||
assert_equal true, foo.document_self
|
||||
assert_equal false, foo.done_documenting
|
||||
assert_equal false, foo.force_documentation
|
||||
assert_equal klass, foo.parent
|
||||
assert_equal :public, foo.visibility
|
||||
assert_equal "\n", foo.text
|
||||
|
||||
assert_equal nil, foo.viewer
|
||||
assert_equal true, foo.document_children
|
||||
assert_equal true, foo.document_self
|
||||
assert_equal false, foo.done_documenting
|
||||
assert_equal false, foo.force_documentation
|
||||
assert_equal klass, foo.parent
|
||||
assert_equal :public, foo.visibility
|
||||
assert_equal "\n", foo.text
|
||||
assert_equal klass.current_section, foo.section
|
||||
end
|
||||
|
||||
|
@ -570,8 +729,9 @@ EOF
|
|||
@parser.parse_comment klass, tk, comment
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
assert_equal [], foo.aliases
|
||||
assert_equal nil, foo.block_params
|
||||
|
@ -599,9 +759,23 @@ EOF
|
|||
assert_equal stream, foo.token_stream
|
||||
end
|
||||
|
||||
def test_parse_constant_attrasgn
|
||||
util_top_level
|
||||
|
||||
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
|
||||
|
||||
util_parser "A[k] = v"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_constant klass, tk, ''
|
||||
|
||||
assert klass.constants.empty?
|
||||
end
|
||||
|
||||
def test_parse_constant_alias
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
util_top_level
|
||||
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
|
||||
cB = klass.add_class RDoc::NormalClass, 'B'
|
||||
|
||||
util_parser "A = B"
|
||||
|
@ -642,8 +816,9 @@ EOF
|
|||
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
assert_equal [], foo.aliases
|
||||
assert_equal nil, foo.block_params
|
||||
|
@ -691,8 +866,9 @@ EOF
|
|||
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'woo_hoo!', foo.name
|
||||
assert_equal 'woo_hoo!', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_method_singleton
|
||||
|
@ -711,6 +887,7 @@ EOF
|
|||
assert_equal 'foo', foo.name
|
||||
assert_equal true, foo.singleton, 'singleton method'
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_method_singleton_name
|
||||
|
@ -729,6 +906,7 @@ EOF
|
|||
assert_equal 'woo_hoo!', foo.name
|
||||
assert_equal true, foo.singleton, 'singleton method'
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_method_string_name
|
||||
|
@ -744,6 +922,7 @@ EOF
|
|||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_meta_method_unknown
|
||||
|
@ -759,6 +938,7 @@ EOF
|
|||
foo = klass.method_list.first
|
||||
assert_equal 'unknown', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_method
|
||||
|
@ -774,8 +954,9 @@ EOF
|
|||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal 'foo', foo.name
|
||||
assert_equal 'my method', foo.comment
|
||||
assert_equal @top_level, foo.file
|
||||
|
||||
assert_equal [], foo.aliases
|
||||
assert_equal nil, foo.block_params
|
||||
|
@ -826,41 +1007,55 @@ EOF
|
|||
assert klass.aliases.empty?
|
||||
end
|
||||
|
||||
def test_parse_method_utf8
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
method = "def ω() end"
|
||||
|
||||
assert_equal Encoding::UTF_8, method.encoding if defined? ::Encoding
|
||||
|
||||
util_parser method
|
||||
def test_parse_method_false
|
||||
util_parser "def false.foo() :bar end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
omega = klass.method_list.first
|
||||
assert_equal "def \317\211", omega.text
|
||||
klass = RDoc::TopLevel.find_class_named 'FalseClass'
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
end
|
||||
|
||||
def test_parse_method_funky
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser "def (blah).foo() :bar end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
assert klass.method_list.empty?
|
||||
end
|
||||
|
||||
def test_parse_method_gvar
|
||||
util_parser "def $stdout.foo() :bar end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
assert @top_level.method_list.empty?
|
||||
end
|
||||
|
||||
def test_parse_method_internal_gvar
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
util_parser "def foo() def $blah.bar() end end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
assert_equal 1, klass.method_list.length
|
||||
end
|
||||
|
||||
def test_parse_method_internal_ivar
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
@ -887,33 +1082,43 @@ EOF
|
|||
assert_equal 1, klass.method_list.length
|
||||
end
|
||||
|
||||
def test_parse_method_nil
|
||||
util_parser "def nil.foo() :bar end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
klass = RDoc::TopLevel.find_class_named 'NilClass'
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
end
|
||||
|
||||
def test_parse_method_no_parens
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser "def foo arg1, arg2\nend"
|
||||
util_parser "def foo arg1, arg2 = {}\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal '(arg1, arg2)', foo.params
|
||||
assert_equal '(arg1, arg2 = {})', foo.params
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_method_parameters_comment
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser "def foo arg1, arg2 # some useful comment\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal '(arg1, arg2)', foo.params
|
||||
|
@ -923,13 +1128,11 @@ EOF
|
|||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser "def foo arg1, arg2, # some useful comment\narg3\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal '(arg1, arg2, arg3)', foo.params
|
||||
|
@ -938,18 +1141,17 @@ EOF
|
|||
def test_parse_method_toplevel
|
||||
klass = @top_level
|
||||
|
||||
comment = "##\n# my method\n"
|
||||
|
||||
util_parser "def foo arg1, arg2\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
object = RDoc::TopLevel.find_class_named 'Object'
|
||||
|
||||
foo = object.method_list.first
|
||||
assert_equal 'Object#foo', foo.full_name
|
||||
assert_equal @top_level, foo.file
|
||||
end
|
||||
|
||||
def test_parse_method_toplevel_class
|
||||
|
@ -967,9 +1169,39 @@ EOF
|
|||
assert_equal 'Object::foo', foo.full_name
|
||||
end
|
||||
|
||||
def test_parse_statements_class_if
|
||||
comment = "##\n# my method\n"
|
||||
def test_parse_method_true
|
||||
util_parser "def true.foo() :bar end"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
klass = RDoc::TopLevel.find_class_named 'TrueClass'
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'foo', foo.name
|
||||
end
|
||||
|
||||
def test_parse_method_utf8
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
method = "def ω() end"
|
||||
|
||||
assert_equal Encoding::UTF_8, method.encoding if
|
||||
Object.const_defined? :Encoding
|
||||
|
||||
util_parser method
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
omega = klass.method_list.first
|
||||
assert_equal "def \317\211", omega.text
|
||||
end
|
||||
|
||||
def test_parse_statements_class_if
|
||||
util_parser <<-CODE
|
||||
module Foo
|
||||
X = if TRUE then
|
||||
|
@ -1024,7 +1256,12 @@ end
|
|||
end
|
||||
|
||||
def test_parse_statements_identifier_alias_method
|
||||
content = "class Foo def foo() end; alias_method :foo2, :foo end"
|
||||
content = <<-RUBY
|
||||
class Foo
|
||||
def foo() end
|
||||
alias_method :foo2, :foo
|
||||
end
|
||||
RUBY
|
||||
|
||||
util_parser content
|
||||
|
||||
|
@ -1078,10 +1315,25 @@ EOF
|
|||
assert_equal 'foo4', foo4.name
|
||||
assert_equal 'foo', foo4.is_alias_for.name
|
||||
|
||||
assert_equal 'unknown', @top_level.classes.first.aliases[0].old_name
|
||||
assert_equal 'unknown', @top_level.classes.first.external_aliases[0].old_name
|
||||
end
|
||||
|
||||
def test_parse_statements_identifier_constant
|
||||
|
||||
sixth_constant = <<-EOF
|
||||
Class.new do
|
||||
rule :file do
|
||||
all(x, y, z) {
|
||||
def value
|
||||
find(:require).each {|r| require r.value }
|
||||
find(:grammar).map {|g| g.value }
|
||||
end
|
||||
def min; end
|
||||
}
|
||||
end
|
||||
end
|
||||
EOF
|
||||
|
||||
content = <<-EOF
|
||||
class Foo
|
||||
FIRST_CONSTANT = 5
|
||||
|
@ -1103,6 +1355,10 @@ class Foo
|
|||
end
|
||||
|
||||
FIFTH_CONSTANT = SECOND_CONSTANT.map { |element| element + 1 }
|
||||
|
||||
SIXTH_CONSTANT = #{sixth_constant}
|
||||
|
||||
SEVENTH_CONSTANT = proc { |i| begin i end }
|
||||
end
|
||||
EOF
|
||||
|
||||
|
@ -1115,26 +1371,43 @@ EOF
|
|||
constant = constants[0]
|
||||
assert_equal 'FIRST_CONSTANT', constant.name
|
||||
assert_equal '5', constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
constant = constants[1]
|
||||
assert_equal 'SECOND_CONSTANT', constant.name
|
||||
assert_equal '[ 1, 2, 3 ]', constant.value
|
||||
assert_equal "[\n1,\n2,\n3\n]", constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
constant = constants[2]
|
||||
assert_equal 'THIRD_CONSTANT', constant.name
|
||||
assert_equal "{ :foo => 'bar', :x => 'y' }", constant.value
|
||||
assert_equal "{\n:foo => 'bar',\n:x => 'y'\n}", constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
constant = constants[3]
|
||||
assert_equal 'FOURTH_CONSTANT', constant.name
|
||||
assert_equal 'SECOND_CONSTANT.map do |element| element + 1 element + 2 end', constant.value
|
||||
assert_equal "SECOND_CONSTANT.map do |element|\nelement + 1\nelement + 2\nend", constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
constant = constants.last
|
||||
constant = constants[4]
|
||||
assert_equal 'FIFTH_CONSTANT', constant.name
|
||||
assert_equal 'SECOND_CONSTANT.map { |element| element + 1 }', constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
# TODO: parse as class
|
||||
constant = constants[5]
|
||||
assert_equal 'SIXTH_CONSTANT', constant.name
|
||||
assert_equal sixth_constant.lines.map(&:strip).join("\n"), constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
|
||||
# TODO: parse as method
|
||||
constant = constants[6]
|
||||
assert_equal 'SEVENTH_CONSTANT', constant.name
|
||||
assert_equal "proc { |i| begin i end }", constant.value
|
||||
assert_equal @top_level, constant.file
|
||||
end
|
||||
|
||||
def test_parse_statements_identifier_attr
|
||||
content = "class Foo; attr :foo; end"
|
||||
content = "class Foo\nattr :foo\nend"
|
||||
|
||||
util_parser content
|
||||
|
||||
|
@ -1146,7 +1419,7 @@ EOF
|
|||
end
|
||||
|
||||
def test_parse_statements_identifier_attr_accessor
|
||||
content = "class Foo; attr_accessor :foo; end"
|
||||
content = "class Foo\nattr_accessor :foo\nend"
|
||||
|
||||
util_parser content
|
||||
|
||||
|
@ -1158,7 +1431,7 @@ EOF
|
|||
end
|
||||
|
||||
def test_parse_statements_identifier_include
|
||||
content = "class Foo; include Bar; end"
|
||||
content = "class Foo\ninclude Bar\nend"
|
||||
|
||||
util_parser content
|
||||
|
||||
|
@ -1170,24 +1443,24 @@ EOF
|
|||
end
|
||||
|
||||
def test_parse_statements_identifier_module_function
|
||||
content = "module Foo def foo() end; module_function :foo; end"
|
||||
content = "module Foo\ndef foo() end\nmodule_function :foo\nend"
|
||||
|
||||
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 'foo', foo.name, 'instance method name'
|
||||
assert_equal :private, foo.visibility, 'instance method visibility'
|
||||
assert_equal false, foo.singleton, 'instance method singleton'
|
||||
assert_equal false, foo.singleton, 'instance method singleton'
|
||||
|
||||
assert_equal 'foo', s_foo.name, 'module function name'
|
||||
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'
|
||||
assert_equal true, s_foo.singleton, 'module function singleton'
|
||||
end
|
||||
|
||||
def test_parse_statements_identifier_private
|
||||
content = "class Foo private; def foo() end end"
|
||||
content = "class Foo\nprivate\ndef foo() end\nend"
|
||||
|
||||
util_parser content
|
||||
|
||||
|
@ -1235,6 +1508,24 @@ end
|
|||
assert_equal 'A#b', m_b.full_name
|
||||
end
|
||||
|
||||
def test_parse_symbol_in_arg
|
||||
util_parser ':blah "blah" "#{blah}" blah'
|
||||
|
||||
assert_equal 'blah', @parser.parse_symbol_in_arg
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal 'blah', @parser.parse_symbol_in_arg
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal nil, @parser.parse_symbol_in_arg
|
||||
|
||||
@parser.skip_tkspace
|
||||
|
||||
assert_equal nil, @parser.parse_symbol_in_arg
|
||||
end
|
||||
|
||||
def test_parse_top_level_statements_alias_method
|
||||
content = <<-CONTENT
|
||||
class A
|
||||
|
@ -1252,6 +1543,20 @@ end
|
|||
@parser.parse_statements @top_level
|
||||
end
|
||||
|
||||
def test_parse_yield_in_braces_with_parens
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
||||
|
||||
util_parser "def foo\nn.times { |i| yield nth(i) }\nend"
|
||||
|
||||
tk = @parser.get_tk
|
||||
|
||||
@parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
|
||||
|
||||
foo = klass.method_list.first
|
||||
assert_equal 'nth(i)', foo.block_params
|
||||
end
|
||||
|
||||
def test_sanity_integer
|
||||
util_parser '1'
|
||||
assert_equal '1', @parser.get_tk.text
|
||||
|
@ -1272,7 +1577,6 @@ end
|
|||
# If you're writing code like this you're doing it wrong
|
||||
|
||||
def test_sanity_interpolation_crazy
|
||||
last_tk = nil
|
||||
util_parser '"#{"#{"a")}" if b}"'
|
||||
|
||||
assert_equal '"#{"#{"a")}" if b}"', @parser.get_tk.text
|
||||
|
@ -1280,7 +1584,6 @@ end
|
|||
end
|
||||
|
||||
def test_sanity_interpolation_curly
|
||||
last_tk = nil
|
||||
util_parser '%{ #{} }'
|
||||
|
||||
assert_equal '%{ #{} }', @parser.get_tk.text
|
||||
|
@ -1290,13 +1593,39 @@ end
|
|||
def test_sanity_interpolation_format
|
||||
util_parser '"#{stftime("%m-%d")}"'
|
||||
|
||||
while tk = @parser.get_tk do end
|
||||
while @parser.get_tk do end
|
||||
end
|
||||
|
||||
def test_sanity_symbol_interpolation
|
||||
util_parser ':"#{bar}="'
|
||||
|
||||
while tk = @parser.get_tk do end
|
||||
while @parser.get_tk do end
|
||||
end
|
||||
|
||||
def test_stopdoc_after_comment
|
||||
|
||||
util_parser <<-EOS
|
||||
module Bar
|
||||
# hello
|
||||
module Foo
|
||||
# :stopdoc:
|
||||
end
|
||||
# there
|
||||
class Baz
|
||||
# :stopdoc:
|
||||
end
|
||||
end
|
||||
EOS
|
||||
|
||||
@parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
|
||||
|
||||
foo = @top_level.modules.first.modules.first
|
||||
assert_equal 'Foo', foo.name
|
||||
assert_equal 'hello', foo.comment
|
||||
|
||||
baz = @top_level.modules.first.classes.first
|
||||
assert_equal 'Baz', baz.name
|
||||
assert_equal 'there', baz.comment
|
||||
end
|
||||
|
||||
def tk(klass, line, char, name, text)
|
||||
|
|
|
@ -41,7 +41,6 @@ contents of a string.
|
|||
parser.scan
|
||||
|
||||
expected = <<-TEXT.strip
|
||||
|
||||
Regular expressions (<i>regexp</i>s) are patterns which describe the
|
||||
contents of a string.
|
||||
TEXT
|
||||
|
@ -49,6 +48,31 @@ contents of a string.
|
|||
assert_equal expected, @top_level.comment
|
||||
end
|
||||
|
||||
# RDoc stops processing comments if it finds a comment line CONTAINING
|
||||
# '<tt>#--</tt>'. This can be used to separate external from internal
|
||||
# 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 '<tt>#++</tt>'.
|
||||
#
|
||||
# I've seen guys that comment their code like this:
|
||||
# # This method....
|
||||
# #-----------------
|
||||
# def method
|
||||
#
|
||||
# => either we do it only in ruby code, or we require the leading #
|
||||
# (to avoid conflict with rules).
|
||||
#
|
||||
# TODO: require the leading #, to provide the feature in simple text files.
|
||||
# Note: in ruby & C code, we require '#--' & '#++' or '*--' & '*++',
|
||||
# to allow rules:
|
||||
#
|
||||
# # this is a comment
|
||||
# #---
|
||||
# # private text
|
||||
# #+++
|
||||
# # this is a rule:
|
||||
# # ---
|
||||
|
||||
def test_remove_private_comments
|
||||
parser = util_parser ''
|
||||
text = "foo\n\n--\nbar\n++\n\nbaz\n"
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
require 'tempfile'
|
||||
require 'tmpdir'
|
||||
require 'rubygems'
|
||||
require 'minitest/autorun'
|
||||
require 'rdoc/rdoc'
|
||||
|
||||
require 'fileutils'
|
||||
require 'tempfile'
|
||||
require 'tmpdir'
|
||||
|
||||
class TestRDocRDoc < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@rdoc = RDoc::RDoc.new
|
||||
@rdoc.options = RDoc::Options.new
|
||||
|
||||
@stats = RDoc::Stats.new 0, 0
|
||||
@rdoc.instance_variable_set :@stats, @stats
|
||||
|
||||
@tempfile = Tempfile.new 'test_rdoc_rdoc'
|
||||
@tempfile.binmode
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
@ -39,48 +45,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
|
|||
assert_empty files
|
||||
end
|
||||
|
||||
def test_read_file_contents
|
||||
@tempfile.write "hi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
assert_equal "hi everybody", @rdoc.read_file_contents(@tempfile.path)
|
||||
end
|
||||
|
||||
def test_read_file_contents_encoding
|
||||
skip "Encoding not implemented" unless defined? ::Encoding
|
||||
|
||||
@tempfile.write "# coding: utf-8\nhi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
contents = @rdoc.read_file_contents @tempfile.path
|
||||
assert_equal "# coding: utf-8\nhi everybody", contents
|
||||
assert_equal Encoding::UTF_8, contents.encoding
|
||||
end
|
||||
|
||||
def test_read_file_contents_encoding_fancy
|
||||
skip "Encoding not implemented" unless defined? ::Encoding
|
||||
|
||||
@tempfile.write "# -*- coding: utf-8; fill-column: 74 -*-\nhi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
contents = @rdoc.read_file_contents @tempfile.path
|
||||
assert_equal("# -*- coding: utf-8; fill-column: 74 -*-\nhi everybody",
|
||||
contents)
|
||||
assert_equal Encoding::UTF_8, contents.encoding
|
||||
end
|
||||
|
||||
def test_read_file_contents_encoding_with_signature
|
||||
skip "Encoding not implemented" unless defined? ::Encoding
|
||||
|
||||
@tempfile.write "\xEF\xBB\xBF""hi everybody"
|
||||
@tempfile.flush
|
||||
|
||||
bug3360 = '[ruby-dev:41452]'
|
||||
contents = @rdoc.read_file_contents @tempfile.path
|
||||
assert_equal "hi everybody", contents, bug3360
|
||||
assert_equal Encoding::UTF_8, contents.encoding, bug3360
|
||||
end
|
||||
|
||||
def test_remove_unparsable
|
||||
file_list = %w[
|
||||
blah.class
|
||||
|
@ -108,6 +72,20 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
|
|||
}
|
||||
end
|
||||
|
||||
def test_setup_output_dir_dry_run
|
||||
skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
|
||||
|
||||
@rdoc.options.dry_run = true
|
||||
|
||||
Dir.mktmpdir do |d|
|
||||
path = File.join d, 'testdir'
|
||||
|
||||
@rdoc.setup_output_dir path, false
|
||||
|
||||
refute File.exist? path
|
||||
end
|
||||
end
|
||||
|
||||
def test_setup_output_dir_exists
|
||||
skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
|
||||
|
||||
|
@ -161,5 +139,26 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_update_output_dir
|
||||
skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
|
||||
|
||||
Dir.mktmpdir do |d|
|
||||
@rdoc.update_output_dir d, Time.now, {}
|
||||
|
||||
assert File.exist? "#{d}/created.rid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_update_output_dir_dry_run
|
||||
skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
|
||||
|
||||
Dir.mktmpdir do |d|
|
||||
@rdoc.options.dry_run = true
|
||||
@rdoc.update_output_dir d, Time.now, {}
|
||||
|
||||
refute File.exist? "#{d}/created.rid"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_self_dump
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
RDoc::RI::Driver.dump @store.cache_path
|
||||
end
|
||||
|
||||
|
@ -83,8 +83,8 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
expected = @RM::Document.new(
|
||||
@RM::Rule.new(1),
|
||||
@RM::Paragraph.new('Also found in:'),
|
||||
@RM::Verbatim.new(' ', 'ruby core', "\n",
|
||||
' ', '~/.ri', "\n"))
|
||||
@RM::Verbatim.new("ruby core\n",
|
||||
"~/.ri\n"))
|
||||
|
||||
assert_equal expected, out
|
||||
end
|
||||
|
@ -143,7 +143,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
@RM::BlankLine.new,
|
||||
@RM::Paragraph.new("Include thingy"),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new(' ', 'Enumerable', "\n"))
|
||||
@RM::Verbatim.new("Enumerable\n"))
|
||||
|
||||
assert_equal expected, out
|
||||
end
|
||||
|
@ -163,8 +163,8 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
@RM::Rule.new(1),
|
||||
@RM::Heading.new(1, "Includes:"),
|
||||
@RM::Paragraph.new("(from #{@store.friendly_path})"),
|
||||
@RM::Verbatim.new(' ', 'Inc', "\n",
|
||||
' ', 'Enumerable', "\n"))
|
||||
@RM::Verbatim.new("Inc\n",
|
||||
"Enumerable\n"))
|
||||
|
||||
assert_equal expected, out
|
||||
end
|
||||
|
@ -195,7 +195,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
expected = @RM::Document.new(
|
||||
@RM::Heading.new(1, 'Class methods:'),
|
||||
@RM::BlankLine.new,
|
||||
@RM::Verbatim.new(' ', 'new'),
|
||||
@RM::Verbatim.new('new'),
|
||||
@RM::BlankLine.new)
|
||||
|
||||
assert_equal expected, out
|
||||
|
@ -285,7 +285,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
doc = @RM::Document.new(
|
||||
@RM::Paragraph.new('hi'))
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display doc
|
||||
end
|
||||
|
||||
|
@ -295,12 +295,12 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_class
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_class 'Foo::Bar'
|
||||
end
|
||||
|
||||
assert_match %r%^= Foo::Bar%, out
|
||||
assert_match %r%^\(from%, out # )
|
||||
assert_match %r%^\(from%, out
|
||||
|
||||
assert_match %r%^= Class methods:%, out
|
||||
assert_match %r%^ new%, out
|
||||
|
@ -315,7 +315,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_class_ambiguous
|
||||
util_multi_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_class 'Ambiguous'
|
||||
end
|
||||
|
||||
|
@ -325,7 +325,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_class_multi_no_doc
|
||||
util_multi_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_class 'Foo::Baz'
|
||||
end
|
||||
|
||||
|
@ -339,7 +339,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_class_superclass
|
||||
util_multi_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_class 'Bar'
|
||||
end
|
||||
|
||||
|
@ -349,7 +349,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_class_module
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_class 'Inc'
|
||||
end
|
||||
|
||||
|
@ -359,7 +359,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_method
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_method 'Foo::Bar#blah'
|
||||
end
|
||||
|
||||
|
@ -371,7 +371,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_method_attribute
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_method 'Foo::Bar#attr'
|
||||
end
|
||||
|
||||
|
@ -382,7 +382,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_method_inherited
|
||||
util_multi_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_method 'Bar#inherit'
|
||||
end
|
||||
|
||||
|
@ -393,7 +393,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
|
|||
def test_display_name_not_found_class
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
assert_equal false, @driver.display_name('Foo::B')
|
||||
end
|
||||
|
||||
|
@ -410,7 +410,7 @@ Foo::Baz
|
|||
def test_display_name_not_found_method
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
assert_equal false, @driver.display_name('Foo::Bar#b')
|
||||
end
|
||||
|
||||
|
@ -427,7 +427,7 @@ Foo::Bar#bother
|
|||
def test_display_method_params
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
out, = capture_io do
|
||||
@driver.display_method 'Foo::Bar#bother'
|
||||
end
|
||||
|
||||
|
@ -496,24 +496,34 @@ Foo::Bar#bother
|
|||
end
|
||||
|
||||
def test_formatter
|
||||
tty = Object.new
|
||||
def tty.tty?() true; end
|
||||
|
||||
driver = RDoc::RI::Driver.new
|
||||
|
||||
io = Object.new
|
||||
def io.tty?; false; end
|
||||
assert_instance_of @RM::ToAnsi, driver.formatter(tty)
|
||||
|
||||
assert_instance_of @RM::ToBs, driver.formatter(io)
|
||||
|
||||
def io.tty?; true; end
|
||||
|
||||
assert_instance_of @RM::ToAnsi, driver.formatter(io)
|
||||
assert_instance_of @RM::ToBs, driver.formatter(StringIO.new)
|
||||
|
||||
driver.instance_variable_set :@paging, true
|
||||
|
||||
assert_instance_of @RM::ToBs, driver.formatter(io)
|
||||
assert_instance_of @RM::ToBs, driver.formatter(StringIO.new)
|
||||
|
||||
driver.instance_variable_set :@formatter_klass, @RM::ToHtml
|
||||
|
||||
assert_instance_of @RM::ToHtml, driver.formatter(io)
|
||||
assert_instance_of @RM::ToHtml, driver.formatter(tty)
|
||||
end
|
||||
|
||||
def test_in_path_eh
|
||||
path = ENV['PATH']
|
||||
|
||||
refute @driver.in_path?('/nonexistent')
|
||||
|
||||
ENV['PATH'] = File.expand_path '..', __FILE__
|
||||
|
||||
assert @driver.in_path?(File.basename(__FILE__))
|
||||
ensure
|
||||
ENV['PATH'] = path
|
||||
end
|
||||
|
||||
def test_method_type
|
||||
|
@ -526,8 +536,8 @@ Foo::Bar#bother
|
|||
def test_list_known_classes
|
||||
util_store
|
||||
|
||||
out, err = capture_io do
|
||||
@driver.list_known_classes
|
||||
out, = capture_io do
|
||||
@driver.list_known_classes
|
||||
end
|
||||
|
||||
assert_equal "Ambiguous\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче