最近试用了一些 markdown 编辑器,之前最有名的是 simplemde, 2017 年之后未更新,有人在此基础上做了个 easymde,现在还有一些更新。
这个东西的一个问题是不支持数学公式。幸好它的自定义能力比较强,我用Katex
给它加了数学表达式的支持。
首先添加一大堆依赖:
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/tomorrow.min.css">
<script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>
<link href="https://cdn.bootcss.com/KaTeX/0.11.1/katex.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/KaTeX/0.11.1/katex.min.js" ></script>
<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">
<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
然后引入下面函数:
<script>
function easymdn_katex_wrap(ele, config, markedOptions) {
markedOptions = {
renderer: new marked.Renderer(),
highlight: function(code, language) {
const validLanguage = hljs.getLanguage(language) ? language : 'cpp';
return hljs.highlight(validLanguage, code).value;
},
pedantic: false,
gfm: true,
breaks: true,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false,
...(markedOptions || {}),
};
marked.setOptions(markedOptions);
let customMarkdownParser = function(plainText) {
plainText = plainText.replace(/\$\$(.*?)\$\$/g, function (match, p1) {
return "<p class='text-center'>"
+ katex.renderToString(p1, {displayMode: true}) + "</p>";
}).replace(/\$(.*?[^\\])\$/g, function (match, p1) {
return katex.renderToString(p1, {displayMode: false});
});
return marked(plainText);
};
/// align table in markdown
let formatTable = function (table) {
function strWidth(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
len += (str.charCodeAt(i) < 256) ? 1 : 2;
}
return len;
}
table = table.trim();
if (!table) {
return "";
}
var rows = table.split("\n").map(function (row) {
row = row.split("|");
row = row.map(function (col) {
return col.trim();
});
return row;
});
var widths = Array(rows[0].length).fill(0);
rows.forEach(function (row) {
row.forEach(function (item, col) {
widths[col] = Math.max(widths[col], strWidth(item));
});
});
console.log(widths);
rows = rows.map(function (row) {
row = row.map(function (item, col) {
if (widths[col] > 0) {
item = " " + item + " ".repeat(widths[col] - strWidth(item) + 1);
}
return item;
}).join("|");
return row;
});
return rows.join("\n");
};
config = {
spellChecker: false,
autosave: {
enabled: false,
},
toolbar: [
'bold', 'italic', 'strikethrough', 'heading-3', 'code', 'quote',
'unordered-list', 'ordered-list', 'clean-block', 'link', 'image', '|', 'table',
{
name: "format_table",
action: function (editor){
console.log(editor);
var selection = editor.codemirror.doc.getSelection();
editor.codemirror.doc.replaceSelection(formatTable(selection));
},
className: "fa fa-align-justify",
title: "格式化表格",
}, 'preview', 'side-by-side', 'fullscreen', '|', 'guide', ],
placeholder: 'Type here...',
tabSize: 4,
previewRender: function(plainText, preview) { // Async method
setTimeout(function(){
preview.innerHTML = customMarkdownParser(plainText);
}, 250);
},
...(config || {})
};
return new EasyMDE(config);
}
</script>
最后要用的时候直接调用:
<script>
var mde = easymde_katex_wrap($("#textarea"));
</script>
几点说明:
- 上述代码增加了
highlight.js
进行代码高亮。 easymde_katex_wrap
函数的第二个参数为easymde
的可选参数,可参考https://github.com/Ionaru/easy-markdown-editor#configuration。easymde_katex_wrap
函数的第三个参数为marked
的可选参数,可参考https://marked.js.org/#/USING_ADVANCED.md#options。
上面还增加了一个按钮,可以对选中的 markdown 表格代码快速对齐。简单举个例子,如果我们选中下面的表格:
| aaaa | bbb | c
|---|-|-
|x|xxxx|xx
点击快速对齐的按钮之后,将会格式化成下面的代码:
| aaaa | bbb | c
| --- | - | -
| x | xxxx | xx
Q. E. D.