From 8d4f2f0ce598faaa76c49d871e5abd3194b70cd9 Mon Sep 17 00:00:00 2001 From: xiaozzzi <42293085+xiaozzzi@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:04:51 +0800 Subject: [PATCH] =?UTF-8?q?Markdown=20=E8=A7=A3=E6=9E=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/renderer/src/assets/utils/hljsTest.ts | 25 +++ .../src/views/article/scripts/codemirror.ts | 2 +- .../src/views/article/scripts/markedjs.ts | 163 ++++++++++-------- 3 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 blossom-editor/src/renderer/src/assets/utils/hljsTest.ts diff --git a/blossom-editor/src/renderer/src/assets/utils/hljsTest.ts b/blossom-editor/src/renderer/src/assets/utils/hljsTest.ts new file mode 100644 index 0000000..eb99a4b --- /dev/null +++ b/blossom-editor/src/renderer/src/assets/utils/hljsTest.ts @@ -0,0 +1,25 @@ +import { log } from 'console' +import hljs from 'highlight.js' + +hljs.addPlugin({ + 'after:highlight': (el) => { + console.log(el); + + let result = '
    ' + let snsArr: string[] = el.value.split(/[\n\r]+/) + snsArr.forEach((item: string) => { + result += `
  1. ${item}
  2. ` + }) + el.value = result += '
' + } +}) + +const html = hljs.highlight( + `public void main () { + li + 神经 +}`, + { language: 'java' } +).value + +console.log(html) diff --git a/blossom-editor/src/renderer/src/views/article/scripts/codemirror.ts b/blossom-editor/src/renderer/src/views/article/scripts/codemirror.ts index e1aa76e..cbb78cf 100644 --- a/blossom-editor/src/renderer/src/views/article/scripts/codemirror.ts +++ b/blossom-editor/src/renderer/src/views/article/scripts/codemirror.ts @@ -432,7 +432,7 @@ export class CmWrapper { /** 在当前位置增加表格 */ private static commandTable = (editor: EditorView) => { this.insertBlockCommand(editor, `\n|||\n|---|---|\n|||\n`) } /** 在当前位置增加多行代码块 */ - private static commandPre = (editor: EditorView) => { this.insertBlockCommand(editor, `\n\`\`\`java\n\n\`\`\`\n`) } + private static commandPre = (editor: EditorView) => { this.insertBlockCommand(editor, `\n\`\`\`\n\n\`\`\`\n`) } /** 在当前位置增加单选框 */ private static commandCheckBox = (editor: EditorView) => { this.insertBlockCommand(editor, `\n- [ ] \n`) } /** 在当前位置增加分割线 */ diff --git a/blossom-editor/src/renderer/src/views/article/scripts/markedjs.ts b/blossom-editor/src/renderer/src/views/article/scripts/markedjs.ts index a376fa3..b10de47 100644 --- a/blossom-editor/src/renderer/src/views/article/scripts/markedjs.ts +++ b/blossom-editor/src/renderer/src/views/article/scripts/markedjs.ts @@ -1,7 +1,7 @@ import { isBlank, isNotBlank } from '@renderer/assets/utils/obj' import { escape2Html } from '@renderer/assets/utils/util' import { marked, Marked } from 'marked' -import { markedHighlight } from "marked-highlight" +import { markedHighlight } from 'marked-highlight' import hljs from 'highlight.js' import katex from 'katex' import 'katex/dist/katex.min.css' @@ -15,24 +15,23 @@ mermaid.initialize({ theme: 'base', startOnLoad: false, securityLevel: 'loose', - 'themeVariables': { - 'fontFamily': 'inherit', + themeVariables: { + fontFamily: 'inherit', // 主要配色 - 'primaryColor': '#cfbef1', - 'primaryTextColor': '#606266', - 'primaryBorderColor': '#A67AFF', + primaryColor: '#cfbef1', + primaryTextColor: '#606266', + primaryBorderColor: '#A67AFF', // 第二颜色 - 'secondaryColor': '#efc75e', - 'secondaryTextColor': '#606266', + secondaryColor: '#efc75e', + secondaryTextColor: '#606266', // 第三颜色 - 'tertiaryColor': '#C4DFFF', - 'tertiaryTextColor': '#606266', + tertiaryColor: '#C4DFFF', + tertiaryTextColor: '#606266', // 连线的颜色 - 'lineColor': '#A0A0A0', + lineColor: '#A0A0A0' } -}); -mermaid.parseError = (_err, _hash) => { -} +}) +mermaid.parseError = (_err, _hash) => {} /** * 标记标识 @@ -51,14 +50,32 @@ marked.use({ headerIds: false }) -// 高亮拓展 -marked.use(markedHighlight({ +// 行号插件, 对 mermaid 等有些许影响 +// hljs.addPlugin({ +// 'after:highlight': (el) => { +// console.log(el.language) +// if (el.language == 'mermaid' || el.language == 'katex') { +// return +// } +// let result = '
    ' +// let snsArr: string[] = el.value.split(/[\n\r]+/) +// snsArr.forEach((item: string) => { +// result += `
  1. ${item}
  2. ` +// }) +// el.value = result += '
' +// } +// }) + +let hljsConfig = { langPrefix: 'hljs language-', highlight(code, lang) { const language = hljs.getLanguage(lang) ? lang : 'shell' return hljs.highlight(code, { language }).value } -})) +} + +// 高亮拓展 +marked.use(markedHighlight(hljsConfig)) // @@ -80,7 +97,6 @@ export const tokenizerCodespan = (src: string): any => { //#region ----------------------------------------< renderer >-------------------------------------- - /** * 标题解析为 TOC 集合, 增加锚点跳转 * @param text 标题内容 @@ -91,7 +107,6 @@ export const renderHeading = (text: any, level: number) => { return `${text}` } - /** * 表格 header/body */ @@ -124,7 +139,7 @@ export const renderBlockquote = (quote: string) => { /** * 支持了新的语义化引用 - * + * * https://github.com/orgs/community/discussions/16925#discussioncomment-3192118 * https://learn.microsoft.com/en-us/contribute/content/markdown-reference#alerts-note-tip-important-caution-warning */ @@ -154,47 +169,55 @@ export const renderBlockquote = (quote: string) => { * 1. bilibili * 格式为: ```bilibili${grammar}bvid${grammar}w100${grammar}h100 * 官方使用文档: https://player.bilibili.com/ - * - * 2. katex + * + * 2. katex * 3. mermaid - * + * * @param code 解析后的 HTML 代码 * @param language 语言 - * @param isEscaped + * @param isEscaped * @param mermaidCallback 替换 html 结果中的 mermaid 内容 */ -export const renderCode = (code: string, language: string | undefined, _isEscaped: boolean, mermaidCallback?: (eleid: string, svg: string) => void) => { +export const renderCode = ( + code: string, + language: string | undefined, + _isEscaped: boolean, + mermaidCallback?: (eleid: string, svg: string) => void +) => { if (language == undefined) { language = 'text' } if (language === 'mermaid' && isNotBlank(code)) { const eleid = 'mermaid-' + Date.now() + '-' + Math.round(Math.random() * 1000) const escape = escape2Html(code) as string - mermaid.parse(escape).then(syntax => { - let canSyntax: boolean | void = syntax - if (canSyntax) { - mermaid.render(eleid + '-svg', escape).then((resp) => { - if (mermaidCallback != undefined) { - const { svg } = resp - let element = document.getElementById(eleid) - element!.innerHTML = svg - mermaidCallback(eleid, svg) - } - }) - } - }).catch(error => { - console.error('mermaid 格式校验失败:错误信息如下:\n', error) - let html = `
+ mermaid + .parse(escape) + .then((syntax) => { + let canSyntax: boolean | void = syntax + if (canSyntax) { + mermaid.render(eleid + '-svg', escape).then((resp) => { + if (mermaidCallback != undefined) { + const { svg } = resp + let element = document.getElementById(eleid) + element!.innerHTML = svg + mermaidCallback(eleid, svg) + } + }) + } + }) + .catch((error) => { + console.error('mermaid 格式校验失败:错误信息如下:\n', error) + let html = `
Mermaid 语法解析失败!

${error}

你可以尝试前往 Mermaid 官网来校验你的内容, 或者查看相关文档: https://mermaid.live/edit
` - if (mermaidCallback != undefined) { - let element = document.getElementById(eleid) - element!.innerHTML = html - mermaidCallback(eleid, html) - } - }) + if (mermaidCallback != undefined) { + let element = document.getElementById(eleid) + element!.innerHTML = html + mermaidCallback(eleid, html) + } + }) return `

${eleid}

` } @@ -260,8 +283,8 @@ export const renderCode = (code: string, language: string | undefined, _isEscape /** * 单行代码块的解析拓展 * 1. katex `$内部写表达式$` - * @param src - * @returns + * @param src + * @returns */ export const renderCodespan = (src: string) => { let arr = src.match(singleDollar) @@ -282,17 +305,17 @@ export const renderCodespan = (src: string) => { } /** - * 拓展图片设置 - * ![照片A${grammar}shadow${grammar}w100]() - * 上面格式解析为 - * - 图片名称为 照片A - * - 图片包含阴影 - * - 图片宽度为100px - * - * @param href 图片路径 - * @param _title null - * @param text 图片的名称 - */ + * 拓展图片设置 + * ![照片A${grammar}shadow${grammar}w100]() + * 上面格式解析为 + * - 图片名称为 照片A + * - 图片包含阴影 + * - 图片宽度为100px + * + * @param href 图片路径 + * @param _title null + * @param text 图片的名称 + */ export const renderImage = (href: string | null, title: string | null, text: string) => { let width = 'auto' let style = '' @@ -318,7 +341,7 @@ export const renderImage = (href: string | null, title: string | null, text: str /** * 解析链接, 拓展双链功能 - * + * * @param href 链接地址 * @param title 链接标题 , 语法拓展内容在title中 * @param text 链接的文字 @@ -363,13 +386,7 @@ export const renderLink = (href: string | null, title: string | null, text: stri //#region ----------------------------------------< simpleMarked >-------------------------------------- const simpleMarked = new Marked({ mangle: false, headerIds: false }) -simpleMarked.use(markedHighlight({ - langPrefix: 'hljs language-', - highlight(code, lang) { - const language = hljs.getLanguage(lang) ? lang : 'shell' - return hljs.highlight(code, { language }).value - } -})) +simpleMarked.use(markedHighlight(hljsConfig)) const simpleRenderer = { code(code: string, language: string | undefined, _isEscaped: boolean): string { @@ -386,11 +403,15 @@ const simpleRenderer = { } return `
${code}
` }, - codespan(src: string): string { return renderCodespan(src) }, + codespan(src: string): string { + return renderCodespan(src) + } } const tokenizer = { - codespan(src: string): any { return tokenizerCodespan(src) } + codespan(src: string): any { + return tokenizerCodespan(src) + } } //@ts-ignore @@ -400,6 +421,4 @@ simpleMarked.use({ tokenizer: tokenizer, renderer: simpleRenderer }) export default marked -export { - simpleMarked -} \ No newline at end of file +export { simpleMarked }