'FakeConverter' => 'languages/Language.php',
'Language' => 'languages/Language.php',
'LanguageConverter' => 'languages/LanguageConverter.php',
+ 'CLDRPluralRuleEvaluator' => 'languages/utils/CLDRPluralRuleEvaluator.php',
# maintenance
'ConvertLinks' => 'maintenance/convertLinks.php',
'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
'defaultDateFormat', 'extraUserToggles', 'specialPageAliases',
'imageFiles', 'preloadedMessages', 'namespaceGenderAliases',
- 'digitGroupingPattern'
+ 'digitGroupingPattern', 'pluralRules'
);
/**
* by a fallback sequence.
*/
static public $mergeableMapKeys = array( 'messages', 'namespaceNames',
- 'dateFormats', 'imageFiles', 'preloadedMessages',
+ 'dateFormats', 'imageFiles', 'preloadedMessages', 'pluralRules'
);
/**
*/
static public $preloadedKeys = array( 'dateFormats', 'namespaceNames' );
+ /*
+ * Associative array containing plural rules.
+ */
+ var $pluralRules = array();
+
var $mergeableKeys = null;
/**
$this->$var = $conf[$var];
}
}
+ $this->readPluralRules();
}
/**
*/
public function getItem( $code, $key ) {
if ( !isset( $this->loadedItems[$code][$key] ) ) {
- wfProfileIn( __METHOD__.'-load' );
+ wfProfileIn( __METHOD__ . '-load' );
$this->loadItem( $code, $key );
- wfProfileOut( __METHOD__.'-load' );
+ wfProfileOut( __METHOD__ . '-load' );
}
if ( $key === 'fallback' && isset( $this->shallowFallbacks[$code] ) ) {
public function getSubitem( $code, $key, $subkey ) {
if ( !isset( $this->loadedSubitems[$code][$key][$subkey] ) &&
!isset( $this->loadedItems[$code][$key] ) ) {
- wfProfileIn( __METHOD__.'-load' );
+ wfProfileIn( __METHOD__ . '-load' );
$this->loadSubitem( $code, $key, $subkey );
- wfProfileOut( __METHOD__.'-load' );
+ wfProfileOut( __METHOD__ . '-load' );
}
if ( isset( $this->data[$code][$key][$subkey] ) ) {
*/
public function isExpired( $code ) {
if ( $this->forceRecache && !isset( $this->recachedLangs[$code] ) ) {
- wfDebug( __METHOD__."($code): forced reload\n" );
+ wfDebug( __METHOD__ . "($code): forced reload\n" );
return true;
}
$preload = $this->store->get( $code, 'preload' );
// Different keys may expire separately, at least in LCStore_Accel
if ( $deps === null || $keys === null || $preload === null ) {
- wfDebug( __METHOD__."($code): cache missing, need to make one\n" );
+ wfDebug( __METHOD__ . "($code): cache missing, need to make one\n" );
return true;
}
// anymore (e.g. uninstalled extensions)
// When this happens, always expire the cache
if ( !$dep instanceof CacheDependency || $dep->isExpired() ) {
- wfDebug( __METHOD__."($code): cache for $code expired due to " .
+ wfDebug( __METHOD__ . "($code): cache for $code expired due to " .
get_class( $dep ) . "\n" );
return true;
}
} elseif ( $_fileType == 'aliases' ) {
$data = compact( 'aliases' );
} else {
- throw new MWException( __METHOD__.": Invalid file type: $_fileType" );
+ throw new MWException( __METHOD__ . ": Invalid file type: $_fileType" );
}
-
return $data;
}
+ /**
+ * Read the plural rule xml files.
+ * First the CLDR xml will be read and it will be extended with
+ * mediawiki specific tailoring.
+ * @since 1.20
+ */
+ protected function readPluralRules() {
+ $CLDRPlural = __DIR__ . "/../languages/data/plurals.xml";
+ $MWPlural = __DIR__ . "/../languages/data/plurals-mediawiki.xml";
+ # Load CLDR plural rules
+ $this->parsePluralXML( $CLDRPlural );
+ if ( file_exists( $MWPlural ) ) {
+ // override or extend.
+ $this->parsePluralXML( $MWPlural );
+ }
+ }
+
+ private function parsePluralXML( $xmlFile ) {
+ $pluraldoc = new DOMDocument();
+ $pluraldoc->load( $xmlFile );
+ $rulesets = $pluraldoc->getElementsByTagName( "pluralRules" );
+ foreach ( $rulesets as $ruleset ) {
+ $codes = $ruleset->getAttribute( 'locales' );
+ $parsedRules = array();
+ $rules = $ruleset->getElementsByTagName( "pluralRule" );
+ foreach ( $rules as $rule ) {
+ $parsedRules[$rule->getAttribute( 'count' )] = $rule->nodeValue;
+ }
+ foreach ( explode( ' ', $codes ) as $code ) {
+ $this->pluralRules[$code] = $parsedRules;
+ }
+ }
+ }
/**
* Merge two localisation values, a primary and a fallback, overwriting the
# Load the primary localisation from the source file
$fileName = Language::getMessagesFileName( $code );
if ( !file_exists( $fileName ) ) {
- wfDebug( __METHOD__.": no localisation file for $code, using fallback to en\n" );
+ wfDebug( __METHOD__ . ": no localisation file for $code, using fallback to en\n" );
$coreData['fallback'] = 'en';
} else {
$deps[] = new FileDependency( $fileName );
$data = $this->readPHPFile( $fileName, 'core' );
- wfDebug( __METHOD__.": got localisation for $code from source\n" );
+ wfDebug( __METHOD__ . ": got localisation for $code from source\n" );
# Merge primary localisation
foreach ( $data as $key => $value ) {
if ( is_null( $coreData['fallback'] ) ) {
$coreData['fallback'] = $code === 'en' ? false : 'en';
}
-
if ( $coreData['fallback'] === false ) {
$coreData['fallbackSequence'] = array();
} else {
$used = false;
foreach ( $data as $key => $item ) {
- if( $this->mergeExtensionItem( $codeSequence, $key, $allData[$key], $item ) ) {
+ if ( $this->mergeExtensionItem( $codeSequence, $key, $allData[$key], $item ) ) {
$used = true;
}
}
$page = str_replace( ' ', '_', $page );
}
# Decouple the reference to prevent accidental damage
- unset($page);
+ unset( $page );
# Set the list keys
$allData['list'] = array();
foreach ( self::$splitKeys as $key ) {
$allData['list'][$key] = array_keys( $allData[$key] );
}
-
+ # Load CLDR plural rules
+ if ( isset( $this->pluralRules[$code] ) ) {
+ $allData['pluralRules'] = $this->pluralRules[$code];
+ }
# Run hooks
wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData ) );
if ( is_null( $allData['namespaceNames'] ) ) {
- throw new MWException( __METHOD__.': Localisation data failed sanity check! ' .
+ throw new MWException( __METHOD__ . ': Localisation data failed sanity check! ' .
'Check that your languages/messages/MessagesEn.php file is intact.' );
}
}
if ( !$code ) {
- throw new MWException( __METHOD__.": Invalid language \"$code\"" );
+ throw new MWException( __METHOD__ . ": Invalid language \"$code\"" );
}
$this->dbw = wfGetDB( DB_MASTER );
}
if ( is_null( $this->currentLang ) ) {
- throw new MWException( __CLASS__.': must call startWrite() before calling set()' );
+ throw new MWException( __CLASS__ . ': must call startWrite() before calling set()' );
}
$this->batch[] = array(
}
// Close reader to stop permission errors on write
- if( !empty($this->readers[$code]) ) {
+ if ( !empty( $this->readers[$code] ) ) {
$this->readers[$code]->close();
}
public function set( $key, $value ) {
if ( is_null( $this->writer ) ) {
- throw new MWException( __CLASS__.': must call startWrite() before calling set()' );
+ throw new MWException( __CLASS__ . ': must call startWrite() before calling set()' );
}
$this->writer->set( $key, serialize( $value ) );
}
protected function getFileName( $code ) {
if ( !$code || strpos( $code, '/' ) !== false ) {
- throw new MWException( __METHOD__.": Invalid language \"$code\"" );
+ throw new MWException( __METHOD__ . ": Invalid language \"$code\"" );
}
return "{$this->directory}/l10n_cache-$code.cdb";
}
while ( count( $this->data ) > $this->maxLoadedLangs && count( $this->mruLangs ) ) {
reset( $this->mruLangs );
$code = key( $this->mruLangs );
- wfDebug( __METHOD__.": unloading $code\n" );
+ wfDebug( __METHOD__ . ": unloading $code\n" );
$this->unload( $code );
}
}
+
}
protected $language;
/**
- * Get the grammer forms for the site content language.
+ * Get the grammar forms for the site content language.
*
* @return array
*/
return $this->language->getGrammarForms();
}
+ /**
+ * Get the plural forms for the site content language.
+ *
+ * @return array
+ */
+ protected function getPluralRules() {
+ return $this->language->getPluralRules();
+ }
+
/**
* Get the digit transform table for the content language
* Seperator transform table also required here to convert
* @return array
*/
protected function getData() {
- return array( 'grammarForms' => $this->getSiteLangGrammarForms(),
- 'digitTransformTable' => $this->getDigitTransformTable()
- );
+ return array(
+ 'digitTransformTable' => $this->getDigitTransformTable(),
+ 'grammarForms' => $this->getSiteLangGrammarForms(),
+ 'pluralRules' => $this->getPluralRules(),
+ );
}
/**
* @param $context ResourceLoaderContext
- * @return string: Javascript code
+ * @return string: JavaScript code
*/
public function getScript( ResourceLoaderContext $context ) {
- $this->language = Language::factory( $context ->getLanguage() );
+ $this->language = Language::factory( $context->getLanguage() );
return Xml::encodeJsCall( 'mw.language.setData', array(
$this->language->getCode(),
$this->getData()
*/
public static function isValidBuiltInCode( $code ) {
- if( !is_string($code) ) {
+ if ( !is_string( $code ) ) {
$type = gettype( $code );
- if( $type === 'object' ) {
+ if ( $type === 'object' ) {
$addmsg = " of class " . get_class( $code );
} else {
$addmsg = '';
$names = array();
- if( $inLanguage ) {
+ if ( $inLanguage ) {
# TODO: also include when $inLanguage is null, when this code is more efficient
wfRunHooks( 'LanguageGetTranslatedLanguageNames', array( &$names, $inLanguage ) );
}
$returnMw = array();
$coreCodes = array_keys( $mwNames );
- foreach( $coreCodes as $coreCode ) {
+ foreach ( $coreCodes as $coreCode ) {
$returnMw[$coreCode] = $names[$coreCode];
}
- if( $include === 'mwfile' ) {
+ if ( $include === 'mwfile' ) {
$namesMwFile = array();
# We do this using a foreach over the codes instead of a directory
# loop so that messages files in extensions will work correctly.
if ( !count( $forms ) ) {
return '';
}
- $forms = $this->preConvertPlural( $forms, 2 );
-
- return ( $count == 1 ) ? $forms[0] : $forms[1];
+ $pluralForm = $this->getPluralForm( $count );
+ $pluralForm = min( $pluralForm, count( $forms ) - 1 );
+ return $forms[$pluralForm];
}
/**
public function getConvRuleTitle() {
return $this->mConverter->getConvRuleTitle();
}
+
+ /**
+ * Get the plural rules for the language
+ * @since 1.20
+ * @return array Associative array with plural form, and plural rule as key-value pairs
+ */
+ public function getPluralRules() {
+ return self::$dataCache->getItem( strtolower( $this->mCode ), 'pluralRules' );
+ }
+
+ /**
+ * Find the plural form matching to the given number
+ * It return the form index.
+ * @return int The index of the plural form
+ */
+ private function getPluralForm( $number ) {
+ $pluralRules = $this->getPluralRules();
+ $form = CLDRPluralRuleEvaluator::evaluate( $number, $pluralRules );
+ return $form;
+ }
+
}
+++ /dev/null
-<?php
-/**
- * Amharic (አማርኛ) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Language
- */
-
-/**
- * Amharic (አማርኛ)
- *
- * @ingroup Language
- */
-class LanguageAm extends Language {
- /**
- * Use singular form for zero
- *
- * @param $count int
- * @param $forms array
- *
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 2 );
-
- return ( $count <= 1 ) ? $forms[0] : $forms[1];
- }
-}
*/
class LanguageAr extends Language {
- /**
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 6 );
-
- if ( $count == 0 ) {
- $index = 0;
- } elseif ( $count == 1 ) {
- $index = 1;
- } elseif ( $count == 2 ) {
- $index = 2;
- } elseif ( $count % 100 >= 3 && $count % 100 <= 10 ) {
- $index = 3;
- } elseif ( $count % 100 >= 11 && $count % 100 <= 99 ) {
- $index = 4;
- } else {
- $index = 5;
- }
- return $forms[$index];
- }
-
/**
* Temporary hack for bug 9413: replace Arabic presentation forms with their
* standard equivalents.
+++ /dev/null
-<?php
-/**
- * Belarusian normative (Беларуская мова) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
- * @ingroup Language
- */
-
-/**
- * Belarusian normative (Беларуская мова)
- *
- * This is still the version from Be-x-old, only duplicated for consistency of
- * plural and grammar functions. If there are errors please send a patch.
- *
- * @ingroup Language
- * @see http://be.wikipedia.org/wiki/Talk:LanguageBe.php
- */
-class LanguageBe extends Language {
-
- /**
- * @param $count int
- * @param $forms array
- *
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- // @todo FIXME: CLDR defines 4 plural forms instead of 3
- // http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
- $forms = $this->preConvertPlural( $forms, 3 );
-
- if ( $count > 10 && floor( ( $count % 100 ) / 10 ) == 1 ) {
- return $forms[2];
- } else {
- switch ( $count % 10 ) {
- case 1: return $forms[0];
- case 2:
- case 3:
- case 4: return $forms[1];
- default: return $forms[2];
- }
- }
- }
-}
+++ /dev/null
-<?php
-/**
- * Bihari (भोजपुरी) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Language
- */
-
-/**
- * Bihari (भोजपुरी)
- *
- * @ingroup Language
- */
-class LanguageBh extends Language {
- /**
- * Use singular form for zero
- *
- * @param $count int
- * @param $forms array
- *
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 2 );
-
- return ( $count <= 1 ) ? $forms[0] : $forms[1];
- }
-}
*/
class LanguageBs extends Language {
- /**
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 3 );
-
- // @todo FIXME: CLDR defines 4 plural forms instead of 3. Plural for decimals is missing.
- // http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
- if ( $count > 10 && floor( ( $count % 100 ) / 10 ) == 1 ) {
- return $forms[2];
- } else {
- switch ( $count % 10 ) {
- case 1: return $forms[0];
- case 2:
- case 3:
- case 4: return $forms[1];
- default: return $forms[2];
- }
- }
- }
/**
* Convert from the nominative form of a noun to some other case
+++ /dev/null
-<?php
-/**
- * Czech (čeština [subst.], český [adj.], česky [adv.]) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Language
- */
-
-/**
- * Czech (čeština [subst.], český [adj.], česky [adv.])
- *
- * @ingroup Language
- */
-class LanguageCs extends Language {
-
- /**
- * Plural transformations
- * Invoked by putting
- * {{plural:count|form1|form2-4|form0,5+}} for two forms plurals
- * {{plural:count|form1|form0,2+}} for single form plurals
- * in a message
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 3 );
-
- switch ( $count ) {
- case 1:
- return $forms[0];
- case 2:
- case 3:
- case 4:
- return $forms[1];
- default:
- return $forms[2];
- }
- }
-}
* @file
* @ingroup Language
*/
-
+
/**
* Old Church Slavonic (Ѩзыкъ словѣньскъ)
*
+++ /dev/null
-<?php
-/**
- * Welsh (Cymraeg) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Niklas Laxström
- * @ingroup Language
- */
-
-/**
- * Welsh (Cymraeg)
- *
- * @ingroup Language
- */
-class LanguageCy extends Language {
-
- /**
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
-
- $forms = $this->preConvertPlural( $forms, 6 );
- $count = abs( $count );
- if ( $count >= 0 && $count <= 3 ) {
- return $forms[$count];
- } elseif ( $count == 6 ) {
- return $forms[4];
- } else {
- return $forms[5];
- }
- }
-}
return $word; # this will return the original value for 'nominatiw' (nominativ) and all undefined case values
}
- /**
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 4 );
-
- switch ( abs( $count ) % 100 ) {
- case 1: return $forms[0]; // singular
- case 2: return $forms[1]; // dual
- case 3:
- case 4: return $forms[2]; // plural
- default: return $forms[3]; // pluralgen
- }
- }
}
+++ /dev/null
-<?php
-/**
- * French (Français) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Language
- */
-
-/**
- * French (Français)
- *
- * @ingroup Language
- */
-class LanguageFr extends Language {
- /**
- * Use singular form for zero (see bug 7309)
- *
- * @param $count int
- * @param $forms array
- *
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 2 );
-
- return ( $count <= 1 ) ? $forms[0] : $forms[1];
- }
-}
return $word;
}
- /**
- * @param $count int
- * @param $forms array
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
-
- // plural forms per http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ga
- $forms = $this->preConvertPlural( $forms, 3 );
-
- if ( $count == 1 ) {
- $index = 0;
- } elseif ( $count == 2 ) {
- $index = 1;
- } else {
- $index = 2;
- }
- return $forms[$index];
- }
}
+++ /dev/null
-<?php
-/**
- * Scots Gaelic (Gàidhlig) specific code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Raimond Spekking
- * @author Niklas Laxström
- * @ingroup Language
- */
-
-/**
- * Scots Gaelic (Gàidhlig)
- *
- * @ingroup Language
- */
-class LanguageGd extends Language {
-
- /**
- * Plural form transformations
- * Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
- *
- * $forms[0] - 1
- * $forms[1] - 2
- * $forms[2] - 11
- * $forms[3] - 12
- * $forms[4] - 3-10, 13-19
- * $forms[5] - 0, 20, rest
- *
- * @param $count int
- * @param $forms array
- *
- * @return string
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 6 );
-
- $count = abs( $count );
- if ( $count == 1 ) {
- return $forms[0];
- } elseif ( $count == 2 ) {
- return $forms[1];
- } elseif ( $count == 11 ) {
- return $forms[2];
- } elseif ( $count == 12 ) {
- return $forms[3];
- } elseif ( ($count >= 3 && $count <= 10) || ($count >= 13 && $count <= 19) ) {
- return $forms[4];
- } else {
- return $forms[5];
- }
- }
-}
return $word;
}
- /**
- * Gets a number and uses the suited form of the word.
- *
- * @param $count Integer: the number of items
- * @param $forms Array with 3 items: the three plural forms
- * @return String: the suited form of word
- */
- function convertPlural( $count, $forms ) {
- if ( !count( $forms ) ) { return ''; }
- $forms = $this->preConvertPlural( $forms, 3 );
-
- if ( $count == 1 ) {
- return $forms[0]; // Singular
- } elseif ( $count == 2 ) {
- return $forms[2]; // Dual or plural if dual is not provided (filled in preConvertPlural)
- } else {
- return $forms[1]; // Plural
- }
- }
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
+<supplementalData>
+ <plurals>
+ <pluralRules locales="he">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ </pluralRules>
+ </plurals>
+ <pluralRules locales="dsb">
+ <pluralRule count="one">n mod 100 is 1</pluralRule>
+ <pluralRule count="two">n mod 100 is 2</pluralRule>
+ <pluralRule count="few">n mod 100 in 3..4</pluralRule>
+ </pluralRules>
+ <pluralRules locales="cu">
+ <pluralRule count="one">n mod 10 is 1</pluralRule>
+ <pluralRule count="two">n mod 10 is 2</pluralRule>
+ <pluralRule count="few">n mod 10 in 3..4</pluralRule>
+ </pluralRules>
+ <!-- Plural form transformations
+ Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
+ $forms[0] - 1
+ $forms[1] - 2
+ $forms[2] - 11
+ $forms[3] - 12
+ $forms[4] - 3-10, 13-19
+ $forms[5] - 0, 20, rest -->
+ <pluralRules locales="gd">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ <pluralRule count="elevan">n is 11</pluralRule>
+ <pluralRule count="twelve">n is 12</pluralRule>
+ <pluralRule count="few">n in 3..10 or n in 13..19</pluralRule>
+ </pluralRules>
+</supplementalData>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
+<supplementalData>
+ <version number="$Revision: 6155 $"/>
+ <generation date="$Date: 2011-09-21 23:51:12 +0530 (ബു, 21 സെപ് 2011) $"/>
+ <plurals>
+ <!-- if locale is known to have no plurals, there are no rules -->
+ <pluralRules locales="az bm bo dz fa id ig ii hu ja jv ka kde kea km kn ko lo ms my sah ses sg th to tr vi wo yo zh"/>
+ <pluralRules locales="ar">
+ <pluralRule count="zero">n is 0</pluralRule>
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ <pluralRule count="few">n mod 100 in 3..10</pluralRule>
+ <pluralRule count="many">n mod 100 in 11..99</pluralRule>
+ </pluralRules>
+ <pluralRules locales="asa af bem bez bg bn brx ca cgg chr da de dv ee el en eo es et eu fi fo fur fy gl gsw gu ha haw he is it jmc kaj kcg kk kl ksb ku lb lg mas ml mn mr nah nb nd ne nl nn no nr ny nyn om or pa pap ps pt rof rm rwk saq seh sn so sq ss ssy st sv sw syr ta te teo tig tk tn ts ur wae ve vun xh xog zu">
+ <pluralRule count="one">n is 1</pluralRule>
+ </pluralRules>
+ <pluralRules locales="ak am bh fil tl guw hi ln mg nso ti wa">
+ <pluralRule count="one">n in 0..1</pluralRule>
+ </pluralRules>
+ <pluralRules locales="ff fr kab">
+ <pluralRule count="one">n within 0..2 and n is not 2</pluralRule>
+ </pluralRules>
+ <pluralRules locales="lv">
+ <pluralRule count="zero">n is 0</pluralRule>
+ <pluralRule count="one">n mod 10 is 1 and n mod 100 is not 11</pluralRule>
+ </pluralRules>
+ <pluralRules locales="iu kw naq se sma smi smj smn sms">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ </pluralRules>
+ <pluralRules locales="ga"> <!-- http://unicode.org/cldr/trac/ticket/3915 -->
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ <pluralRule count="few">n in 3..6</pluralRule>
+ <pluralRule count="many">n in 7..10</pluralRule>
+ </pluralRules>
+ <pluralRules locales="ro mo">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="few">n is 0 OR n is not 1 AND n mod 100 in 1..19</pluralRule>
+ </pluralRules>
+ <pluralRules locales="lt">
+ <pluralRule count="one">n mod 10 is 1 and n mod 100 not in 11..19</pluralRule>
+ <pluralRule count="few">n mod 10 in 2..9 and n mod 100 not in 11..19</pluralRule>
+ </pluralRules>
+ <pluralRules locales="be bs hr ru sh sr uk">
+ <pluralRule count="one">n mod 10 is 1 and n mod 100 is not 11</pluralRule>
+ <pluralRule count="few">n mod 10 in 2..4 and n mod 100 not in 12..14</pluralRule>
+ <pluralRule count="many">n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14</pluralRule>
+ <!-- others are fractions -->
+ </pluralRules>
+ <pluralRules locales="cs sk">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="few">n in 2..4</pluralRule>
+ </pluralRules>
+ <pluralRules locales="pl">
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="few">n mod 10 in 2..4 and n mod 100 not in 12..14</pluralRule>
+ <pluralRule count="many">n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14</pluralRule>
+ <!-- others are fractions -->
+ <!-- and n mod 100 not in 22..24 from Tamplin -->
+ </pluralRules>
+ <pluralRules locales="sl">
+ <pluralRule count="one">n mod 100 is 1</pluralRule>
+ <pluralRule count="two">n mod 100 is 2</pluralRule>
+ <pluralRule count="few">n mod 100 in 3..4</pluralRule>
+ </pluralRules>
+ <pluralRules locales="mt"> <!-- from Tamplin's data -->
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="few">n is 0 or n mod 100 in 2..10</pluralRule>
+ <pluralRule count="many">n mod 100 in 11..19</pluralRule>
+ </pluralRules>
+ <pluralRules locales="mk"> <!-- from Tamplin's data -->
+ <pluralRule count="one">n mod 10 is 1 and n is not 11</pluralRule>
+ </pluralRules>
+ <pluralRules locales="cy"> <!-- from http://www.saltcymru.org/wordpress/?p=99&lang=en -->
+ <pluralRule count="zero">n is 0</pluralRule>
+ <pluralRule count="one">n is 1</pluralRule>
+ <pluralRule count="two">n is 2</pluralRule>
+ <pluralRule count="few">n is 3</pluralRule>
+ <pluralRule count="many">n is 6</pluralRule>
+ </pluralRules>
+ <pluralRules locales="lag">
+ <pluralRule count="zero">n is 0</pluralRule>
+ <pluralRule count="one">n within 0..2 and n is not 0 and n is not 2</pluralRule>
+ </pluralRules>
+ <pluralRules locales="shi">
+ <pluralRule count="one">n within 0..1</pluralRule>
+ <pluralRule count="few">n in 2..10</pluralRule>
+ </pluralRules>
+ <pluralRules locales="br"> <!-- from http://unicode.org/cldr/trac/ticket/2886 -->
+ <pluralRule count="one">n mod 10 is 1 and n mod 100 not in 11,71,91</pluralRule>
+ <pluralRule count="two">n mod 10 is 2 and n mod 100 not in 12,72,92</pluralRule>
+ <pluralRule count="few">n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99</pluralRule>
+ <pluralRule count="many">n mod 1000000 is 0 and n is not 0</pluralRule>
+ </pluralRules>
+ <pluralRules locales="ksh">
+ <pluralRule count="zero">n is 0</pluralRule>
+ <pluralRule count="one">n is 1</pluralRule>
+ </pluralRules>
+ <pluralRules locales="tzm">
+ <pluralRule count="one">n in 0..1 or n in 11..99</pluralRule>
+ </pluralRules>
+ <pluralRules locales="gv">
+ <pluralRule count="one">n mod 10 in 1..2 or n mod 20 is 0</pluralRule>
+ </pluralRules>
+ <pluralRules locales="gd">
+ <pluralRule count="one">n in 1,11</pluralRule>
+ <pluralRule count="two">n in 2,12</pluralRule>
+ <pluralRule count="few">n in 3..10,13..19</pluralRule>
+ </pluralRules>
+ </plurals>
+</supplementalData>
--- /dev/null
+<?php
+/**
+ * Parse and evaluate a plural rule
+ *
+ * @author Niklas Laxstrom
+ *
+ * @copyright Copyright © 2010-2012, Niklas Laxström
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @file
+ */
+
+class CLDRPluralRuleEvaluator {
+ /**
+ * Evaluate a number against a set of plural rules. If a rule passes,
+ * return the index of plural rule.
+ *
+ * @param int The number to be evaluated against the rules
+ * @param array The associative array of plural rules in pluralform => rule format.
+ * @return int The index of the plural form which passed the evaluation
+ */
+ public static function evaluate( $number, $rules ) {
+ $formIndex = 0;
+ if ( !$rules ) {
+ return 0;
+ }
+ foreach ( $rules as $form => $rule ) {
+ $parsedRule = self::parseCLDRRule( $rule, $number );
+ // FIXME eval is bad.
+ if ( eval( "return $parsedRule;" ) ) {
+ return $formIndex;
+ }
+ $formIndex++;
+ }
+ return $formIndex;
+ }\r
+ private static function parseCLDRRule( $rule ) {
+ $rule = preg_replace( '/\bn\b/', '$number', $rule );
+ $rule = preg_replace( '/([^ ]+) mod (\d+)/', 'self::mod(\1,\2)', $rule );
+ $rule = preg_replace( '/([^ ]+) is not (\d+)/' , '\1!=\2', $rule );
+ $rule = preg_replace( '/([^ ]+) is (\d+)/', '\1==\2', $rule );
+ $rule = preg_replace( '/([^ ]+) not in (\d+)\.\.(\d+)/', '!self::in(\1,\2,\3)', $rule );
+ $rule = preg_replace( '/([^ ]+) not within (\d+)\.\.(\d+)/', '!self::within(\1,\2,\3)', $rule );
+ $rule = preg_replace( '/([^ ]+) in (\d+)\.\.(\d+)/', 'self::in(\1,\2,\3)', $rule );
+ $rule = preg_replace( '/([^ ]+) within (\d+)\.\.(\d+)/', 'self::within(\1,\2,\3)', $rule );
+ // AND takes precedence over OR
+ $andrule = '/([^ ]+) and ([^ ]+)/i';
+ while ( preg_match( $andrule, $rule ) ) {
+ $rule = preg_replace( $andrule, '(\1&&\2)', $rule );
+ }
+ $orrule = '/([^ ]+) or ([^ ]+)/i';
+ while ( preg_match( $orrule, $rule ) ) {
+ $rule = preg_replace( $orrule, '(\1||\2)', $rule );
+ }
+
+ return $rule;
+ }
+
+ private static function in( $num, $low, $high ) {
+ return is_int( $num ) && $num >= $low && $num <= $high;
+ }
+
+ private static function within( $num, $low, $high ) {
+ return $num >= $low && $num <= $high;
+ }
+
+ private static function mod( $num, $mod ) {
+ if ( is_int( $num ) ) {
+ return (int) fmod( $num, $mod );
+ }
+ return fmod( $num, $mod );
+ }
+}
/** @dataProvider providerPluralDual */
function testPluralDual( $result, $value ) {
- $forms = array( 'one', 'many', 'two' );
+ $forms = array( 'one', 'two', 'other' );
$this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) );
}
function providerPluralDual() {
return array (
- array( 'many', 0 ), // Zero -> plural
+ array( 'other', 0 ), // Zero -> plural
array( 'one', 1 ), // Singular
array( 'two', 2 ), // Dual
- array( 'many', 3 ), // Plural
+ array( 'other', 3 ), // Plural
);
}
/** @dataProvider providerPlural */
function testPlural( $result, $value ) {
- $forms = array( 'one', 'many' );
+ $forms = array( 'one', 'other' );
$this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) );
}
function providerPlural() {
return array (
- array( 'many', 0 ), // Zero -> plural
+ array( 'other', 0 ), // Zero -> plural
array( 'one', 1 ), // Singular
- array( 'many', 2 ), // Plural, no dual provided
- array( 'many', 3 ), // Plural
+ array( 'other', 2 ), // Plural, no dual provided
+ array( 'other', 3 ), // Plural
);
}
}