- define an extensions
function markedMention() {
return {
extensions: [{
name: 'mention',
level: 'inline',
start(src) {
// console.log("markedMention start....", src);
return src.indexOf('#')
},
tokenizer(src, tokens) {
const rule = /^(#[a-zA-Z0-9]+)\s?/
const match = rule.exec(src)
// console.log("mention...", match)
if (match) {
const token = {
type: 'mention',
raw: match[0],
text: match[1],
tokens: [],
}
return token
}
},
renderer(token) {
// console.log("men....", token);
return `<span class="mention" data-mention="${
token.text}">${
token.text}</span>`;
},
}]
}
}
- Use marked.use(markedMention)
- At this time, name will be used as the unique identifier
- Put the tokenizer into the array corresponding to the level, the level can be inline or block
- start is placed in the start[Level] (startInline) corresponding to the level
- Renderers are set in extensions.renderers according to name
- The case where the parsing level is inline here
- When applying, we need to use marked.parse(markdown copy, { gfm: true, ...various configurations})
- Before using marked.parse, if you need additional extensions, you need to use the .use() method to expand before that, which is equivalent to adding content to the default value (defaults)
// 使用marked.parse,就是在根据defaults来构建一个新的对象。
function marked(src, opt, callback) {
return parseMarkdown(Lexer.lex, Parser.parse)(src, opt, callback);
}
// Lexer.lex
lex(src) {
src = src.replace(/\r\n|\r/g, '\n');
let next;
while (next = this.inlineQueue.shift()) {
this.inlineTokens(next.src, next.tokens);
}
return this.tokens;
}
// Parser.parse
This is the flowchart I put together, including the conversion process of the markdown2html library.