@@ -63,15 +63,15 @@ def cross_reference(name, text = nil, code = true, rdoc_ref: false)
6363
6464 if !name . end_with? ( '+@' , '-@' ) && match = name . match ( /(.*[^#:])?@(.*)/ )
6565 context_name = match [ 1 ]
66- label = RDoc ::Text . decode_legacy_label ( match [ 2 ] )
67- text ||= "#{ label } at <code>#{ context_name } </code>" if context_name
66+ label = convert_string ( RDoc ::Text . decode_legacy_label ( match [ 2 ] ) )
67+ text ||= "#{ label } at <code>#{ convert_string ( context_name ) } </code>" if context_name
6868 text ||= label
6969 code = false
7070 else
71- text ||= name
71+ text ||= convert_string ( name )
7272 end
7373
74- link lookup , text , code , rdoc_ref : rdoc_ref
74+ create_html_link lookup , text , code , rdoc_ref : rdoc_ref
7575 end
7676
7777 ##
@@ -94,7 +94,10 @@ def handle_regexp_CROSSREF(name)
9494 return name if name =~ /\A [a-z]*\z /
9595 end
9696
97- cross_reference name , rdoc_ref : false
97+ # Even if name is not a crossref, RDoc removes prefix '#' here. Maybe bug.
98+ fallback_name = @show_hash ? name : name . delete_prefix ( '#' )
99+
100+ cross_reference ( name , rdoc_ref : false ) || convert_string ( fallback_name )
98101 end
99102
100103 ##
@@ -106,7 +109,8 @@ def handle_regexp_HYPERLINK(url)
106109
107110 case url
108111 when /\A rdoc-ref:/
109- cross_reference $', rdoc_ref : true
112+ ref = $'
113+ cross_reference ( ref , rdoc_ref : true ) || convert_string ( ref )
110114 else
111115 super
112116 end
@@ -126,7 +130,8 @@ def handle_regexp_RDOCLINK(url)
126130 if in_tidylink_label?
127131 convert_string ( url )
128132 else
129- cross_reference $', rdoc_ref : true
133+ ref = $'
134+ cross_reference ( ref , rdoc_ref : true ) || convert_string ( ref )
130135 end
131136 else
132137 super
@@ -140,34 +145,40 @@ def handle_regexp_RDOCLINK(url)
140145 def gen_url ( url , text )
141146 if url =~ /\A rdoc-ref:/
142147 name = $'
143- cross_reference name , text , name == text , rdoc_ref : true
148+ cross_reference ( name , text , name == text , rdoc_ref : true ) || text
144149 else
145150 super
146151 end
147152 end
148153
149154 ##
150155 # Creates an HTML link to +name+ with the given +text+.
156+ # Called from html generators.
157+
158+ def link ( name , text )
159+ create_html_link ( name , convert_string ( text ) )
160+ end
161+
162+ # Creates an HTML link to +name+ with the given html +text+.
151163
152- def link ( name , text , code = true , rdoc_ref : false )
164+ def create_html_link ( name , text , code = true , rdoc_ref : false )
153165 if !( name . end_with? ( '+@' , '-@' ) ) and name =~ /(.*[^#:])?@/
154166 name = $1
155167 label = $'
156168 end
157169
158- ref = @cross_reference . resolve name , text if name
170+ ref = @cross_reference . resolve ( name ) if name
159171
160- case ref
161- when String then
172+ if name && ref . nil?
162173 if rdoc_ref && @options . warn_missing_rdoc_ref
163174 puts "#{ @from_path } : `rdoc-ref:#{ name } ` can't be resolved for `#{ text } `"
164175 end
165- ref
176+ nil
166177 else
167178 path = ref ? ref . as_href ( @from_path ) : +""
168179
169180 if code and RDoc ::CodeObject === ref and !( RDoc ::TopLevel === ref )
170- text = "<code>#{ CGI . escapeHTML text } </code>"
181+ text = "<code>#{ text } </code>"
171182 end
172183
173184 if label
@@ -207,29 +218,41 @@ def link(name, text, code = true, rdoc_ref: false)
207218 end
208219
209220 def handle_TT ( code )
210- emit_inline ( tt_cross_reference ( code ) || "<code>#{ CGI . escapeHTML code } </code>" )
221+ emit_inline ( tt_cross_reference ( code ) || "<code>#{ convert_string ( code ) } </code>" )
211222 end
212223
213224 # Applies additional special handling on top of the one defined in ToHtml.
214225 # When a tidy link is <tt>{Foo}[rdoc-ref:Foo]</tt>, the label part is surrounded by <tt><code></code></tt>.
215226 # TODO: reconsider this workaround.
216227 def apply_tidylink_label_special_handling ( label , url )
217- if url == "rdoc-ref:#{ label } " && cross_reference ( label ) . include? ( '<code>' )
228+ if url == "rdoc-ref:#{ label } " && cross_reference ( label ) & .include? ( '<code>' )
218229 "<code>#{ convert_string ( label ) } </code>"
219230 else
220231 super
221232 end
222233 end
223234
235+ # Handles cross-reference and suppressed-crossref inside tt tag.
236+ # Returns nil if code is not a cross-reference nor a suppressed-crossref.
224237 def tt_cross_reference ( code )
225238 return if in_tidylink_label?
226239
227240 crossref_regexp = @options . hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP
228- match = crossref_regexp . match ( code )
241+ # REGEXP sometimes matches to a string starts with backslash which is not a suppressed crossref. (e.g. `\+`)
242+ # We need to check the backslash removed part matches to crossref_regexp
243+ match = crossref_regexp . match ( code . delete_prefix ( '\\' ) )
229244 return unless match && match . begin ( 1 ) . zero?
230245 return unless match . post_match . match? ( /\A [[:punct:]\s ]*\z / )
231246
232- ref = cross_reference ( code )
233- ref if ref != code
247+ if code . start_with? ( '\\' )
248+ # Remove leading backslash if crossref exists
249+ "<code>#{ convert_string ( code [ 1 ..] ) } </code>" if cross_reference ( code [ 1 ..] )
250+ else
251+ # Even if code is not a crossref, RDoc removes prefix '#' here. Maybe bug.
252+ # `<tt>#comment</tt>` will be rendered as `<tt>comment</tt>`
253+ fallback_code = @show_hash ? code : code . delete_prefix ( '#' )
254+
255+ cross_reference ( code ) || "<code>#{ convert_string ( fallback_code ) } </code>"
256+ end
234257 end
235258end
0 commit comments