From 93610918995c6249862df350270f99bc4bdd18e9 Mon Sep 17 00:00:00 2001 From: Aleksa Vujicic Date: Tue, 31 Jan 2012 11:06:53 +1300 Subject: [PATCH] Bug 7327: Translate scripts now handle javascript vars inside strings --- misc/translator/TmplTokenizer.pm | 3 ++ misc/translator/tmpl_process3.pl | 57 ++++++++++++++++++++++++++++++++++---- misc/translator/xgettext.pl | 36 ++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 6 deletions(-) diff --git a/misc/translator/TmplTokenizer.pm b/misc/translator/TmplTokenizer.pm index 6129f8d..35a21b7 100644 --- a/misc/translator/TmplTokenizer.pm +++ b/misc/translator/TmplTokenizer.pm @@ -153,6 +153,9 @@ sub _split_js ($) { } elsif ($s0 =~ /^\/\*(?:(?!\*\/).)*\*\//s) { # C-style comment push @it, $&; $s0 = $'; + } elsif ($s0 =~ /^(?:(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*')|(?:[A-Za-z_][A-Za-z0-9_]*))(?:\s*\+\s*(?:(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*')|[A-Za-z_][A-Za-z0-9_]*))+/isg) { # Variable in string + $s0 = $'; + push @it, "''+".$&."+''"; # This is so that the very first and last quotes are the same # Keyword or identifier, ECMA-262 p.13 (section 7.5) } elsif ($s0 =~ /^[A-Z_\$][A-Z\d_\$]*/is) { # IdentifierName push @it, $&; diff --git a/misc/translator/tmpl_process3.pl b/misc/translator/tmpl_process3.pl index cb69117..a322da8 100755 --- a/misc/translator/tmpl_process3.pl +++ b/misc/translator/tmpl_process3.pl @@ -116,12 +116,57 @@ sub text_replace (**) { } elsif ($s->has_js_data) { for my $t (@{$s->js_data}) { # FIXME for this whole block - if ($t->[0]) { - printf $output "%s%s%s", $t->[2], find_translation $t->[3], - $t->[2]; - } else { - print $output $t->[1]; - } + if ($t->[0]) { + my $to_print; + if ($t->[1] =~ /^(?:(?")(?(?:\\"|[^"])*)"|(?')(?(?:\\'|[^'])*)')(?(?:\s*\+\s*(?:(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*')|[A-Za-z_][A-Za-z0-9_]*))+)$/ig) { + my @vars; + my $quote = $+{startquote}; + my $to_parse = $+{startquote}.$+{rest}; + my $to_translate = $+{startstring}; + while (1) { # Loop through and substitute all vars with '%s' + if ($to_parse =~ /^$quote((?:\s*\+\s*[A-Za-z_][0-9A-Za-z_]*)\s*\+\s*)(?['"])/isg) { # 1 var + push @vars, "'".$1."'"; + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + $to_translate .= '%s'; + } elsif ($to_parse =~ /^$quote((?:\s*\+\s*[A-Za-z_][0-9A-Za-z_]*){2,})\s*\+\s*(?['"])/isg) { # 2+ vars + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + my @current_vars = split(/\s*\+\s*/,$1); + shift(@current_vars); + foreach my $var (@current_vars) { + $var = "'+".$var."+'"; + $to_translate .= '%s'; + } + push @vars, @current_vars; + } elsif ($to_parse =~ /^$quote\s*\+\s*(?['"])/is) { # plus between two strings + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + } elsif ($quote eq "'" && $to_parse =~ /^'(?(?:\\'|[^'])*?)'/is) { # 'string' + $to_parse = $quote.$'; + $to_translate .= $+{text}; + $to_translate =~ s/\\'/'/ig; + } elsif ($quote eq "\"" && $to_parse =~ /^"(?(?:\\"|[^"])*?)"/is) { # "string" + $to_parse = $quote.$'; + $to_translate .= $+{text}; + $to_translate =~ s/\\"/"/ig; + } else { + last; + } + } + $to_print = find_translation($to_translate); + $to_print =~ s/'/\\'/ig; + foreach my $substitute (@vars) { # Substitute all '%s' with vars + $to_print =~ s/\%s/$substitute/i; + } + $t->[2] = "'"; + } else { + $to_print = find_translation($t->[3]); + } + printf $output "%s%s%s", $t->[2], $to_print, $t->[2]; + } else { + print $output $t->[1]; + } } } elsif (defined $t) { # Quick fix to bug 4472 diff --git a/misc/translator/xgettext.pl b/misc/translator/xgettext.pl index 21e3fc5..53aa3d2 100755 --- a/misc/translator/xgettext.pl +++ b/misc/translator/xgettext.pl @@ -212,6 +212,42 @@ EOF } elsif ($text{$t}->[0]->has_js_data) { printf OUTPUT "#. For the first occurrence,\n" if @{$text{$t}} > 1; printf OUTPUT "#. SCRIPT\n"; + for my $jsdata (@{$text{$t}->[0]->js_data}) { + if ($jsdata->[0]) { + if ($jsdata->[1] =~ /^(?:(?")(?(?:\\"|[^"])*)"|(?')(?(?:\\'|[^'])*)')(?(?:\s*\+\s*(?:(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*')|[A-Za-z_][A-Za-z0-9_]*))+)$/ig) { + my $quote = $+{startquote}; + my $to_parse = $+{startquote}.$+{rest}; + my $to_store = $+{startstring}; + while (1) { # Loop through and substitute all vars with '%s' + if ($to_parse =~ /^$quote((?:\s*\+\s*[A-Za-z_][0-9A-Za-z_]*)\s*\+\s*)(?['"])/isg) { # 1 var + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + $to_store .= '%s'; + } elsif ($to_parse =~ /^$quote((?:\s*\+\s*[A-Za-z_][0-9A-Za-z_]*){2,})\s*\+\s*(?['"])/isg) { # 2+ vars + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + my @current_vars = split(/\s*\+\s*/,$1); + shift(@current_vars); + $to_store .= '%s' foreach (@current_vars); + } elsif ($to_parse =~ /^$quote\s*\+\s*(?['"])/is) { # plus between two strings + $quote = $+{nextquotes}; + $to_parse = $quote.$'; + } elsif ($quote eq "'" && $to_parse =~ /^'(?(?:\\'|[^'])*?)'/is) { # 'string' + $to_parse = $quote.$'; + $to_store .= $+{text}; + $to_store =~ s/\\'/'/ig; + } elsif ($quote eq "\"" && $to_parse =~ /^"(?(?:\\"|[^"])*?)"/is) { # "string" + $to_parse = $quote.$'; + $to_store .= $+{text}; + $to_store =~ s/\\"/"/ig; + } else { + last; + } + } + $t = $to_store; + } + } + } } my $cformat_p; for my $token (@{$text{$t}}) { -- 1.7.5.4