diff --git a/lib/sdoc/generator.rb b/lib/sdoc/generator.rb index 9c9c2a05..7a9ba1f6 100644 --- a/lib/sdoc/generator.rb +++ b/lib/sdoc/generator.rb @@ -3,18 +3,12 @@ require 'fileutils' require 'json' +require "rdoc" +require_relative "rdoc_monkey_patches" + require 'sdoc/templatable' require 'sdoc/helpers' require 'sdoc/version' -require 'rdoc' - -RDoc::TopLevel.prepend(Module.new do - attr_writer :path - - def path - @path ||= super - end -end) class RDoc::ClassModule def with_documentation? diff --git a/lib/sdoc/postprocessor.rb b/lib/sdoc/postprocessor.rb index 25a97ace..0445f1b7 100644 --- a/lib/sdoc/postprocessor.rb +++ b/lib/sdoc/postprocessor.rb @@ -11,8 +11,6 @@ def process(rendered) rebase_urls!(document) version_rails_guides_urls!(document) - unlink_unintentional_ref_links!(document) - style_ref_links!(document) unify_h1_headings!(document) highlight_code_blocks!(document) @@ -72,23 +70,6 @@ def version_url(url, version) uri.to_s end - def unlink_unintentional_ref_links!(document) - document.css(".description a[href^='classes/'] > code:only-child > text()").each do |text_node| - if text_node.inner_text.match?(/\A[A-Z](?:[A-Z]+|[a-z]+)\z/) - text_node.parent.parent.replace(text_node) - end - end - end - - def style_ref_links!(document) - document.css(".description a[href^='classes/']:has(> text():only-child)").each do |element| - text = element.inner_text - if !text.include?(" ") || text.match?(/\S\(/) - element.inner_html = "#{element.inner_html}" - end - end - end - def unify_h1_headings!(document) if h1 = document.at_css("#context > .description h1:first-child") if hgroup = document.at_css("#content > hgroup") diff --git a/lib/sdoc/rdoc_monkey_patches.rb b/lib/sdoc/rdoc_monkey_patches.rb new file mode 100644 index 00000000..8040f5cc --- /dev/null +++ b/lib/sdoc/rdoc_monkey_patches.rb @@ -0,0 +1,24 @@ +require "rdoc" + +RDoc::TopLevel.prepend(Module.new do + attr_writer :path + + def path + @path ||= super + end +end) + + +RDoc::Markup::ToHtmlCrossref.prepend(Module.new do + def cross_reference(name, text = nil, code = true) + if text + # Style ref links that look like code, such as `{Rails}[rdoc-ref:Rails]`. + code ||= !text.include?(" ") || text.match?(/\S\(/) + elsif name.match?(/\A[A-Z](?:[A-Z]+|[a-z]+)\z/) + # Prevent unintentional ref links, such as `Rails` or `ERB`. + return name + end + + super + end +end) diff --git a/spec/postprocessor_spec.rb b/spec/postprocessor_spec.rb index ae2ea09e..faa1d6b2 100644 --- a/spec/postprocessor_spec.rb +++ b/spec/postprocessor_spec.rb @@ -58,72 +58,6 @@ end end - it "unlinks unintentional autolinked code ref links in descriptions" do - rendered = <<~HTML - - -
- Rails - ERB - - ::Rails - FooBar -
- - Nav - HTML - - expected = <<~HTML -
- Rails - ERB - - ::Rails - FooBar -
- - Nav - HTML - - _(SDoc::Postprocessor.process(rendered)).must_include expected - end - - it "styles unstyled code ref links in descriptions" do - rendered = <<~HTML - - -
- Qux - Qux - Foo#bar?(qux, &block) - *_bar! - - Qux - Not Code - (also) not code -
- - Permalink - HTML - - expected = <<~HTML -
- Qux - Qux - Foo#bar?(qux, &block) - *_bar! - - Qux - Not Code - (also) not code -
- - Permalink - HTML - - _(SDoc::Postprocessor.process(rendered)).must_include expected - end - it "unifies

headings for a context" do rendered = <<~HTML
diff --git a/spec/rdoc_monkey_patches_spec.rb b/spec/rdoc_monkey_patches_spec.rb new file mode 100644 index 00000000..51c70e8e --- /dev/null +++ b/spec/rdoc_monkey_patches_spec.rb @@ -0,0 +1,50 @@ +require "spec_helper" + +describe "RDoc monkey patches" do + describe RDoc::TopLevel do + it "supports setting #path" do + top_level = rdoc_top_level_for("class Foo; end") + + _(top_level.path).wont_be_nil + + top_level.path = "some/path" + _(top_level.path).must_equal "some/path" + end + end + + describe RDoc::Markup::ToHtmlCrossref do + it "prevents unintentional ref links" do + description = rdoc_top_level_for(<<~RUBY).find_module_named("CoolApp").description + module ERB; end + module Rails; end + + # CoolApp uses Rails and ERB. See ::Rails. See also ::ERB. + module CoolApp; end + RUBY + + _(description).must_match %r"CoolApp uses Rails and ERB" + _(description).must_match %r"See ::Rails" + _(description).must_match %r"See also ::ERB" + end + + it "styles ref links that look like code" do + description = rdoc_top_level_for(<<~RUBY).find_module_named("Foo").description + # Some of {Foo}[rdoc-ref:Foo]'s methods can be called with multiple + # arguments, such as {bar(x, y)}[rdoc-ref:#bar]. + # + # But {baz cannot}[rdoc-ref:#baz] and {qux (also) cannot}[rdoc-ref:#qux]. + class Foo + def bar(x, y); end + def baz; end + def qux; end + end + RUBY + + _(description).must_match %r"Some of Foo" + _(description).must_match %r"such as bar\(x, y\)" + + _(description).must_match %r"But baz cannot" + _(description).must_match %r"and qux \(also\) cannot" + end + end +end