Class: RDoc::Markup::ToHtmlCrossref
- Defined in:
- lib/rdoc/markup/to_html_crossref.rb
Overview
Subclass of the RDoc::Markup::ToHtml class that supports looking up method names, classes, etc to create links. RDoc::CrossReference is used to generate those links based on the current context.
Constant Summary collapse
- ALL_CROSSREF_REGEXP =
:stopdoc:
RDoc::CrossReference::ALL_CROSSREF_REGEXP
- CROSSREF_REGEXP =
RDoc::CrossReference::CROSSREF_REGEXP
Constants inherited from ToHtml
RDoc::Markup::ToHtml::HTML_CHARACTER_ALIASES, RDoc::Markup::ToHtml::LIST_TYPE_TO_HTML, RDoc::Markup::ToHtml::TO_HTML_CHARACTERS, RDoc::Markup::ToHtml::URL_CHARACTERS_REGEXP_STR
Constants included from Text
Text::MARKUP_FORMAT, Text::SPACE_SEPARATED_LETTER_CLASS
Instance Attribute Summary collapse
-
#context ⇒ Object
RDoc::CodeObject for generating references.
-
#show_hash ⇒ Object
Should we show ‘#’ characters on method references?.
Attributes inherited from ToHtml
#code_object, #from_path, #in_list_entry, #list, #res
Attributes included from Text
Instance Method Summary collapse
-
#apply_tidylink_label_special_handling(label, url) ⇒ Object
Applies additional special handling on top of the one defined in ToHtml.
-
#cross_reference(name, text = nil, code = true, rdoc_ref: false) ⇒ Object
Creates a link to the reference
nameif the name exists. -
#gen_url(url, text) ⇒ Object
Generates links for
rdoc-ref:scheme URLs and allows RDoc::Markup::ToHtml to handle other schemes. -
#handle_regexp_CROSSREF(name) ⇒ Object
We’re invoked when any text matches the CROSSREF pattern.
-
#handle_regexp_HYPERLINK(url) ⇒ Object
Handles
rdoc-ref:scheme links and allows RDoc::Markup::ToHtml to handle other schemes. -
#handle_regexp_RDOCLINK(url) ⇒ Object
targetis an rdoc-schemed link that will be converted into a hyperlink. - #handle_TT(code) ⇒ Object
-
#init_link_notation_regexp_handlings ⇒ Object
:nodoc:.
-
#initialize(from_path, context, pipe: false, output_decoration: true, hyperlink_all: false, show_hash: false, autolink_excluded_words: [], warn_missing_rdoc_ref: true) ⇒ ToHtmlCrossref
constructor
Creates a new crossref resolver that generates links relative to
contextwhich lives atfrom_pathin the generated files. -
#link(name, html_string, code = true, rdoc_ref: false) ⇒ Object
Creates an HTML link to
namewith the givenhtml_string. -
#tt_cross_reference(code) ⇒ Object
Handles cross-reference and suppressed-crossref inside tt tag.
Methods inherited from ToHtml
#accept_blank_line, #accept_block_quote, #accept_heading, #accept_list_end, #accept_list_item_end, #accept_list_item_start, #accept_list_start, #accept_paragraph, #accept_raw, #accept_rule, #accept_table, #accept_verbatim, #convert_string, #deduplicate_heading_id, #emit_inline, encode_fallback, #end_accepting, #handle_BOLD, #handle_BOLD_WORD, #handle_EM, #handle_EM_WORD, #handle_HARD_BREAK, #handle_PLAIN_TEXT, #handle_RDOCLINK, #handle_REGEXP_HANDLING_TEXT, #handle_STRIKE, #handle_TIDYLINK, #handle_inline, #handle_regexp_HTML_CHARACTERS, #handle_regexp_QUOTE_AFTER_WORD, #handle_regexp_QUOTE_NOT_AFTER_WORD, #handle_regexp_SUPPRESSED_CROSSREF, #html_list_name, #in_tidylink_label?, #init_regexp_handlings, #list_end_for, #list_item_start, #parsable_text_to_html, #parseable?, #start_accepting, #to_html
Methods included from Text
decode_legacy_label, expand_tabs, #flush_left, #markup, #normalize_comment, #parse, #snippet, #strip_hashes, #strip_newlines, #strip_stars, to_anchor, #wrap
Methods inherited from Formatter
#accept_document, #add_regexp_handling_RDOCLINK, #annotate, #apply_regexp_handling, #convert, #convert_string, gen_relative_url, #handle_BOLD, #handle_BOLD_WORD, #handle_EM, #handle_EM_WORD, #handle_HARD_BREAK, #handle_PLAIN_TEXT, #handle_REGEXP_HANDLING_TEXT, #handle_STRIKE, #handle_TEXT, #handle_TIDYLINK, #handle_inline, #ignore, #parse_url, #traverse_inline_nodes, #tt?
Constructor Details
#initialize(from_path, context, pipe: false, output_decoration: true, hyperlink_all: false, show_hash: false, autolink_excluded_words: [], warn_missing_rdoc_ref: true) ⇒ ToHtmlCrossref
Creates a new crossref resolver that generates links relative to context which lives at from_path in the generated files. ‘#’ characters on references are removed unless show_hash is true. Only method names preceded by ‘#’ or ‘::’ are linked, unless hyperlink_all is true.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 30 def initialize(from_path, context, pipe: false, output_decoration: true, hyperlink_all: false, show_hash: false, autolink_excluded_words: [], warn_missing_rdoc_ref: true) raise ArgumentError, 'from_path cannot be nil' if from_path.nil? super(pipe: pipe, output_decoration: output_decoration) @context = context @from_path = from_path @hyperlink_all = hyperlink_all @show_hash = show_hash @autolink_excluded_words = autolink_excluded_words @warn_missing_rdoc_ref = warn_missing_rdoc_ref @cross_reference = RDoc::CrossReference.new @context end |
Instance Attribute Details
#context ⇒ Object
RDoc::CodeObject for generating references
17 18 19 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 17 def context @context end |
#show_hash ⇒ Object
Should we show ‘#’ characters on method references?
22 23 24 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 22 def show_hash @show_hash end |
Instance Method Details
#apply_tidylink_label_special_handling(label, url) ⇒ Object
Applies additional special handling on top of the one defined in ToHtml. When a tidy link is {Foo}[rdoc-ref:Foo], the label part is surrounded by . TODO: reconsider this workaround.
230 231 232 233 234 235 236 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 230 def apply_tidylink_label_special_handling(label, url) if url == "rdoc-ref:#{label}" && cross_reference(label)&.include?('<code>') "<code>#{convert_string(label)}</code>" else super end end |
#cross_reference(name, text = nil, code = true, rdoc_ref: false) ⇒ Object
Creates a link to the reference name if the name exists. If text is given it is used as the link text, otherwise name is used. Returns nil if the link target could not be resolved.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 62 def cross_reference(name, text = nil, code = true, rdoc_ref: false) # Strip '#' for link display text (e.g. #method shows as "method" in links) display = !@show_hash && name.start_with?('#') ? name[1..] : name if !display.end_with?('+@', '-@') && match = display.match(/(.*[^#:])?@(.*)/) context_name = match[1] label = convert_string(RDoc::Text.decode_legacy_label(match[2])) text ||= "#{label} at <code>#{convert_string(context_name)}</code>" if context_name text ||= label code = false else text ||= convert_string(display) end link(name, text, code, rdoc_ref: rdoc_ref) end |
#gen_url(url, text) ⇒ Object
Generates links for rdoc-ref: scheme URLs and allows RDoc::Markup::ToHtml to handle other schemes.
143 144 145 146 147 148 149 150 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 143 def gen_url(url, text) if url =~ /\Ardoc-ref:/ name = $' cross_reference(name, text, name == text, rdoc_ref: true) || text else super end end |
#handle_regexp_CROSSREF(name) ⇒ Object
We’re invoked when any text matches the CROSSREF pattern. If we find the corresponding reference, generate a link. If the name we’re looking for contains no punctuation, we look for it up the module/class chain. For example, ToHtml is found, even without the RDoc::Markup:: prefix, because we look for it in module Markup first.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 86 def handle_regexp_CROSSREF(name) return convert_string(name) if in_tidylink_label? return name if @autolink_excluded_words&.include?(name) return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails unless @hyperlink_all then # This ensures that words entirely consisting of lowercase letters will # not have cross-references generated (to suppress lots of erroneous # cross-references to "new" in text, for instance) return name if name =~ /\A[a-z]*\z/ end cross_reference(name, rdoc_ref: false) || convert_string(name) end |
#handle_regexp_HYPERLINK(url) ⇒ Object
Handles rdoc-ref: scheme links and allows RDoc::Markup::ToHtml to handle other schemes.
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 105 def handle_regexp_HYPERLINK(url) return convert_string(url) if in_tidylink_label? case url when /\Ardoc-ref:/ ref = $' cross_reference(ref, rdoc_ref: true) || convert_string(ref) else super end end |
#handle_regexp_RDOCLINK(url) ⇒ Object
target is an rdoc-schemed link that will be converted into a hyperlink. For the rdoc-ref scheme the cross-reference will be looked up and the given name will be used.
All other contents are handled by the superclass
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 125 def handle_regexp_RDOCLINK(url) case url when /\Ardoc-ref:/ if in_tidylink_label? convert_string(url) else ref = $' cross_reference(ref, rdoc_ref: true) || convert_string(ref) end else super end end |
#handle_TT(code) ⇒ Object
223 224 225 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 223 def handle_TT(code) emit_inline(tt_cross_reference(code) || "<code>#{convert_string(code)}</code>") end |
#init_link_notation_regexp_handlings ⇒ Object
:nodoc:
48 49 50 51 52 53 54 55 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 48 def init_link_notation_regexp_handlings add_regexp_handling_RDOCLINK # The crossref must be linked before tidylink because Klass.method[:sym] # will be processed as a tidylink first and will be broken. crossref_re = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP @markup.add_regexp_handling crossref_re, :CROSSREF end |
#link(name, html_string, code = true, rdoc_ref: false) ⇒ Object
Creates an HTML link to name with the given html_string. html_string should be already escaped and may contain HTML tags. Returns the link HTML string, or nil if the reference could not be resolved.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 157 def link(name, html_string, code = true, rdoc_ref: false) if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/ name = $1 label = $' end ref = @cross_reference.resolve name if name # Non-text source files (C, Ruby, etc.) don't get HTML pages generated, # so don't auto-link to them. Explicit rdoc-ref: links are still allowed. if !rdoc_ref && RDoc::TopLevel === ref && !ref.text? return end if ref path = ref.as_href(@from_path) if code and RDoc::CodeObject === ref and !(RDoc::TopLevel === ref) html_string = "<code>#{html_string}</code>" end elsif name if rdoc_ref && @warn_missing_rdoc_ref puts "#{@from_path}: `rdoc-ref:#{name}` can't be resolved for `#{html_string}`" end return else # A bare label reference like @foo still produces a valid anchor link return unless label path = +"" end if label # Decode legacy labels (e.g., "What-27s+Here" -> "What's Here") # then convert to GitHub-style anchor format decoded_label = RDoc::Text.decode_legacy_label(label) formatted_label = RDoc::Text.to_anchor(decoded_label) # Case 1: Path already has an anchor (e.g., method link) # Input: C1#method@label -> path="C1.html#method-i-m" # Output: C1.html#method-i-m-label if path =~ /#/ path << "-#{formatted_label}" # Case 2: Label matches a section title # Input: C1@Section -> path="C1.html", section "Section" exists # Output: C1.html#section (uses section.aref for GitHub-style) elsif (section = ref&.sections&.find { |s| decoded_label == s.title }) path << "##{section.aref}" # Case 3: Ref has an aref (class/module context) # Input: C1@heading -> path="C1.html", ref=C1 class # Output: C1.html#class-c1-heading elsif ref.respond_to?(:aref) path << "##{ref.aref}-#{formatted_label}" # Case 4: No context, just the label (e.g., TopLevel/file) # Input: README@section -> path="README_md.html" # Output: README_md.html#section else path << "##{formatted_label}" end end "<a href=\"#{path}\">#{html_string}</a>" end |
#tt_cross_reference(code) ⇒ Object
Handles cross-reference and suppressed-crossref inside tt tag. Returns nil if code is not an existing cross-reference nor a suppressed-crossref.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/rdoc/markup/to_html_crossref.rb', line 240 def tt_cross_reference(code) return if in_tidylink_label? crossref_regexp = @hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP # REGEXP sometimes matches a string that starts with a backslash but is not a # suppressed cross-reference (for example, `\+`), so the backslash-removed # part needs to be checked against crossref_regexp. match = crossref_regexp.match(code.delete_prefix('\\')) return unless match && match.begin(1).zero? return unless match.post_match.match?(/\A[[:punct:]\s]*\z/) # cross_reference(file_page) may return a link without code tag. # We need to check it because this method shouldn't return an html text without code tag. if code.start_with?('\\') # Remove leading backslash if crossref exists "<code>#{convert_string(code[1..])}</code>" if cross_reference(code[1..])&.include?('<code>') else html = cross_reference(code) html if html&.include?('<code>') end end |