1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Import RDoc 3.5.2

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2011-02-05 06:20:57 +00:00
parent d8ebf3829f
commit 8aa895294b
17 changed files with 564 additions and 290 deletions

View file

@ -1,3 +1,7 @@
Sat Feb 5 15:18:25 2011 Eric Hodel <drbrain@segment7.net>
* lib/rdoc: Upgrade to RDoc 3.5.2
Sat Feb 5 12:05:27 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/syck/rubyext.c (syck_node_init_copy): SyckNode is not

4
NEWS
View file

@ -92,8 +92,8 @@ with all sufficient information, see the ChangeLog file.
* support for bash/zsh completion.
* RDoc
* RDoc has been upgraded to RDoc 3.5.1. For full release notes see
http://rdoc.rubyforge.org/History_txt.html
* RDoc has been upgraded to RDoc 3.5.2. For full release notes see
http://docs.seattlerb.org/rdoc/History_txt.html
* rexml
* [incompatible] support Ruby native encoding mechanism

View file

@ -95,7 +95,7 @@ module RDoc
##
# RDoc version you are using
VERSION = '3.5.1'
VERSION = '3.5.2'
##
# Method visibilities

View file

@ -44,7 +44,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
##
# Adds +an_alias+ as an alias for this method in +context+.
def add_alias(an_alias, context)
def add_alias(an_alias, context = nil )
method = self.class.new an_alias.text, an_alias.new_name
method.record_location an_alias.file
@ -54,7 +54,7 @@ class RDoc::AnyMethod < RDoc::MethodAttr
method.comment = an_alias.comment
method.is_alias_for = self
@aliases << method
context.add_method method
context.add_method( method ) if context
method
end

View file

@ -59,11 +59,6 @@ class RDoc::Context < RDoc::CodeObject
attr_reader :requires
##
# Sections in this context
attr_reader :sections
##
# Hash <tt>old_name => [aliases]</tt>, for aliases
# that haven't (yet) been resolved to a method/attribute.
@ -93,13 +88,18 @@ class RDoc::Context < RDoc::CodeObject
attr_reader :constants_hash
##
# A per-comment section of documentation like:
# A section of documentation like:
#
# # :section: The title
# # The body
#
# Sections can be referenced multiple times and will be collapsed into a
# single section.
class Section
include RDoc::Text
##
# Section comment
@ -110,11 +110,6 @@ class RDoc::Context < RDoc::CodeObject
attr_reader :parent
##
# Section sequence number (for linking)
attr_reader :sequence
##
# Section title
@ -125,21 +120,69 @@ class RDoc::Context < RDoc::CodeObject
##
# Creates a new section with +title+ and +comment+
def initialize(parent, title, comment)
def initialize parent, title, comment
@parent = parent
@title = title
@title = title ? title.strip : title
@@sequence.succ!
@sequence = @@sequence.dup
set_comment comment
@comment = extract_comment comment
end
##
# Sections are equal when they have the same #sequence
# Sections are equal when they have the same #title
def ==(other)
self.class === other and @sequence == other.sequence
def == other
self.class === other and @title == other.title
end
##
# Anchor reference for linking to this section
def aref
title = @title || '[untitled]'
CGI.escape(title).gsub('%', '-').sub(/^-/, '')
end
##
# Appends +comment+ to the current comment separated by a rule.
def comment= comment
comment = extract_comment comment
return if comment.empty?
if @comment then
@comment += "\n# ---\n#{comment}"
else
@comment = comment
end
end
##
# Extracts the comment for this section from the original comment block.
# If the first line contains :section:, strip it and use the rest.
# Otherwise remove lines up to the line containing :section:, and look
# for those lines again at the end and remove them. This lets us write
#
# # :section: The title
# # The body
def extract_comment comment
if comment =~ /^#[ \t]*:section:.*\n/ then
start = $`
rest = $'
if start.empty? then
rest
else
rest.sub(/#{start.chomp}\Z/, '')
end
else
comment
end
end
def inspect # :nodoc:
@ -150,31 +193,11 @@ class RDoc::Context < RDoc::CodeObject
end
##
# Set the comment for this section from the original comment block. If
# the first line contains :section:, strip it and use the rest.
# Otherwise remove lines up to the line containing :section:, and look
# for those lines again at the end and remove them. This lets us write
#
# # :section: The title
# # The body
# Section sequence number (deprecated)
def set_comment(comment)
return unless comment
if comment =~ /^#[ \t]*:section:.*\n/ then
start = $`
rest = $'
if start.empty?
@comment = rest
else
@comment = rest.sub(/#{start.chomp}\Z/, '')
end
else
@comment = comment
end
@comment = nil if @comment.empty?
def sequence
warn "RDoc::Context::Section#sequence is deprecated, use #aref"
@sequence
end
end
@ -192,7 +215,7 @@ class RDoc::Context < RDoc::CodeObject
@visibility = :public
@current_section = Section.new self, nil, nil
@sections = [@current_section]
@sections = { nil => @current_section }
@classes = {}
@modules = {}
@ -669,6 +692,28 @@ class RDoc::Context < RDoc::CodeObject
@method_list.sort.each {|m| yield m}
end
##
# Iterator for each section's contents sorted by title. The +section+, the
# section's +constants+ and the sections +attributes+ are yielded. The
# +constants+ and +attributes+ collections are sorted.
#
# To retrieve methods in a section use #methods_by_type with the optional
# +section+ parameter.
#
# NOTE: Do not edit collections yielded by this method
def each_section # :yields: section, constants, attributes
constants = @constants.group_by do |constant| constant.section end
constants.default = []
attributes = @attributes.group_by do |attribute| attribute.section end
attributes.default = []
@sections.sort_by { |title, _| title.to_s }.each do |_, section|
yield section, constants[section].sort, attributes[section].sort
end
end
##
# Finds an attribute +name+ with singleton value +singleton+.
@ -876,10 +921,13 @@ class RDoc::Context < RDoc::CodeObject
end
##
# Breaks method_list into a nested hash by type (class or instance) and
# visibility (public, protected, private)
# Breaks method_list into a nested hash by type (<tt>'class'</tt> or
# <tt>'instance'</tt>) and visibility (+:public+, +:protected+, +:private+).
#
# If +section+ is provided only methods in that RDoc::Context::Section will
# be returned.
def methods_by_type
def methods_by_type section = nil
methods = {}
TYPES.each do |type|
@ -892,6 +940,7 @@ class RDoc::Context < RDoc::CodeObject
end
each_method do |method|
next if section and not method.section == section
methods[method.type][method.visibility] << method
end
@ -996,12 +1045,30 @@ class RDoc::Context < RDoc::CodeObject
@unmatched_alias_lists.delete key
end
##
# Sections in this context
def sections
@sections.values
end
def sections_hash # :nodoc:
@sections
end
##
# Creates a new section with +title+ and +comment+
def set_current_section(title, comment)
@current_section = Section.new self, title, comment
@sections << @current_section
if @sections.key? title then
@current_section = @sections[title]
@current_section.comment = comment
else
@current_section = Section.new self, title, comment
@sections[title] = @current_section
end
@current_section
end
##

View file

@ -62,22 +62,6 @@ 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
@ -130,7 +114,18 @@ 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'
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'
when RDoc::RubyToken::TkREGEXP then 'ruby-regexp'
when RDoc::RubyToken::TkSTRING then 'ruby-string'
when RDoc::RubyToken::TkVal then 'ruby-value'
end
text = CGI.escapeHTML t.text

View file

@ -9,17 +9,13 @@
<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 %>">
<body id="top" class="<%= klass.type %>">
<div id="metadata">
<div id="home-metadata">
@ -45,7 +41,7 @@
</div>
</div>
<% if !svninfo.empty? %>
<% if !svninfo.empty? then %>
<div id="file-svninfo-section" class="section">
<h3 class="section-header">Subversion Info</h3>
<div class="section-body">
@ -66,9 +62,8 @@
</div>
<div id="class-metadata">
<% if klass.type == 'class' then %>
<!-- 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 %>
@ -79,8 +74,20 @@
</div>
<% end %>
<% unless klass.sections.length == 1 then %>
<!-- Sections -->
<div id="sections-section" class="section">
<h3 class="section-header">Sections</h3>
<ul class="link-list">
<% klass.sections.sort_by { |s| s.title.to_s }.each do |section| %>
<li><a href="#<%= section.aref %>"><%= h section.title %></a></li>
<% end %>
</ul>
</div>
<% end %>
<% unless klass.classes_and_modules.empty? then %>
<!-- 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">
@ -91,8 +98,8 @@
</div>
<% end %>
<% unless klass.method_list.empty? then %>
<!-- Method Quickref -->
<% unless klass.method_list.empty? %>
<div id="method-list-section" class="section">
<h3 class="section-header">Methods</h3>
<ul class="link-list">
@ -103,13 +110,13 @@
</div>
<% end %>
<% unless klass.includes.empty? then %>
<!-- 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 %>
<% unless String === inc.module then %>
<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>
@ -154,7 +161,7 @@
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
</div>
<% if $DEBUG_RDOC %>
<% if $DEBUG_RDOC then %>
<div id="debugging-toggle"><img src="<%= rel_prefix %>/images/bug.png"
alt="toggle debugging" height="16" width="16" /></div>
<% end %>
@ -164,126 +171,142 @@
<div id="documentation">
<h1 class="<%= klass.type %>"><%= klass.full_name %></h1>
<div id="description">
<div id="description" class="description">
<%= klass.description %>
</div>
</div><!-- description -->
<!-- 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 %>
<% klass.each_section do |section, constants, attributes| %>
<div id="<%= section.aref %>" class="documentation-section">
<% if section.title then %>
<h2 class="section-header">
<%= section.title %>
<a href="#top">&uarr; top</a>
</h2>
<% end %>
</dl>
</div>
<% end %>
<!-- 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>
<div class="method-description">
<% if attrib.comment %>
<%= attrib.description.strip %>
<% else %>
<p class="missing-docs">(Not documented)</p>
<% end %>
</div>
<% if section.comment then %>
<div class="description">
<%= section.description %>
</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.each do |method| %>
<div id="<%= method.html_name %>-method" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>">
<a name="<%= h method.aref %>"></a>
<% if method.call_seq %>
<% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %>
<div class="method-heading">
<span class="method-callseq"><%= call_seq.strip.gsub(/->/, '&rarr;').gsub( /^\w+\./m, '') %></span>
<% if i == 0 %>
<span class="method-click-advice">click to toggle source</span>
<% unless constants.empty? then %>
<!-- Constants -->
<div id="constants-list" class="section">
<h3 class="section-header">Constants</h3>
<dl>
<% constants.each do |const| %>
<dt><a name="<%= const.name %>"><%= const.name %></a></dt>
<% if const.comment then %>
<dd class="description"><%= const.description.strip %></dd>
<% else %>
<dd class="description missing-docs">(Not documented)</dd>
<% end %>
</div>
<% end %>
<% else %>
<div class="method-heading">
<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>
</div>
<% end %>
</dl>
</div>
<% end %>
<div class="method-description">
<% if method.comment %>
<%= method.description.strip %>
<% unless attributes.empty? then %>
<!-- Attributes -->
<div id="attribute-method-details" class="method-section section">
<h3 class="section-header">Attributes</h3>
<% attributes.each do |attrib| %>
<div id="<%= attrib.html_name %>-attribute-method" class="method-detail">
<a name="<%= h attrib.name %>"></a>
<% if attrib.rw =~ /w/i then %>
<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 then %>
<%= attrib.description.strip %>
<% else %>
<p class="missing-docs">(Not documented)</p>
<% end %>
</div>
</div>
<% end %>
</div><!-- attribute-method-details -->
<% end %>
<% if method.token_stream %>
<div class="method-source-code"
id="<%= method.html_name %>-source">
<!-- Methods -->
<% klass.methods_by_type(section).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>
<% if method.call_seq then %>
<% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %>
<div class="method-heading">
<span class="method-callseq"><%= call_seq.strip.gsub(/->/, '&rarr;').gsub( /^\w+\./m, '') %></span>
<% if i == 0 then %>
<span class="method-click-advice">click to toggle source</span>
<% end %>
</div>
<% end %>
<% else %>
<div class="method-heading">
<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>
</div>
<% end %>
<div class="method-description">
<% if method.comment then %>
<%= method.description.strip %>
<% else %>
<p class="missing-docs">(Not documented)</p>
<% end %>
<% if method.token_stream then %>
<div class="method-source-code" id="<%= method.html_name %>-source">
<pre>
<%= method.markup_code %>
</pre>
</div><!-- <%= method.html_name %>-source -->
<% end %>
</div>
<% unless method.aliases.empty? then %>
<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 %>
</div>
<% 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">
Alias for: <a href="<%= klass.aref_to method.is_alias_for.path %>"><%= h method.is_alias_for.name %></a>
</div>
<% end %>
</div><!-- <%= method.html_name %>-method -->
<% 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>
<% end %>
</div><!-- <%= visibility %>-<%= type %>-method-details -->
<% end
end %>
</div><!-- <%= section.aref %> -->
<% end %>
<% end %>
</div>
<% end
end %>
</div>
</div><!-- documentation -->
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>

View file

@ -278,46 +278,46 @@ ul.link-list .type {
/* @group Documentation Section */
#description {
.description {
font-size: 100%;
color: #333;
}
#description p {
.description p {
margin: 1em 0.4em;
}
#description li p {
.description li p {
margin: 0;
}
#description ul {
.description ul {
margin-left: 1.5em;
}
#description ul li {
.description ul li {
line-height: 1.4em;
}
#description dl,
.description dl,
#documentation dl {
margin: 8px 1.5em;
border: 1px solid #ccc;
}
#description dl {
.description dl {
font-size: 14px;
}
#description dt,
.description dt,
#documentation dt {
padding: 2px 4px;
font-weight: bold;
background: #ddd;
}
#description dd,
.description dd,
#documentation dd {
padding: 2px 12px;
}
#description dd + dt,
.description dd + dt,
#documentation dd + dt {
margin-top: 0.7em;
}
@ -325,9 +325,21 @@ ul.link-list .type {
#documentation .section {
font-size: 90%;
}
#documentation h3.section-header {
#documentation h2.section-header {
margin-top: 2em;
padding: 0.75em 0.5em;
background: #ccc;
color: #333;
font-size: 175%;
border: 1px solid #bbb;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#documentation h3.section-header {
margin-top: 2em;
padding: 0.25em 0.5em;
background-color: #dedede;
color: #333;
font-size: 150%;
@ -359,6 +371,23 @@ ul.link-list .type {
color: #666;
}
.documentation-section h2 {
position: relative;
}
.documentation-section h2 a {
position: absolute;
top: 8px;
right: 10px;
font-size: 12px;
color: #9b9877;
visibility: hidden;
}
.documentation-section h2:hover a {
visibility: visible;
}
/* @group Method Details */
#documentation .method-source-code {

View file

@ -502,10 +502,11 @@ require 'rdoc'
# 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:
# 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
@ -513,7 +514,10 @@ require 'rdoc'
# # See it glisten in the noon-day sun.
# # ----------------------------------------
#
# <i>Note: Current formatters to not take sections into account.</i>
# Sections may be referenced multiple times in a class or module allowing
# methods, attributes and constants to be ordered one way for implementation
# ordering but still grouped together in documentation. If a section has
# multiple comments they will be concatenated with a dividing rule.
#
# [+:call-seq:+]
# Lines up to the next blank line in the comment are treated as the method's

View file

@ -10,6 +10,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
include RDoc::Text
# :section: Utilities
##
# Maps RDoc::Markup::Parser::LIST_TOKENS types to HTML tags
@ -55,6 +57,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
File.join(*from)
end
# :section:
##
# Creates a new formatter that will output HTML
@ -75,54 +79,21 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
init_tags
end
##
# Maps attributes to HTML tags
def init_tags
add_tag :BOLD, "<b>", "</b>"
add_tag :TT, "<tt>", "</tt>"
add_tag :EM, "<em>", "</em>"
end
# :section: Special Handling
#
# These methods handle special markup added by RDoc::Markup#add_special.
##
# Generate a hyperlink 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
type = $1
path = $2
else
type = "http"
path = url
url = "http://#{url}"
end
if type == "link" then
url = if path[0, 1] == '#' then # is this meaningful?
path
else
self.class.gen_relative_url @from_path, path
end
end
if (type == "http" or type == "link") and
url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
"<img src=\"#{url}\" />"
else
"<a href=\"#{url}\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
end
end
# :section: Special handling
##
# 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
# <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.
# +special+ is a potential hyperlink. The following schemes are handled:
#
# <tt>mailto:</tt>::
# Inserted as-is.
# <tt>http:</tt>::
# Links are checked to see if they reference an image. If so, that image
# gets inserted using an <tt><img></tt> tag. Otherwise a conventional
# <tt><a href></tt> is used.
# <tt>link:</tt>::
# Reference to a local file relative to the output directory.
def handle_special_HYPERLINK(special)
url = special.text
@ -130,8 +101,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
end
##
# Here's a hyperlink where the label is different to the URL
# <label>[url] or {long label}[url]
# This +special+ is a hyperlink where the label is different from the URL
# label[url] or {long label}[url]
def handle_special_TIDYLINK(special)
text = special.text
@ -143,41 +114,9 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
gen_url url, label
end
# :section: Utilities
##
# Wraps +txt+ to +line_len+
def wrap(txt, line_len = 76)
res = []
sp = 0
ep = txt.length
while sp < ep
# scan back for a space
p = sp + line_len - 1
if p >= ep
p = ep
else
while p > sp and txt[p] != ?\s
p -= 1
end
if p <= sp
p = sp + line_len
while p < ep and txt[p] != ?\s
p += 1
end
end
end
res << txt[sp...p] << "\n"
sp = p
sp += 1 while sp < ep and txt[sp] == ?\s
end
res.join.strip
end
# :section: Visitor
#
# These methods implement the HTML visitor.
##
# Prepares the visitor for HTML generation
@ -283,6 +222,8 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
@res << raw.parts.join("\n")
end
# :section: Utilities
##
# CGI escapes +text+
@ -290,6 +231,36 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
CGI.escapeHTML text
end
##
# Generate a hyperlink 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
type = $1
path = $2
else
type = "http"
path = url
url = "http://#{url}"
end
if type == "link" then
url = if path[0, 1] == '#' then # is this meaningful?
path
else
self.class.gen_relative_url @from_path, path
end
end
if (type == "http" or type == "link") and
url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then
"<img src=\"#{url}\" />"
else
"<a href=\"#{url}\">#{text.sub(%r{^#{type}:/*}, '')}</a>"
end
end
##
# Determines the HTML list element for +list_type+ and +open_tag+
@ -299,6 +270,15 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
tags[open_tag ? 0 : 1]
end
##
# Maps attributes to HTML tags
def init_tags
add_tag :BOLD, "<b>", "</b>"
add_tag :TT, "<tt>", "</tt>"
add_tag :EM, "<em>", "</em>"
end
##
# Returns the HTML tag for +list_type+, possible using a label from
# +list_item+

View file

@ -747,7 +747,7 @@ Usage: #{opt.program_name} [options] [names...]
if @generator.respond_to? :setup_options then
@option_parser ||= OptionParser.new
@generator.setup_options self
@generator.setup_options self
end
end

View file

@ -260,5 +260,37 @@ http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse
html
end
##
# Wraps +txt+ to +line_len+
def wrap(txt, line_len = 76)
res = []
sp = 0
ep = txt.length
while sp < ep
# scan back for a space
p = sp + line_len - 1
if p >= ep
p = ep
else
while p > sp and txt[p] != ?\s
p -= 1
end
if p <= sp
p = sp + line_len
while p < ep and txt[p] != ?\s
p += 1
end
end
end
res << txt[sp...p] << "\n"
sp = p
sp += 1 while sp < ep and txt[sp] == ?\s
end
res.join.strip
end
end

View file

@ -47,7 +47,7 @@ method(a, b) { |c, d| ... }
def test_markup_code
tokens = [
RDoc::RubyToken::TkCONSTANT. new(0, 0, 0, 'CONSTANT'),
RDoc::RubyToken::TkKW. new(0, 0, 0, 'KW'),
RDoc::RubyToken::TkDEF. 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'),
@ -90,6 +90,12 @@ method(a, b) { |c, d| ... }
assert_equal 'C1', instance_method.parent_name
assert_equal '(foo)', instance_method.params
aliased_method = Marshal.load Marshal.dump(@c2.method_list.last)
assert_equal 'C2#a', aliased_method.full_name
assert_equal 'C2', aliased_method.parent_name
assert_equal '()', aliased_method.params
class_method = Marshal.load Marshal.dump(@c1.method_list.first)
assert_equal 'C1::m', class_method.full_name

View file

@ -251,6 +251,34 @@ class TestRDocContext < XrefTestCase
refute_equal @c2_c3, @c3
end
def test_each_section
sects = []
consts = []
attrs = []
@c1.each_section do |section, constants, attributes|
sects << section
consts << constants
attrs << attributes
end
assert_equal [nil, 'separate'], sects.map { |section| section.title }
expected_consts = [
[@c1.constants.first],
[],
]
assert_equal expected_consts, consts
expected_attrs = [
[@c1.attributes[0], @c1.attributes[3]],
[@c1.attributes[1], @c1.attributes[2]],
]
assert_equal expected_attrs, attrs
end
def test_find_attribute_named
assert_equal nil, @c1.find_attribute_named('none')
assert_equal 'R', @c1.find_attribute_named('attr').rw
@ -373,5 +401,42 @@ class TestRDocContext < XrefTestCase
assert_equal(-1, @c2_c3.<=>(@c3))
end
def test_methods_by_type
expected = {
'instance' => {
:private => [],
:protected => [],
:public => [@c1_m],
},
'class' => {
:private => [],
:protected => [],
:public => [@c1__m],
},
}
assert_equal expected, @c1.methods_by_type
end
def test_methods_by_type_section
separate = @c1.sections_hash['separate']
@c1_m.section = separate
expected = {
'instance' => {
:private => [],
:protected => [],
:public => [@c1_m],
},
'class' => {
:private => [],
:protected => [],
:public => [],
},
}
assert_equal expected, @c1.methods_by_type(separate)
end
end

View file

@ -0,0 +1,54 @@
require 'rubygems'
require 'cgi'
require 'minitest/autorun'
require 'rdoc'
require 'rdoc/code_objects'
class TestRDocContextSection < MiniTest::Unit::TestCase
def setup
@S = RDoc::Context::Section
@s = @S.new nil, 'section', '# comment'
end
def test_aref
assert_equal 'section', @s.aref
assert_equal '5Buntitled-5D', @S.new(nil, nil, nil).aref
assert_equal 'one+two', @S.new(nil, 'one two', nil).aref
end
def test_comment_equals
@s.comment = "# :section: section\n"
assert_equal "# comment", @s.comment
@s.comment = "# :section: section\n# other"
assert_equal "# comment\n# ---\n# other", @s.comment
s = @S.new nil, nil, nil
s.comment = "# :section:\n# other"
assert_equal "# other", s.comment
end
def test_extract_comment
assert_equal '', @s.extract_comment('')
assert_equal '', @s.extract_comment("# :section: b\n")
assert_equal '# c', @s.extract_comment("# :section: b\n# c")
assert_equal '# c', @s.extract_comment("# a\n# :section: b\n# c")
end
def test_sequence
_, err = capture_io do
assert_match(/\ASEC\d{5}\Z/, @s.sequence)
end
assert_equal "#{@S}#sequence is deprecated, use #aref\n", err
end
end

View file

@ -17,16 +17,26 @@ class TestRDocOptions < MiniTest::Unit::TestCase
end
def test_check_files
skip "assumes UNIX permission model" if /mswin|mingw/ =~ RUBY_PLATFORM
out, err = capture_io do
Dir.mktmpdir do |dir|
Dir.chdir dir do
FileUtils.touch 'unreadable'
FileUtils.chmod 0, 'unreadable'
begin
unreadable = nil # variable for windows
@options.files = %w[nonexistent unreadable]
Dir.chdir dir do
if RUBY_PLATFORM =~ /mswin|mingw/ then
unreadable = open 'unreadable'
File.delete 'unreadable'
else
FileUtils.touch 'unreadable'
FileUtils.chmod 0, 'unreadable'
end
@options.check_files
@options.files = %w[nonexistent unreadable]
@options.check_files
end
ensure
unreadable.close if unreadable
end
end
end

View file

@ -2,8 +2,13 @@ XREF_DATA = <<-XREF_DATA
class C1
attr :attr
# :section: separate
attr_reader :attr_reader
attr_writer :attr_writer
# :section:
attr_accessor :attr_accessor
CONST = :const