268
280
### For generic translatable XML files ###
270
while ($input =~ /(?:<!--([^>]*?)-->[^\n]*\n?[^\n]*)?\s_$w+\s*=\s*\"([^"]*)\"/sg) { # "
271
$messages{entity_decode_minimal($2)} = [];
272
$comments{entity_decode_minimal($2)} = $1 if (defined($1));
275
while ($input =~ /(?:<!--([^>]*?)-->\s*)?<_($w+)(?: xml:space="($w+)")?[^>]*>(.*?)<\/_\2>/sg) {
277
if (!defined($3) || $3 ne "preserve") {
283
$comments{$_} = $1 if (defined($1));
281
my $tree = readXml($input);
287
my $vartype = ref $var;
289
if ($vartype =~ /ARRAY/) {
292
foreach my $el (@arr) {
297
} elsif ($vartype =~ /HASH/) {
300
foreach my $key (keys %hash) {
302
print_var($hash{$key});
311
# Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment)
312
sub getAttributeString
315
my $do_translate = shift || 1;
316
my $language = shift || "";
317
my $translate = shift;
319
foreach my $e (reverse(sort(keys %{ $sub }))) {
321
my $string = $sub->{$e};
324
$string =~ s/^[\s]+//;
325
$string =~ s/[\s]+$//;
327
if ($string =~ /^'.*'$/)
331
$string =~ s/^['"]//g;
332
$string =~ s/['"]$//g;
334
## differences from intltool-merge.in.in
336
$comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT;
337
$messages{entity_decode($string)} = [];
340
## differences end here from intltool-merge.in.in
341
$result .= " $key=$quote$string$quote";
346
# Verbatim copy from intltool-merge.in.in
350
my $spacepreserve = shift || 0;
351
my @list = @{ $ref };
354
my $count = scalar(@list);
355
my $attrs = $list[0];
358
$spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
359
$spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
361
while ($index < $count) {
362
my $type = $list[$index];
363
my $content = $list[$index+1];
367
# lets strip the whitespace here, and *ONLY* here
368
$content =~ s/\s+/ /gs if (!$spacepreserve);
371
} elsif ( "$type" ne "1" ) {
372
# We've got another element
374
$result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
376
my $subresult = getXMLstring($content, $spacepreserve);
378
$result .= ">".$subresult . "</$type>";
391
# Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed
392
# Translate list of nodes if necessary
393
sub translate_subnodes
397
my $language = shift || "";
398
my $singlelang = shift || 0;
399
my $spacepreserve = shift || 0;
401
my @nodes = @{ $content };
403
my $count = scalar(@nodes);
405
while ($index < $count) {
406
my $type = $nodes[$index];
407
my $rest = $nodes[$index+1];
408
traverse($fh, $type, $rest, $language, $spacepreserve);
413
# Based on traverse() in intltool-merge.in.in
416
my $fh = shift; # unused, to allow us to sync code between -merge and -extract
417
my $nodename = shift;
419
my $language = shift || "";
420
my $spacepreserve = shift || 0;
422
if ($nodename && "$nodename" eq "1") {
423
$XMLCOMMENT = $content;
424
} elsif ($nodename) {
426
my @all = @{ $content };
427
my $attrs = shift @all;
429
my $outattr = getAttributeString($attrs, 1, $language, \$translate);
431
if ($nodename =~ /^_/) {
437
$spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
438
$spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
441
$lookup = getXMLstring($content, $spacepreserve);
442
if (!$spacepreserve) {
443
$lookup =~ s/^\s+//s;
444
$lookup =~ s/\s+$//s;
447
if ($lookup && $translate != 2) {
448
$comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT;
449
$messages{$lookup} = [];
450
} elsif ($translate == 2) {
451
translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
455
my $count = scalar(@all);
458
while ($index < $count) {
459
my $type = $all[$index];
460
my $rest = $all[$index+1];
461
traverse($fh, $type, $rest, $language, $spacepreserve);
471
# Verbatim copy from intltool-merge.in.in, $fh for compatibility
476
my $language = shift || "";
478
my $name = shift @{ $ref };
479
my $cont = shift @{ $ref };
481
while (!$name || "$name" eq "1") {
482
$name = shift @{ $ref };
483
$cont = shift @{ $ref };
486
my $spacepreserve = 0;
487
my $attrs = @{$cont}[0];
488
$spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
490
traverse($fh, $name, $cont, $language, $spacepreserve);
493
# Verbatim copy from intltool-merge.in.in
494
sub intltool_tree_comment
497
my $data = $expat->original_string();
498
my $clist = $expat->{Curlist};
503
push @$clist, 1 => $data;
506
# Verbatim copy from intltool-merge.in.in
507
sub intltool_tree_cdatastart
510
my $clist = $expat->{Curlist};
513
push @$clist, 0 => $expat->original_string();
516
# Verbatim copy from intltool-merge.in.in
517
sub intltool_tree_cdataend
520
my $clist = $expat->{Curlist};
523
$clist->[$pos] .= $expat->original_string();
526
# Verbatim copy from intltool-merge.in.in
527
sub intltool_tree_char
531
my $clist = $expat->{Curlist};
534
# Use original_string so that we retain escaped entities
537
if ($pos > 0 and $clist->[$pos - 1] eq '0') {
538
$clist->[$pos] .= $expat->original_string();
540
push @$clist, 0 => $expat->original_string();
544
# Verbatim copy from intltool-merge.in.in
545
sub intltool_tree_start
551
# Use original_string so that we retain escaped entities
552
# in attribute values. We must convert the string to an
553
# @origlist array to conform to the structure of the Tree
556
my @original_array = split /\x/, $expat->original_string();
557
my $source = $expat->original_string();
559
# Remove leading tag.
561
$source =~ s|^\s*<\s*(\S+)||s;
563
# Grab attribute key/value pairs and push onto @origlist array.
567
if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
569
$source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
571
push @origlist, '"' . $2 . '"';
573
elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
575
$source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
577
push @origlist, "'" . $2 . "'";
585
my $ol = [ { @origlist } ];
587
push @{ $expat->{Lists} }, $expat->{Curlist};
588
push @{ $expat->{Curlist} }, $tag => $ol;
589
$expat->{Curlist} = $ol;
592
# Copied from intltool-merge.in.in and added comment handler.
595
my $xmldoc = shift || return;
596
my $ret = eval 'require XML::Parser';
598
die "You must have XML::Parser installed to run $0\n\n";
600
my $xp = new XML::Parser(Style => 'Tree');
601
$xp->setHandlers(Char => \&intltool_tree_char);
602
$xp->setHandlers(Start => \&intltool_tree_start);
603
$xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
604
$xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
606
## differences from intltool-merge.in.in
607
$xp->setHandlers(Comment => \&intltool_tree_comment);
608
## differences end here from intltool-merge.in.in
610
my $tree = $xp->parse($xmldoc);
613
# <foo><!-- comment --><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
615
# [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar,
616
# [{}, 0, "Howdy", ref, [{}]], 0, "do" ] ]
287
621
sub type_schemas {