aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-02-05 06:20:57 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-02-05 06:20:57 +0000
commit8aa895294b8d696489b51a5e69b2986f452da905 (patch)
tree085fe578ab276ff3be423448a4b9407c60a6dc51
parentd8ebf3829f24fcb05ff47a12a9bb83e8b993aeae (diff)
downloadruby-8aa895294b8d696489b51a5e69b2986f452da905.tar.gz
Import RDoc 3.5.2
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog4
-rw-r--r--NEWS4
-rw-r--r--lib/rdoc.rb2
-rw-r--r--lib/rdoc/any_method.rb4
-rw-r--r--lib/rdoc/context.rb143
-rw-r--r--lib/rdoc/generator/markup.rb29
-rw-r--r--lib/rdoc/generator/template/darkfish/classpage.rhtml253
-rw-r--r--lib/rdoc/generator/template/darkfish/rdoc.css51
-rw-r--r--lib/rdoc/markup.rb14
-rw-r--r--lib/rdoc/markup/to_html.rb144
-rw-r--r--lib/rdoc/options.rb2
-rw-r--r--lib/rdoc/text.rb32
-rw-r--r--test/rdoc/test_rdoc_any_method.rb8
-rw-r--r--test/rdoc/test_rdoc_context.rb65
-rw-r--r--test/rdoc/test_rdoc_context_section.rb54
-rw-r--r--test/rdoc/test_rdoc_options.rb26
-rw-r--r--test/rdoc/xref_data.rb5
17 files changed, 557 insertions, 283 deletions
diff --git a/ChangeLog b/ChangeLog
index fe2b9cddee..bb6867e9df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index 8edc997cdb..feca91e46f 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/lib/rdoc.rb b/lib/rdoc.rb
index e3885b1cbb..0b521a5d2d 100644
--- a/lib/rdoc.rb
+++ b/lib/rdoc.rb
@@ -95,7 +95,7 @@ module RDoc
##
# RDoc version you are using
- VERSION = '3.5.1'
+ VERSION = '3.5.2'
##
# Method visibilities
diff --git a/lib/rdoc/any_method.rb b/lib/rdoc/any_method.rb
index 5877ec9662..f691598910 100644
--- a/lib/rdoc/any_method.rb
+++ b/lib/rdoc/any_method.rb
@@ -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
diff --git a/lib/rdoc/context.rb b/lib/rdoc/context.rb
index 3c12d10058..3f2856db05 100644
--- a/lib/rdoc/context.rb
+++ b/lib/rdoc/context.rb
@@ -60,11 +60,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.
# (Not to be confused with the aliases of the context.)
@@ -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
@@ -111,11 +111,6 @@ class RDoc::Context < RDoc::CodeObject
attr_reader :parent
##
- # Section sequence number (for linking)
-
- attr_reader :sequence
-
- ##
# Section title
attr_reader :title
@@ -125,56 +120,84 @@ 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
- def inspect # :nodoc:
- "#<%s:0x%x %s %p>" % [
- self.class, object_id,
- @sequence, title
- ]
+ ##
+ # 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
##
- # Set the comment for this section from the original comment block. If
- # the first line contains :section:, strip it and use the rest.
+ # 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 set_comment(comment)
- return unless comment
-
+ def extract_comment comment
if comment =~ /^#[ \t]*:section:.*\n/ then
start = $`
rest = $'
- if start.empty?
- @comment = rest
+ if start.empty? then
+ rest
else
- @comment = rest.sub(/#{start.chomp}\Z/, '')
+ rest.sub(/#{start.chomp}\Z/, '')
end
else
- @comment = comment
+ comment
end
+ end
- @comment = nil if @comment.empty?
+ def inspect # :nodoc:
+ "#<%s:0x%x %s %p>" % [
+ self.class, object_id,
+ @sequence, title
+ ]
+ end
+
+ ##
+ # Section sequence number (deprecated)
+
+ 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 = {}
@@ -670,6 +693,28 @@ class RDoc::Context < RDoc::CodeObject
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+.
def find_attribute(name, 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
@@ -997,11 +1046,29 @@ class RDoc::Context < RDoc::CodeObject
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
##
diff --git a/lib/rdoc/generator/markup.rb b/lib/rdoc/generator/markup.rb
index dd7c73044d..1919a62ec8 100644
--- a/lib/rdoc/generator/markup.rb
+++ b/lib/rdoc/generator/markup.rb
@@ -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
diff --git a/lib/rdoc/generator/template/darkfish/classpage.rhtml b/lib/rdoc/generator/template/darkfish/classpage.rhtml
index 4a1bdcdea9..856321532b 100644
--- a/lib/rdoc/generator/template/darkfish/classpage.rhtml
+++ b/lib/rdoc/generator/template/darkfish/classpage.rhtml
@@ -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 -->
+
+ <% 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 %>
- <!-- 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 %>
+ <% if section.comment then %>
+ <div class="description">
+ <%= section.description %>
+ </div>
<% 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>
+ <% 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 %>
<% end %>
- </div>
+ </dl>
</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 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 %>
- <% 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><!-- attribute-method-details -->
+ <% end %>
- <div class="method-description">
- <% if method.comment %>
- <%= method.description.strip %>
+ <!-- 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 %>
- <p class="missing-docs">(Not documented)</p>
+ <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 %>
- <% if method.token_stream %>
- <div class="method-source-code"
- id="<%= method.html_name %>-source">
+ <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>
- <% 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 %>
+ <% 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 %>
- <% 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>
+ <% 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 -->
- <% end %>
- </div>
- <% end
- end %>
+ <% end %>
+ </div><!-- <%= visibility %>-<%= type %>-method-details -->
+ <% end
+ end %>
+ </div><!-- <%= section.aref %> -->
+ <% end %>
- </div>
+ </div><!-- documentation -->
<div id="validator-badges">
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
diff --git a/lib/rdoc/generator/template/darkfish/rdoc.css b/lib/rdoc/generator/template/darkfish/rdoc.css
index 59f568ae47..c5a93ff150 100644
--- a/lib/rdoc/generator/template/darkfish/rdoc.css
+++ b/lib/rdoc/generator/template/darkfish/rdoc.css
@@ -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 {
diff --git a/lib/rdoc/markup.rb b/lib/rdoc/markup.rb
index 9a2e7f2ca8..73de2d06f8 100644
--- a/lib/rdoc/markup.rb
+++ b/lib/rdoc/markup.rb
@@ -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
diff --git a/lib/rdoc/markup/to_html.rb b/lib/rdoc/markup/to_html.rb
index d587a8abbc..599f3713f1 100644
--- a/lib/rdoc/markup/to_html.rb
+++ b/lib/rdoc/markup/to_html.rb
@@ -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+
@@ -291,6 +232,36 @@ 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
+
+ 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+
def html_list_name(list_type, open_tag)
@@ -300,6 +271,15 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter
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+
diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb
index c5f3b36b8d..dd91706638 100644
--- a/lib/rdoc/options.rb
+++ b/lib/rdoc/options.rb
@@ -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
diff --git a/lib/rdoc/text.rb b/lib/rdoc/text.rb
index 6dec4217e6..501871c8df 100644
--- a/lib/rdoc/text.rb
+++ b/lib/rdoc/text.rb
@@ -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
diff --git a/test/rdoc/test_rdoc_any_method.rb b/test/rdoc/test_rdoc_any_method.rb
index 2104322c91..930d9773bd 100644
--- a/test/rdoc/test_rdoc_any_method.rb
+++ b/test/rdoc/test_rdoc_any_method.rb
@@ -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
diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb
index 9f110fc9f8..71870c545f 100644
--- a/test/rdoc/test_rdoc_context.rb
+++ b/test/rdoc/test_rdoc_context.rb
@@ -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
diff --git a/test/rdoc/test_rdoc_context_section.rb b/test/rdoc/test_rdoc_context_section.rb
new file mode 100644
index 0000000000..1636c98246
--- /dev/null
+++ b/test/rdoc/test_rdoc_context_section.rb
@@ -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
+
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 763f50b5f0..8e5ec853cc 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -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'
-
- @options.files = %w[nonexistent unreadable]
-
- @options.check_files
+ begin
+ unreadable = nil # variable for windows
+
+ 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.files = %w[nonexistent unreadable]
+
+ @options.check_files
+ end
+ ensure
+ unreadable.close if unreadable
end
end
end
diff --git a/test/rdoc/xref_data.rb b/test/rdoc/xref_data.rb
index 3afb06bd13..5a7e98d671 100644
--- a/test/rdoc/xref_data.rb
+++ b/test/rdoc/xref_data.rb
@@ -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