MakeIndex, Mendex, XindyとMendexのUnicode化

MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
返信数: 29
ここのディスカッショントピックupLaTeX+mendexで索引作成時のトラブルでも話題になっていたように、
現在、Mendexでは、UTF-8の入力には対応しているものの、内部はEUC-JPのままです。
(e-)(u)pLaTeXのみならずXeLaTeX, LuaTeX-jaとの組み合わせでも
日英二か国語までは使えているはずですが、
文字コードのまま直接扱えるのはJIS第1,2水準までで、
鷗外の「鷗」などは直接扱えません。
(ptexencの機能で^^e9^^b7^^97に置き換えられる。)

では、何をどのくらいまで手に入れればよさそうか、ということを考え始めています。
もしよろしかったら議論におつきあいください。

まずは、MakeIndex, Mendex, Xindyの状況をTeX Wikiの索引作成のツール比較の項
簡単にまとめてみました。
誤認や不足があれば修正いただけると助かります。

以下は、今、私が考えていることです。

日本語の索引作成という観点では、Mendexの
「日本語のインデックスは、読みによるソートを行う」
「インデックスとして、表記+読みの組の入力が可能」
は、機能としてぜひほしいところ。
「辞書ファイルの利用により、読みの入力の軽減が可能」は、
あれば便利だが、無いとどうしようもないというほどではない。

Xindyは、多言語化を目指している点、カスタマイズ可能な開発方針や、
開発が活発な点で期待が大きい。
しかし、日本語の索引作成の面で
「日本語のインデックスは、読みによるソートを行う」
「インデックスとして、表記+読みの組の入力が可能」
のあたりの機能はまだ持っていないようだ。
大方針として、Xindyにそのような日本語向け機能を追加する、という案は、
将来性としてはよさそうだが、
中身がLispなので、私が改造したり、パッチを提案したりは難しそう。

Mendexは、日本語の索引作成機能としては、重要な点が押さえられており、
日本人にとって使いやすいことは間違いなさそう。
しかし、内部コードがEUC-JPべったりのハードコードになっており、
Unicode化へのハードルは高い。
現在の、入力コードにUTF-8が使える状態をゼロ段階として、
二段階のUnicode化を考えてみました。

[1] 表記+読みのうち、表記だけを内部Unicode(UTF-8)化する。
読みやソートのアルゴリズムは、現状のEUC-JPのまま。
読みにJIS第三水準の仮名(アイヌ語用の小仮名等)は使えない。
ハングル等の日英以外の言語は使えない。
表記にはUnicodeがフルに使えるようになるし、
ソートは現状でも実用レベルであるため、
日英二か国語の範囲ではかなり強力になるはず。

[2] 読みも内部Unicode化する。
ソートのアルゴリズムにICUを使う。
あわよくば、ソートの部分にギリシャ文字、キリル文字、ハングル等も使えるようになり、
多言語化が進められるようになるはず。

今後についてですが、
[1]の改造を少々試してみたところ、
もう一息でちゃんと動くところまで来ました。
アスキーメディアワークスさんのMendexのソースからかけ離れることなく実現出来そうです。
そこでMendexの修正という形でTeX Liveに入れさせてもらおうと考えています。
しかしTeX Live 2014のcomplete freezeまであとわずかしかないので、
安全性を考えてTeX Live 2015を目指そうと思っています。

[2]は、MendexのソースコードのEUC-JP依存のところをすべて書き換えることになり、
大きな改造になることは必至。
しかもEUC-JP依存の部分(後方互換性)を残したまま改造を進めるのはつらそう。
Mendexのソースを出発点にするにしても、抽象化を進めICU呼び出しを足していくイメージになりそう。
なので、「Mendex + パッチ」の形はあきらめてMendexとは別の名前で開発してみようかな、
と思っています。
以前は、大改造のイメージしかなく二の足を踏んでいたのですが、
ICUを使って多言語化の道も開けるならやってみようかな、と思い始めているところです。
Xindyとの位置関係が微妙ですが…。

調べていて疑問に思ったのですが、
中国語、韓国語などでは、MakeIndexの類のツールは作られたり利用されたりしていないのでしょうか?

t tk への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- 本田 知亮 の投稿
徒然なことを書かせていただきますが
ご容赦を.

現場としては
じつはUTFとかそういう問題は大きくないです.
文字種の問題は最悪のケース,
作字すればなんとかなります

索引を作る際に頭がいたいのは
ソートの規則のほう(*1)で,
ソートの規則を外側から指定できれば
とてもうれしいです.

(*1)出版社ごと,
場合によっては編集者ごとに微妙に違う。。。

ソートの規則としては

(1)無視する文字
(2)同一視する文字
(3)具体的な順番
(4)同じソート順の語句をどのような順番で並べるか

を決めてあげてあとは辞書式ってところでしょうか.
現状,
(1)は「よみにいれない」
(2)は「よみでは同じ文字にする」
ということで処置していますが,
これがなかなかにつらいものです
やっつけのスクリプトで処理しますが
indexの中身が複雑になるとしんどいです

索引生成ツールで実際にソートのために
渡されてくるものに対して適用されるソートの規則を
いじれるといいのではないかと思います

(4)については,索引の場合,
単純にソートが安定とかそうではないとかよりも
たとえば初めの出現ページが前の方が前とか
恣意的に「大事な語句が前」とかということが
あると思います
本田 知亮 への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
貴重なご意見ありがとうございます。

索引生成ツールで実際にソートのために
渡されてくるものに対して適用されるソートの規則を
いじれるといいのではないかと思います

ソートについては、
mendexのソースを眺めたところ、
日英の用途でも物足りない部分がありそうだ、と想像しておりました。
ICUでは、そのあたりのカスタマイズが出来るらしいので、
ソートをICUへ丸投げにするにしても、
インターフェースを上手に作りさえすれば強力になるのではないか、
と目論んでおります。
先は長そうですが、構想を持って、いろいろ試してみたいと思います。

t tk への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Shikano Keiichiro の投稿
mendexの近代化は将来を考えるととても助かります。

ベースとなるソースについてですが、アスキーで配布されてる2.6eにはページ範囲の出力などにバグが残っている状態だったと記憶してます。

  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=534641

最新のTeX Liveに収録されてるものでは修正が施されてるとも聞いてるので杞憂かもしれませんが、念のためコメントです。

ちなみに韓国語については、専用のツールはあるけれど日本語のようにソート順をすべて原稿上で与える必要があるわけではないし厄介に感じたことはない、という話をTUG 2013でCho先生から聞きました。
Shikano Keiichiro への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
コメントありがとうございます。韓国語の話も参考になりました。

今のTeX Live svnにあるコードは、2.6fになっています。
ChangeLog.jp によると、

2.6e->2.6f
・2階層以上の索引の親階層の読みが直前の索引と同じ場合、親階層が出力されない不具合を修正。

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=534641
に関するところは、↓で修正されているのだと理解しました。
http://www.tug.org/svn/texlive/trunk/Build/source/texk/mendexk/fwrite.c?r1=27982&r2=31621&sortby=date

今後の改造は、TeX Live svnのコード(+[1]の改造)をベースにする予定ですので、
ご指摘の点は修正済みになっていると思います。

t tk への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
[1] 表記+読みのうち、表記だけを内部Unicode(UTF-8)化する。
この改造をしたパッチを作成しました。
upTeXのページ で公開しました。
テストに使用したサンプルファイルも一緒に付けています。
奥村先生ご指摘の「森鷗外」の例もOKになります。

オプション -I を追加しました。
mendex -U -I utf8 hoge.idx
で「表記+読み」のうち、「表記」のデータのバッファをUTF-8にします。
mendex -U -I euc hoge.idx
ではオリジナルと同じように、「表記」のデータのバッファをEUC-JPにします。
いずれの場合も「読み」のバッファはEUC-JPのままですし、
ソートのアルゴリズムも従来と同じです。

内部バッファの文字コードのdefaultの値は、
入力文字コードのオプションにより依存するようにしてみました。
-S (shift_jis), -E (euc), -J (jis) は、オリジナルと同じ -I euc 相当、
-U (utf8)は、 -I utf8 相当
がdefaultです。

-I euc と -I utf8 とでは、
多くの場合、出力結果は完全に一致しますが、
同音異義語が含まれる場合、*.indの出力で、その語の順序が入れ替わることがあるようです。(例: samples/dakuten.tex)
パッチ前のmendexと同じ出力を得ようとするならば、
(パッチ前) mendex -U hoge.idx
(パッチ後) mendex -U -I euc hoge.idx
とすればよいです。

予想通り小さなパッチで済み、充分テストしたつもりですが、
TeXLive 2014は、コードフリーズまで一週間を切っており、
今のタイミングで突っ込むべきかどうか、
安全側に考えて控えるべきか、迷っています。
ご意見があればお願いします。

t tk への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- 奥村 晴彦 の投稿
> 奥村先生ご指摘の「森鷗外」の例もOKになります。

それはありがたいです!
TeX Live 2014に入れちゃえ!(私は危険人物 ;-) )
奥村 晴彦 への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
背中を押されたので賛成
r33962, r33963でTeX Live svnにコミットしました。
角藤先生にW32TeXにも入れていただいたようです。ありがとうございます。

t tk への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Dora TeX の投稿
ありがとうございます。さっそく試させて頂きました。
\index{もりおうがい@森鷗外}
の例なども正しく動きました。

ただし,当方の環境では,
\indexentry{A|see{あ}}{1}
のように see{} の中に和文文字を入れたutf8の .idx を
mendex -U hoge.idx
で処理すると,
Bad encap string in hoge.idx, line 1....done (0 entries accepted, 1 rejected).
というエラーが出ました。
mendex -U -I euc hoge.idx
ならば問題ありませんでしたが。
Dora TeX への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Akira Kakuto の投稿
こちらも同じです:

\indexentry{もりおうがい@森鷗外|see{あ}}{1}
は ng
\indexentry{もりおうがい@森鷗外|see{漢字}}{1}
は ok
Akira Kakuto への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Akira Kakuto の投稿
以下のパッチでなおるのではないかと思います:

--- fread.c.orig Sun May 11 23:05:58 2014
+++ fread.c Sun May 11 23:40:27 2014
@@ -455,10 +455,6 @@
if (buff[i]==arg_open) nest++;
else if (buff[i]==arg_close) nest--;
estr[i]=buff[i];
- if ((unsigned char)buff[i]>0x80) {
- i++;
- estr[i]=buff[i];
- }
}

return -1;
Akira Kakuto への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Dora TeX の投稿
角藤先生,ありがとうございます。
そのパッチを当ててみたところ,問題なく see{あ} が通るようになりました。
Dora TeX への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- Akira Kakuto の投稿
同じパッチを svn に適用しておきました。
Akira Kakuto への返信

Re: MakeIndex, Mendex, XindyとMendexのUnicode化

- t tk の投稿
やらかしてしまいました悲しい
EUC-JPの2バイトを仮定している場所は他にもありましたので、
修正し、
TeX Live svnに r33996 のようにコミットしました。
see{あ} のテストも一緒に入れました。

今度は大丈夫であることを祈ります。

t tk への返信

mendex v3.0 (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
4年ぶりの更新になります。
mendex の「読み+表記」のうち「表記」の文字コードのデフォルトを UTF-8 に変更する方針です。
mendex version 3.0 [15-May-2018] としました。
TeX Live svn にコミット済み、W32TeX では導入済み、その他はTeX Live 2019にて反映される予定です。

Windowsでは、入出力の文字コードのデフォルトも ShiftJIS から UTF-8 に変更になります。

詳細は githubの mendexのデフォルト文字コードのUTF-8化 をご覧ください。

以下の例は、pLaTeXでもupLaTeXでも通用する例です。
以前はmendexの起動時に "-I utf8" オプションまたは "-U" オプションが必要でしたが、今回の更新によりオプションが不要になります。
================================
% pLaTeX or upLaTeX, UTF-8で記載
\documentclass[autodetect-engine]{jsarticle}
\usepackage{otf}
\ifnum\jis"2121="3000
% upLaTeX
\else
\DeclareUnicodeCharacter{9DD7}{\UTF{9DD7}}% pLaTeXで「鷗」を直接入力
\fi
\usepackage{makeidx}
\makeindex
\begin{document}
森鷗外\index{もりおうがい@森鷗外}
\printindex
\end{document}
================================

副作用として、同音異義語の順序がアスキー社さんのオリジナルのmendex v2.6f と異なる場合が生じます。
その非互換が問題になる場合は、明示的に "-I euc" オプションを指定することで従来通りの動作が得られますので、ご対応をお願いします。
当方の調査(5冊程度ですが…)では、出版されている書籍で副作用の懸念のあるケースに該当する事例は発見できませんでした。

t tk への返信

upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
mendexの内部Unicode化を施したソフトを作成し、名前は upmendex としました。
upTeXのページ で公開しました。ご興味があればお試しください。

  • mendex version 2.6f (TeX Live版)をベース
  • makeindexとほぼ互換、mendexと互換
  • 内部をUnicode化、入出力はUTF-8限定
  • upLaTeX, XeLaTeX, luaLaTeXとともに使えるはず
  • 日本語、英語はもちろん、英語以外のラテン文字、ギリシャ文字、キリル文字に対応。
  • ソートに International Components for Unicode (ICU)を使用


ptexencライブラリーは外しました。入出力にUTF-8以外のエンコーディング(Shift_JIS, EUC-JPなど)は使えません。

mendex -U とほぼ似た動きをしますが、ソーティングの部分をICU利用にごっそりと変更したので、少し違う結果になることもあります。

テストはあまり沢山はできていません。妙な動きをしていたらご指摘いただけると助かります。今後仕様変更もあり得るので、α版としておきます。

テストはVine Linux上で、 /usr/lib の ICU で行っています。Windows上, TeX Liveに入っているICUとの間のテストは出来ていません。

ICUのソート(Collation)は、オプション設定で動きを制御できるらしいですが、まだ利用できていません。

今のところ、日本語、ラテン文字、ギリシャ文字、キリル文字に対応ですが、もう少し拡張したいところです。言語の勉強から要りそうなので、中長期的に構えています。

もう少し安心出来たら、CTAN, TeX Live (2015?)入りを目指したいです。


t tk への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
Windows で make して試して見ました。
samples ディレクトリで
make scripts
の方は,結果も output ディレクトリ内のものと一致しましたが,
make styles
の方は,
This is upmendex version 0.01 (TeX Live 2015/dev).
Scanning input file multi.idx....done (7 entries accepted, 0 rejected).
7 entries accepted, 0 rejected.
Sorting index.

となって,無限ループに陥ったようになります。
ICU のライブラリがまずいのでしょうか?
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
> となって,無限ループに陥ったようになります。

何故か,multi.idx の最後の行
\indexentry{¥¥¥¥¥}{7}
を処理できないようです。
理由は全くわかりません。
これを除くと
make all
が ok になりました。

Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
(続き)

\indexentry{¥}{7}
のように¥一個だけの場合,
\centerline{\bfseries --- Symbols ---}\par\nobreak
  \item ¥\leaders\hbox{$\cdot$}\hfill 7
  \item 0123456789\leaders\hbox{$\cdot$}\hfill 6
のように正しく Symbols としてソートされますが,
二個以上になると,無限ループとなります。
なお,
\indexentry{えんきごうたち@¥¥¥¥¥¥¥¥}{7}
は勿論成功します。
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
角藤様

夜遅くまでありがとうございます。
バグが一箇所見つかったのでpatchを添付します。
今まで動いていたのが不思議な、基本的なミスです。

それを当てなくてもなぜかこちらのLinuxでは動いています。
ICUとは直接の関係はないところです。
ご指摘の無限ループが直るかどうか、あまり確信は持てていませんが
お試しいただけると嬉しいです。

t tk への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
ありがとうございます。このパッチで全て ok と
なりました。
make all
によって出来た全ての *.ind は output/*.ind
と一致しました。
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
upmendex.test
が失敗しましたが,存在しないオプション -U
を消すと成功しました。
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
W32TeX に upmendex.exe を入れておきました。(2015/01/26 にアプロード).
win32版 makeindex-w32.tar.xz
win64版 makeindex-w64.tar.xz (バイナリだけなので,win32版も必要)
texdoc upmendex
で文書を表示します。

ICU ライブラリは基本的に静的にリンクしてありますが,一個だけ DLL
が必要です。その DLL は xetex-w32.tar.xz (64ビット版は xetex-w64.tar.xz)
内にありますから,XeTeX をインストール済ならば既に入っています。
XeTeX をインストールしていない場合には,upmendex.exe を使用するため
にはインストールする必要があります。
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Akira Kakuto の投稿
実際にアプロードするのを忘れていて,今アプロードした
ので,入手可能になるのは一日遅れます。
Akira Kakuto への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- 浮亭 夢介 の投稿
upmendex を使えば以前,角藤先生が作成して
くださった editutf8ind.exe は不要というこ
とですよね.確認させて頂きます.
t tk への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
mendexの内部Unicode化を施したソフト upmendex を更新しver.0.02としました。
uptexのページ で公開しました。

今回の目玉は、韓国語 (ハングル) 対応です。
また、若干のバグ修正をしました。

まだまだα版レベルと思います。また、韓国語は勉強中です。
変な動作や仕様面の不自然なところ等があれば、ご指摘いただけるとありがたいです。
また、改善のご提案などをいただけると助かります。

t tk への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
以下、upmendex 0.02の簡単な説明です。

uplatexのみならず、xelatex, lualatexとの組み合わせでも動作すると思います。

現代ハングルのUnicodeのファイルは、
通常、Hangul Syllables (U+AC00 ~ U+D7AF) (完成形)を使用していると思います。
基本的動作は、よみの部分にU+AC00 ~ U+D7AFを使用し、
"ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎ"
の見出しをつけるものです。

*.idx の中で、
\indexentry{세종대왕}{1}
の基本的な形式はもちろんのこと、
\indexentry{세종대왕@세종대왕(世宗大王)}{1}
のように、
\indexentry{よみ@見出し}{1}
とすることができます。

また、「漢字→かな」の場合と同様に
「漢字→ハングル」の辞書ファイルを作成し
漢字のハングル読みによるソートも可能(のはず)です。(未テスト)

見出しの文字はdefaultでは
"ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅋㅌㅍㅎ"
Hangul Compatibility Jamo (U+3131 ~)
を使用しています。

style fileの中で
tumunja "가나다라마바사아자차카타파하"
tumunja "㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭"
tumunja "㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻"
tumunja "㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍"
tumunja "㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛"
等のいずれかを指定すると、見出しの文字を変更できます。
tumunja "ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅋ"
等と一部を抜くことで、一部の見出しを飛ばすこともできます。
以上のオプション指定で、世の中に出回っている韓国語の本の索引のほとんど全てのケースをカバーできていると思います。

Unicodeのファイルとして、
Hangul Jamo (U+1100 ~ U+11FF) (組合形)を使用した場合、
ICUが対応しているならば、予想通りの動作をすると思います。
しかし、テストしていません。

また、古ハングルについては組合形を使用することになっているようですが、
どんな仕様が適切なのか分からないので、対応外とします。
適切な仕様や実際の使用例などを教えてくださると、
もしかすると対応できるかもしれません。

また、北朝鮮と韓国でソート順が違ったりするそうですが、よく分かりません。
ICUは韓国式でソートしていると思いますし、今回の仕様は韓国式になっていると思います。
こちらについても、適切な仕様や実際の使用例などを教えてくださると、
もしかすると対応できるかもしれません。

ハングルとは別件ですが、
欧文のアクセント付き文字が頭文字に来た場合、
見出しが適切でなくなる場合があるようです。
今後、検討ならびに対応する予定です。
(言語の勉強から要りそうで、時間が掛りそうです。仕様検討などをご協力いただけると助かります。)
また、ICUのソートのオプション指定についても
今後、検討する予定です。

t tk への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- Yamamoto Munehiro "munepi" の投稿
ttkさん、

Mac OS X 10.6 以降対応で upmendex を標準でmakeしたら、link 時に文句を言われました。

Undefined symbols for architecture x86_64:
  "_ucol_open_55", referenced from:
      _wsort in sort.o
  "_ucol_strcoll_55", referenced from:
      _wcomp in sort.o
ld: symbol(s) not found for architecture x86_64

ひとまず、libicui18n.a も手動でリンクして、upmendex を得ました。

このバイナリを用いて、upmendex-0.02-20150517.tar.xzに同梱されていた samples/ において、make するかぎりにおいて、期待した動作をしました。
Yamamoto Munehiro "munepi" への返信

Re: upmendex (Re: MakeIndex, Mendex, XindyとMendexのUnicode化)

- t tk の投稿
munepiさん、ご報告ありがとうございます。
ひとまず動作しているみたいでほっとしております。

libicuのリンクについて、私の手元でも自動で出来ておらず、手動でリンクしています。
configure や Makefile.in などの書き方がまずいのだと思いますが、どうすれば直るのか分かっていません。
お手間をかけさせて申し訳ありません。