日本語／英語混じりの文献を処理するTypstパッケージ

# はじめに

[Typst](https://typst.app/)では，文献処理をするために`bibliography`関数が用意されています．しかし，基本的に英語文献にしか対応しておらず，例えば複数著者に対して
```typst
山田太郎, 佐藤花子, タイトル, 出版社名 (2020).
```
と表示して欲しいところが，
```typst
山田太郎 and 佐藤花子, タイトル, 出版社名 (2020).
```
のように`and`が入ってしまいます．これを解決するには，[別の記事](https://qiita.com/Suzukeh/items/986793803f8ae0158122)で述べられているようにCSLを書き換える方法が挙げられます．このようにすると，languageフィールドを`.yml`内に追加することで判別が可能となります．

しかし，この方法にはいくつか問題点が挙げられます．例えば，

- `.bib`形式のファイルを毎度`.yml`形式に書き換えなければならない
- `.yml`内に`language`フィールドを追加しなければならない
- アルファベット順に文献を並べられない

などです．そこで，[typstで文献を直書きする方法](https://zrbabbler.hatenablog.com/entry/2024/05/06/180901)を参考にして新たなパッケージを作ることにしました．

今回作成したパッケージは`enja-bib`という名前で[typst universe](https://typst.app/universe/package/enja-bib)に登録しましたので，すぐに使用できると思います．ぜひ使ってみてください！

# 主な機能

パッケージの主な機能は以下になります．

- `.bib`形式ファイルを読み込んで，日本語・英語文献を区別して設定する
- `language`フィールドを挿入せず，自動で判別する
- `yomi`フィールドを利用して，日本語文献もアルファベット順へ並び替えられるようにする

これに加えて，個人的に欲しい機能も付け加えることにしました．

- CSLを操作せずに，typst形式のまま文献の表示方法を変えられるようにする
- 直書きにも対応する
- 番号で管理する方法（バンクーバー方式）と著者名・年号で管理する方法（ハーバード方式）をすぐに切り替えられるようにする

# パッケージの使い方

まずパッケージを読み込みます．

```typst
#import "@preview/enja-bib:0.1.0": *
#import bib-setting-plain: *
#show: bib-init
```

- 1行目：typst universeに登録されている`enja-bib`パッケージを読み込む
- 2行目：文献の出力形式を決定（ここでは`plain`スタイルを適用するため，`bib-setting-plain`をインポート）
- 3行目：`ref`関数に出力形式を設定するための関数で，文献を参照する前に置く

文献を出力するには，次のように書きます．

```typst
#bibliography-list(
    title: [参考文献],
    ..bib-file(read("mybib_jp.bib")),
)
```

このとき，`bib-file`がBibTeXを読み込むための関数です．

## 出力の構造

文献の出力では，上記のように`bib-file`関数を`bibliography-list`関数の中に入れます．
それぞれの関数は，次のような意味を持ちます．

- `bibliography-list`：文献を順番に並び替えて出力する（引用順やアルファベット順，文献リストの順など）
- `bib-file`：bibtexファイルを読み込んで，「文献」の形にする

例えば，`bib-file`では，入力
```bibtex
@book{yamada-sato-2020,
    author    = {山田, 太郎 and 佐藤, 花子},
    title     = {タイトル},
    publisher = {出版社名},
    year      = {2020}
}
```
に対して，これを出力する形式
```
山田太郎, 佐藤花子, タイトル, 出版社名 (2020).
```
などに書き換えます．
書き換えられた文献を`bibliography-list`に渡すことによって，目的の順番に並び替えて出力できます．

## 参照方法

オリジナルの`bibliography`には`cite`関数を利用しますが，この代わりに
```typst
#citet(<ラベル名>)//山田,佐藤(2020)
#citep(<ラベル名>)//(山田,佐藤, 2020)
#citen(<ラベル名>)//(1) (引用順の番号)
```
などが使用できます．
引用の関数は，後の方法で新たに定義することもできます．

## 文献スタイルを変更する方法

すぐに使える文献スタイルとして

- jplainを模倣したplainスタイル
- 日本機械学会の引用を模倣したjsmeスタイル

があります．これらの設定の一部を変更することで，簡単に文献スタイルを変更できます．

### 全体設定の変更

全体設定を変更するには，`bibliography-list`関数に引数を追加します．

```typst
#bibliography-list(
  bib-sort: true,
  bib-sort-ref: true,
  bib-full: true,
  bib-vancouver: "(1)",
  vancouver-style: true,
  bib-year-doubling: "a",
  //ここにbib-fileなどの文献を追加...
)
```

- `bib-sort`：文献をアルファベット順に並び替えるか
- `bib-sort-ref`：引用されている順に並び替えるか
- `bib-full`：引用されていない文献も全て表示するか
- `bib-vancouver`：バンクーバー方式のとき，文献番号スタイル
- `vancouver-style`：バンクーバー方式にするか
- `bib-year-doubling`：ハーバード方式のとき，著者・年号の重複時に区別する番号スタイル

sort系の設定では，全てfalseにすると文献リストの順番に出力されます．
逆に全てtrueとすると、引用順に並び替えられ、引用されていない文献はアルファベット順になります．

### 文献スタイルの変更

また，文献スタイルを変更するには，`bib-file`関数に引数を追加します．設定する引数名は，

```typst
bibtex-(エントリー名)-(en または ja)
```

とします．例えば，英語文献のarticleを設定したいときには，`bibtex-article-en`が引数名です．
英語と日本語文献はそれぞれ引数が異なるので，別々の設定ができます．

各引数には，例えば次のように設定します．

```typst
bibtex-article-en: (
    ("author", (none,"",author-set3, "", ". ", (), ".")),
    ("title", (none,"",title-en, "", ". ", (), ".")),
    ("journal", (none,"",all-emph, "", ", ", (), ".")),
    //...出力する項目を順に並べる
)
```

一番外側の配列は，英語文献のarticleのときに出力される項目の順番を表します．
上の例では，author -> title -> journal...の順に出力されます．

各項目内の配列は，次のように設定します．

```typst
("author", (none,"",author-set3, "", ". ", (), "."))
```

配列内は

- 項目名
- 設定項目

の順に書きます．
設定項目は

```typst
(none,"",author-set3, "", ". ", (), ".")
```

のように書きます．それぞれ

- 直前の項目がAのとき，直前の語尾文字列Bを削除して置き換える文字列
- 必ず出力する先頭文字列
- 項目を出力する関数
- 最後の項目でない限り必ず出力される語尾文字列
- 語尾文字列B
- A
- 最後の項目のとき出力される語尾文字列

です．基本的には，配列の順番に出力されます．条件分岐が多いですが，例えば

```typst
山田太郎, 佐藤花子, タイトル, 出版社名 (2020).
```

のように年号の直前にカンマが不要な場合などに便利です．
このとき年号の設定には
```typst
(" ","(",all-return, "%year-doubling)", ", ", ("author","title","journal", "volume", "number"), "%year-doubling).")
```
などを入れます．
この場合，直前の項目がarticle, title, volume, numberの場合に直前の語尾文字列Bを消して，代わりに`" "`を出力します．

上の例では`%year-doubling`という文字列がありますが，これはハーバード方式の文献表示で同一著者名・年号の文献がある場合に付与される文字列を表しています．`%year-doubling`の文字列を変更したい場合には`bibliography-list`関数と`bib-file`関数の引数`year-doubling`で設定できます(が，ほとんどの場合変える必要はないと思います)．

項目を出力する関数はあらかじめいくつか定義されていますが，独自に作ることもできます．
例えば，既存関数である`all-emph`(項目を斜体表記にして返す)では次のように定義されています．

```typst
#let all-emph(biblist, name) = {
  return emph(biblist.at(name).sum())
}
```

引数には

- `biblist`：`bibtex`形式の文献項目の`dictionary`型
- `name`：今呼ばれている文献項目名

が必要です．

### 参照設定の変更

`@...`のように参照するときの表示を設定するには，`bib-init`関数に引数`bib-cite`を加えます．
```typst
#show: bib-init.with(bib-cite: ([], bib-citet-default, [; ], []))
```

与える配列は

- 参照時の最初の文字列
- 出力する文字列を作る関数
- 2つ以上の文献で，文献間に出力される文字列
- 参照時の一番最後の文字列

です．
残念ながら`@...`を使って複数文献を一気に参照する方法は見つかっていないため，現状配列の3番目の要素は使用されません（今後のアップデートのために設定しています）．

これに加えて，`cite`系の関数を独自に作ることもできます．例えば，

```typst
#let citet = bib-style.bib-cite-func.with(bib-cite: ([], bib-citet-default, [; ], []))
```

のように設定します．与える配列は先ほどのものと同じです．この関数を使う場合は，複数文献が使えます．例えば

```typst
#citet(<文献1>, <文献2>)
```

のように書けば

```typst
著者1 (年号1); 著者2; (年号2)
```

と出力されます．`cite`系の関数は先に示した通り既にいくつか設定されていますので，それらはすぐに使用できます．

# おわりに

Typstで[日本語／英語混じりの文献を処理するためのパッケージ](https://github.com/tkrhsmt/enja-bib)を紹介しました．このパッケージは[typst universe](https://typst.app/universe/package/enja-bib)にも登録されていますので，ぜひ使ってみてください！
まだまだ多くのバグが残っていると思いますが，積極的に使用してissuesで報告してくださると嬉しいです．また，`plain`や`jsme`以外の新しい文献スタイルを追加したい場合も，積極的にissuesやpull requestsを出してもらえると嬉しいです．