🚀

po4a 化されていない POD ページの po4a 化

に公開

前回の記事

https://zenn.dev/yasumichi/articles/1f6873bc5cfefa

今回の作業対象

https://github.com/linux-jm/manual/tree/master/pod/sudo

現在、翻訳されているファイルは、以下の通り。

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

参考

再度挑戦

$ 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);}'
GitHubで編集を提案

Discussion