Sphinxでbibtexを使うときの引用ラベルのカスタマイズ

reStructuredTextはちょっとめんどくさいけどすばらしいです。Markdownなんかではやっていけません。LaTeXは人間が書くものでなくなってほしいです。あいだをとってreSTは良いです。

そんなreSTでも参考文献は大事です。LaTeXをやめられない理由のひとつにbibtexを使ったcitationがあります。reST+Sphinxでbibtexを使うために[sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/en/latest/)という拡張機能が開発されています。

引用ではスタイルも大事です。論文[1]と書くより [Cheng 10] とかって書きたくないですか。わたしは [jsai.bst](http://www.ai-gakkai.or.jp/jsai2017/author-guideline/) 派なので [Cheng 10] のような表記が好きです。

sphinxcontrib-bibtexのデフォルトで存在するスタイル（pybtexのスタイル）がplainと日本語消えるやつ（alpha）くらいしかなかったので、引用ラベルだけjsai.bstっぽくする設定を書きました。あとついでにそのままの引用キーがでるものも。
（もしかしたらなんですけど、bstファイルをそのまま使う方法が存在しそうな気もします）

以下のコードをSphinxのconf.pyに書き込むと、jsaiとkeyというスタイルが使えるようになります。
jsaiを使うと[Author 10]のような表記になって、keyを使うとbibtexの引用キーそのままが表示されます。

# keyスタイル

```python
from pybtex.style.formatting.unsrt import Style as UnsrtStyle
from pybtex.style.labels import BaseLabelStyle
from pybtex.plugin import register_plugin

class KeyLabelStyle(BaseLabelStyle):
    def format_labels(self, sorted_entries):
        return [entry.key for entry in sorted_entries]

class KeyStyle(UnsrtStyle):
    default_label_style = 'keylabel'

register_plugin('pybtex.style.labels', 'keylabel', KeyLabelStyle)
register_plugin('pybtex.style.formatting', 'key', KeyStyle)
```


利用例：

```
～～では論文 :cite:`Lazer2009` を参照。

.. bibliography:: references.bib
   :style: key
```

入力bibtex：

```
@article{Lazer2009,
 author = {Lazer, David and Pentland, Alex and Adamic, Lada and Aral, Sinan and Barab{\'{a}}si, Albert-L{\'{a}}szl{\'{o}} and Brewer, Devon and Christakis, Nicholas and Contractor, Noshir and Fowler, James and Gutmann, Myron and Jebara, Tony and King, Gary and Macy, Michael and Roy, Deb and {Van Alstyne}, Marshall},
 journal = {Science},
 number = {5915},
 pages = {721-723},
 title = {{Computational Social Science}},
 volume = {323},
 year = {2009}
}
```

出力：

> ～～では論文 [Lazer2009] を参照。
> [Lazer2009]	David Lazer, Alex Pentland, Lada Adamic, Sinan Aral, Albert-László Barabási, Devon Brewer, Nicholas Christakis, Noshir Contractor, James Fowler, Myron Gutmann, Tony Jebara, Gary King, Michael Macy, Deb Roy, and Marshall Van Alstyne. Computational Social Science. Science, 323(5915):721–723, 2009.


# jsaiスタイル

```python
from pybtex.style.formatting.unsrt import Style as UnsrtStyle
from pybtex.style.labels import BaseLabelStyle
from pybtex.plugin import register_plugin
import unicodedata
from collections import Counter

def is_japanese(string):
    for c in string:
        name = unicodedata.name(c)
        if('CJK UNIFIED' in name or
           'HIRAGANA' in name or
           'KATAKANA' in name):
            return True
    return False

class AuthorYearLabelStyle(BaseLabelStyle):
    def format_labels(self, sorted_entries):
        labels = [self.format_label(entry) for entry in sorted_entries]
        # keyが同じentryをuniqueにする
        counter = Counter(labels)
        counted = Counter()
        for label in labels:
            if counter[label] == 1:
                yield label
            else:
                yield label + chr(ord('a') + counted[label])
                counted.update([label])

    def format_label(self, entry):
        # authorもyearもないエントリ
        if not 'author' in entry.persons and not 'year' in entry.fields:
            return entry.key
        # labelはfirst authorのlast name + year
        if 'author' in entry.persons:
            firstauthor = entry.persons['author'][0]
            if is_japanese(''.join(firstauthor.first_names + firstauthor.last_names)):
                author = ''.join(firstauthor.first_names)
            else:
                author = ''.join(firstauthor.last_names)
        else:
            author = ''
        if 'year' in entry.fields:
            yeartail = entry.fields['year'][-2:]
        else:
            yeartail = ''
        return '%s %s' % (author, yeartail)

class JsaiStyle(UnsrtStyle):
    default_label_style = 'authoryearlabel'

register_plugin('pybtex.style.labels', 'authoryearlabel', AuthorYearLabelStyle)
register_plugin('pybtex.style.formatting', 'jsai', JsaiStyle)
```


利用例：

```
～～では論文 :cite:`Lazer2009` を参照。

.. bibliography:: references.bib
   :style: jsai
```

出力：

> ～～では論文 [Lazer 09] を参照。
> [Lazer 09]	David Lazer, Alex Pentland, Lada Adamic, Sinan Aral, Albert-László Barabási, Devon Brewer, Nicholas Christakis, Noshir Contractor, James Fowler, Myron Gutmann, Tony Jebara, Gary King, Michael Macy, Deb Roy, and Marshall Van Alstyne. Computational Social Science. Science, 323(5915):721–723, 2009.


# 今後の課題

ラベル部分だけじゃなくて名前やタイトルやページ数表記などもカスタマイズしたい。

bibtexから余計なフィールドを取り除く[bibtex cleaner](https://bibtexcleaner.herokuapp.com/)もよろしくお願いします。