Edited at

まだまだ Word で消耗してるの? 大学のレポートを Markdown で書こう (Docker 編)

これは以前書いた記事 まだ Word で消耗してるの? 大学のレポートを Markdown で書こう の新版です。環境構築が Docker でスッと行えるようになったので、より消耗しづらくなるかと思います。


みなさん、大学の実験レポートは何で書いていますか? Word ですか?

私も Word で書いていた時代がありますが、特に数式の入力や式番号を振るのに苦労した覚えがあります :innocent: LaTeX でかけばいい感じに数式を組めるのですが、構文がちょっと煩わしいですよね...

そこでみつけた :sparkles: Pandoc :sparkles:


Pandoc について

Pandoc は Haskell で書かれた文章変換ツールです。Markdown から LaTeX、PDF の変換もできますし、ほかにもたくさんのフォーマットに対応しています。

Pandoc を使えば、少々面倒な LaTeX を使わずに、Markdown でガンガンレポートを書いて、ガンガン進捗を生み出せるはず。さらに、実験レポートが .docx ではなく単なるテキストファイルになるため、進捗を Git で管理できるようになります :tada:


環境構築

LaTeX や pandoc のインストールは大変であることが一般に知られています[要出典]。そこで、docker を活用して環境構築をスッとできるようにするのが最近のトレンドです。

先人が作った k1LoW/docker-alpine-pandoc-ja というとても便利な docker イメージもありましたが、ちょっとバージョンが古かったので fork して作り直しました: Kumassy/docker-alpine-pandoc-ja

まずは docker をインストールして、 Kumassy/docker-alpine-pandoc-ja を pull しておきましょう。

docker pull kumassy/alpine-pandoc-ja


チートシート

---

documentclass: ltjsarticle
title: すごいレポート
author: 寿限無
header-includes:
- \usepackage[margin=1in]{geometry}

figureTitle: " "
tableTitle: " "
listingTitle: "コード "
figPrefix: "図."
eqnPrefix: "式."
tblPrefix: "表."
lstPrefix: "コード."
---

# 見出し
## 見出し
いい感じの文章を書いてレポートの本文をうめていく。改行したいときは見難いがこのように→
スペースを 2 つつければ改行できる

1 行空行を空けると[^1]別のパラグラフになる。

![すごい図[^fig]](graph.png){#fig:sugoi}

![この図はちょっと大きいから調整する](graph-large.png){#fig:sugoi-large height=60mm}

| i | サイコロの目 |
|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |

:すごい表 {#tbl:table}

| サンプル | 見た目 / ${\rm m^2 \cdot kg \cdot s^{-3} \cdot A^{-1}}$ | 雰囲気 / ${\rm m^{-2} \cdot kg^{-1} \cdot s^{4} \cdot A^{2}}$ |
|:---------:|----------------------:|----------------------:|
| ポカリスエット | 2 | 40 |
| アクエリアス | 2 | 21 |
| ダカラ | 3 | 8 |

:へんな表 {#tbl:table-long}

この辺で改ページ
\clearpage

## 注意
1. [@fig:sugoi] は普通の図
1. [@fig:sugoi-large] のような大きい図を貼るときは height=70mm などとして適当に調整する
1. [@tbl:table] のように表にラベルをつけるときは `:タイトル {#tbl:tabl}` のように `{}` の前にスペースが必要
1. [@tbl:table-long] のように表のヘッダーが長いときは `:-----------------------:` みたいに 2 行目の `-` を増やせば表の横幅が広くなったりする

## いろいろな式
### インラインの式
本文中に唐突に $E = mc^2$ 埋め込む。

インラインの式中に $a_n = \frac{1}{\pi} \int_{0}^{2\pi} f(x) \cos nx dx$ のような分数やインテグラルが入るとちょっと見にくくなるので、$\displaystyle b_n = \frac{1}{\pi} \int_{0}^{2\pi} f(x) \sin nx dx$ とすると見やすくなる。

### よくある式
$$f(x) = \frac{a_0}{2} + \sum_{n = 1}^{\infty} a_n \cos nx + b_n \sin nx$${#eq:fourier}

こうやって [@eq:fourier] 参照する。

### よくつかうギリシャ文字たち
$\alpha, \beta, \gamma, \delta, \Delta, \varepsilon, \theta, \lambda, \mu, \nu, \pi, \rho, \sigma, \Sigma, \tau, \phi, \omega$

$$\frac{\partial f}{\partial y} \frac{d f}{d x}$$

## ソースコード
``{#lst:awesome-code .javascript .numberLines startFrom="10" caption="すごいコード"}
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");

gulp.task("es6", function() {
return browserify("./src/app.js")
.transform("babelify")
.bundle()
.pipe(source("bundle.js"))
.pipe(gulp.dest("dist"));
});
``

↑↓ホントはバッククォートは3つ書いてください

``
$ cd
$ mkdir -p projectX
$ pbpaste > projectX/gulpfile.js
``

[@lst:awesome-code] のようにするとシンタックスハイライトもできるし行番号もつけれたりするが、長いコードだとページ上の配置や改ページが微妙になることがあってあまり使い勝手がよくなかったりする。
どうせ白黒で印刷するなら下の例のようにしたほうがいい。

### 見出し
#### 見出し
##### 見出し

# 参考文献 {-}
`{-}` をつけるとこのセクションには見出しに通し番号がつかなくなる

-
箇条書き
- 箇条書き
- ネスト
- ネスト
- ネスト

ビルド


bash

docker run -it --rm -v `pwd`:/workspace -v `pwd`:/root/.pandoc/templates kumassy/alpine-pandoc-ja pandoc -F pandoc-crossref report.md -o report.pdf --pdf-engine=lualatex --template mytemplate.tex -N


report-0.png

report2.png

report3.png

report4.png


Pandoc の基本的な使い方と注意点

まず、レポートを Markdown 形式で書きます。


bash

$ cat report.md

Hello, World!

そして、次のコマンドを実行すると、PDF ができます。


bash

docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja pandoc report.md -o report.pdf


HelloWorld.png

簡単ですね :thumbsup: Pandoc は -o オプションで指定した拡張子を判断して、最適なドキュメント形式に変換してくれます。

しかし、日本語を含む文章は注意が必要です。


bash

$ cat report.md

こんにちは、世界!

japaneseErr.png

これを直すには、ドキュメントクラスの指定と、Pandoc が内部で使う LaTeX エンジンの設定が必要です。


bash

docker run -it --rm -v `pwd`:/workspace -v kumassy/alpine-pandoc-ja pandoc report.md -o report.pdf -V documentclass=ltjsarticle --pdf-engine=lualatex


japanese.png

documentclass の設定ですが、-V documentclass=ltjsarticle オプションを渡す代わりに、以下のように YAML メタデータブロックで指定することもできます。


report.md

---

documentclass: ltjsarticle
---

# レポート本文
これから真に驚くべきレポートを書くつもりだが、この余白はそれを書くには狭すぎる



本文をかく :pencil2:


見出しの書き方

普通の Markdown の記法で書けば OK です。


本文

# 見出し

## 見出し
### 見出し
#### 見出し
##### 見出し
###### 見出し
本文

header.png

Pandoc ユーザーズガイドによると 6 段階の見出しを使えるようですが、見た目的には 5 段階までしか使えないようです。使っても 3 階層くらいなので問題ないでしょう。


見出しに通し番号をつける

Pandoc に -N オプションを渡すと、通し番号つきの見出しを作ってくれます。ちなみに、特定の章だけ通し番号を降ってほしくない場合は、見出しの末尾に {-} をつければ OK です。


本文

# 目的

# 原理
# 実験方法
# 実験結果
# 考察
# 参考文献 {-}

headerSomeN.png


相互参照

図表番号を手で管理するのはしんどいので、相互参照を使います。でも、残念ながら Pandoc 単体では相互参照はできません。1 :scream: そこで、pandoc-crossref を使いましょう。

具体的な記法は後で書きますが、例えば図に fig:graph というラベルをつけたとしたら、本文中で [@fig:graph] とすることで、図番号をとってこれます。


pandoc-crossref を使うには

pandoc-crossref をそのまま使うとデフォルトでは eq. 1 fig. 2 のような結果になるので、 prefix の設定が必要です。そのため、以下の設定を YAML メタデータブロックに書いておきましょう。


report.md

---

figureTitle: " "
tableTitle: " "
listingTitle: "コード "
figPrefix: "図."
eqnPrefix: "式."
tblPrefix: "表."
lstPrefix: "コード."
---

ビルドするときにはフィルターの設定をします


bash

docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja pandoc -F pandoc-crossref source.md -o dist.pdf --pdf-engine=lualatex



画像の貼り方

これも普通の Markdown と同じです。


本文

![とても重要な図](the_great_graph.png)


相互参照のラベルをつけるには、次のようにします。


本文

![とても重要な図](the_great_graph.png){#fig:graph}


これを参照するには、本文中で [@fig:graph] としてください。


本文

# 考察

[@fig:graph] を見てください。すごいでしょう👍👍👍


画像のレイアウトについて

LaTeX のように、上に配置、下に配置といった指定はできません。図がページに収まらなかったら、基本的には次のページの一番上に配置されます。Pandoc Markdown では画像のレイアウトはある程度諦めなければなりません :sweat:

それでも、デフォルトでのレイアウトだと困ることもあります。そのときは次の順で試していくといいでしょう。


画像の大きさを変える

次のようにすると、画像の大きさを指定することができます。使える単位は %mm です2。適当に画像の大きさを調整すると、少しはマシなレイアウトになるでしょう。


本文

![とても重要な図](the_great_graph.png){#fig:graph height=70%}



改ページする

適当なところで改ページを入れてあげて、レイアウトを調整するやり方です。Pandoc Markdown では、文章中で LaTeX のコマンドを使えるので、おもむろに \clearpage してあげます。\clearpage はまだ出力していない図を出力して改ページするコマンドです。\newpage だと文章だけしか改行されないのでうまくレイアウトできません。


本文

とても長い文章

\clearpage

# 実験結果
![とても重要な図](the_great_graph.png){#fig:graph height=70%}



LaTeX 記法で書く

上記のやり方ではどうしてもうまくいかない場合は、LaTeX 記法で図を入れることもできます。ただメンテナンスがしづらくなるので、あくまで最終手段として考えましょう。


表の作り方

これも普通の Markdown と同じです。


本文

| i | サイコロの目 |

|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |

table.png

相互参照のラベルをつけるには、次のようにします。{} の前にスペースが必要なので注意してください。


本文

| i | サイコロの目 |

|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |
: すごい表 {#tbl:table}

[@tbl:table] はとてもすごい表だ


tableN.png

Pandoc Markdown の表では上のスタイルの表しか書けません。例えば、この表にサイコロの目の合計の行をつけたかったとします。


本文

| i | サイコロの目 |

|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |
| $\Sigma$ | 29 |

:すごい表 {#tbl:table}

[@tbl:table] はとてもすごい表だ


tableNoTeX.png

Pandoc Markdown では合計の行の上に水平線を引くことができません。そういうときは、LaTeX 記法で表を書くしかありません :cry:

表を最初から LaTeX で書くのはしんどいので、Pandoc でいったん LaTeX を吐いてコピペするのがいいでしょう。


bash

docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja pandoc -F pandoc-crossref src.md -o tmp.tex -N


そうすると LaTeX 形式の表を得られます


bash

$ cat tmp.tex

\begin{longtable}[]{@{}rc@{}}
\caption{\label{tbl:table}すごい表 }\tabularnewline
\toprule
i & サイコロの目\tabularnewline
\midrule
\endfirsthead
\toprule
i & サイコロの目\tabularnewline
\midrule
\endhead
1 & 3\tabularnewline
2 & 2\tabularnewline
3 & 6\tabularnewline
4 & 5\tabularnewline
5 & 1\tabularnewline
6 & 4\tabularnewline
7 & 2\tabularnewline
8 & 6\tabularnewline
\(\Sigma\) & 29\tabularnewline
\bottomrule
\end{longtable}


これを Markdown にそのまま貼り付ければ OK です。もとの Markdown 形式の表はコメントアウトしておきましょう。また、これを PDF に変換するときに ! LaTeX Error: Environment longtable undefined. ! Undefined control sequence. <recently read> \toprule と怒られてしまったので、header-includes に以下のように書いておきましょう。


本文

---

header-includes:
- \usepackage{longtable}
- \usepackage{booktabs}
---

<!-- | i | サイコロの目 |
|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |
| $\Sigma$ | 29 |

:すごい表 {#tbl:table}

[@tbl:table] はとてもすごい表だ -->

\begin{longtable}[]{@{}rc@{}}
\caption{\label{tbl:table}すごい表 }\tabularnewline
\toprule
i & サイコロの目\tabularnewline
\midrule
\endfirsthead
\toprule
i & サイコロの目\tabularnewline
\midrule
\endhead
1 & 3\tabularnewline
2 & 2\tabularnewline
3 & 6\tabularnewline
4 & 5\tabularnewline
5 & 1\tabularnewline
6 & 4\tabularnewline
7 & 2\tabularnewline
8 & 6\tabularnewline \hline
\(\Sigma\) & 29\tabularnewline
\bottomrule
\end{longtable}

[@tbl:table] はとてもすごい表だ


これを通常通り PDF に変換すれば OK です。

tableTeX.png


表のヘッダが改行されてしまう

たまに表のヘッダに気合を入れて単位を書いたりすると、表のヘッダが 1 行に収まらず、改行されてしまうことがあります。


本文

| サンプル | つよさ 1 ${\rm m^2 \cdot kg \cdot s^{-3} \cdot A^{-1}}$ | つよさ 2 ${\rm m^{-2} \cdot kg^{-1} \cdot s^{4} \cdot A^{2}}$ |

|:-----:|-----:|-----:|
| ポカリスエット | 2 | 40 |
| アクエリアス | 2 | 21 |
| ダカラ | 3 | 8 |

: 各サンプルにおけるつよさの評価 {#tbl:table}


tableNoFix.png

こういうときは - を増やせば OK です。


本文

| サンプル | つよさ 1 ${\rm m^2 \cdot kg \cdot s^{-3} \cdot A^{-1}}$ | つよさ 2 ${\rm m^{-2} \cdot kg^{-1} \cdot s^{4} \cdot A^{2}}$ |

|:-----:|----------------------:|----------------------:|
| ポカリスエット | 2 | 40 |
| アクエリアス | 2 | 21 |
| ダカラ | 3 | 8 |

: 各サンプルにおけるつよさの評価 {#tbl:table}


tableFix.png


式の書き方

式の書き方も LaTeX と同じです。インラインスタイルで数式を書くには数式を$で囲い、ブロックスタイルで数式を書くには数式を $$ で囲います。ブロックスタイルの数式には、相互参照のラベルをつけることができます。


本文

# 目的

私の好きな式は $E = mc^2$ です。

[@eq:fourier] も好きです。
$$f(x) = \frac{a_0}{2} + \sum_{n = 1}^{\infty} a_n \cos nx + b_n \sin nx$${#eq:fourier}

ここで $a_n = \frac{1}{\pi} \int_{0}^{2\pi} f(x) \cos nx dx$ で、$\displaystyle b_n = \frac{1}{\pi} \int_{0}^{2\pi} f(x) \sin nx dx$ です。

好きなギリシャ文字は $\alpha, \beta, \gamma, \delta, \Delta, \varepsilon, \theta, \lambda, \mu, \nu, \pi, \rho, \sigma, \Sigma, \tau, \phi, \omega$ です。

$$\frac{\partial f}{\partial y} \frac{d f}{d x}$$


eq.png


注釈

文章中や図・表のタイトルに注釈をつけることができます。以下のソースコードは ] が全角の になっているのでそのままコピペしないようにしてください。


本文

この考え方は正しいでしょう[^1]
注釈の識別子はわかりやすい名前をつけましょう[^we-can-use-very-long-name]

[^1]: ホンマか??
[^we-can-use-very-long-name]: 長い名前も使うことができます。


annotation.png


コメント

HTML 形式のコメントは pandoc から無視されるので、参考文献やTODOをメモするのに便利です。


本文

<!-- TODO: 図を差し替える -->



その他の tips


複数の式を参照する

[@eq:hoge; @eq:piyo; @eq:fuga] とすれば OK です。こうすると、式. 1, 3, 5 や 式. 1-3 という感じになります。複数の表や図を参照する場合も同様です。


式をイコールを揃えてかく

Pandoc Markdown では実現できないので、レポートの文章を工夫してイコールを揃える必要がないようにしましょう。どうしてもイコールを揃える必要がある場合は、LaTeX の align 環境を使えば OK です。


本文

\begin{align}

f(x) &= \frac 1 2 - \frac 2 \pi \sum_{k=1}^{\infty}(\frac{1}{2k - 1}\sin \frac{(2k - 1)}{2}\pi)\cos(2k - 1)x \nonumber \\
&= \frac 1 2 - \frac 2 \pi \{ \cos x - \frac 1 3 \cos 3x + \frac 1 5 \cos 5x - \frac 1 7 \cos 7x - \dots \} \nonumber
\end{align}

eqAlign.png


分子式を書く

mhchem パッケージを使えばいいでしょう。LaTeX のパッケージを使う場合は、YAML メタデータブロックの header-includes\usepackage を書きます。


本文

---

header-includes:
- \usepackage[version=3]{mhchem}
---

私は毎日 2L の \ce{H2O} を飲みます。


chemH20.png

mhchem パッケージはデフォルトではインストールされていないので、tlmgr でインストールしましょう。

$ docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja /bin/bash

# tlmgr install mhchem
# pandoc report.md -o report.pdf --pdf-engine=lualatex


分子構造を書く

chemfig パッケージを使います。分子式と同様に YAML メタデータブロックの header-includes\usepackage を書きましょう。


本文

---

header-includes:
- \usepackage[version=3]{mhchem}
---
\chemfig{*6(-=-=-=)}

chemB.png

大きい分子構造を書いていると、紙面に収まらなくなることがあります。そのようなときは \resizebox を使えばいいでしょう。例えばこれはトコフェロール (ビタミン E) です。

---

header-includes:
- \usepackage{chemfig}
---

\resizebox{\textwidth}{!}{
\chemfig{*6((-R2)=( - R3)-(-[,1.0001] O -[::60]?(-[6]) -[:-30] -[::60] -[:-30] -[::60] (-[2]) -[:-30] -[::60] -[:-30] -[::60](-[2]) -[:-30] -[::60] -[:-30] -[::60](-[2]) -[:-30])=(-[,1.0001] -[:-30] -[6]?)-( - R1)=( - OH)-)} %*
}

chemE.png

chemfig についてはこちらが詳しいので、参照してください :eyes:


chemfigパッケージによる構造式描画

http://doratex.hatenablog.jp/entry/20141212/1418393703



相互参照の色を変える

デフォルトでは相互参照による図表番号が赤色っぽくなってしまいます。筆者は「まあいいだろう :relieved:」とこのままレポートを提出しましたが、指導員に「不自然だ、直せ :imp:」と言われてしまったため、なんとかする方法を探しました。

colorLink.png

YAML メタデータブロックに \hypersetup{ colorlinks = false } を渡せば OK です。


本文

---

header-includes:
- \hypersetup{ colorlinks = false }
---


大学で指定された表紙をつける

pandoc では markdown を PDF に変換するときのテンプレートを好きなのに変えることができるので、レポートの表紙が LaTeX で配布されていれば比較的ラクに表紙をつけることができます。

ただ私が大学から受けとた表紙は :poop: .docx :poop: だったので無限に消耗しました。


できたもの

report-template.png

tabularxtable を組み合わせたらいい感じにできました。ソース: https://gist.github.com/Kumassy/cbecb2a34f68cfd0a6be24426f9c7aa4


表紙の作り方

まずは pandoc がデフォルトで使用しているテンプレートを出力しましょう。今回は latex を選択します。


bash

docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja pandoc -D latex > mytemplate.tex


\begin{document} から \end{document}までが文章の本体なので、必要に応じていじりましょう。ところで、テンプレート中に

$if(title)$

\maketitle
$endif$

などとありますが、title などは YAML メタデータブロックから渡されるデータになります。これをうまく使えば、テンプレート中の 実験題目報告者氏名 を markdown から渡せるようになってハッピーです。


ビルド

--template オプションを使用します


bash

docker run -it --rm -v `pwd`:/workspace kumassy/alpine-pandoc-ja pandoc source.md -o dist.pdf --template mytemplate.tex  --pdf-engine=lualatex



ビルド

、。,. に変換するのが面倒なので、 sed で変換してしまいましょう。 Makefile を作っておくと便利です。


Makefile

report.pdf: report.md

cat report.md | sed -e 's/、/,/g' | sed -e 's/。/./g' | docker run -i --rm -v `pwd`:/workspace -v `pwd`:/root/.pandoc/templates kumassy/alpine-pandoc-ja pandoc -F pandoc-crossref -o report.pdf --pdf-engine=lualatex --template mytemplate.tex -N


まとめ

Markdown でレポートをゴリゴリ書けると捗りますね :thumbsup:


リンク





  1. 注釈 



  2. % って何に対して % なんだろう。。。 :thinking: まあともかく、いい感じの見た目になればいいでしょう。