mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 01:23:57 +02:00
* lib/rdoc: Update to 3.9.1. Fixes === lines in verbatim sections.
Fixes :nodoc: on class aliases. Fixes :stopdoc: creating references to Object. Fixes spacing when class comments are merged in ri. Fixes `ri []` crash. Fixes bug report URL when rdoc crashes. Adds :doc: and :nodoc: to allow hiding of implementation details in ruby. Makes `rdoc` and `ri` gem-aware. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@32803 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e2c24e1616
commit
8e627bc1f7
33 changed files with 1058 additions and 603 deletions
|
@ -222,6 +222,9 @@ class RDoc::ClassModule < RDoc::Context
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# TODO: filter included items by #display?
|
||||
|
||||
def marshal_dump # :nodoc:
|
||||
attrs = attributes.sort.map do |attr|
|
||||
[ attr.name, attr.rw,
|
||||
|
|
|
@ -114,6 +114,7 @@ class RDoc::CodeObject
|
|||
@done_documenting = false
|
||||
@force_documentation = false
|
||||
@received_nodoc = false
|
||||
@ignored = false
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -139,6 +140,13 @@ class RDoc::CodeObject
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Should this CodeObject be shown in documentation?
|
||||
|
||||
def display?
|
||||
@document_self and not @ignored
|
||||
end
|
||||
|
||||
##
|
||||
# Enables or disables documentation of this CodeObject's children unless it
|
||||
# has been turned off by :enddoc:
|
||||
|
@ -195,6 +203,11 @@ class RDoc::CodeObject
|
|||
self
|
||||
end
|
||||
|
||||
##
|
||||
# File name where this CodeObject was found.
|
||||
#
|
||||
# See also RDoc::Context#in_files
|
||||
|
||||
def file_name
|
||||
return unless @file
|
||||
|
||||
|
@ -220,6 +233,34 @@ class RDoc::CodeObject
|
|||
@full_name = full_name
|
||||
end
|
||||
|
||||
##
|
||||
# Use this to ignore a CodeObject and all its children until found again
|
||||
# (#record_location is called). An ignored item will not be shown in
|
||||
# documentation.
|
||||
#
|
||||
# See github issue #55
|
||||
#
|
||||
# The ignored status is temporary in order to allow implementation details
|
||||
# to be hidden. At the end of processing a file RDoc allows all classes
|
||||
# and modules to add new documentation to previously created classes.
|
||||
#
|
||||
# If a class was ignored (via stopdoc) then reopened later with additional
|
||||
# documentation it should be shown. If a class was ignored and never
|
||||
# reopened it should not be shown. The ignore flag allows this to occur.
|
||||
|
||||
def ignore
|
||||
@ignored = true
|
||||
|
||||
stop_doc
|
||||
end
|
||||
|
||||
##
|
||||
# Has this class been ignored?
|
||||
|
||||
def ignored?
|
||||
@ignored
|
||||
end
|
||||
|
||||
##
|
||||
# File name of our parent
|
||||
|
||||
|
@ -238,6 +279,7 @@ class RDoc::CodeObject
|
|||
# Records the RDoc::TopLevel (file) where this code object was defined
|
||||
|
||||
def record_location top_level
|
||||
@ignored = false
|
||||
@file = top_level
|
||||
end
|
||||
|
||||
|
@ -250,6 +292,7 @@ class RDoc::CodeObject
|
|||
|
||||
@document_self = true
|
||||
@document_children = true
|
||||
@ignored = false
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -423,6 +423,7 @@ class RDoc::Context < RDoc::CodeObject
|
|||
if klass then
|
||||
# if TopLevel, it may not be registered in the classes:
|
||||
enclosing.classes_hash[name] = klass
|
||||
|
||||
# update the superclass if needed
|
||||
if superclass then
|
||||
existing = klass.superclass
|
||||
|
@ -623,8 +624,10 @@ class RDoc::Context < RDoc::CodeObject
|
|||
|
||||
##
|
||||
# Is there any content?
|
||||
# This means any of: comment, aliases, methods, attributes,
|
||||
# external aliases, require, constant.
|
||||
#
|
||||
# This means any of: comment, aliases, methods, attributes, external
|
||||
# aliases, require, constant.
|
||||
#
|
||||
# Includes are also checked unless <tt>includes == false</tt>.
|
||||
|
||||
def any_content(includes = true)
|
||||
|
|
|
@ -192,7 +192,7 @@ class RDoc::Generator::Darkfish
|
|||
top_level = klass.full_name.gsub( /::.*/, '' )
|
||||
[nscounts[top_level] * -1, klass.full_name]
|
||||
end.select do |klass|
|
||||
klass.document_self
|
||||
klass.display?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -176,6 +176,8 @@
|
|||
</div><!-- description -->
|
||||
|
||||
<% klass.each_section do |section, constants, attributes| %>
|
||||
<% constants = constants.select { |const| const.display? } %>
|
||||
<% attributes = attributes.select { |attr| attr.display? } %>
|
||||
<div id="<%= section.aref %>" class="documentation-section">
|
||||
<% if section.title then %>
|
||||
<h2 class="section-header">
|
||||
|
|
|
@ -269,40 +269,43 @@ require 'rdoc'
|
|||
# preceding the first character with a backslash (see <i>Escaping
|
||||
# Text Markup</i>, below).
|
||||
#
|
||||
# === Hyperlinks
|
||||
# === Links
|
||||
#
|
||||
# Hyperlinks to the web starting with +http:+, +mailto:+, +ftp:+ or +www.+
|
||||
# Links to starting with +http:+, +https:+, +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.
|
||||
# converted into an inline image element.
|
||||
#
|
||||
# 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].
|
||||
# Links starting with <tt>rdoc-ref:</tt> will link to the referenced class,
|
||||
# module, method, file, etc. If the referenced item is not documented the
|
||||
# text will be and no link will be generated.
|
||||
#
|
||||
# Example hyperlinks:
|
||||
# Links starting with +link:+ refer to local files whose path is relative to
|
||||
# the <tt>--op</tt> directory.
|
||||
#
|
||||
# link:RDoc.html
|
||||
# http://rdoc.rubyforge.org
|
||||
# Links can also be of the form <tt>label[url]</tt>, 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: <tt>{multi word label}[url]<tt>.
|
||||
#
|
||||
# Example links:
|
||||
#
|
||||
# https://github.com/rdoc/rdoc
|
||||
# mailto:user@example.com
|
||||
# {RDoc Documentation}[http://rdoc.rubyforge.org]
|
||||
# {RDoc Markup}[link:RDoc/Markup.html]
|
||||
# {RDoc Markup}[rdoc-ref:RDoc::Markup]
|
||||
#
|
||||
# === 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
|
||||
# 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:
|
||||
# is used to escape potential links:
|
||||
#
|
||||
# * 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
|
||||
# * This will not be linked to \RDoc::RDoc#document
|
||||
#
|
||||
# generates:
|
||||
#
|
||||
|
@ -310,16 +313,16 @@ require 'rdoc'
|
|||
# * 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
|
||||
# * This will not be linked 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.
|
||||
# Inside \<tt> tags, more precisely, leading backslashes are removed only if
|
||||
# followed by a markup character (<tt><*_+</tt>), a backslash, or a known link
|
||||
# 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.
|
||||
# This behavior is inherited from RDoc version 1, and has been kept for
|
||||
# compatibility with existing RDoc documentation.
|
||||
#
|
||||
# === Conversion of characters
|
||||
#
|
||||
|
@ -378,11 +381,10 @@ require 'rdoc'
|
|||
# # ...
|
||||
# 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).
|
||||
# Names of classes, files, and any method names containing an underscore or
|
||||
# preceded by a hash character are automatically linked from comment text to
|
||||
# their description. This linking 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
|
||||
|
|
|
@ -71,9 +71,7 @@ class RDoc::Markup::Document
|
|||
# Does this document have no parts?
|
||||
|
||||
def empty?
|
||||
@parts.empty? or
|
||||
(@parts.length == 1 and RDoc::Markup::Document === @parts.first and
|
||||
@parts.first.empty?)
|
||||
@parts.empty? or (@parts.length == 1 and merged? and @parts.first.empty?)
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -85,6 +83,11 @@ class RDoc::Markup::Document
|
|||
# The information in +other+ is preferred over the receiver
|
||||
|
||||
def merge other
|
||||
if empty? then
|
||||
@parts = other.parts
|
||||
return self
|
||||
end
|
||||
|
||||
other.parts.each do |other_part|
|
||||
self.parts.delete_if do |self_part|
|
||||
self_part.file and self_part.file == other_part.file
|
||||
|
@ -96,6 +99,13 @@ class RDoc::Markup::Document
|
|||
self
|
||||
end
|
||||
|
||||
##
|
||||
# Does this Document contain other Documents?
|
||||
|
||||
def merged?
|
||||
RDoc::Markup::Document === @parts.first
|
||||
end
|
||||
|
||||
def pretty_print q # :nodoc:
|
||||
start = @file ? "[doc (#{@file}): " : '[doc: '
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ require 'rdoc/markup'
|
|||
# Base class for RDoc markup formatters
|
||||
#
|
||||
# Formatters use a visitor pattern to convert content into output.
|
||||
#
|
||||
# If you'd like to write your own Formatter use
|
||||
# RDoc::Markup::FormatterTestCase. If you're writing a text-output formatter
|
||||
# use RDoc::Markup::TextFormatterTestCase which provides extra test cases.
|
||||
|
||||
class RDoc::Markup::Formatter
|
||||
|
||||
|
|
|
@ -86,11 +86,18 @@ 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
|
||||
type, text, = get
|
||||
|
||||
heading
|
||||
text = case type
|
||||
when :TEXT then
|
||||
skip :NEWLINE
|
||||
text
|
||||
else
|
||||
unget
|
||||
''
|
||||
end
|
||||
|
||||
RDoc::Markup::Heading.new level, text
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -405,13 +412,19 @@ class RDoc::Markup::Parser
|
|||
@line += 1
|
||||
token
|
||||
# === text => :HEADER then :TEXT
|
||||
when s.scan(/(=+)\s*/) then
|
||||
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.sub(/\r$/, ''), *token_pos(pos)]
|
||||
header = [:HEADER, level, *token_pos(pos)]
|
||||
|
||||
if s[2] =~ /^\r?\n/ then
|
||||
s.pos -= s[2].length
|
||||
header
|
||||
else
|
||||
pos = s.pos
|
||||
s.scan(/.*/)
|
||||
@tokens << header
|
||||
[:TEXT, s.matched.sub(/\r$/, ''), *token_pos(pos)]
|
||||
end
|
||||
# --- (at least 3) and nothing else on the line => :RULE
|
||||
when s.scan(/(-{3,}) *$/) then
|
||||
[:RULE, s[1].length - 2, *token_pos(pos)]
|
||||
|
|
|
@ -13,6 +13,8 @@ require 'rdoc/encoding'
|
|||
|
||||
class RDoc::Markup::PreProcess
|
||||
|
||||
attr_accessor :options
|
||||
|
||||
@registered = {}
|
||||
|
||||
##
|
||||
|
@ -38,6 +40,7 @@ class RDoc::Markup::PreProcess
|
|||
def initialize(input_file_name, include_path)
|
||||
@input_file_name = input_file_name
|
||||
@include_path = include_path
|
||||
@options = nil
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -54,56 +57,122 @@ class RDoc::Markup::PreProcess
|
|||
# If +code_object+ is given and the param is set as metadata on the
|
||||
# +code_object+. See RDoc::CodeObject#metadata
|
||||
|
||||
def handle text, code_object = nil
|
||||
def handle text, code_object = nil, &block
|
||||
encoding = if defined?(Encoding) then text.encoding else nil end
|
||||
# regexp helper (square brackets for optional)
|
||||
# $1 $2 $3 $4 $5
|
||||
# [prefix][\]:directive:[spaces][param]newline
|
||||
text.gsub!(/^([ \t]*#?[ \t]*)(\\?):(\w+):([ \t]*)(.+)?\n/) do
|
||||
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 = $3.downcase
|
||||
param = $5
|
||||
|
||||
case directive
|
||||
when 'include' then
|
||||
filename = param.split[0]
|
||||
encoding = if defined?(Encoding) then text.encoding else nil end
|
||||
include_file filename, prefix, encoding
|
||||
when 'category' then
|
||||
if RDoc::Context === code_object then
|
||||
section = code_object.add_section param, ''
|
||||
code_object.temporary_section = section
|
||||
end
|
||||
|
||||
'' # ignore category if we're not on an RDoc::Context
|
||||
else
|
||||
result = yield directive, param if block_given?
|
||||
|
||||
case result
|
||||
when nil then
|
||||
code_object.metadata[directive] = param if code_object
|
||||
if RDoc::Markup::PreProcess.registered.include? directive then
|
||||
handler = RDoc::Markup::PreProcess.registered[directive]
|
||||
result = handler.call directive, param if handler
|
||||
else
|
||||
result = "#{prefix}:#{directive}: #{param}\n"
|
||||
end
|
||||
when false then
|
||||
result = "#{prefix}:#{directive}: #{param}\n"
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
handle_directive $1, $3, $5, code_object, encoding, &block
|
||||
end
|
||||
|
||||
text
|
||||
end
|
||||
|
||||
#--
|
||||
# When 1.8.7 support is ditched prefix can be defaulted to ''
|
||||
|
||||
def handle_directive prefix, directive, param, code_object = nil,
|
||||
encoding = nil
|
||||
blankline = "#{prefix.strip}\n"
|
||||
directive = directive.downcase
|
||||
|
||||
case directive
|
||||
when 'arg', 'args' then
|
||||
return blankline unless code_object
|
||||
|
||||
code_object.params = param
|
||||
|
||||
blankline
|
||||
when 'category' then
|
||||
if RDoc::Context === code_object then
|
||||
section = code_object.add_section param, ''
|
||||
code_object.temporary_section = section
|
||||
end
|
||||
|
||||
blankline # ignore category if we're not on an RDoc::Context
|
||||
when 'doc' then
|
||||
return blankline unless code_object
|
||||
code_object.document_self = true
|
||||
code_object.force_documentation = true
|
||||
|
||||
blankline
|
||||
when 'enddoc' then
|
||||
return blankline unless code_object
|
||||
code_object.done_documenting = true
|
||||
|
||||
blankline
|
||||
when 'include' then
|
||||
filename = param.split.first
|
||||
include_file filename, prefix, encoding
|
||||
when 'main' then
|
||||
@options.main_page = param if @options.respond_to? :main_page
|
||||
|
||||
blankline
|
||||
when 'nodoc' then
|
||||
return blankline unless code_object
|
||||
code_object.document_self = nil # notify nodoc
|
||||
code_object.document_children = param !~ /all/i
|
||||
|
||||
blankline
|
||||
when 'notnew', 'not_new', 'not-new' then
|
||||
return blankline unless RDoc::AnyMethod === code_object
|
||||
|
||||
code_object.dont_rename_initialize = true
|
||||
|
||||
blankline
|
||||
when 'startdoc' then
|
||||
return blankline unless code_object
|
||||
|
||||
code_object.start_doc
|
||||
code_object.force_documentation = true
|
||||
|
||||
blankline
|
||||
when 'stopdoc' then
|
||||
return blankline unless code_object
|
||||
|
||||
code_object.stop_doc
|
||||
|
||||
blankline
|
||||
when 'title' then
|
||||
@options.default_title = param if @options.respond_to? :default_title=
|
||||
|
||||
blankline
|
||||
when 'yield', 'yields' then
|
||||
return blankline unless code_object
|
||||
# remove parameter &block
|
||||
code_object.params.sub!(/,?\s*&\w+/, '') if code_object.params
|
||||
|
||||
code_object.block_params = param
|
||||
|
||||
blankline
|
||||
else
|
||||
result = yield directive, param if block_given?
|
||||
|
||||
case result
|
||||
when nil then
|
||||
code_object.metadata[directive] = param if code_object
|
||||
|
||||
if RDoc::Markup::PreProcess.registered.include? directive then
|
||||
handler = RDoc::Markup::PreProcess.registered[directive]
|
||||
result = handler.call directive, param if handler
|
||||
else
|
||||
result = "#{prefix}:#{directive}: #{param}\n"
|
||||
end
|
||||
when false then
|
||||
result = "#{prefix}:#{directive}: #{param}\n"
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Handles the <tt>:include: _filename_</tt> directive.
|
||||
#
|
||||
|
|
|
@ -70,7 +70,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
@list = nil
|
||||
@from_path = ''
|
||||
|
||||
# external hyperlinks
|
||||
# external links
|
||||
@markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK)
|
||||
|
||||
# and links of the form <text>[<url>]
|
||||
|
@ -84,7 +84,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
# These methods handle special markup added by RDoc::Markup#add_special.
|
||||
|
||||
##
|
||||
# +special+ is a potential hyperlink. The following schemes are handled:
|
||||
# +special+ is a potential link. The following schemes are handled:
|
||||
#
|
||||
# <tt>mailto:</tt>::
|
||||
# Inserted as-is.
|
||||
|
@ -97,12 +97,13 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
|
||||
def handle_special_HYPERLINK(special)
|
||||
url = special.text
|
||||
|
||||
gen_url url, url
|
||||
end
|
||||
|
||||
##
|
||||
# This +special+ is a hyperlink where the label is different from the URL
|
||||
# label[url] or {long label}[url]
|
||||
# This +special+ is a link where the label is different from the URL
|
||||
# <tt>label[url]</tt> or <tt>{long label}[url]</tt>
|
||||
|
||||
def handle_special_TIDYLINK(special)
|
||||
text = special.text
|
||||
|
@ -232,8 +233,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
|
|||
end
|
||||
|
||||
##
|
||||
# Generate a hyperlink for +url+, labeled with +text+. Handles the special
|
||||
# cases for img: and link: described under handle_special_HYPERLINK
|
||||
# Generate a link for +url+, labeled with +text+. Handles the special cases
|
||||
# for img: and link: described under handle_special_HYPERLINK
|
||||
|
||||
def gen_url(url, text)
|
||||
if url =~ /([A-Za-z]+):(.*)/ then
|
||||
|
|
|
@ -1,92 +1,19 @@
|
|||
require 'rdoc/markup/to_html'
|
||||
require 'rdoc/cross_reference'
|
||||
|
||||
##
|
||||
# Subclass of the RDoc::Markup::ToHtml class that supports looking up words
|
||||
# from a context. Those that are found will be hyperlinked.
|
||||
# Subclass of the RDoc::Markup::ToHtml class that supports looking up method
|
||||
# names, classes, etc to create links. RDoc::CrossReference is used to
|
||||
# generate those links based on the current context.
|
||||
|
||||
class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
||||
|
||||
##
|
||||
# Regular expression to match class references
|
||||
#
|
||||
# 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 (not recommended)
|
||||
|
||||
CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)'
|
||||
|
||||
##
|
||||
# Regular expression to match method references.
|
||||
#
|
||||
# See CLASS_REGEXP_STR
|
||||
|
||||
METHOD_REGEXP_STR = '([a-z]\w*[!?=]?)(?:\([\w.+*/=<>-]*\))?'
|
||||
|
||||
##
|
||||
# Regular expressions matching text that should potentially have
|
||||
# cross-reference links generated are passed to add_special. Note that
|
||||
# these expressions are meant to pick up text for which cross-references
|
||||
# have been suppressed, since the suppression characters are removed by the
|
||||
# code that is triggered.
|
||||
|
||||
CROSSREF_REGEXP = /(
|
||||
# A::B::C.meth
|
||||
#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}
|
||||
|
||||
# Stand-alone method (preceded by a #)
|
||||
| \\?\##{METHOD_REGEXP_STR}
|
||||
|
||||
# Stand-alone method (preceded by ::)
|
||||
| ::#{METHOD_REGEXP_STR}
|
||||
|
||||
# A::B::C
|
||||
# The stuff after CLASS_REGEXP_STR is a
|
||||
# nasty hack. CLASS_REGEXP_STR unfortunately matches
|
||||
# words like dog and cat (these are legal "class"
|
||||
# names in Fortran 95). When a word is flagged as a
|
||||
# potential cross-reference, limitations in the markup
|
||||
# engine suppress other processing, such as typesetting.
|
||||
# This is particularly noticeable for contractions.
|
||||
# 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-reference 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
|
||||
# one special character (period, slash, or
|
||||
# underscore).
|
||||
| (?:\.\.\/)*[-\/\w]+[_\/\.][-\w\/\.]+
|
||||
|
||||
# Things that have markup suppressed
|
||||
# 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
|
||||
# :stopdoc:
|
||||
ALL_CROSSREF_REGEXP = RDoc::CrossReference::ALL_CROSSREF_REGEXP
|
||||
CLASS_REGEXP_STR = RDoc::CrossReference::CLASS_REGEXP_STR
|
||||
CROSSREF_REGEXP = RDoc::CrossReference::CROSSREF_REGEXP
|
||||
METHOD_REGEXP_STR = RDoc::CrossReference::METHOD_REGEXP_STR
|
||||
# :startdoc:
|
||||
|
||||
##
|
||||
# RDoc::CodeObject for generating references
|
||||
|
@ -102,7 +29,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
# 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. Only method names
|
||||
# preceded by '#' or '::' are hyperlinked, unless +hyperlink_all+ is true.
|
||||
# preceded by '#' or '::' are linked, unless +hyperlink_all+ is true.
|
||||
|
||||
def initialize(from_path, context, show_hash, hyperlink_all = false,
|
||||
markup = nil)
|
||||
|
@ -111,22 +38,36 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
|
||||
crossref_re = hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
|
||||
|
||||
@cross_reference = RDoc::CrossReference.new context
|
||||
|
||||
@markup.add_special crossref_re, :CROSSREF
|
||||
@markup.add_special(/rdoc-ref:\S+\w/, :HYPERLINK)
|
||||
|
||||
@from_path = from_path
|
||||
@context = context
|
||||
@show_hash = show_hash
|
||||
@from_path = from_path
|
||||
@hyperlink_all = hyperlink_all
|
||||
@show_hash = show_hash
|
||||
end
|
||||
|
||||
@seen = {}
|
||||
##
|
||||
# Creates a link to the reference +name+ if the name exists. If +text+ is
|
||||
# given it is used as the link text, otherwise +name+ is used.
|
||||
|
||||
def cross_reference name, text = nil
|
||||
lookup = name
|
||||
|
||||
name = name[1..-1] unless @show_hash if name[0, 1] == '#'
|
||||
|
||||
text = name unless text
|
||||
|
||||
link lookup, text
|
||||
end
|
||||
|
||||
##
|
||||
# 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, ToHtml is found, even without the <tt>RDoc::Markup::</tt>
|
||||
# prefix, because we look for it in module Markup first.
|
||||
# corresponding reference, generate a link. If the name we're looking for
|
||||
# contains no punctuation, we look for it up the module/class chain. 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
|
||||
|
@ -138,66 +79,41 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
|
|||
return name if name =~ /\A[a-z]*\z/
|
||||
end
|
||||
|
||||
return @seen[name] if @seen.include? name
|
||||
cross_reference name
|
||||
end
|
||||
|
||||
lookup = name
|
||||
##
|
||||
# Handles <tt>rdoc-ref:</tt> scheme links and allows RDoc::Markup::ToHtml to
|
||||
# handle other schemes.
|
||||
|
||||
name = name[1..-1] unless @show_hash if name[0, 1] == '#'
|
||||
def handle_special_HYPERLINK special
|
||||
return cross_reference $' if special.text =~ /\Ardoc-ref:/
|
||||
|
||||
# Find class, module, or method in class or module.
|
||||
#
|
||||
# Do not, however, use an if/elsif/else chain to do so. Instead, test
|
||||
# each possible pattern until one matches. The reason for this is that a
|
||||
# string like "YAML.txt" could be the txt() class method of class YAML (in
|
||||
# which case it would match the first pattern, which splits the string
|
||||
# into container and method components and looks up both) or a filename
|
||||
# (in which case it would match the last pattern, which just checks
|
||||
# whether the string as a whole is a known symbol).
|
||||
super
|
||||
end
|
||||
|
||||
if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/ =~ lookup then
|
||||
type = $2
|
||||
type = '' if type == '.' # will find either #method or ::method
|
||||
method = "#{type}#{$3}"
|
||||
container = @context.find_symbol_module($1)
|
||||
elsif /^([.#]|::)#{METHOD_REGEXP_STR}/ =~ lookup then
|
||||
type = $1
|
||||
type = '' if type == '.'
|
||||
method = "#{type}#{$2}"
|
||||
container = @context
|
||||
##
|
||||
# Generates links for <tt>rdoc-ref:</tt> scheme URLs and allows
|
||||
# RDoc::Markup::ToHtml to handle other schemes.
|
||||
|
||||
def gen_url url, text
|
||||
return super unless url =~ /\Ardoc-ref:/
|
||||
|
||||
cross_reference $', text
|
||||
end
|
||||
|
||||
##
|
||||
# Creates an HTML link to +name+ with the given +text+.
|
||||
|
||||
def link name, text
|
||||
ref = @cross_reference.resolve name, text
|
||||
|
||||
case ref
|
||||
when String then
|
||||
ref
|
||||
else
|
||||
container = nil
|
||||
"<a href=\"#{ref.as_href @from_path}\">#{text}</a>"
|
||||
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
|
||||
# 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
|
||||
lookup
|
||||
end
|
||||
|
||||
@seen[lookup] = out
|
||||
|
||||
out
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -106,6 +106,8 @@ class RDoc::Parser
|
|||
# Applies +directive+'s +value+ to +code_object+, if appropriate
|
||||
|
||||
def self.process_directive code_object, directive, value
|
||||
warn "RDoc::Parser::process_directive is deprecated and wil be removed in RDoc 4. Use RDoc::Markup::PreProcess#handle_directive instead" if $-w
|
||||
|
||||
case directive
|
||||
when 'nodoc' then
|
||||
code_object.document_self = nil # notify nodoc
|
||||
|
@ -196,6 +198,9 @@ class RDoc::Parser
|
|||
@content = content
|
||||
@options = options
|
||||
@stats = stats
|
||||
|
||||
@preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
@preprocess.options = @options
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -645,9 +645,7 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
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
|
||||
look_for_directives_in meth_obj, comment
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -913,12 +911,10 @@ class RDoc::Parser::C < RDoc::Parser
|
|||
# * :title: My Awesome Project
|
||||
# */
|
||||
#
|
||||
# This routine modifies its parameter
|
||||
# This method modifies the +comment+
|
||||
|
||||
def look_for_directives_in(context, comment)
|
||||
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
|
||||
preprocess.handle comment, context do |directive, param|
|
||||
def look_for_directives_in context, comment
|
||||
@preprocess.handle comment, context do |directive, param|
|
||||
case directive
|
||||
when 'main' then
|
||||
@options.main_page = param
|
||||
|
|
|
@ -405,17 +405,9 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
#
|
||||
# This routine modifies its +comment+ parameter.
|
||||
|
||||
def look_for_directives_in(context, comment)
|
||||
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
|
||||
preprocess.handle comment, context do |directive, param|
|
||||
def look_for_directives_in context, comment
|
||||
@preprocess.handle comment, context do |directive, param|
|
||||
case directive
|
||||
when 'enddoc' then
|
||||
context.done_documenting = true
|
||||
''
|
||||
when 'main' then
|
||||
@options.main_page = param if @options.respond_to? :main_page
|
||||
''
|
||||
when 'method', 'singleton-method',
|
||||
'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
|
||||
false # handled elsewhere
|
||||
|
@ -423,16 +415,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
context.set_current_section param, comment
|
||||
comment.replace ''
|
||||
break
|
||||
when 'startdoc' then
|
||||
context.start_doc
|
||||
context.force_documentation = true
|
||||
''
|
||||
when 'stopdoc' then
|
||||
context.stop_doc
|
||||
''
|
||||
when 'title' then
|
||||
@options.default_title = param if @options.respond_to? :default_title=
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -629,6 +611,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
|
||||
cls_type = single == SINGLE ? RDoc::SingleClass : RDoc::NormalClass
|
||||
cls = declaration_context.add_class cls_type, given_name, superclass
|
||||
cls.ignore unless container.document_children
|
||||
|
||||
read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
|
||||
cls.record_location @top_level
|
||||
|
@ -679,7 +662,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
##
|
||||
# Parses a constant in +context+ with +comment+
|
||||
|
||||
def parse_constant(container, tk, comment)
|
||||
def parse_constant container, tk, comment
|
||||
offset = tk.seek
|
||||
line_no = tk.line_no
|
||||
|
||||
|
@ -718,7 +701,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then
|
||||
nest -= 1
|
||||
when TkCOMMENT then
|
||||
if nest <= 0 && @scanner.lex_state == EXPR_END
|
||||
if nest <= 0 &&
|
||||
(@scanner.lex_state == EXPR_END || !@scanner.continue) then
|
||||
unget_tk tk
|
||||
break
|
||||
end
|
||||
|
@ -733,7 +717,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
end
|
||||
|
||||
container.add_module_alias mod, name, @top_level if mod
|
||||
get_tk # TkNL
|
||||
break
|
||||
end
|
||||
when TkNL then
|
||||
|
@ -1327,11 +1310,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
keep_comment = true
|
||||
|
||||
when TkCLASS then
|
||||
if container.document_children then
|
||||
parse_class container, single, tk, comment
|
||||
else
|
||||
nest += 1
|
||||
end
|
||||
parse_class container, single, tk, comment
|
||||
|
||||
when TkMODULE then
|
||||
if container.document_children then
|
||||
|
@ -1516,11 +1495,13 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
##
|
||||
# Parses statements in the top-level +container+
|
||||
|
||||
def parse_top_level_statements(container)
|
||||
def parse_top_level_statements container
|
||||
comment = collect_first_comment
|
||||
look_for_directives_in(container, comment)
|
||||
look_for_directives_in container, comment
|
||||
|
||||
# HACK move if to RDoc::Context#comment=
|
||||
container.comment = comment if container.document_self unless comment.empty?
|
||||
|
||||
parse_statements container, NORMAL, nil, comment
|
||||
end
|
||||
|
||||
|
@ -1643,16 +1624,17 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|||
# 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)
|
||||
def read_documentation_modifiers context, allow
|
||||
directive, value = read_directive allow
|
||||
|
||||
return unless directive
|
||||
|
||||
case directive
|
||||
when 'notnew', 'not_new', 'not-new' then
|
||||
context.dont_rename_initialize = true
|
||||
else
|
||||
RDoc::Parser.process_directive context, directive, value
|
||||
@preprocess.handle_directive '', directive, value, context do |dir, param|
|
||||
if %w[notnew not_new not-new].include? dir then
|
||||
context.dont_rename_initialize = true
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -153,6 +153,8 @@ module RDoc::Parser::RubyTools
|
|||
@token_listeners.each do |obj|
|
||||
obj.pop_token
|
||||
end if @token_listeners
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -387,6 +387,8 @@ Options may also be set in the 'RI' environment variable.
|
|||
klass.superclass unless klass.module?
|
||||
end.compact.shift || 'Object'
|
||||
|
||||
superclass = superclass.full_name unless String === superclass
|
||||
|
||||
"#{name} < #{superclass}"
|
||||
end
|
||||
|
||||
|
@ -451,7 +453,7 @@ Options may also be set in the 'RI' environment variable.
|
|||
# Adds a list of +methods+ to +out+ with a heading of +name+
|
||||
|
||||
def add_method_list out, methods, name
|
||||
return unless methods
|
||||
return if methods.empty?
|
||||
|
||||
out << RDoc::Markup::Heading.new(1, "#{name}:")
|
||||
out << RDoc::Markup::BlankLine.new
|
||||
|
@ -518,11 +520,13 @@ Options may also be set in the 'RI' environment variable.
|
|||
|
||||
found.each do |store, klass|
|
||||
comment = klass.comment
|
||||
class_methods = store.class_methods[klass.full_name]
|
||||
instance_methods = store.instance_methods[klass.full_name]
|
||||
attributes = store.attributes[klass.full_name]
|
||||
# TODO the store's cache should always return an empty Array
|
||||
class_methods = store.class_methods[klass.full_name] || []
|
||||
instance_methods = store.instance_methods[klass.full_name] || []
|
||||
attributes = store.attributes[klass.full_name] || []
|
||||
|
||||
if comment.empty? and !(instance_methods or class_methods) then
|
||||
if comment.empty? and
|
||||
instance_methods.empty? and class_methods.empty? then
|
||||
also_in << store
|
||||
next
|
||||
end
|
||||
|
@ -531,7 +535,17 @@ Options may also be set in the 'RI' environment variable.
|
|||
|
||||
unless comment.empty? then
|
||||
out << RDoc::Markup::Rule.new(1)
|
||||
out << comment
|
||||
|
||||
if comment.merged? then
|
||||
parts = comment.parts
|
||||
parts = parts.zip [RDoc::Markup::BlankLine.new] * parts.length
|
||||
parts.flatten!
|
||||
parts.pop
|
||||
|
||||
out.push(*parts)
|
||||
else
|
||||
out << comment
|
||||
end
|
||||
end
|
||||
|
||||
if class_methods or instance_methods or not klass.constants.empty? then
|
||||
|
@ -554,13 +568,12 @@ Options may also be set in the 'RI' environment variable.
|
|||
end)
|
||||
|
||||
out << list
|
||||
out << RDoc::Markup::BlankLine.new
|
||||
end
|
||||
|
||||
add_method_list out, class_methods, 'Class methods'
|
||||
add_method_list out, instance_methods, 'Instance methods'
|
||||
add_method_list out, attributes, 'Attributes'
|
||||
|
||||
out << RDoc::Markup::BlankLine.new
|
||||
end
|
||||
|
||||
add_also_in out, also_in
|
||||
|
@ -1090,11 +1103,11 @@ Options may also be set in the 'RI' environment variable.
|
|||
# NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
|
||||
# method
|
||||
|
||||
def parse_name(name)
|
||||
def parse_name name
|
||||
parts = name.split(/(::|#|\.)/)
|
||||
|
||||
if parts.length == 1 then
|
||||
if parts.first =~ /^[a-z]/ then
|
||||
if parts.first =~ /^[a-z]|^([%&*+\/<>^`|~-]|\+@|-@|<<|<=>?|===?|=>|=~|>>|\[\]=?|~@)$/ then
|
||||
type = '.'
|
||||
meth = parts.pop
|
||||
else
|
||||
|
|
|
@ -126,7 +126,7 @@ Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} #{RUBY_RELEASE_DATE}
|
|||
|
||||
Please file a bug report with the above information at:
|
||||
|
||||
http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse
|
||||
https://github.com/rdoc/rdoc/issues
|
||||
|
||||
EOF
|
||||
raise
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue