texjporg / tex-jp-build

Minimum source repository to build Japanese TeX processing tools
23 stars 6 forks source link

bibtexuの日本語(CJK)対応 #139

Closed t-tk closed 2 years ago

t-tk commented 2 years ago

bibtexuを日本語(あるいはCJK)対応にしたいと思い検討を始めました。ご意見あればお願いします。 少々長くなります。まずは状況のまとめから。 日本語化に関わる(u)pbibtex, bibtexuの組み込み関数の状況を簡単に表にまとめました。

function (u)pbibtex bibtexu 備考
SORT バイト順[1] ICU
change.case$ ASCIIのみ[2] ICU upbibtexを改善したい
width$ 不正確 Latin-1,ExtA, CJK対応(v3.80)
substring$ 多バイト対応 CP毎(v3.80)
text.length$ 多バイト対応 CP単位
text.prefix$ 多バイト対応 CP毎
add.period$ !?等の後無効 !?等の後無効(v3.80)
chr.to.int$ 先頭バイト CP毎(v3.80)
int.to.chr$ バイト単位 CP毎(v3.80)
num.names$ 日本語氏名対応 CJK対応(v4.00)[3] bibtexuに導入した(v4.00)
format.name$ 日本語氏名対応 CJK対応(v4.00)[3] bibtexuに導入した(v4.00)
is.kanji.str$ CJKを検出 CJK検出(v4.00)[4] bibtexuに導入した(v4.00)
is.cjk.str$ [4] CJK検出(v4.00)[4] bibtexuに導入した(v4.00)。upbibtexは導入見送り。

※CP: codepointを略した。サロゲートペアは1CP。合成文字やIVSなどは複数のCPで1文字になる。

upbibtexは、[1] ソートはバイト順、[2] 大文字小文字変換はASCIIのみというところに制限がある。大文字小文字変換はもう少し拡張の余地があると思っているが、ソート順の多言語化をちゃんとやろうとするとICUを使わざるを得なくなる。それならbibtexuに日本語機能を入れた方が早かろう、というのが今回の開発の動機。ついでに、多バイト対応の部分でトラブル続きのupbibtexの弱点もカバーできることを期待。

(u)pbibtexはそのもとのjbibtexの頃から文字列処理の関数(substring$,text.prefix$など)の処理がバイト単位であり、多バイト対応する方針で作られている。 bibtexuは、それらがコードポイント(CP)単位で動くことを目指している模様。 しかしbibtexuを調べてみるとちゃんと動いていなかった。例えばsubstring$にBMP超えの文字を入れると文字列が壊れた。 substring$, chr.to.int$, int.to.chr$ はまともに動くように改良して v3.80 としてコミットした。 add.period$ は、(u)pbibtex と同様に、「‼⁇⁈⁉‽!?」の後ではピリオドを追加しないようにbibtexu v3.80 に入れた。 width$ は upbibtex ではまともと言えないまま今まで対応してこなかった。bibtex[8u]でも今までASCIIの範囲した対応していなかった。今回、Latin-1, Latin Extended A, CJKの文字でまともになるようにしてbibtexu v3.80 に入れた。

bibtexu の日本語対応はもう先が見えるところまで来ていると考えている。 upbibtexと比較して、日本語処理のために bibtexu で不足している残件は[3]num.names$, format.name$の日本語氏名対応、[4]is.kanji.str$の日本語(CJK)文字列の検出の2つ。 [3]は{j,(u)p}bibtexの仕様をそのままbibtexuに入れたいと考えている。→ v4.00で入れた。 [4]は、bibtexuに持ち込む際、"kanji"という日本語に依存した名前でなく is.cjk.str$ に名前を変えて入れたい。 そして、(u)pbibtex に is.cjk.str$is.kanji.str$ のエイリアスとして入れて、スタイルファイル .bst の is.kanji.str$ is.cjk.str$ に変更していけば upbibtex と bibtexu での共用が可能になる。→ bibtexu(v4.00) にis.kanji.str$ is.cjk.str$ を入れた。upbibtex は変更なし。

今後のことを考えるとここ(tex-jp-build)にbibtex-xのソースも入れて管理したい。

t-tk commented 2 years ago

tex-jp-buildにbibtex-xのソース を追加しました。

aminophen commented 2 years ago

bibtex の ICU 活用は,たしかに魅力的です。ありがとうございます。今思ったことをメモしておきます。

t-tk commented 2 years ago

コメントありがとうございます。 tests/bibtexu-yannis.test は、2021年8月の改修で r60293 で再度有効にした後、 TeX Live 2022 のテストでも問題になっていないのでもう安心してよいと思います。逆に言うと、つい最近までちょっとのことで問題が発覚する位脆弱な状態だったとも言えますが。 今回、bibtex8 に使われている巨大メモリーのテストをbibtexuにも入れたので環境依存の問題も見つけやすくなったと思います。 is.kanji.str$ の方は、そうですね。bibtexu に is.kanji.str$ を入れる、または is.kanji.str$is.cjk.str$ の両方を入れる方向で考えます。

t-tk commented 2 years ago

いろいろ試しています。今考えている方針について、備忘録を兼ねて書いておきます。 ご意見があればお願いします。

[1] upbibtex, change.case$ Latin-1, Latin Extended-A, Greek, Cyrillicの主なものには対応したい。 トルコ語のdotless iなどには対応しない。 大文字のエスツェットU+1E9Eは対応しない。 小文字のエスツェットU+00DFはの大文字化は "ß" → "SS" とする。(ICUもそうなっている。bibtexuもそれを利用)

U+00DF ß LATIN SMALL LETTER SHARP S, 0xC3 0x9F in UTF-8 U+1E9E ẞ LATIN CAPITAL LETTER SHARP S, 0xE1 0xBA 0x9E in UTF-8

pbibtex は対応しない。

[2] upbibtex, is.kanji.str$ 基本的に現状維持のつもり。 ただし、"Ideographic Description Characters" は、漢字というよりCJK記号の方が適切。 upTeXでの分類が不適切だった。 次回の更新で「漢字」→「CJK記号」の変更をして is.kanji.str$ の判定からも外したい。 bibtexuに追加予定の is.cjk.str$ と同様の拡張も可能と思うが実装が面倒なので見送り。

[3] bibtex[8u], ビット和とビット積 bibtexuに追加するつもりの is.cjk.str$ とのからみで整数のビット論理和の演算子 | とビット論理積の演算子 & を追加。 Unicodeに関係なく有用と思われるので bibtex8, bibtexu の両方に追加予定。

[4] bibtexu, is.cjk.str$, is.kanji.str$ is.kanji.str$ と同様の目的だが拡張した仕様でbibtexuに新設する。 スタックの文字列をポップし、文字列内にCJKの文字が含まれればビットを立てた整数を返す。 漢字、かな、ハングル、注音記号、その他CJKの文字が含まれればそれぞれ、0x001, 0x002, 0x004, 0x008, 0x800 のビットを立てる。 文字列が漢字とCJK以外(ASCII等)で構成されていれば 0x001, 文字列が漢字とかなとCJK以外(ASCII等)で構成されていれば 0x003, 文字列が漢字とハングルとCJK以外(ASCII等)で構成されていれば 0x005, 文字列が漢字とかなと全角英数字とCJK以外(ASCII等)で構成されていれば 0x803 が返り値となる。 is.cjk.str$ の返り値と論理積を取ればどの文字集合を含んでいるかを得ることができる。 is.kanji.str$ は、(u)pbibtexとの互換性目的だが is.cjk.str$ の alias とする。 upbibtex の is.kanji.str$ が "1" しか返らないのと違って返り値が多様な整数値となるが、実用上問題ないはず。

CJKの間でニュートラルな、日本語偏重ではない仕様となり、幅広く応用可能であり、名案だと自画自賛。

[5] bibtexu, num.names$, format.name$ jbibtex の仕様をそのまま採用する方針。" ” が姓と名の区切り、"、", ","が姓名と姓名の区切りに使える。 jbibtex 同様、入力は「姓 名」の順序を想定。 {ff}が姓、{ll}が名となり意味的には欧米の習慣と逆になるが、想定のbstは {ff}{ll} であり出力は「姓名」の順になる。

[6] bibtexu の行分割 以前 upbibtex で問題になったCJK文字と空白の間の行分割について https://github.com/texjporg/tex-jp-build/pull/132 https://github.com/texjporg/pbibtex-manual/issues/1

同様の問題は bibtexu でも発生するので対策を試している。 行分割を許すのはLatin, Greek, Cyrillicと Hangul Syllables としてその他大多数は分割不可としてみた。 分割許容と分割不可の境目をどうしたらよいのか、自信が無い。

Hangul Syllables の場合が適切なのか不安。 Hangul Syllablesの直後に改行が来た場合 upTeX では空白扱いとなるようにしているが XeTeXやLuaTeX ではどうしているのか??

[7] bibtexu で jbibtex のテスト jbibtex の配布に含まれる j*.bst を UTF-8 にしたものでぼちぼちテストを開始。 大体動いている。 upbibtex と比べて行分割の位置が違ったり、文字列中のBOMが自動的に消されないで残ったり細かい違いはあるが問題は見つかっていない。 テストファイルはここのブランチには入れているがTeX Live svnには持ち込まないつもり。

[8] j.bst の文字コード 現在 j.bst の配布の文字コードは JIS になっている。 将来 bibtexu 兼用にするためには、配布も UTF-8 にしたい。XeLaTeXやLuaLaTeXとの併用も視野に入れたい。 しかし、その場合pLaTeX + ShiftJIS/EUC + 非Windowsの環境が動かなくなる。 UTF-8への移行を推奨するか、漢字の自動判定をTeX Liveに持ち込むか。

[9] upbibtex chr.to.int$, int.to.chr$の多バイト対応 今まで問題になったこともなく、バグではなく「仕様範囲外」「未実装」 の項目と思うが出来た方が美しい。 未着手だがやってみるか。

[10] その他 テストの追加、マニュアル記載が直近の課題。 仕様的にはいい線いっていると思う。順次TeX Live svn にコミットしていきたい。 bibtexu の日本語対応、CJK対応でまだ残っている課題があるのか?

[11] (追記) max_print_line max_print_line を texmf.cnf 等で設定できるようにする。 従来ハードコードされていて url の表記などで問題になっていた。

t-tk commented 2 years ago

これまで bibtex[8u] に入れて試していた更新を TeX Live svn にコミットしました(r63173)。

https://github.com/texjporg/tex-jp-build/issues/139#issuecomment-1107694857 の中で残件は [1], [2], [8], [9]

t-tk commented 2 years ago

日本人の姓と名の順番について↓の記事を見ました。 https://shiro-takeda.hateblo.jp/entry/%3Fp%3D2638 https://github.com/kmaed/biblatex-japanese/issues/18

jbibtex に付属していた jplain.bst は .bib で "姓 名" の順番に書き .bst では {ff}{ll} の順番を指定し .bbl では "姓名"と出力するようになっています。 その代わりに "名 姓" の順番で .bib を作ることを前提とした場合、 *.bst では is.kanji.str$で日本語判定されたとき {ll}{ff} の順番を指定するようにすればよいだけのように思います。 jbibtex の作者の松井さんも迷った末に format.names$ の改造は見送られたようです。 今回の bibtexu の CJK 対応でもそうする(対応無し)つもりです。

t-tk commented 2 years ago

これまで upbibtex に入れて試していた更新を TeX Live svn にコミットしました(r63246)。

max_print_line を texmf.cnf 等で設定できるようにしました。 従来 max_print_line はハードコードされていて url の表記などで問題になっていました。 Greek, Cyrillic で change.case$ の動作が変わることになる (今まで効いていなかったものが動くようになる)。 それで困る場合(大文字化、小文字化を無効にしたい場合)は、入力時に {ΑΠΣ} {απσ} {АРЯ} {апя} のように波括弧付きで入力していただくか、pbibtex を使っていただくつもり。

https://github.com/texjporg/tex-jp-build/issues/139#issuecomment-1107694857 の中で残件は [8], [9] と pbibtex-manual の [10] ただし、[2] の upTeX での対応はまだ。

t-tk commented 2 years ago

https://github.com/texjporg/tex-jp-build/issues/139#issuecomment-1107694857 の中の[9]は、https://github.com/texjporg/tex-jp-build/commit/00d50b2233328406df7af9fd5cced8d2312b9874 を予定。→ r63305コミット

多バイト文字の文字コードの整数値は pbibtexでは JIS すなわち ( Ku + 0x20 ) << 8 + ( Ten + 0x20 ) upbibtexでは Unicodeスカラー値 (UTF32)

aminophen commented 2 years ago

追いつけていませんが,色々と検討ありがとうございます。

pbibtexでは JIS すなわち ( Ku + 0x20 ) << 8 + ( Ten + 0x20 )

これについては,従来の jbibtex.pdf(松井さんのもの)に

chr.to.int$ は引数が漢字コードならばsingle characterでなくてもwarningを出さず,漢字文字列の1バイト目のコードを値として返すようにした これは0.10バージョンで試作したスタイルファイル中で,漢字コード文字列の判定をいいかげんに行うために必要となった変更であり,0.20バージョンでは漢字コード文字列判定用に新たな組み込み関数を追加したので不要かも知れない.

と書かれているのですが,pbibtex では変更する,という理解でよいでしょうか。

t-tk commented 2 years ago

はい。pbibtex Ver0.35 (TeX Live 2023)以降では、今回の試作の通りの仕様に変更したいと考えています。理由は以下の通りです。 chr.to.int$ の仕様として漢字文字列の1バイト目のコードを返す、というのが自然な仕様とは思いにくく、変更後の仕様の方が自然と感じる。 pbibtex-base の中の *.bst でも多バイト文字には使われていないようだし、ASCIIよりも大きな正の整数が帰り値となることに変わりないので変更に伴って問題が発生することは稀であろう。

aminophen commented 2 years ago

ASCIIよりも大きな正の整数が帰り値となることに変わりないので変更に伴って問題が発生することは稀であろう

なるほど,確かにそうですね。了解です。

t-tk commented 2 years ago

(u)pbibtex に施した拡張の分のマニュアルへの記載の追加とテストの追加を行いました。 (u)pBibTeX j0.35 (TeX Live 2023/dev)拡張のマニュアル化 TeX Live 2023 のコードフリーズの頃にCTAN投稿する予定です。

bibtexu の日本語対応をpbibtex-baseに入っている j*.bst, jxampl.bib, jbtxdoc.bibでテストした結果、 予定通り、(u)pbibtex との差分はほとんどなく、ほぼ互換で実用的な問題が無いというレベルになっています。

唯一はっきり違う点は次の通りです。 jname.bst で以下のような差が出ています。 p が pbibtex, up が upbibtex, bu が bibtexu の結果の*.bblです。

❯ diff3 tests/jxampl/output/jxampl-jname-{p,up,bu}-wide.bbl
====
1:307c
  \bibitem[富士80]{ssl}
2:307c
  \bibitem[富80]{ssl}
3:307c
  \bibitem[富士通80]{ssl}

https://github.com/texjporg/tex-jp-build/issues/139#issuecomment-1107694857 の中で残件は [8]  →今後、文字コードを JIS → UTF-8 に? で扱います。 それと[2] の upTeX での対応はまだ。  →今後、Unicode 15.0.0 で扱います。

あとは宣伝です。ここは閉じようと思います。

t-tk commented 2 years ago

bibtexuの日本語(CJK)対応の一連の改良や拡張が一段落したので、日本語化に関わる(u)pbibtex, bibtexuの組み込み関数の状況の表をまとめ直しました。

function (u)pbibtex bibtexu 備考
SORT バイト順[1] ICU
change.case$ ギリシャ、キリル文字対応[2] ICU upbibtex(u1.29)で拡張
width$ 不正確 Latin-1,ExtA, CJK対応(v3.80)
substring$ 多バイト対応 CP毎(v3.80)
text.length$ 多バイト対応 CP単位
text.prefix$ 多バイト対応 CP毎
add.period$ !?等の後無効 !?等の後無効(v3.80)
chr.to.int$ CP毎(j1.35) CP毎(v3.80) (u)pbibtex(j1.35)で拡張
int.to.chr$ CP毎(j1.35) CP毎(v3.80) (u)pbibtex(j1.35)で拡張
num.names$ 日本語氏名対応 CJK対応(v4.00)[3] bibtexuに導入した(v4.00)
format.name$ 日本語氏名対応 CJK対応(v4.00)[3] bibtexuに導入した(v4.00)
is.kanji.str$ CJKを検出 CJK検出(v4.00)[4] bibtexuに導入した(v4.00)
is.cjk.str$ --- CJK検出(v4.00)[4] bibtexuに導入した(v4.00)。upbibtexには導入しない。

※CP: codepointを略した。サロゲートペアは1CP。合成文字やIVSなどは複数のCPで1文字になる。

upbibtexは、[1] ソートはバイト順というところに制限がある。ソート順の多言語化をちゃんとやろうとするとICUを使わざるを得なくなる。今回のbibtexu の日本語対応は将来そちらに進むことができるようにするのが狙いの一つ。

upbibtexは、[2] 大文字小文字変換はASCIIのみという制限があったが、Latin-1, Latin Extended-A, Greek and Coptic, Cyrillic, Cyrillic Supplementブロックの文字も変換対象とするように今回(u1.29)拡張した。

bibtexu(v4.00まで)に施した改良、拡張は以下。 (u)pbibtexはそのもとのjbibtexの頃から文字列処理の関数(substring$,text.prefix$など)の処理がバイト単位であり、多バイト対応する方針で作られている。 bibtexuは、それらがコードポイント(CP)単位で動くことを目指している模様だが、今までちゃんと動いていなかった。 substring$, chr.to.int$, int.to.chr$ はまともに動くように改良して v3.80 としてコミットした。 add.period$ は、(u)pbibtex と同様に、「‼⁇⁈⁉‽!?」の後ではピリオドを追加しないようにbibtexu v3.80 に入れた。

width$ は upbibtex では今までちゃんとした対応がなく、今回も対応していない。 bibtex[8u]でも今までASCIIの範囲しか対応していなかった。今回、Latin-1, Latin Extended A, CJKの文字でまともになるようにしてbibtexu v3.80 に入れた。

[3]num.names$, format.name$の日本語氏名対応は、{j,(u)p}bibtexの仕様をそのままbibtexu(v4.00)に入れた。

[4]is.kanji.str$の日本語(CJK)文字列の検出。bibtexuに持ち込む際、 is.cjk.str$ という名前で CJK の文字を検知できるものを入れ、is.kanji.str$is.cjk.str$ のエイリアスとしてbibtexu(v4.00) に入れた。upbibtex は変更なし。

以上の改良や拡張の結果、bibtexu (v4.00) は (u)pbibtex とほぼ互換で日本語対応できている。 upbibtex と bibtexu の機能の差は上記の表のとおりで、結果として *aux, *.bib, *.bst の処理に現れる違いは

何かお気づきの点があればお知らせください。