| LOCALE::PO4A::TRANSTRACTOR.3PM(1) | User Contributed Perl Documentation | LOCALE::PO4A::TRANSTRACTOR.3PM(1) |
Locale::Po4a::TransTractor - 汎用翻訳抽出機構。
po4a (PO for anything) プロジェクトは、gettext ツールが想定していないドキュメントのような領域で翻訳をしやすくすること (またより興味深いのは、翻訳文の保守がしやすくなること) を目標にしています。
このクラスは、翻訳可能な文字列を検索するためのドキュメントのパース、PO ファイルへの抽出、出力したドキュメントへの翻訳した文字列の置換に使用する、すべての po4a パーサの祖先になります。
もっと形式張って言うと、入力として以下の引数を取ります:
以下を出力します:
これを視覚的に表すと次のようになります:
入力ドキュメント-\ /---> 出力ドキュメント
\ / (翻訳済)
+-> parse() 関数 ---------+
/ \
入力 PO --------/ \---> 出力 PO
(抽出済)
この関数は後述の process() 関数から呼ばれますが、new() 関数を使用してドキュメントに内容を手で追加するのを選んだ場合、この関数自体を呼ばねばなりません。
以下の例は、"<p>" で始まる段落のリストをパースします。簡単にするために、ドキュメントは整形されている、すなわち、現れるタグは '<p>' のみで、各段落はこのタグで必ず始まると仮定します。
sub parse {
my $self = shift;
PARAGRAPH: while (1) {
my ($paragraph,$pararef)=("","");
my $first=1;
my ($line,$lref)=$self->shiftline();
while (defined($line)) {
if ($line =~ m/<p>/ && !$first--; ) {
# Not the first time we see <p>.
# Reput the current line in input,
# and put the built paragraph to output
$self->unshiftline($line,$lref);
# Now that the document is formed, translate it:
# - Remove the leading tag
$paragraph =~ s/^<p>//s;
# - (翻訳されていない)先頭のタグと
# (翻訳された)残りの段落を出力に押し込みます
$self->pushline( "<p>"
. $self->translate($paragraph,$pararef)
);
next PARAGRAPH;
} else {
# Append to the paragraph
$paragraph .= $line;
$pararef = $lref unless(length($pararef));
}
# Reinit the loop
($line,$lref)=$self->shiftline();
}
# Did not get a defined line? End of input file.
return;
}
}
parse 関数を実装したら、次節で説明するパブリックインターフェースを用いて document クラスを使用できます。
new() で受け付けるもの以外の引数 (と想定する型):
負値は行を全く折り返さない意味です。
通底するPoファイルは次のオプションも受け付けます。すなわちporefs, copyright-holder, msgid-bugs-address, package-name, package-version, wrap-poです。
この関数は2つの必須の実引数と1つの省略できる実引数を取ります。
*
ディスクから読むファイル名
*
POファイルで参照を構成するときにファイル名として使う名前
*
そのファイルを読むために使う文字集合(既定でUTF-8)
この配列
"@{$self->{TT}{doc_in}}"
にはこの入力文書のデータが別の意味合いを持つ文字列の配列として保管されています。
* 文字列 $textline
には入力テキストデータのそれぞれの行が含まれます。
* 文字列
"$filename:$linenum"
には位置が含まれており「参照」と呼ばれます("linenum"は1始まりです)。
パースは一切行わないことに注意してください。入力ファイルがドキュメントに格納した時点で parse() 関数を使用するべきです。
この翻訳された文書データは以下によって与えられます。
* "$self->docheader()"
はプラグインのヘッダテキストを保有します。また、
* "@{$self->{TT}{doc_out}}"
は配列に翻訳されたメインのテキストのそれぞれの行を保有します。
[po4a ドキュメントの通常の使用...]
($percent,$hit,$queries) = $document->stats();
print "$percent\%($queries中$hit)の文字列の翻訳があります。\n";
この関数は、エラー時に null 以外の数値を返します。
入力を取得し出力を返すために4つの関数が提供されています。これらはPerlのshift/unshiftとpush/popに大変似ています。
* Perlのshiftは最初の配列の要素を返し配列からその要素を切り落とします。 * Perlのunshiftは配列に要素をその配列の最初の要素として前置します。 * Perlのpopは配列の最後の要素を返しそれを配列から切り落とします。 * Perlのpushは配列にその配列の最後の要素として後置します。
1つ目の対は入力についてのもので、2つ目は出力についてのものです。覚え方としては、入力ではshiftにより得られる最初の行に関心があり、出力ではpushがするように結果を末尾に加えたいのだ、とできます。
翻訳するべきテキストを扱う関数を一つ用意しています。
この関数は、いくつか追加引数を取れます。ハッシュとしてまとめなければなりません。例えば:
$self->translate("string","ref","type",
'wrap' => 1);
動作:
コマンドラインで指定した出力文字セットが使われます。指定しない場合は、入力 PO ファイルの文字セットを使用します。入力 PO ファイルにデフォルトの "CHARSET" がある場合は、入力ドキュメントの文字セットを返します。そして、エンコーディングの変換は行われません。
現在の TransTractor の欠点の一つに、(debconf テンプレートや、.desktop ファイルのような) すべての言語を含む翻訳済みドキュメントを扱えないというものがあります。
この問題に対処するには、以下のようにインターフェースのみを変更することが必要です:
$self->pushline_all({ "Description[".$langcode."]=".
$self->translate($line,$ref,$langcode)
});
これで十分だといいのですが ;)
Denis Barbier <barbier@linuxfr.org> Martin Quinson (mquinson#debian.org) Jordi Vilalta <jvprat@gmail.com>
倉澤 望 <nabetaro@debian.or.jp> Debian JP Documentation ML <debian-doc@debian.or.jp>
| 2024-08-06 | perl v5.38.2 |