azukipochette's weblog

memory dump (mini)

Git リポジトリ上の Markdown ファイルを編集したら自動的に PowerPoint ファイルを生成するようにした話

前回の続編です。

前回までで Pandoc が動く Docker イメージを作ったので docker pull と docker run をすれば手軽に Markdown から PowerPoint が生成できるようになったのですが、自分はいいもののほかの人に使ってもらうためには Docker の環境を構築して docker run のためのコマンドを説明して...とかなり大変なので、Git リポジトリ上の Markdown を書き換えたら自動的に PowerPoint を生成されるよ!というふうにする気になりました。今回はその自動化の話です。

Markdown (*.md) ファイルを再帰的に探索して Pandoc で PowerPoint ファイル (.pptx) に変換する

手動を前提にしていた時は気にしなくてよかったのですが、自動化するので複数ファイルの変換をどうやってやるか考えます。

今回の場合は、サブ フォルダーも含めてどこかにある *.md から同じ名前の *.pptx を生成するようにします。「ほかのフォルダーに同名のファイルがあった場合はどうするの?」という問題はありますが、私の利用用途では問題にならないので、考慮していません。

また、生成した "*.pptx" は out フォルダーを作ってそこに放り込むことにします。ここでも「フォルダ構造は無視でいいの?」という話がありますが、これも考慮しません。*1

というわけで、以下のようなシェルス クリプトを書きました。

#!/bin/sh
mkdir out

find `pwd` -name "*.md" | while read line
do
  echo $line
  filename=`basename $line .md`
  pandoc $filename.md -o ./out/$filename.pptx 
done

カレント フォルダー配下の Markdown ファイルを取得し、そのパスから Pandoc で次々に PowerPoint ファイル化するようにしています。

echo しているのは、ちゃんとファイルを見つけられているかどうかを確認するためのものですので、不要なら消しちゃってください。

docker run 時にシェルスクリプトを実行するようにする

作ったシェルスクリプトをホスト側で実行するかコンテナ側で実行するかは人によって好みがことなるかも知れませんが、結局コンテナ側で実行することにしました。 というわけで、前回の Dockerfile を以下のように書き換えます *2。 なお、先ほどのシェル スクリプト ファイルは run.sh という名前にしています。

FROM ubuntu:18.04

# Update ubuntu
RUN apt-get update -qq
RUN apt-get upgrade -qq

RUN apt-get install -y wget
RUN wget -q https://github.com/jgm/pandoc/releases/download/2.2.1/pandoc-2.2.1-1-amd64.deb
RUN dpkg -i pandoc-2.2.1-1-amd64.deb

# Install texlive
RUN apt-get install -y texlive-latex-recommended

# install wkhtmltopdf
RUN apt-get install -y -qq xvfb libfontconfig wkhtmltopdf

RUN apt-get clean

VOLUME /workspace
WORKDIR /workspace

COPY run.sh /usr/local/bin/run.sh
RUN chmod +x /usr/local/bin/run.sh
CMD ["run.sh"]

最後の 3 行を追加しました。

パスの通っている適切な場所にスクリプト ファイルをコピーして、chmod で実行権限をつけて CMD で呼び出しています。

docker build は大変遅いので、作った docker イメージを Docker Hub ようなパブリックなリポジトリか、Container Repository のようなプライベートなリポジトリに docker push するとよいと思います。

自動ビルドを使って Markdown ファイルが変更されたら PowerPoint ファイルを生成するようにする

無料で使える自動ビルド サービスといえば、Circle CI が有名だと思うのですが、今回の場合は Markdown ファイルのバージョン管理も一緒にさせたいので、まるっと 5 名までなら無料枠で使える Visual Studio Team Services を使います。*3

Visual Studio Team Services の場合、自動ビルドに使用するホストされたエージェントは Windows、MacOS、Linux から選べますが...今回は Linux を選びました *4

せっかくなので、自動化に使用した YAML ファイルを共有します。docker pull するときのイメージ名などはご自身の環境に合わせて変更してください (<yourname> の部分)。

resources:
- repo: self
queue:
  name: Hosted Linux Preview
  condition: succeeded()
steps:
- bash: |
   docker pull <yourname>/pandoc:latest
   docker run --rm -v $(Build.SourcesDirectory):/workspace <yourname>/pandoc 
  displayName: Bash Script

- task: PublishBuildArtifacts@1
  displayName: Publish Artifact: drop
  inputs:
    PathtoPublish: '$(Build.SourcesDirectory)/out'

あとは、継続的インテグレーション設定にしておけば、ファイルが変更されるたびに自動的に PowerPoint ファイルが生成されるようになります! (そんなに頻繁に生成したい?...という話はありますが...)

おまけ

これまで Visual Studio Team Services の自動ビルド設定を説明するときには、設定手順を書かなくてはならずとてもツラかったのですが、YAML ファイルの登場で方法の共有が手軽になったのはいいですね。ただ、まだ Preview 機能なので、[Preview features] から [Build YAML definitions] を有効にしないと使えませんのでご注意を (アカウント単位で有効化が必要)。

それでは、よい自動化生活を。Enjoy!

*1:どちらも大規模/無管理でないかぎり運用で回避できると予想

*2:はてなブログって Dockerfile の Syntax Highlight って対応していないのでしょうか...??

*3:ツールの組み合わせについては、Jenkins がいい!、GitLab がいい!などいろいろと好みがあると思いますので、お好きな組み合わせでどうぞ

*4:Windows 以外は preview なのですが、Windows を選ぶ必要が理由がないので...