summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2010-11-02 20:12:14 +0100
committerYorhel <git@yorhel.nl>2010-11-02 20:12:14 +0100
commit73a2ee4403f75e12922486ca1c12b11a74bbeb4d (patch)
treec52466a19a1207cb011dfecfc8b3626ef9e7b494
parentd6cbbc9025ccffae5ec590c692676ac944775eb0 (diff)
Automatically read L10N keys from script.js
This makes jsgen.pl a bit easier to maintain, as there's not one reliable source to get the keys from (namely, the JS code itself). Also cleaned up the l10n() function in jsgen.pl to be more readable. I had expected the new .js file to be smaller because this trick may remove some keys that were previously present but unused. Unfortunately it seems the file only grew a bit larger and compression seems to be less effective now. No idea why this happened. :-(
-rw-r--r--ChangeLog1
-rw-r--r--data/script.js32
-rwxr-xr-xutil/jsgen.pl90
3 files changed, 71 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 3774e5b7..b5033e15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,7 @@
- Removed XML sitemap
- Added image dimensions to screenshot thumbail <img> tags
- Prefix all cookies with a configurable cookie_prefix
+ - Automatically read L10N keys from script.js
- Bugfix: only redirect VN search to VN page if page=1
- Bugfix: remove duplicate votes when merging tags (fixes a 500)
- Bugfix: Multi::Anime: don't crash when anidb returns an invalid or empty year
diff --git a/data/script.js b/data/script.js
index 3e2b479f..e3a1b553 100644
--- a/data/script.js
+++ b/data/script.js
@@ -14,6 +14,25 @@
* tvs -> VN page tag spoilers
* vnr -> VN relation editor
*/
+
+/* Internationalization note:
+ * The translation keys to be inserted in the header of this file are parsed
+ * from the source code. So when using mt(), make sure it is in the following
+ * format:
+ * mt('<exact translation key>',<more arguments>
+ * or
+ * mt('<exact translation key>')
+ * The single quotes and (lack of) spaces are significant!
+ *
+ * To use non-exact translation keys as argument to mt(), make sure to
+ * indicate which keys should be inserted in the header by adding a comment
+ * containing the following format:
+ * l10n /<perl regex>/
+ * any keys matching that regex will be included.
+ *
+ * The "_lang_*" keys for all languages for which we have a translation are
+ * already included automatically.
+ */
var expanded_icon = '▾';
var collapsed_icon = '▸';
@@ -365,14 +384,14 @@ function rlDropDown(lnk) {
var rs = tag('ul', tag('li', tag('b', mt('_vnpage_uopt_relrstat'))));
var vs = tag('ul', tag('li', tag('b', mt('_vnpage_uopt_relvstat'))));
for(var i=0; i<rlst_rstat.length; i++) {
- var val = mt('_rlst_rstat_'+rlst_rstat[i]);
+ var val = mt('_rlst_rstat_'+rlst_rstat[i]); // l10n /_rlst_rstat_\d+/
if(st[0] && st[0].indexOf(val) >= 0)
rs.appendChild(tag('li', tag('i', val)));
else
rs.appendChild(tag('li', tag('a', {href:'#', rl_rid:relid, rl_act:'r'+rlst_rstat[i], onclick:rlMod}, val)));
}
for(var i=0; i<rlst_vstat.length; i++) {
- var val = mt('_rlst_vstat_'+rlst_vstat[i]);
+ var val = mt('_rlst_vstat_'+rlst_vstat[i]); // l10n /_rlst_vstat_\d+/
if(st[1] && st[1].indexOf(val) >= 0)
vs.appendChild(tag('li', tag('i', val)));
else
@@ -1039,7 +1058,7 @@ function scrAdd(id, nsfw, rel) {
var tr = tag('tr', { id:'scr_tr_'+id, scr_id: id, scr_status: id?2:1, scr_rel: rel, scr_nsfw: nsfw},
tag('td', { 'class': 'thumb'}, mt('_js_loading')),
tag('td',
- tag('b', mt(id ? '_vnedit_scr_fetching' : '_vnedit_scr_uploading')),
+ tag('b', id ? mt('_vnedit_scr_fetching') : mt('_vnedit_scr_uploading')),
tag('br', null),
id ? null : mt('_vnedit_scr_upl_msg'),
tag('br', null),
@@ -1188,7 +1207,8 @@ function scrUploadComplete() {
tr.scr_id = -10;
}
if(tr.scr_id < 0) {
- alert(mt(tr.scr_id == -10 ? '_vnedit_scr_oops' : tr.scr_id == -1 ? '_vnedit_scr_errformat' : '_vnedit_scr_errempty'));
+ alert(tr.scr_id == -10 ? mt('_vnedit_scr_oops') :
+ tr.scr_id == -1 ? mt('_vnedit_scr_errformat') : mt('_vnedit_scr_errempty'));
scrDel(tr);
} else {
tr.id = 'scr_tr_'+tr.scr_id;
@@ -1231,7 +1251,7 @@ var tglSpoilers = [];
function tglLoad() {
for(var i=0; i<=3; i++)
- tglSpoilers[i] = mt('_tagv_spoil'+i);
+ tglSpoilers[i] = mt('_tagv_spoil'+i); // l10n /_tagv_spoil\d+/
// tag dropdown search
dsInit(byId('tagmod_tag'), '/xml/tags.xml?q=', function(item, tr) {
@@ -1871,7 +1891,7 @@ if(byId('expandlist')) {
var lnk = byId('expandlist');
setexpand = function() {
var exp = getCookie('histexpand') == 1;
- setText(lnk, mt(exp ? '_js_collapse' : '_js_expand'));
+ setText(lnk, exp ? mt('_js_collapse') : mt('_js_expand'));
var tbl = lnk;
while(tbl.nodeName.toLowerCase() != 'table')
tbl = tbl.parentNode;
diff --git a/util/jsgen.pl b/util/jsgen.pl
index 2235d289..27cbc6da 100755
--- a/util/jsgen.pl
+++ b/util/jsgen.pl
@@ -22,75 +22,73 @@ use LangFile;
use VNDB::L10N;
-my $jskeys_lang = join '|', VNDB::L10N::languages();
-my $jskeys = qr{^(?:
- _lang_(?:$jskeys_lang)|
- _js_.+|
- _menu_emptysearch|
- _vnpage_uopt_(?:10?vote|rel.+)|
- _rlst_[vr]stat_.+|
- _vnedit_rel_(?:isa|of|addbut|del|none|findformat|novn|double)|
- _redit_form_med_.+|
- _vnedit_scr_.+|
- _tagv_(?:add|spoil\d|notfound|nometa|double)|
- _redit_form_vn_(?:addbut|remove|none|vnformat|notfound|double)|
- _redit_form_prod_(?:addbut|remove|none|pformat|notfound|double)|
- _pedit_rel_(?:addbut|del|none|findformat|notfound|double)
- )$}x;
-
sub l10n {
- # Using JSON::XS or something may be shorter and less error prone,
- # although I would have less power over the output (mostly the quoting of the keys)
+ # parse the .js code to find the l10n keys to use
+ my $js = shift;
+ my @keys;
+ push @keys, $1 ? quotemeta($1) : qr/$2/ while($js =~ m{(?:mt\('([a-z0-9_]+)'[,\)]|l10n /([^/]+)/)}g);
+ # also add the _lang_* for all languages for which we have a translation
+ my $jskeys_lang = join '|', VNDB::L10N::languages();
+ push @keys, qr/_lang_(?:$jskeys_lang)/;
+ # fetch the corresponding text from lang.txt
+ my %lang; # key1 => { lang1 => .., lang2 => .. }, key2 => { .. }
my $lang = LangFile->new(read => "$ROOT/data/lang.txt");
- my @r;
- push @r, 'L10N_STR = {';
- my $cur; # undef = none/excluded, 1 = awaiting first TL line, 2 = after first TL line
- my %lang;
+ my $cur; # 0 = none/excluded, 1 = TL lines
+ my $key;
while((my $l = $lang->read())) {
my $type = shift @$l;
if($type eq 'key') {
- my $key = shift @$l;
- push @r, ' }' if $cur;
- $cur = $key =~ $jskeys ? 1 : undef;
- if($cur) {
- $r[$#r] .= ',' if $r[$#r] =~ /}$/;
- # let's assume key names don't trigger a reserved word in JS
- $key = qq{"$key"} if $key !~ /^[a-z_][a-z0-9_]*$/i;
- push @r, qq| $key: {|;
- }
+ my $k = shift @$l;
+ $cur = grep $k =~ /$_/, @keys;
+ $key = $k;
}
- $lang{$l->[0]} = 1 if $type eq 'tl';
if($type eq 'tl' && $cur) {
my($lang, $sync, $val) = @$l;
next if !$val;
+ $lang{$key}{$lang} = $val;
+ }
+ }
+
+ # generate JS code
+ my $r = "L10N_STR = {\n";
+ my $first = 1;
+ for my $key (sort keys %lang) {
+ $r .= ",\n" if !$first;
+ $first = 0;
+ # let's assume all L10N keys are valid JS variable names
+ $r .= sprintf qq| "%s": {\n|, $key;
+ my $firstk = 1;
+ for (sort keys %{$lang{$key}}) {
+ $r .= ",\n" if !$firstk;
+ $firstk = 0;
+ my $lang = $_;
+ $lang = qq{"$lang"} if $lang =~ /^(?:as|do|if|in|is)$/; # reserved two-char words
+ my $val = $lang{$key}{$_};
$val =~ s/"/\\"/g;
$val =~ s/\n/\\n/g;
- $r[$#r] .= ',' if $cur == 2;
- $lang = qq{"$l->[0]"} if $lang =~ /^(?:as|do|if|in|is)$/; # reserved two-char words
- push @r, qq| $lang: "$val"|;
- $cur = 2;
+ $r .= sprintf qq| %s: "%s"|, $lang, $val;
}
+ $r .= "\n }";
}
- push @r, ' }' if $cur;
- push @r, '};';
- push @r, 'L10N_LANG = [ '.join(', ', map qq{"$_"}, VNDB::L10N::languages()).' ];';
- return join "\n", @r;
+ $r .= "\n};\n";
+ $r .= 'L10N_LANG = [ '.join(', ', map qq{"$_"}, VNDB::L10N::languages()).' ];';
+ return "$r\n";
}
sub jsgen {
# JavaScript::Minifier::XS doesn't correctly handle perl's unicode,
# so just do everything in raw bytes instead.
- my $js = encode_utf8(l10n()) . "\n";
- $js .= sprintf "rlst_rstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_rstat}};
- $js .= sprintf "rlst_vstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_vstat}};
- $js .= sprintf "cookie_prefix = '%s';\n", $S{cookie_prefix};
open my $JS, '<', "$ROOT/data/script.js" or die $!;
- $js .= join '', <$JS>;
+ my $js .= join '', <$JS>;
close $JS;
+ my $head = encode_utf8(l10n($js)) . "\n";
+ $head .= sprintf "rlst_rstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_rstat}};
+ $head .= sprintf "rlst_vstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_vstat}};
+ $head .= sprintf "cookie_prefix = '%s';\n", $S{cookie_prefix};
open my $NEWJS, '>', "$ROOT/static/f/script.js" or die $!;
- print $NEWJS $JavaScript::Minifier::XS::VERSION ? JavaScript::Minifier::XS::minify($js) : $js;
+ print $NEWJS $JavaScript::Minifier::XS::VERSION ? JavaScript::Minifier::XS::minify($head.$js) : $head.$js;
close $NEWJS;
}