source: trunk/third/xml-i18n-tools/xml-i18n-merge.in @ 15545

Revision 15545, 9.2 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15544, which included commits to RCS files with non-trunk default branches.
Line 
1#!@PERL@ -w
2
3#
4#  The XML Translation Merge Tool
5#
6#  Copyright (C) 2000 Free Software Foundation.
7#  Copyright (C) 2000 Eazel, Inc
8#
9#  This library is free software; you can redistribute it and/or
10#  modify it under the terms of the GNU General Public License as
11#  published by the Free Software Foundation; either version 2 of the
12#  License, or (at your option) any later version.
13#
14#  This script is distributed in the hope that it will be useful,
15#  but WITHOUT ANY WARRANTY; without even the implied warranty of
16#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17#  General Public License for more details.
18#
19#  You should have received a copy of the GNU General Public License
20#  along with this library; if not, write to the Free Software
21#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22#
23#  Authors:  Maciej Stachowiak <mjs@eazel.com>
24#            Kenneth Christiansen <kenneth@gnu.org>
25#
26
27
28## Release information
29my $PROGRAM      = "xml-i18n-merge";
30my $PACKAGE      = "@PACKAGE@";
31my $VERSION      = "@VERSION@";
32
33## Script options - Enable by setting value to 1
34my $ENABLE_OAF   = "1";
35
36## Loaded modules
37use strict;
38use File::Basename;
39use Getopt::Long;
40
41## Scalars used by the option stuff
42my $HELP_ARG    = "0";
43my $VERSION_ARG = "0";
44my $OAF_STYLE_ARG = "0";
45my $KEYS_STYLE_ARG = "0";
46my $DESKTOP_STYLE_ARG = "0";
47
48
49## Handle options
50GetOptions (
51            "help|h|?"   => \$HELP_ARG,
52            "version|v"  => \$VERSION_ARG,
53            "oaf-style|o" => \$OAF_STYLE_ARG,
54            "keys-style|k" => \$KEYS_STYLE_ARG,
55            "desktop-style|d" => \$DESKTOP_STYLE_ARG
56            ) or &error;
57
58
59my $PO_DIR;
60my $FILE;
61my $OUTFILE;
62
63my @languages;
64my %po_files_by_lang = ();
65my %translations = ();
66
67&split_on_argument;
68
69
70## Check for options.
71## This section will check for the different options.
72
73sub split_on_argument {
74
75    if ($VERSION_ARG) {
76        &version;
77
78    } elsif ($HELP_ARG) {
79        &help;
80    } elsif ($OAF_STYLE_ARG && @ARGV > 2) {
81        &place_normal;
82        &message;
83        &preparation;
84        &oaf_merge_translations;
85    } elsif ($KEYS_STYLE_ARG && @ARGV > 2) {
86        &place_normal;
87        &message;
88        &preparation;
89        &keys_merge_translations;
90    } elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) {
91        &place_normal;
92        &message;
93        &preparation;
94        &desktop_merge_translations;
95    } else {
96        &help;
97    } 
98}   
99
100
101sub place_normal {
102    $PO_DIR = $ARGV[0];
103    $FILE = $ARGV[1];
104    $OUTFILE = $ARGV[2];
105}   
106
107
108## Sub for printing release information
109sub version{
110    print "${PROGRAM} (${PACKAGE} ${VERSION}\n";
111    print "Written by Maciej Stachowiak and Kenneth Christiansen, 2000.\n\n";
112    print "Copyright (C) 2000 Free Software Foundation, Inc.\n";
113    print "Copyright (C) 2000, 2001 Eazel, Inc.\n";
114    print "This is free software; see the source for copying conditions.  There is NO\n";
115    print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
116    exit;
117}
118
119## Sub for printing usage information
120sub help{
121    print "Usage: xml-i18n-merge [OPTIONS] PO_DIRECTORY FILENAME OUTPUT_FILE\n";
122    print "Generates an xml file that includes translated versions of some attributes,\n";
123    print "from an untranslated source and a po directory that includes translations.\n";
124    print "  -V, --version                shows the version\n";
125    print "  -H, --help                   shows this help page\n";
126    print "  -o, --oaf-style              includes translations in the oaf style\n";
127    print "  -k, --keys-style             includes translations in the keys style\n";
128    print "  -d, --desktop-style          includes translations in the desktop style\n";
129    print "\nReport bugs to <mjs\@eazel.com>.\n";
130    exit;
131}
132
133
134## Sub for printing error messages
135sub error{
136#   print "xml-i18n-merge: invalid option @ARGV\n";
137    print "Try `xml-i18n-merge --help' for more information.\n";
138    exit;
139}
140
141
142sub message {
143    print "Merging translations into $OUTFILE.\n";
144}
145
146
147
148sub preparation {
149   &gather_po_files;
150   &create_translation_database;   
151}
152
153
154
155# General-purpose code for looking up translations in .po files
156
157sub gather_po_files
158{
159    my @po_files = glob("${PO_DIR}/*.po");
160
161    @languages = map (&po_file2lang, @po_files);
162
163    foreach my $lang (@languages) {
164        $po_files_by_lang{$lang} = shift (@po_files);
165    }
166}
167
168sub po_file2lang
169{
170    my $tmp = $_;
171    $tmp =~ s/^.*\/(.*)\.po$/$1/;
172    return $tmp;
173}
174
175
176sub create_translation_database
177{
178    foreach my $lang (@languages) {
179
180        my $po_file = $po_files_by_lang{$lang};
181
182        open PO_FILE, "<$po_file";     
183
184        while (<PO_FILE>) {
185            if (/^#,.*fuzzy/) {
186                $_ = <PO_FILE>; next;
187            }
188            if (/^msgid "(.*)"/ ) {
189                my $msgid = $1;
190                $_ = <PO_FILE>;
191               
192                if (/^msgstr "(.+)"/) {
193                    my $msgstr = $1;
194                    $translations{$lang . "|" . $msgid} = $msgstr;
195                    # print "[$lang]$msgstr\n";
196                }
197            }           
198        }
199    }
200}
201
202sub lookup_translations
203{
204    my ($value) = @_;
205 
206    my %transmap = ();
207
208    foreach my $lang (@languages) {
209        my $translation = lookup_translation ($value, $lang);
210           
211        if ($translation) {
212            $transmap{$lang} = $translation;
213        }
214    }
215
216    return %transmap;
217}
218
219
220sub lookup_translation
221{
222    my ($string, $lang) = @_;
223    $string =~ s/\+/\\+/g;
224 
225    my $salt = "$lang|$string";
226     
227    if ($translations{$salt}) {
228        return $translations{$salt};
229    }
230 
231    return "";
232}
233
234
235sub entity_encode_translations
236{
237    my %transmap = @_;
238
239    foreach my $key (keys %transmap) {
240        $transmap{$key} = entity_encode ($transmap{$key});
241    }
242
243    return %transmap;
244}
245
246
247sub entity_encode
248{
249    my ($pre_encoded) = @_;
250
251    my @list_of_chars = unpack ('C*', $pre_encoded);
252
253    return join ('', map (&entity_encode_int, @list_of_chars));
254}
255
256sub entity_encode_int
257{
258    # FIXME: should probably entity encode more stuff.
259    if ($_ > 127) {
260        return "&#" . $_ . ";";
261    } else {
262        return chr $_;
263    }
264}
265
266
267
268
269
270## OAF-specific merge code
271 
272sub oaf_merge_translations
273{
274    my $oaf_source; {
275       local (*INPUT);
276       local $/; # slurp mode
277       open (INPUT, "<${FILE}") || die "can't open ${FILE}: $!";
278       $oaf_source = <INPUT>;
279    }
280
281    open OUTPUT, ">${OUTFILE}";
282
283    while ($oaf_source =~ /^(.*<oaf_attribute[^<]*_value=\"[^\"]*\"[^<]*>)$/mg)  {
284        my $orig_node = $1;
285       
286        my $non_translated_line = $orig_node;
287        $non_translated_line =~ s/_value=\"/value=\"/;
288           
289        my $new_node="${non_translated_line}\n";
290           
291        my $value_str = $orig_node;
292        $value_str =~ s/.*_value=\"([^\"]*)\".*/$1/sg;
293           
294        if ($value_str) {
295            my %value_translation_map = entity_encode_translations
296                (lookup_translations ($value_str));
297
298            foreach my $key (keys %value_translation_map) {
299                my $translation = $value_translation_map{$key};
300                   
301                my $translated_line = $orig_node;
302                $translated_line =~ s/name=\"([^\"]*)\"/name=\"$1-${key}\"/g;
303                $translated_line =~ s/_value=\"[^\"]*\"/value=\"${translation}\"/g;
304                $new_node="$new_node${translated_line}\n";
305            }
306        }
307
308        $oaf_source =~ s/$orig_node/$new_node/;
309    }           
310
311    print OUTPUT $oaf_source;   
312
313    close OUTPUT;
314    close INPUT;
315}
316
317sub keys_merge_translations
318{       
319    open INPUT, "<${FILE}";
320
321    open OUTPUT, ">${OUTFILE}";
322
323    while (<INPUT>) {
324        chomp;
325        if (/^\s*_.*=.*/)  {
326            my $orig_line = $_;
327   
328            my $non_translated_line = $orig_line;
329            $non_translated_line =~ s/_(.*)=/$1=/;
330           
331            print OUTPUT "${non_translated_line}\n";
332           
333            my $value_str = $orig_line;
334            $value_str =~ s/.*_.*=(.*)/$1/;
335           
336            if ($value_str) {
337                my %value_translation_map = lookup_translations ($value_str);
338           
339                foreach my $key (keys %value_translation_map) {
340                    my $translation = $value_translation_map{$key};
341
342                    my $translated_line = $orig_line; 
343                    $translated_line =~ s/_(.*)=([^\n]*)/\[$key]$1=$translation/;
344                    print OUTPUT "$translated_line\n";
345                }
346            }
347        } else {
348            print OUTPUT "$_\n";
349        }
350    }
351                 
352    close OUTPUT;
353    close INPUT;
354}
355
356sub desktop_merge_translations
357{
358    open INPUT, "<${FILE}";
359
360    open OUTPUT, ">${OUTFILE}";
361
362    while (<INPUT>) {
363        chomp;
364        if (/^\s*_.*=.*/)  {
365            my $orig_line = $_;
366
367            my $non_translated_line = $orig_line;
368            $non_translated_line =~ s/_(.*)=/$1=/;
369
370            print OUTPUT "${non_translated_line}\n";
371
372            my $value_str = $orig_line;
373            $value_str =~ s/.*_.*=(.*)/$1/;
374
375            if ($value_str) {
376                my %value_translation_map = lookup_translations ($value_str);
377
378                foreach my $key (keys %value_translation_map) {
379                    my $translation = $value_translation_map{$key};
380
381                    my $translated_line = $orig_line;
382                    $translated_line =~ s/^_(.*)=([^\n]*)/$1\[$key]=$translation/;
383                    print OUTPUT "$translated_line\n";
384                }
385            }
386        } else {
387            print OUTPUT "$_\n";
388        }
389    }
390
391    close OUTPUT;
392    close INPUT;
393
394}
Note: See TracBrowser for help on using the repository browser.