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",
|
||||
"highlight.js": "^11.6.0",
|
||||
"juice": "^8.0.0",
|
||||
"katex": "^0.16.9",
|
||||
"marked": "^4.0.18",
|
||||
"minio": "7.0.33",
|
||||
"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"
|
||||
/>
|
||||
<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>
|
||||
|
||||
<body>
|
||||
@ -39,5 +42,11 @@
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
<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>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
按Ctrl+F可格式化
|
||||
按Ctrl/Command+F可格式化
|
||||
*/
|
||||
/* 一级标题样式 */
|
||||
h1 {
|
||||
|
@ -54,6 +54,7 @@ export default {
|
||||
value: `rgba(250, 81, 81, 1)`,
|
||||
desc: `热情活泼`,
|
||||
},
|
||||
// { label: `微信绿`, value: `rgb(26, 173, 25,1)`, desc: `经典微信绿` },
|
||||
],
|
||||
codeThemeOption: [
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Renderer } from "marked";
|
||||
import hljs from 'highlight.js';
|
||||
|
||||
import hljs from "highlight.js";
|
||||
import katex from "katex";
|
||||
class WxRenderer {
|
||||
constructor(opts) {
|
||||
this.opts = opts;
|
||||
@ -121,24 +121,37 @@ class WxRenderer {
|
||||
return `<blockquote ${getStyles("blockquote")}>${text}</blockquote>`;
|
||||
};
|
||||
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/>")
|
||||
.replace(/\n/g,"<br/>")
|
||||
.replace(/(>[^<]+)|(^[^<]+)/g, function(str) {
|
||||
return str.replace(/\s/g, ' ')
|
||||
text = text
|
||||
.replace(/\r\n/g, "<br/>")
|
||||
.replace(/\n/g, "<br/>")
|
||||
.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) =>
|
||||
`<code ${getStyles("codespan")}>${text}</code>`;
|
||||
renderer.listitem = (text) =>
|
||||
`<li ${getStyles(
|
||||
"listitem"
|
||||
)}><span><%s/></span>${text}</li>`;
|
||||
`<li ${getStyles("listitem")}><span><%s/></span>${text}</li>`;
|
||||
|
||||
renderer.list = (text, ordered, start) => {
|
||||
text = text.replace(/<\/*p .*?>/g, "").replace(/<\/*p>/g, "");
|
||||
|
@ -203,27 +203,27 @@ export default {
|
||||
formatItems: [
|
||||
{
|
||||
label: `加粗`,
|
||||
kbd: `Ctrl + B`,
|
||||
kbd: `Ctrl/Command + B`,
|
||||
emitArgs: [`addFormat`, `**`],
|
||||
},
|
||||
{
|
||||
label: `斜体`,
|
||||
kbd: `Ctrl + I`,
|
||||
kbd: `Ctrl/Command + I`,
|
||||
emitArgs: [`addFormat`, `*`],
|
||||
},
|
||||
{
|
||||
label: `删除线`,
|
||||
kbd: `Alt + Shift + U`,
|
||||
kbd: `Ctrl/Command + D`,
|
||||
emitArgs: [`addFormat`, `~~`],
|
||||
},
|
||||
{
|
||||
label: `超链接`,
|
||||
kbd: `Alt + Shift + K`,
|
||||
kbd: `Ctrl/Command + K`,
|
||||
emitArgs: [`addFormat`, `[`, `]()`],
|
||||
},
|
||||
{
|
||||
label: `格式化`,
|
||||
kbd: `Alt + Shift + L`,
|
||||
kbd: `Ctrl/Command + F`,
|
||||
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 { 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`, {
|
||||
state: () => ({
|
||||
wxRenderer: null,
|
||||
@ -88,9 +92,6 @@ export const useStore = defineStore(`store`, {
|
||||
editorDom.value =
|
||||
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, {
|
||||
mode: `text/x-markdown`,
|
||||
theme: `xq-light`,
|
||||
@ -104,7 +105,7 @@ export const useStore = defineStore(`store`, {
|
||||
localStorage.setItem(`__editor_content`, doc)
|
||||
editor.setValue(doc)
|
||||
},
|
||||
[[`${modPrefix}-B`]]: function bold(editor) {
|
||||
[`${modPrefix}-B`]: function bold(editor) {
|
||||
const selected = editor.getSelection()
|
||||
editor.replaceSelection(`**${selected}**`)
|
||||
},
|
||||
@ -116,6 +117,10 @@ export const useStore = defineStore(`store`, {
|
||||
const selected = editor.getSelection()
|
||||
editor.replaceSelection(`*${selected}*`)
|
||||
},
|
||||
[`${modPrefix}-K`]: function italic(editor) {
|
||||
const selected = editor.getSelection()
|
||||
editor.replaceSelection(`[${selected}]()`)
|
||||
},
|
||||
[`${modPrefix}-L`]: function code(editor) {
|
||||
const selected = editor.getSelection()
|
||||
editor.replaceSelection(`\`${selected}\``)
|
||||
@ -138,12 +143,12 @@ export const useStore = defineStore(`store`, {
|
||||
matchBrackets: true,
|
||||
autofocus: true,
|
||||
extraKeys: {
|
||||
'Ctrl-F': function autoFormat(editor) {
|
||||
[`${modPrefix}-F`]: function autoFormat(editor) {
|
||||
const doc = formatCss(editor.getValue(0))
|
||||
localStorage.setItem(`__css_content`, doc)
|
||||
editor.setValue(doc)
|
||||
},
|
||||
'Ctrl-S': function save(editor) {},
|
||||
[`${modPrefix}-S`]: function save(editor) {},
|
||||
},
|
||||
})
|
||||
},
|
||||
|
@ -1,11 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
class="container"
|
||||
:class="{ container_night: nightMode }"
|
||||
@keydown.alt.shift.k="addFormat('[', ']()')"
|
||||
@keydown.alt.shift.u="addFormat('~~')"
|
||||
@keydown.ctrl.alt.l="formatContent()"
|
||||
>
|
||||
<div class="container" :class="{ container_night: nightMode }">
|
||||
<el-container>
|
||||
<el-header class="editor__header">
|
||||
<editor-header
|
||||
|
Loading…
Reference in New Issue
Block a user