Fix gettext's plural forms for more than 2 plural forms. Props moeffju and nbachiyski. fixes #4005

git-svn-id: http://svn.automattic.com/wordpress/trunk@5266 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
rob1n 2007-04-13 23:29:47 +00:00
parent 24e1d66471
commit 62f5c944dc
1 changed files with 359 additions and 331 deletions

View File

@ -45,6 +45,7 @@ class gettext_reader {
var $originals = NULL; // offset of original table
var $translations = NULL; // offset of translation table
var $pluralheader = NULL; // cache header field for plural forms
var $select_string_function = NULL; // cache function, which chooses plural forms
var $total = 0; // total string count
var $table_originals = NULL; // table for original strings (offsets)
var $table_translations = NULL; // table for translated strings (offsets)
@ -283,12 +284,38 @@ class gettext_reader {
} else {
$header = $this->get_translation_string(0);
}
$header .= "\n"; //make sure our regex matches
if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
$expr = $regs[1];
else
$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
$this->pluralheader = $expr;
// add parentheses
// important since PHP's ternary evaluates from left to right
$expr.= ';';
$res= '';
$p= 0;
for ($i= 0; $i < strlen($expr); $i++) {
$ch= $expr[$i];
switch ($ch) {
case '?':
$res.= ' ? (';
$p++;
break;
case ':':
$res.= ') : (';
break;
case ';':
$res.= str_repeat( ')', $p) . ';';
$p= 0;
break;
default:
$res.= $ch;
}
}
$this->pluralheader = $res;
}
return $this->pluralheader;
}
@ -300,21 +327,22 @@ class gettext_reader {
* @return int array index of the right plural form
*/
function select_string($n) {
if (is_null($this->select_string_function)) {
$string = $this->get_plural_forms();
$string = str_replace('nplurals',"\$total",$string);
$string = str_replace("n",$n,$string);
$string = str_replace('plural',"\$plural",$string);
# poEdit doesn't put any semicolons, which
# results in parse error in eval
$string .= ';';
$total = 0;
$plural = 0;
eval("$string");
if ($plural >= $total) $plural = $total - 1;
return $plural;
if (preg_match("/nplurals\s*=\s*(\d+)\s*\;\s*plural\s*=\s*(.*?)\;+/", $string, $matches)) {
$nplurals = $matches[1];
$expression = $matches[2];
$expression = str_replace("n", '$n', $expression);
} else {
$nplurals = 2;
$expression = ' $n == 1 ? 0 : 1 ';
}
$func_body = "
\$plural = ($expression);
return (\$plural <= $nplurals)? \$plural : \$plural - 1;";
$this->select_string_function = create_function('$n', $func_body);
}
return call_user_func($this->select_string_function, $n);
}
/**