Class: MarkdownIt::RulesBlock::Lheading

Inherits:
Object
  • Object
show all
Extended by:
Common::Utils
Defined in:
lib/motion-markdown-it/rules_block/lheading.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, charCodeAt, escapeHtml, escapeRE, fromCharCode, fromCodePoint, isMdAsciiPunct, isPunctChar, isSpace, isValidEntityCode, isWhiteSpace, normalizeReference, replaceEntityPattern, unescapeAll, unescapeMd

Class Method Details

.lheading(state, startLine, endLine, silent = true) ⇒ 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
# File 'lib/motion-markdown-it/rules_block/lheading.rb', line 9

def self.lheading(state, startLine, endLine, silent = true)
  nextLine        = startLine + 1
  terminatorRules = state.md.block.ruler.getRules('paragraph')

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

  oldParentType     = state.parentType
  state.parentType  = 'paragraph' # use paragraph to match terminatorRules

  # jump line-by-line until empty one or EOF
  while nextLine < endLine && !state.isEmpty(nextLine)
    # this would be a code block normally, but after paragraph
    # it's considered a lazy continuation regardless of what's there
    (nextLine += 1) and next if (state.sCount[nextLine] - state.blkIndent > 3)

    #
    # Check for underline in setext header
    #
    if state.sCount[nextLine] >= state.blkIndent
      pos = state.bMarks[nextLine] + state.tShift[nextLine]
      max = state.eMarks[nextLine]

      if pos < max
        marker = charCodeAt(state.src, pos)

        if marker == 0x2D || marker == 0x3D # - or =
          pos = state.skipChars(pos, marker)
          pos = state.skipSpaces(pos)

          if pos >= max
            level = (marker == 0x3D ? 1 : 2) # =
            break
          end
        end
      end
    end

    # quirk for blockquotes, this line should already be checked by that rule
    (nextLine += 1) and next if state.sCount[nextLine] < 0

    # Some tags can terminate paragraph without empty line.
    terminate = false
    l = terminatorRules.length
    0.upto(l - 1) do |i|
      if terminatorRules[i].call(state, nextLine, endLine, true)
        terminate = true
        break
      end
    end
    break if terminate

    nextLine += 1
  end

  if !level
    # Didn't find valid underline
    return false
  end

  content = state.getLines(startLine, nextLine, state.blkIndent, false).strip

  state.line = nextLine + 1

  token          = state.push('heading_open', "h#{level.to_s}", 1)
  token.markup   = marker.chr
  token.map      = [ startLine, state.line ]

  token          = state.push('inline', '', 0)
  # token.content  = state.src.slice(pos...state.eMarks[startLine]).strip
  token.content  = content
  token.map      = [ startLine, state.line - 1 ]
  token.children = []

  token          = state.push('heading_close', "h#{level.to_s}", -1)
  token.markup   = marker.chr

  state.parentType = oldParentType

  return true
end