Markdownファイルで外部ファイルをインポートするならcog

Markdownドキュメント内で外部のファイルの内容を引用したい場面が多々ある。プログラムや設定ファイルの説明などを加工としているときに多い。

外部ファイルの内容をコピーしてMarkdownドキュメントにペーストしても解決するが、外部ファイルの内容が変更された時には、Markdownドキュメント側も変更する必要があり、保守が大変になる。

cogというコードジェネレータを使ってこの問題を解決した。

例えば以下の様なMarkdownファイルを用意する。

以下はZookeeper用Dockerfileである。

<!-- [[[cog
import cog
filepath = "/home/laclefyoshi/Documents/zookeeper/Dockerfile"
label = "#lst:zookeeper_dockerfile"
format = ".dockerfile"
caption = "Zookeeper用Dockerfile"
cog.outl("```{%s %s .numberLines caption=\"%s\"}" % (label, format, caption))
with open(filepath) as f:
    cog.outl("".join(f.readlines()).strip())
cog.outl("```")
]]] -->
<!-- [[[end]]] -->

filepathに適切なファイルを配置し、cogコマンドでこのファイルを処理させる。

$ cog.py memo.md

結果は以下のとおり。

以下はZookeeper用Dockerfileである。

<!-- [[[cog
import cog
filepath = "Dockerfile"
label = "#lst:zookeeper_dockerfile"
format = ".dockerfile"
caption = "Zookeeper用Dockerfile"
cog.outl("```{%s %s .numberLines caption=\"%s\"}" % (label, format, caption))
with open(filepath) as f:
    cog.outl("".join(f.readlines()).strip())
cog.outl("```")
]]] -->
```{#lst:zookeeper_dockerfile .dockerfile .numberLines caption="Zookeeper用Dockerfile"}
FROM centos
MAINTAINER SAEKI Yoshiyasu <@laclefyoshi>

WORKDIR /tmp
RUN yum install -y java-1.7.0-openjdk-devel.x86_64 tar.x86_64
ENV JAVA_HOME /usr/lib/jvm/java
RUN curl -O http://ftp.tsukuba.wide.ad.jp/software/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
RUN tar zxvf zookeeper-3.4.6.tar.gz
RUN cp zookeeper-3.4.6/conf/zoo_sample.cfg zookeeper-3.4.6/conf/zoo.cfg
RUN mkdir -p /tmp/zookeeper
RUN mv zookeeper-3.4.6 /opt/

WORKDIR /opt/zookeeper-3.4.6
ENTRYPOINT ["./bin/zkServer.sh"]
CMD ["start-foreground"]
EXPOSE 2181
```
<!-- [[[end]]] -->

これをpandocでHTML出力すると、以下のようになる。

逆にコードの中にドキュメントを書く(文芸的プログラミング)という方法もあるが、今回はドキュメントの割合が大きかったので、こういう解決策を選んだ。