BibLaTeXで日本語文献と英語文献の混在を扱う

ここしばらく，日本語と英語の文献が混在している場合は諦めて文献リストを手打ちして作成してきたのですが，いい加減めんどくさくなってきたのと，日本心理学会の手引きが改訂されたことをきっかけに，再度BibLaTeXでなんとかできないか試してみました。その結果，どうやらうまくいったみたいなので，個人的な覚書も兼ねてここに記録しておこうと思います。

なお，今回作成したBibLaTeX用スタイルファイルは，[こちら](https://github.com/sbtseiji/biblatex-jpa)で公開しています。

## 日本語文献と英語文献の区別
BibLaTeXの`.bib`ファイルでは，`language`というフィールドが追加されているので，これを使用します。日本語文献として扱うものについては，`language`フィールドに`japanese`と入力しておきます。

もちろんこれだけでは何も変化しませんので，このフィールドを用いて処理を分岐するよう，BibLaTeXのコマンドに変更を加える必要があります。

## BibLaTeXのスタイルファイル

BibLaTeXでは，`.bbx`，`.cbx`，`.dbx`という3種類のファイルを使用して文献処理の方法を指定します。`.bbx`ファイルは文献リストの書式に関するもので，`.`.cbx`は本文中への引用書式に関するファイルです。`.dbx`は，新規にフィールドを追加したりする場合に使用します。本文中の引用形式は`authoryear`のままでよく，文献リストの書式にのみ変更を加えたい場合，たとえば`mystyle.bbx`ファイルを用意して，プリアンブルで

```
use package[backend=biber,citestyle=authoryear, bibstyle=mystyle]{biblatex}
```

のようにすればOKです。

ただ，この組み合わせで使用することが決まっているのなら，`mystyle.cbx`も用意して，そこに次のように書いておくのが良いでしょう。

```
\ProvidesFile{mystyle.cbx}[2022/12/01\space my citation style]
\RequireCitationStyle{authoryear}
```

このようにして，`.cbx`ファイルの中で使用したい既存のスタイルファイルを読み込むようにしておけば，

```
use package[backend=biber,style=mystyle]{biblatex}
```

と書くだけでオリジナルのスタイルを使用することができます。`.bbx`ファイルと`.cbx`ファイルは必ず必要ですが，`.dbx`ファイルはなくても構いません。

## `.bbx`ファイルの作成

`.bbx`ファイルを作成する場合も，1からすべてのスタイルを書く必要はありません。`.cbx`ファイルと同様に，既存のスタイルファイルを読み込んで，必要な部分のみ上書きすることができます。

```
\ProvidesFile{mystyle.bbx}[2022/12/01\space my bibliography style]

\RequireBibliographyStyle{authoryear}
```

### `.bbx`ファイルの仕組み

bibファイルに変更を加える場合，BibLaTeXがどのような仕組みで文献リストを生成しているのかについて理解する必要がありますが，これはBibLaTeXのマニュアルだけではかなり大変だと思います。今回の作業では，`authoryear.bbx`や`standard.bbx`など，基本となるスタイルファイルの中身や，`biblatex.def`で定義されている内容がとても参考になりました。BibLaTeXでは，基本的に次のような流れで文献情報を処理しているようです。

1. bibエントリのタイプごとに処理を振り分ける
2. タイプごとに`BibliographyDriver`を用いて指定された順序でフィールドデータを処理する
3. `bibmacro`でフィールドデータに必要な加工を加える 
4. `Format`で指定された書式にそって各フィールドの内容を出力する
5. その際，あらかじめ指定された区切り文字を使用する

ほとんどの場合，このうちの2〜5のいずれかのレベルで変更を加えることになります。たとえば，文献リストで著者名や出版年，論文タイトルなどの表示順序を変更したい場合には，2のレベルでの変更が必要です。これに対し，名前の表示方法を変更したいだけだという場合には，3〜5のレベルで変更を行えば良いということになります。

#### BibliographyDriver

BibLaTeXでは，`article`や`book`など，エントリタイプごとに`BibliographyDriver`が設定されています。これは，それぞれのエントリでどのフィールドデータをどの順序で処理するかを指定するものです。たとえば，`book`タイプの文献リストを「著者名，タイトル，出版年」という順したければ，`book`用の`BibliographyDriver`を定義し直すことになります。

この場合の処理をもっとも単純な形で記述すると次のようになります。

```
\DeclareBibliographyDriver{book}{%
  \usebibmacro{begentry}%
    \printnames{author}%
    \printfield{title}%
    \printdate% 
  \usebibmacro{finentry}%
}
```

各エントリタイプの処理は，`begentry`で始まって`finentry`で終わるので，各フィールドの処理をこの2つの間に記述します。`\printnames`は，著者名や編集者名など，`name`タイプのリストの内容を出力するためのコマンドです。フィードの内容が実際にどのように表示されるかは，各フィールドの`Format`によって定義されています。

なお，フィールドの内容を出力するコマンドはフィールドのタイプ（`name`，`list`，`field`,`date`）によって異なり，`name`の場合には`\printnames{}`，`list`の場合には`\printlist{}`，`date`の場合には`\printdate`，それ以外のフィールドの場合には`\printfiled{}`というように，フィールドのタイプごとに異なります。表示したいフィールドがどのタイプに相当するのかについては，BibLaTeXのマニュアルを参照するのがよいでしょう。なお，著者名フィールドなど，`name`を出力するコマンドは，`\printnames[given-family]{}`や`\printnames[family-given]{}`のように，オプションを受け付けるようになっています。著者名を「姓-名」の順で表示したければ，`\printnames[family-given]{author}`とすればよいのです。

#### bibmacro

場合によっては，`\print`コマンドでフィールドの内容を出力する前に，フィールドデータを加工したい，あるいは，複数のフィールドをセットとして扱いたいということもあるでしょう。そのような場合には，`bibmacro`を使用します。たとえば，複数のエントリタイプで共通して「著者名(出版年).」という出力を使用する場合，各ドライバに同じ処理を書くよりも，これらを「`author+year`」のようなマクロとしてひとまとめに定義しておいた方が，コードがスッキリします。「著者名(出版年).」という形でフィールド情報を表示するマクロ（`author+year`）の定義は，次のような形になります。

```
\newbibmacro{author+year}{%
  \printnames{author}% 著者名フィールドの出力
  \printtext[parens]{\printdate}% 日付フィールドの内容を括弧内に出力
}
```

なお，既存のスタイルファイルを読み込んでそこに修正を加える場合，`author+year`のような基本的なマクロは，すでに読み込み先のファイルで定義されていることでしょう。そのような場合，マクロの定義には`\newbibmacro`ではなく`\renewbibmacro`を使用します。これは`newcommand`と`renewcommand`の関係と同じことなので，これ以上の説明は必要ないと思います。

#### フィールドFormat

`\printnames`などの出力コマンドが実行されると，フィールドの内容は`\DeclareXXFormat`で指定された書式にそって整形されてタイプセットされます。たとえば，著者名フィールドである`author`の出力形式は`\DeclarNameFormat{author}`によって定義されており，`\printnames{author}`がコールされた場合，この`\DeclarNameFormat{author}`の設定に従って`name`フィールドの内容が出力されます。

たとえば`\DeclareNameFormat{author}`が次のように設定されていたとしましょう。

```
          \namepartfamily%
          \space%
          \namepartgiven%
```
すると，`\printnames{author}`によって著者名が「著者姓 著者名」の順で出力されるのです。

なお，`author`など`name`タイプのリストでは，`\DeclarNameFormat{family-given}`や`\DeclarNameFormat{given-family}`のようなフォーマットも定義されており，`\printnames[family-given]{author}`として指定すると，`\DeclarNameFormat{family-given}`に指定された書式で`name`フィールドの内容が出力されるようになっています。

また，`name`タイプと`list`タイプのフィールドは複数の値を格納することができ，これらのフィールドに複数の値が含まれている場合には，その個数分だけ繰り返しこのフォーマットの定義による処理が実行されます。このとき，今現在何番目の項目を処理しているのかについての情報は`listcount`カウンタを，この`name`フィールドに全部で何個の名前が含まれているのかについては`listtotal`カウンタに格納されており，これらのカウンタの値を利用することで，著者順によって処理を分岐させることも可能です。

たとえば，日本心理学会やAPAの文献リストフォーマットでは，共著者が20人以下であれば全員表示，20人を超える場合は19人目まで表示して，途中は「…」で省略し，最後の著者名を表示するという，かなり複雑な処理が求められています。この処理は，`\DeclarNameFormat{family-given}`を次のように定義することで対処可能です。

```
\ifthenelse{\value{listcount}=20\AND\value{listcount}<\value{listtotal}}{%
  % 現在処理中の著者が20人目で，かつ，まだこの後にも著者がいる場合
  　　 \ldots% 「…」を表示
  }{%
    \ifthenelse{\value{listcount}>20\AND\value{listcount}<\value{listtotal}}{%
      % 現在処理中の著者は20番目より後ろで，かつ，これが最後の著者ではない場合
      % 何も表示しない
    }{%
      \namepartfamily\space\namepartgiven% 「著者姓 著者名」を出力
      \ifthenelse{\value{listcount}=\value{listtotal}}{%
        % 現在処理中の著者が最後の場合
        % 何も表示しない
      }{%
        \printtext{・}% 中黒（・）を表示
      }%
    }%
  }%
}
```

なお，この`\Declare***Format{}`による書式定義は，`\Declare***Format[エントリタイプ]{}`という形で特定のエントリタイプにのみ適用することもできます。そのため，たとえば次のように定義することで，論文など`article`タイプのエントリの場合には著者名を「姓 名」の順で，書籍など`book`タイプのエントリの場合には著者名を「名　姓」の順で表示させるといったことも可能です。

```
\DeclareNameFormat[article]{author}{\namepartfamily\space\namepartgiven}%
\DeclareNameFormat[book]{author}{\namepartgiven\space\namepartfamily}%
```

#### 区切り文字（デリミタ）

たとえば著者姓と著者名の間の区切り文字を「，」でなく「 」にしたいというだけであれば，フィールドの書式を定義しなおさなくても，各フィールドの書式に使用されている区切り文字（デリミタ）を定義し直すだけで十分かもしれません。たとえば，著者名を「family-given（姓-名）」の順で表示する場合のデリミタは「`\revsdnamepunct`」という名前で定義されており，`authoryear`スタイルや`apa`スタイルでは，この中身は「\addcomma\space（, ）」となっています。これを「\space」に変更すれば，著者姓と著者名の間には空白が挿入されるようになるのです。

ただし，単にこの「`\revsdnamepunct`」を修正しただけでは，言語に関係なくすべての文献で著者姓と著者名の間が空白で表示されてしまいます。英語文献の場合は「Familyname, Givenname」，日本語文献の場合には「Familyname Givenname」というように，言語によって区切り文字を変更したい場合には，文献項目の読み込みのたびに実行される`AtEveryBibitem`に，次のように設定をしておきます。

```
\AtEveryBibitem{%
  \ifthenelse{\boolean{japanese}}{%
    % 文献の言語が日本語の場合は区切り文字は空白
    \renewcommand*{\revsdnamepunct}{\space}%
  }{%
    % 文献の言語が日本語以外の場合は区切り文字はコンマと空白
    \renewcommand*{\revsdnamepunct}{\addcomma\space}%
  }%
}
```

BibLaTeXでは，`***punct`や`***delim`という名前で多数の区切り文字があらかじめ定義されています。どのような区切り文字がどのように定義されているのかについては，BibLaTeXのマニュアルやbiblatex.defファイル，あるいはベースとして使用するスタイルの`.bib`ファイルを参照してください。また，これらのデリミタは，次のようにして特定の文脈のみに限定した指定もできます。

```
\DeclareDelimFormat[bib,biblist]{\revsdnamepunct}{\addcomma\space}%
```

この場合には，このデリミタに関する指定は文献リストの文脈にのみ適用され，それ以外の文脈，たとえば本文中への引用には適用されません。

## `.cbx`ファイルの作成

`.cbx`ファイルの設定も，基本は`.bbx`ファイルと同じです。`.cbx`ファイルでは`\textcite`や`\parencite`などの引用コマンドごとにマクロが定義されており，必要に応じてこれらのマクロの設定を変更することで希望する結果が得られます。これらのマクロは，引用する文献エントリごとに実行されるので，たとえば直近に処理した文献エントリの著者名ハッシュを保存することで，「山田（2001）」と「山田（2005）」のような同じ著者による複数の文献を「山田（2001,2005）」のようにひとまとめにして表記することができます。

```
\renewbibmacro{textcite}{
  \iffieldequals{namehash}{\cbx@lasthash}{%
    % このエントリの著者が直前のエントリと同じ場合（著者名を表示しない）
    \setunit{\compcitedelim}%                区切り文字を表示
    \usebibmacro{cite:plabelyear+extradate}% 出版年を表示
  }{%
    % それ以外の場合（著者名を表示する）
    \printnames{labelname}%                  著者ラベルを表示
    \setunit{\printdelim{nameyeardelim}}%    区切り文字を表示
    \usebibmacro{cite:plabelyear+extradate}% 出版年を表示
    \savefield{namehash}{\cbx@lasthash}}%    このエントリの著者を保存
    \setunit{\multicitedelim}%               引用の区切り文字を表示
  }%
}
```

なお，すでに述べたように，`.cbx`ファイルは`RequireCitationStyle{}`で既存のスタイルファイルを読み込んで上書きして使用することができますので，自分が利用したいスタイルファイルにもっとも近いものを読み込み，必要な部分のみ修正を加えるようにするのがよいでしょう。