Browse Source

Implemented multiple lines for all stages in parsing a po file

Wouter van Os 8 years ago
parent
commit
3d35c7e726

+ 17 - 9
src/I18n/Parser/PoFileParser.php

@@ -60,7 +60,6 @@ class PoFileParser
      *
      * This parser sacrifices some features of the reference implementation the
      * differences to that implementation are as follows.
-     * - No support for comments spanning multiple lines.
      * - Translator and extracted comments are treated as being the same type.
      * - Message IDs are allowed to have other encodings as just US-ASCII.
      *
@@ -81,6 +80,7 @@ class PoFileParser
 
         $messages = [];
         $item = $defaults;
+        $stage = null;
 
         while ($line = fgets($stream)) {
             $line = trim($line);
@@ -89,28 +89,36 @@ class PoFileParser
                 // Whitespace indicated current item is done
                 $this->_addMessage($messages, $item);
                 $item = $defaults;
+                $stage = null;
             } elseif (substr($line, 0, 7) === 'msgid "') {
                 // We start a new msg so save previous
                 $this->_addMessage($messages, $item);
                 $item['ids']['singular'] = substr($line, 7, -1);
+                $stage = ['ids', 'singular'];
             } elseif (substr($line, 0, 8) === 'msgstr "') {
                 $item['translated'] = substr($line, 8, -1);
+                $stage = ['translated'];
             } elseif (substr($line, 0, 9) === 'msgctxt "') {
                 $item['context'] = substr($line, 9, -1);
+                $stage = ['context'];
             } elseif ($line[0] === '"') {
-                $continues = isset($item['context']) ? 'context' : (isset($item['translated']) ? 'translated' : 'ids');
-
-                if (is_array($item[$continues])) {
-                    end($item[$continues]);
-                    $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
-                } else {
-                    $item[$continues] .= substr($line, 1, -1);
+                switch (count($stage)) {
+                    case 2:
+                        $item[$stage[0]][$stage[1]] .= substr($line, 1, -1);
+                        break;
+
+                    case 1:
+                        $item[$stage[0]] .= substr($line, 1, -1);
+                        break;
                 }
             } elseif (substr($line, 0, 14) === 'msgid_plural "') {
                 $item['ids']['plural'] = substr($line, 14, -1);
+                $stage = ['ids', 'plural'];
             } elseif (substr($line, 0, 7) === 'msgstr[') {
                 $size = strpos($line, ']');
-                $item['translated'][(int)substr($line, 7, 1)] = substr($line, $size + 3, -1);
+                $row = (int)substr($line, 7, 1);
+                $item['translated'][$row] = substr($line, $size + 3, -1);
+                $stage = ['translated', $row];
             }
         }
         // save last item

+ 22 - 1
tests/TestCase/I18n/Parser/PoFileParserTest.php

@@ -97,7 +97,28 @@ class PoFileParserTest extends TestCase
                         4 => '%-5d = 0 or > 1 (translated)'
                     ]
                 ]
-            ]
+            ],
+            '%d = 2' => [
+                '_context' => [
+                    'This is another translated context' => 'First Context trasnlation',
+                ]
+            ],
+            '%-6d = 3' => [
+                '_context' => [
+                    '' => '%-6d = 1 (translated)',
+                ]
+            ],
+            'p:%-6d = 0 or > 1' => [
+                '_context' => [
+                    '' => [
+                        0 => '%-6d = 1 (translated)',
+                        1 => '',
+                        2 => '',
+                        3 => '',
+                        4 => '%-6d = 0 or > 1 (translated)',
+                    ]
+                ]
+            ],
         ];
         $this->assertEquals($expected, $messages);
     }

+ 17 - 1
tests/test_app/TestApp/Locale/rule_1_po/default.po

@@ -18,7 +18,8 @@ msgstr "Plural Rule 1 (translated)"
 msgctxt ""
 "This is the context"
 msgid "%d = 1"
-msgstr "First Context trasnlation"
+msgstr ""
+"First Context trasnlation"
 
 msgctxt "Another Context"
 msgid "%d = 1"
@@ -31,6 +32,21 @@ msgid_plural "%-5d = 0 or > 1"
 msgstr[0] "%-5d = 1 (translated)"
 msgstr[4] "%-5d = 0 or > 1 (translated)"
 
+msgctxt ""
+"This is another translated context"
+msgid ""
+"%d = 2"
+msgstr ""
+"First Context trasnlation"
+
+msgid "%-6d = 3"
+msgid_plural "%-6d = 0 or > 1"
+msgstr[0] ""
+"%-6d = 1 (translated)"
+msgstr[4] ""
+"%-6d = 0 or > 1 (translated)"
+""
+
 #~ msgid "Plural-Forms 1"
 #~ msgstr "Plural-Forms 1 (translated)"