前回pre
タグの中でPug記法を使う方法を紹介しました。
実際に使っていたのですが、少々具合が悪いことに気が付きました。
:pug(pretty=true)
フィルタを指定した場合、
ブロック要素は改行されるのですが、インライン要素では改行されません。
また、Pugのpretty=true
のオプションも廃止予定のようです。(すっかり忘れてました。)
ですので、今回は別の方法を探してみたいと思います。単に使うfilterを変更するだけです。
モジュールを探して追加
pretty
がうまく処理できるようなフィルタを探しました。
:pug
でPug→HTMLに変換したあとに、HTMLを整理するフィルタを使えば良さそうです。
探してみたところ、 jstransformer-html-beautifyというモジュールが見つかりました。 早速インストールします。
$ npm install --save-dev jstransformer-html-beautify
試す
以下のPugテンプレートで試します。文章はWikipediaから拝借しました。
div パグについて
p
| #[b パグ](Pug)は、犬の種類(犬種)の一つ。短鼻の小型犬。#[br]
| 短毛でダブルコート、垂れ耳、巻き尾。
| 毛色はフォーン(サンプル画像の毛色)、#[span.black 黒]、#[span.white 白]、#[span.slver シルバー]など。
//
シルバーの毛色は見たことない!
|
| なお、黒以外の毛色の場合は鼻から口の周辺及び耳は黒い。
| フォーンのパグは背中に沿って黒のトレースがある
sup [1]
| 。
まずは前回の方法です。filterには:escape-html:pug(pretty=true)
を指定しています。
pre
code
:escape-html:pug(pretty=true)
...
結果
<div>パグについて</div>
<p><b>パグ</b>(Pug)は、犬の種類(犬種)の一つ。短鼻の小型犬。<br/>
短毛でダブルコート、垂れ耳、巻き尾。
毛色はフォーン(サンプル画像の毛色)、<span class="black">黒</span>、<span class="white">白</span>、<span class="slver">シルバー</span>など。
<!--シルバーの毛色は見たことない!
-->
なお、黒以外の毛色の場合は鼻から口の周辺及び耳は黒い。
フォーンのパグは背中に沿って黒のトレースがある<sup>[1]</sup>。
</p>
ブロックタグが1行目の場合、不自然な改行が出てしまいます。
また、Pugフィルタにdoctype
を指定していないので、XMLと認識されbr
タグに閉じスラッシュが入ってしまいます。
続いて新しい方法です。fitlerには:escape-html:html-beautify(indent-size=2 inline=''):pug(doctype='html')
を指定します。
:pug
にはdoctype='html'
を指定し、:html-beautify
にはindent-size=2
とinline=''
を指定しました。
pre
code
:escape-html:html-beautify(indent-size=2 inline=''):pug(doctype='html')
...
indent-size
はその名の通りインデントの幅を指定することができます。今回は2
にしました。
inline
は、インライン要素のタグ名を指定します。指定したタグ名がインライン要素のタグとして認識され、それ以外の要素はブロックタグとして認識されます。
今回は何も指定していないので、全てのタグがブロック要素のタグとして認識されるようになります。
ブロック要素タグは、開始タグの直後に別のブロック要素がある場合、改行を入れます。つまり、ブロック要素の開始直後にインライン要素タグがある場合も改行されて表示されます。
結果
<div>パグについて</div>
<p>
<b>パグ</b>(Pug)は、犬の種類(犬種)の一つ。短鼻の小型犬。
<br>
短毛でダブルコート、垂れ耳、巻き尾。
毛色はフォーン(サンプル画像の毛色)、<span class="black">黒</span>、<span class="white">白</span>、<span class="slver">シルバー</span>など。
<!--シルバーの毛色は見たことない!-->
なお、黒以外の毛色の場合は鼻から口の周辺及び耳は黒い。
フォーンのパグは背中に沿って黒のトレースがある<sup>[1]</sup>。
</p>
<p>
<sup>a</sup>
</p>
これで前回よりも少し見やすい状態になりました。
mixinを指定したくても...
今回のfilterは少し複雑です。
HTMLを表示するpre
タグを使うたびに指定するのは面倒です。
そう思ってmixin
を指定しようとしたのですが、どうやらそれは出来ないようです。
mixin
にはMixin Blocksという機能があります。
Mixin Blocksはmixin
を呼び出す際に、その中に内包するように要素を指定すると、
mixin
の中でblock
を指定すると、内包した要素を出力することができます。
しかし以下のように指定しても、blockという文字が出力されてしまい、本来出力してほしい内容(block
)は出力されません。
mixin html_code
pre
code
:escape-html:html-beautify(indent-size=2 inline=''):pug(doctype='html')
block
+html_code
...
上記以外にもいろいろと試行錯誤したのですが、mixin
のblock
にフィルタを適用することはできませんでした。
仕方ないので都度フィルタを指定する方法を取ることにしています。
おまけ
pre > code
で表示するならhighlight.jsおすすめですが、
filterとしてhighlightjsと同じように動作するjstransformer-highlightもあります。
highlightフィルタを使うと、ソースコードをあらかじめハイライトした状態のHTMLを生成します。
キーワードが色付きのspan
タグで囲われて、エスケープ済みの状態で生成されます。
つまり、ブラウザでhighlight.jsを実行する必要が無くなるので、コンテンツの軽量化も見込めます。
導入も簡単で、npm
でjstransformer-highlight
をインストールして、
:escape-html
の代わりに:highlight
を指定するだけです。
$ npm install --save-dev jstransformer-highlight
pre
code
:highlight(lang='html'):html-beautify(indent-size=2 inline=''):pug(doctype='html')
...