Skip to content

Commit fc27830

Browse files
committed
Refactor ToHtmlCrossref#convert_flow
1 parent 31f76e1 commit fc27830

2 files changed

Lines changed: 59 additions & 34 deletions

File tree

lib/rdoc/markup/to_html_crossref.rb

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -184,53 +184,73 @@ def link(name, text, code = true, rdoc_ref: false)
184184
end
185185
end
186186

187-
def convert_flow(flow)
187+
def convert_flow(flow_items, &block)
188188
res = []
189189

190190
i = 0
191-
while i < flow.size
192-
item = flow[i]
193-
i += 1
191+
while i < flow_items.size
192+
item = flow_items[i]
193+
194194
case item
195-
when RDoc::Markup::AttrChanger then
196-
# Make "+Class#method+" a cross reference
197-
if tt_tag?(item.turn_on) and
198-
String === (str = flow[i]) and
199-
RDoc::Markup::AttrChanger === flow[i+1] and
200-
tt_tag?(flow[i+1].turn_off, true)
201-
then
202-
crossref_re = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
203-
204-
if match = crossref_re.match(str)
205-
trailing = str[match.end(1)..-1] || ''
206-
207-
if match.begin(1).zero? and
208-
trailing.match?(/\A[[:punct:]\s]*\z/) and
209-
trailing !~ /[#@]/ and
210-
(text = cross_reference str) != str
211-
then
212-
text = yield text, res if defined?(yield)
213-
res << text
214-
i += 2
215-
next
216-
end
217-
end
195+
when RDoc::Markup::AttrChanger
196+
if (text = convert_tt_crossref(flow_items, i))
197+
text = block.call(text, res) if block
198+
res << text
199+
i += 3
200+
next
218201
end
202+
219203
off_tags res, item
220-
on_tags res, item
221-
when String then
204+
on_tags res, item
205+
i += 1
206+
when String
222207
text = convert_string(item)
223-
text = yield text, res if defined?(yield)
208+
text = block.call(text, res) if block
224209
res << text
225-
when RDoc::Markup::RegexpHandling then
210+
i += 1
211+
when RDoc::Markup::RegexpHandling
226212
text = convert_regexp_handling(item)
227-
text = yield text, res if defined?(yield)
213+
text = block.call(text, res) if block
228214
res << text
215+
i += 1
229216
else
230217
raise "Unknown flow element: #{item.inspect}"
231218
end
232219
end
233220

234221
res.join('')
235222
end
223+
224+
private
225+
226+
##
227+
# Detects <tt>...</tt> spans that contain a single cross-reference candidate.
228+
# When the candidate occupies the whole span (aside from trailing
229+
# punctuation), the tt markup is replaced by the resolved cross-reference.
230+
231+
def convert_tt_crossref(flow, index)
232+
opener = flow[index]
233+
return unless tt_tag?(opener.turn_on)
234+
235+
string = flow[index + 1]
236+
closer = flow[index + 2]
237+
238+
return unless String === string
239+
return unless RDoc::Markup::AttrChanger === closer
240+
return unless tt_tag?(closer.turn_off, true)
241+
242+
crossref_regexp = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
243+
match = crossref_regexp.match(string)
244+
return unless match
245+
return unless match.begin(1).zero?
246+
247+
trailing = match.post_match
248+
# Only convert when the remainder is punctuation/whitespace so other tt text stays literal.
249+
return unless trailing.match?(/\A[[:punct:]\s]*\z/)
250+
251+
text = cross_reference(string)
252+
return if text == string
253+
254+
text
255+
end
236256
end

test/rdoc/rdoc_markup_to_html_crossref_test.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def test_convert_CROSSREF
3434
end
3535

3636
def test_convert_CROSSREF_backslash_in_tt
37+
hyperlink_all = @options.hyperlink_all
3738
@options.hyperlink_all = false
3839

3940
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'C9.html', @c9_b
@@ -49,10 +50,14 @@ def test_convert_CROSSREF_backslash_in_tt
4950
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'C9.html', @c9_b
5051
result = formatter.convert '<tt>.bar.hello(\)</tt>'
5152

52-
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'Foo.html', foo
53-
result = formatter.convert '<tt>.bar.hello(\\)</tt>'
53+
assert_equal para('<code>.bar.hello(\)</code>'), result
54+
55+
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'C9.html', @c9_b
56+
result = formatter.convert '<tt>.bar.hello(\\\\)</tt>'
5457

5558
assert_equal para('<code>.bar.hello(\\)</code>'), result
59+
ensure
60+
@options.hyperlink_all = hyperlink_all
5661
end
5762

5863
def test_convert_CROSSREF_ignored_excluded_words

0 commit comments

Comments
 (0)