123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- // HTML block
- import block_names from '../common/html_blocks.mjs'
- import { HTML_OPEN_CLOSE_TAG_RE } from '../common/html_re.mjs'
- // An array of opening and corresponding closing sequences for html tags,
- // last argument defines whether it can terminate a paragraph or not
- //
- const HTML_SEQUENCES = [
- [/^<(script|pre|style|textarea)(?=(\s|>|$))/i, /<\/(script|pre|style|textarea)>/i, true],
- [/^<!--/, /-->/, true],
- [/^<\?/, /\?>/, true],
- [/^<![A-Z]/, />/, true],
- [/^<!\[CDATA\[/, /\]\]>/, true],
- [new RegExp('^</?(' + block_names.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true],
- [new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + '\\s*$'), /^$/, false]
- ]
- export default function html_block (state, startLine, endLine, silent) {
- let pos = state.bMarks[startLine] + state.tShift[startLine]
- let max = state.eMarks[startLine]
- // if it's indented more than 3 spaces, it should be a code block
- if (state.sCount[startLine] - state.blkIndent >= 4) { return false }
- if (!state.md.options.html) { return false }
- if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false }
- let lineText = state.src.slice(pos, max)
- let i = 0
- for (; i < HTML_SEQUENCES.length; i++) {
- if (HTML_SEQUENCES[i][0].test(lineText)) { break }
- }
- if (i === HTML_SEQUENCES.length) { return false }
- if (silent) {
- // true if this sequence can be a terminator, false otherwise
- return HTML_SEQUENCES[i][2]
- }
- let nextLine = startLine + 1
- // If we are here - we detected HTML block.
- // Let's roll down till block end.
- if (!HTML_SEQUENCES[i][1].test(lineText)) {
- for (; nextLine < endLine; nextLine++) {
- if (state.sCount[nextLine] < state.blkIndent) { break }
- pos = state.bMarks[nextLine] + state.tShift[nextLine]
- max = state.eMarks[nextLine]
- lineText = state.src.slice(pos, max)
- if (HTML_SEQUENCES[i][1].test(lineText)) {
- if (lineText.length !== 0) { nextLine++ }
- break
- }
- }
- }
- state.line = nextLine
- const token = state.push('html_block', '', 0)
- token.map = [startLine, nextLine]
- token.content = state.getLines(startLine, nextLine, state.blkIndent, true)
- return true
- }
|