diff --git a/ExampleMarkdown.md b/ExampleMarkdown.md index fd4359f355..8622fcab77 100644 --- a/ExampleMarkdown.md +++ b/ExampleMarkdown.md @@ -14,6 +14,18 @@ For the following styles, see ExampleRDoc.rdoc for style examples: These items all use the same styles as RDoc format files. +## Anchor Links + +RDoc supports GitHub-style anchor links. You can link to any heading using its +anchor, which is the heading text converted to lowercase with spaces replaced +by hyphens and special characters removed. + +For example: + +* [Link to Footnotes](#footnotes) +* [Link to Blockquotes](#blockquotes) +* [Link to Anchor Links](#anchor-links) + ## Footnotes Footnotes are rendered at the bottom of the documentation section[^1]. For @@ -36,4 +48,3 @@ Here is how a blockquote looks. > > 75 years? This text is from [Riker Ipsum](http://rikeripsum.com) - diff --git a/ExampleRDoc.rdoc b/ExampleRDoc.rdoc index b5dd68c19c..750fdc4795 100644 --- a/ExampleRDoc.rdoc +++ b/ExampleRDoc.rdoc @@ -3,6 +3,18 @@ This document contains example output to show RDoc styling. This file was created from a RDoc Markup file. +== Anchor Links + +RDoc generates GitHub-style anchors for headings. The anchor is the heading +text converted to lowercase with spaces replaced by hyphens and special +characters removed. + +You can link to headings using Markdown-style syntax: + +- {Link to Headings}[#headings] +- {Link to Paragraphs}[#paragraphs] +- {Link to Verbatim sections}[#verbatim-sections] + == Headings You should not use headings beyond level 3, it is a sign of poor organization diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 1ceda2656d..1729144f4c 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -957,22 +957,30 @@ # # [Heading] # -# - Link: RDoc::RD@LICENSE links to RDoc::RDoc::RD@LICENSE. +# Headings generate GitHub-style anchors: lowercase, spaces as hyphens, +# special characters removed. For example, == Hello World generates +# anchor hello-world. # -# Note that spaces in the actual heading are represented by + characters -# in the linkable text. +# Link to headings are recommended to use the GitHub-style anchor format: # -# - Link: RDoc::Options@Saved+Options -# links to RDoc::Options@Saved+Options. +# - RDoc::Options@saved-options links to RDoc::Options@saved-options. +# - RDoc::RD@license links to RDoc::RD@license. # -# Punctuation and other special characters must be escaped like CGI.escape. +# To link to headings on the same page, you can also use Markdown-style anchor links: +# +# - {link text}[#hello-world] links to the heading == Hello World. +# - {link text}[#saved-options] links to the heading == Saved Options. +# +# The legacy format with + for spaces is also supported, but not recommended: +# +# - RDoc::Options@Saved+Options links to RDoc::Options@Saved+Options. # # Pro tip: The link to any heading is available in the alphabetical table of contents -# at the top left of the page for the class or module. +# at the right sidebar of the page. # # [Section] # -# See {Directives for Organizing Documentation}[#class-RDoc::MarkupReference-label-Directives+for+Organizing+Documentation]. +# See {Directives for Organizing Documentation}[#class-rdoc-markupreference-directives-for-organizing-documentation]. # # - Link: RDoc::Markup::ToHtml@Visitor links to RDoc::Markup::ToHtml@Visitor. # diff --git a/lib/rdoc/code_object/class_module.rb b/lib/rdoc/code_object/class_module.rb index d7ee36f950..00e406b1a6 100644 --- a/lib/rdoc/code_object/class_module.rb +++ b/lib/rdoc/code_object/class_module.rb @@ -188,10 +188,26 @@ def aref_prefix # :nodoc: end ## - # HTML fragment reference for this module or class. See - # RDoc::NormalClass#aref and RDoc::NormalModule#aref + # HTML fragment reference for this module or class using GitHub-style + # anchor format (lowercase, :: replaced with -). + # + # Examples: + # Foo -> class-foo + # Foo::Bar -> class-foo-bar def aref + "#{aref_prefix}-#{full_name.downcase.gsub('::', '-')}" + end + + ## + # Legacy HTML fragment reference for backward compatibility. + # Returns the old RDoc-style anchor format. + # + # Examples: + # Foo -> class-Foo + # Foo::Bar -> class-Foo::Bar + + def legacy_aref "#{aref_prefix}-#{full_name}" end diff --git a/lib/rdoc/code_object/context/section.rb b/lib/rdoc/code_object/context/section.rb index 16b778174f..7600a16935 100644 --- a/lib/rdoc/code_object/context/section.rb +++ b/lib/rdoc/code_object/context/section.rb @@ -70,11 +70,30 @@ def add_comment(comment) end ## - # Anchor reference for linking to this section + # Anchor reference for linking to this section using GitHub-style format. + # + # Examples: + # "Section" -> "section" + # "One Two" -> "one-two" + # "[untitled]" -> "untitled" def aref title = @title || '[untitled]' + RDoc::Text.to_anchor(title) + end + + ## + # Legacy anchor reference for backward compatibility. + # + # Examples: + # "Section" -> "section" + # "One Two" -> "one+two" + # "[untitled]" -> "5Buntitled-5D" + + def legacy_aref + title = @title || '[untitled]' + CGI.escape(title).gsub('%', '-').sub(/^-/, '') end diff --git a/lib/rdoc/generator/template/aliki/class.rhtml b/lib/rdoc/generator/template/aliki/class.rhtml index 69adfab1ad..5a6fa35b18 100644 --- a/lib/rdoc/generator/template/aliki/class.rhtml +++ b/lib/rdoc/generator/template/aliki/class.rhtml @@ -29,6 +29,7 @@ <% end %> +
C1"), result
+ assert_equal para("foo at C1"), result
result = @to.convert 'C1#m@foo'
- assert_equal para("foo at C1#m"),
+ assert_equal para("foo at C1#m"),
result
end
def test_convert_CROSSREF_label_for_md
result = @to.convert 'EXAMPLE@foo'
- assert_equal para("foo at EXAMPLE"), result
+ assert_equal para("foo at EXAMPLE"), result
end
def test_convert_CROSSREF_label_period
result = @to.convert 'C1@foo.'
- assert_equal para("foo at C1."), result
+ assert_equal para("foo at C1."), result
end
def test_convert_CROSSREF_label_space
result = @to.convert 'C1@foo+bar'
- assert_equal para("foo bar at C1"),
+ assert_equal para("foo bar at C1"),
result
end
@@ -101,7 +101,14 @@ def test_convert_CROSSREF_section
@c1.add_section 'Section'
result = @to.convert 'C1@Section'
- assert_equal para("Section at C1"), result
+ assert_equal para("Section at C1"), result
+ end
+
+ def test_convert_CROSSREF_section_with_spaces
+ @c1.add_section 'Public Methods'
+
+ result = @to.convert 'C1@Public+Methods'
+ assert_equal para("Public Methods at C1"), result
end
def test_convert_CROSSREF_constant
@@ -135,7 +142,7 @@ def test_convert_RDOCLINK_rdoc_ref_method
def test_convert_RDOCLINK_rdoc_ref_method_label
result = @to.convert 'rdoc-ref:C1#m@foo'
- assert_equal para("foo at C1#m"),
+ assert_equal para("foo at C1#m"),
result, 'rdoc-ref:C1#m@foo'
end
@@ -171,33 +178,33 @@ def test_convert_RDOCLINK_rdoc_ref_method_percent_label
result = @to.convert 'rdoc-ref:C1#%@f'
- assert_equal para("f at C1#%"),
+ assert_equal para("f at C1#%"),
result
m.singleton = true
result = @to.convert 'rdoc-ref:C1::%@f'
- assert_equal para("f at C1::%"),
+ assert_equal para("f at C1::%"),
result
end
def test_convert_RDOCLINK_rdoc_ref_label
result = @to.convert 'rdoc-ref:C1@foo'
- assert_equal para("foo at C1"), result,
+ assert_equal para("foo at C1"), result,
'rdoc-ref:C1@foo'
end
def test_convert_RDOCLINK_rdoc_ref_label_in_current_file
result = @to.convert 'rdoc-ref:@foo'
- assert_equal para("foo"), result,
+ assert_equal para("foo"), result,
'rdoc-ref:@foo'
result = @to.convert '{Foo}[rdoc-ref:@foo]'
- assert_equal para("Foo"), result,
+ assert_equal para("Foo"), result,
'{Foo}[rdoc-ref:@foo]'
end
@@ -222,7 +229,7 @@ def test_handle_regexp_CROSSREF
end
def test_handle_regexp_CROSSREF_label
- assert_equal "foo at C1#m",
+ assert_equal "foo at C1#m",
REGEXP_HANDLING('C1#m@foo')
end
@@ -285,7 +292,7 @@ def test_handle_regexp_TIDYLINK_rdoc
def test_handle_regexp_TIDYLINK_label
link = @to.handle_regexp_TIDYLINK tidy 'C1#m@foo'
- assert_equal "tidy",
+ assert_equal "tidy",
link, 'C1#m@foo'
end
diff --git a/test/rdoc/markup/to_html_test.rb b/test/rdoc/markup/to_html_test.rb
index 49bf51b306..3d2b010c4b 100644
--- a/test/rdoc/markup/to_html_test.rb
+++ b/test/rdoc/markup/to_html_test.rb
@@ -24,34 +24,34 @@ def accept_document
end
def accept_heading
- assert_equal "\n