]> git.proxmox.com Git - proxmox-i18n.git/blame - po2js.pl
po2js: cleanup perl code
[proxmox-i18n.git] / po2js.pl
CommitLineData
3f7b1143
DM
1#!/usr/bin/perl
2
3use strict;
4use warnings;
9ce3f62e 5use Getopt::Std;
3f7b1143
DM
6use Locale::PO;
7use JSON;
8use Encode;
9
10# current limits:
11# - we do not support plural. forms
12# - no message content support
13
9ce3f62e
DM
14my $options = {};
15
c1ae7daa 16getopts('t:o:v:', $options) ||
9ce3f62e
DM
17 die "unable to parse options\n";
18
3f7b1143
DM
19die "no files specified\n" if !scalar(@ARGV);
20
3f7b1143
DM
21# like FNV32a, but we only return 31 bits (positive numbers)
22sub fnv31a {
23 my ($string) = @_;
24
25 my $hval = 0x811c9dc5;
df8c4aa4 26 for my $c (unpack('C*', $string)) {
3f7b1143 27 $hval ^= $c;
df8c4aa4 28 $hval += ($hval << 1) + ($hval << 4) + ($hval << 7) + ($hval << 8) + ($hval << 24);
3f7b1143
DM
29 $hval = $hval & 0xffffffff;
30 }
31 return $hval & 0x7fffffff;
32}
33
fe2d4dee 34my $catalog = {};
3f7b1143
DM
35
36foreach my $filename (@ARGV) {
37 my $href = Locale::PO->load_file_ashash($filename) ||
38 die "unable to load '$filename'\n";
df8c4aa4 39
3f7b1143
DM
40 my $charset;
41 my $hpo = $href->{'""'} || die "no header";
42 my $header = $hpo->dequote($hpo->msgstr);
43 if ($header =~ m|^Content-Type:\s+text/plain;\s+charset=(\S+)$|im) {
44 $charset = $1;
45 } else {
46 die "unable to get charset\n" if !$charset;
47 }
48
df8c4aa4 49 for my $k (keys %$href) {
3f7b1143
DM
50 my $po = $href->{$k};
51 next if $po->fuzzy(); # skip fuzzy entries
df8c4aa4 52 my $ref = $po->reference() or next; # skip unused entries
c1ae7daa 53
df8c4aa4 54 # skip entries if "t" is defined (pve/pmg) and the string is
c1ae7daa
DC
55 # not used there or in the widget toolkit
56 next if $options->{t} && $ref !~ m/($options->{t}|proxmox)\-/;
df8c4aa4 57
3f7b1143
DM
58 my $qmsgid = decode($charset, $po->msgid);
59 my $msgid = $po->dequote($qmsgid);
60
61 my $qmsgstr = decode($charset, $po->msgstr);
62 my $msgstr = $po->dequote($qmsgstr);
63
64 next if !length($msgid); # skip header
fe2d4dee 65 next if !length($msgstr); # skip untranslated entries
3f7b1143
DM
66
67 my $digest = fnv31a($msgid);
68
df8c4aa4 69 die "duplicate digest '$digest' (msgid '$msgid')\n" if $catalog->{$digest};
3f7b1143
DM
70
71 $catalog->{$digest} = [ $msgstr ];
72 # later, we can add plural forms to the array
73 }
74}
75
76my $json = to_json($catalog, {canonical => 1, utf8 => 1});
77
c08a2840
TL
78my $version = $options->{v} // ("dev-build " . localtime());
79my $content = "// $version\n"; # write version to the beginning to better avoid stale cache
9ce3f62e
DM
80
81my $outfile = $options->{o};
82
83$content .= "// Proxmox Message Catalog: $outfile\n" if $outfile;
84
85$content .= <<__EOD;
7159a792 86const __proxmox_i18n_msgcat__ = $json;
3f7b1143
DM
87
88function fnv31a(text) {
7159a792
TL
89 let hval = 0x811c9dc5;
90 for (const c of text) {
3f7b1143
DM
91 hval ^= c;
92 hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
93 }
94 hval &= 0x7fffffff;
95 return hval;
96}
97
98function gettext(buf) {
7159a792
TL
99 let digest = fnv31a(buf);
100 return __proxmox_i18n_msgcat__[digest]?.[0] ?? buf;
3f7b1143 101}
3f7b1143
DM
102__EOD
103
9ce3f62e
DM
104if ($outfile) {
105 open(my $fh, '>', $outfile) ||
106 die "unable to open '$outfile' - $!\n";
107 print $fh $content;
108} else {
109 print $content;
110}