aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfilip <filip.komar@gmail.com>2015-08-25 23:11:12 +0200
committerfilip <filip.komar@gmail.com>2015-08-25 23:11:12 +0200
commitad791614f4a8f6fc83f9868bc1a9105b6795104d (patch)
tree0b77e75eca3bda84b682a60effcc707e98c28d25
parent2ab1825eadc15c26d0cd684e83709a980b9c415b (diff)
downloadnav-ad791614f4a8f6fc83f9868bc1a9105b6795104d.tar
nav-ad791614f4a8f6fc83f9868bc1a9105b6795104d.tar.gz
nav-ad791614f4a8f6fc83f9868bc1a9105b6795104d.tar.bz2
nav-ad791614f4a8f6fc83f9868bc1a9105b6795104d.tar.xz
nav-ad791614f4a8f6fc83f9868bc1a9105b6795104d.zip
bugfix for mga#14899 (proper handling of gettext files)
details in bug report
-rw-r--r--php-mo.php159
1 files changed, 112 insertions, 47 deletions
diff --git a/php-mo.php b/php-mo.php
index 470ce80..6f635c2 100644
--- a/php-mo.php
+++ b/php-mo.php
@@ -1,29 +1,68 @@
<?php
/**
- * based on php.mo 0.1 by Joss Crowcroft (http://www.josscrowcroft.com)
- * added case for commented unused string
- * fixed "fuzzy flag first line" bug which didn't saved previous proper string at all
- * removed unedeed phpmo_convert and phpmo_write_mo_file
- *
- * Converts gettext translation '.po' files to binary '.mo' files in PHP.
- *
- * Usage:
- * <?php require('php-mo.php'); phpmo_convert( 'input.po', [ 'output.mo' ] ); ?>
- *
- * NB:
- * - If no $output_file specified, output filename is same as $input_file (but .mo)
- * - Returns true/false for success/failure
- * - No warranty, but if it breaks, please let me know
- *
- * More info:
- * https://github.com/josscrowcroft/php.mo
- *
- * Based on php-msgfmt by Matthias Bauer (Copyright © 2007), a command-line PHP tool
- * for converting .po files to .mo.
- * (http://wordpress-soc-2007.googlecode.com/svn/trunk/moeffju/php-msgfmt/msgfmt.php)
- *
- * License: GPL v3 http://www.opensource.org/licenses/gpl-3.0.html
- */
+* Changes from php.mo:
+* supress the error if there's no file
+* fixed "fuzzy flag first line" bug which didn't saved previous proper string at all
+* fix the warning if list finds no $data
+* added case for commented unused string
+* proper handling of msgctxt
+* better storing of same msgid
+* corrected data structure for correct counting of plural msgstr
+* don't add last translation if it's fuzzy
+* removed unedeed phpmo_convert and phpmo_write_mo_file
+* more info on https://bugs.mageia.org/show_bug.cgi?id=14899
+*
+* it returns array of translations:
+* $dictionary = phpmo_parse_po_file('input.po');
+*
+* $dictionary = array (
+* '' => array (
+* 'msgid' => '',
+* 'msgstr' => array (
+* 0 => 'Project-Id-Version: ...',
+* ),
+* ),
+* 'string for translation 1' => array (
+* 'msgid' => 'string for translation 1',
+* 'msgstr' => array (
+* 0 => 'translated string 1',
+* ),
+* ),
+* 'string for translation 2' => array (
+* 'msgid' => 'string for translation 2',
+* 'msgstr' => array (
+* 0 => 'translated string 2',
+* 1 => 'translated string 2 but different context',
+* 2 => 'another translated string 2 with different context',
+* ),
+* 'msgctxt' => array (
+* 1 => 'context explanation for msgstr[1]',
+* 2 => 'context explanation for msgstr[2]',
+* ),
+* ),
+* 'string for translation 3' => array (
+* 'msgid' => 'string for translation 3',
+* 'msgid_plural' => 'plural string for translation 3',
+* 'msgstr' => array (
+* 0 => array (
+* 0 => 'translated string 3 for nplurals 0',
+* 1 => 'translated string 3 for nplurals 1',
+* 2 => 'translated string 3 for nplurals 2',
+* ),
+* ),
+* ),
+* );
+*
+****************************************************************************************
+*
+* based on php.mo 0.1 by Joss Crowcroft (http://www.josscrowcroft.com)
+* which is
+* Based on php-msgfmt by Matthias Bauer (Copyright © 2007), a command-line PHP tool
+* for converting .po files to .mo.
+* (http://wordpress-soc-2007.googlecode.com/svn/trunk/moeffju/php-msgfmt/msgfmt.php)
+*
+* License: GPL v3 http://www.opensource.org/licenses/gpl-3.0.html
+*/
function phpmo_clean_helper($x) {
if (is_array($x)) {
@@ -60,34 +99,29 @@ function phpmo_parse_po_file($in) {
// iterate over lines
while(($line = fgets($fh, 65536)) !== false) {
$line = trim($line);
- if ($line === '') {
- // save stored entry on empty line
- // block moved to fix "fuzzy flag first line" bug which didn't saved previous proper string at all
- if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) {
- if (!$fuzzy)
- $hash[] = $temp;
- $temp = array ();
- $state = null;
- $fuzzy = false;
- }
+ if ($line === '')
continue;
- }
+
$array_of_splited_string = preg_split('/\s/', $line, 2);
$key = $array_of_splited_string[0];
$data = (isset($array_of_splited_string[1]) ? $array_of_splited_string[1] : '');
-
switch ($key) {
case '#,' : // flag...
- $fuzzy = in_array('fuzzy', preg_split('/,\s*/', $data));
case '#' : // translator-comments
case '#.' : // extracted-comments
case '#:' : // reference...
case '#|' : // msgid previous-untranslated-string
- break;
case '#~' : // commented-unused-string
- $temp = array ();
- $state = null;
- $fuzzy = false;
+ // start a new entry
+ if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) {
+ if (!$fuzzy)
+ $hash[] = $temp;
+ $temp = array ();
+ $state = null;
+ $fuzzy = false;
+ }
+ if ($key == '#,')
+ $fuzzy = in_array('fuzzy', preg_split('/,\s*/', $data));
break;
case 'msgctxt' :
// context
@@ -96,7 +130,23 @@ function phpmo_parse_po_file($in) {
case 'msgid_plural' :
// untranslated-string-plural
$state = $key;
- $temp[$state] = $data;
+ // store previous entry if it exists
+ if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) {
+ if (!$fuzzy)
+ $hash[] = $temp;
+ $temp = array ();
+ $fuzzy = false;
+ }
+ if ($key == 'msgctxt') {
+ if (array_key_exists('msgstr', $temp)) {
+ $msgctxt_index = count($temp['msgstr']);
+ } else {
+ $msgctxt_index = 0;
+ }
+ $temp['msgctxt'][$msgctxt_index] = $data;
+ } else {
+ $temp[$state] = $data;
+ }
break;
case 'msgstr' :
// translated-string
@@ -111,11 +161,11 @@ function phpmo_parse_po_file($in) {
} else {
// continued lines
switch ($state) {
- case 'msgctxt' :
case 'msgid' :
case 'msgid_plural' :
$temp[$state] .= "\n" . $line;
break;
+ case 'msgctxt' :
case 'msgstr' :
$temp[$state][sizeof($temp[$state]) - 1] .= "\n" . $line;
break;
@@ -132,7 +182,8 @@ function phpmo_parse_po_file($in) {
// add final entry
if ($state == 'msgstr')
- $hash[] = $temp;
+ if (!$fuzzy)
+ $hash[] = $temp;
// Cleanup data, merge multiline entries, reindex hash for ksort
$temp = $hash;
@@ -145,10 +196,24 @@ function phpmo_parse_po_file($in) {
return FALSE;
}
}
- $hash[$entry['msgid']] = $entry;
+ // if there's already same msgid we need to store it there
+ if (array_key_exists($entry['msgid'], $hash)) {
+ $index = count($hash[$entry['msgid']]['msgstr']);
+ $hash[$entry['msgid']]['msgstr'][$index] = $entry['msgstr'][0];
+ // is different msgctxt present also?
+ if (array_key_exists('msgctxt', $entry)) {
+ $hash[$entry['msgid']]['msgctxt'][$index] = $entry['msgctxt'][0];
+ }
+ } else {
+ // if msgid_plural exists we need to store msgstr to subarray for proper counting of l10n completion
+ if (array_key_exists('msgid_plural', $entry)) {
+ $msgstr_plural = $entry['msgstr'];
+ $entry['msgstr'] = array();
+ $entry['msgstr'][] = $msgstr_plural;
+ }
+ $hash[$entry['msgid']] = $entry;
+ }
}
return $hash;
}
-
-?> \ No newline at end of file