Skip to content

Commit 3e0ec07

Browse files
committed
Refactor ToHtmlCrossref#convert_flow
1 parent b715f67 commit 3e0ec07

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

lib/rdoc/markup/to_html_crossref.rb

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

187-
def convert_flow(flow)
187+
##
188+
# Converts inline "flow" items emitted by
189+
# RDoc::Markup::AttributeManager#flow. The array contains strings plus
190+
# formatting sentinels (RDoc::Markup::AttrChanger) and regexp placeholders.
191+
# Inline <tt>…</tt> runs that wrap a single cross-reference candidate are
192+
# upgraded to HTML links; everything else follows the base formatter logic.
193+
194+
def convert_flow(flow_items, &block)
188195
res = []
189196

190197
i = 0
191-
while i < flow.size
192-
item = flow[i]
193-
i += 1
198+
while i < flow_items.size
199+
item = flow_items[i]
200+
194201
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
202+
when RDoc::Markup::AttrChanger
203+
if (text = convert_tt_crossref(flow_items, i))
204+
text = block.call(text, res) if block
205+
res << text
206+
i += 3
207+
next
218208
end
209+
219210
off_tags res, item
220-
on_tags res, item
221-
when String then
211+
on_tags res, item
212+
i += 1
213+
when String
222214
text = convert_string(item)
223-
text = yield text, res if defined?(yield)
215+
text = block.call(text, res) if block
224216
res << text
225-
when RDoc::Markup::RegexpHandling then
217+
i += 1
218+
when RDoc::Markup::RegexpHandling
226219
text = convert_regexp_handling(item)
227-
text = yield text, res if defined?(yield)
220+
text = block.call(text, res) if block
228221
res << text
222+
i += 1
229223
else
230224
raise "Unknown flow element: #{item.inspect}"
231225
end
232226
end
233227

234228
res.join('')
235229
end
230+
231+
private
232+
233+
##
234+
# Detects <tt>...</tt> spans that contain a single cross-reference candidate.
235+
# When the candidate occupies the whole span (aside from trailing
236+
# punctuation), the tt markup is replaced by the resolved cross-reference.
237+
238+
def convert_tt_crossref(flow, index)
239+
opener = flow[index]
240+
return unless tt_tag?(opener.turn_on)
241+
242+
string = flow[index + 1]
243+
closer = flow[index + 2]
244+
245+
return unless String === string
246+
return unless RDoc::Markup::AttrChanger === closer
247+
return unless tt_tag?(closer.turn_off, true)
248+
249+
crossref_re = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
250+
match = crossref_re.match(string)
251+
return unless match
252+
return unless match.begin(1).zero?
253+
254+
trailing = string[match.end(1)..-1] || ''
255+
return unless trailing.match?(/\A[[:punct:]\s]*\z/)
256+
257+
text = cross_reference(string)
258+
return if text == string
259+
260+
text
261+
end
236262
end

test/rdoc/rdoc_markup_to_html_crossref_test.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,20 @@ 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

39-
foo = RDoc::NormalClass.new 'Foo'
40-
foo.store = @store
41-
foo.parent = @top_level
42-
foo.add_method RDoc::AnyMethod.new(nil, 'bar')
40+
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'C9.html', @c9_b
41+
result = formatter.convert '<tt>.bar.hello(\)</tt>'
4342

44-
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'Foo.html', foo
45-
result = formatter.convert '<tt>.bar.hello(\\)</tt>'
43+
assert_equal para('<code>.bar.hello(\)</code>'), result
44+
45+
formatter = RDoc::Markup::ToHtmlCrossref.new @options, 'C9.html', @c9_b
46+
result = formatter.convert '<tt>.bar.hello(\\\\)</tt>'
4647

4748
assert_equal para('<code>.bar.hello(\\)</code>'), result
49+
ensure
50+
@options.hyperlink_all = hyperlink_all
4851
end
4952

5053
def test_convert_CROSSREF_ignored_excluded_words

0 commit comments

Comments
 (0)