Skip to content

Commit 4bda36a

Browse files
Wrap method signatures in <code>
This factors out a `method_signature` helper that wraps method signatures in `<code>` tags and ensures that signatures are always HTML-escaped, including signatures from `:call-seq:` documentation. Incidentally, this fixes a visual disparity between `:call-seq:` signatures and normal method signatures due to the way they were wrapped with `<b>` tags. This commit also forces the postprocessor to use Nokogiri's `HTML5` parser to prevent extraneous newlines from being inserted into a signature's preformatted `<h3>` tag.
1 parent 5a42bbc commit 4bda36a

File tree

5 files changed

+59
-9
lines changed

5 files changed

+59
-9
lines changed

lib/rdoc/generator/template/rails/_context.rhtml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,8 @@
130130
%>
131131
<h2 class="content__divider"><%= visibility.to_s.capitalize %> <%= type %> methods</h2>
132132
<% methods.each do |method| %>
133-
<div class="method">
134-
<h3 class="method__signature" id="<%= method.aref %>">
135-
<% if method.call_seq %>
136-
<b><%= method.call_seq.gsub(/->/, '&rarr;').gsub(/\n(.)/, '<br />\1') %></b>
137-
<% else %>
138-
<b><%= h method.name %></b><%= h method.params %>
139-
<% end %>
140-
</h3>
133+
<div class="method" id="<%= method.aref %>">
134+
<h3 class="method__signature"><%= method_signature method %></h3>
141135
<%= link_to "Link", method, class: "permalink", name: method.aref %>
142136

143137
<% unless method.aliases.empty? %>

lib/rdoc/generator/template/rails/resources/css/main.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ html {
486486
.method__signature {
487487
font-size: 1.1em;
488488
font-weight: normal;
489+
white-space: pre-wrap;
489490
padding-bottom: var(--space-sm);
490491
border-bottom: 2px solid var(--code-bg);
491492
}

lib/sdoc/helpers.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,17 @@ def more_less_ul(items, limit)
116116
end
117117
end
118118

119+
def method_signature(rdoc_method)
120+
if rdoc_method.call_seq
121+
rdoc_method.call_seq.split(/\n+/).map do |line|
122+
# Support specifying a call-seq like `to_s -> string`
123+
line.split(" -> ").map { |side| "<code>#{h side}</code>" }.join(" &rarr; ")
124+
end.join("\n")
125+
else
126+
"<code>#{h rdoc_method.name}#{h rdoc_method.params}</code>"
127+
end
128+
end
129+
119130
def method_source_code_and_url(rdoc_method)
120131
source_code = rdoc_method.markup_code if rdoc_method.token_stream
121132

lib/sdoc/postprocessor.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module SDoc::Postprocessor
77
extend self
88

99
def process(rendered)
10-
document = Nokogiri::HTML.parse(rendered)
10+
document = Nokogiri::HTML5.parse(rendered)
1111

1212
rebase_urls!(document)
1313
version_rails_guides_urls!(document)

spec/helpers_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,50 @@ def ul(items)
502502
end
503503
end
504504

505+
describe "#method_signature" do
506+
it "returns the method signature wrapped in <code>" do
507+
method = rdoc_top_level_for(<<~RUBY).find_module_named("Foo").find_method("bar", false)
508+
module Foo; def bar(qux); end; end
509+
RUBY
510+
511+
_(@helpers.method_signature(method)).must_equal "<code>bar(qux)</code>"
512+
end
513+
514+
it "escapes the method signature" do
515+
method = rdoc_top_level_for(<<~RUBY).find_module_named("Foo").find_method("bar", false)
516+
module Foo; def bar(op = :<, &block); end; end
517+
RUBY
518+
519+
_(@helpers.method_signature(method)).must_equal "<code>bar(op = :&lt;, &amp;block)</code>"
520+
end
521+
522+
it "handles :call-seq: documentation" do
523+
mod = rdoc_top_level_for(<<~RUBY).find_module_named("Foo")
524+
module Foo
525+
# :call-seq:
526+
# bar(op = :<)
527+
# bar(&block)
528+
def bar(*args, &block); end
529+
530+
# :call-seq:
531+
# qux(&block) -> self
532+
# qux -> Enumerator
533+
def qux(&block); end
534+
end
535+
RUBY
536+
537+
_(@helpers.method_signature(mod.find_method("bar", false))).must_equal <<~HTML.chomp
538+
<code>bar(op = :&lt;)</code>
539+
<code>bar(&amp;block)</code>
540+
HTML
541+
542+
_(@helpers.method_signature(mod.find_method("qux", false))).must_equal <<~HTML.chomp
543+
<code>qux(&amp;block)</code> &rarr; <code>self</code>
544+
<code>qux</code> &rarr; <code>Enumerator</code>
545+
HTML
546+
end
547+
end
548+
505549
describe "#method_source_code_and_url" do
506550
before :each do
507551
@helpers.options.github = true

0 commit comments

Comments
 (0)