Hi all,
I did an incredible discovery this morning: the translate-toolkit
package. This package includes a magic tool called "po2txt", which can
be used to convert the related .po files back to an error-detail.txt file.
I am also attaching a new version of the script. This version avoids
duplicate records from po file.
On 06/16/2011 03:45 AM, Amos Jeffries wrote:
On Wed, 15 Jun 2011 16:24:56 -0600, Alex Rousskov wrote:
On 06/15/2011 03:17 PM, Tsantilas Christos wrote:
From what I can understand a translator will use a program like the
poedit to read the above output and produce a new file for a language.
For example the error-details.txt.el.po file.
I thought the translation blobs produced by your script will go into
existing .po files that are already used for translating error pages and
such. In other words, for any supported language, Squid will have a
single .po file that Squid loads and uses for translations. Am I off
track here? Amos?
That was the idea. Yes.
Yes we can always use one po file. We can just add the output of my
script to existing po files. eg:
# mk-error-details-po.pl error-details.txt >> en.po
or even better using the msgcat utility:
# mk-error-details-po.pl error-details.txt > error-details.po
# msgcat en.po error-details.po
- the English "template" version of error-details.txt needs to go in
errors/error-details.txt,
- scripts/update-pot.sh needs to run your convert right after the
per-page dictionaries for-loop. and before the call to msgcat. You can
see from that for-loop where the resulting .po needs to be.
OK I see. All this thinks need to be integrated to Makefile and
update-pot.sh script
That gets it into the system for people to translate.
As for getting it out again....
I think po2text in error/Makefile.am ".po.lang:" target should produce
the translated version of errors/el/error-details.txt or
errors/error-details.el.txt / .txt.el
We can use the po2txt utility like follows:
po2txt -t error-details.txt -i error-details.po >
errors/en/error-details.txt
or if we merged error-details.po file to the general po files:
po2txt -t error-details.txt -i en.po > errors/en/error-details.txt
Looks OK.
Then the question becomes, how do we allow the admin to edit the
results? an /etc/squid/error-details.txt which loads first and overrides
anything we provide?
It follows the same policy with the error pages templates.
If I am not wrong if the user has configured an error_directory will get
the error details from here else from the related "share/errors/en/"
related path.
Amos
#!/usr/bin/perl -w
use warnings;
use strict;
# This script read the error-details.txt error details template, and prints to the
# std output the contents of a possible .po file.
#
# This file consist of records like the following:
#
# name: X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
# detail: "SSL Certficate error: certificate issuer (CA) not known: %ssl_ca_name"
# descr: "Unable to get issuer certificate"
#
# The records separated with an empty line.
# Comments starting with '#' supported.
my $File;
my $mode;
if (! ($File = shift @ARGV) ) {
printf STDERR "Usage: \n ".$0." error-detail-file\n\n";
exit -1;
}
if (!open(IN, "<$File")) {
printf STDERR "Can not open file %s\n", $File;
exit -1;
}
my @PO_RECORDS;
my $lineNumber=0;
while(<IN>) {
my($line) = $_;
$lineNumber=$lineNumber+1;
if ($line =~ /^\#.*/ ) {
# print "Ignore comment: ".$line;
next;
}
elsif ($line =~ /^\s*$/ ) {
# print "Empty line!".$line;
next;
}
my($rec) = "";
my($lineOffset) = 0;
do {
$rec = $rec.$line;
$line = <IN>;
$lineOffset=$lineOffset+1;
} while($line && $line !~ /^\s*$/);
processRecord(\@PO_RECORDS, $rec, $lineNumber);
$lineNumber= $lineNumber + $lineOffset;
}
foreach(@PO_RECORDS) {
my $poRec = $_;
print $poRec->{"comment"};
print "msgid ".$poRec->{"msgid"}."\n";
print "msgstr ".$poRec->{"msgstr"}."\n\n";
}
exit(0);
sub processRecord
{
my($RECS, $rec, $lnumber) = @_;
# print "Rec on $File:$lnumber:\n".$rec."--\n";
# print "#: $File:$lnumber\n";
my(@lines) = split /\n/, $rec;
my($currentField) = "";
my(%currentRec);
my $offset = 0;
foreach (@lines) {
my($l) = $_;
if ($l =~ /^name:(.*)/) {
$currentRec{"name"} = trim($1);
$currentField = "name";
}
elsif ( $l =~ /^detail:(.*)/ ) {
$currentRec{"detail"} = toCstr(trim_quoted($1));
$currentField = "detail";
}
elsif ($l =~ /^descr:(.*)/) {
$currentRec{"descr"} = toCstr(trim_quoted($1));
$currentField = "descr";
}
elsif($l = ~ /^(\s+.*)/ && defined($currentRec{$currentField})) {
my($fmtl) = toCstr($1);
$currentRec{$currentField}= $currentRec{$currentField}."\\n".$fmtl;
}
}
my (%poRecDetail, %poRecDescr);
# print "#: $File+".$currentRec{"name"}.".detail:$lnumber\n";
# print "msgid ".$currentRec{"detail"}."\n";
# print "msgstr ".$currentRec{"detail"}."\n";
# print "\n";
$poRecDetail{"comment"} = "#: $File+".$currentRec{"name"}.".detail:$lnumber\n";
$poRecDetail{"msgid"} = $currentRec{"detail"};
$poRecDetail{"msgstr"} = $currentRec{"detail"};
merge(\@$RECS, \%poRecDetail);
# print "#: $File+".$currentRec{"name"}.".descr:$lnumber\n";
# print "msgid ".$currentRec{"descr"}."\n";
# print "msgstr ".$currentRec{"descr"}."\n";
# print "\n";
$poRecDescr{"comment"} = "#: $File+".$currentRec{"name"}.".descr:$lnumber\n";
$poRecDescr{"msgid"} = $currentRec{"descr"};
$poRecDescr{"msgstr"} = $currentRec{"descr"};
merge(\@$RECS, \%poRecDescr);
}
sub merge {
my ($RECS, $poRec) = @_;
foreach(@$RECS) {
my $item = $_;
# print "Have Rec:".$item->{"msgid"};
if ($poRec->{"msgid"} eq $item->{"msgid"}) {
$item->{"comment"} = $item->{"comment"}.$poRec->{"comment"};
return;
}
}
push @$RECS, $poRec;
return;
}
sub trim
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
sub trim_quoted
{
my $string = shift;
$string =~ s/^\s+"/"/;
$string =~ s/"\s+$/"/;
return $string;
}
sub toCstr
{
my $string = shift;
$string =~ s/\t/\\t/g;
return $string;
}