コンテンツにスキップ

ドキュメントと出力画像の同期

v0.10 で導入

ソフトウェアの技術文書では、本文に記載されたコマンド例と貼り付けられた実行結果画像が乖離しがちです。 ツールのバージョンアップに伴ってコマンド出力を撮り直す作業を手動で行っていると、画像と本文の更新漏れが発生しやすくなります。 また、Astro などの静的サイトジェネレーター(SSG)では、ドキュメント内に記述された画像ファイルがローカルに存在しないだけでビルドが停止するため、特定の OS や CI 環境でしか再現できないコマンド画像の取り扱いが開発の妨げになります。

console2svg batch markdown は、Markdown や MDX 内のコメントマーカーを検出して端末コマンドを実行し、生成された画像をドキュメントへ自動反映するバッチ同期機能です。 手動のスクリーンショット撮影を排除し、ドキュメントの記述と実行結果を常に一致させます。

ドキュメントへの画像埋め込みは、マーカーの配置とバッチコマンド実行の 2 つの工程で行います。

  1. ドキュメント内の画像を配置したい位置に <!-- c2s:: [command] --> 形式のコメントマーカーを記述します。

    example.md
    `dotnet --info` を実行すると以下の出力が得られます。
    <!-- c2s:: dotnet --info | head -n10 -->
  2. 入力ディレクトリと画像の出力先を指定して batch markdown を実行します。

    Terminal
    console2svg batch markdown -i ./docs -o ./assets
  3. コマンドがマーカーを解析して端末出力をキャプチャし、指定ディレクトリへ SVG 画像を保存します。 同時に元の Markdown ファイルが自動で書き換わり、マーカーの直後に画像リンクが挿入されます。

    example.md
    `dotnet --info` を実行すると以下の出力が得られます。
    <!-- c2s:: dotnet --info | head -n10 -->
    ![dotnet --info | head -n10](assets/generated/a1b2c3d4.svg)

すでにマーカーの直後に画像リンクが存在している場合は、リンクを重複して挿入することなく、参照先の画像ファイルだけを上書き更新します。

Web サイトのビルドシステムによっては、ファイルの物理的な出力先と Markdown 上で記述すべき URL パスが異なる場合があります。 この差異を吸収するのが --link-base オプションです。

Terminal
console2svg batch markdown \
-i ./docs \
-o ./my-site/public/assets \
--link-base /assets

例えば Astro では、/public/assets/ に配置された静的アセットは、Markdown から /assets/filename.svg という絶対パスで参照します。 -o で実際の配置場所を指定しつつ、--link-base に Web 上の公開パスを指定することで、Markdown に挿入される画像リンクのプレフィックスを任意に調整できます。

生成された画像を Git リポジトリの管理下に含めるかどうかは、プロジェクトの規模やリポジトリ容量の方針に応じて選択します。

画像点数が少なく、リポジトリ単体で完結させたい場合は、生成された画像ファイルと更新された Markdown の双方をそのままコミットします。

Terminal
console2svg batch markdown -i docs -o assets
git add docs assets
git commit -m "docs: 実行例の画像を更新"

この運用では、クローンした直後の開発環境であってもすべての画像が揃っているため、追加の生成手順を踏むことなくローカルでドキュメントサイトをビルドできます。

画像を Git 管理から除外する場合

Section titled “画像を Git 管理から除外する場合”

画像アセットが多数に及び、Git リポジトリの容量肥大化を避けたい場合は、画像ファイルを .gitignore で管理対象外とし、Markdown には画像リンクを付与せずマーカーのみを保持します。

example.md
<!-- c2s:: echo "Hero Image" -->
画像リンクを手動で書かないことで、アセット管理をビルドパイプラインへ委ねます。

ドキュメントサイトの公開時に、CI パイプライン内で batch markdown を実行して画像を生成し、そのまま静的アセットとしてデプロイします。

deploy.sh
console2svg batch markdown -i ./docs -o ./public/assets
npm run build

ただし、この方式ではローカル環境に画像が存在しないため、SSG のビルドが失敗する原因になります。 この問題は、次に述べる batch restore または --placeholder で解決します。

外部生成アセットの同期とローカルビルド

Section titled “外部生成アセットの同期とローカルビルド”

CI 上でのみ画像を生成する構成では、ローカル開発環境のビルドを通すための補助機能を利用します。

batch restore によるリモートアセットの復元

Section titled “batch restore によるリモートアセットの復元”

batch markdown は画像を生成する際、出力ディレクトリの直下にアセットのマニフェスト情報である assets.json を自動出力します。

  • ディレクトリassets/
    • ディレクトリgenerated/
      • a1b2c3d4.svg
    • assets.json

このマニフェストファイルを CI 上で公開アセットと一緒にデプロイしておけば、ローカル環境から batch restore を実行してリモートの生成済み画像をダウンロードできます。

Terminal
console2svg batch restore -o ./assets \
https://example.com/assets/assets.json

リモートに存在しなくなった古い画像ファイルをローカルから一掃したい場合は、--prune オプションを付加して同期します。

--placeholder による即時ビルドの確保

Section titled “--placeholder による即時ビルドの確保”

ネットワーク経由での画像ダウンロードを待たずに、とにかくローカルでのサイト構築を通したい場合は、--placeholder を指定します。

Terminal
console2svg batch markdown -i ./docs -o ./assets --placeholder

このオプションを指定すると、実際のコマンド実行を一切行わず、マーカーが要求するファイル名で 0 バイトのダミーファイルを即座に作成します。 SSG の「画像ファイルが存在しない」というリンク切れエラーを回避し、マークアップの執筆やレイアウト調整に専念できます。

コマンドハッシュによる画像アセットの共有

Section titled “コマンドハッシュによる画像アセットの共有”

同一のコマンドとオプションで指定されたマーカーは、たとえ異なるファイルに分散して配置されていても、ハッシュ値が一致するため単一の画像アセットとして共有されます。

<!-- c2s:: -w 100 -h 12 --- dotnet --info | head -n10 -->

この仕様は、多言語化ドキュメントを構築する際に特に有効です。 英語ドキュメントと日本語ドキュメントで同じコマンド実行結果を掲載する場合、それぞれに同じマーカーを記述しておけば、出力される画像ファイルは 1 つにまとめられ、ストレージとビルド時間を節約できます。

単なるインラインコマンドの実行にとどまらず、画面の装飾設定や出力形式の変更、前処理・後処理の自動化が可能です。

マーカー行の区切り記号(--)の前に、console2svg capture と共通のオプションを指定できます。

example.md
<!-- c2s:: -w 100 -h 10 -d macos -t nord --format png -- dotnet --version -->

--format png を指定すると、SVG の代わりに PNG 形式の画像が生成され、Markdown にも .png へのリンクが挿入されます。

YAML による実行ライフサイクルの制御

Section titled “YAML による実行ライフサイクルの制御”

実行前の環境構築や、実行後に作成された不要ファイルの削除を制御する場合は、マーカーの内部に YAML 形式でライフサイクルを定義します。

example.md
<!-- c2s:: -w 100 -h 10 -d macos
setup:
dotnet build
capture:
dotnet run --no-build
teardown:
rm -f temporary-file
-->

setup に記述されたコマンドは環境を準備するためだけに実行され、その出力は画像に含まれません。 画面としてキャプチャされるのは capture に指定されたコマンドの実行結果のみです。 すべての処理が終了した後は、成否に関わらず teardown に指定された後処理が実行されます。

名前付きコードブロックの参照

Section titled “名前付きコードブロックの参照”

ドキュメント内に記載されたサンプルコードをそのまま実行してキャプチャに収めたい場合は、コードブロックに c2s-id を付与し、マーカー内から {code:id} で参照します。

example.md
```csharp c2s-id=program
Console.WriteLine("Hello from C#!");
```
```bash c2s-id=run
dotnet run app.cs
```
<!-- c2s::
setup: |
cat > app.cs <<'EOF'
{code:program}
EOF
capture: "{code:run}"
teardown: rm -f app.cs
-->

この記法を用いることで、解説用のサンプルコードと実行コマンドを二重管理する手間を排し、コードブロックを修正した際に画像の中身も自動的に追従させることができます。

セキュリティに関する注意事項

Section titled “セキュリティに関する注意事項”

マーカー内に記述された setup、capture、teardown の各スクリプトは、実行環境のシェル上でそのまま評価されます。 第三者から送られた Pull Request や、信頼できない外部の Markdown ファイルに対して batch markdown を無差別に実行してはいけません。 悪意あるコマンドの混入を防ぐため、CI 環境で自動実行する場合は対象ブランチや権限を厳密に制限してください。