mirror of
https://github.com/doocs/md.git
synced 2024-11-28 13:36:32 +08:00
feat: support Mermaid and Katex (#250)
--------- Co-authored-by: hoollyzhang <hoollyzhang@tencent.com>
This commit is contained in:
parent
806c4c086d
commit
192c7878f9
1235
package-lock.json
generated
1235
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
|||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"highlight.js": "^11.6.0",
|
"highlight.js": "^11.6.0",
|
||||||
"juice": "^8.0.0",
|
"juice": "^8.0.0",
|
||||||
|
"katex": "^0.16.9",
|
||||||
"marked": "^4.0.18",
|
"marked": "^4.0.18",
|
||||||
"minio": "7.0.33",
|
"minio": "7.0.33",
|
||||||
"node-fetch": "^3.2.10",
|
"node-fetch": "^3.2.10",
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
href="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/wechatsync/article-syncjs@latest/dist/styles.css"
|
href="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/wechatsync/article-syncjs@latest/dist/styles.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/npm/prettify/r298/prettify.min.js"></script>
|
<script src="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/npm/prettify/r298/prettify.min.js"></script>
|
||||||
|
|
||||||
|
<!-- KaTeX CSS -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -39,5 +42,11 @@
|
|||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
<script src="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/wechatsync/article-syncjs@latest/dist/main.js"></script>
|
<script src="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/gh/wechatsync/article-syncjs@latest/dist/main.js"></script>
|
||||||
|
<!-- 支持一下 mermaid -->
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||||
|
mermaid.initialize({ startOnLoad: true });
|
||||||
|
window.mermaid = mermaid;
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
按Ctrl+F可格式化
|
按Ctrl/Command+F可格式化
|
||||||
*/
|
*/
|
||||||
/* 一级标题样式 */
|
/* 一级标题样式 */
|
||||||
h1 {
|
h1 {
|
||||||
|
@ -54,6 +54,7 @@ export default {
|
|||||||
value: `rgba(250, 81, 81, 1)`,
|
value: `rgba(250, 81, 81, 1)`,
|
||||||
desc: `热情活泼`,
|
desc: `热情活泼`,
|
||||||
},
|
},
|
||||||
|
// { label: `微信绿`, value: `rgb(26, 173, 25,1)`, desc: `经典微信绿` },
|
||||||
],
|
],
|
||||||
codeThemeOption: [
|
codeThemeOption: [
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Renderer } from "marked";
|
import { Renderer } from "marked";
|
||||||
import hljs from 'highlight.js';
|
import hljs from "highlight.js";
|
||||||
|
import katex from "katex";
|
||||||
class WxRenderer {
|
class WxRenderer {
|
||||||
constructor(opts) {
|
constructor(opts) {
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
@ -23,7 +23,7 @@ class WxRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let base_block = merge(base, {});
|
let base_block = merge(base, {});
|
||||||
for (let ele in themeTpl.block) {
|
for (let ele in themeTpl.block) {
|
||||||
if (themeTpl.block.hasOwnProperty(ele)) {
|
if (themeTpl.block.hasOwnProperty(ele)) {
|
||||||
let style = themeTpl.block[ele];
|
let style = themeTpl.block[ele];
|
||||||
@ -121,24 +121,37 @@ class WxRenderer {
|
|||||||
return `<blockquote ${getStyles("blockquote")}>${text}</blockquote>`;
|
return `<blockquote ${getStyles("blockquote")}>${text}</blockquote>`;
|
||||||
};
|
};
|
||||||
renderer.code = (text, lang) => {
|
renderer.code = (text, lang) => {
|
||||||
lang = hljs.getLanguage(lang) ? lang : 'plaintext';
|
if (lang === "katex") {
|
||||||
|
const html = katex.renderToString(text);
|
||||||
|
return `${html}`;
|
||||||
|
}
|
||||||
|
if (lang.startsWith("mermaid")) {
|
||||||
|
setTimeout(() => {
|
||||||
|
window.mermaid?.run();
|
||||||
|
}, 0);
|
||||||
|
return `<center><pre class="mermaid">${text}</pre></center>`;
|
||||||
|
}
|
||||||
|
lang = hljs.getLanguage(lang) ? lang : "plaintext";
|
||||||
|
|
||||||
text = hljs.highlight(text, {language: lang}).value;
|
text = hljs.highlight(text, { language: lang }).value;
|
||||||
|
|
||||||
text = text.replace(/\r\n/g,"<br/>")
|
text = text
|
||||||
.replace(/\n/g,"<br/>")
|
.replace(/\r\n/g, "<br/>")
|
||||||
.replace(/(>[^<]+)|(^[^<]+)/g, function(str) {
|
.replace(/\n/g, "<br/>")
|
||||||
return str.replace(/\s/g, ' ')
|
.replace(/(>[^<]+)|(^[^<]+)/g, function (str) {
|
||||||
});
|
return str.replace(/\s/g, " ");
|
||||||
|
});
|
||||||
|
|
||||||
return `<pre class="hljs code__pre" ${getStyles("code_pre")}><code class="prettyprint language-${lang}" ${getStyles("code")}>${text}</code></pre>`
|
return `<pre class="hljs code__pre" ${getStyles(
|
||||||
|
"code_pre"
|
||||||
|
)}><code class="prettyprint language-${lang}" ${getStyles(
|
||||||
|
"code"
|
||||||
|
)}>${text}</code></pre>`;
|
||||||
};
|
};
|
||||||
renderer.codespan = (text, lang) =>
|
renderer.codespan = (text, lang) =>
|
||||||
`<code ${getStyles("codespan")}>${text}</code>`;
|
`<code ${getStyles("codespan")}>${text}</code>`;
|
||||||
renderer.listitem = (text) =>
|
renderer.listitem = (text) =>
|
||||||
`<li ${getStyles(
|
`<li ${getStyles("listitem")}><span><%s/></span>${text}</li>`;
|
||||||
"listitem"
|
|
||||||
)}><span><%s/></span>${text}</li>`;
|
|
||||||
|
|
||||||
renderer.list = (text, ordered, start) => {
|
renderer.list = (text, ordered, start) => {
|
||||||
text = text.replace(/<\/*p .*?>/g, "").replace(/<\/*p>/g, "");
|
text = text.replace(/<\/*p .*?>/g, "").replace(/<\/*p>/g, "");
|
||||||
|
@ -203,27 +203,27 @@ export default {
|
|||||||
formatItems: [
|
formatItems: [
|
||||||
{
|
{
|
||||||
label: `加粗`,
|
label: `加粗`,
|
||||||
kbd: `Ctrl + B`,
|
kbd: `Ctrl/Command + B`,
|
||||||
emitArgs: [`addFormat`, `**`],
|
emitArgs: [`addFormat`, `**`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `斜体`,
|
label: `斜体`,
|
||||||
kbd: `Ctrl + I`,
|
kbd: `Ctrl/Command + I`,
|
||||||
emitArgs: [`addFormat`, `*`],
|
emitArgs: [`addFormat`, `*`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `删除线`,
|
label: `删除线`,
|
||||||
kbd: `Alt + Shift + U`,
|
kbd: `Ctrl/Command + D`,
|
||||||
emitArgs: [`addFormat`, `~~`],
|
emitArgs: [`addFormat`, `~~`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `超链接`,
|
label: `超链接`,
|
||||||
kbd: `Alt + Shift + K`,
|
kbd: `Ctrl/Command + K`,
|
||||||
emitArgs: [`addFormat`, `[`, `]()`],
|
emitArgs: [`addFormat`, `[`, `]()`],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `格式化`,
|
label: `格式化`,
|
||||||
kbd: `Alt + Shift + L`,
|
kbd: `Ctrl/Command + F`,
|
||||||
emitArgs: [`formatContent`],
|
emitArgs: [`formatContent`],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -8,6 +8,10 @@ import DEFAULT_CONTENT from '@/assets/example/markdown.md'
|
|||||||
import DEFAULT_CSS_CONTENT from '@/assets/example/theme-css.txt'
|
import DEFAULT_CSS_CONTENT from '@/assets/example/theme-css.txt'
|
||||||
import { setColor, formatDoc, formatCss } from '@/assets/scripts/util'
|
import { setColor, formatDoc, formatCss } from '@/assets/scripts/util'
|
||||||
|
|
||||||
|
const defaultKeyMap = CodeMirror.keyMap[`default`]
|
||||||
|
const modPrefix =
|
||||||
|
defaultKeyMap === CodeMirror.keyMap[`macDefault`] ? `Cmd` : `Ctrl`
|
||||||
|
|
||||||
export const useStore = defineStore(`store`, {
|
export const useStore = defineStore(`store`, {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
wxRenderer: null,
|
wxRenderer: null,
|
||||||
@ -88,9 +92,6 @@ export const useStore = defineStore(`store`, {
|
|||||||
editorDom.value =
|
editorDom.value =
|
||||||
localStorage.getItem(`__editor_content`) || formatDoc(DEFAULT_CONTENT)
|
localStorage.getItem(`__editor_content`) || formatDoc(DEFAULT_CONTENT)
|
||||||
}
|
}
|
||||||
const defaultKeyMap = CodeMirror.keyMap[`default`]
|
|
||||||
const modPrefix =
|
|
||||||
defaultKeyMap === CodeMirror.keyMap[`macDefault`] ? `Cmd` : `Ctrl`
|
|
||||||
this.editor = CodeMirror.fromTextArea(editorDom, {
|
this.editor = CodeMirror.fromTextArea(editorDom, {
|
||||||
mode: `text/x-markdown`,
|
mode: `text/x-markdown`,
|
||||||
theme: `xq-light`,
|
theme: `xq-light`,
|
||||||
@ -104,7 +105,7 @@ export const useStore = defineStore(`store`, {
|
|||||||
localStorage.setItem(`__editor_content`, doc)
|
localStorage.setItem(`__editor_content`, doc)
|
||||||
editor.setValue(doc)
|
editor.setValue(doc)
|
||||||
},
|
},
|
||||||
[[`${modPrefix}-B`]]: function bold(editor) {
|
[`${modPrefix}-B`]: function bold(editor) {
|
||||||
const selected = editor.getSelection()
|
const selected = editor.getSelection()
|
||||||
editor.replaceSelection(`**${selected}**`)
|
editor.replaceSelection(`**${selected}**`)
|
||||||
},
|
},
|
||||||
@ -116,6 +117,10 @@ export const useStore = defineStore(`store`, {
|
|||||||
const selected = editor.getSelection()
|
const selected = editor.getSelection()
|
||||||
editor.replaceSelection(`*${selected}*`)
|
editor.replaceSelection(`*${selected}*`)
|
||||||
},
|
},
|
||||||
|
[`${modPrefix}-K`]: function italic(editor) {
|
||||||
|
const selected = editor.getSelection()
|
||||||
|
editor.replaceSelection(`[${selected}]()`)
|
||||||
|
},
|
||||||
[`${modPrefix}-L`]: function code(editor) {
|
[`${modPrefix}-L`]: function code(editor) {
|
||||||
const selected = editor.getSelection()
|
const selected = editor.getSelection()
|
||||||
editor.replaceSelection(`\`${selected}\``)
|
editor.replaceSelection(`\`${selected}\``)
|
||||||
@ -138,12 +143,12 @@ export const useStore = defineStore(`store`, {
|
|||||||
matchBrackets: true,
|
matchBrackets: true,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
'Ctrl-F': function autoFormat(editor) {
|
[`${modPrefix}-F`]: function autoFormat(editor) {
|
||||||
const doc = formatCss(editor.getValue(0))
|
const doc = formatCss(editor.getValue(0))
|
||||||
localStorage.setItem(`__css_content`, doc)
|
localStorage.setItem(`__css_content`, doc)
|
||||||
editor.setValue(doc)
|
editor.setValue(doc)
|
||||||
},
|
},
|
||||||
'Ctrl-S': function save(editor) {},
|
[`${modPrefix}-S`]: function save(editor) {},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="container" :class="{ container_night: nightMode }">
|
||||||
class="container"
|
|
||||||
:class="{ container_night: nightMode }"
|
|
||||||
@keydown.alt.shift.k="addFormat('[', ']()')"
|
|
||||||
@keydown.alt.shift.u="addFormat('~~')"
|
|
||||||
@keydown.ctrl.alt.l="formatContent()"
|
|
||||||
>
|
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header class="editor__header">
|
<el-header class="editor__header">
|
||||||
<editor-header
|
<editor-header
|
||||||
|
Loading…
Reference in New Issue
Block a user