Skip to content

Commit

Permalink
Allow for missing whitelines.
Browse files Browse the repository at this point in the history
  • Loading branch information
clemens-tolboom committed May 19, 2012
1 parent 480e035 commit 66a0aa6
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 17 deletions.
11 changes: 9 additions & 2 deletions Dumper/PoFileDumper.php
Expand Up @@ -27,9 +27,16 @@ public function format(MessageCatalogue $messages, $domain = 'messages')
{
$output = '';

$newLine = FALSE;
foreach ($messages->all($domain) as $source => $target) {
$output .= sprintf("msgid \"%s\"\n", $this->escape($source));
$output .= sprintf("msgstr \"%s\"\n\n", $this->escape($target));
if ($newLine) {
$output .= "\n";
}
else {
$newLine = TRUE;
}
$output .= sprintf('msgid "%s"' . "\n", $this->escape($source));
$output .= sprintf('msgstr "%s"', $this->escape($target));
}

return $output;
Expand Down
82 changes: 70 additions & 12 deletions Loader/PoFileLoader.php
Expand Up @@ -15,6 +15,7 @@

/**
* @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
* @copyright Copyright (c) 2012, Clemens Tolboom
*/
class PoFileLoader extends ArrayLoader implements LoaderInterface
{
Expand All @@ -41,6 +42,36 @@ public function load($resource, $locale, $domain = 'messages')
/**
* Parses portable object (PO) format.
*
* From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
* we should be able to parse files having:
*
* white-space
* # translator-comments
* #. extracted-comments
* #: reference...
* #, flag...
* #| msgid previous-untranslated-string
* msgid untranslated-string
* msgstr translated-string
*
* extra or different lines are:
*
* #| msgctxt previous-context
* #| msgid previous-untranslated-string
* msgctxt context
*
* #| msgid previous-untranslated-string-singular
* #| msgid_plural previous-untranslated-string-plural
* msgid untranslated-string-singular
* msgid_plural untranslated-string-plural
* msgstr[0] translated-string-case-0
* ...
* msgstr[N] translated-string-case-n
*
* The definition states:
* - white-space and comments are optional.
* - msgid "" that an empty singleline defines a header.
*
* This parser sacrifices some features of the reference implementation the
* differences to that implementation are as follows.
* - No support for comments spanning multiple lines.
Expand Down Expand Up @@ -69,20 +100,14 @@ private function parse($resource)
$line = trim($line);

if ($line === '') {
if (is_array($item['translated'])) {
$messages[$item['ids']['singular']] = stripslashes($item['translated'][0]);
if (isset($item['ids']['plural'])) {
$plurals = array();
foreach ($item['translated'] as $plural => $translated) {
$plurals[] = sprintf('{%d} %s', $plural, $translated);
}
$messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals));
}
} elseif(!empty($item['ids']['singular'])) {
$messages[$item['ids']['singular']] = stripslashes($item['translated']);
}
// Whitespace indicated current item is done
$this->addMessage($messages, $item);
$item = $defaults;
} elseif (substr($line, 0, 7) === 'msgid "') {
// We start a new msg so save previous
// TODO: this fails when comments or contexts are added
$this->addMessage($messages, $item);
$item = $defaults;
$item['ids']['singular'] = substr($line, 7, -1);
} elseif (substr($line, 0, 8) === 'msgstr "') {
$item['translated'] = substr($line, 8, -1);
Expand All @@ -103,8 +128,41 @@ private function parse($resource)
}

}
// save last item
$this->addMessage($messages, $item);
fclose($stream);

return array_filter($messages);
}

/**
* Save a translation item to the messeages.
*
* A .po file could contain by error missing plural indexes. We need to
* fix these before saving them.
*
* @param array $messages
* @param array $item
*/
private function addMessage(array &$messages, array $item)
{
if (is_array($item['translated'])) {
$messages[$item['ids']['singular']] = stripslashes($item['translated'][0]);
if (isset($item['ids']['plural'])) {
$plurals = $item['translated'];
// PO are by definition indexed so sort by index.
ksort($plurals);
// Make sure every index is filled.
end($plurals);
$count = key($plurals);
// Fill missing spots with '-'.
$empties = array_fill(0, $count+1, '-');
$plurals += $empties;
ksort($plurals);
$messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals));
}
} elseif(!empty($item['ids']['singular'])) {
$messages[$item['ids']['singular']] = stripslashes($item['translated']);
}
}
}
2 changes: 1 addition & 1 deletion Tests/Loader/PoFileLoaderTest.php
Expand Up @@ -39,7 +39,7 @@ public function testLoadPlurals()
$resource = __DIR__.'/../fixtures/plurals.po';
$catalogue = $loader->load($resource, 'en', 'domain1');

$this->assertEquals(array('foo' => 'bar', 'foos' => '{0} bar|{1} bars'), $catalogue->all('domain1'));
$this->assertEquals(array('foo' => 'bar', 'foos' => 'bar|bars'), $catalogue->all('domain1'));
$this->assertEquals('en', $catalogue->getLocale());
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
}
Expand Down
3 changes: 1 addition & 2 deletions Tests/fixtures/resources.po
@@ -1,3 +1,2 @@
msgid "foo"
msgstr "bar"

msgstr "bar"

0 comments on commit 66a0aa6

Please sign in to comment.