OmegaTのHTMLファイルフィルターを移行した話

HTMLファイルの翻訳に関して、OmegaTのビルトインフィルターがポンコツな話を旧はてなダイアリー時代にも書いたりしてたんですが*1、ふと思い立ってOkapi Filters Plugin for OmegaTに再チャレンジしたところ、なんとかなったのと、これに付随して以前からやりたいことができたので、自分用にメモっておくお話。

これまでの環境

  • OmegaTにビルトインされているHTMLフィルターを使って訳文を生成(翻訳メモリーもこれで生成しており、GitHubにある全部の翻訳はこれを使い回し)
  • OmegaTの翻訳ファイル生成はなぜかバッチ処理できなかったので、GUIをわざわざ起動して、都度生成
  • PowerShellで翻訳生成文書の前後処理(whatwg.orgからcurlっぽいことをして原HTMLを前処理、うさんくさい後処理もPowerShellで)

OmegaTバッチ処理する

手順が前後するけれども、これはまあ比較的単純で、取扱説明書にあるようにOmegaT コンソールモードで動かせばいいだけの話だったり(単純な話なんだけども、なぜか以前に試したときは動かなかった)。

java -jar OmegaT.jar /path/to/project --mode=console-translate

jarファイルの直後のディレクトリーは、OmegaTのプロジェクトファイルのあるディレクトリーを指定。Windowsであればエクスプローラーでパス名を出せるのでそれをはっつける。My documentみたいにうっかりスペースが含まれている場合は、ダブルクオーテーションでくくるのをお忘れなく。

ちなみに、ディレクトリーの解決の関係で(実際には試してないけれども)、bash on Windows(正確にはWindows Subsystem for Linux)にあるjavaで叩くとコケると思われるので、bashからは

exec cmd.exe /c omegat_run.bat

とでもして、cmd上で走らせている。

フィルターの移行

tmxを移行させる

OmegaTのタグの数え上げがズレる(ビルトインフィルターが0から数え上げるのに対して、Okapiフィルターは1から数え上げる)のと、タグの名前がほぼ全て汎用になる(HTMLのa要素は、ビルトインフィルターでは<a0>になるが、Okapiのフィルターはタグ名がなんであると<g1>のようにgに解決される)。例えば次のように機械的に置換してしまう。

for mark in s a g d e
do
for i in {0..30}
do
    j=$(( $i+1 ))
    sed -i -e 's!\&lt;/${mark}${i}\&gt;!\&lt;/g${j}\&gt;!g' omegat-replaced.tmx
    sed -i -e 's!\&lt;${mark}${i}\&gt;!\&lt;g${j}\&gt;!g' omegat-replaced.tmx
done
done

置換済みのtmxを、OmegaTの翻訳メモリディレクトリー(\tm\auto)に設置すれば、一致した箇所は自動的に食ってくれる(9割方はこの方法で解決できる)。

OmegaTのフィルターをOkapiのフィルターに切り替える設定

グローバルには[設定]→[ファイルフィルター]→[ファイルフィルター]で、ビルトインフィルターのチェックを外してしまえばOkapiのフィルターを使用するようになるが、プロジェクトごとに切り替えることもできる。その場合は、[プロジェクト]→[プロジェクト設定]→[ファイルフィルター]で、[ファイルフィルター設定をプロジェクト専用にする]にチェックを入れた上で、読ませるフィルターを変更すればよい。

Okapiフィルターの要素・属性ルールを変更する(重要)

2019年3月時点では、デフォルトの要素・属性ルールがポンコツ(例えば、mark要素を知らない)なので、Okapi Rainbowを起動して。[Tools]→[Filter configuration...]でHTMLを選択し、[create]でCustom Configurationでokf_html@copy-of-default.fprmを任意のディレクトリーに吐き出させる。吐き出したファイルはテキストエディターで編集可能。

ルールの書き方は、HTML Filter - Okapi Frameworkに記載されているとおり。すでに仕込まれているものを見れば、なんとなくわかる(雑)。

カスタム設定を読ませる

OmegaTのフィルターをOkapiのフィルターに切り替える設定」の画面で、HTML files (Okapi)を選択して、[設定]ボタンを押すと、Okapi Filter Optionsというダイアログが出てくる。"Use the following filter parameters file:"に切り替えて、先ほどの設定ファイルを指定すればよい。ファイルの文法を間違えてプロジェクトが読めなくなってしまったときは、プロジェクトディレクトリーの\omegat\filters.xml中の<filter className="net.sf.okapi.lib.omegat.HTMLFilter" enabled="true">の中にある要素を適当に変えればよい(雑)

HTMLファイルの前処理

Okapiのフィルターのバグ挙動として、

<a href=./>Home</a>

というようなHTML断片を読むと、パースに失敗して出力ファイルがおかしくなる。これを回避するにはあらかじめ

<a href="./">Home</a>

と引用符でくくってしまう。次のようにsedで一括処理してしまう。

grep -l '<a href=./>' ./dev/*.html | xargs sed -i -e 's!<a href=./>!<a href="./">!g'

フィルター間のdiffをとる

精製ファイルを目視で眺めても結構抜けがあったりするけれども、diffでハイライトさせるとよりわかりやすくはなる。
HTML Diff servicePerlスクリプトCVS log for 2009/htmldiff/htmldiff.plから入手できるので、ローカルでperlを叩けばOK。OmegaTビルトインフィルターは原HTMLに関わらず特定の文字列(たとえば>)を実体参照に勝手に置換してしまうようなので、diffを取る前に置換して比較するとよい。

grep -l '&gt;' *.html | xargs sed -i -e 's!&gt;!>!g'

みたいな感じで。

とまあ、ざっくりとこんな感じかなと。
翻訳をはじめた当時は、Windows Subsystem for Linuxがなく、PowerShellという選択肢がベターではあった(のでPowerShellを使っていた)けれども、そんなに真面目にやる気がなく、Linuxにほんのちょっぴり馴染みがあるので、シェルスクリプトで処理できるの個人的には結構楽ですね。