From eb33352399bb075c89b58f106dfbbb1efd2a67a3 Mon Sep 17 00:00:00 2001 From: Innei Date: Sat, 13 Aug 2022 20:38:11 +0800 Subject: [PATCH] feat: make some compatibility with Kami Markdown syntax Signed-off-by: Innei --- src/modules/markdown/markdown.service.ts | 98 ++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/src/modules/markdown/markdown.service.ts b/src/modules/markdown/markdown.service.ts index bb3f5f95..e4318b08 100644 --- a/src/modules/markdown/markdown.service.ts +++ b/src/modules/markdown/markdown.service.ts @@ -273,6 +273,28 @@ ${text.trim()} }, childTokens: ['text'], }, + { + level: 'inline', + name: 'katex', + start(src) { + return src.match(/\$/)?.index ?? -1 + }, + renderer(token) { + return `${token.text}` + }, + tokenizer(src) { + const rule = /^\$([\s\S]+?)\$(?!\$)/ + const match = rule.exec(src) + if (match) { + return { + type: 'katex', + raw: match[0], + // @ts-ignore + text: match[1].trim(), + } + } + }, + }, { level: 'inline', name: 'mention', @@ -280,23 +302,79 @@ ${text.trim()} return src.match(/\(/)?.index ?? -1 }, renderer(token) { - // @ts-ignore - const username = this.parser.parseInline(token.text).slice(1) - return `@${username}\n` + const { groups } = token + const { prefix, name: username } = groups + + const prefixToUrlMap = { + GH: 'https://github.com/', + TW: 'https://twitter.com/', + TG: 'https://t.me/', + } + const urlPrefix = prefixToUrlMap[prefix] + return `${username}` }, - tokenizer(src, tokens) { - const rule = /^\((@(\w+\b))\)\s?(?!\[.*?\])/ + tokenizer(src) { + const rule = + /^\{((?(GH)|(TW)|(TG))@(?\w+\b))\}\s?(?!\[.*?\])/ const match = rule.exec(src) if (match) { + const { groups } = match return { type: 'mention', raw: match[0], - text: this.lexer.inlineTokens(match[1].trim(), []), + groups, } } }, childTokens: ['text'], }, + { + level: 'block', + name: 'container', + start(src) { + return src.indexOf(':::') + }, + renderer(token) { + const { groups, images, paragraph } = token + const { params, content, name } = groups + + switch (name) { + case 'gallery': + // @ts-expect-error + return `
${this.parser.parseInline( + images, + )}
` + case 'banner': + return `
${this.parser.parse( + paragraph, + )}
` + } + return '' + }, + tokenizer(src) { + const shouldCatchContainerName = [ + 'gallery', + 'banner', + /* 'carousel', */ + ].join('|') + const match = new RegExp( + `^\\s*::: *(?(${shouldCatchContainerName})) *({(?(.*?))})? *\n(?[\\s\\S]+?)\\s*::: *(?:\n *)+\n?`, + ).exec(src) + if (match) { + const { groups } = match + return { + type: 'container', + raw: match[0], + groups, + // @ts-expect-error + images: this.lexer.inlineTokens(groups.content), + // @ts-expect-error + paragraph: this.lexer.blockTokens(groups.content), + } + } + }, + childTokens: ['paragraph', 'image'], + }, ], renderer: { @@ -350,18 +428,24 @@ ${text.trim()} '', '', '', - '', // '', // '', // '', + '', ], script: [ `window.mermaid.initialize({theme: 'default',startOnLoad: false})`, `window.mermaid.init(undefined, '.mermaid')`, + `window.onload = () => { document.querySelectorAll('.katex-render').forEach(el => { window.katex.render(el.innerHTML, el, { + throwOnError: false, + }) }) }`, ], link: [ '', '', + // katex + '', ], style: [style, themeStyleSheet], }