@@ -59,21 +59,21 @@ def init_link_notation_regexp_handlings
5959 # given it is used as the link text, otherwise +name+ is used.
6060
6161 def cross_reference ( name , text = nil , code = true , rdoc_ref : false )
62- lookup = name
62+ # Strip '#' from display text for method references (e.g. #method -> method),
63+ # but only when @show_hash is false and only for link text, not for fallback.
64+ display = !@show_hash && name . start_with? ( '#' ) ? name [ 1 ..] : name
6365
64- name = name [ 1 ..-1 ] unless @show_hash if name [ 0 , 1 ] == '#'
65-
66- if !name . end_with? ( '+@' , '-@' ) && match = name . match ( /(.*[^#:])?@(.*)/ )
66+ if !display . end_with? ( '+@' , '-@' ) && match = display . match ( /(.*[^#:])?@(.*)/ )
6767 context_name = match [ 1 ]
6868 label = RDoc ::Text . decode_legacy_label ( match [ 2 ] )
6969 text ||= "#{ label } at <code>#{ context_name } </code>" if context_name
7070 text ||= label
7171 code = false
7272 else
73- text ||= name
73+ text ||= display
7474 end
7575
76- link lookup , text , code , rdoc_ref : rdoc_ref
76+ link ( name , text , code , rdoc_ref : rdoc_ref ) || name
7777 end
7878
7979 ##
@@ -150,6 +150,7 @@ def gen_url(url, text)
150150
151151 ##
152152 # Creates an HTML link to +name+ with the given +text+.
153+ # Returns the link HTML string, or +nil+ if the reference could not be resolved.
153154
154155 def link ( name , text , code = true , rdoc_ref : false )
155156 if !( name . end_with? ( '+@' , '-@' ) ) and name =~ /(.*[^#:])?@/
@@ -162,56 +163,60 @@ def link(name, text, code = true, rdoc_ref: false)
162163 # Non-text source files (C, Ruby, etc.) don't get HTML pages generated,
163164 # so don't auto-link to them. Explicit rdoc-ref: links are still allowed.
164165 if !rdoc_ref && RDoc ::TopLevel === ref && !ref . text?
165- return text
166+ return
166167 end
167168
168169 case ref
169- when String then
170+ when String
170171 if rdoc_ref && @warn_missing_rdoc_ref
171172 puts "#{ @from_path } : `rdoc-ref:#{ name } ` can't be resolved for `#{ text } `"
172173 end
173- ref
174+ return
175+ when nil
176+ # A bare label reference like @foo still produces a valid anchor link
177+ return unless label
178+ path = +""
174179 else
175- path = ref ? ref . as_href ( @from_path ) : + ""
180+ path = ref . as_href ( @from_path )
176181
177182 if code and RDoc ::CodeObject === ref and !( RDoc ::TopLevel === ref )
178183 text = "<code>#{ CGI . escapeHTML text } </code>"
179184 end
185+ end
180186
181- if label
182- # Decode legacy labels (e.g., "What-27s+Here" -> "What's Here")
183- # then convert to GitHub-style anchor format
184- decoded_label = RDoc ::Text . decode_legacy_label ( label )
185- formatted_label = RDoc ::Text . to_anchor ( decoded_label )
186-
187- # Case 1: Path already has an anchor (e.g., method link)
188- # Input: C1#method@label -> path="C1.html#method-i-m"
189- # Output: C1.html#method-i-m-label
190- if path =~ /#/
191- path << "-#{ formatted_label } "
192-
193- # Case 2: Label matches a section title
194- # Input: C1@Section -> path="C1.html", section "Section" exists
195- # Output: C1.html#section (uses section.aref for GitHub-style)
196- elsif ( section = ref &.sections &.find { |s | decoded_label == s . title } )
197- path << "##{ section . aref } "
198-
199- # Case 3: Ref has an aref (class/module context)
200- # Input: C1@heading -> path="C1.html", ref=C1 class
201- # Output: C1.html#class-c1-heading
202- elsif ref . respond_to? ( :aref )
203- path << "##{ ref . aref } -#{ formatted_label } "
204-
205- # Case 4: No context, just the label (e.g., TopLevel/file)
206- # Input: README@section -> path="README_md.html"
207- # Output: README_md.html#section
208- else
209- path << "##{ formatted_label } "
210- end
187+ if label
188+ # Decode legacy labels (e.g., "What-27s+Here" -> "What's Here")
189+ # then convert to GitHub-style anchor format
190+ decoded_label = RDoc ::Text . decode_legacy_label ( label )
191+ formatted_label = RDoc ::Text . to_anchor ( decoded_label )
192+
193+ # Case 1: Path already has an anchor (e.g., method link)
194+ # Input: C1#method@label -> path="C1.html#method-i-m"
195+ # Output: C1.html#method-i-m-label
196+ if path =~ /#/
197+ path << "-#{ formatted_label } "
198+
199+ # Case 2: Label matches a section title
200+ # Input: C1@Section -> path="C1.html", section "Section" exists
201+ # Output: C1.html#section (uses section.aref for GitHub-style)
202+ elsif ( section = ref &.sections &.find { |s | decoded_label == s . title } )
203+ path << "##{ section . aref } "
204+
205+ # Case 3: Ref has an aref (class/module context)
206+ # Input: C1@heading -> path="C1.html", ref=C1 class
207+ # Output: C1.html#class-c1-heading
208+ elsif ref . respond_to? ( :aref )
209+ path << "##{ ref . aref } -#{ formatted_label } "
210+
211+ # Case 4: No context, just the label (e.g., TopLevel/file)
212+ # Input: README@section -> path="README_md.html"
213+ # Output: README_md.html#section
214+ else
215+ path << "##{ formatted_label } "
211216 end
212-
213- "<a href=\" #{ path } \" >#{ text } </a>"
214217 end
218+
219+ "<a href=\" #{ path } \" >#{ text } </a>"
215220 end
216221
217222 def handle_TT ( code )
0 commit comments