Class: RDoc::CrossReference
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/rdoc/cross_reference.rb |
Overview
CrossReference is a reusable way to create cross references for names.
Constant Summary
-
ALL_CROSSREF_REGEXP =
# File 'lib/rdoc/cross_reference.rb', line 92
Version of CROSSREF_REGEXP used when --hyperlink-all is specified.
/ (?:^|[\s()]) ( (?: # A::B::C.meth #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} # A::B::C | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) # Stand-alone method | \\?#{METHOD_REGEXP_STR} # Things that look like filenames | (?:\.\.\/)*[-\/\w][_\/.][-\w\/.] # Things that have markup suppressed | \\[^\s<] ) # labels for headings (?:@[\w%-])? )/x -
CLASS_REGEXP_STR =
# File 'lib/rdoc/cross_reference.rb', line 16
Regular expression to match class references
- There can be a '\' in front of text to suppress the cross-reference
- There can be a '::' in front of class names to reference from the top-level namespace.
- The method can be followed by parenthesis (not recommended)
'\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)' -
CROSSREF_REGEXP =
# File 'lib/rdoc/cross_reference.rb', line 45
Regular expressions matching text that should potentially have cross-reference links generated are passed to add_regexp_handling. Note that these expressions are meant to pick up text for which cross-references have been suppressed, since the suppression characters are removed by the code that is triggered.
/(?:^|[\s()]) ( (?: # A::B::C.meth #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} # A::B::C # The stuff after CLASS_REGEXP_STR is a # nasty hack. CLASS_REGEXP_STR unfortunately matches # words like dog and cat (these are legal "class" # names in Fortran 95). When a word is flagged as a # potential cross-reference, limitations in the markup # engine suppress other processing, such as typesetting. # This is particularly noticeable for contractions. # In order that words like "can't" not # be flagged as potential cross-references, only # flag potential class cross-references if the character # after the cross-reference is a space, sentence # punctuation, tag start character, or attribute # marker. | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) # Stand-alone method (preceded by a #) | \\?\##{METHOD_REGEXP_STR} # Stand-alone method (preceded by ::) | ::#{METHOD_REGEXP_STR} # Things that look like filenames # The key thing is that there must be at least # one special character (period, slash, or # underscore). | (?:\.\.\/)*[-\/\w][_\/.][-\w\/.] # Things that have markup suppressed # Don't process things like '\<' in \<tt>, though. # TODO: including < is a hack, not very satisfying. | \\[^\s<] ) # labels for headings (?:@[\w%-](?:\.[\w|%-]+)?)? )/x -
METHOD_ARGS_REGEXP_STR =
# File 'lib/rdoc/cross_reference.rb', line 26
Regular expression to match method arguments.
/(?:\((?:#{METHOD_ARG_REGEXP_STR}(?:,\s*#{METHOD_ARG_REGEXP_STR})*)?\))?/.source
-
METHOD_ARG_REGEXP_STR =
# File 'lib/rdoc/cross_reference.rb', line 21
Regular expression to match a single method argument.
'[\w.*/=<>-]' -
METHOD_REGEXP_STR =
# File 'lib/rdoc/cross_reference.rb', line 33
Regular expression to match method references.
See CLASS_REGEXP_STR
/( (?!\d)[\w]+[!?=]?| %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~] )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze
Class Method Summary
-
.new(context) ⇒ CrossReference
constructor
Allows cross-references to be created based on the given
context(RDoc::Context).
Instance Attribute Summary
-
#seen
rw
Hash of references that have been looked-up to their replacements.
Instance Method Summary
-
#resolve(name)
Returns a reference to
name. -
#resolve_local_symbol(name)
Returns a method, attribute or constant reference to
nameif it exists in the containing context object.
Constructor Details
.new(context) ⇒ CrossReference
Allows cross-references to be created based on the given context
(RDoc::Context).
# File 'lib/rdoc/cross_reference.rb', line 125
def initialize(context) @context = context @store = context.store @seen = {} end
Instance Attribute Details
#seen (rw)
Hash of references that have been looked-up to their replacements
# File 'lib/rdoc/cross_reference.rb', line 119
attr_accessor :seen
Instance Method Details
#resolve(name)
Returns a reference to name.
If the reference is found and name is not documented nil will be
returned. If name is not found nil is returned.
# File 'lib/rdoc/cross_reference.rb', line 196
def resolve(name) return @seen[name] if @seen.include? name ref = @context.find_symbol name ref = resolve_local_symbol name unless ref # Try a page name ref = @store.page name if not ref and name =~ /^[\w.\/]+$/ ref = nil if RDoc::Alias === ref # external alias, can't link to it ref = nil unless ref&.display? @seen[name] = ref ref end
#resolve_local_symbol(name)
Returns a method, attribute or constant reference to name
if it exists in the containing context object. It returns
nil otherwise.
For example, this method would decompose name = 'A::CONSTANT' into a container object A and a symbol 'CONSTANT', and it would try to find 'CONSTANT' in A.
# File 'lib/rdoc/cross_reference.rb', line 141
def resolve_local_symbol(name) ref = nil type = nil container = nil case name when /#{CLASS_REGEXP_STR}::([A-Z]\w*)\z/o then symbol = $2 container = @context.find_symbol_module($1) when /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o then type = $2 if '.' == type # will find either #method or ::method symbol = $3 else symbol = "#{type}#{$3}" end container = @context.find_symbol_module($1) when /^([.#]|::)#{METHOD_REGEXP_STR}/o then type = $1 if '.' == type symbol = $2 else symbol = "#{type}#{$2}" end container = @context end if container then unless RDoc::TopLevel === container then if '.' == type then if 'new' == symbol then # AnyClassName.new will be class method ref = container.find_local_symbol symbol ref = container.find_ancestor_local_symbol symbol unless ref else ref = container.find_local_symbol "::#{symbol}" ref = container.find_ancestor_local_symbol "::#{symbol}" unless ref ref = container.find_local_symbol "##{symbol}" unless ref ref = container.find_ancestor_local_symbol "##{symbol}" unless ref end else ref = container.find_local_symbol symbol ref = container.find_ancestor_local_symbol symbol unless ref end end end ref end