1 require 'rdoc/markup/to_html'
4 # Subclass of the RDoc::Markup::ToHtml class that supports looking up words in
5 # the AllReferences list. Those that are found (like AllReferences in this
6 # comment) will be hyperlinked
8 class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml
10 attr_accessor :context
13 # We need to record the html path of our caller so we can generate
14 # correct relative paths for any hyperlinks that we find
16 def initialize(from_path, context, show_hash)
17 raise ArgumentError, 'from_path cannot be nil' if from_path.nil?
20 # class names, variable names, or instance variables
21 @markup.add_special(/(
22 # A::B.meth(**) (for operator in Fortran95)
23 \w+(::\w+)*[.\#]\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?
24 # meth(**) (for operator in Fortran95)
25 | \#\w+(\([.\w\*\/\+\-\=\<\>]+\))?
26 | \b([A-Z]\w*(::\w+)*[.\#]\w+) # A::B.meth
27 | \b([A-Z]\w+(::\w+)*) # A::B
28 | \#\w+[!?=]? # #meth_name
29 | \\?\b\w+([_\/\.]+\w+)*[!?=]? # meth_name
33 @from_path = from_path
35 @show_hash = show_hash
41 # We're invoked when any text matches the CROSSREF pattern
42 # (defined in MarkUp). If we fine the corresponding reference,
43 # generate a hyperlink. If the name we're looking for contains
44 # no punctuation, we look for it up the module/class chain. For
45 # example, HyperlinkHtml is found, even without the Generator::
46 # prefix, because we look for it in module Generator first.
48 def handle_special_CROSSREF(special)
51 return name if name =~ /\A[a-z]*\z/
53 return @seen[name] if @seen.include? name
55 if name[0, 1] == '#' then
57 name = lookup unless @show_hash
63 # Find class, module, or method in class or module.
65 # Do not, however, use an if/elsif/else chain to do so. Instead, test
66 # each possible pattern until one matches. The reason for this is that a
67 # string like "YAML.txt" could be the txt() class method of class YAML (in
68 # which case it would match the first pattern, which splits the string
69 # into container and method components and looks up both) or a filename
70 # (in which case it would match the last pattern, which just checks
71 # whether the string as a whole is a known symbol).
73 if /([A-Z][\w:]*)[.\#](\w+[!?=]?)/ =~ lookup then
76 ref = @context.find_symbol container, method
80 /([A-Za-z][\w:]*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup then
83 ref = @context.find_symbol container, method
86 ref = @context.find_symbol lookup unless ref
88 out = if lookup =~ /^\\/ then
90 elsif ref and ref.document_self then
91 "<a href=\"#{ref.as_href(@from_path)}\">#{name}</a>"