返回
markdown-it源码分析5-ParserInline
前端
2024-02-12 21:21:20
markdown-it源码分析5-ParserInline
我们从上一节得知,markdown-it先经过ParserCore
的处理之后,会生成type
为inline
的token
。接下来,我们就开始进入ParserInline
解析器了。ParserInline
的代码如下:
ParserInline.prototype.parse = function(str, start, end, loose) {
var state = this.state
var Pos = this.Pos
var relStart = start + 1
var pos = relStart
var max = end
var esc = 0
var ch
var match
var len
var fence = 0
var bracket = 0
var token
if (this.options.disable.length) {
loop: while (pos < max) {
ch = str.charCodeAt(pos)
for (var i = 0; i < this.options.disable.length; i++) {
if (this.options.disable[i].test(String.fromCharCode(ch))) {
pos++
continue loop
}
}
break
}
}
while (pos < max) {
ch = str.charCodeAt(pos)
if (this.options.extensions && this.options.extensions.inline) {
// extensions can add additional characters
var hooks = this.options.extensions.inline.map(function (ext) {
return ext.regex
})
var m = matchHook(str, hooks, pos, loose)
if (m) {
fence = 0
match = m.match
len = match[0].length
pos += len
ch = str.charCodeAt(pos)
if (ch !== 0) {
// fence/open-bracket/close-bracket
if (ch === 126 || ch === 96 || ch === 42) {
pos += len - 1
continue
}
if (ch === 91) {
bracket++
} else if (ch === 93) {
if (bracket) { bracket-- } else {
pos += len - 1
continue
}
}
if (ch === 124) {
token = state.push('text', '', 0)
token.content = String.fromCharCode(ch)
pos += 1
continue
}
}
if (!fence) {
if (match.closeRe && match.closeRe.test(match.markup)) {
len += match.closeRe.lastIndex - match.closeRe.exec(match.markup)[0].length
}
token = state.push(match.name, match.markup, len)
token.plugin = m.plugin
continue
}
if (ch === 96 || ch === 126) {
pos += match.closeRe.lastIndex - match.closeRe.exec(match.markup)[0].length
fence = 0
continue
}
}
}
if (ch === 0) {
break
}
if (ch === 96 && !esc) {
fence = fence + 1
} else if (ch === 92) {
esc = esc + 1
} else {
esc = 0
}
if (fence > 0 || esc % 2 === 0) {
pos++
} else {
break
}
}
if (bracket && this.options.strict) {
state.pending += '[';
state.pending += str.slice(relStart, pos)
state.pending += ']'
}
return relStart
};
在代码中,我们可以看到,ParserInline
首先会判断是否需要跳过一些字符。接着,它会开始遍历字符串,处理行内元素。
当它遇到一个字符时,它会首先检查是否有扩展语法需要处理。如果有,则会调用扩展语法的正则表达式来匹配字符串。如果匹配成功,则会将匹配到的内容解析成一个token
,并添加到state
中。
如果字符串中没有扩展语法,则ParserInline
会根据字符来判断是否需要解析成token
。例如,如果字符是[
,则会将其解析成一个link
或image
的token
。
最后,如果字符串中没有任何需要解析的字符,则ParserInline
会将字符串添加到state.pending
中。
总结
ParserInline
是markdown-it
解析器中处理行内元素的解析器。它可以解析各种各样的行内元素,包括链接、强调、代码块等。ParserInline
的解析过程非常复杂,但它的工作原理并不难理解。