Markhor_Engineの使い方

Markhor_Engine documentation

Markhor_Engineは、Markdownで書かれた文章をHTMLに変換するJSプラグインです。
ほかのライブラリには依存せず、ブラウザでもNode.jsでも使えます。
IE 5.5以上、Chrome 1以上、Safari 1以上、Firefox 1以上で動作します。


導入

<script type="text/javascript" src="https://ohiro.ndjp.net/js/markhor_engine.js"></script>を、
<head>か<body>のどこかしらに記述しておいてください。


バージョンを指定したURLでも配信しています。バージョンを固定して使いたいときは、こちらをお使いください。
https://ohiro.ndjp.net/js/markhor_engine/1.3.0/markhor_engine.js
(1.3.0の部分を、使いたいバージョンに変えてください。バージョンを指定しない上のURLは、常に最新版です。)


Node.jsで使うときは、ダウンロードしたファイルをrequireで読み込みます。
var Markhor = require('./markhor_engine.js');

使用

Markhor.render(Markdownの文字列, 設定)を呼ぶと、変換後のHTML文字列が返ってきます。
設定は省略できます(詳しくは「設定」をご覧ください)。
nullやundefinedを渡したときは、空の文字列が返ります。


例

<textarea id="src"></textarea>
<div id="out"></div>

<script type="text/javascript">
  document.getElementById('src').onkeyup = function () {
    document.getElementById('out').innerHTML = Markhor.render(this.value);
  };
</script>


下のテキストボックスに書くと、その下に変換結果が出ます。


使える記法

種類書き方出力されるHTML
見出し(Atx形式)# 見出し(#は1〜6個。後ろに空白が必要。行末に空白を空けて#を書くと、取り除かれる)<h1>〜<h6>
見出し(Setext形式)文字の次の行に===(h1)、---(h2)(=も-も1個以上で成立。上にある複数行の段落が、まとめて見出しになる)<h1>、<h2>
太字**太字**、__太字__<b>
斜体*斜体*、_斜体_(語の途中の_は斜体にならない。*は語の途中でも効く。)<i>
打ち消し線~~打ち消し~~(~が2個のときだけ)<del>
インラインコード`code`(バッククォートで囲む。中にバッククォートを書くときは、囲む個数を増やす。中ではMarkdown記法は効かず、そのまま表示される。)<code>
コードブロック```か~~~(3個以上)の行で囲む。開始行に言語名を書ける(閉じる行は、開始と同じ文字で、同じ個数以上)。または行頭を空白4個かタブで字下げ。<pre><code>
リンク[文字](URL)、[文字](URL "title")('title'や(title)でもよい。title属性がつく)。URLに空白を含めるときは<URL>で囲む。URLの中の(と)は、対になっていれば書ける。<a>
参照リンク[文字][ID]と、別の行に[ID]: URLか[ID]: URL "title"(IDは大文字小文字を区別しない。[文字][]や[文字]とIDを省略すると、文字がIDになる。定義の行は、段落の途中ではなく、段落の先頭にあるものだけが有効)。<a>
自動リンク<https://...>(スキーム)、または<someone@example.com>(mailto:のリンクになる)。<>の中にはhttp系やftp以外のスキームも書けるが、「URLの検査」で許可されたものだけがリンクになる。<>がなくても、行頭、空白、* _ ~ (の後ろにある、http:// https:// ftp://で始まる文字列はリンクになる。<a>
画像![代替テキスト](URL)、![代替テキスト](URL "title")、![代替テキスト][ID]<img>
引用行頭に><blockquote>
箇条書き行頭に- * +と空白。項目の文字の位置まで字下げすると入れ子になる。<ul>
番号つきリスト行頭に1.か1)と空白(数字は9桁まで)。最初の番号がstart属性になる。<ol>
タスクリスト- [ ] 未完了、- [x] 完了操作できないチェックボックス
表|で区切る。1行目が見出し行(<th>)になる。見出し行のすぐ下に、区切りの行(---|---のように-だけのセル。見出し行とセルの数が同じであること)が必要で、無いと表にならず普通の文になる。区切りの行に:を書くと、列ごとに寄せを指定できる(:---左、:---:中央、---:右)。本体の行はセルが足りなければ空欄、多ければ切り捨て。空行や、他のブロック(見出しなど)で表は終わる。セルの中に|を書くときは\|<table>
水平線---、***、___(3個以上。- - -のように空白を挟んでもよい。)<hr>
エスケープ\*のように、記号の前に\。対象はASCIIの記号すべて(! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~)。それ以外の文字の前の\は、そのまま表示される。コードの中では効かない。記号そのもの
文字参照&copy; &#169; &#xA9;のような文字参照は、文字に変換される(名前はHTML5のもの。未知の名前や、;のないものはそのまま表示される)。コードの中では効かない。\&copy;と書くと、変換されない。リンクのURL・title・画像の代替テキストの中でも変換される。文字そのもの
行末の改行行末に空白2個以上か\を書くと、その行で折り返す。コードの中や、段落の最後の行では効かない。<br>
HTMLタグ<div>のようなタグは、HTMLとしては出力されず、文字としてそのまま表示される。&lt;div&gt;


補足
・続けて書いた行は1つの<p>にまとまり、行の区切りは改行文字になります(画面上は空白と同じ)。引用の>のない続きの行も、同じ段落になります。
・リストの項目の間に空行があると、各項目が<p>で囲まれます。別のリストに分けたいときは、記号を変えるか(-の次は*など)、番号つきなら区切りの文字を変えて(.と))ください。
・リストの項目の中に、字下げした段落、コードブロック、引用、入れ子のリストを書けます。入れ子の<ul>や<ol>は、<li>の中に出力されます。
・表の寄せ指定は、<th>と<td>のalign属性になります。表のセルの中で使えるのはインライン記法(太字やリンクなど)だけです。
・リンクと画像は、URLの後ろに空白を空けて"title"と書くと、title属性がつきます。titleの中では、太字などの記法は変換されず、そのまま表示されます。titleが空のときは、つきません。
・画像のaltには、代替テキストから太字などの記号を除いた文字だけが入ります。
・リンクと画像のURLは、日本語や空白などが%E3...のようにパーセントエンコードされ、&は&amp;になって出力されます(すでにある%XXはそのままです)。
・コードブロックの言語名は、開始行の最初の単語がそのまま使われます。コードブロックが閉じられていないときは、文章の最後(囲んでいる引用やリストの終わり)で閉じられます。
・コードブロックの言語名は、class="language-言語名"になるほか、ラベル用の<span>として出力されます。ラベルの見た目は、CSSで指定してください。表示する文字はcodeLangLabelで変えられます。
・引用とリストの入れ子は、合わせて255段までです。それより深いものは、文字として表示されます。極端に入り組んだ文章で処理が続けられないときは、全体が<pre>に入った文字として返ります。


出力されるクラス

クラス付く場所
markhor-code-labeled言語名つきのコードブロックの<pre>
markhor-code-label言語名のラベル(<span>)
language-言語名言語名つきのコードブロックの<code>(language-jsなど)
markhor-taskタスクリストの<li>
markhor-task-boxタスクリストのチェックボックス(<input>)

設定

第2引数に、次のような項目をもつオブジェクトを渡します。すべて省略できます。


var html = Markhor.render(text, {
  linkTarget: '',
  linkRel: 'noopener noreferrer',
  allowImages: false
});

項目初期値説明
linkTarget"_blank"リンクのtargetです。空文字列にすると、targetをつけません。
linkRelなしリンクのrelです。_blankのままなら、"noopener noreferrer"をおすすめします。
allowImagestruefalseにすると画像を表示せず、代替テキストだけを出力します。
allowedSchemesなしリンクに追加で許可するスキームの配列です。例:['sms', 'line'](画像には効きません)
urlFilterなしURLごとに許可するかどうかを決める関数です。「URLの検査」をご覧ください。
unsafeUrlsfalsetrueにすると、スキームの検査をやめます。自分で書いた文章だけを変換するときのみ使ってください。
codeLangLabelなし(言語名を表示)falseにすると、コードブロックのラベルを出力しません。function (lang)という関数を渡すと、その戻り値(文字列)がラベルになります。戻り値が空文字列のときも、ラベルは出ません。言語名のないコードブロックには、もともとラベルがつきません。
closeUnterminatedfalse1.3系のみ(1.4系以降は常にtrueで、指定しても効果がありません)。
閉じられていないコードブロックを、文章の最後で閉じます。falseのままだと、</code></pre>がつかないままHTMLが終わります。

URLの検査

リンクと画像のURLは、変換のときに検査されます。許可されなかったリンクは文字だけ、画像は代替テキストだけになります。


http https ftp mailto tel…リンクで使えます
http https ftp、およびdata:image/のpng jpeg gif webp bmp…画像で使えます
スキームのない相対URL(/a/b、#topなど)…どちらでも使えます
javascript:など、上にないもの…使えません(&colon;や空白を混ぜて隠したものも検出します)


urlFilterは、function (url, kind, ok)という形で書きます。
url…元のURLです(&なども書いたままの、エスケープ前のものです)。
kind…リンクなら"link"、画像なら"image"です。
ok…標準の検査で許可されたかどうか(trueかfalse)です。

戻り値によって、次のように動きます。
false…使わない
文字列…そのURLに置き換える(置き換えたURLには標準の検査が行われません)
true…使う(標準の検査で許可されなくても使うので、javascript:も通ってしまいます)
それ以外(undefinedなど)…標準の検査のとおりにする


例(画像は自分のサイトのものだけ許可する)

Markhor.render(text, {
  urlFilter: function (url, kind, ok) {
    if (kind === 'image' && url.indexOf('https://ohiro.ndjp.net/') !== 0) {
      return false;
    }
    return ok;
  }
});

そのほかの機能

Markhor.version…バージョンの文字列("1.3.0"など)です。
Markhor.escapeHtml(文字列)…& < > "をエスケープした文字列を返します。
Markhor.isSafeUrl(URL, 種類, 設定)…そのURLが許可されるかどうかをtrueかfalseで返します。種類は"link"か"image"で、設定にはrenderと同じものを渡せます。

以前のバージョンの動作(1.3系)

1.3系では、CommonMarkの仕様とは違う動作がいくつかありました。
1.4系で、CommonMarkの仕様に合わせました。


文章の組み立て

項目1.3系まで1.4系以降
段落改行ごとに別々の<p>になる続けて書いた行は1つの段落になる(行末の空白2個か\で<br>)
Setext形式の見出しすぐ上の1行だけが見出しになる上の複数行の段落が、まとめて見出しになる
水平線---のように、同じ文字を続けて書いたものだけ- - -のように空白を挟んでもよい
リストの入れ子字下げが深くなると入れ子になり、<ul>が<li>と<li>の間に出力された項目の文字の位置まで字下げすると入れ子になり、<li>の中に出力される
番号つきリストの番号無視され、常に1から数える最初の番号がstart属性になる
リストの間の空行空行で別のリストに分かれる同じリストのまま、項目が<p>で囲まれる。分けたいときは記号を変える。
リストの項目の中身1行の文字だけ。続きの行は別の段落になりリストが終わる。複数行、複数の段落、コードブロック、引用、入れ子のリストを書ける
引用1行ごとに<p>。中は段落だけで、見出し、リスト、入れ子の引用は使えない。続く行は1つの段落。見出し、リスト、コードブロック、入れ子の引用も書ける。
コードブロックの字下げ引用・リスト・表の中では使えない引用とリストの中でも使える
コードブロックを閉じる行同じ文字が3個以上あれば閉じる開始と同じ文字で、同じ個数以上のときだけ閉じる
閉じられていないコードブロックcloseUnterminatedがfalse(初期値)だと、</code></pre>が出力されない常に最後で閉じる(closeUnterminatedは効果なし)
コードブロックの言語名英数字と_ + # . -の部分だけ。先頭がほかの文字なら言語名なし。開始行の最初の単語がそのまま言語名になる
表|を含む行は、ふつうの文やリストの中でも表の行になった。区切りの行は何行目でも読み飛ばされ、セルの数も揃えない。セルの中の\|でも区切られた見出し行のすぐ下に、セル数の合った区切りの行がないと表にならない。本体の行は列の数に揃えられる。\|はセルの中の|になる。
参照リンクの定義1行で完結するものだけ。段落の途中にあっても有効。URLやtitleが次の行にあってもよい。段落の途中にあるものは無効。


文字の記法

項目1.3系まで1.4系以降
エスケープできる記号\ ` * _ { } [ ] ( ) # + - . !のみ。~ | < >などは対象外ASCIIの記号すべて。記号以外の前の\は、そのまま表示される。
文字参照&copy;は&amp;copy;になり、そのまま「&copy;」と表示される。文字(©)に変換される
太字・斜体の判定単純な置き換え。snake_case_wordの_も斜体になる。前後の文字で判定する。語の途中の_は斜体にならない。
打ち消し線内側に~があると効かない。前後が空白の~~でも効く。前後が空白の~~は効かない(*や_と同じ規則)。~が3個以上並んでいるものは効かない。
改行行末の空白2個や\では折り返せない折り返せる
リンクのURL)を含められない対になった()は書ける。空白を含めるときは<URL>で囲む。
リンクのtitle"..."か'...'だけで、中に)は書けない(...)でもよい。中に)を書ける。
出力されるURL日本語などは書いたままの文字で出力される%E6%97%A5のように、パーセントエンコードされる
画像のalt代替テキストにコードを書くと、<code>などのタグがaltに入ることがある記号を除いた文字だけが入る
<...>の自動リンクhttp https ftpのみ。URLに&があると使えない。メールアドレスも使える。&も書ける。スキームは「URLの検査」で許可されたもののみ。
行の途中の自動リンク行頭と空白の後ろのみ。最後の. , ; : ! ?のうち1文字だけを除いた* _ ~ (の後ろでもよい。最後の? ! . , : * _ ~ ' "、対になっていない)、&amp;のような終わりは、いくつでも除かれる。
入力のU+0001〜U+0004内部で使うため、取り除く。取り除かない(U+0000だけがU+FFFDに変わる)