目录

Markdown 增强

用 Markdown 写文档,主要是省去了排版的麻烦,编辑也简单随便使用个文本编辑器就行。不过也有无力的时候,比如绘图等。
这里我使用一些现成的 js 库,完成一些复杂的功能。当然从简洁的角度这样不太优雅,但是可以保留原始数据方便修改,各有利弊吧。
以下方法使用是 html 语言,所以在 html 中也适用的。

UML 序列图

使用 js-sequence-diagrams 库。
该库可以将文本描述自动生成 UML 序列图。

准备

主要需要以下 js 文件,可以将其下载到本地,也可使用网上在线库。

  • jquery.min.js
  • underscore-min.js
  • raphael.min.js
  • sequence-diagram-min.js

编辑

在 markdown 中开头添加 js 引用路径,如下:

<script src="/js/jquery.min.js"></script>
<script src="/js/underscore-min.js"></script>
<script src="/js/raphael.min.js"></script>
<script src="/js/sequence-diagram-min.js"></script>

想要渲染的文本使用 <div class="diagram"></div> 标记,如下:

<div class="diagram">
    Alice->Bob: Hello Bob, how are you?
    Note right of Bob: Bob thinks
    Bob-->Alice: I am good thanks!
</div>

在文件末尾添加动作:

<script>
    $(".diagram").sequenceDiagram({theme: 'hand'});
</script>

结果

Alice->Bob: Hello Bob, how are you? Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!

PS: hexo 会渲染 html 代码,造成显示错误,如下可避免

{% raw %}
your html
{% endraw %}

条形图

使用 Chart.js 库。

准备

主要需要以下 js 文件:

  • jquery.min.js
  • Chart.min.js

为了方便使用,再添加一个解析文件(chart.md.js):

(function($){
    var methods = {
        bar : function() {
            var data = $.parseJSON(this.text())
            // get data
            var datasets = [];
            var color = Math.random() * 360;
            for (var i = 0; i < data[`data`].length; i++) {
                var dataset = {};
                dataset.label = data[`data`][i][`label`];
                dataset.data = data[`data`][i][`data`];
                dataset.borderWidth = 1;
                dataset.hoverBorderWidth = 2;
                var h = Math.round(color + (i * 137.5)) % 360;
                var l = Math.round(Math.random() * 20) + 60;
                dataset.backgroundColor = 'hsla(' + h + ',70%,' + l + '%,0.4)';
                dataset.borderColor = 'hsla(' + h + ',70%,' + l + '%,1)';
                datasets[i] = dataset;
            }
            // get bar type
            var type = 'bar';
            var xstacked = false;
            var ystacked = false;
            if (data.hasOwnProperty("type")) {
                var ss = data[`type`];
                if (ss.indexOf('horiz') >= 0) {
                    type = 'horizontalBar';
                    if (ss.indexOf('over') >= 0) {
                        ystacked = true;
                    }
                } else {
                    if (ss.indexOf('over') >= 0) {
                        xstacked = true;
                    }
                }
                if (ss.indexOf('stack') >= 0) {
                    xstacked = true;
                    ystacked = true;
                }
            }
            new Chart(this, {
                type: type,
                data: {
                    labels: data[`item`],
                    datasets: datasets,
                },
                options: {
                    responsive: false,
                    title: {
                        display: data.hasOwnProperty("title"),
                        text: data[`title`],
                    },
                    legend: {
                        display: data[`data`][0].hasOwnProperty("label"),
                    },
                    scales: {
                        xAxes: [{
                            stacked: xstacked,
                            ticks: {
                                beginAtZero: true,
                            },
                        }],
                        yAxes: [{
                            stacked: ystacked,
                            ticks: {
                                beginAtZero: true,
                            },
                        }],
                    },
                    tooltips: {
                        mode: (xstacked || ystacked) ? 'label' : 'single',
                    },
                },
            });
        }
    };
    $.fn.chart = function( method ){
        if ( methods[method] ) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        }  else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.chart' );
        }
    };
})(jQuery);

修改

在 markdown 中开头添加 js 引用路径,如下:

<script src="/js/jquery.min.js"></script>
<script src="/js/Chart.min.js"></script>
<script src="/js/chart.md.js"></script>

想要渲染的文本使用 <canvas class="bar" width="xxx" height="xxx"></canvas> 标记,数据使用 json 格式,如下:

<canvas class="bar" width="400" height="400">
{
    "title": "I have Title",
    "item": ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    "type": "horiz stack",
    "data": [{
            "label": "one",
            "data": [12, 19, 3, 5, 2, 3]
        },{
            "label": "two",
            "data": [23, 34, 1, 0, 39, 22]
        },{
            "label": "thrid",
            "data": [21, 0, 1, 20, 12, 15]
        }]
}
</canvas>

type:

  • horiz:条形图水平显示
  • over:一个条形图多个时叠加显示
  • stack:一个条形图多个时累加显示

在文件末尾添加动作:

<script>
    $(".bar").each(function(){
        $(this).chart('bar')
    })
</script>

结果

{ "title": "I have Title", "item": ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], "type": "horiz stack", "data": [{ "label": "one", "data": [12, 19, 3, 5, 2, 3] },{ "label": "two", "data": [23, 34, 1, 0, 39, 22] },{ "label": "thrid", "data": [21, 0, 1, 20, 12, 15] }] }

解析器修改

markdown 渲染有不同的解析器,各个可能有差异,有些需要修改才能支持自己添加的 js 文件。

OmniMarkupPreviewer

OmniMarkupPreviewer 是 sublime 的插件,可以实时显示渲染 markdown 文档。
新添加的 js 文件可以放在以下目录:

C:\Users\xxx\AppData\Roaming\Sublime Text 3\Packages

markdown 文件中 js 的路径如下:

<script src="/public/xxx.js"></script>