@@ -62,13 +62,13 @@ def cross_reference(name, text = nil, code = true, rdoc_ref: false)
6262 name = name [ 1 ..-1 ] unless @show_hash if name [ 0 , 1 ] == '#'
6363
6464 if !( name . end_with? ( '+@' , '-@' ) ) and name =~ /(.*[^#:])?@/
65- text ||= [ CGI . unescape ( $') , ( " at <code>#{ $1 } </code>" if $~. begin ( 1 ) ) ] . join ( "" )
65+ text ||= [ convert_string ( CGI . unescape ( $') ) , ( " at <code>#{ convert_string ( $1 ) } </code>" if $~. begin ( 1 ) ) ] . join ( "" )
6666 code = false
6767 else
68- text ||= name
68+ text ||= convert_string ( name )
6969 end
7070
71- link lookup , text , code , rdoc_ref : rdoc_ref
71+ create_html_link lookup , text , code , rdoc_ref : rdoc_ref
7272 end
7373
7474 ##
@@ -91,7 +91,10 @@ def handle_regexp_CROSSREF(name)
9191 return name if name =~ /\A [a-z]*\z /
9292 end
9393
94- cross_reference name , rdoc_ref : false
94+ # Even if name is not a crossref, RDoc removes prefix '#' here. Maybe bug.
95+ fallback_name = @show_hash ? name : name . delete_prefix ( '#' )
96+
97+ cross_reference ( name , rdoc_ref : false ) || convert_string ( fallback_name )
9598 end
9699
97100 ##
@@ -103,7 +106,8 @@ def handle_regexp_HYPERLINK(url)
103106
104107 case url
105108 when /\A rdoc-ref:/
106- cross_reference $', rdoc_ref : true
109+ ref = $'
110+ cross_reference ( ref , rdoc_ref : true ) || convert_string ( ref )
107111 else
108112 super
109113 end
@@ -123,7 +127,8 @@ def handle_regexp_RDOCLINK(url)
123127 if in_tidylink_label?
124128 convert_string ( url )
125129 else
126- cross_reference $', rdoc_ref : true
130+ ref = $'
131+ cross_reference ( ref , rdoc_ref : true ) || convert_string ( ref )
127132 end
128133 else
129134 super
@@ -137,34 +142,40 @@ def handle_regexp_RDOCLINK(url)
137142 def gen_url ( url , text )
138143 if url =~ /\A rdoc-ref:/
139144 name = $'
140- cross_reference name , text , name == text , rdoc_ref : true
145+ cross_reference ( name , text , name == text , rdoc_ref : true ) || text
141146 else
142147 super
143148 end
144149 end
145150
146151 ##
147152 # Creates an HTML link to +name+ with the given +text+.
153+ # Called from html generators.
154+
155+ def link ( name , text )
156+ create_html_link ( name , convert_string ( text ) )
157+ end
158+
159+ # Creates an HTML link to +name+ with the given html +text+.
148160
149- def link ( name , text , code = true , rdoc_ref : false )
161+ def create_html_link ( name , text , code = true , rdoc_ref : false )
150162 if !( name . end_with? ( '+@' , '-@' ) ) and name =~ /(.*[^#:])?@/
151163 name = $1
152164 label = $'
153165 end
154166
155- ref = @cross_reference . resolve name , text if name
167+ ref = @cross_reference . resolve ( name ) if name
156168
157- case ref
158- when String then
169+ if name && ref . nil?
159170 if rdoc_ref && @options . warn_missing_rdoc_ref
160171 puts "#{ @from_path } : `rdoc-ref:#{ name } ` can't be resolved for `#{ text } `"
161172 end
162- ref
173+ nil
163174 else
164175 path = ref ? ref . as_href ( @from_path ) : +""
165176
166177 if code and RDoc ::CodeObject === ref and !( RDoc ::TopLevel === ref )
167- text = "<code>#{ CGI . escapeHTML text } </code>"
178+ text = "<code>#{ text } </code>"
168179 end
169180
170181 if label
@@ -203,29 +214,41 @@ def link(name, text, code = true, rdoc_ref: false)
203214 end
204215
205216 def handle_TT ( code )
206- emit_inline ( tt_cross_reference ( code ) || "<code>#{ CGI . escapeHTML code } </code>" )
217+ emit_inline ( tt_cross_reference ( code ) || "<code>#{ convert_string ( code ) } </code>" )
207218 end
208219
209220 # Applies additional special handling on top of the one defined in ToHtml.
210221 # When a tidy link is <tt>{Foo}[rdoc-ref:Foo]</tt>, the label part is surrounded by <tt><code></code></tt>.
211222 # TODO: reconsider this workaround.
212223 def apply_tidylink_label_special_handling ( label , url )
213- if url == "rdoc-ref:#{ label } " && cross_reference ( label ) . include? ( '<code>' )
224+ if url == "rdoc-ref:#{ label } " && cross_reference ( label ) & .include? ( '<code>' )
214225 "<code>#{ convert_string ( label ) } </code>"
215226 else
216227 super
217228 end
218229 end
219230
231+ # Handles cross-reference and suppressed-crossref inside tt tag.
232+ # Returns nil if code is not a cross-reference nor a suppressed-crossref.
220233 def tt_cross_reference ( code )
221234 return if in_tidylink_label?
222235
223236 crossref_regexp = @options . hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
224- match = crossref_regexp . match ( code )
237+ # REGEXP sometimes matches to a string starts with backslash which is not a suppressed crossref. (e.g. `\+`)
238+ # We need to check the backslash removed part matches to crossref_regexp
239+ match = crossref_regexp . match ( code . delete_prefix ( '\\' ) )
225240 return unless match && match . begin ( 1 ) . zero?
226241 return unless match . post_match . match? ( /\A [[:punct:]\s ]*\z / )
227242
228- ref = cross_reference ( code )
229- ref if ref != code
243+ if code . start_with? ( '\\' )
244+ # Remove leading backslash if crossref exists
245+ "<code>#{ convert_string ( code [ 1 ..] ) } </code>" if cross_reference ( code [ 1 ..] )
246+ else
247+ # Even if code is not a crossref, RDoc removes prefix '#' here. Maybe bug.
248+ # `<tt>#comment</tt>` will be rendered as `<tt>comment</tt>`
249+ fallback_code = @show_hash ? code : code . delete_prefix ( '#' )
250+
251+ cross_reference ( code ) || "<code>#{ convert_string ( fallback_code ) } </code>"
252+ end
230253 end
231254end
0 commit comments