2012-06-02

今週はずっと体調が悪かった。さて、

The pytextseg package provides functions to wrap plain texts: fill and wrap are Unicode-aware alternatives for those of textwrap standard module; fold and unfold are functions mainly focus on plain text messages such as e-mail.

It also provides lower level interfaces for text segmentation: LineBreak class for line breaking; GCStr class for grapheme cluster segmentation.

ということで、今やっていることそのもののモジュールがやはりすでに存在していた。もともと C の行分割ライブラリ(これ自体は数年前からある)を作られていて、その Python バインディングみたい。折り返し用の wrap 関数を同梱するとこまで被ってる(汗)。まあいずれ必要な人は必要になるよね……。Python のモジュールとして見れば API の設計とかで考えの違うところはあるけど。

そんなわけで、textseg という名前は PyPI にすでに登録されていた。ので、unicodeseg という名前にした。0.5.1 です。API も整理してだいぶ変わってきてるけど、そろそろ落ちついてきた。wxPython を使った、GUI のデモも付けたよ。まだ遅いけど、速くするのはまだ我慢している。

それでこのドキュメントを書きながら思ったのは、大事なのは、API リファレンスより Unicode のテキスト境界処理の基本的な概念だよなーということだった。これをリファレンスに入れると量が増えすぎてしまうし、このモジュールの説明だけに限った話でもないので、いまその部分だけ独立させて覚え書きにしようとしているところです。それがここ(「Unicode テキスト境界処理覚え書き」)にあります。まだ書きかけだけど、読んで何かコメントありましたらくださいな。

2012-05-27

今週知ったこと。走ってる Python インタプリタの unicode 内部実装が narrow (16bit UCS-2) か wide (32bit UCS-4) かを知る方法: sys.maxunicode を見る。

ucd.py 0.5.0 を公開。今週できたとこまでの中間報告という感じ。来週もやるよー。

こまごまと進めていったら、sentence break とか分割をカスタマイズ可能にするとか、面倒だと思ってたところができてしまったのでちょっと嬉しい。

そろそろモジュールの名前を変えたい。ucd というのは、Line_Break 属性を返す関数などがあるので最初は unicodedata モジュールに近いものかと思って “Unicode Character Database” からとっていたもの。しかしだんだん方向性が見えてきて、違う名前のほうが相応しいような気がしてきた。いま思ってるのは、これは文字列をいろいろな境界で分割する機能(segmentation)を提供しているものと言えるので、textseguniseg なんてどうかな、と。UAX #29 も “Unicode Text Segmentation” だしね(UAX #14: Unicode Line Breaking Algorithm とかも扱ってるけど)。あと ucd.codepoint とかのサブモジュールは廃止予定。廃止というか、ルート・パッケージでぜんぶ import してしまう。関数名が長くなって取っつきにくい。

2012-05-20

更新情報

こないだぶつぶつ言ってた件、思いきって手を入れたので公開することにしました。Python で Unicode 文字列を分割したりするモジュールです。で、その一部だった codepoint.py は引っ込めた。短い命であった。

というか、これ一回公開してますね。おととしのいまごろ、今とおんなじようなぐだぐだしたテンションで。この時は uniwrap.py がメインで ucd はそれに必要なモジュールという感じで書いてる。

その後このモジュールはあんまり触ってなくて、でも ucd.codepoint の部分はけっこう使い回してて、なんかずるずると依存していたのだった。今回気を取り直してごっそり見直してコードを整理しました。

データベース部分に組み込みの sqlite3 モジュールを使うようにしました。遅くなってるような気がする(前はデータから Python コードを直接生成していた)けど、unicode.org のサイトで公開されてるデータから完全に機械的に流し込んでいるので、この部分で余計な心配をする必要がないのは開発途上の今の段階ではいいかな、と。

UAX #29 で定義されてる、文字(グラフィム・クラスタ)単位と単語単位の分割は完全に実装できてます。ユニット・テストは unicode.org のテスト用データから自動生成してテスト・ケースにしてるので、これはたぶん大丈夫。ものすごく愚直に落とし込んだコードなので、遅いけど、動いてます。速くするのはこれからテスト逸脱しないようにやっていけばいいよね。

で、問題は UAX #14 の行分割のほう。いわゆる禁則処理に相当するんですけどね、前にツイッターでぶつぶつ言ってたような気がするけど、この Technical Report に提供されてるテスト用データ(LineBreakTest.txt)がどうもバグってるらしいのね。前はそれで unicode.org メーリングリストにまで書いて訊いたのだった(そこで言われた)。だから、せっかくここからテスト・ケースを生成してもテスト側が間違ってたりするから必ず失敗する。これの開発にいまいちのめり込めなかったのはこのぐだぐだのテスト・データのせいだっ。

今回これもより愚直で馬鹿正直な(遅い)コードにしたおかげか、それでもテストのほとんどは通るようになっている。5202 件あって失敗は 17 まで減った(ucd/linebreaktest.py をスクリプトとして実行すると ucd/linebreak.py 用のユニット・テストを実行します)。失敗内容を見ると、件のテスト側が間違っているっぽいのがほとんどで、微妙な(どっちが間違っているのか仕様をよく読んで考える必要がある)のが数例という感じ。

uniwrap.py という折り返しスクリプトを(今回も)付けてるので遊んでみてください。あと、このスクリプトは GUI 用の折り返し処理にも使えるクラスを内蔵してまして、それもこの先ブラッシュアップしていきたいんだ。

このモジュールを前提にできると、この先他のテキスト処理のライブラリが作り&公開しやすいのだけどなあ。

2012-05-16

今年のゴールデンウィークはどこに行くともなくて、家や近所で本を読んだりコード書いたりしてた。

私用でいろいろと使っている Python のモジュールを整理して公開したいのだけど、その整理がどうもうまくまとまらない。仮名とか漢字とかを扱うデータベース的なものが多いんだけど、たいてい Unicode 文字列と真面目に取り組まないといけないことになる(とくに JIS X 0213:2004 以降に対応しようとすると)。で、そのために unicode オブジェクトを適切に分割するとか数え上げるとかするようなサブモジュールを作ることになる。とりあえずその部分だけ公開しようとしたのが、codepoint.py です。

でもこれだけだと物足りないこともあるね。たとえば JIS X 0213 では半濁点のついたカ行の仮名や小書きの「プ」などが追加されてるんだけど(主にアイヌ語の表記のためだと思う)、これらは Unicode では単独のコードポイントには割り振られていなくて、「仮名文字、U+309A」という、ふたつのコードポイントの組み合わせで表すことになっている(それでこれまでの JIS では保たれていた Unicode とのコードポイントにおける一対一の対応関係というのが崩れたと非難されたりもした)。こうした文字を含む文字列を列挙 (iterate) するときには、コードポイント単位での分割では不十分である。

Unicode では最小の区分単位であるコードポイントの上位に、「利用者が一文字と認識している区切り」にほぼ等しいものとして、grapheme cluster という区分が定義されている。上記のような文字列はこのグラフィム・クラスタ単位で分割して処理しなければいけないわけです。ほんとは。

で、そういうユーティリティ的なものをどうまとめるかが悩みどころで、本来の目的のモジュールのサブモジュールに入れてしまえば依存関係がなくなるから楽なんだけど、グラフィム・クラスタ云々までやるとけっこうコードが大きくなって、それだけでモジュールにしたほうがよさげになる。じゃあ独立させればとなるんだけど、独立させるとその上の単語区切りとか禁則とかのことも扱うモジュールであることを期待されるような気がして話がでかくなる(本来のモジュールのほうに手が回らなくなりそう)。あーどうしよう、というのをもう数年悩んでる。数年悩んでたら unicodedata モジュールが標準で対応してきてるんじゃないのと思ったけどまだ対応してこない。

でもここに書いてたらちょっとやる気になってきたよ。やるかも。ていうか前にここで出したことあるっけ? まあいいか。ツイッターだと字数制限あるしこういう悩みは書けなかったんだよねー。

2012-02-26

更新、ではないけど……。

Aaron Swartz のファミリー・ネームについて、シュワルツという表記が一般的になりつつあるのに疑問を持っていたので、先日思いきってツイッターで本人に聞いてみたのだけど、そのときのやりとりを「Aaron Swartz のファミリー・ネーム」というリストにまとめました。その後 yomoyomo さんからもコメントもらったり。(名前にまつわる話題が続いたのは偶然。)

紹介されていたビデオを見ると、Swartz というのは向こうの人も発音にとまどう綴りなのかもしれないと思った。アーロンは「いちおう言っとくと僕は発音にはこだわってないからね」みたいなこと言ってたけど、かれは自分の姓を好き勝手に発音されることについてはいちいち抵抗するのにもううんざりしてたのかも。

でもさー、この件では昨年から一貫してなぜか yomoyomo さんの態度がやたら硬いのにちょっとまいった。彼の姓をできるだけ適切な日本語の読みで呼んでやろう、ということにはまったく興味がないみたいなんだもん。けっきょく最後まで先方が気にしてたのは「ワタシが間違ってるか否か」だけだったみたい。ちょっと思ってたのと違ってたな……。アルファブロガー。表記にまつわる軽い話題のつもりだったのに、なんか論争のような印象に思われてしまったのかなー。僕の話の持っていきかたに問題があったのかなー。でもそんなナイーブなこと気にしなきゃならない子供でもないよなー。とか、ぐるぐるしている。だいいち俺は「あなたは間違ってるっ」みたいなことは一言も言ってないぞ。

後味わるい。