3 # Quick hack to build a .pot file from an Android strings.xml file
5 # Copyright: Morphoss Ltd <http://www.morphoss.com/>
6 # Author: Andrew McMillan <andrew@mcmillan.net.nz>
7 # License: CC-0, Public Domain, GPL v2, GPL v3, Apache v2 or Simplified BSD.
8 # Other licenses considered on request.
15 use Getopt
::Long
qw(:config permute); # allow mixed args.
18 # Stuff that should not be hard-coded, but is :-)
19 my $resources_dir = "../res";
20 my @extract_filenames = ( "strings", "timezonenames" );
21 my $build_filename = "strings";
22 my $messages_filename = "messages.pot";
29 GetOptions
('debug!' => \
$debug,
31 'extract!' => \
$extractmode,
32 'build!' => \
$buildmode,
34 'help' => \
$helpmeplease );
36 usage
() if ( $helpmeplease || ($extractmode && $buildmode) );
39 $code_dir =~ s{/[^/]*$}{};
43 # Update/extract the strings for the messages.po file
44 extract_po_file
(\
@extract_filenames, $messages_filename);
46 elsif ( $buildmode ) {
47 # From the language po files build the various strings files.
48 build_strings_files
($messages_filename, $build_filename );
56 Provides basic help to the user.
59 print "You must specify either '--extract' or '--build'\n";
65 Extracts the strings from some Android strings.xml into a messages.po file
68 my $filenames = shift;
71 my @xgettext = ( "xgettext", "-L", "PO", "-o", $outfile, "-" );
72 open( XGETTEXT
, "|-", @xgettext );
74 printf( "Extracting to '%s'\n", $outfile ) if ( $debug );
76 for my $filename ( @
$filenames ) {
77 $filename = $resources_dir ."/values/". $filename . ".xml";
78 printf( XGETTEXT
"#SourceFileStart:%s\n", $filename );
79 printf( "Extracting strings from '%s'\n", $filename ) if ( $debug );
80 open( XMLFILE
, "<", $filename );
82 m{<string .*?name="(.*?)".*?>(.*?)</string>} && do {
85 $msgstr =~ s{\\'}{'}g;
86 $msgstr =~ s/"/"/g;
87 printf( XGETTEXT
'msgid "%s"%s', $msgid, "\n" );
88 printf( XGETTEXT
'msgstr "%s"%s', $msgstr, "\n\n" );
90 m{<!--(.*?)-->} && do {
91 printf( XGETTEXT
"#%s\n", $1 );
95 printf( XGETTEXT
"#SourceFileEnd:%s\n\n", $filename );
97 printf( "Extraction completed\n" ) if ( $debug );
104 Finds the translated .po files in a directory and uses them to construct a new strings.xml file
105 for each one by merging the details from the original strings.xml with the translated strings
106 from the la_NG.po file.
108 sub build_strings_files
{
109 my $template_file = shift;
110 my $stringsfile = shift;
112 # Now merge into each translation
113 opendir(my $dh, ".");
114 while( my $fn = readdir($dh) ) {
115 if( $fn =~ m{^([a-z]{2}(_
[A
-Z
]{2})?
)\
.po
$} ) {
117 printf( "Building language: %s\n", $lang );
118 my $strings = get_translated_strings
($fn);
119 merge_into_xml
( $lang, $strings, $stringsfile );
128 sub get_translated_strings
{
129 my $filename = shift;
132 open( TRANSLATED
, "<", $filename );
135 while( <TRANSLATED
> ) {
138 if ( /^\s*msgid \"(.*)"\r?\n?$/ ) {
140 $strings->{$msgid} = "";
142 elsif ( defined($msgid) ) {
143 /^\s*(msgstr )?"(.*)"\r?\n?$/ && do {
144 $strings->{$msgid} .= $2;
151 # foreach my $s ( keys %{$strings} ) {
152 # printf( STDOUT "<string name=\"%s\">%s</string>\n", $s, $strings->{$s} );
164 my $strings_filename = shift;
166 $lang =~ s{_([A-Z]{2})}{-r$1};
167 my $in_filename = sprintf( '%s/values/%s.xml', $resources_dir, $strings_filename);
169 my $outdir = sprintf('%s/values-%s', $resources_dir, $lang);
170 mkdir $outdir unless( -d
$outdir );
171 my $out_filename = sprintf( '%s/%s.xml', $outdir, $strings_filename);
172 open( XMLIN
, "<", $in_filename );
173 open( XMLOUT
, ">", $out_filename );
176 if ( ! m{<!--} && m{<string (.*?)name="(.*?)"(.*?)>(.*?)</string>} ) {
177 my $preamble = (defined($1)?
$1:"");
179 my $postamble = (defined($3)?
$3:"");
181 $msgstr =~ s{\\'}{'}g;
182 next if ( ! defined($strings->{$msgid}) || $msgstr eq $strings->{$msgid} );
183 next if ( $strings->{$msgid} eq "" );
184 $strings->{$msgid} =~ s{"}{"}g;
185 $strings->{$msgid} =~ s{(['\\])}{\\$1}g;
186 printf( XMLOUT
'<string %sname="%s"%s>%s</string>%s',
187 $preamble, $msgid, $postamble, $strings->{$msgid}, "\n" );
190 print XMLOUT
unless( $_ =~ m{^\s*$} );