Class: MarkdownIt::RulesBlock::Fence

Inherits:
Object
  • Object
show all
Extended by:
Common::Utils
Defined in:
lib/motion-markdown-it/rules_block/fence.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

Class Method Summary collapse

Methods included from Common::Utils

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

Class Method Details

.fence(state, startLine, endLine, silent) ⇒ Object




9
10
11
12
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
# File 'lib/motion-markdown-it/rules_block/fence.rb', line 9

def self.fence(state, startLine, endLine, silent)
  haveEndMarker = false
  pos           = state.bMarks[startLine] + state.tShift[startLine]
  max           = state.eMarks[startLine]

  # if it's indented more than 3 spaces, it should be a code block
  return false if state.sCount[startLine] - state.blkIndent >= 4

  return false if pos + 3 > max

  marker = state.src.charCodeAt(pos)

  if marker != 0x7E && marker != 0x60 #  != ~ && != `
    return false
  end

  # scan marker length
  mem = pos;
  pos = state.skipChars(pos, marker)
  len = pos - mem

  return false if len < 3

  markup = state.src.slice(mem...pos)
  params = state.src.slice(pos...max)

  return false if params.include?(fromCharCode(marker))

  # Since start is found, we can report success here in validation mode
  return true if silent

  # search end of block
  nextLine = startLine

  while true
    nextLine += 1
    if nextLine >= endLine
      # unclosed block should be autoclosed by end of document.
      # also block seems to be autoclosed by end of parent
      break
    end

    pos = mem = state.bMarks[nextLine] + state.tShift[nextLine]
    max = state.eMarks[nextLine];

    if pos < max && state.sCount[nextLine] < state.blkIndent
      # non-empty line with negative indent should stop the list:
      # - ```
      #  test
      break
    end

    next if state.src.charCodeAt(pos) != marker

    if state.sCount[nextLine] - state.blkIndent >= 4
      # closing fence should be indented less than 4 spaces
      next
    end

    pos = state.skipChars(pos, marker)

    # closing code fence must be at least as long as the opening one
    next if pos - mem < len

    # make sure tail has spaces only
    pos = state.skipSpaces(pos)

    next if pos < max

    haveEndMarker = true
    # found!
    break
  end

  # If a fence has heading spaces, they should be removed from its inner block
  len           = state.sCount[startLine]

  state.line    = nextLine + (haveEndMarker ? 1 : 0)

  token         = state.push('fence', 'code', 0)
  token.info    = params
  token.content = state.getLines(startLine + 1, nextLine, len, true)
  token.markup  = markup
  token.map     = [ startLine, state.line ]

  return true
end