Skip to content

Commit fbbb2a2

Browse files
committed
fix: improve markmap block parsing
1 parent 5c78731 commit fbbb2a2

File tree

1 file changed

+29
-35
lines changed

1 file changed

+29
-35
lines changed

src/markdown-it/markmap.ts

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,56 @@ import type MarkdownIt from 'markdown-it'
99
const transformer = new Transformer()
1010

1111
export function markmap(md: MarkdownIt) {
12-
const MARKMAP_SINGLE_NEWLINE = /((?<!\n)\n)([ \t]*{%\s*markmap\b.*?%}\s*)/g
13-
14-
// Preprocess: ensure each {% markmap %} directive is preceded by an extra newline,
15-
// so that it has a blank line before it and is treated as a block.
12+
// Reset counter before normalize
1613
md.core.ruler.before('normalize', 'markmap_newline', state => {
1714
resetCounter()
18-
state.src = state.src.replace(
19-
MARKMAP_SINGLE_NEWLINE,
20-
'$1\n$2'
21-
)
2215
})
2316

2417
// Add markmap block rule
25-
md.block.ruler.before('fence', 'markmap', (state, startLine, endLine) => {
26-
const startLineText = state.src.slice(state.bMarks[startLine], state.eMarks[startLine]).trim()
27-
const match = startLineText.match(MARKMAP_OPEN_RE)
18+
md.block.ruler.before('fence', 'markmap', (state, startLine, endLine, silent) => {
19+
let pos = state.bMarks[startLine] + state.tShift[startLine]
20+
let max = state.eMarks[startLine]
2821

29-
if (!match) return false
22+
if (pos >= max) return false
3023

31-
const height: string | undefined = match[1]
32-
let nextLine = startLine + 1
24+
const line = state.src.slice(pos, max).trim()
3325

26+
const match = line.match(MARKMAP_OPEN_RE)
3427

35-
// Find {% endmarkmap %}
36-
while (nextLine < endLine) {
37-
if (state.src.slice(state.bMarks[nextLine], state.eMarks[nextLine]).trim() === MARKMAP_CLOSE) {
38-
state.line = nextLine + 1
39-
40-
const openToken = state.push('markmap_open', 'div', 1)
41-
openToken.block = true
42-
openToken.markup = match[0]
28+
if (!match) return false
4329

44-
const contentToken = state.push('markmap_content', '', 0)
45-
contentToken.content = state.getLines(startLine + 1, nextLine, 0, false)
46-
contentToken.meta = { height }
30+
if (silent) return true
4731

32+
const height: string | undefined = match[1]
33+
let nextLine = startLine
34+
let haveEndMarker = false
4835

49-
const closeToken = state.push('markmap_close', 'div', -1)
50-
closeToken.block = true
51-
closeToken.markup = MARKMAP_CLOSE
36+
while (nextLine < endLine) {
37+
pos = state.bMarks[nextLine] + state.tShift[nextLine]
38+
max = state.eMarks[nextLine]
5239

53-
return true
40+
if (pos < max && state.src.slice(pos, max).trim() === MARKMAP_CLOSE) {
41+
haveEndMarker = true
42+
break
5443
}
44+
5545
nextLine++
5646
}
5747

58-
return false
48+
state.line = nextLine + (haveEndMarker ? 1 : 0)
49+
50+
const token = state.push('markmap', 'div', 0)
51+
token.meta = { height }
52+
token.content = state.getLines(startLine + 1, nextLine, state.sCount[startLine], true)
53+
token.markup = '{% markmap %}'
54+
token.map = [startLine, state.line]
55+
56+
return true
5957
}, {
6058
alt: ['paragraph', 'reference', 'blockquote', 'list'],
6159
})
6260

63-
md.renderer.rules.markmap_open = () => ``
64-
65-
md.renderer.rules.markmap_content = (tokens, idx) => {
61+
md.renderer.rules.markmap = (tokens, idx) => {
6662
// parse content
6763
const _content = tokens[idx].content
6864
const height: string | undefined = tokens[idx].meta?.height
@@ -79,6 +75,4 @@ export function markmap(md: MarkdownIt) {
7975

8076
return `${wrapHTML}\n${styleHTML}`
8177
}
82-
83-
md.renderer.rules.markmap_close = () => ``
8478
}

0 commit comments

Comments
 (0)