diff --git a/lib/rdoc/markup/to_html_crossref.rb b/lib/rdoc/markup/to_html_crossref.rb
index c5e4f62c97..c0bfb3eb70 100644
--- a/lib/rdoc/markup/to_html_crossref.rb
+++ b/lib/rdoc/markup/to_html_crossref.rb
@@ -94,6 +94,18 @@ def handle_regexp_CROSSREF(target)
return name if name =~ /\A[a-z]*\z/
end
+ # Check if the match is solely due to an escaped character pattern.
+ # If the text contains backslash escapes but doesn't match any
+ # valid cross-reference pattern (class, method, etc.), return as-is
+ if name =~ /\\/ &&
+ name !~ /\A#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}\z/o &&
+ name !~ /\A\\?#{CLASS_REGEXP_STR}\z/o &&
+ name !~ /\A\\?\##{METHOD_REGEXP_STR}\z/o &&
+ name !~ /\A::#{METHOD_REGEXP_STR}\z/o &&
+ name !~ /\A\.\.\/|[-\/\w]+[_\/.][-\w\/.]+\z/ # filepath pattern
+ return name
+ end
+
cross_reference name, rdoc_ref: false
end
@@ -198,13 +210,29 @@ def convert_flow(flow)
String === (str = flow[i]) and
RDoc::Markup::AttrChanger === flow[i+1] and
tt_tag?(flow[i+1].turn_off, true) and
- (@options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP).match?(str) and
- (text = cross_reference str) != str
+ (@options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP).match?(str)
then
- text = yield text, res if defined?(yield)
- res << text
- i += 2
- next
+ # Check if the match is solely due to an escaped character pattern.
+ # If the text contains backslash escapes but doesn't match any
+ # valid cross-reference pattern (class, method, etc.), skip cross-referencing
+ if str =~ /\\/ &&
+ str !~ /\A#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}\z/o &&
+ str !~ /\A\\?#{CLASS_REGEXP_STR}\z/o &&
+ str !~ /\A\\?\##{METHOD_REGEXP_STR}\z/o &&
+ str !~ /\A::#{METHOD_REGEXP_STR}\z/o &&
+ str !~ /\A\.\.\/|[-\/\w]+[_\/.][-\w\/.]+\z/ # filepath pattern
+ # Don't cross-reference, just output the text wrapped in code tags
+ text = "#{CGI.escapeHTML(str)}
"
+ text = yield text, res if defined?(yield)
+ res << text
+ i += 2
+ next
+ elsif (text = cross_reference str) != str
+ text = yield text, res if defined?(yield)
+ res << text
+ i += 2
+ next
+ end
end
off_tags res, item
on_tags res, item
diff --git a/test/rdoc/rdoc_markup_to_html_crossref_test.rb b/test/rdoc/rdoc_markup_to_html_crossref_test.rb
index a52c7f1506..3404bd9256 100644
--- a/test/rdoc/rdoc_markup_to_html_crossref_test.rb
+++ b/test/rdoc/rdoc_markup_to_html_crossref_test.rb
@@ -33,6 +33,22 @@ def test_convert_CROSSREF
assert_equal para("# :stopdoc:
:"), result
end
+ def test_convert_CROSSREF_backslash_escapes_in_monofont
+ # Test that backslash escapes in monofont don't create unwanted links
+ result = @to.convert '.bar.hello(\)'
+ assert_equal para(".bar.hello(\\)
"), result
+
+ result = @to.convert '.bar.hello(\\\\)'
+ assert_equal para(".bar.hello(\\)
"), result
+
+ # Regular method references should still work
+ result = @to.convert 'C1#m'
+ assert_equal para("C1#m
"), result
+
+ result = @to.convert 'C1.m'
+ assert_equal para("C1.m
"), result
+ end
+
def test_convert_CROSSREF_ignored_excluded_words
@options.autolink_excluded_words = ['C1']