Class: MarkdownIt::ParserInline

Inherits:
Object
  • Object
show all
Defined in:
lib/motion-markdown-it/parser_inline.rb

Constant Summary collapse

RULES =

Parser rules

[
  [ 'text',            lambda { |state, startLine| RulesInline::Text.text(state, startLine) } ],
  [ 'linkify',         lambda { |state, silent| RulesInline::Linkify.linkify(state, silent) } ],
  [ 'newline',         lambda { |state, startLine| RulesInline::Newline.newline(state, startLine) } ],
  [ 'escape',          lambda { |state, startLine| RulesInline::Escape.escape(state, startLine) } ],
  [ 'backticks',       lambda { |state, startLine| RulesInline::Backticks.backtick(state, startLine) } ],
  [ 'strikethrough',   lambda { |state, silent|    RulesInline::Strikethrough.tokenize(state, silent) } ],
  [ 'emphasis',        lambda { |state, silent|    RulesInline::Emphasis.tokenize(state, silent) } ],
  [ 'link',            lambda { |state, startLine| RulesInline::Link.link(state, startLine) } ],
  [ 'image',           lambda { |state, startLine| RulesInline::Image.image(state, startLine) } ],
  [ 'autolink',        lambda { |state, startLine| RulesInline::Autolink.autolink(state, startLine) } ],
  [ 'html_inline',     lambda { |state, startLine| RulesInline::HtmlInline.html_inline(state, startLine) } ],
  [ 'entity',          lambda { |state, startLine| RulesInline::Entity.entity(state, startLine) } ],
]
RULES2 =

rule2 ruleset was created specifically for emphasis/strikethrough post-processing and may be changed in the future.

Don’t use this for anything except pairs (plugins working with balance_pairs).

[
  [ 'balance_pairs',   lambda { |state| RulesInline::BalancePairs.link_pairs(state) } ],
  [ 'strikethrough',   lambda { |state| RulesInline::Strikethrough.postProcess(state) } ],
  [ 'emphasis',        lambda { |state| RulesInline::Emphasis.postProcess(state) } ],
  # [ 'text_collapse',   lambda { |state| RulesInline::TextCollapse.text_collapse(state) } ]
  # rules for pairs separate '**' into its own text tokens, which may be left unused,
  # rule below merges unused segments back with the rest of the text
  [ 'fragments_join',  lambda { |state| RulesInline::FragmentsJoin.fragments_join(state) } ]
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParserInline




45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/motion-markdown-it/parser_inline.rb', line 45

def initialize
  # ParserInline#ruler -> Ruler
  #
  # [[Ruler]] instance. Keep configuration of inline rules.
  @ruler = Ruler.new

  RULES.each do |rule|
    @ruler.push(rule[0], rule[1])
  end

  # ParserInline#ruler2 -> Ruler
  #
  # [[Ruler]] instance. Second ruler used for post-processing
  # (e.g. in emphasis-like rules).
  @ruler2 = Ruler.new

  RULES2.each do |rule|
    @ruler2.push(rule[0], rule[1])
  end
end

Instance Attribute Details

#rulerObject

Returns the value of attribute ruler.



9
10
11
# File 'lib/motion-markdown-it/parser_inline.rb', line 9

def ruler
  @ruler
end

#ruler2Object

Returns the value of attribute ruler2.



9
10
11
# File 'lib/motion-markdown-it/parser_inline.rb', line 9

def ruler2
  @ruler2
end

Instance Method Details

#parse(str, md, env, outTokens) ⇒ Object

ParserInline.parse(str, md, env, outTokens)

Process input string and push inline tokens into outTokens




153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/motion-markdown-it/parser_inline.rb', line 153

def parse(str, md, env, outTokens)
  state = RulesInline::StateInline.new(str, md, env, outTokens)

  tokenize(state)

  rules = @ruler2.getRules('')
  len = rules.length

  0.upto(len - 1) do |i|
    rules[i].call(state)
  end
end

#skipToken(state) ⇒ Object

Skip single token by running all rules in validation mode; returns true if any rule reported success




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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/motion-markdown-it/parser_inline.rb', line 69

def skipToken(state)
  pos        = state.pos
  rules      = @ruler.getRules('')
  len        = rules.length
  maxNesting = state.md.options[:maxNesting]
  cache      = state.cache
  ok         = false

  if cache[pos] != nil
    state.pos = cache[pos]
    return
  end

  if state.level < maxNesting
    0.upto(len -1) do |i|
      # Increment state.level and decrement it later to limit recursion.
      # It's harmless to do here, because no tokens are created. But ideally,
      # we'd need a separate private state variable for this purpose.
      state.level += 1
      ok = rules[i].call(state, true)
      state.level -= 1

      break if ok
    end
  else
    # Too much nesting, just skip until the end of the paragraph.
    #
    # NOTE: this will cause links to behave incorrectly in the following case,
    #       when an amount of `[` is exactly equal to `maxNesting + 1`:
    #
    #       [[[[[[[[[[[[[[[[[[[[[foo]()
    #
    # TODO: remove this workaround when CM standard will allow nested links
    #       (we can replace it by preventing links from being parsed in
    #       validation mode)
    state.pos = state.posMax
  end

  state.pos += 1 if !ok
  cache[pos] = state.pos
end

#tokenize(state) ⇒ Object

Generate tokens for input range




113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/motion-markdown-it/parser_inline.rb', line 113

def tokenize(state)
  rules      = @ruler.getRules('')
  len        = rules.length
  end_pos    = state.posMax
  maxNesting = state.md.options[:maxNesting]

  while state.pos < end_pos
    # Try all possible rules.
    # On success, rule should:
    #
    # - update `state.pos`
    # - update `state.tokens`
    # - return true

    ok = false
    if state.level < maxNesting
      0.upto(len - 1) do |i|
        ok = rules[i].call(state, false)
        break if ok
      end
    end

    if ok
      break if state.pos >= end_pos
      next
    end

    state.pending += state.src[state.pos]
    state.pos     += 1
  end

  unless state.pending.empty?
    state.pushPending
  end
end