rougeでシンタックスハイライト
2018年8月、Re:VIEWのEPUB生成でrougeを使用してコードリストをシンタックスハイライトにしました。
Re:VIEWのバージョンは2.5.0です。
>review version 2.5.0
rougeのバージョンは3.2.0です。
>rougify version 3.2.0
Windows10に書籍執筆支援システム「Re:VIEW」をインストールして使用しています。
ソースコードリスト
Re:VIEW フォーマットガイドによると、原稿にソースコードを入れるには、4種類の方法があります。
連番 | 行番号 | コマンド |
---|---|---|
あり | なし | //list[識別子][キャプション][言語指定]{ ~ //} |
あり | あり | //listnum[識別子][キャプション][言語指定]{ ~ //} |
なし | なし | //emlist[キャプション][言語指定]{ ~ //} |
なし | あり | //emlistnum[キャプション][言語指定]{ ~ //} |
- 識別子 : リストを参照するときのID
- キャプション : リストのタイトル
- 言語指定 : ソースコードの言語(省略可能)
ソースコードを参照するときは、@<list>{識別子}と記述します。
Re:VIEWテスト原稿
下記のようなテスト原稿(sample6.re)を作成します。
C++言語のソースコードリストを行番号付きで入れます。言語指定はどのように記述するか不明ですが、取りあえず「cpp」としました。
= ソースコードリスト C++言語で書いたプログラムコードを@<list>{sample}に示します。 //listnum[sample][ラスタースキャン・ループ][cpp]{ void Image_process( ImageFunc efunc ,int iw ,int ih ,const uchar *pucSrc ,uchar *pucDst ) { for(int iy=1; iy<ih-1; iy++) { for(int ix=1; ix<iw-1; ix++) { uchar uc = pucSrc[ (iy+0)*iw + (ix+0) ]; // 中央 uchar ua = pucSrc[ (iy-1)*iw + (ix+0) ]; // 上 uchar ub = pucSrc[ (iy+1)*iw + (ix+0) ]; // 下 uchar ul = pucSrc[ (iy+0)*iw + (ix-1) ]; // 左 uchar ur = pucSrc[ (iy+0)*iw + (ix+1) ]; // 右 // uchar ux = Func_dilation(uc ,ua ,ub ,ul ,ur); pucDst[ iy*iw + ix ] = ux; } } } //}
EPUB生成
生成したEPUBを確認します。
すっきりしたコードリストですが、少々不満があります。
- 等幅フォントでないのでリストが見づらい
- コードリストの背景に薄い色があったほうがよい
PDF生成
生成したPDFを確認します。
TeXらしく美しいコードリストです。等幅フォントでリストは見やすいです。
コードリストの改善
Re:VIEWで生成したEPUBの内容を解析してみます。EPUBをzip解凍して、コードを確認します。(OEBPS>sample6.xhtml)
<div id="sample" class="code"> <p class="caption">リスト1.1: ラスタースキャン・ループ</p> <pre class="list language-cpp"> 1: void Image_process( ImageFunc efunc ,int iw ,int ih ,const uchar *pucSrc ,uchar *pucDst ) 2: { 3: for(int iy=1; iy<ih-1; iy++) 4: { ・・・ 省略 16: } 17: } </pre> </div>
codeクラスの<DIV>タグで全体を囲み、list language-cppクラスの<PRE>タグでソースコードを囲んでいます。
スタイルシートの変更で解決できそうです。
スタイルシートは、config.ymlで指定します。
# CSSファイル(配列で複数指定可) stylesheet: ["style.css"]
スタイルシートstyle.cssの定義を確認します。
pre.emlist, pre.source, pre.list { margin: 0; padding: 5px; border: 1px #aaa solid; background-color: gainsboro; font-family: monospace ; }
listクラスの<PRE>タグに、背景色(background-color:)とフォントファミリー(font-family: monospace )を追加します。
生成したEPUBを確認します。
等幅フォントでコードリストがそろい、またコードリストの背景に色がつきました。
rougeでシンタックスハイライト
listコマンドの言語指定は省略可能ですが、どのような意味を持つのでしょうか。
Re:VIEW フォーマットガイドに次のように記載があるだけで詳細は不明です。
言語指定は、ハイライトを有効にしたときに利用されます。
Re:VIEWでハイライトができそうです。しかし、方法がわかりません。Re:VIEWは素晴らしいツールなのですが、情報が少なくて苦労します。
調べてみると、config.ymlにハイライトの設定がありました。
# ソースコードハイライトを利用する (rouge,pygmentsには外部gemが必要) # highlight: # html: "rouge" # latex: "listings"
知ってる人は当たり前のことなのでしょうが、私はrougeやpygmentsは何なのかわかりません。rougeについて調べてみると、RougeはRubyで書いたシンタックスハイライトのようです。
An elegant, extendable code highlighter written in pure Ruby.
純粋なRubyで書かれたエレガントで拡張可能なコードハイライター。
デフォルトでは、コメントアウトになっていたので highlight:を有効にしてhtml: “rouge”を選びます。
# ソースコードハイライトを利用する (rouge,pygmentsには外部gemが必要) highlight: html: "rouge" # latex: "listings"
外部gemが必要と書いてあるので、別途インストールが必要です。
>gem install rouge Fetching: rouge-3.2.0.gem (100%) Successfully installed rouge-3.2.0 Parsing documentation for rouge-3.2.0 Installing ri documentation for rouge-3.2.0 Done installing documentation for rouge after 13 seconds 1 gem installed >rougify version 3.2.0
生成したEPUBを確認すると、少しだけシンタックスハイライトになりました。
想像していたハイライトとは違って少し地味です。
CSS定義で改善
Re:VIEWで生成したEPUBの内容を解析してみます。EPUBをzip解凍して、コードを確認します。(OEBPS>sample6.xhtml)
<div id="sample" class="code"> <p class="caption">リスト1.1: ラスタースキャン・ループ</p> <table class="highlight rouge-table"> <tbody> <tr> <td class="rouge-gutter gl"> <pre class="lineno">1…</pre> </td> <td class="rouge-code"> <pre><span class="kt">void</span> <span class="nf">Image_process</span> ・・・・ </pre> </td> </tr> </tbody> </table>
codeクラスの<DIV>タグで全体を囲み、テーブルで行番号とコード本体を分離し、rouge-codeクラスの<PRE>タグでソースコードがわからないぐらい<span>による装飾をしています。
rouge用のスタイルシートが必要みたいです。調べてみると、rougeはスタイルシートを生成できるみたいです。
>rougify usage: rougify [command] [args...] where <command> is one of: highlight highlight code help print help info style print CSS styles list list available lexers guess guess the languages of file version print the rouge version number See `rougify help <command>` for more info. >rougify style > rouge.css
スタイルシートをリダイレクトしてrouge.cssに出力します。
スタイルシートは、config.ymlで指定しています。
# CSSファイル(配列で複数指定可) stylesheet: ["style.css"]
rouge.cssも追加します。
# CSSファイル(配列で複数指定可) stylesheet: ["style.css" ,"rouge.css"]
生成したEPUBを確認します。
とてもカラフルなシンタックスハイライトになりました。
rougeの言語指定
//listコマンドの言語指定は、rougeに渡されるわけです。rougeが認識する言語指定について調べてみます。
>rougify usage: rougify [command] [args...] where <command> is one of: highlight highlight code help print help info style print CSS styles list list available lexers guess guess the languages of file version print the rouge version number See `rougify help <command>` for more info. >rougify list ・・・ c: The C programming language ・・・ cpp: The C++ programming language [aliases: c++] ・・・
百種類以上の言語を指定できるようです。C++言語の言語指定は、cppで正解でした。
CSS定義でもう少し改善
等幅フォントではないのでコードリストがそろっていません。スタイルシートをもう少し修正します。
スタイルシートrouge.cssの定義の最後に下記を追加します。
.rouge-code pre{ font-family: monospace ; }
生成したEPUBを確認します。
等幅フォントになりコードリストがそろいました。
まとめ
書籍執筆支援システム「Re:VIEW(EPUB)」でrougeを使用してコードリストをシンタックスハイライトにしました。
Re:VIEW(EPUB)は、外部ツールで拡張してスタイル変更により見え方を変更できるのでとても便利です。