po4a 化されていない POD ページの po4a 化
前回の記事
今回の作業対象
現在、翻訳されているファイルは、以下の通り。
POD とは
Perl 関連パッケージで良く用いられる、 POD (Plain Old Documentation) 形式で書かれたページです。
po4a 用ディレクトリの作成
$ cd manual/pod/sudo
$ mkdir -p po4a/{sudo,sudoers,visudo}
既存の翻訳における文字コードの変更
既存の翻訳が、EUC-JP
でエンコードされているようなので UTF-8
に変更した。
原文と既存の翻訳から PO ファイルを作成する
最初の試み
po4a-gettextize で sudo.pod
の ja.po 作成を試みる
$ po4a-gettextize --format pod --master original/sudo.pod --localized draft/sudo.pod --po po4a/sudo/ja.po
po4a-gettextize is only useful to convert previously existing translations to a PO based workflow. Once you successfully converted your project to po4a, you should use the po4a(1) program to maintain it and update your translations.
Attempt to call undefined import method with arguments ("process" ...) via package "Locale::Po4a::TransTractor" (Perhaps you forgot to load the package?) at /home/yasumichi/homebrew/Cellar/po4a/0.73_1/libexec/lib/perl5/Locale/Po4a/Pod.pm line 15.
po4a gettextize: Original has less strings than the translation (96<258). Please fix it by removing the extra entry from the translated file. You may need an addendum (cf po4a(7)) to reput the chunk in place after gettextization. A possible cause is that a text duplicated in the original is not translated the same way each time. Remove one of the translations, and you're fine.
po4a gettextization: Structure disparity between original and translated files:
msgid (at original/sudo.pod:42) is of type '=head1' while
msgstr (at draft/sudo.pod:42 draft/sudo.pod:51) is of type '=begin'.
Original text: NAME
Translated text: JM-copyright
(result so far dumped to gettextization.failed.po)
The gettextization failed (once again). Don't give up, gettextizing is a subtle art, but this is only needed once to convert a project to the gorgeous luxus offered by po4a to translators.
Please refer to the po4a(7) documentation, the section "HOWTO convert a pre-existing translation to po4a?" contains several hints to help you in your task
Original has less strings than the translation (96<258).
とある通り、翻訳側の語数が圧倒的に多いようだ。
msgid (at original/sudo.pod:42) is of type '=head1' while
msgstr (at draft/sudo.pod:42 draft/sudo.pod:51) is of type '=begin'.
最初の方でエラーになっている。どうも翻訳側の以下の部分が追加されているようだ。
=begin JM-copyright
Japanese Version Copyright (c) 2000-2004 Yuichi SATO
all rights reserved.
Translated Sat Oct 7 14:39:18 JST 2000
by Yuichi SATO <ysato444@yahoo.co.jp>
Updated & Modified Fri Dec 6 04:40:44 JST 2002 by Yuichi SATO
Updated & Modified Fri Apr 16 00:05:41 JST 2004 by Yuichi SATO
=end JM-copyright
=begin JM-word
WORD: real uid 実ユーザ ID
WORD: real gid 実グループ ID
WORD: effective uid 実効ユーザ ID
WORD: effective gid 実効グループ ID
WORD: ownership 所有者
WORD: permission アクセス権
WORD: DISCLAIMER 放棄宣言
=end JM-word
追加部分を別ファイルに切り出す
補遺格納用のディレクトリを作成する。
$ mkdir po4a/add_ja
po4a/add_ja/sudo.ja.add
という名前で追加部分を切り出し、以下のヘッダーを追加した。
PO4A-HEADER: mode=before; position=NAME
コメントとして残されている原文の除去
なお、=begin JM-comment
から =end JM-comment
で挟んだブロックに以下のように原文がコメントとして残されているようである。
=begin JM-comment
sudo - execute a command as another user
=end JM-comment
これらを全て除去する。
$ sed -z -i "s/\n=begin JM-comment[^=]*=end JM-comment\n//g" draft/sudo.pod
参考
- sedで複数行にまたがった文字列を置換する方法 | ゲンゾウ用ポストイット
- 【Bash】sedの最短一致 - 地方エンジニアの学習日記
- 【脱sed】いい加減シェルスクリプトで文字列をsedで置換するなんてやめよう #Linux - Qiita ※直接関係はありません
再度挑戦
$ po4a-gettextize --format pod --master original/sudo.pod --localized draft/sudo.pod --po po4a/sudo/ja.po
po4a-gettextize is only useful to convert previously existing translations to a PO based workflow. Once you successfully converted your project to po4a, you should use the po4a(1) program to maintain it and update your translations.
Attempt to call undefined import method with arguments ("process" ...) via package "Locale::Po4a::TransTractor" (Perhaps you forgot to load the package?) at /home/yasumichi/homebrew/Cellar/po4a/0.73_1/libexec/lib/perl5/Locale/Po4a/Pod.pm line 15.
ja.po の作成には成功したようだが、警告が出ている。
Attempt to call undefined import method
を翻訳すると「定義されていないインポートメソッドを呼び出そうとしました」ということらしい。
perl5400delta - perl v5.40.0 での変更点 - perldoc.jp の 不明なパッケージの import メソッドを呼び出すと警告が発生しますで説明されている事象のようである。
問題となっているのは、lib/perl5/Locale/Po4a/Pod.pm
の15行目にある以下の記述である。
use Locale::Po4a::TransTractor qw(process new get_in_charset get_out_charset);
ただ、本家のリポジトリを確認すると既に修正済みの問題の様である。
sudoers.pod
の ja.po 作成
補遺を切り出したのち、po4a-gettextize
を実行した。
$ po4a-gettextize --format pod --master original/sudoers.pod --localized draft/sudoers.pod --po po4a/sudoers/ja.po
po4a-gettextize is only useful to convert previously existing translations to a PO based workflow. Once you successfully converted your project to po4a, you should use the po4a(1) program to maintain it and update your translations.
Attempt to call undefined import method with arguments ("process" ...) via package "Locale::Po4a::TransTractor" (Perhaps you forgot to load the package?) at /home/yasumichi/homebrew/Cellar/po4a/0.73_1/libexec/lib/perl5/Locale/Po4a/Pod.pm line 15.
po4a gettextize: Original has less strings than the translation (300<321). Please fix it by removing the extra entry from the translated file. You may need an addendum (cf po4a(7)) to reput the chunk in place after gettextization. A possible cause is that a text duplicated in the original is not translated the same way each time. Remove one of the translations, and you're fine.
po4a gettextization: Structure disparity between original and translated files:
msgid (at original/sudoers.pod:196) is of type 'textblock' while
msgstr (at draft/sudoers.pod:214 draft/sudoers.pod:222 draft/sudoers.pod:266 draft/sudoers.pod:273 draft/sudoers.pod:821 draft/sudoers.pod:833 draft/sudoers.pod:849 draft/sudoers.pod:861 draft/sudoers.pod:876 draft/sudoers.pod:886 draft/sudoers.pod:1085 draft/sudoers.pod:1090 draft/sudoers.pod:1096 draft/sudoers.pod:1102) is of type '=begin'.
Original text: If a C<Cmnd> has associated command line arguments, then the arguments in the C<Cmnd> must match exactly those given by the user on the command line (or match the wildcards if there are any). Note that the following characters must be escaped with a '\\' if they are used in command arguments: ',', ':', '=', '\\'.
Translated text: JM-comment
(result so far dumped to gettextization.failed.po)
The gettextization failed (once again). Don't give up, gettextizing is a subtle art, but this is only needed once to convert a project to the gorgeous luxus offered by po4a to translators.
Please refer to the po4a(7) documentation, the section "HOWTO convert a pre-existing translation to po4a?" contains several hints to help you in your task
語数が合わないので調査してみるとコメントとして残されている原文の除去で使った正規表現が不十分で以下のように JM-comment
ブロック内に =
が存在するブロックが除去できていなかった。
=begin JM-comment
If a C<Cmnd> has associated command line arguments, then the arguments
in the C<Cmnd> must match exactly those given by the user on the command line
(or match the wildcards if there are any). Note that the following
characters must be escaped with a '\' if they are used in command
arguments: ',', ':', '=', '\'.
=end JM-comment
正規表現:最短一致でマッチさせる表現 | WWWクリエイターズを参考に正規表現を変えてみたが、うまくいかず…。多分、sed では使えない方法なのだろう。
とりあえず、手作業で除去したのち、po4a-gettextize
が成功した。
残りの visudo.pod
は、すんなり ja.po 化に成功した。
fuzzy フラグの除去
各翻訳エントリについている fuzzy
フラグを除去する。
#, fuzzy
POT ファイルの作成
とりあえず、空の POT ファイルを作成する。
$ touch po4a/sudo/sudo.pot
po4a用設定ファイルの作成
[po_directory] po4a/sudo
[type: pod] original/sudo.pod $lang:draft/sudo.pod \
add_$lang:?po4a/add_$lang/add_ja/sudo.ja.add
po4aで翻訳できることを確認する
$ po4a po4a/sudo/po4a.cfg
Makefile の作成
manual/manual/cups/Makefile を流用。
THRESH = 100
EXTFLAGS =
PO4AFLAGS += -k $(THRESH) $(EXTFLAGS)
LANGS = ja
PACKAGE = sudo
PO4A_SUBDIRS = $(wildcard po4a/*)
WORK_DIR = .
all: translate
translate: $(patsubst po4a/%, translate-%, $(PO4A_SUBDIRS))
# This target is to escape "add_*" directory in po4a.
translate-add_%:
@:
translate-%:
po4a $(PO4AFLAGS) -v --variable langs='$(LANGS)' \
--previous --srcdir $(WORK_DIR) --destdir $(WORK_DIR) \
po4a/$*/po4a.cfg
stats: $(patsubst po4a/%, stat-%, $(PO4A_SUBDIRS))
stat-%:
@for l in $(LANGS); do \
echo -n "$*($$l): "; \
msgfmt --statistics -o /dev/null po4a/$*/$$l.po; \
done
page-stat:
@LC_ALL=C po4a $(PO4AFLAGS) --force -v -k 0 --variable langs='$(LANGS)' \
--previous --srcdir $(WORK_DIR) --destdir $(WORK_DIR) $(PO4ACFG) | \
grep translated | \
sed -e 's/(\([1-9][0-9]*\) strings)/(\1 of \1 strings)/' \
-e 's/[()]//g' \
-e 's/^draft\/man[1-9]\///' | \
awk '{printf("%-15s: %7s (%3s/%3s)\n",$$1,$$3,$$5,$$7);}'
Discussion