Closed24

【解決】自作DenoモジュールでMS-IMEのユーザー辞書ファイルを生成したいので試行錯誤する

WhyKWhyK

今回、ユーザー辞書ファイル生成モジュール『bId』でMS-IME対応を行ないたいので、その試行錯誤を記録する(だいたいは先人のマネになると思う)
今のところGoogle日本語入力は確実に動作する(ことえりはCSVを吐き出す処理を書いたけど動作確認してない)
https://github.com/rwl-dev/bid

WhyKWhyK

出力ファイルを見る限り、エンコードはUTF-16LEらしい

このときのMS-IME対応の機能要件

  • TSVで出力
  • エンコードをUTF-16LEに変更
WhyKWhyK

encoding.jsを利用して各種エンコーディングに対応
https://github.com/windchime-yk/deno-util/blob/v1.5.0/file.ts#L36-L50

外部から入ってくるUTF-8を、任意のエンコードに変更することができるようになる。

これで解決と思ってUTF-16LEを指定してファイル出力をしたところ、VS Codeでは『バイナリか対応していないエンコードです』なる警告が表示された。IME自体の出力ファイルは問題なく読めたので不穏な気配を察知、MS-IMEで読み込むもファイル形式の違いで全件弾かれる。
その後、改めてMS-IMEの出力ファイルについて調べたところ、BOMが必要ということに気づく。

WhyKWhyK

モジュール側もエンコーディングとBOM追加ができるように変更済み。
https://github.com/rwl-dev/bid/blob/9656a89ec64589ad17e9ca69a8a884949319bfde/mod.ts#L47-L52
https://github.com/rwl-dev/bid/blob/9656a89ec64589ad17e9ca69a8a884949319bfde/mod.ts#L68-L76
UTF-16LEがエンコードだとわかっていたので、エンコードはUTF-16、BOMはLEに指定する。

が、エンコーディング対応のときと同じようにVS Codeで表示されず、全件が弾かれるという結果になる。
おそらくエンコーディングをUTF-16LEにせずにUTF-16にしたからではないかと予測、次の試行錯誤に持ち越し。

WhyKWhyK

ホントにエンコードが想定しているものになっているのか怪しくなってきたので、検出ツールがないか調べる。以下記事がヒット。
https://uxmilk.jp/47131

記事中にnkfというオープンソースツールの紹介があり、これで確認ができるらしいことがわかる。
https://ja.osdn.net/projects/nkf/

WhyKWhyK

OSDNからインストールすると手動で構築する必要があるが、Makefileの知識がなかったため上手くいかなかった。
調べたところ、macOSではHomebrewが、WindowsではScoopの非公式Bucketでインストールできることがわかった

Homebrew(macOS BigSur)

brew install nkf

を実行すればインストールできる。

nkf -V

で動作確認可能。

Scoop(Windows 10 Home)

非公式BucketのURLは以下。
https://github.com/dooteeen/scoop-for-jp

scoop bucket add jp https://github.com/dooteeen/scoop-for-jp

で非公式Bucketと紐づけ、

scoop install nkf

を実行すればインストールされる。
動作確認はHomebrewと同一。

WhyKWhyK

nkfで調べた結果、そもそもバイナリとして出力されていることがわかった。

PS D:\_system\User\Documents\web\dictionary> nkf -g .\dist\msime_development.txt
BINARY
windchime-yk@WhyK dictionary % nkf -g dist/msime_development.txt 
BINARY

指定しなければ変換処理が走らないので、MS-IME対応のところのみ問題が発生しているのは正しい。

PS D:\_system\User\Documents\web\dictionary> nkf -g .\dist\google_development.txt
UTF-8
windchime-yk@WhyK dictionary % nkf -g dist/google_development.txt 
UTF-8

ファイル作成処理がおかしいのかもしれない。

WhyKWhyK

ファイル作成処理の単体試験を確認したが、作成されるファイルはUTF-16LEだった。
その後の処理に問題がある?

WhyKWhyK

単体試験を更新したが、バイナリファイルとして表示される
https://github.com/windchime-yk/deno-util/pull/14/files

windchime-yk@WhyK deno-util % nkf -g test/folders/file4.txt 
UTF-16

ただし、nkfでの判定はUTF-16。

ファイルにUTF-16文字列を入れたためだと思われるので、合わせてreadFileも修正したほうがいいかもしれない。

WhyKWhyK

CI環境としてはUbuntu:latestなので、Ubuntuで出力した際にバイナリに変換された?
DockerでUbuntu仮想環境を構築して確認する。
https://hub.docker.com/_/ubuntu/

よく考えたら前段確認作業でWindowsローカル実機での出力結果がバイナリなので、CI環境は無関係だった。

WhyKWhyK

試しにWindowsでもバイナリになるか試したが、こちらもUTF-16として出力された。

PS D:\_system\User\Documents\web\deno-util> nkf -g .\test\folders\file4.txt
UTF-16

この時点でファイル作成処理側の問題ではなく、利用側つまりbIdの問題であるとわかった。

WhyKWhyK

現状のまとめ

  • deno-utilのファイル作成処理はWindowsやmacOSでも正常に動作している
  • bIdを利用して出力すると、MS-IME用のファイルがバイナリとして出力される
  • ローカル環境でバイナリとして出力が確認されている以上、CIは関係ない

現状の結論

bIdの実装側に問題がある。

WhyKWhyK

MS-IME対応は据え置きになったので一旦クローズするが、時間を置いて調査を再開する。

WhyKWhyK

Node互換性でBufferがあり、これで実装可能ということをゴリラさんに教えていただいた。

import { Buffer } from "node:buffer";
const utf8string = "->😃🧒🏼üčē<-";
const buf = Buffer.from(`\ufeff${utf8string}`, "utf16le");
await Deno.writeFile("utf16le.txt", buf);

手元で試したところ、問題なく動作したので、これで上手いこといかないか試してみる

WhyKWhyK

対応完了。
ゴリラさんに感謝……。

このスクラップは2023/04/24にクローズされました