どうせ myoujijiten るなら (いっそ MS IME にも)

どうせなら、と。

これは MeCab 辞書だけをターゲットに考えたけれど、IME に対する辞書にも持ってけるよなぁと。

Unix だと今でも wnn、KAKASI、SKK、EGG とかが使われてんのかな、良くわかんないけど。それらのための出力もやろうと思えば出来るけれども、私は今はこれらのユーザではないので、今回のネタは MS IME のみ。

私は死にかけの Windows 7 のIMJP10 の情報しか書けないけど、きっと後続のバージョンでも似たような感じにはなるんじゃないかなと思う。基礎はこれだけ:

  1. IME バー(というのかな?) から「ツール」→「辞書ツール」
  2. 一語一語ちまちま登録するには、メニューから「編集」→「新規登録」
  3. 一覧をテキストとして書き出すには、メニューから「ツール」→「一覧の出力」
  4. 書き出したテキストから登録するには、メニューから「ツール」→「テキストファイルからの登録」

これだけでどんなテキストファイルを作って、それをどうやって投入するかがわかる。

テキストの構造はシンプルで:

 1 !Microsoft IME Dictionary Tool
 2 !Version:
 3 !Format:WORDLIST
 4 !User Dictionary Name: C:\Users\hhsprings\AppData\Roaming\Microsoft\IMJP10\imjp10u.dic
 5 !Output File Name: C:\Users\hhsprings\AppData\Roaming\Microsoft\IMJP10\output2.txt
 6 !DateTime: 2019年10月18日 20:04
 7 
 8 あたし	アタシ	さ変形動名詞
 9 いいだろうか	いいだろうか	名詞
10 いや	イヤ	名詞
11 いんぽーとらいぶらり	インポートライブラリ	さ変形動名詞
12 おもいます	オモイマス	さ変形動名詞
13 こわい	コワイ	さ変形動名詞
14 かんじや	貫地谷	姓	貫地谷かほりとか

いわゆる tsv、つまりタブ区切りで、順に「読み」「変換語」「品詞」「ユーザコメント」。エンコーディングは Microsoft 流儀の「utf-8-sig」(BOM 付きの utf-8)、かな、たぶんそうだろう。

ここまでくればあとは簡単だろう、てことだが、まずは私のスクリプトでの決断をしないといけない。なんせこれ、以前にも ffmpeg ネタで心当たりのあるパターン。「出力以外は全部おんなじ」なわけだから、まさにテンプレートエンジンの呼ばれて飛び出るだろうであろうそうだろう。今回も Mako にしとこーっと。「標準 Python だけで完遂する」ことにこだわる理由は、これの場合は少ないからね。

ひとまず MeCab オンリーなターゲットのまま Mako 化:

核心部のみ抽出
 1 # ...
 2 import mako.template  # require mako
 3 # ...
 4 
 5 def _to_mecab_input(distdir, fn, reader, fromsysdic):
 6     # ...
 7 
 8     for (key1, key2), cont in results.items():
 9             # ...
10 
11             #
12             result.append((s, "姓", r, p, cost,
13                            "(:{}:)".format("|".join(c)), comment))
14         tmpl = mako.template.Template("""\
15 表層形, 品詞細分類3, 読み, 発音, コスト, :衝突品詞:, :IPA辞書でのコスト:
16 % for (sur, clsk3, reading, pronoun, cost, conflict, ipacost) in result:
17 ${sur},${clsk3},${reading},${pronoun},${cost},${conflict},${ipacost}
18 % endfor
19 """)
20         with io.open(ofn, "wb") as fo:
21             fo.write(tmpl.render(result=result).encode("utf-8"))

一撃だね。(実際の変更内容は、ひとまずこれだけの差異をぶち込んだので、Rev3 → Rev4 の変更を参照。)

あとはこの埋め込みテンプレートを指定できるようにすることと、「utf-8-sig」、つまり出力エンコーディング指定を出来るようにすること。あ、あと、「読み」はひらがなにする必要があるのか。これは k2h をテンプレートで使えるようにすればいいね。

MS IME のはいちいちテンプレートを作成させて指定するのもなかなかダルいんで、組み込みとしときたいなぁ。


と、ここまで準備と皮算用してからが少々迷走。全然入らないので困っていた。

まず最初に。「拡張子は是が非でもなにがなんでもいつなんどきでもどんなときもどんなときもまよいつづける….txt」。これに気付かずしばらくうなってた。

次に「utf-8-sig」がダウトだった。辞書ツールに吐かせたヤツ、よくよくみると UCS2 なんだよね、あうーん、どど迷惑。いまどき utf 読めないなんて…。「transfer」だぞ、とらんすふぁれなくてどーする。

で、少なくとも私は Python で ucs を外部コードとして吐き出す術を知らない。内部コードそのものなんだから「バイナリとして書き出しちゃえば済むやん」と C/C++ 脳はうったえるが、それを Python でするのはね…簡単じゃねーわ。

んで、「日本語 Windows なんだからどーせ SJIS 使えろ」と思ったらやっぱりビンゴ。あぁ、もうこれはエントリを捨ててでもそうするかね、と。

というわけで、ここまでの変更が Rev4 → Rev6。(5から6は改行コードの扱い。DOSコードじゃないとダメなのかと思った試行錯誤をそのまま入れてしまったのが Rev5。ただ私は DOS コードが嫌いなので、Unix LF を維持したかったの。)

あとは「任意のおれおれテンプレート」を使えるようにすること、が一つなんだけれど、それよりも前に、実際に MSIME の辞書ツールで投入するのに、ファイル数が多いのが問題なんだよな。ほんとに一個ずつしか渡せないので、かなり鬱陶しい。さらにファイル数減らしたほうが良さそうだ。

この残作業については追記しないので、興味がある方は GIST を追っかけてちょうだい。


03:30追記:
実際に投入するかどうかはよくよく考えたほうがいいよ。私はやってみるまで気付かなかったのだが、MeCab で考える「衝突」よりも遥かに傷が深いんだよね。

つまり MeCab の「合致」は主として「漢字」に対するものだけれど、(「MS」に限らず)IME に対する辞書の場合は読み、つまり「ひらがな」での合致が問題を起こすわけね。今だから大変だよ。ほとんど学習させてない状態なので、日常語で姓に当たる当たる。一つのセンテンス書くだけで何度も変換しなおしを繰り返してる。