119
123
elsif ($XML_STYLE_ARG && @ARGV > 2)
129
131
elsif ($KEYS_STYLE_ARG && @ARGV > 2)
134
&keys_merge_translations;
136
&keys_merge_translations;
137
139
elsif ($DESKTOP_STYLE_ARG && @ARGV > 2)
141
&desktop_merge_translations;
144
&desktop_merge_translations;
144
147
elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2)
148
&schemas_merge_translations;
152
&schemas_merge_translations;
151
155
elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2)
155
&rfc822deb_merge_translations;
159
&rfc822deb_merge_translations;
162
elsif ($QUOTED_STYLE_ARG && @ARGV > 2)
167
"ed_merge_translations;
191
203
-k, --keys-style includes translations in the keys style
192
204
-s, --schemas-style includes translations in the schemas style
193
205
-r, --rfc822deb-style includes translations in the RFC822 style
206
--quoted-style includes translations in the quoted string style
194
207
-x, --xml-style includes translations in the standard xml style
197
-u, --utf8 convert all strings to UTF-8 before merging
198
-p, --pass-through use strings as found in .po files, without
199
conversion (STRONGLY unrecommended with -x)
210
-u, --utf8 convert all strings to UTF-8 before merging
211
(default for everything except RFC822 style)
212
-p, --pass-through deprecated, does nothing and issues a warning
200
213
-m, --multiple-output output one localized file per locale, instead of
201
214
a single file containing all localized elements
202
215
-c, --cache=FILE specify cache file name
462
470
return "\\" if $sequence eq "\\\\";
463
471
return "\"" if $sequence eq "\\\"";
464
472
return "\n" if $sequence eq "\\n";
466
# gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal),
467
# \xXX (hex) and has a comment saying they want to handle \u and \U.
473
return "\r" if $sequence eq "\\r";
474
return "\t" if $sequence eq "\\t";
475
return "\b" if $sequence eq "\\b";
476
return "\f" if $sequence eq "\\f";
477
return "\a" if $sequence eq "\\a";
478
return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7)
480
return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/);
481
return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/);
483
# FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489
469
485
return $sequence;
504
519
my @list_of_chars = unpack ('C*', $pre_encoded);
506
if ($PASS_THROUGH_ARG)
508
return join ('', map (&entity_encode_int_even_high_bit, @list_of_chars));
512
# with UTF-8 we only encode minimalistic
513
return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
521
# with UTF-8 we only encode minimalistic
522
return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
517
525
sub entity_encode_int_minimalist
646
645
# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree
647
# doesn't support nesting of translatable tags (i.e. <_blah>this <_doh>doesn't</_doh> work</_blah> -- besides
648
# can you define the correct semantics for this?)
649
my $spacepreserve = shift || 0;
654
650
my @list = @{ $ref };
657
653
my $count = scalar(@list);
658
654
my $attrs = $list[0];
657
$spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
658
$spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
660
660
while ($index < $count) {
661
661
my $type = $list[$index];
662
662
my $content = $list[$index+1];
664
664
# We've got CDATA
666
666
# lets strip the whitespace here, and *ONLY* here
667
$content =~ s/\s+/ /gs;
668
$result .= ($content);
670
#print "no cdata content when expected it\n"; # is this possible, is this ok?
671
# what to do if this happens?
672
# Did I mention that I hate XML::Parser tree style?
667
$content =~ s/\s+/ /gs if (!$spacepreserve);
670
} elsif ( "$type" ne "1" ) {
675
671
# We've got another element
676
672
$result .= "<$type";
677
$result .= getAttributeString($attrs, 0); # no nested translatable elements
673
$result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
679
my $subresult = getXMLstring($content);
675
my $subresult = getXMLstring($content, $spacepreserve);
680
676
if ($subresult) {
681
677
$result .= ">".$subresult . "</$type>";
690
# Translate list of nodes if necessary
691
sub translate_subnodes
695
my $language = shift || "";
696
my $singlelang = shift || 0;
697
my $spacepreserve = shift || 0;
699
my @nodes = @{ $content };
701
my $count = scalar(@nodes);
703
while ($index < $count) {
704
my $type = $nodes[$index];
705
my $rest = $nodes[$index+1];
707
my $oldMO = $MULTIPLE_OUTPUT;
708
$MULTIPLE_OUTPUT = 1;
709
traverse($fh, $type, $rest, $language, $spacepreserve);
710
$MULTIPLE_OUTPUT = $oldMO;
712
traverse($fh, $type, $rest, $language, $spacepreserve);
718
sub isWellFormedXmlFragment
720
my $ret = eval 'require XML::Parser';
722
die "You must have XML::Parser installed to run $0\n\n";
725
my $fragment = shift;
726
return 0 if (!$fragment);
728
$fragment = "<root>$fragment</root>";
729
my $xp = new XML::Parser(Style => 'Tree');
731
eval { $tree = $xp->parse($fragment); };
697
738
my $nodename = shift;
698
739
my $content = shift;
699
740
my $language = shift || "";
741
my $spacepreserve = shift || 0;
701
743
if (!$nodename) {
702
744
if ($content =~ /^[\s]*$/) {
708
750
my @all = @{ $content };
709
751
my $attrs = shift @all;
710
my $outattr = getAttributeString($attrs, 1, $language);
711
752
my $translate = 0;
753
my $outattr = getAttributeString($attrs, 1, $language, \$translate);
713
755
if ($nodename =~ /^_/) {
715
757
$nodename =~ s/^_//;
718
print $fh "<$nodename$outattr";
761
$spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
762
$spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
764
print $fh "<$nodename", $outattr;
719
765
if ($translate) {
720
$lookup = getXMLstring($content);
721
$lookup =~ s/^\s+//s;
722
$lookup =~ s/\s+$//s;
725
my $translation = $translations{$language, $lookup};
726
if ($MULTIPLE_OUTPUT && $translation) {
727
print $fh " xml:lang=\"", $language, "\"";
728
print $fh ">", $translation, "</$nodename>";
766
$lookup = getXMLstring($content, $spacepreserve);
767
if (!$spacepreserve) {
768
$lookup =~ s/^\s+//s;
769
$lookup =~ s/\s+$//s;
772
if ($lookup || $translate == 2) {
773
my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup});
774
if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) {
775
$translation = $lookup if (!$translation);
776
print $fh " xml:lang=\"", $language, "\"" if $language;
778
if ($translate == 2) {
779
translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
781
print $fh $translation;
783
print $fh "</$nodename>";
729
785
return; # this means there will be no same translation with xml:lang="$language"...
730
786
# if we want them both, just remove this "return"
732
print $fh ">$lookup</$nodename>";
789
if ($translate == 2) {
790
translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
794
print $fh "</$nodename>";
739
800
for my $lang (sort keys %po_files_by_lang) {
740
801
if ($MULTIPLE_OUTPUT && $lang ne "$language") {
745
805
# Handle translation
747
my $localattrs = getAttributeString($attrs, 1, $lang);
748
my $decode_string = ($lookup); #entity_decode($lookup);
749
my $translation = $translations{$lang, $decode_string};
751
$translation = ($translation);
808
my $localattrs = getAttributeString($attrs, 1, $lang, \$translate);
809
my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup});
810
if ($translate && !$translation) {
811
$translation = $lookup;
814
if ($translation || $translate) {
753
816
$leading_space =~ s/.*\n//g;
754
817
print $fh $leading_space;
755
print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs;
756
print $fh ">", $translation , "</$nodename>";
818
print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">";
819
if ($translate == 2) {
820
translate_subnodes($fh, \@all, $lang, 1, $spacepreserve);
822
print $fh $translation;
824
print $fh "</$nodename>";
762
830
my $count = scalar(@all);
763
831
if ($count > 0) {
769
while ($index < $count) {
770
my $type = $all[$index];
771
my $rest = $all[$index+1];
772
traverse($fh, $type, $rest, $language);
834
while ($index < $count) {
835
my $type = $all[$index];
836
my $rest = $all[$index+1];
837
traverse($fh, $type, $rest, $language, $spacepreserve);
776
840
print $fh "</$nodename>";
848
sub intltool_tree_comment
852
my $clist = $expat->{Curlist};
855
push @$clist, 1 => $data;
858
sub intltool_tree_cdatastart
861
my $clist = $expat->{Curlist};
864
push @$clist, 0 => $expat->original_string();
867
sub intltool_tree_cdataend
870
my $clist = $expat->{Curlist};
873
$clist->[$pos] .= $expat->original_string();
782
876
sub intltool_tree_char
784
878
my $expat = shift;
1368
sub quoted_translation
1370
my ($lang, $string) = @_;
1372
$string =~ s/\\\"/\"/g;
1374
my $translation = $translations{$lang, $string};
1375
$translation = $string if !$translation;
1377
$translation =~ s/\"/\\\"/g;
1381
sub quoted_merge_translations
1383
if (!$MULTIPLE_OUTPUT) {
1384
print "Quoted only supports Multiple Output.\n";
1388
for my $lang (sort keys %po_files_by_lang) {
1390
mkdir $lang or die "Cannot create subdirectory $lang: $!\n";
1392
open INPUT, "<${FILE}" or die;
1393
open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
1394
binmode (OUTPUT) if $^O eq 'MSWin32';
1397
s/\"(([^\"]|\\\")*[^\\\"])\"/"\"" . "ed_translation($lang, $1) . "\""/ge;