Markdownを表示するJavaScript

Markdown形式をクライアント側でHTMLに変換してよしなに表示してくれるmarked.jsがあるが、シーケンス図等には対応していない。
やっぱり図をさくっとmdで書きたいので、flowchart.jsおよびjs-sequence-diagrams.jsのブロックも書けるようラップした。

処理概要

  1. sequenceならびにflowchartのブロックを抽出、divで置き換え
  2. marked.jsでHTMLに変換
  3. flowchart.jsならびにjs-sequence-diagrams.jsでSVGに変換、divに設定

サンプルコード

<!DOCTYPE html>
<html>
    <head>
        <base target="_top">
        <title>Markdown Page</title>
        <!-- marked.js -->
        <!-- SEE: https://github.com/markedjs/marked -->
        <link rel="stylesheet" href="./styles/default.css">
        <script src="./scripts/marked.min.js"></script>
        <script src="./scripts/highlight.pack.js"></script>
        <script>hljs.initHighlightingOnLoad();</script>
        <!-- flowchart.js -->
        <!-- SEE: https://flowchart.js.org/ -->
        <script src="./scripts/raphael.min.js"></script>
        <script src="./scripts/flowchart-latest.js"></script>
        <!-- js-sequence-diagrams.js -->
        <!-- SEE: https://bramp.github.io/js-sequence-diagrams/ -->
        <script src="./scripts/webfont.js"></script>
        <script src="./scripts/snap.svg-min.js"></script>
        <script src="./scripts/underscore-min.js"></script>
        <script src="./scripts/sequence-diagram-min.js"></script>
    </head>
    <body>
        <hr />
        <div id="markdown" style="display: none;">
# Markdownテスト  

プログラムのソースコード例  
```c#
public class MyClass {
    public MyClass() {
        return;
    }
}
```
テーブル例  

|#|Key|Value
|:-|:---|:-----
|1|Name|`echo 'HELLO'`
|2|Varbose|False

フローチャート例  
```flowchart
st=>start: Start:>http://www.google.com[blank]\n
e=>end:>http://www.google.com
op1=>operation: My Operation
op2=>operation: Stuff|current
sub1=>subroutine: My Subroutine
cond=>condition: Yes
or No?\n:>http://www.google.com
c2=>condition: Good idea|rejected
io=>inputoutput: catch something...|request

st->op1(right)->cond
cond(yes, right)->c2
cond(no)->sub1(left)->op1
c2(true)->io->e
c2(false)->op2->e
```

シーケンス図例  
```sequence
Andrew->China: Says Hello
Note right of China: China thinks\nabout it
China-->Andrew: How are you?

Andrew->>China: I am good thanks!
```

以上。
        </div>
        <div id="html"></div>
        <script type="text/javascript">
            var divMarkdown = document.getElementById("markdown");
            var strInput = divMarkdown.innerText;
            // flowchartおよびsequence部分を取り出し、divに置き換える
            var re = /^([ \t]*`{3,}(flowchart|sequence)\s*$\n((?:^(?:(?:[^`]|`(?!``))*)$\n)*)^\s*`{3,}[ \t]*$)/m;
            var defs = new Array();
            while(strInput.match(re)) {
                strInput = strInput.replace(re, function(match, block, type, definition, offset, input) {
                    var n = defs.length + 1;
                    var id = "svg_" + n + "_" + type;
                    defs.push({
                    type: type,
                    definition: definition,
                    id: id
                    });
                    console.log(">> " + type);
                    console.log(definition);
                    return '<div id="' + id + '"></div>';
                });
            }

            // marked
            marked.setOptions({langPrefix: ""});
            var divHtml = document.getElementById("html");
            divHtml.innerHTML = marked(strInput);

            // flowchat and sequence
            for(var i = 0; i < defs.length; ++i) {
                switch(defs[i]["type"]) {
                case "flowchart":
                    flowchart.parse(defs[i]["definition"]).drawSVG(defs[i]["id"]);  
                    break;
                case "sequence":
                    Diagram.parse(defs[i]["definition"]).drawSVG(defs[i]["id"]);
                    break;
                }
            }
        </script>
    </body>
</html>

実際の画面

入力したMarkdown

(html中のdivのinnerText部分)

# Markdownテスト  

プログラムのソースコード例  
```c#
public class MyClass {
    public MyClass() {
        return;
    }
}
```
テーブル例  

|#|Key|Value
|:-|:---|:-----
|1|Name|`echo 'HELLO'`
|2|Varbose|False

フローチャート例  
```flowchart
st=>start: Start:>http://www.google.com[blank]\n
e=>end:>http://www.google.com
op1=>operation: My Operation
op2=>operation: Stuff|current
sub1=>subroutine: My Subroutine
cond=>condition: Yes
or No?\n:>http://www.google.com
c2=>condition: Good idea|rejected
io=>inputoutput: catch something...|request

st->op1(right)->cond
cond(yes, right)->c2
cond(no)->sub1(left)->op1
c2(true)->io->e
c2(false)->op2->e
```

シーケンス図例  
```sequence
Andrew->China: Says Hello
Note right of China: China thinks\nabout it
China-->Andrew: How are you?

Andrew->>China: I am good thanks!
```

以上。

描画結果

…いらぬ横線を消すのを忘れていた。

クライアント側で表示できるので、GoogleSpreadSheetをWebサーバ化して
無料のMarkdown形式のWikiにする、なんてこともできそう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です