ちょっと話題の記事

44種類のフォーマットに対応したPandocでMarkdownをHTML形式に変換する

MarkdownファイルをHTMLへの変換で採用したPandocの解説です。公式Dockerが提供されていたりCI/CDに組み込みやすいツールだったので前のめりにご紹介。
2020.03.17

「GitHubに格納したMarkdown、ええ感じで公開したいんやで!!」

Markdownで書いたドキュメントを何らかの形で公開したいというニーズは凄くあると思います。いろんなツールをあれこれ探していたんですが、やっぱり「Pandoc」に落ち着きました。

  • 変換フォーマットが超絶豊富
  • HTML用テンプレートが用意されている
  • WordやPDFにも変換できる
  • 公式DockerイメージがあるのでCI/CDに組み込みやすい
  • おまけにGitHub Actionsのサンプルもあるで!

結構今どきのツールだったので、前のめりに紹介いたします!!

(祭) ∧ ∧
 Y  ( ゚Д゚)
 Φ[_ソ__y_l〉     ドキュメント変換マツリダワッショイ
    |_|_|
    し'´J

利用するツールはPandoc

今回利用するツールは、Universal Documet ConverterのPandoc

Pandoc - About pandoc

If you need to convert files from one markup format into another, pandoc is your swiss-army knife. Pandoc can convert between the following formats:
引用:Pandoc - About pandoc

様々なマークアップ文章フォーマットをあらゆる形式に変換するツールです。そう、スイスアーミーナイフのように…

というわけで、万能文書変換ツールといえばわかりやすい。

Pandocの魅力

そんな万能文書変換ツールのPandocですが、ちょっと調べてみた限りでも、魅力が一杯です。

魅力①「対応するフォーマットが膨大」

Pandocの特徴は、対応フォーマットが非常に幅広い点。全部で44種類の文書形式に対応しており、変換元と変換先双方に対応しているフォーマットも非常に多いです。

フォーマット分類 フォーマット 変換元 変換先
Lightweight markup formats Markdown
reStructuredText
AsciiDoc
Emacs Org-Mode
Emacs Muse
Textile
txt2tags
HTML formats HTML4
HTML5
Ebooks EPUB version 2 or 3
FictionBook2
Documentation formats GNU TexInfo
Haddock markup
Roff formats roff man
roff ms
TeX formats LaTeX
ConTeXt
XML formats DocBook version 4 or 5
JATS
TEI Simple
Outline formats OPML
Data formats CSV tables
Word processor formats Microsoft Word docx
OpenOffice/LibreOffice ODT
OpenDocument XML
Microsoft PowerPoint
Interactive notebook formats Jupyter notebook (ipynb)
Page layout formats InDesign ICML
Wiki markup formats MediaWiki markup
DokuWiki markup
TikiWiki markup
TWiki markup
Vimwiki markup
XWiki markup
ZimWiki markup
Jira wiki markup
Slide show formats LaTeX Beamer
Slidy
reveal.js
Slideous
S5
DZSlides
Custom formats custom writers can be written in lua.
PDF PDF

今回紹介するMarkdownやHTMLは当然として、reStructuredText、Textile、LaTeX、何故かCSV,EPUB、docx(Word)や、pptx(PowerPoint)、Jupyter notebook、各種Wiki形式、PDFに対応しています。

魅力②「メタデータや独自フォーマットへの豊富な対応」

Pandocは、Markdownのシンタックス拡張や、ドキュメントメタデータ、テーブル、脚注、箇条書き、上付き文字、下付き文字、順序付きリストに対応しています。文書変換時に、このあたりのフォーマット情報がきちんと変換されるのは心強い。

魅力③「定期的なアップデート」

Pandoc - Releasesを見るとわかりますが、ほぼ3ヶ月に一度ほど定期的に更新されています。最新のリリースは2020年2月15日と非常にフレッシュ! 自分実はPandoc自体は3年ぐらい前からその存在はしっていて、かなり歴史が長いプロダクトだと思うんですが、今でもこれぐらいの頻度で更新されているのは心強い。

魅力④「公式Dockerイメージが提供されていて、CI/CDで使いやすい」

個人的に一番気に入っているポイントが、公式よりDockerイメージが提供されているところ。

PandocはHaskell製のツールで、通常の利用には各クライアントへのインストールが必要なのですが、公式でDockerイメージが提供されています。

ので、Dockerがインストールされている環境では、以下のようなワンライナーで即文書変換が可能です。この場合、カレントディレクトリにあるREADME.mdREADME.pdfに変換します。

docker run --rm --volume "$(pwd):/data" --user $(id -u):$(id -g) pandoc/latex README.md -o README.pdf

Dockerイメージが提供されているということは、各種CI/CDツールで使いやすい。例えば、MasterブランチへのMarkdownテキストプッシュをトリガーに自動的にHTMLやPDFに変換して、Web公開するという使い方もできます。

魅力⑤「GitHub Actions のサンプルあり」

公式から、GitHub Actionsのサンプルも提供されていたりします。素敵!

pandoc/pandoc-action-example: using the pandoc document converter on GitHub Actions

実際にHTMLへの変換をやってみる

実際に、MarkdownファイルからHTMLへの変換をやってみます。

基本的な使い方

今回自分は、pandocをクライアントインストールせずに公式で提供されるdockerイメージを利用します。その場合のMarkdown(sample.md)をHTML(sample.html)に変換する基本的な構文は以下のとおり。

docker run --rm --volume "$(pwd):/data" --user $(id -u):$(id -g) pandoc/core sample.md -o sample.html

dockerコマンドの内容を簡単に解説すると、以下の通り。

  • --volume "$(pwd):/data"
    • クライアントのカレントディレクトリをコンテナ内の/dataフォルダにマウント
  • --user $(id -u):$(id -g)
    • クライアントのユーザーとグループを利用してコンテナを実行
  • pandoc/core
    • DockerHubの公式Dockerイメージを利用

pandocをDocker使わずに、普通にクライアントにインストールして利用する場合は、pandoc/core 〜以降を、pandoc 〜で書き換えて利用します。以降のスクリプト例では、pandocをクライアントインストールした内容となっています。

各オプションについての公式マニュアル

Pandoc、オプションが膨大にあります。詳細はこちらの公式ドキュメントを参照。

Pandoc - Pandoc User’s Guide

アウトプットファイルの指定

-oオプションで、出力ファイル名を指定します。これを指定しない場合、変換結果は標準出力に出力されます。

pandoc -s sample.md -o sample.html

HTMLファイルとしての出力

-sオプションにより、HTMLファイルが適切なheadbodyタグを出力してくれます。後続のスタイルシート指定の際にも必要なので、HTMLファイル出力時は必須のオプションです。

pandoc -s sample.md -o sample.html

スタイルシートの指定

pandocのデフォルトだと、出力されたHTMLのスタイルがそっけないので、独自のスタイルを埋め込みたい場合、-cオプションで、スタイルシートを指定できます。

pandoc sample.md -c style.css -o sample.html

目次(Table of Contents)の生成

見出しタグ(H要素)をまとめた目次を生成します。

  • --toc
    • 目次の生成
  • --toc-depth=NUMBER
    • 目次を生成するH要素のレベル。デフォルトでは3となっていて、その場合H1〜H3が目次として生成されます
pandoc -s --toc -c style.css --toc --toc-depth=2 sample.md -o sample.html

テンプレートファイルの指定

HTMLの文書構造から指定するため、Pandocにはテンプレート機能があり、そのテンプレートを指定することができます。

  • --template=FILE|URL
    • テンプレートに利用するファイルへの相対パス、もしくはURL

テンプレートファイルの書き方のマニュアルはこちらに定義されています。

templates - Pandoc User’s Guide

提供されているテンプレートを使って省力化

上記ドキュメントを参考にテンプレートファイルをイチから作成しても良いんですが、結構手間がかかるので、おすすめは、それっぽいテンプレートを使って自分好みに編集していく方法です。

自分が探した限りだと、このリポジトリがおすすめ。この中のhtmlディレクトリに、HTML用のテンプレートファイルが格納されています。

ryangrose/easy-pandoc-templates: A collection of portable pandoc templates with no dependencies

この中のhtml/elegant_bootstrap_menu.htmlがおすすめで、これを利用する場合こんな感じです。

pandoc -s --toc --template=easy-pandoc-templates/html/elegant_bootstrap_menu.html sample.md -o sample.html

こんな感じで変換されます!いい感じ。

--tocオプションを併用することで、ドキュメントなどによくある見出しを左側に固定して表示できるので、Markdownで書いたドキュメントをHTMLに変換するときに使いやすいと思います。細かい見た目は、ここからスタイルシートを変更して対応可能。

導入も簡単で手間も少なくMarkdownをHTMLに変換できる便利ツール

今回自分が変換したいドキュメントはこちら。まだ思いっきり書きかけやけど。

classmethod/aws-container-design-guide: AWSにおけるコンテナスタンダード(AWS環境においてコンテナ基盤を構築するにあたり、そのベストプラクティスをまとめた文書。想定読者はアプリケーション開発者ではなく、インフラ設計者)

GitHubでそのままMarkdownみてもらおうと思ったんですが、ある程度の分量になってくるとやっぱり目次もつけたHTMLで公開したいなぁという欲がでてきて、このPandocを触ってました。自分にとってはなんと言っても、公式でDockerイメージが提供されていることによるCI/CDへの組み込みやすさが魅力です。

まだ実装できていませんが、近いうちにGitHub Actionsに組み込んで、Markdownを自動的にHTMLにしてS3から公開することを目論んでいます。HTML以外にもWordやPDFへの変換もやりたいですね。先人の知恵、ありがたい。

それでは、今日はこのへんで。濱田(@hamako9999)でした。