Class: MarkdownIt::RulesBlock::StateBlock

Inherits:
Object
  • Object
show all
Includes:
Common::Utils
Defined in:
lib/motion-markdown-it/rules_block/state_block.rb

Constant Summary

Constants included from Common::Utils

Common::Utils::DIGITAL_ENTITY_TEST_RE, Common::Utils::ENTITY_RE, Common::Utils::HTML_ESCAPE_REPLACE_RE, Common::Utils::HTML_ESCAPE_TEST_RE, Common::Utils::HTML_REPLACEMENTS, Common::Utils::REGEXP_ESCAPE_RE, Common::Utils::UNESCAPE_ALL_RE, Common::Utils::UNESCAPE_MD_RE, Common::Utils::UNICODE_PUNCT_RE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Common::Utils

#arrayReplaceAt, #assign, #charCodeAt, #escapeHtml, #escapeRE, #fromCharCode, #fromCodePoint, #isMdAsciiPunct, #isPunctChar, #isSpace, #isValidEntityCode, #isWhiteSpace, #normalizeReference, #replaceEntityPattern, #unescapeAll, #unescapeMd

Constructor Details

#initialize(src, md, env, tokens) ⇒ StateBlock




13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 13

def initialize(src, md, env, tokens)
  @src = src

  # link to parser instance
  @md  = md
  @env = env

  #--- Internal state variables

  @tokens = tokens

  @bMarks = []  # line begin offsets for fast jumps
  @eMarks = []  # line end offsets for fast jumps
  @tShift = []  # offsets of the first non-space characters (tabs not expanded)
  @sCount = []  # indents for each line (tabs expanded)

  # An amount of virtual spaces (tabs expanded) between beginning
  # of each line (bMarks) and real beginning of that line.
  #
  # It exists only as a hack because blockquotes override bMarks
  # losing information in the process.
  #
  # It's used only when expanding tabs, you can think about it as
  # an initial tab length, e.g. bsCount=21 applied to string `\t123`
  # means first tab should be expanded to 4-21%4 === 3 spaces.
  #
  @bsCount    = []

  # block parser variables
  @blkIndent  = 0       # equired block content indent (for example, if we are
                        # inside a list, it would be positioned after list marker)
  @line       = 0       # line index in src
  @lineMax    = 0       # lines count
  @tight      = false   # loose/tight mode for lists
  @parentType = 'root'  # if `list`, block parser stops on two newlines
  @ddIndent   = -1      # indent of the current dd block (-1 if there isn't any)
  @listIndent = -1      # indent of the current list block (-1 if there isn't any)

  # can be 'blockquote', 'list', 'root', 'paragraph' or 'reference'
  # used in lists to determine if they interrupt a paragraph
  @parentType = 'root'

  @level = 0

  # renderer
  @result = ''

  # Create caches
  # Generate markers.
  s            = @src
  indent_found = false

  start = pos = indent = offset = 0
  len = s.length
  while pos < len
    ch = charCodeAt(s, pos)

    if !indent_found
      if isSpace(ch)
        indent += 1

        if ch == 0x09
          offset += 4 - offset % 4
        else
          offset += 1
        end
        (pos += 1) and next
      else
        indent_found = true
      end
    end

    if ch == 0x0A || pos == (len - 1)
      pos += 1 if ch != 0x0A
      @bMarks.push(start)
      @eMarks.push(pos)
      @tShift.push(indent)
      @sCount.push(offset)
      @bsCount.push(0)

      indent_found = false
      indent       = 0
      offset       = 0
      start        = pos + 1
    end

    pos += 1
  end

  # Push fake entry to simplify cache bounds checks
  @bMarks.push(s.length)
  @eMarks.push(s.length)
  @tShift.push(0)
  @sCount.push(0)
  @bsCount.push(0)

  @lineMax = @bMarks.length - 1 # don't count last fake line
end

Instance Attribute Details

#blkIndentObject

Returns the value of attribute blkIndent.



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

def blkIndent
  @blkIndent
end

#bMarksObject

Returns the value of attribute bMarks.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def bMarks
  @bMarks
end

#bsCountObject

Returns the value of attribute bsCount.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def bsCount
  @bsCount
end

#ddIndentObject

Returns the value of attribute ddIndent.



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

def ddIndent
  @ddIndent
end

#eMarksObject

Returns the value of attribute eMarks.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def eMarks
  @eMarks
end

#envObject

Returns the value of attribute env.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def env
  @env
end

#levelObject

Returns the value of attribute level.



10
11
12
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 10

def level
  @level
end

#lineObject

Returns the value of attribute line.



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

def line
  @line
end

#lineMaxObject

Returns the value of attribute lineMax.



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

def lineMax
  @lineMax
end

#listIndentObject

Returns the value of attribute listIndent.



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

def listIndent
  @listIndent
end

#mdObject

Returns the value of attribute md.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def md
  @md
end

#parentTypeObject

Returns the value of attribute parentType.



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

def parentType
  @parentType
end

#resultObject

Returns the value of attribute result.



10
11
12
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 10

def result
  @result
end

#sCountObject

Returns the value of attribute sCount.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def sCount
  @sCount
end

#srcObject

Returns the value of attribute src.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def src
  @src
end

#tightObject

Returns the value of attribute tight.



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

def tight
  @tight
end

#tokensObject

Returns the value of attribute tokens.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def tokens
  @tokens
end

#tShiftObject

Returns the value of attribute tShift.



8
9
10
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 8

def tShift
  @tShift
end

Instance Method Details

#getLines(line_begin, line_end, indent, keepLastLF) ⇒ Object

cut lines range from source.




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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 187

def getLines(line_begin, line_end, indent, keepLastLF)
  line = line_begin

  return '' if line_begin >= line_end

  queue = Array.new(line_end - line_begin)

  i = 0
  while line < line_end
    lineIndent = 0
    lineStart = first = @bMarks[line]

    if line + 1 < line_end || keepLastLF
      # No need for bounds check because we have fake entry on tail.
      last = @eMarks[line] + 1
    else
      last = @eMarks[line]
    end

    while first < last && lineIndent < indent
      ch = charCodeAt(@src, first)

      if isSpace(ch)
        if ch === 0x09
          lineIndent += 4 - (lineIndent + @bsCount[line]) % 4
        else
          lineIndent += 1
        end
      elsif first - lineStart < @tShift[line]
        # patched tShift masked characters to look like spaces (blockquotes, list markers)
        lineIndent += 1
      else
        break
      end

      first += 1
    end

    if lineIndent > indent
      # partially expanding tabs in code blocks, e.g '\t\tfoobar'
      # with indent=2 becomes '  \tfoobar'
      queue[i] = (' ' * (lineIndent - indent)) + @src.slice(first...last)
    else
      queue[i] = @src.slice(first...last)
    end
    line += 1
    i    += 1
  end

  return queue.join('')
end

#isEmpty(line) ⇒ Object




127
128
129
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 127

def isEmpty(line)
  return @bMarks[line] + @tShift[line] >= @eMarks[line]
end

#push(type, tag, nesting) ⇒ Object

Push new token to “stream”.




114
115
116
117
118
119
120
121
122
123
124
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 114

def push(type, tag, nesting)
  token       = Token.new(type, tag, nesting)
  token.block = true

  @level -= 1 if nesting < 0 # closing tag
  token.level = @level
  @level += 1 if nesting > 0 # opening tag

  @tokens.push(token)
  return token
end

#skipChars(pos, code) ⇒ Object

Skip char codes from given position




165
166
167
168
169
170
171
172
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 165

def skipChars(pos, code)
  max = @src.length
  while pos < max
    break if (charCodeAt(@src, pos) != code)
    pos += 1
  end
  return pos
end

#skipCharsBack(pos, code, min) ⇒ Object

Skip char codes reverse from given position - 1




176
177
178
179
180
181
182
183
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 176

def skipCharsBack(pos, code, min)
  return pos if pos <= min

  while (pos > min)
    return (pos + 1) if code != charCodeAt(@src, pos -= 1)
  end
  return pos
end

#skipEmptyLines(from) ⇒ Object




132
133
134
135
136
137
138
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 132

def skipEmptyLines(from)
  while from < @lineMax
    break if (@bMarks[from] + @tShift[from] < @eMarks[from])
    from += 1
  end
  return from
end

#skipSpaces(pos) ⇒ Object

Skip spaces from given position.




142
143
144
145
146
147
148
149
150
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 142

def skipSpaces(pos)
  max = @src.length
  while pos < max
    ch = charCodeAt(@src, pos)
    break if !isSpace(ch)
    pos += 1
  end
  return pos
end

#skipSpacesBack(pos, min) ⇒ Object

Skip spaces from given position in reverse.




154
155
156
157
158
159
160
161
# File 'lib/motion-markdown-it/rules_block/state_block.rb', line 154

def skipSpacesBack(pos, min)
  return pos if pos <= min

  while (pos > min)
    return pos + 1 if !isSpace(charCodeAt(@src, pos -= 1))
  end
  return pos
end