ブログにちょっとしたネタ記事を投稿しました。 https://t.co/T621Qa5LqL 「サイゼリヤで1000円あれば最大何kcal摂れるのか」をTeX言語で計算する ~TeX言語で動的計画法(DP)~ #TeX
— Yusuke Terada (@doraTeX) 2019年5月20日
- 「サイゼリヤで1000円あれば最大何kcal摂れるのか」をTeX言語で計算する ~TeX言語で動的計画法(DP)~ (TeX Alchemist Online)
どうやら、TeXを使うと計算と組版を一気にやってしまえて最高、なようです。
ところで、皆さんご存知の通りTeXはアレなわけですが、どうやら聞くところによると、Pandocも相当アレなようです。
人はなぜ、苦しみながらPandocでドキュメントを書き続けるのか #pandoc_night
— 藤原惟📕 (@skyy_writing) 2019年5月20日
- Pandoc Night 2019 スライド&ツイートまとめ (togetter)
となると、「サイゼリヤで1000円あれば最大何kcal摂れるのか」をPandocで一気に計算して組版する、というネタがあって然るべきなのは、当然の帰結でしょう。
というわけで、やってみました。
方針
- Pandoc 2版の機能である「Luaフィルタ(
--lua-filter
オプション)」を利用する。 - Markdown文書中に現れる特定の形式のマークアップを、「サイゼリヤ問題の解の組版結果」に置き換える。
- 解の計算はフィルタ内のLuaコードで行う。(アルゴリズムは元ネタと同じく動的計画法を使う。)
- メニューのデータは別途CSVファイルで用意する。
サイゼリヤ問題を解くMarkdown文書
- Pandoc:「サイゼリヤで1000円あれば最大何kcal摂れるのか」を解くLuaフィルタ (Gist/zr-tex8r)
フィルタsaizeriya.luaを含むファイル一式はここに置いてあります。
[sample.md]
# 問題 予算1000円以内で,サイゼリヤで最大カロリーを摂取するような注文の仕方を求めよ。ただしサイゼリヤの料理のメニューは以下の通りとする。 [一覧](./menu.csv){.saizeriya-list} # 解答 以下の通り。 [解答](./menu.csv){.saizeriya-solve badget=1000}
[menu.csv]
彩りガーデンサラダ,130,299 小エビのサラダ,115,349 やわらかチキンのサラダ,134,299 わかめサラダ,92,299 イタリアンサラダ,196,299 ……(略)……
書式の説明
特定のクラスを付けたリンク要素を書くと、その部分がフィルタによって置き換えられます。
次のように、クラスにsaizeriya-list
を指定したリンクを書くと、指定のメニューファイルを読み込んでメニューの一覧の箇条書きを生成してその場に出力します。(テキスト
は出力されません。)
[テキスト](メニューファイルのパス){.saizeriya-list}
クラスにsaizeriya-solve
を指定したリンクを書くと、指定のメニューファイルを読み込んでサイゼリヤ問題を解き、その解答を表組にしたものを出力します。この際に予算額はbadget
という属性で指定します。
[テキスト](メニューファイルのパス){.saizeriya-solve badget=予算額}
さっそくPandocしてみる
以下のコマンドで、先のMarkdown文書(sample.md)をWord文書に変換します。
pandoc sample.md --lua-filter=saizeriya.lua -o sample.docx
※「Wordは嫌だ」という人は、出力ファイル名のsample.docx
の拡張子を変えて別の形式を選びましょう。例えばsample.odt
とするとOpenDocument形式になります。sample-out.md
のようにすると別ファイルにMarkdown形式で出力できます。
出力されたWord文書(sample.docx)を開いてみると、メニュー一覧が正しく挿入されていることが判ります。
※以下の出力結果はPandoc 2.7.2(最新版)によるものです。
そして、最後のページをみると、例の栄養満点な3点セットが、無事に出力されていました。