グローバル環境を可能な限り汚染せずにMarkdownから組版のPDFを生成(ゆめみ大技林 '23)
本稿は2023年5月に開催された技術書典 14と技術書同人誌博覧会 8にて無料で配布していた ゆめみ大技林 '23の寄稿している記事のウェブ版です。
グローバル環境を可能な限り汚染せずにMarkdownから組版のPDFを生成
組版の PDF を生成するためのツールに Vivliostyle があります。本書籍も Vivliostyle を使用して Markdown ファイルから組版の PDF を生成していますが、各々の環境で Vivliostyle をどうやって動かすかという課題がありました。当初は yarn を使って Vivliostyle をインストールしていました。そこで問題となるのが PATH や各端末にインストールされているツールのバージョンの違いなど、環境要因で環境構築に失敗するケースがあります。
そこで本稿では環境依存の問題を極力発生しない形で Vivliostyle を動かす方法をご紹介します。
本稿で紹介すること
- Vivliostyle を使用して Markdown ファイルから組版の PDF を生成する方法
- Vivliostyle を動かす時に可能な限り依存ツールをインストールしない方法(本稿ではそれをグローバル環境を汚染しないという表現を用いています)
- make コマンドを活用して、各ツールのインストールと実行を簡略化する方法
動作確認環境
- OS: macOS 13.3.1 (a) (22E772610a)
- CPU: Apple M2 Pro
本稿のサンプルコード
本稿のサンプルコードは https://github.com/yusuga/markdown-to-typesetting-pdf になります。
本稿で取り扱うツール
ツール名 | 用途 |
---|---|
brew | macOS向けのパッケージマネージャー |
Docker | コンテナ仮想化プラットフォーム |
colima | Dockerコンテナを実行するための軽量なLinuxベースの仮想化環境 |
Vivliostyle | Web技術を用いて電子書籍の作成、表示、印刷を可能にするCSSフレームワーク |
Markdownから組版のPDFを生成する方法
1. brewをインストール
brew は macOS のパッケージマネージャーです。いわば、ツールを管理するためのツールです。
まず、brew 自体は次のようにインストールします。執筆時点で公式サイトに記載のもののため、今後変更される可能性があることにご注意ください。
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/
install.sh)"
2. Dockerをインストール
Docker は、コンテナ型の仮想環境を実行するためのプラットフォームです。
仮想環境とは、macOS 上に別の OS を仮想的に構築して、その仮想環境内に閉じた形で色々なアプリケーションを実行できるというイメージです。
インストール方法は、公式の「Install Docker Desktop on Mac」にインストーラがありますが、本稿では brew 経由でインストールします。
brew install docker
3. colimaをインストール
colima は、Docker コンテナを実行するための軽量な Linux ベースの仮想化環境です。
Docker Desktop は大企業(従業員が 250 人以上、または年間収益が 1,000 万ドル以上)が商用利用する場合には有料のサブスクリプションが必要になります。ただし、 Docker 自体の使用は無料なため、本稿では Dcoker Desktop の代替で colima を利用する方法をご紹介します。
colima は brew 経由でインストールします。
brew install colima
4. colimaの起動
Docker を動かすために colima を起動します。
colima start
5. Vivliostyleの実行
Vivliostyle は、Web 技術を用いて電子書籍の作成、表示、印刷を可能にする CSS フレームワークです。
Vivliostyle は Docker 経由で実行します。PDF を生成するには各種ファイルが必要となるため、現時点ではひとまず -v
でバージョンを表示して実行可能なことを確認します。
docker run \
--rm \
-v $(pwd):/local \
-w /local \
ghcr.io/vivliostyle/cli:6.1.0 -v
Tips
Vivliostyle の Docker image は公式が配布しています。
makeコマンドをタスクランナーとして使用する
ここまでで各ツールのインストールと実行をご紹介しました。本項では、これらのコマンドを make コマンドにまとめて、環境構築も合わせて実行する方法をご紹介します。
makeコマンドとは
make
コマンドは、UNIX 系の OS ではデフォルトで使用可能なコマンドです。本来は C で書かれたソースコード一式をビルドするためなどに使われていました。本稿では make コマンドをタスクランナー(各コマンドを実行)として使用します。その他の選択肢としてはシェルスクリプトを使用する方法もあります。筆者は両方運用してみた結果、make コマンドの記述の方がわかりやすいという理由で make コマンドを選択しています。
Makefileの記述
全文は、 yusuga/markdown-to-typesetting-pdf/blob/main/Makefile をご参照ください。
1. 変数を定義
Makefile 内ではさまざまな PATH にアクセスしているため、それらを変数で定義しています。変数名を大文字にしてるのは Makefile の慣例です。定義した変数は $(変数)
で展開でき、定義した値が文字列として差し代わるだけの単純な仕組みです。
# Makefileがあるディレクトリを取得するScript
MAKEFILE_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
# 以下は MAKEFILE_DIR から各ディレクトリやファイルへのPATH
MAKEFILE_PATH := $(MAKEFILE_DIR)/Makefile
BOOK_DIR := $(MAKEFILE_DIR)/book
VIVLIOSTYLE_WORKSPACE_DIR := $(BOOK_DIR)/.vivliostyle
OUTPUT_DIR := $(BOOK_DIR)/output
BOOK_PATH := $(OUTPUT_DIR)/ebook.pdf
2. .PHONYを定義
make コマンドは実行時に make コマンド名と同名のファイルやディレクトリがあるとそれらを優先して解釈されます。そこで .PHONY
を定義することで make コマンドの実行が優先されるようになります。定義場所はどこでもいいのですが、コマンド定義の前の行に書かれることが多いです。
.PHONY: open
## pdfを開く
open:
open $(BOOK_PATH)
3. 各ツールのインストール
各ツールを実行する前に必要なツールがインストールされているかを command
で確認します。brew のみ、単純にインストールできないためインストールされているかの確認のみになります。
.PHONY: check_brew
check_brew:
@if ! command -v brew >/dev/null 2>&1; then \
echo "brewをインストールする必要があります。 https://brew.sh/index_ja"; \
exit 1; \
fi
.PHONY: install_docker
install_docker:
@if ! command -v colima >/dev/null 2>&1; then \
brew install docker; \
fi
.PHONY: install_colima
install_colima:
@if ! command -v colima >/dev/null 2>&1; then \
brew install colima; \
fi
.PHONY: start_colima
start_colima:
@if [ $$(colima status 2>&1 | grep -c "not running") -eq 1 ]; then \
colima start; \
fi
複数の make コマンドを 1 つの make コマンドにまとめます。make コマンドは次のようにコマンド名をスペース区切りで記述すると順番に実行されます。
.PHONY: prepare_docker
prepare_docker: \
check_brew \
install_docker \
install_colima \
start_colima
4. Dockerの実行
Docker の実行の前に前述の prepare_docker
を実行させるために DOCKER
変数を定義します。これにより $(DOCKER) run
と書けば、必ず prepare_docker
を実行してから docker run
を実行できます。
DOCKER = \
@$(MAKE) prepare_docker; \
$(shell command -v docker)
Tips
変数への代入は :=
ではなくて =
を使用します。これらは変数の初期化タイミングの違いがあります。:=
は即時展開変数といい、変数に値を代入するタイミングで式が評価されます(実行されます)。=
は単純展開変数といい、変数が参照されたタイミングで式が評価されます。これらは変数にコマンドを書く場合には注意する必要があり :=
で書いてしまうと、make コマンドの実行前に変数が確定してしまうため(つまりは式が評価される)、=
を使う必要があります。
5. Vivliostyleの実行
Docker 経由での Vivliostyle の実行には前述の DOCKER
変数を使用します。こうすることで Vivliostyle を実行するために必要なツールのインストールと Docker を実行可能な状態にできます。本稿では Vivliostyle で build するために必要なことは割愛しますが、サンプルコードには build するために最低限必要なファイルが追加してあります。
## https://github.com/vivliostyle/vivliostyle-cli/pkgs/container/cli
VIVLIOSTYLE_CLI_IMAGE_NAME := ghcr.io/vivliostyle/cli
VIVLIOSTYLE_CLI_IMAGE_TAG := 6.1.0
VIVLIOSTYLE_CLI = $(DOCKER) run \
--rm \
-v $(BOOK_DIR):/local \
-w /local \
$(VIVLIOSTYLE_CLI_IMAGE_NAME):$(VIVLIOSTYLE_CLI_IMAGE_TAG)
.PHONY: pdf
## pdfを生成
pdf:
$(VIVLIOSTYLE_CLI) build \
--no-sandbox
Tips
Docker image 名とタグバージョンを変数化することで、バージョンの変更をしやすくしています。
6. 生成ファイルの削除
環境構築時に生成した各種ファイルや生成した成果物を削除する make コマンドです。何か問題が発生し、リセットしたい場合に役立ちます。
.PHONY: clean
## 生成ファイルをすべて削除
clean:
rm -rf $(VIVLIOSTYLE_WORKSPACE_DIR)
rm -rf $(OUTPUT_DIR)
@if command -v colima >/dev/null 2>&1; then \
$(MAKE) stop_colima; \
fi
Tips
make コマンドでは環境構築のリセットや生成物の削除する用途のコマンドには、慣例的に clean
が命名されています。
まとめ
本稿では、Docker を使うことによって Vivliostyle を動かすために必要なツールをグローバルな環境にインストールせず実行する方法をご紹介しました。また、Docker Desktop の代わりに colima を利用することで、Docker を無料で使用できるため、どなたでも気軽に試せる構成になっています。
前回のゆめみ大技林 '22 では「グローバル環境を汚染しない Xcode の開発環境構築」を執筆したのですが、今回も同様に Docker を利用して環境依存の問題をなくそうというテーマでした。最近は Ruby や Node を使わないといけないなったらすぐに Docker を使って環境を分離したい、という思考になってきています。さまざまなツールにより便利になっていく反面、より環境構築周りが複雑化してきている気がします。引き続き環境依存をなくしたツール利用を模索していきたいです。
Discussion