Markdownからプレゼンテーションを生成する

特殊な性癖（LaTeX）を持つ人向け。

# モチベーション

最近は Google Slides もかなり使いやすくなってきたので（意図的に PowerPoint に関しては触れない）それほど切羽詰まった欲求ではないのだが、この「プレゼンテーションを作る」という作業はとてもつらい作業である事には変わりが無い。

もちろん簡単に書けて、簡単に生成できるのが良い。そして、特に私は変な所にこだわってしまう性格なので、機能がありすぎるのも困る。「書いた！」「作った！」「終了！」ぐらいが良い。

そこで pandoc ですよ奥様。[pandoc](https://pandoc.org/) は以下のような構成で動く、フォーマットを持つテキストのコンバータである。

- Reader: 特定のフォーマットのファイルを読み込む
- 中間データ（JSON）に変換
- Writer: 中間データを特定のフォーマットとして書き出す

[オヒサル](https://pandoc.org/) を見てもらえば分かるのだが、対応しているフォーマットが非常に多く、とても素晴らしい。

まずは pandoc の入力とするフォーマット。簡単に書けて出力もそこそこ綺麗に整形できると言えば、[Markdown](https://daringfireball.net/projects/markdown/) である（特に[GitHub-Flavored Markdown](https://github.github.com/gfm/)）。すべてのテキストフォーマットは Markdown で良いんじゃないかと思っている。

そして pandoc の出力となるフォーマット。free でそこそこ綺麗なプレゼンテーションを作れると言えば、[LaTeX](https://github.com/latex3/latex2e) の [beamer](https://github.com/josephwright/beamer) である。

Markdown を書き、pandoc で LaTeX beamer に変換し、それを DVI にコンパイルし、さらに PDF に変換することで、プレゼンテーションを作成することが出来る。

例えば、こんな簡単な Markdown を書いたとする。

```
---
title: convert Markdown to Presentation
subtitle: using vanilla pandoc
author: tetutaro
date: \today
---

# 変換する

## pandoc

[pandoc](https://pandoc.org/) は以下のような構成を持つ、構造を持つテキストのコンバータである。

- Reader: 特定のフォーマットのファイルを読み込む
- 中間データ（JSON）に変換
- Writer: 中間データを特定のフォーマットとして書き出す

$$
y = 3x + 2
$$

これは数式の例である。
```

このファイルを `test.md` として、以下の処理を行う。

- `> pandoc -s test.md -t beamer -o test.tex`
- 生成された `test.tex` をちょっと修正（！）
- `> latexmk test.tex`

すると、出来上がるのはこんな PDF である。

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84885/28f97903-ba5e-61c7-3f4a-bf3437553459.gif)

正直、とても不満がある。

- beamer にちゃんとテーマを設定して、きれいな見た目にしたい
- 参照（fig. １とか eq. (2) とか）も簡単に書けて、ちゃんとクリックで飛べるようにしたい
- 日本語しか書く予定がないので、fig とか equation とか日本語化したいし、日付も日本風にしたい
- 日本語対応の LaTeX を使おうとするとエラーが出て毎回修正しなきゃいけないの何とかしたい
- beamer には block という奴があるので、折角なのでそれを使えるようにしたい
- この block を使って、ソースコードの表示をそれっぽくしたい
- LaTeX で数式を表示する align 環境の `&` による位置整形を使いたい
- 普通のテキストのPDFにしたい時もあるし、ワイドの（16:9の）プレゼンテーションにしたい時もあるので、それを簡単に切り替えたい
- 何回もコマンドを叩くのは面倒臭いので、一発で済ませたい

beamer の block の例

![TmGdo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84885/57d9f528-8d69-65fb-0256-cf47790cbe59.png)

# 不満点を解消する
上記の不満点を解消するためには、色々やるべきことがある。

## pandoc テンプレートの利用

上記の例で pandoc を叩いたコマンド `pandoc -s test.md -t beamer -o test.tex` の中の `-s` は `--standalone` の略であり、このオプションが付いた場合は pandoc は「テンプレート」を用いて出力を整形する。pandoc のデフォルトのテンプレートは[ココ](https://github.com/jgm/pandoc-templates)にある。

そして、pandoc に `--template=xxx` と指定することで、使うテンプレートを指定することが出来る。この時にはファイル名の拡張子の前の部分しか指定できなく、拡張子には出力形式の名前（`-t` で指定した名前）が自動的に使われる。

テンプレートを自分で作ることで、以下の不満点が解消できる。

- beamer のテーマの設定
- 参照したものの名前（fig. とか eq. とか）、日付の日本語化
- 日本語 LaTeX 環境に適したLaTeXヘッダ等の設定
- block の色合いとかの設定

## pandoc フィルターの利用

テンプレートだけでは不十分で、不都合な出力を整形したり、足りない出力を補わなくてはならない。

pandoc にはフィルターという機能があり、`--filter=xxx` と指定することで、pandoc が入力ファイルを読み込んで中間データ（JSON）にした後に、その中間データに対して処理を追加することが出来る。

このフィルターの実装は [pandocfilters](https://github.com/jgm/pandocfilters) を使うのが最も有名だが、正直 pandocfilters は Haskel 風で、Python 的にはめちゃめちゃ使いづらい。

そこで [panflute](https://github.com/sergiocorreia/panflute)を使うことを非常におすすめしたい。こっちは pandoc 中間データの各形式が class に変換されるし、何よりソースコードを読めば何をすべきかが分かる！

フィルターとしては３種類が必要。

ひとつは相互参照をきちんと整形するもの。これをやるフィルターとしては[pandoc-crossref](https://github.com/lierdakil/pandoc-crossref)というものが既にあるのだが、Haskel で何やってるか分からないし（！）、表とか数式のラベルが上手く処理できない気がする。

残りの２種類はそれぞれ、beamer への変換と普通の LaTeX への変換用。以下のことを行わなきゃならない。

- Markdown のヘッダを、block や beamer の frame に上手く変換する
- ３連グレイヴ・アクセント（```）をソースコード表示用に変換する
- 数式環境の変換

## コマンド

普通のテキストPDFか beamer か、beamer も 4:3 なのか 16:9 なのかを簡単に指定したい。うまい方法は無いかと考えた結果、拡張子でなんとかならないかと。

- hogehoge.md → 普通のテキストPDF
- hogehoge.beamer.md → beamer (4:3)
- hogehoge.beamer169.md → beamer (16:9)

こうすると、ファイル名だけで生成するものを制御できる。

あと、pandoc と latexmk を一度に呼び出すようにすれば便利。

シェルスクリプトで十分設定できるのだが、コマンドのパスの問題とか面倒臭いので、Python コマンドにしちゃえばいいんじゃないかと。

## beamer テーマ

例えば [Beamer theme gallery](https://deic-web.uab.cat/~iblanes/beamer_gallery/index.html) にbeamerのテーマの一覧があるのだが、正直、どれも堅苦しい。

なので、自分で作った。大変だった。（承認欲求）

４種類×３パターンの、合計１２種類。

このテーマを Markdown の YAML ヘッダで指定できるよう、pandoc テンプレートに細工した。

# 作った

ということで、作った。

https://github.com/tetutaro/knit_markdown

Mac における LaTeX 環境のインストール方法、latexmk の設定まで README に書いてあるので、簡単に出来るはず。README には beamer テーマのサンプルも置いてある。

Markdown の書き方は[knit_markdown/samples](https://github.com/tetutaro/knit_markdown/tree/main/samples)にある Markdown を見てもらうか、これを PDF に変換した奴を見てもらえれば。

最初の Markdown の例をちょっとだけ変更する。

```
---
title: convert Markdown to Presentation
subtitle: using knit_markdown
author: tetutaro
date: \jtoday
bib: test.bib
---

# 変換する

## pandoc

[pandoc](https://pandoc.org/) [@pandoc] は以下のような構成を持つ、構造を持つテキストのコンバータである。

- Reader: 特定のフォーマットのファイルを読み込む
- 中間データ（JSON）に変換
- Writer: 中間データを特定のフォーマットとして書き出す

$$
y = 3x + 2 {#eq:sample}
$$

[@eq:sample]は数式の例である。
```

これを `test.beamer.md` として、ついでに `test.bib` として以下の内容のファイルも作る。

```
@Misc{pandoc,
    title="pandoc.org",
    url="https://pandoc.org/"
}
```

これを `> knit_markdown test.beamer.md` とするだけで、以下の PDF が出来る。

![test.beamer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84885/72a0e500-43f8-0028-c456-e64628772033.gif)

# 最後に

みなさんのプレゼンテーションライフがより実りあるものになりますよう（上手い締めの言葉が思いつかない）