【Typst + Zotero】日本語文献の著者を"and"で区切らないようにする

# はじめに
Typstはコンパイルが爆速すぎる組版システム。
Zoteroは便利な文献管理ツール。
組み合わせたら最強になる！

と思って色々やった過程で、こんな感じ↓に著者のところで不要な "and" が出てくる問題が解決した (?) ので共有します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759481/9bc502fb-0361-9040-9805-e620248d64c9.png)

まだTypst使ったことない人は、コンパイルが速すぎてLaTeXに戻りたくなくなるレベルなのでぜひ試してみてください。

# 結論
1. Better BibTeX for Zoteroでbibファイルをエクスポート
1. Hayagriva形式のymlに変換
1. CSLでlanguageフィールドを読んで日本語か判定

作ったテンプレート↓

https://github.com/Suzukeh/typst_template

# 不要な "and" とは
日本語の論文で参考文献を示す場合、著者が複数いる日本語文献だと
```
鈴木, 佐藤, 田中,
```
として、カンマで区切るだけです。

一方、英語文献だと
```
A. Smith, M. Jackson, and J. Williams
```
として、最後の人の前には (一般的な英文法通りに) `and`を入れます。

このような混在はTypstのbibliography環境だけでは対応できず、何らかの工夫が必要です。

# 解決方法
1. Zoteroで文献管理するときに言語フィールドを記入
2. Better BibTeX for ZoteroでbibファイルをAutomatic export
3. hayagriva CLIで `hayagriva refs.bib > refs.yml`
4. YAML変換時に消えてしまったlanguageフィールドを挿入しなおす
5. 参考文献のスタイルを定義するCSLでlanguageフィールドから日本語文献か判定
6. `#bibliography`でYAMLとCSLを指定

## 1. 言語フィールドを記入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759481/047a6fbb-4d9b-34e1-15a7-603cc4514d11.png)
日本語なら `ja` か `ja-JP` のどっちかを書いておけばいいです。英語なら`en`とか。
Zoteroに取り込んだときの習慣にしておくといいかも。

## 2. Better BibTeXからbibをエクスポート
これとかを参考にして設定してください。

https://zenn.dev/sky_y/articles/pandoc-advent-2020-bib1#%E8%87%AA%E5%8B%95%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88

## 3. bibファイルをHayagriva形式に変換する
HayagrivaのCLIツールをインストールしてください。
```shell
cargo install hayagriva --features cli
```

インストールしたら、Better BibTeXからエクスポートされたbibをHayagriva形式のYAMLに変換します。

```shell
hayagriva refs.bib > refs.yml
```

## 4. languageフィールドを挿入しなおす
さっきの変換ではなぜかlanguageフィールドが取り込まれないので、ymlを編集して追加します。後のため、日本語文献だけにしておきます。

つまり、日本語文献に対してだけ

```yaml
  language: ja
```
と挿入します。

## 5. CSLでlanguageフィールドを読んで日本語か判定
CSL (Citation Style Language) の仕組みはちゃんと理解していないです。
[typst-jp-conf-template](https://github.com/kimushun1101/typst-jp-conf-template)のものを99%そのまま使っています。

```xml
<macro name="author">
<choose>
  <if match="any" variable="language">
    <names variable="author">
      <name form="short" delimiter=", "/>
      <label form="short" prefix=", "/>
      <substitute>
        <names variable="editor"/>
      </substitute>
    </names>
  </if>
  <else>
    <names variable="author">
      <name initialize-with=". " delimiter=", " and="text"/>
      <label form="short" prefix=", "/>
      <substitute>
        <names variable="editor"/>
      </substitute>
    </names>
  </else>
</choose>
</macro>
```
として、languageフィールドがあるもの = 日本語文献では`and`を使わないようにしているようです。

> 日本語論文として重要な点は、CSL ファイルでは Hayagriva で記述された `language` の属性を見て、著者表示を "カンマ区切りのみ" にするか "カンマ区切り+最終著者の前にand" にするかを決定している点です。
[typst-jp-conf-template](https://github.com/kimushun1101/typst-jp-conf-template/blob/aeac8f90e44d91cf665a89e2aa0c9243baffa814/main.typ#L336C1-L337C1)より

## 6. `#bibliography`でYAMLとCSLを指定
これまでに用意した参考文献コレクション`refs.yml`と参照スタイル`noandjp.csl`をTypstで適用します。
```typst
#set text(lang: "en") //日本語設定だと "and" →「と」になってしまう
#bibliography("refs.yml", title: "参考文献", style: "noandjp.csl")
```
# bib→ymlの変換と修正プロセスをまとめる
参考文献を更新するたびに手作業でlanguageを挿入するのは面倒すぎるので、bib→ymlの変換とlanguageの修正をまとめたpythonスクリプトにしました。

`subprocess.call()`でHayagrivaの変換を実行し、BibtexParserを使ってbibにあるlanguageフィールドの情報を読み取り、PyYAMLを使ってymlに挿入しています。

https://github.com/Suzukeh/typst_template/blob/main/bib2hayaml.py

# おわりに
なんとか「賢い文献管理」と言える負荷に収まったと思いたいです。

<details><summary>余談：ここに至るまでの経緯</summary>

最近 $\LaTeX$ からTypstに乗り換えた。

Typstで日本語環境を作っている先人のおかげでほとんどの問題が解決した。
ありがたい...

さて、日本語文献にandが差し込まれるのをどうにかしたいと思って調べてみると
* [bxbibwrite](https://zrbabbler.hatenablog.com/entry/2024/05/06/180901)で直書き
* [fake-bibliography](https://github.com/mkpoli/ipsj-typst-template/blob/master/lib/bibliography.typ)でbibliography環境を魔改造
* [CSL](https://github.com/kimushun1101/typst-jp-conf-template/blob/aeac8f90e44d91cf665a89e2aa0c9243baffa814/libs/rsj-conf/rsj-conf.csl#L44)でlanguageフィールドを読んでなんとかする

の3通りがあった。
せっかくZoteroで文献管理してるので直書きは嫌だし、fake-bibliographyはどうも裏技的なやり方らしい。
となると、CSLでなんとかするのがよさそう。
Better BibTeXはHayagrivaスタイルのYAMLを吐き出してくれないが、`hayagriva [bibfile] > [ymlfile]`で変換できるらしいから問題ない。

と思ったら、変換するとlanguageフィールドが消える。とりあえず[issue](https://github.com/typst/hayagriva/issues/263)は投げるとしても、今からRustを勉強するのは締切を考えると無理。

こうなるとbibからlanguageフィールドを読んでymlを修正するしかない。
→ 変換と修正をまとめて `bib2hayaml.py` にした。
</details>