Markdown 解析功能优化

This commit is contained in:
xiaozzzi 2023-10-08 22:04:51 +08:00
parent e5a096d013
commit 8d4f2f0ce5
3 changed files with 117 additions and 73 deletions

View File

@ -0,0 +1,25 @@
import { log } from 'console'
import hljs from 'highlight.js'
hljs.addPlugin({
'after:highlight': (el) => {
console.log(el);
let result = '<ol>'
let snsArr: string[] = el.value.split(/[\n\r]+/)
snsArr.forEach((item: string) => {
result += `<li>${item}</li>`
})
el.value = result += '</ol>'
}
})
const html = hljs.highlight(
`public void main () {
li
}`,
{ language: 'java' }
).value
console.log(html)

View File

@ -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`) }
/** 在当前位置增加分割线 */

View File

@ -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 = '<ol>'
// let snsArr: string[] = el.value.split(/[\n\r]+/)
// snsArr.forEach((item: string) => {
// result += `<li>${item}</li>`
// })
// el.value = result += '</ol>'
// }
// })
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 `<h${realLevel} id="${realLevel}-${text}">${text}</h${realLevel}>`
}
/**
* 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 = `<div class='bl-preview-analysis-fail-block'>
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 = `<div class='bl-preview-analysis-fail-block'>
<div class="fail-title">Mermaid !</div><br/>
${error}<br/><br/>
Mermaid , : <a href='https://mermaid.live/edit' target='_blank'>https://mermaid.live/edit</a>
</div>`
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 `<p id="${eleid}">${eleid}</p>`
}
@ -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 <a title="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 `<pre><code class="hljs language-${language}">${code}</code></pre>`
},
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
}
export { simpleMarked }