mirror of https://github.com/vuejs/vitepress
fix(markdown): entities and escapes not working properly (#3882)
parent
99c0cece62
commit
d5dbd704ce
@ -1,11 +1,53 @@
|
||||
import type MarkdownIt from 'markdown-it'
|
||||
import type StateCore from 'markdown-it/lib/rules_core/state_core.mjs'
|
||||
import type Token from 'markdown-it/lib/token.mjs'
|
||||
|
||||
export function restoreEntities(md: MarkdownIt): void {
|
||||
md.core.ruler.disable('text_join')
|
||||
md.renderer.rules.text_special = (tokens, idx) => {
|
||||
if (tokens[idx].info === 'entity') {
|
||||
return tokens[idx].markup // leave as is so Vue can handle it
|
||||
}
|
||||
return md.utils.escapeHtml(tokens[idx].content)
|
||||
md.core.ruler.at('text_join', text_join)
|
||||
md.renderer.rules.text = (tokens, idx) => escapeHtml(tokens[idx].content)
|
||||
}
|
||||
|
||||
function text_join(state: StateCore): void {
|
||||
let curr, last
|
||||
const blockTokens = state.tokens
|
||||
const l = blockTokens.length
|
||||
|
||||
for (let j = 0; j < l; ++j) {
|
||||
if (blockTokens[j].type !== 'inline') continue
|
||||
|
||||
const tokens = blockTokens[j].children || []
|
||||
const max = tokens.length
|
||||
|
||||
for (curr = 0; curr < max; ++curr)
|
||||
if (tokens[curr].type === 'text_special') tokens[curr].type = 'text'
|
||||
|
||||
for (curr = last = 0; curr < max; ++curr)
|
||||
if (
|
||||
tokens[curr].type === 'text' &&
|
||||
curr + 1 < max &&
|
||||
tokens[curr + 1].type === 'text'
|
||||
) {
|
||||
tokens[curr + 1].content =
|
||||
getContent(tokens[curr]) + getContent(tokens[curr + 1])
|
||||
tokens[curr + 1].info = ''
|
||||
tokens[curr + 1].markup = ''
|
||||
} else {
|
||||
if (curr !== last) tokens[last] = tokens[curr]
|
||||
++last
|
||||
}
|
||||
|
||||
if (curr !== last) tokens.length = last
|
||||
}
|
||||
}
|
||||
|
||||
function getContent(token: Token): string {
|
||||
return token.info === 'entity'
|
||||
? token.markup
|
||||
: token.info === 'escape' && token.content === '&'
|
||||
? '&'
|
||||
: token.content
|
||||
}
|
||||
|
||||
function escapeHtml(str: string): string {
|
||||
return str.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
||||
}
|
||||
|
Loading…
Reference in new issue