📄 intltool-merge.in
字号:
$translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; }}sub finalize{}sub unescape_one_sequence{ my ($sequence) = @_; return "\\" if $sequence eq "\\\\"; return "\"" if $sequence eq "\\\""; return "\n" if $sequence eq "\\n"; # gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal), # \xXX (hex) and has a comment saying they want to handle \u and \U. return $sequence;}sub unescape_po_string{ my ($string) = @_; $string =~ s/(\\.)/unescape_one_sequence($1)/eg; return $string;}## NOTE: deal with < - < but not > - > because it seems its ok to have ## > in the entity. For further info please look at #84738.sub entity_decode{ local ($_) = @_; s/'/'/g; # ' s/"/"/g; # " s/&/&/g; s/</</g; return $_;} # entity_encode: (string)## Encode the given string to XML format (encode '<' etc). It also # encodes high bit if not in UTF-8 mode.sub entity_encode{ my ($pre_encoded) = @_; my @list_of_chars = unpack ('C*', $pre_encoded); if ($PASS_THROUGH_ARG) { return join ('', map (&entity_encode_int_even_high_bit, @list_of_chars)); } else { # with UTF-8 we only encode minimalistic return join ('', map (&entity_encode_int_minimalist, @list_of_chars)); }}sub entity_encode_int_minimalist{ return """ if $_ == 34; return "&" if $_ == 38; return "'" if $_ == 39; return "<" if $_ == 60; return chr $_;}sub entity_encode_int_even_high_bit{ if ($_ > 127 || $_ == 34 || $_ == 38 || $_ == 39 || $_ == 60) { # the ($_ > 127) should probably be removed return "&#" . $_ . ";"; } else { return chr $_; }}sub entity_encoded_translation{ my ($lang, $string) = @_; my $translation = $translations{$lang, $string}; return $string if !$translation; return entity_encode ($translation);}## XML (bonobo-activation specific) merge codesub ba_merge_translations{ my $source; { local $/; # slurp mode open INPUT, "<$FILE" or die "can't open $FILE: $!"; $source = <INPUT>; close INPUT; } open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) { print OUTPUT $1; my $node = $2 . "\n"; my @strings = (); $_ = $node; while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { push @strings, entity_decode($3); } print OUTPUT; my %langs; for my $string (@strings) { for my $lang (keys %po_files_by_lang) { $langs{$lang} = 1 if $translations{$lang, $string}; } } for my $lang (sort keys %langs) { $_ = $node; s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; print OUTPUT; } } print OUTPUT $source; close OUTPUT;}## XML (non-bonobo-activation) merge codesub parseTree{ my $fh = shift; my $ref = shift; my $depth = shift || 0; my $language = shift || ""; my $not_cdata = 0; my $has_children; $entered_tag[$depth + 1] = 0; # Check to see if this is not a CDATA element. # foreach my $sub (@{ $ref }) { if (ref $sub eq 'ARRAY') { $not_cdata = 1; } } foreach my $sub (@{ $ref }) { # Handle empty nodes. # if (! $sub) { next; } if (ref $sub eq 'ARRAY') { # Process subnodes # $has_children = 0; # Check to see if current tag has any elements that need to be translated. # if ($translation_depth == -1) { foreach my $subsub (@{ $sub } ) { if (ref $subsub eq 'HASH') { foreach my $e (reverse(keys %{ $subsub })) { if ($e =~ /^_/) { $translation_depth = $depth; } } } elsif (ref $subsub eq 'ARRAY') { $has_children = 1; } } } my $current_tag = pop(@tag_stack); push @tag_stack, $current_tag; @translation_strings = (); $must_end_tag = $depth; print $fh "<", $current_tag; parseTree($fh, $sub, $depth + 1, $language); # Close any open tags # if ($must_end_tag != -1) { if ($must_end_tag < $depth) { print $fh ">"; } else { print $fh " />"; pop(@tag_stack); if ($depth == $translation_depth) { $translation_depth = -1; } } $must_end_tag = -1; } # Add ending tag(s), if needed # if ($entered_tag[$depth + 1] == 1) { while ($last_depth > $depth) { $last_depth--; print $fh "</", pop(@tag_stack), ">"; } } $last_depth = $depth; # If beginning a translation block, then process for each language. # if ($translation_depth == $depth) { my $do_language; # Skip languages that do not have translations. Since we only # do this check when $translation_depth == $depth, it will never # happen for nodes inside a node with a translated element. # for my $lang (sort keys %po_files_by_lang) { if ($has_children == 1) { $do_language = 1; } else { # Skip this language if there is no translation # $do_language = 0; foreach my $string (@translation_strings) { my $decode_string = entity_decode($string); my $translation = $translations{$lang, $decode_string}; if ($translation) { $do_language = 1; last; } } } if ($do_language == 0) { next; } print $fh "\n"; $leading_space =~ s/.*\n//g; print $fh $leading_space; if ($MULTIPLE_OUTPUT && $lang ne "$language") { next; } print $fh "<", $current_tag, " xml:lang=\"", $lang, "\""; $must_end_tag = $depth; parseTree($fh, $sub, $depth + 1, $lang); # Close any open tags # if ($must_end_tag != -1) { if ($must_end_tag < $depth) { print $fh ">"; } else { print $fh " />"; pop(@tag_stack); if ($depth == $translation_depth) { $translation_depth = -1; } } $must_end_tag = -1; } # Add ending tag(s), if needed # if ($entered_tag[$depth + 1] == 1) { while ($last_depth > $depth + 1) { $last_depth--; print $fh "</", pop(@tag_stack), ">"; } print $fh "</", $current_tag, ">"; } } $translation_depth = -1; $last_depth = $depth; } $leading_space = ""; } elsif (ref $sub eq 'HASH') { # Process tag elements # foreach my $e (reverse(keys %{ $sub })) { my $key = $e; my $string = $sub->{$e}; my $quote = '"'; $string =~ s/^[\s]+//; $string =~ s/[\s]+$//; if ($string =~ /^'.*'$/) { $quote = "'"; } $string =~ s/^['"]//g; $string =~ s/['"]$//g; if ($key =~ /^_/) { $key =~ s|^_||g; if ($language) { # Handle translation # my $decode_string = entity_decode($string); my $translation = $translations{$language, $decode_string}; if ($translation) { $translation = entity_encode($translation); $string = $translation; } } } print $fh " $key=$quote$string$quote"; } } else { # Handle tags and CDATA values # Mark parent tag as having been entered. # $entered_tag[$depth] = 1; # The last_depth flag allows us to determine if this tag should be # closed with "/>" or ">" # $last_depth = $depth; # Close any open tags # if ($must_end_tag != -1) { if ($must_end_tag < $depth) { print $fh ">"; } else { print $fh " />"; pop(@tag_stack); } $must_end_tag = -1; } if ($sub =~ /^[\s]*$/) { $leading_space .= $sub; print $fh $sub; } elsif ($not_cdata) { # Handle tags # my $temp_tag = $sub; # Display key # if ($sub =~ /^_/) { $temp_tag =~ s|^_||g; if ($translation_depth == -1) { $translation_depth = $depth; } } # Push the tag on the stack, it will get handled when the ARRAY # for this tag is processed. # push(@tag_stack, $temp_tag); } else { # Handle CDATA # my $string = $sub; $string =~ s/^[\s]+//; $string =~ s/[\s]+$//; push(@translation_strings, $string); # Display CDATA # if ($language) { # Handle translation # my $decode_string = entity_decode($string); my $translation = $translations{$language, $decode_string}; if ($translation) { $translation = entity_encode($translation); $string = $translation; } } print $fh $string; } } }}sub intltool_tree_char{ my $expat = shift; my $text = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; # Use original_string so that we retain escaped entities # in CDATA sections. # if ($pos > 0 and $clist->[$pos - 1] eq '0') { $clist->[$pos] .= $expat->original_string(); } else { push @$clist, 0 => $expat->original_string(); }}sub intltool_tree_start{ my $expat = shift;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -