環境構築が Docker でスッと行えるようにした新版を公開しました
まだまだ Word で消耗してるの? 大学のレポートを Markdown で書こう (Docker 編)
https://qiita.com/Kumassy/items/ffa752da5f7193c4929c
みなさん、大学の実験レポートは何で書いていますか? Word ですか?
私も去年は Word で書いていたのですが、特に数式の入力や式番号を振るのに苦労した覚えがあります 今年は LaTeX で書いてやる! と心に決めていたのですが、LaTeX のシンタックスはちょっと面倒くさい感じがしました...
そこでみつけた Pandoc
Pandoc について
Pandoc は Haskell で書かれた文章変換ツールです。Markdown から LaTeX、PDF の変換もできますし、ほかにもたくさんのフォーマットに対応しています。
Pandoc を使えば、少々面倒な LaTeX を使わずに、Markdown でガンガンレポートを書いて、ガンガン進捗を生み出せるはず。さらに、実験レポートが .docx ではなく単なるテキストファイルになるため、進捗をガンガン Git にコミットしていくことも可能です
準備
以下のものをインストールしておいてください。詳しい手順については、ここでは割愛します。
- pandoc
- pandoc-crossref
例えば、このあたりが参考になると思います。
Markdown+Texの環境構築と使い方
http://qiita.com/ish_774/items/82cbda064792306a5493
チートシート
---
documentclass: ltjsarticle
title: すごいレポート
author: 寿限無
header-includes:
- \usepackage[margin=1in]{geometry}
---
# 見出し
## 見出し
いい感じの文章を書いてレポートの本文をうめていく。改行したいときは見難いがこのように→
スペースを 2 つつければ改行できる
1 行空行を空けると[^1]別のパラグラフになる。
[^1]: 注釈
![すごい図[^fig]](graph.png){#fig:sugoi}
![この図はちょっと大きいから調整する](graph-large.png){#fig:sugoi-large height=60mm}
[^fig]: 図のタイトルなどにも注釈をつけることができる
| 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"));
});
'''
↑↓ ここは ' ではなく本当は `
'''
$ cd
$ mkdir -p projectX
$ pbpaste > projectX/gulpfile.js
'''
[@lst:awesome-code] のようにするとシンタックスハイライトもできるし行番号もつけれたりするが、長いコードだとページ上の配置や改ページが微妙になることがあってあまり使い勝手がよくなかったりする。
どうせ白黒で印刷するなら下の例のようにしたほうがいい。
### 見出し
#### 見出し
##### 見出し
# 参考文献 {-}
`{-}` をつけるとこのセクションには見出しに通し番号がつかなくなる
- 箇条書き
- 箇条書き
- ネスト
- ネスト
- ネスト
ビルド
pandoc -F pandoc-crossref report.md -o report.pdf --latex-engine=lualatex --template=mytemplate.tex -N
Pandoc の基本的な使い方と注意点
まず、レポートを Markdown 形式で書きます。
$ cat report.md
Hello, World!
そして、次のコマンドを実行すると、PDF ができます。
pandoc report.md -o report.pdf
簡単ですね Pandoc は -o
オプションで指定した拡張子を判断して、最適なドキュメント形式に変換してくれます。
しかし、日本語を含む文章は注意が必要です。
$ cat report.md
こんにちは、世界!
これを直すには、ドキュメントクラスの指定と、Pandoc が内部で使う LaTeX エンジンの設定が必要です。
pandoc report.md -o report.pdf -V documentclass=ltjsarticle --latex-engine=lualatex
追記 (2017/04/14)
documentclass の設定ですが、以下のように YAML メタデータブロックで指定することもできます。その場合、コマンドラインでの -V documentclass=ltjsarticle
オプションは不要です。
---
documentclass: ltjsarticle
---
# レポート本文
これから真に驚くべきレポートを書くつもりだが、この余白はそれを書くには狭すぎる
本文をかく
見出しの書き方
普通の Markdown の記法で書けば OK です。
# 見出し
## 見出し
### 見出し
#### 見出し
##### 見出し
###### 見出し
本文
Pandoc ユーザーズガイドによると 6 段階の見出しを使えるようですが、実際は 5 段階までしか使えないようです。使っても 3 階層くらいなので問題ないでしょう。
見出しに通し番号をつける
Pandoc に -N
オプションを渡すと、通し番号つきの見出しを作ってくれます。ちなみに、特定の章だけ通し番号を降ってほしくない場合は、見出しの末尾に {-}
をつければ OK です。
# 目的
# 原理
# 実験方法
# 実験結果
# 考察
# 参考文献 {-}
相互参照
図表番号を手で管理するのはしんどいので、相互参照を使います。でも、残念ながら Pandoc 単体では相互参照はできません。1 そこで、pandoc-crossref を使いましょう。
具体的な記法は後で書きますが、例えば図に fig:graph
というラベルをつけたとしたら、本文中で [@fig:graph]
とすることで、図番号をとってこれます。
pandoc-crossref を使うには
pandoc-crossref をそのまま使うとデフォルトでは eq. 1
fig. 2
のような結果になるので、 prefix の設定が必要です。なので、以下のような config.yaml
を ~/.pandoc-crossref
に作っておきましょう。
figureTitle: "図 "
tableTitle: "表 "
listingTitle: "コード "
figPrefix: "図."
eqnPrefix: "式."
tblPrefix: "表."
lstPrefix: "コード."
ビルドするときにはフィルターの設定をします
pandoc source.md -o dist.pdf -F pandoc-crossref --latex-engine=lualatex
参考:
Markdownで相互参照を使うならpandoc-crossref
http://d.hatena.ne.jp/LaclefYoshi/20150616/crossref
画像の貼り方
これも普通の Markdown と同じです。
![とても重要な図](the_great_graph.png)
相互参照のラベルをつけるには、次のようにします。
![とても重要な図](the_great_graph.png){#fig:graph}
これを参照するには、本文中で [@fig:graph]
としてください。
# 考察
[@fig:graph] を見てください。すごいでしょう👍👍👍
画像のレイアウトについて
LaTeX のように、上に配置、下に配置といった指定はできません。図がページに収まらなかったら、基本的には次のページの一番上に配置されます。Pandoc Markdown では画像のレイアウトはある程度諦めなければなりません
それでも、デフォルトでのレイアウトだと困ることもあります。そのときは次の順で試していくといいでしょう。
画像の大きさを変える
次のようにすると、画像の大きさを指定することができます。使える単位は %
か 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 |
相互参照のラベルをつけるには、次のようにします。{}
の前にスペースが必要なので注意してください。
| i | サイコロの目 |
|------:|:------:|
| 1 | 3 |
| 2 | 2 |
| 3 | 6 |
| 4 | 5 |
| 5 | 1 |
| 6 | 4 |
| 7 | 2 |
| 8 | 6 |
: すごい表 {#tbl:table}
[@tbl:table] はとてもすごい表だ
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] はとてもすごい表だ
Pandoc Markdown では合計の行の上に水平線を引くことができません。そういうときは、LaTeX 記法で表を書くしかありません
表を最初から LaTeX で書くのはしんどいので、Pandoc でいったん LaTeX を吐いてコピペするのがいいでしょう。
pandoc -F pandoc-crossref src.md -o tmp.tex -N
そうすると LaTeX 形式の表を得られます
$ 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 です。
表のヘッダが改行されてしまう
たまに表のヘッダに気合を入れて単位を書いたりすると、表のヘッダが 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}
こういうときは -
を増やせば 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}
式の書き方
式の書き方も 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}$$
注釈
文章中や図・表のタイトルに注釈をつけることができます。以下のソースコードは ]
が全角の ]
になっているのでそのままコピペしないようにしてください。
この考え方は正しいでしょう[^1]。
注釈の識別子はわかりやすい名前をつけましょう[^we-can-use-very-long-name]。
[^1]: ホンマか??
[^we-can-use-very-long-name]: 長い名前も使うことができます。
コメント
HTML 形式のコメントは pandoc から無視されるので、参考文献やTODOをメモするのに便利です。
<!-- TODO: 図を差し替える -->
グラフの書き方
長くなりそうなので、別ページで解説します(執筆中)...
matplotlib で書きます
その他の 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}
分子式を書く
mhchem パッケージを使えばいいでしょう。LaTeX のパッケージを使う場合は、YAML メタデータブロックの header-includes
に \usepackage
を書きます。
---
header-includes:
- \usepackage[version=3]{mhchem}
---
私は毎日 2L の \ce{H2O} を飲みます。
分子構造を書く
chemfig パッケージを使います。分子式と同様に YAML メタデータブロックの header-includes
に \usepackage
を書きましょう。
---
header-includes:
- \usepackage[version=3]{mhchem}
---
\chemfig{*6(-=-=-=)}
大きい分子構造を書いていると、紙面に収まらなくなることがあります。そのようなときは \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)-)} %*
}
chemfig についてはこちらが詳しいので、参照してください
chemfigパッケージによる構造式描画
http://doratex.hatenablog.jp/entry/20141212/1418393703
相互参照の色を変える
デフォルトでは相互参照による図表番号が赤色っぽくなってしまいます。筆者は「まあいいだろう 」とこのままレポートを提出しましたが、指導員に「不自然だ、直せ 」と言われてしまったため、なんとかする方法を探しました。
YAML メタデータブロックに \hypersetup{ colorlinks = false }
を渡せば OK です。
---
header-includes:
- \hypersetup{ colorlinks = false }
---
大学で指定された表紙をつける
pandoc では markdown を PDF に変換するときのテンプレートを好きなのに変えることができるので、レポートの表紙が LaTeX で配布されていれば比較的ラクに表紙をつけることができます。
ただ私が大学から受けとた表紙は .docx だったので無限に消耗しました。
できたもの
tabularx
や table
を組み合わせたらいい感じにできました。ソース: https://gist.github.com/Kumassy/cbecb2a34f68cfd0a6be24426f9c7aa4
表紙の作り方
まずは pandoc がデフォルトで使用しているテンプレートを出力しましょう。今回は latex を選択します。
pandoc -D latex > mytemplate.tex
\begin{document}
から \end{document}
までが文章の本体なので、必要に応じていじりましょう。ところで、テンプレート中に
$if(title)$
\maketitle
$endif$
などとありますが、title
などは YAML メタデータブロックから渡されるデータになります。これをうまく使えば、テンプレート中の 実験題目 や 報告者氏名 を markdown から渡せるようになってハッピーです。
ビルド
--template
オプションを使用します
pandoc source.md -o dist.pdf --template=mytemplate.tex --latex-engine=lualatex
ビルド
Makefile
を作っておくと便利です。
report.pdf: report.md
cat report.md | sed -e 's/、/,/g' | sed -e 's/。/./g' | pandoc -F pandoc-crossref -o report.pdf --latex-engine=lualatex -N
エディタについて
現状では Atom + Markdown Preview Plus がいいと思います。ただ、たまにうまくレンダリングしてくれなくなることがあって、安定性はいまいちよくないです。。。
まとめ
Markdown でレポートをゴリゴリ書けると捗りますね
作業環境
筆者の作業環境です
macOS 10.12.6
pandoc-crossref-0.2.5.0
$ latex -v
pdfTeX 3.14159265-2.6-1.40.17 (TeX Live 2016)
$ pandoc -v
pandoc 1.19.2.1
リンク
- Pandoc ユーザーズガイド 日本語版
http://sky-y.github.io/site-pandoc-jp/users-guide/
これを読めばだいたい解決する - pandoc-crossref
https://github.com/lierdakil/pandoc-crossref