Pandocでの執筆環境を整える

# はじめに

ここしばらく、以下の要件を満たす執筆環境を構築すべく、既存のツールを活用しつつ、それらでは足りない部分に関して新規のツールを開発してきました。まだまだ細かな問題は沢山あると思いますし、そもそもかなりニッチな気がするのですが、参考になる部分があれば幸いです。

# 要件

- Markdownファイルを入力としてPDF（XeLaTeX経由）とHTMLを出力できる
- 図、表、文献を参照できる
- 文献の引用スタイルはThe Chicago Manual of Style 17th editionの[Notes and Bibliography](https://www.chicagomanualofstyle.org/tools_citationguide/citation-guide-1.html)に対応できる
- 注釈は、PDFでは脚注（footnotes）として、HTMLでは傍注（side notes）として扱える

# 環境

- macOS Ventura 13.2.1
- Pandoc 3.1.2
- Node.js v16.13.1

なお、これは私が動作確認を行った環境を示すものであり、この環境に限定されるものではありません。もし、Windowsなど私とは異なる環境で試していただいた方は、お気づきの点などコメント等でお知らせいただければ幸いです。

# 準備

## 基本ツールのインストール

[Homebrew](https://brew.sh/index_ja)をインストールしたうえで、[Pandoc](https://pandoc.org/)、[pandoc-crossref](https://github.com/lierdakil/pandoc-crossref)、BasicTeX、LaTeX用の日本語コレクション、Node.jsをインストールします。

```shell-session
$ brew install pandoc
$ brew install pandoc-crossref
$ brew install --cask basictex
$ sudo tlmgr update --self --all
$ sudo tlmgr paper a4
$ sudo tlmgr install collection-langjapanese
$ brew install node
```

## 自作ツールの簡単な紹介とインストール

要件に挙げた環境を構築するため、前述した標準的なツールにくわえ、いくつかの小さなツールを自作しました。それらについて簡潔に紹介します。いずれもGitHubからダウンロードできます。

### pandoc-ruby-filter

文章中のルビ表記を処理して、LaTeXやHTMLなどの出力形式に合わせて変換するPandocフィルターです。このフィルターを制作するにあたり、[minoki](https://github.com/minoki)さんの[pandoc-aozora-ruby](https://github.com/minoki/pandoc-aozora-ruby)を参照しています。ただし、pandoc-aozora-rubyでサポートされていた省略記法（漢字から始まる文字列に対して｜を省略できる）には対応していません。

https://github.com/kotobuki/pandoc-ruby-filter

### citeproc-js-based-replacer

Markdownファイル内の引用キー（`@key`）を置き換え、「参考文献」または「Bibliography」というヘッダーがある場合に文献目録を追加するPandocフィルターです。

https://github.com/kotobuki/citeproc-js-based-replacer

1. `npm install`を実行して必要なライブラリをインストールする
2. [jm-styles](https://github.com/Juris-M/jm-styles) などから、使用したいCSL-Mファイルを入手する
3. [citation-style-language / locales](https://github.com/citation-style-language/locales/tree/6b0cb4689127a69852f48608b6d1a879900f418b) から必要なlocaleファイル（例：`locales-en-US.xml`）を入手する
4. [Jurism](https://juris-m.github.io/)や[Zotero](https://www.zotero.org/)によりJSON形式のbibliographyを生成する

JurismやZoteroでは、Extraフィールドに次のように`original-title`などを入力することにより、翻訳書の原書に関する情報を追記することができます。

```
original-date: 2022
original-publisher: Global Academic Press
original-publisher-place: "Chicago, IL
original-title: The Philosophy of Free Will
```

### chicago-fullnote-bibliography-short-title-subsequent-ja.csl

[Chicago Manual of Style 17th edition (full note, short title subsequent)](https://www.zotero.org/styles?q=id%3Achicago-fullnote-bibliography-short-title-subsequent)を[CSL](https://citationstyles.org/)（Citation Style Language）の拡張版である[CSL-M](https://citeproc-js.readthedocs.io/en/latest/csl-m/index.html)に対応させ、文献の`language`に従って日本語（`ja`）でも表記できるようにするためのCSLファイルです。英語の文献、日本語の文献、英語を日本語に翻訳した文献などのパターンに対応し、注釈と文献目録の両方に対応することを目指しています。

https://github.com/kotobuki/chicago-fullnote-bibliography-short-title-subsequent-ja-csl

### pandoc-sidenote.js

Markdown文書内の脚注を傍注（side note：番号あり・margin note：番号なし）に変換するシンプルなPandocフィルターです。Jacob Zimmermanらによる[`pandoc-sidenote`](https://github.com/jez/pandoc-sidenote)から着想を得てJavaScriptで実装されています。オリジナル版からの機能拡張として、URLを自動的にリンクに変換します。

https://github.com/kotobuki/pandoc-sidenote-js

### ファイルの配置例

上記のファイル一通りを配置した場合の配置例を示します。

- `citeproc-js-based-replacer.js`
- `pandoc-sidenote.js`
- `ruby_filter.lua`
- `chicago-fullnote-bibliography-short-title-subsequent-ja.csl`
- `locales-en-US.xml`
- `locales-ja-JP.xml`
- `bibliography.json`
- `input.md`
- `node_modules/`

# 使用例

Markdown形式の入力ファイルからPDFとHTMLを出力するまでの手順は次のようになります。なお、架空の論考と文献を生成するにあたってはChatGPT（[March 23版](https://help.openai.com/en/articles/6825453-chatgpt-release-notes#h_98b0bcf5a4)）を用いています。

## サンプルのファイル群

```md:input.md
---
documentclass: bxjsarticle
classoption: pandoc
papersize: a4
title: 決定論と自由意志の相互作用
subtitle: 人間のエージェンシーに関する新たな視点
author: 大林滋
bibliography: bibliography.json
csl: chicago-fullnote-bibliography-short-title-subsequent-ja.csl
figPrefix: 図
tableTitle: 表
tblPrefix: 表
titleDelim: ：
---

[@tbl:比較表]に示したように、｜決定論《デターミニズム》と｜非決定論《インデターミニズム》の立場には根本的な違いがある。決定論では、すべての出来事が必然的であり予測可能だと考える。これに対して非決定論では、人間の自由意志には未来を変える力があると考える。この違いは、倫理や意思決定においても重要な影響を与える。

| 立場         | 決定論                                 | 非決定論                             |
| :----------- | :------------------------------------- | :----------------------------------- |
| 基本的考え方 | すべての出来事は必然的であり、予測可能 | 人間の自由意志により未来は変わりうる |
| 哲学的問題   | 倫理、意思決定、責任                   | 自由意志の起源、意思決定プロセス     |
| 代表的人物   | ラプラス、ニュートン                   | カント、サルトル                     |

: 決定論と非決定論の比較 {#tbl:比較表}

「人間の主体性」を論じる際には、決定論と自由意志の微妙なバランスを考慮することが不可欠である。MorganとPatrovがその代表的な著作『自由意志の哲学』で雄弁に説いたように、個人はあらかじめ決められた道に縛られるのではなく、環境、遺伝、経験などの要因が複雑に絡み合って、自分の運命を積極的に形成している ^[[@morgan2023jiyu [p. 42]]]。この視点は、個人の責任、倫理的な意思決定、自己実現の追求といった従来の概念を見直すよう私たちを誘う。

# 参考文献

```

```json:bibliography.json
[
  {
    "id": "morgan2023jiyu",
    "author": [
      { "family": "Morgan", "given": "Casey" },
      { "family": "Patrov", "given": "Alexei" }
    ],
    "citation-key": "morgan2023jiyu",
    "event-place": "東京",
    "issued": { "date-parts": [[2023]] },
    "language": "ja",
    "original-date": { "date-parts": [[2022]] },
    "original-publisher": "Global Academic Press",
    "original-publisher-place": "Chicago, IL",
    "original-title": "The Philosophy of Free Will",
    "publisher": "城南大学出版会",
    "publisher-place": "東京",
    "title": "自由意志の哲学",
    "translator": [{ "family": "鈴木", "given": "真紀" }],
    "type": "book"
  }
]
```

```tex:preamble.tex
% pxrubricaパッケージを使用する
\usepackage{pxrubrica}

% オプションの既定値を設定する：Jは自動切替熟語ルビ
\rubysetup{J}

% 図および表に対して自動生成されるキャプションを削除する（pandoc-crossrefとの重複を防ぐため）
\usepackage{caption}
\captionsetup[figure]{labelformat=empty,labelsep=none}
\captionsetup[table]{labelformat=empty,labelsep=none}
```

## 図表の相互参照・文献参照・ルビの置換

```shell-session
$ pandoc input.md -s --filter pandoc-crossref --filter=./citeproc-js-based-replacer.js -o output.md
```

## PDFへの変換

```shell-session
$ pandoc output.md --lua-filter=./ruby_filter.lua --pdf-engine=xelatex -H preamble.tex -o output.pdf
```

![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92577/dcd72f37-2242-71cd-92e2-4f442362b87a.png)

## HTMLへの変換

```shell-session
$ pandoc output.md --filter ./pandoc-sidenote.js -o output.html
```

side notes形式を使用するにあたっては、[pandoc-markdown-css-theme](https://github.com/jez/pandoc-markdown-css-theme)を使用することをおすすめします。なお、pandoc-markdown-css-themeはHaskellで記述された[pandoc-sidenote](https://github.com/jez/pandoc-sidenote)フィルターの使用が想定されています。しかしながら、2023年4月30日の時点で配布されているバイナリであるv0.22.2はPandoc v3.1.2とは互換性がなく、かつmacOS上でビルドできる環境を構築するのが困難だったため、JavaScriptで書き直したバージョンpandoc-sidenote.jsを用いています。このため、`tools`フォルダにある`build.sh`の一部書き換えが必要です。

```shell:build.sh（変更前）
pandoc \
  ...
  --filter pandoc-sidenote \
  ...
```

```shell:build.sh（変更後）
pandoc \
  ...
  --filter pandoc-sidenote-js \
  ...
```

## 既知の問題

この例で用いた架空の翻訳書のように`language`が`ja`に設定されていると、著者名などが全て`family name`→`given name`の順になってしまいます。スタイルによっては問題ありませんが、Chicagoなどフルネームを記載するスタイルでは不都合が生じます。この件に関して、`citeproc-js`の[該当箇所](https://github.com/Juris-M/citeproc-js/blob/73bc1b44bc7d54d0bfec4e070fd27f5efe024ff9/citeproc_commonjs.js#L13737)を確認し、修正案のプルリクエストも送信済みです。

# おわりに

今回紹介した自作ツール群はまだ開発が始まったばかりであり、要望や不具合に関するレポートを歓迎します。とくに、プルリクエストは大歓迎です！:bow:

# レファレンス

- [Pandoc Markdownで青空文庫風のルビ記法を使う](https://qiita.com/mod_poppo/items/218500f4e22eaecfe4b5)