summaryrefslogtreecommitdiff
path: root/packages/markdown-it-14.1.0/lib/rules_block/fence.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/markdown-it-14.1.0/lib/rules_block/fence.mjs')
-rw-r--r--packages/markdown-it-14.1.0/lib/rules_block/fence.mjs94
1 files changed, 94 insertions, 0 deletions
diff --git a/packages/markdown-it-14.1.0/lib/rules_block/fence.mjs b/packages/markdown-it-14.1.0/lib/rules_block/fence.mjs
new file mode 100644
index 0000000..930f7b3
--- /dev/null
+++ b/packages/markdown-it-14.1.0/lib/rules_block/fence.mjs
@@ -0,0 +1,94 @@
+// fences (``` lang, ~~~ lang)
+
+export default function fence (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 (pos + 3 > max) { return false }
+
+ const marker = state.src.charCodeAt(pos)
+
+ if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) {
+ return false
+ }
+
+ // scan marker length
+ let mem = pos
+ pos = state.skipChars(pos, marker)
+
+ let len = pos - mem
+
+ if (len < 3) { return false }
+
+ const markup = state.src.slice(mem, pos)
+ const params = state.src.slice(pos, max)
+
+ if (marker === 0x60 /* ` */) {
+ if (params.indexOf(String.fromCharCode(marker)) >= 0) {
+ return false
+ }
+ }
+
+ // Since start is found, we can report success here in validation mode
+ if (silent) { return true }
+
+ // search end of block
+ let nextLine = startLine
+ let haveEndMarker = false
+
+ for (;;) {
+ nextLine++
+ if (nextLine >= endLine) {
+ // unclosed block should be autoclosed by end of document.
+ // also block seems to be autoclosed by end of parent
+ break
+ }
+
+ 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
+ }
+
+ if (state.src.charCodeAt(pos) !== marker) { continue }
+
+ if (state.sCount[nextLine] - state.blkIndent >= 4) {
+ // closing fence should be indented less than 4 spaces
+ continue
+ }
+
+ pos = state.skipChars(pos, marker)
+
+ // closing code fence must be at least as long as the opening one
+ if (pos - mem < len) { continue }
+
+ // make sure tail has spaces only
+ pos = state.skipSpaces(pos)
+
+ if (pos < max) { continue }
+
+ haveEndMarker = true
+ // found!
+ break
+ }
+
+ // If a fence has heading spaces, they should be removed from its inner block
+ len = state.sCount[startLine]
+
+ state.line = nextLine + (haveEndMarker ? 1 : 0)
+
+ const 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
+}