Aleksander Machniak
2015-12-03 b6b92c0dddf5247efc12656bbc351aab3cdc31d4
commit | author | age
50ee4c 1 #!/usr/bin/env php
T 2 <?php
3 /*
4  +-----------------------------------------------------------------------+
5  | bin/exportgettext.sh                                                  |
6  |                                                                       |
7  | This file is part of the Roundcube Webmail client                     |
8  | Copyright (C) 2011, The Roundcube Dev Team                            |
070607 9  | Licensed under the GNU General Public License                         |
50ee4c 10  |                                                                       |
T 11  | PURPOSE:                                                              |
12  |   Export PHP-based localization files to PO files for gettext         |
13  +-----------------------------------------------------------------------+
14  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
15  +-----------------------------------------------------------------------+
16 */
17
0ea079 18 define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
50ee4c 19 require INSTALL_PATH.'program/include/clisetup.php';
T 20
21 if ($argc < 2) {
22     die("Usage: " . basename($argv[0]) . " SRCDIR DESTDIR\n");
23 }
24
25 $srcdir = unslashify(realpath($argv[1]));
84ff80 26 $destdir = unslashify($argv[2]);
T 27 $layout = 'launchpad';  # or 'narro';
c7dcb3 28 $langcode_map = array(
15dfdb 29     'hy_AM' => 'hy',
c7dcb3 30     'ar_SA' => 'ar',
T 31     'az_AZ' => 'az',
32     'bg_BG' => 'bg',
33     'bs_BA' => 'bs',
34     'ca_ES' => 'ca',
15dfdb 35     'cs_CZ' => 'cs',
c7dcb3 36     'cy_GB' => 'cy',
T 37     'da_DK' => 'da',
38     'et_EE' => 'et',
39     'el_GR' => 'el',
40     'eu_ES' => 'eu',
a0be7a 41     'fa_IR' => 'fa',
c7dcb3 42     'ga_IE' => 'ga',
15dfdb 43     'ka_GE' => 'ka',
c7dcb3 44     'gl_ES' => 'gl',
T 45     'he_IL' => 'he',
46     'hi_IN' => 'hi',
47     'hr_HR' => 'hr',
48     'ja_JP' => 'ja',
49     'ko_KR' => 'ko',
50     'km_KH' => 'km',
51     'ms_MY' => 'ms',
52     'mr_IN' => 'mr',
949431 53     'ml_IN' => 'ml',
c7dcb3 54     'pl_PL' => 'pl',
T 55     'si_LK' => 'si',
56     'sl_SI' => 'sl',
57     'sq_AL' => 'sq',
58     'sr_CS' => 'sr',
59     'sv_SE' => 'sv',
60     'uk_UA' => 'uk',
61     'vi_VN' => 'vi',
62 );
50ee4c 63
T 64
65 // converting roundcube localization dir
66 if (is_dir($srcdir.'/en_US')) {
67     load_en_US($srcdir.'/en_US');
68     
69     foreach (glob($srcdir.'/*') as $locdir) {
70         if (is_dir($locdir)) {
71             $lang = basename($locdir);
72             //echo "$locdir => $destdir$lang\n";
73             convert_dir($locdir, $destdir . ($layout != 'launchpad' ? $lang : ''));
74         }
75     }
76 }
7d84ff 77 // converting single localization directory
50ee4c 78 else if (is_dir($srcdir)) {
7d84ff 79     if (is_file($srcdir.'/en_US.inc'))  // plugin localization
T 80         load_en_US($srcdir.'/en_US.inc');
81     else
82         load_en_US(realpath($srcdir.'/../en_US'));  // single language
50ee4c 83     convert_dir($srcdir, $destdir);
T 84 }
85 // converting a single file
86 else if (is_file($srcdir)) {
87     //load_en_US();
88     convert_file($srcdir, $destdir);
89 }
90
91
92 /**
93  * Load en_US localization which is used to build msgids
94  */
95 function load_en_US($fn)
96 {
97     $texts = array();
98     
99     if (is_dir($fn)) {
100         foreach (glob($fn.'/*.inc') as $ifn) {
101             include($ifn);
102             $texts = array_merge($texts, (array)$labels, (array)$messages);
103         }
104     }
105     else if (is_file($fn)) {
106         include($fn);
19145d 107         $texts = array_merge($texts, (array)$labels, (array)$messages);
50ee4c 108     }
T 109     
110     $GLOBALS['en_US'] = $texts;
111 }
112
113 /**
114  * Convert all .inc files in the given src directory
115  */
116 function convert_dir($indir, $outdir)
117 {
118     global $layout;
119     
120     if (!is_dir($outdir))  // attempt to create destination dir
121         mkdir($outdir, 0777, true);
122
123     foreach (glob($indir.'/*.inc') as $fn) {
124         $filename = basename($fn);
125
126         // create subdir for each template (launchpad rules)
127         if ($layout == 'launchpad' && preg_match('/^(labels|messages)/', $filename, $m)) {
128             $lang = end(explode('/', $indir));
129             $destdir = $outdir . '/' . $m[1];
130             if (!is_dir($destdir))
131                 mkdir($destdir, 0777, true);
132             $outfn = $destdir . '/' . $lang . '.po';
133         }
134         else {
135             $outfn = $outdir . '/' . preg_replace('/\.[a-z0-9]+$/i', '', basename($fn)) . '.po';
136         }
137
138         convert_file($fn, $outfn);
139     }
140 }
141
142 /**
143  * Convert the given Roundcube localization file into a gettext .po file
144  */
145 function convert_file($fn, $outfn)
146 {
c7dcb3 147     global $layout, $langcode_map;
50ee4c 148
T 149     $basename =  basename($fn);
150     $srcname = str_replace(INSTALL_PATH, '', $fn);
84ff80 151     $product = preg_match('!plugins/(\w+)!', $srcname, $m) ? 'roundcube-plugin-' . $m[1] : 'roundcubemail';
50ee4c 152     $lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
T 153     $labels = $messages = $seen = array();
154
155     if (is_dir($outfn))
156         $outfn .= '/' . $basename . '.po';
157
158     // launchpad requires the template file to have the same name as the directory
159     if (strstr($outfn, '/en_US') && $layout == 'launchpad') {
160         $a = explode('/', $outfn);
161         array_pop($a);
162         $templ = end($a);
163         $a[] = $templ . '.pot';
164         $outfn = join('/', $a);
165         $is_pot = true;
166     }
167     // launchpad is very picky about file names
c7dcb3 168     else if ($layout == 'launchpad' && preg_match($regex = '!/([a-z]{2})_([A-Z]{2})!', $outfn, $m)) {
T 169         if ($shortlang = $langcode_map[$lang])
170             $outfn = preg_replace($regex, '/'.$shortlang, $outfn);
171         else if ($m[1] == strtolower($m[2]))
172             $outfn = preg_replace($regex, '/\1', $outfn);
50ee4c 173     }
T 174
175     include($fn);
c53293 176     $texts = array_merge($labels, $messages);
50ee4c 177     
T 178     // write header
179     $header = <<<EOF
180 # Converted from Roundcube PHP localization files
181 # Copyright (C) 2011 The Roundcube Dev Team
182 # This file is distributed under the same license as the Roundcube package.
183 #
184 #: %s
185 msgid ""
186 msgstr ""
84ff80 187 "Project-Id-Version: %s\\n"
50ee4c 188 "Report-Msgid-Bugs-To: \\n"
7d84ff 189 "%s: %s\\n"
50ee4c 190 "Last-Translator: \\n"
T 191 "Language-Team: Translations <hello@roundcube.net>\\n"
192 "Language: %s\\n"
193 "Content-Type: text/plain; charset=UTF-8\\n"
194 "Content-Transfer-Encoding: 8bit\\n"
195 EOF;
196     
c53293 197     $out = sprintf($header, $srcname, $product, $is_pot ? "POT-Creation-Date" : "PO-Revision-Date", date('c'), $shortlang ? $shortlang : $lang);
50ee4c 198     $out .= "\n";
T 199     
200     $messages = array();
201     foreach ((array)$texts as $label => $msgstr) {
7d84ff 202         $msgid = $is_pot ? $msgstr : ($GLOBALS['en_US'][$label] ?: $label);
50ee4c 203         $messages[$msgid][] = $label;
T 204     }
041c93 205
50ee4c 206     foreach ($messages as $msgid => $labels) {
T 207         $out .= "\n";
208         foreach ($labels as $label)
209             $out .= "#: $srcname:$label\n";
210         $msgstr = $texts[$label];
211         $out .= 'msgid ' . gettext_quote($msgid) . "\n";
212         $out .= 'msgstr ' . gettext_quote(!$is_pot ? $msgstr : '') . "\n";
213     }
214
215     if ($outfn == '-')
216         echo $out;
217     else {
218         echo "$fn\t=>\t$outfn\n";
219         file_put_contents($outfn, $out);
220     }
221 }
222
223 function gettext_quote($str)
224 {
225     $out = "";
070607 226     $lines = explode("\n", wordwrap(stripslashes($str)));
5b5ed4 227     $last = count($lines) - 1;
T 228     foreach ($lines as $i => $line)
229         $out .= '"' . addcslashes($line, '"') . ($i < $last ? ' ' : '') . "\"\n";
50ee4c 230     return rtrim($out);
T 231 }
232
7fe381 233 ?>