#!/usr/bin/env php | +-----------------------------------------------------------------------+ */ define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' ); require INSTALL_PATH.'program/include/clisetup.php'; if ($argc < 2) { die("Usage: " . basename($argv[0]) . " SRCDIR DESTDIR\n"); } $srcdir = unslashify(realpath($argv[1])); $destdir = unslashify($argv[2]); $layout = 'launchpad'; # or 'narro'; $langcode_map = array( 'hy_AM' => 'hy', 'ar_SA' => 'ar', 'az_AZ' => 'az', 'bg_BG' => 'bg', 'bs_BA' => 'bs', 'ca_ES' => 'ca', 'cs_CZ' => 'cs', 'cy_GB' => 'cy', 'da_DK' => 'da', 'et_EE' => 'et', 'el_GR' => 'el', 'eu_ES' => 'eu', 'fa_IR' => 'fa', 'ga_IE' => 'ga', 'ka_GE' => 'ka', 'gl_ES' => 'gl', 'he_IL' => 'he', 'hi_IN' => 'hi', 'hr_HR' => 'hr', 'ja_JP' => 'ja', 'ko_KR' => 'ko', 'km_KH' => 'km', 'ms_MY' => 'ms', 'mr_IN' => 'mr', 'ml_IN' => 'ml', 'pl_PL' => 'pl', 'si_LK' => 'si', 'sl_SI' => 'sl', 'sq_AL' => 'sq', 'sr_CS' => 'sr', 'sv_SE' => 'sv', 'uk_UA' => 'uk', 'vi_VN' => 'vi', ); // converting roundcube localization dir if (is_dir($srcdir.'/en_US')) { load_en_US($srcdir.'/en_US'); foreach (glob($srcdir.'/*') as $locdir) { if (is_dir($locdir)) { $lang = basename($locdir); //echo "$locdir => $destdir$lang\n"; convert_dir($locdir, $destdir . ($layout != 'launchpad' ? $lang : '')); } } } // converting single localization directory else if (is_dir($srcdir)) { if (is_file($srcdir.'/en_US.inc')) // plugin localization load_en_US($srcdir.'/en_US.inc'); else load_en_US(realpath($srcdir.'/../en_US')); // single language convert_dir($srcdir, $destdir); } // converting a single file else if (is_file($srcdir)) { //load_en_US(); convert_file($srcdir, $destdir); } /** * Load en_US localization which is used to build msgids */ function load_en_US($fn) { $texts = array(); if (is_dir($fn)) { foreach (glob($fn.'/*.inc') as $ifn) { include($ifn); $texts = array_merge($texts, (array)$labels, (array)$messages); } } else if (is_file($fn)) { include($fn); $texts = array_merge($texts, (array)$labels, (array)$messages); } $GLOBALS['en_US'] = $texts; } /** * Convert all .inc files in the given src directory */ function convert_dir($indir, $outdir) { global $layout; if (!is_dir($outdir)) // attempt to create destination dir mkdir($outdir, 0777, true); foreach (glob($indir.'/*.inc') as $fn) { $filename = basename($fn); // create subdir for each template (launchpad rules) if ($layout == 'launchpad' && preg_match('/^(labels|messages)/', $filename, $m)) { $lang = end(explode('/', $indir)); $destdir = $outdir . '/' . $m[1]; if (!is_dir($destdir)) mkdir($destdir, 0777, true); $outfn = $destdir . '/' . $lang . '.po'; } else { $outfn = $outdir . '/' . preg_replace('/\.[a-z0-9]+$/i', '', basename($fn)) . '.po'; } convert_file($fn, $outfn); } } /** * Convert the given Roundcube localization file into a gettext .po file */ function convert_file($fn, $outfn) { global $layout, $langcode_map; $basename = basename($fn); $srcname = str_replace(INSTALL_PATH, '', $fn); $product = preg_match('!plugins/(\w+)!', $srcname, $m) ? 'roundcube-plugin-' . $m[1] : 'roundcubemail'; $lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : ''; $labels = $messages = $seen = array(); if (is_dir($outfn)) $outfn .= '/' . $basename . '.po'; // launchpad requires the template file to have the same name as the directory if (strstr($outfn, '/en_US') && $layout == 'launchpad') { $a = explode('/', $outfn); array_pop($a); $templ = end($a); $a[] = $templ . '.pot'; $outfn = join('/', $a); $is_pot = true; } // launchpad is very picky about file names else if ($layout == 'launchpad' && preg_match($regex = '!/([a-z]{2})_([A-Z]{2})!', $outfn, $m)) { if ($shortlang = $langcode_map[$lang]) $outfn = preg_replace($regex, '/'.$shortlang, $outfn); else if ($m[1] == strtolower($m[2])) $outfn = preg_replace($regex, '/\1', $outfn); } include($fn); $texts = array_merge($labels, $messages); // write header $header = <<\\n" "Language: %s\\n" "Content-Type: text/plain; charset=UTF-8\\n" "Content-Transfer-Encoding: 8bit\\n" EOF; $out = sprintf($header, $srcname, $product, $is_pot ? "POT-Creation-Date" : "PO-Revision-Date", date('c'), $shortlang ? $shortlang : $lang); $out .= "\n"; $messages = array(); foreach ((array)$texts as $label => $msgstr) { $msgid = $is_pot ? $msgstr : ($GLOBALS['en_US'][$label] ?: $label); $messages[$msgid][] = $label; } foreach ($messages as $msgid => $labels) { $out .= "\n"; foreach ($labels as $label) $out .= "#: $srcname:$label\n"; $msgstr = $texts[$label]; $out .= 'msgid ' . gettext_quote($msgid) . "\n"; $out .= 'msgstr ' . gettext_quote(!$is_pot ? $msgstr : '') . "\n"; } if ($outfn == '-') echo $out; else { echo "$fn\t=>\t$outfn\n"; file_put_contents($outfn, $out); } } function gettext_quote($str) { $out = ""; $lines = explode("\n", wordwrap(stripslashes($str))); $last = count($lines) - 1; foreach ($lines as $i => $line) $out .= '"' . addcslashes($line, '"') . ($i < $last ? ' ' : '') . "\"\n"; return rtrim($out); } ?>