Class: JsDuck::Inline::Link

Inherits:
Object
  • Object
show all
Defined in:
lib/jsduck/inline/link.rb

Overview

Implementation of inline tag @link

It also takes care of the auto-detection of links in text through the #create_magic_links method.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(link_renderer) ⇒ Link

Returns a new instance of Link.



21
22
23
24
25
26
27
# File 'lib/jsduck/inline/link.rb', line 21

def initialize(link_renderer)
  @class_context = ""
  @doc_context = {}
  @relations = link_renderer.relations
  @renderer = link_renderer
  @re = /\{@link\s+(\S*?)(?:\s+(.+?))?\}/m
end

Instance Attribute Details

#class_contextObject

Sets up instance to work in context of particular class, so that when #blah is encountered it knows that Context#blah is meant.



15
16
17
# File 'lib/jsduck/inline/link.rb', line 15

def class_context
  @class_context
end

#doc_contextObject

Sets up instance to work in context of particular doc object. Used for error reporting.



19
20
21
# File 'lib/jsduck/inline/link.rb', line 19

def doc_context
  @doc_context
end

Instance Method Details

#apply_tpl(target, text, full_link) ⇒ Object

applies the link template



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/jsduck/inline/link.rb', line 43

def apply_tpl(target, text, full_link)
  if target =~ /^(.*)#(static-)?#{MemberRegistry.regex}?(.*)$/
    cls = $1.empty? ? @class_context : $1
    static = $2 ? true : nil
    type = $3 ? $3.intern : nil
    member = $4
  else
    cls = target
    static = nil
    type = false
    member = false
  end

  # Construct link text
  if text
    text = text
  elsif member
    text = (cls == @class_context) ? member : (cls + "." + member)
  else
    text = cls
  end

  if !@relations[cls]
    Logger.warn(:link, "#{full_link} links to non-existing class", @doc_context)
    return text
  elsif member
    ms = @renderer.find_members(cls, {:name => member, :tagname => type, :static => static})
    if ms.length == 0
      Logger.warn(:link, "#{full_link} links to non-existing member", @doc_context)
      return text
    end

    if ms.length > 1
      # When multiple public members, see if there remains just
      # one when we ignore the static members. If there's more,
      # report ambiguity. If there's only static members, also
      # report ambiguity.
      instance_ms = ms.find_all {|m| !m[:static] }
      if instance_ms.length > 1
        alternatives = instance_ms.map {|m| "#{m[:tagname]} in #{m[:owner]}" }.join(", ")
        Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives, @doc_context)
      elsif instance_ms.length == 0
        static_ms = ms.find_all {|m| m[:static] }
        alternatives = static_ms.map {|m| "static " + m[:tagname].to_s }.join(", ")
        Logger.warn(:link_ambiguous, "#{full_link} is ambiguous: "+alternatives, @doc_context)
      end
    end

    return @renderer.link(cls, member, text, type, static)
  else
    return @renderer.link(cls, false, text)
  end
end

#replace(input) ⇒ Object

Takes StringScanner instance.

Looks for inline tag at the current scan pointer position, when found, moves scan pointer forward and performs the apporpriate replacement.



34
35
36
37
38
39
40
# File 'lib/jsduck/inline/link.rb', line 34

def replace(input)
  if input.check(@re)
    input.scan(@re).sub(@re) { apply_tpl($1, $2, $&) }
  else
    false
  end
end