merged branch clemens-tolboom/pofileloader-better-whitelines (PR #4339)

Commits
-------

fb6cf3e Allow for missing whitelines.

Discussion
----------

Allow for missing whitelines.

The Gettext specification allows for 'whitespace is optional' between message string.

For this to work PoFileLoader needs to save found messages on more places while processing. Thus a new method is introduced.

For the tests to work PoFileDumper was changed slightly to only emit white-lines when necessary.

I added more documentation from the GNU gettext documentation to make the code more understandable.

When [[BUG] PoFileLoader pluralhandling uses interval instead of index.](https://github.com/symfony/symfony/pull/4336) this patch needs some small rework.

(this is part of [[WIP]: Allow Drupal to use Translate component)](https://github.com/symfony/symfony/pull/4249)

---------------------------------------------------------------------------

by travisbot at 2012-05-19T12:44:19Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1374295) (merged fb6cf3ef into 58b92453).

---------------------------------------------------------------------------

by stof at 2012-05-19T13:19:29Z

you need to rebase your branch. github tells us it cannot be merged automatically
This commit is contained in:
Fabien Potencier 2012-05-19 15:21:01 +02:00
commit 63c76c421e
3 changed files with 80 additions and 16 deletions

View File

@ -27,9 +27,16 @@ class PoFileDumper extends FileDumper
{
$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;

View File

@ -15,6 +15,7 @@ use Symfony\Component\Config\Resource\FileResource;
/**
* @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
{
@ -41,6 +42,36 @@ class PoFileLoader extends ArrayLoader implements LoaderInterface
/**
* 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.
@ -69,20 +100,14 @@ class PoFileLoader extends ArrayLoader implements LoaderInterface
$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[] = $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);
@ -103,8 +128,41 @@ class PoFileLoader extends ArrayLoader implements LoaderInterface
}
}
// save last item
$this->addMessage($messages, $item);
fclose($stream);
return $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']);
}
}
}

View File

@ -1,3 +1,2 @@
msgid "foo"
msgstr "bar"
msgstr "bar"