屋根裏

コードを書いたりします

Pandocを使ってMarkdownでレポートを書いてみる

普段はWordでレポートを書いているのですが、数式が多いときやソースコードを貼るときなんかは正直面倒です。

理系でレポートを書くって言うとLaTeXを使っている人が多いような印象もあるのですが、LaTeXも慣れるまでは色々と大変そうです。

そこで、普段メモや授業のノートを取るのに使っているMarkdownを使ってレポートを書けるようにしてみます。素のMarkdownでは章番号や相互参照などが使えないので、Pandocを導入してみます。

インストール

LaTeX

LaTeXは以前大学の授業で使ったので既に入れていたのですが、w32texTeXインストーラ3でインストールした気がします。

Pandoc

GitHubからインストーラをダウンロードして実行します。

pandoc-crossref

GitHubからzipファイルをダウンロードします。Pandocのバージョンとpandoc-crossrefがビルドされたバージョンが同じになるように注意してください。

zipファイルを解凍して出てきたexeファイルはPandocをインストールしたフォルダ(おそらくC:\Program Files\Pandoc\です)に入れます。

環境

$ luatex -v
This is LuaTeX, Version 1.07.0 (TeX Live 2018/W32TeX)
(略)
$ pandoc -v
pandoc 2.7.3
Compiled with pandoc-types 1.17.5.4, texmath 0.11.2.2, skylighting 0.8.1
(略)
$ pandoc-crossref -v
pandoc-crossref v0.3.4.1 git commit 02e7cffbe81e183fb58bcb88959fc6682ceb56b5 (HEAD) built with Pandoc v2.7.3, pandoc-types v1.17.5.4 and GHC 8.4.4

実行

試しに以下のhoge.mdをPandocでPDFにしてみます。

最初にYAMLメタデータブロックでタイトルや筆者などを指定できます。コードブロックに使っている'''```に置き換えてください。

---
title: Sample
author: torin
figureTitle: "図"
tableTitle: "表"
listingTitle: "コード"
figPrefix: "図"
eqnPrefix: "式"
tblPrefix: "表"
lstPrefix: "コード"
---

# 見出し1

## 見出し2

![イラスト](figure.png){#fig:figure height=50%}

\clearpage

| A    | B    | X    |
| ---- | ---- | ---- |
| 0    | 0    | 0    |
| 0    | 1    | 0    |
| 1    | 0    | 0    |
| 1    | 1    | 1    |

: AND回路の真理値表 {#tbl:table}

$$
a^2+b^2=c^2
$$ {#eq:equation}

'''{.python #lst:code .numberLines caption="HelloWorld"}
print("Hello World")
'''

[@fig:figure]や[@tbl:table]、[@eq:equation]、[@lst:code]のように相互参照ができる[^comment][^comment]: 注釈もつけられる

次のコマンドを実行すると下の画像のようなPDFが出力されます。

pandoc -F pandoc-crossref hoge.md -o hoge.pdf --pdf-engine=lualatex -V documentclass=ltjarticle -N

f:id:yurkth:20191228043810p:plain

f:id:yurkth:20191228044250p:plain

それぞれのオプションは以下の通りになっています。

  • -F pandoc-crossref
    フィルターにpandec-crossrefを指定して相互参照を使えるようにします。
  • hoge.md -o hoge.pdf
    入出力ファイルです。出力ファイル形式は拡張子で判別されます。
  • --pdf-engine=lualatex -V documentclass=ltjarticle
    デフォルトでは日本語の表示ができないのでエンジンとドキュメントクラスを指定します。
  • -N
    章番号をつけてくれます。参考文献のように番号をつけたくない項目には{-}を末尾につけます。

改善

ひとまずMarkdownをPDFに変換することはできましたが、レイアウトが少し気に入らないので改善していきます。

コードブロック

上の画像を見ていただければ分かりますが、コードブロックがとても見にくいので変えてみます。

コマンドを実行する際に--listings -H header.texと2つのオプションをつけます。

--listingsオプションでコードブロックにLaTeXのlistingパッケージを適用し、-Hオプションで指定したヘッダファイルで以下のように細かいレイアウトを指定します。

\usepackage{listings}
\usepackage{xcolor}
 
\lstset{
    basicstyle=\ttfamily,
    keywordstyle=\color[rgb]{0,0,0.6}\bfseries,
    stringstyle=\color[rgb]{0,0.6,0},
    commentstyle=\color[rgb]{0.4,0.4,0.4}\itshape,
    numberstyle=\ttfamily,
    numbers=none,
    stepnumber=1,
    numbersep=15pt,
    numberstyle=\color[rgb]{0.6,0.6,0.6},
    tabsize=4,
    breaklines=true,
    captionpos=t,
    frame=single,
    rulecolor=\color[rgb]{0.8,0.8,0.8}, 
    backgroundcolor=\color[rgb]{0.95,0.95,0.95},
    showspaces=false,
    showtabs=false,
    showstringspaces=false
}

用紙

次に-V geometry:a4paper -V geometry:margin=3cmのオプションで用紙のサイズと余白を指定します。

ここはコマンドの通り、用紙のサイズをA4にして余白を3cmにしています。

フォント

フォントも変えておきたいですね。フォントは-V CJKmainfont=ipaexm.ttf -V mainfont="Times New Roman"で指定できます。

1つ目のオプションで日本語用のフォント、2つ目で英文用のフォントを指定します(参考)。今回は日本語用のフォントにIPAex明朝を選びました。

表紙

最後に表紙をつけます。大学のレポートでは学科指定の表紙をつけなくてはいけないので,--template=template.texで指定できるテンプレートにLaTeXで表紙を書きます。

template.texは下のコマンドで出力したものを使います。

\begin{document}から\end{document}の間にある$body$が本文になるのでその前に表紙を入れるといいでしょう。$author$のようにするとYAMLメタデータブロックで指定した変数を参照できます。

pandoc -D latex > template.tex

コマンドの整理

さて、ここまでのコマンドをまとめると下のようになります。長いですね。

実際に使うときはスクリプトなんかにまとめることになると思いますが、どのオプションで何を指定したかが分かりにくいので整理しておきます。

pandoc -F pandoc-crossref hoge.md -o hoge.pdf --pdf-engine=lualatex -V documentclass=ltjarticle -N --listings -H header.tex -V geometry:a4paper -V geometry:margin=3cm -V CJKmainfont=ipaexm.ttf -V mainfont="Times New Roman" --template=template.tex

上のコマンドは大部分が-Vオプションによる変数の設定になっています。

この変数はYAMLファイルにまとめ、--metadata-fileオプションで呼び出すことができます。-Vオプションで指定した変数と、ついでにMarkdownYAMLメタデータブロックで設定していた変数の一部をmetadata.yamlにまとめると次のようになります。

これでコマンドも見やすくなり、変数を変更したいときも簡単に行なえます。

documentclass: ltjarticle
figureTitle: "図"
tableTitle: "表"
listingTitle: "コード"
figPrefix: "図"
eqnPrefix: "式"
tblPrefix: "表"
lstPrefix: "コード"
geometry: a4paper
geometry: margin=3cm
CJKmainfont: ipaexm.ttf
mainfont: Times New Roman

最終的に次のコマンドでMarkdownをPDFに変換することができるようになりました。

pandoc -F pandoc-crossref hoge.md -o hoge.pdf --pdf-engine=lualatex -N --listings -H header.tex --metadata-file=metadata.yaml --template=template.tex

コードブロックの見た目もいい感じになりました。

f:id:yurkth:20191228044430p:plain

エディタ

エディタはTyporaを使ってます。

pandoc-crossrefで入れた相互参照なんかはちゃんと表示されないですけど、ソースコードとプレビューを交互に見たりしなくていいので使いやすいですね。

コードブロックに相互参照をつけるときは{.python #lst:code .numberLines caption="HelloWorld"}のように言語の指定を頭に持ってこないと、Typoraで編集してるときにシンタックスハイライトが付かないので注意です。

まとめ

これでMarkdownでレポートを書けるようになりました。

細かいところをいじろうとすると結局LaTeXも必要になりますが、やっぱりMarkdownで書けるようになると便利ですね。

実際に使うときはスクリプトやバッチファイルにまとめてD&Dして処理できるようにすると楽です。

参考文献