summaryrefslogtreecommitdiff
path: root/util/jsgen.pl
blob: e2f8af879e66cdf91fd9924ffddaf2c4418192b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/perl

package VNDB;

use strict;
use warnings;
use Encode 'encode_utf8';
use Cwd 'abs_path';
use JSON::XS;
eval { require JavaScript::Minifier::XS; };

our($ROOT, %S, %O);
BEGIN { ($ROOT = abs_path $0) =~ s{/util/jsgen\.pl$}{}; }
require $ROOT.'/data/global.pl';

use lib "$ROOT/lib";
use LangFile;

# The VNDB::L10N module is not really suited to be used outside the VNDB::*
# framework, but it's the central location that defines which languages we have
# and in what order to display them.
use VNDB::L10N;



my %lang; # lang1 => { key1 => .., key22 => .. }, lang2 => { .. }

sub l10n_load {
  # fetch all text from lang.txt
  my $lang = LangFile->new(read => "$ROOT/data/lang.txt");
  my $key;
  while((my $l = $lang->read())) {
    my $type = shift @$l;
    $key = shift @$l if $type eq 'key';
    $lang{$l->[0]}{$key} = $l->[2] if $type eq 'tl';
  }
}


sub l10n {
  my($lang, $js) = @_;

  # parse the .js code and replace mt()'s that can be modified in-place, otherwise add to the @keys
  my @keys;
  $js =~ s{(?:mt\('([a-z0-9_]+)'([,\)])|l10n /([^/]+)/)}#
    my($k, $s, $q) = ($1, $2, $3);
    my $v = $k ? $lang{$lang}{$k} || $lang{'en'}{$k} : '';
    if($q) { $q ne '<perl regex>' && push @keys, qr/$q/; '' }
    elsif($s eq ')' && $v && $v !~ /[\~\[\]]/) {
      $v =~ s/"/\\"/g;
      $v =~ s/\n/\\n/g;
      qq{"$v"}
    } else {
      push @keys, quotemeta($k);
      "mt('$k'$s"
    }
  #eg;

  my %keys;
  for my $key (sort keys %{$lang{$lang}}) {
    next if !grep $key =~ /$_/, @keys;
    my $val = $lang{$lang}{$key} || $lang{'en'}{$key};
    $val =~ s/"/\\"/g;
    $val =~ s/\n/\\n/g;
    $val =~ s/\[index,.+$// if $key =~ /^_vnlength_/; # special casing the VN lengths, since the JS mt() doesn't handle [index]
    $keys{$key} = $val;
  }
  (\%keys, $js);
}


# screen resolution information, suitable for usage in filFSelect()
sub resolutions {
  my $ln = shift;
  my $cat = '';
  my @r;
  my $push = \@r;
  for my $i (0..$#{$S{resolutions}}) {
    my $r = $S{resolutions}[$i];
    if($cat ne $r->[1]) {
      push @r, [$r->[1] =~ /^_/ ? $lang{$ln}{$r->[1]}||$lang{'en'}{$r->[1]} : $r->[1]];
      $cat = $r->[1];
      $push = $r[$#r];
    }
    my $n = $r->[0] =~ /^_/ ? $lang{$ln}{$r->[0]}||$lang{'en'}{$r->[0]} : $r->[0];
    push @$push, [$i, $n];
  }
  \@r
}


sub vars {
  my($lang, $l10n) = @_;
  my %vars = (
    rlist_status  => $S{rlist_status},
    cookie_prefix => $O{cookie_prefix},
    age_ratings   => $S{age_ratings},
    languages     => $S{languages},
    platforms     => $S{platforms},
    char_roles    => $S{char_roles},
    media         => [sort keys %{$S{media}}],
    release_types => $S{release_types},
    animated      => $S{animated},
    voiced        => $S{voiced},
    vn_lengths    => $S{vn_lengths},
    blood_types   => $S{blood_types},
    genders       => $S{genders},
    char_roles    => $S{char_roles},
    staff_roles   => $S{staff_roles},
    resolutions   => scalar resolutions($lang),
    l10n_lang     => [ map [ $_, $lang{$_}{"_lang_$_"}||$lang{en}{"_lang_$_"} ], VNDB::L10N::languages() ],
    l10n_str      => $l10n,
  );
  JSON::XS->new->encode(\%vars);
}


# Reads main.js and any included files.
sub readjs {
  my $f = shift || 'main.js';
  open my $JS, '<:utf8', "$ROOT/data/js/$f" or die $!;
  local $/ = undef;
  local $_ = <$JS>;
  close $JS;
  s{^//include (.+)$}{'(function(){'.readjs($1).'})();'}meg;
  $_;
}


sub jsgen {
  my $js = readjs 'main.js';

  for my $l (VNDB::L10N::languages()) {
    my($l10n, $body) = l10n($l, $js);
    $body =~ s{/\*VARS\*/}{vars($l, $l10n)}eg;

    # JavaScript::Minifier::XS doesn't correctly handle perl's unicode, so manually encode
    my $content = encode_utf8($body);
    open my $NEWJS, '>', "$ROOT/static/f/js/$l.js" or die $!;
    print $NEWJS $JavaScript::Minifier::XS::VERSION ? JavaScript::Minifier::XS::minify($content) : $content;
    close $NEWJS;
  }
}

l10n_load;
jsgen;