昨今Markdownベースでドキュメントサイトを構築することが増えています。Markdownでサクッと書いてWebで公開。バージョン管理もできてとても良い感じです。しかしサイトのコンテンツを書籍のような組版文書にしようとすると途端にハードルが高くなります。
映えるPDFを作りたい
見映えを気にしないでPDFを作りたいだけなら、ブラウザの印刷機能を利用できます。しかし、表紙・目次・ページ番号付きで、書籍や論文や取説や仕様書に相応しいレベルのPDFとなるとどうでしょう。なかなか一筋縄ではいきませんよね。職場で仕様書や簡易取説・手順書などをバージョン管理しやすいMarkdownで書きたくても、綺麗なPDFを出力する手段がなく、諦めてWordを使う経験をしたことのある方も多いのではないでしょうか。
Vivliostyle
そんな悩みを解決してくれる素晴らしいプロダクトがあります。Vivliostyleです。Vivliostyleは、Markdownやhtmlを元に、css組版によって書籍品質のPDFを出力できるOSSです。コマンドライン版のVivliostyle CLIも提供されており、元となる原稿群とconfigファイルを準備すればPDF組版文書が出力できます。ドキュメントサイトの生成時にこのconfigファイルを一緒に生成することができれば、VivliostyleによるPDF化で高品質な文書を出力できるということです。
HugoからVivliostyleのconfigを出力する
HugoはMarkdownからWebサイトを生成できる静的サイトジェネレータで、The world’s fastest framework for building websites
の謳い文句の通り、非常に高速にドキュメントサイトをビルドできます。テーマ作成により独自テンプレート出力が可能なので、これによりVivliostyleにインプットするconfigファイルを適切に出力すれば
のように、執筆からPDF生成までシームレスに統合できるはずです。
hugo-theme-vivliocli
これらのアイデアから、ドキュメントサイトとともにVivliostyle用のconfigファイルを出力するHugoテーマ、 hugo-theme-vivliocli を作りました。テーマの詳しい使い方は User Guide を参照してください。出力例でもあるPDF版はこちらです。以下、簡単に機能を紹介します。
表紙・目次・しおり・章番号・ページ番号つき組版PDFを任意ディレクトリから出力
_pdf.md
ファイルが配置された任意のセクションを、表紙・目次・しおり・章番号・ページ番号を含む組版PDFとして出力できます。章番号はMarkdownファイルの階層構造に加えファイル内の見出しまで考慮して自動で割り当てられます。1つのサイトに複数の_pdf.md
を置くこともできるため、複数のPDF文書からなるドキュメントサイトの構築が可能です。
セル結合を含む複雑な表の描画
csvファイルを読み込む形でMarkdown内に表を描画できます。csvの各セル内部でもMarkdown記法を使用できます。また独自記法(||
, ->
)によりセルの縦横結合も可能です。表のキャプションやテキスト整列などにも対応しています。
MermaidとMathjaxをサポート
Mermaidによるダイアグラム描画とMathjaxによる数式描画が可能です(PDF化可能なのは後述のバッチ使用時)。
\frac{\pi}{2} =
\left( \int_{0}^{\infty} \frac{\sin x}{\sqrt{x}} dx \right)^2 =
\sum_{k=0}^{\infty} \frac{(2k)!}{2^{2k}(k!)^2} \frac{1}{2k+1} =
\prod_{k=1}^{\infty} \frac{4k^2}{4k^2 - 1}
使い道
GitHubPagesでドキュメント公開しつつPDFも用意したり、個人ブログをテーマごとにPDF出力してムック本や技術書にしてみたり、仕様書、取説などプロダクトに関連する一連のPDFを1サイトで管理運営したり、色々考えられます。因みに筆者はまだPDFを実際に入稿したことはないので、このテーマで出力したPDFを入稿して紙の書籍化する場合のハードルは未検討です。
実際に使ってみる
Hugo, Vivliostyle, hugo-theme-vivliocli を使って実際にPDFを作成してみましょう。筆者の環境がWindowsなのでコードはWindowsをベースに記載します。
HugoとVivliostyleのインストール
こちらからHugoをインストールします。Windowsの場合以下のようにwingetからインストールできます。
winget install Hugo.Hugo
次にVivliostyleをインストールします。Node.js環境がない場合は先にインストールしておいてください。
npm install -g @vivliostyle/cli
サイトを作成する
Hugoで新しいサイトを作成します。
hugo new site myPDF
cd myPDF
こちらからダウンロードしたSource code (zip)
を展開して/themes/hugo-theme-vivliocli
となるように適宜リネームして配置します。また、/themes/hugo-theme-vivliocli/exampleSite/config
ディレクトリを/config
にコピペします。
configの編集
/config/default.toml
を開き以下の行を削除しましょう。
themesdir = "../.."
また、baseURL,titleを編集します。
baseURL = ""
title = "My PDF Site"
PDF表紙を作る
/content/ja/firstpdf
ディレクトリを作成し、/content/ja/firstpdf/_pdf.md
を作成します。これがPDFの表紙兼設定ファイルになります。内容は見たらなんとなく分かるかと思います。詳しくはこちら。
---
pdfname: 'firstpdf'
doctitle: 'My first pdf'
subtitle: 'subtitle'
header: '2023/5/2'
author: 'auther'
pagesize: 'A5'
book: true
cover: true
toc: true
sectionNumberLevel: 2
colophon: false
outputs:
- vivlio_cover
- vivlio_config
---
コンテンツを作る
/content/ja/firstpdf/_index.md
を作成して以下のように編集します。これはサイトのチャプターページとなります。PDF出力時には含まれないので適当にタイトルだけつけておきます(ちなみにサイト上ではweight順にメニューに表示されます)。
---
title: "firstpdf"
weight: 10
---
次に/content/ja/firstpdf
下にfirst.md
,second.md
を作成して記事を書きましょう。Hugoではフロントマターのtitle
がトップレベルの見出しになるので、Markdown的には見出し2(##)以下を本文として書くことになります。
---
title: "最初の記事"
weight: 10
---
## 最初の記事
こんにちは。これは最初の記事です。
書けたらHugoでプレビューしてみましょう。
hugo server --config config/default.toml
http://localhost:1313
にアクセスすればサイトプレビューを閲覧できます。適当に記事を追加したり編集・保存したりしてみてください。Hugoのライブリロード機能によりリアルタイムに編集した内容が反映されると思います。
セル結合した表を挿入してみる
以下のcsvをfirst.md
の横にtest.csv
という名前で配置し、first.md
からincludeしてみましょう。
A,B,C,D
A-1,B-1,C-1,D-1
||,B-2,C-2,**D-2**
## includeしてみる
{{< include "./test.csv" >}}
サイトを出力する
以下のコマンドでサイトをビルドします。
hugo --config config/default.toml
public
ディレクトリにサイトが出力されます。ドキュメントサイトとしてホストする場合にはこのディレクトリを成果物としてアップします。ローカル環境でも/public/ja/index.html
をブラウザで開くことで閲覧できます。
PDFを出力する
PDF出力時にはconfig.toml
のisPDF
フラグをtrueに設定しておく必要があります。default.toml
を書き換えてもよいのですが、環境変数で一時的に上書きしてビルドしてみましょう。
set HUGO_PARAMS_ISPDF=true
hugo --config config/default.toml
同じくpublic
ディレクトリにWebサイトが出力されます。/public/ja/index.html
を開くとメニューが消えて目次になっているのがわかるかと思います。また/public/ja/firstpdf
には_pdf.vivlio.config.js
と_pdf.vivlio.cover.html
が出力されています。これらが_pdf.md
を元に出力されたVivliostyle用configファイルと表紙ファイルです。実装の都合上この場所でそのままビルドができないので、1階層上にコピーし、/public/ja/_pdf.vivlio.config.js
と/public/ja/_pdf.vivlio.cover.html
という状態にしてください。
これで準備が整ったのでVivliostyleでビルドしてみましょう。
cd public/ja
vivliostyle build -c _pdf.vivlio.config.js
/public/ja/firstpdf.pdf
が出力されたら成功です。実際に使用する際には毎回これらの操作をするのは大変なので、スクリプトを用意することになります。Windows限定ですが、テーマのCI
ディレクトリにはサイトのビルドからVivliostyleによるPDF出力まで実施するバッチ/powershellスクリプトをつけています(数式とMermaid図描画のための中間処理などもやっています)。
さいごに
本記事ではHugoを扱いましたが、Hugoに限らず様々な静的サイトジェネレータで同じような仕組みにより組版PDF文書が出力可能なサイトを作れるのではないかと思います。Markdownで書いて、ドキュメントサイトと美しいPDFを同時に手に入れましょう!