3 # ABSTRACT: Command line tool for converting a po file into a Gettext.js compatible json dataset
5 # Copyright (C) 2008, Joshua I. Miller E<lt>unrtst@cpan.orgE<gt>, all
8 # This program is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU Library General Public License as published
10 # by the Free Software Foundation; either version 2, or (at your option)
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Library General Public License for more details.
18 # You should have received a copy of the GNU Library General Public
19 # License along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 use File
::Basename
qw(basename);
29 my $gettext_context_glue = "\004";
32 return "$0 {-p} {file.po} > {outputfile.json}
33 -p : do pretty-printing of json data\n";
43 if ($ARGV[0] =~ /^--?p$/) {
50 if ($ARGV[0] =~ /^-h/) {
55 unless (-r
$ARGV[0]) {
56 print "ERROR: Unable to read file [$ARGV[0]]\n";
65 # we'll be building this data struct
68 my $plural_form_count;
70 my $pos = Locale
::PO
->load_file_asarray($src) or die "Can't parse po file [$src].";
73 foreach my $po (@
$pos)
75 my $qmsgid1 = $po->msgid;
76 my $msgid1 = $po->dequote( $qmsgid1 );
79 if (length($msgid1) == 0)
81 my $qmsgstr = $po->msgstr;
82 my $cur = $po->dequote( $qmsgstr );
84 foreach my $h (split(/\n/, $cur))
86 next unless length($h);
87 my @h = split(':', $h, 2);
89 if (length($cur{$h[0]})) {
90 warn "SKIPPING DUPLICATE HEADER LINE: $h\n";
91 } elsif ($h[0] =~ /#-#-#-#-#/) {
92 warn "SKIPPING ERROR MARKER IN HEADER: $h\n";
96 warn "PROBLEM LINE IN HEADER: $h\n";
104 # populate header ref
105 foreach my $key (keys %cur) {
106 $$json{''}{$key} = length($cur{$key}) ?
$cur{$key} : '';
109 # save plural form count
110 if ($$json{''}{'Plural-Forms'}) {
111 my $t = $$json{''}{'Plural-Forms'};
113 if ($t =~ /nplurals=(\d+)/) {
114 $plural_form_count = $1;
116 die "ERROR parsing plural forms header [$t]\n";
119 warn "NO PLURAL FORM HEADER FOUND - DEFAULTING TO 2\n";
121 $plural_form_count = 2;
126 my $qmsgctxt = $po->msgctxt;
127 my $msgctxt = $po->dequote($qmsgctxt) if $qmsgctxt;
129 # build the new msgid key
130 my $msg_ctxt_id = defined($msgctxt) ?
join($gettext_context_glue, ($msgctxt, $msgid1)) : $msgid1;
132 # build translation side
136 my $qmsgid_plural = $po->msgid_plural;
137 my $msgid2 = $po->dequote( $qmsgid_plural ) if $qmsgid_plural;
138 push(@trans, $msgid2);
141 # this shows up different if we're plural
142 if (defined($msgid2) && length($msgid2))
144 my $plurals = $po->msgstr_n;
145 for (my $i=0; $i<$plural_form_count; $i++)
147 my $qstr = ref($plurals) ?
$$plurals{$i} : undef;
148 my $str = $po->dequote( $qstr ) if $qstr;
154 my $qmsgstr = $po->msgstr;
155 my $msgstr = $po->dequote( $qmsgstr ) if $qmsgstr;
156 push(@trans, $msgstr);
159 $$json{$msg_ctxt_id} = \
@trans;
164 my $jsonobj = new JSON
;
165 my $basename = basename
($src);
166 $basename =~ s/\.pot?$//;
169 print $jsonobj->pretty->encode( { $basename => $json });
171 print $jsonobj->encode($json);
181 po2json - Command line tool for converting a po file into a Gettext.js compatible json dataset
189 po2json /path/to/domain.po > domain.json
193 This takes a PO file, as is created from GNU Gettext's xgettext, and converts it into a JSON file.
195 The output is an annonymous associative array. So, if you plan to load this via a <script> tag, more processing will be require (the output from this program must be assigned to a named javascript variable). For example:
197 echo -n "var json_locale_data = " > domain.json
198 po2json /path/to/domain.po >> domain.json
199 echo ";" >> domain.json
203 po2json - Convert a Uniforum format portable object file to javascript object notation.
207 -p : pretty-print the output. Makes the output more human-readable.
211 Locale::PO has a potential bug (I don't know if this actually causes a problem or not). Given a .po file with an entry like:
217 When $po->dump is run on that entry, it will output:
222 The above is removing the first linebreak. I don't know if that is significant. If so, we'll have to rewrite using a different parser (or include our own parser).
236 Copyright (C) 2008, Joshua I. Miller E<lt>unrtst@cpan.orgE<gt>, all rights reserved. See the source code for details.
240 Torsten Raudssus <torsten@raudss.us>
242 =head1 COPYRIGHT AND LICENSE
244 This software is copyright (c) 2012 by DuckDuckGo, Inc. L<http://duckduckgo.com/>, Torsten Raudssus <torsten@raudss.us>.
246 This is free software; you can redistribute it and/or modify it under
247 the same terms as the Perl 5 programming language system itself.