1 |
|
2 |
|
3 |
|
4 | const blockNames = require('markdown-it/lib/common/html_blocks')
|
5 | const HTML_OPEN_CLOSE_TAG_RE = require('markdown-it/lib/common/html_re').HTML_OPEN_CLOSE_TAG_RE
|
6 |
|
7 |
|
8 |
|
9 | const HTML_SEQUENCES = [
|
10 | [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
|
11 | [/^<!--/, /-->/, true],
|
12 | [/^<\?/, /\?>/, true],
|
13 | [/^<![A-Z]/, />/, true],
|
14 | [/^<!\[CDATA\[/, /\]\]>/, true],
|
15 |
|
16 | [/^<[A-Z]/, />/, true],
|
17 |
|
18 | [/^<\w+\-/, />/, true],
|
19 | [new RegExp('^</?(' + blockNames.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true],
|
20 | [new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\s*$'), /^$/, false]
|
21 | ]
|
22 |
|
23 | module.exports = md => {
|
24 | md.block.ruler.at('html_block', htmlBlock)
|
25 | }
|
26 |
|
27 | function htmlBlock (state, startLine, endLine, silent) {
|
28 | let i, nextLine, lineText
|
29 | let pos = state.bMarks[startLine] + state.tShift[startLine]
|
30 | let max = state.eMarks[startLine]
|
31 |
|
32 |
|
33 | if (state.sCount[startLine] - state.blkIndent >= 4) { return false }
|
34 |
|
35 | if (!state.md.options.html) { return false }
|
36 |
|
37 | if (state.src.charCodeAt(pos) !== 0x3C) { return false }
|
38 |
|
39 | lineText = state.src.slice(pos, max)
|
40 |
|
41 | for (i = 0; i < HTML_SEQUENCES.length; i++) {
|
42 | if (HTML_SEQUENCES[i][0].test(lineText)) { break }
|
43 | }
|
44 |
|
45 | if (i === HTML_SEQUENCES.length) {
|
46 | return false
|
47 | }
|
48 |
|
49 | if (silent) {
|
50 |
|
51 | return HTML_SEQUENCES[i][2]
|
52 | }
|
53 |
|
54 | nextLine = startLine + 1
|
55 |
|
56 |
|
57 |
|
58 | if (!HTML_SEQUENCES[i][1].test(lineText)) {
|
59 | for (; nextLine < endLine; nextLine++) {
|
60 | if (state.sCount[nextLine] < state.blkIndent) { break }
|
61 |
|
62 | pos = state.bMarks[nextLine] + state.tShift[nextLine]
|
63 | max = state.eMarks[nextLine]
|
64 | lineText = state.src.slice(pos, max)
|
65 |
|
66 | if (HTML_SEQUENCES[i][1].test(lineText)) {
|
67 | if (lineText.length !== 0) { nextLine++ }
|
68 | break
|
69 | }
|
70 | }
|
71 | }
|
72 |
|
73 | state.line = nextLine
|
74 |
|
75 | const token = state.push('html_block', '', 0)
|
76 | token.map = [startLine, nextLine]
|
77 | token.content = state.getLines(startLine, nextLine, state.blkIndent, true)
|
78 |
|
79 | return true
|
80 | }
|