在 EasyMDE 里添加数学表达式支持和表格快速对齐

作者: , 共 5043 字 , 共阅读 0

最近试用了一些 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>

几点说明:

上面还增加了一个按钮,可以对选中的 markdown 表格代码快速对齐。简单举个例子,如果我们选中下面的表格:

| aaaa | bbb | c
|---|-|-
|x|xxxx|xx

点击快速对齐的按钮之后,将会格式化成下面的代码:

| aaaa | bbb  | c  
| ---  | -    | -  
| x    | xxxx | xx 

Q. E. D.

类似文章:
最近做社会实践项目遇到的一个问题,需要动态修改一个表格。本来以为要想修改一行,直接设置新的 tr.innerHTML 即可。后来发现在 Firefox 下可行,但在 IE 下通不过,查看了一下帮助,才发现 innerHTML 还没有一个通用标准,而在 IE 下innerHTML对于标签为 COL, COLGROUP, FRAMESET, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR 的元素是只读的。要想在 IE 下动态修改表格,只能使用 insertRow 和 insertCell;
IT » Markdown, Pelican, Mkdocs
最近写文档和写博客都开始用 markdown ,其中博客用得是Pelican,文档用Mkdocs。它们俩都用python-markdown模块来处理 markdown 文件。而这个模块支持扩展,可以大大提升 markdown 的表现力:
Python 数据分析工具 pandas 中以 DataFrame 和 Series 作为主要的数据结构。
IT » Highcharts, vue
标准版的 Highcharts 要想提供导出数据,可参考https://api.highcharts.com/highcharts/exporting.csv,核心是引入exporting.jsexport-data.js两个额外的 JS ,不需要做别的操作:
编程 » C++, 数据容器
我们知道在javascript以及Python 3.6+中,所有的dict都保留了插入顺序。但在 C++中,无论是std::map还是std::unordered_map,都没有保留插入顺序。当遍历时,std::map得到的是一个根据键值排序的有序序列,而std::unordered_map则基本是乱序。
招聘部门:中信证券股权衍生品业务线
IT »
有时候用vim打开文件,每行结尾都有一个灰色的^M。这个原因是该文件在 windows 或 mac 系统上被创建: