diff options
Diffstat (limited to 'maintenance/language')
-rw-r--r-- | maintenance/language/StatOutputs.php | 2 | ||||
-rw-r--r-- | maintenance/language/alltrans.php | 3 | ||||
-rw-r--r-- | maintenance/language/checkExtensions.php | 268 | ||||
-rw-r--r-- | maintenance/language/checkLanguage.inc | 476 | ||||
-rw-r--r-- | maintenance/language/checkLanguage.php | 306 | ||||
-rw-r--r-- | maintenance/language/date-formats.php | 4 | ||||
-rw-r--r-- | maintenance/language/diffLanguage.php | 3 | ||||
-rw-r--r-- | maintenance/language/digit2html.php | 5 | ||||
-rw-r--r-- | maintenance/language/dumpMessages.php | 3 | ||||
-rw-r--r-- | maintenance/language/function-list.php | 4 | ||||
-rw-r--r-- | maintenance/language/lang2po.php | 3 | ||||
-rw-r--r-- | maintenance/language/langmemusage.php | 3 | ||||
-rw-r--r-- | maintenance/language/languages.inc | 47 | ||||
-rw-r--r-- | maintenance/language/messageTypes.inc | 83 | ||||
-rw-r--r-- | maintenance/language/messages.inc | 430 | ||||
-rw-r--r-- | maintenance/language/rebuildLanguage.php | 23 | ||||
-rw-r--r-- | maintenance/language/transstat.php | 3 | ||||
-rw-r--r-- | maintenance/language/validate.php | 4 | ||||
-rw-r--r-- | maintenance/language/writeMessagesArray.inc | 50 |
19 files changed, 1012 insertions, 708 deletions
diff --git a/maintenance/language/StatOutputs.php b/maintenance/language/StatOutputs.php index 50829cbe..f65b263e 100644 --- a/maintenance/language/StatOutputs.php +++ b/maintenance/language/StatOutputs.php @@ -3,6 +3,8 @@ if (!defined('MEDIAWIKI')) die(); /** * Statistic output classes. * + * @file + * @ingroup MaintenanceLanguage * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com> * @author Ashar Voultoiz <thoane@altern.org> */ diff --git a/maintenance/language/alltrans.php b/maintenance/language/alltrans.php index 4adc2a66..67c870e6 100644 --- a/maintenance/language/alltrans.php +++ b/maintenance/language/alltrans.php @@ -1,6 +1,7 @@ <?php /** - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage * * Get all the translations messages, as defined in the English language file. */ diff --git a/maintenance/language/checkExtensions.php b/maintenance/language/checkExtensions.php index 1cfb0de8..ab6f9ba8 100644 --- a/maintenance/language/checkExtensions.php +++ b/maintenance/language/checkExtensions.php @@ -1,269 +1,25 @@ <?php /** - * Copyright (C) 2007 Ashar Voultoiz <hashar@altern.org> + * Check the extensions language files. * - * Based on dumpBackup: - * Copyright (C) 2005 Brion Vibber <brion@pobox.com> - * - * http://www.mediawiki.org - * - * 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 - * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ -# -# Lacking documentation. Examples: -# php checkExtensions.php /opt/mw/extensions/CentralAuth/CentralAuth.i18n.php wgCentralAuthMessages -# php checkExtensions.php --extdir /opt/mw/extensions/ -# -# BUGS: cant guess registered extensions :) -# TODO: let users set parameters to configure checklanguage.inc - -// Filename for the extension i18n files database: -define( 'EXT_I18N_DB', 'i18n.db' ); - -$optionsWithArgs = array( 'extdir', 'lang' ); - require_once( dirname(__FILE__).'/../commandLine.inc' ); require_once( 'languages.inc' ); require_once( 'checkLanguage.inc' ); - -class extensionLanguages extends languages { - private $mExt18nFilename, $mExtArrayName ; - private $mExtArray; - - function __construct( $ext18nFilename, $extArrayName ) { - $this->mExt18nFilename = $ext18nFilename; - $this->mExtArrayName = $extArrayName; - - $this->mIgnoredMessages = array(); - $this->mOptionalMessages = array(); - - if ( file_exists( $this->mExt18nFilename ) ) { - require_once( $this->mExt18nFilename ); - - $foundarray = false; - if( isset( ${$this->mExtArrayName} ) ) { - // File provided in the db file - $foundarray = ${$this->mExtArrayName}; - } else { - - /* For extensions included elsewhere. For some reason other extensions - * break with the global statement, so recheck here. - */ - global ${$this->mExtArrayName}; - if( is_array( ${$this->mExtArrayName} ) ) { - $foundarray = ${$this->mExtArrayName}; - } - - /* we might have been given a function name, test it too */ - if( function_exists( $this->mExtArrayName ) ) { - // Load data - $funcName = $this->mExtArrayName ; - $foundarray = $funcName(); - } - - if(!$foundarray) { - // Provided array could not be found we try to guess it. - - # Using the extension path ($m[1]) and filename ($m[2]): - $m = array(); - preg_match( '%.*/(.*)/(.*).i18n\.php%', $this->mExt18nFilename, $m); - $arPathCandidate = 'wg' . $m[1].'Messages'; - $arFileCandidate = 'wg' . $m[2].'Messages'; - $funcCandidate = "ef{$m[2]}Messages"; - - // Try them: - if( isset($$arPathCandidate) && is_array( $$arPathCandidate ) ) { - print "warning> messages from guessed path array \$$arPathCandidate.\n"; - $foundarray = $$arPathCandidate; - } elseif( isset($$arFileCandidate) && is_array( $$arFileCandidate ) ) { - print "warning> messages from guessed file array \$$arFileCandidate.\n"; - $foundarray = $$arFileCandidate; - } elseif( function_exists( $funcCandidate ) ) { - print "warning> messages build from guessed function {$funcCandidate}().\n"; - $foundarray = $funcCandidate(); - } - } - - # We are unlucky, return empty stuff - if(!$foundarray) { - print "ERROR> failed to guess an array to use.\n"; - $this->mExtArray = null; - $this->mLanguages = null; - return; - } - } - - $this->mExtArray = $foundarray ; - $this->mLanguages = array_keys( $this->mExtArray ); - } else { - wfDie( "File $this->mExt18nFilename not found\n" ); - } - } - - protected function loadRawMessages( $code ) { - if ( isset( $this->mRawMessages[$code] ) ) { - return; - } - if( isset( $this->mExtArray[$code] ) ) { - $this->mRawMessages[$code] = $this->mExtArray[$code] ; - } else { - $this->mRawMessages[$code] = array(); - } - } - - public function getLanguages() { - return $this->mLanguages; - } -} - -/** - * @param $filename Filename containing the extension i18n - * @param $arrayname The name of the array in the filename - * @param $filter Optional, restrict check to a given language code (default; null) - */ -function checkExtensionLanguage( $filename, $arrayname, $filter = null ) { - $extLanguages = new extensionLanguages($filename, $arrayname); - - $langs = $extLanguages->getLanguages(); - if( !$langs ) { - print "ERROR> \$$arrayname array does not exist.\n"; - return false; - } - - $nErrors = 0; - if( $filter ) { - $nErrors += checkLanguage( $extLanguages, $filter ); - } else { - print "Will check ". count($langs) . " languages : " . implode(' ', $langs) .".\n"; - foreach( $langs as $lang ) { - if( $lang == 'en' ) { - #print "Skipped english language\n"; - continue; - } - - $nErrors += checkLanguage( $extLanguages, $lang ); - } - } - - return $nErrors; -} - -/** - * Read the db file, parse it, start the check. - */ -function checkExtensionRepository( $extdir, $db ) { - $fh = fopen( $extdir. '/' . $db, 'r' ); - - $line_number = 0; - while( $line = fgets( $fh ) ) { - $line_number++; - - // Ignore comments - if( preg_match( '/^#/', $line ) ) { - continue; - } - - // Load data from i18n database - $data = split( ' ', chop($line) ); - $i18n_file = @$data[0]; - $arrayname = @$data[1]; - - print "------------------------------------------------------\n"; - print "Checking $i18n_file (\$$arrayname).\n"; - - // Check data - if( !file_exists( $extdir . '/' . $i18n_file ) ) { - print "ERROR> $i18n_file not found ($db:$line_number).\n"; - continue; - } -# if( $arrayname == '' ) { -# print "warning> no array name for $i18n_file ($db:$line_number).\n"; -# } - - $i18n_file = $extdir . '/' . $i18n_file ; - - global $myLang; - $nErrors = checkExtensionLanguage( $i18n_file, $arrayname, $myLang ); - if($nErrors == 1 ) { - print "\nFound $nErrors error for this extension.\n"; - } elseif($nErrors) { - print "\nFound $nErrors errors for this extension.\n"; - } else { - print "Looks OK.\n"; - } - - print "\n"; - } -} - - -function usage() { -// Usage -print <<<END -Usage: - php checkExtensions.php <filename> <arrayname> - php checkExtensions.php --extdir <extension repository> - -Common option: - --lang <language code> : only check the given language. - +if( !class_exists( 'MessageGroups' ) || !class_exists( 'PremadeMediawikiExtensionGroups' ) ) { + echo <<<END +Please add the Translate extension to LocalSettings.php, and enable the extension groups: + require_once( 'extensions/Translate/Translate.php' ); + \$wgTranslateEC = array_keys( \$wgTranslateAC ); +If you still get this message, update Translate to its latest version. END; -die; -} - -// Play with options and arguments -$myLang = isset($options['lang']) ? $options['lang'] : null; - -if( isset( $options['extdir'] ) ) { - $extdb = $options['extdir'] . '/' . EXT_I18N_DB ; - - if( file_exists( $extdb ) ) { - checkExtensionRepository( $options['extdir'], EXT_I18N_DB ); - } else { - print "$extdb does not exist\n"; - } - -} else { - // Check arguments - if ( isset( $argv[0] ) ) { - - if (file_exists( $argv[0] ) ) { - $filename = $argv[0]; - } else { - print "Unable to open file '{$argv[0]}'\n"; - usage(); - } - - if ( isset( $argv[1] ) ) { - $arrayname = $argv[1]; - } else { - print "You must give an array name to be checked\n"; - usage(); - } - - global $myLang; - checkExtensionLanguage( $filename, $arrayname, $myLang ); - } else { - usage(); - } + exit(-1); } - +$cli = new CheckExtensionsCLI( $options, $argv[0] ); +$cli->execute(); diff --git a/maintenance/language/checkLanguage.inc b/maintenance/language/checkLanguage.inc index 51de8014..2cfd1b04 100644 --- a/maintenance/language/checkLanguage.inc +++ b/maintenance/language/checkLanguage.inc @@ -1,15 +1,491 @@ <?php +/** + * @ingroup MaintenanceLanguage + */ + +class CheckLanguageCLI { + protected $code = null; + protected $level = 2; + protected $doLinks = false; + protected $wikiCode = 'en'; + protected $checkAll = false; + protected $output = 'plain'; + protected $checks = array(); + protected $L = null; + + protected $defaultChecks = array( + 'untranslated', 'obsolete', 'variables', 'empty', 'plural', + 'whitespace', 'xhtml', 'chars', 'links', 'unbalanced' + ); + + protected $results = array(); + + private $includeExif = false; + + /** + * GLOBALS: $wgLanguageCode; + */ + public function __construct( Array $options ) { + + if ( isset( $options['help'] ) ) { + echo $this->help(); + exit(); + } + + if ( isset($options['lang']) ) { + $this->code = $options['lang']; + } else { + global $wgLanguageCode; + $this->code = $wgLanguageCode; + } + + if ( isset($options['level']) ) { + $this->level = $options['level']; + } + + $this->doLinks = isset($options['links']); + $this->includeExif = !isset($options['noexif']); + $this->checkAll = isset($options['all']); + + if ( isset($options['wikilang']) ) { + $this->wikiCode = $options['wikilang']; + } + + if ( isset( $options['whitelist'] ) ) { + $this->checks = explode( ',', $options['whitelist'] ); + } elseif ( isset( $options['blacklist'] ) ) { + $this->checks = array_diff( + $this->defaultChecks, + explode( ',', $options['blacklist'] ) + ); + } else { + $this->checks = $this->defaultChecks; + } + + if ( isset($options['output']) ) { + $this->output = $options['output']; + } + + # Some additional checks not enabled by default + if ( isset( $options['duplicate'] ) ) { + $this->checks[] = 'duplicate'; + } + + $this->L = new languages( $this->includeExif ); + } + + protected function getChecks() { + $checks = array(); + $checks['untranslated'] = 'getUntranslatedMessages'; + $checks['duplicate'] = 'getDuplicateMessages'; + $checks['obsolete'] = 'getObsoleteMessages'; + $checks['variables'] = 'getMessagesWithoutVariables'; + $checks['plural'] = 'getMessagesWithoutPlural'; + $checks['empty'] = 'getEmptyMessages'; + $checks['whitespace'] = 'getMessagesWithWhitespace'; + $checks['xhtml'] = 'getNonXHTMLMessages'; + $checks['chars'] = 'getMessagesWithWrongChars'; + $checks['links'] = 'getMessagesWithDubiousLinks'; + $checks['unbalanced'] = 'getMessagesWithUnbalanced'; + return $checks; + } + + protected function getDescriptions() { + $descriptions = array(); + $descriptions['untranslated'] = '$1 message(s) of $2 are not translated to $3, but exist in en:'; + $descriptions['duplicate'] = '$1 message(s) of $2 are translated the same in en and $3:'; + $descriptions['obsolete'] = '$1 message(s) of $2 do not exist in en or are in the ignore list, but are in $3'; + $descriptions['variables'] = '$1 message(s) of $2 in $3 don\'t use some variables that en uses:'; + $descriptions['plural'] = '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:'; + $descriptions['empty'] = '$1 message(s) of $2 in $3 are empty or -:'; + $descriptions['whitespace'] = '$1 message(s) of $2 in $3 have trailing whitespace:'; + $descriptions['xhtml'] = '$1 message(s) of $2 in $3 contain illegal XHTML:'; + $descriptions['chars'] = '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:'; + $descriptions['links'] = '$1 message(s) of $2 in $3 have problematic link(s):'; + $descriptions['unbalanced'] = '$1 message(s) of $2 in $3 have unbalanced {[]}:'; + return $descriptions; + } + + protected function help() { + return <<<ENDS +Run this script to check a specific language file, or all of them. +Command line settings are in form --parameter[=value]. +Parameters: + * lang: Language code (default: the installation default language). + * all: Check all customized languages. + * help: Show this help. + * level: Show the following level (default: 2). + * links: Link the message values (default off). + * wikilang: For the links, what is the content language of the wiki to display the output in (default en). + * whitelist: Do only the following checks (form: code,code). + * blacklist: Don't do the following checks (form: code,code). + * duplicate: Additionally check for messages which are translated the same to English (default off). + * noexif: Don't check for EXIF messages (a bit hard and boring to translate), if you know that they are currently not translated and want to focus on other problems (default off). +Check codes (ideally, all of them should result 0; all the checks are executed by default (except duplicate and language specific check blacklists in checkLanguage.inc): + * untranslated: Messages which are required to translate, but are not translated. + * duplicate: Messages which translation equal to fallback + * obsolete: Messages which are untranslatable, but translated. + * variables: Messages without variables which should be used. + * empty: Empty messages. + * whitespace: Messages which have trailing whitespace. + * xhtml: Messages which are not well-formed XHTML (checks only few common errors). + * chars: Messages with hidden characters. + * links: Messages which contains broken links to pages (does not find all). + * unbalanced: Messages which contains unequal numbers of opening {[ and closing ]}. +Display levels (default: 2): + * 0: Skip the checks (useful for checking syntax). + * 1: Show only the stub headers and number of wrong messages, without list of messages. + * 2: Show only the headers and the message keys, without the message values. + * 3: Show both the headers and the complete messages, with both keys and values. + +ENDS; + } + + public function execute() { + $this->doChecks(); + if ( $this->level > 0 ) { + switch ($this->output) { + case 'plain': + $this->outputText(); + break; + case 'wiki': + $this->outputWiki(); + break; + default: + throw new MWException( "Invalid output type $this->output"); + } + } + } + + protected function doChecks() { + $ignoredCodes = array( 'en', 'enRTL' ); + + $this->results = array(); + # Check the language + if ( $this->checkAll ) { + foreach ( $this->L->getLanguages() as $language ) { + if ( !in_array($language, $ignoredCodes) ) { + $this->results[$language] = $this->checkLanguage( $language ); + } + } + } else { + if ( in_array($this->code, $ignoredCodes) ) { + throw new MWException("Cannot check code $this->code."); + } else { + $this->results[$this->code] = $this->checkLanguage( $this->code ); + } + } + } + + protected function getCheckBlacklist() { + global $checkBlacklist; + return $checkBlacklist; + } + + protected function checkLanguage( $code ) { + # Syntax check only + if ( $this->level === 0 ) { + $this->L->getMessages( $code ); + return; + } + + $results = array(); + $checkFunctions = $this->getChecks(); + $checkBlacklist = $this->getCheckBlacklist(); + foreach ( $this->checks as $check ) { + if ( isset($checkBlacklist[$code]) && + in_array($check, $checkBlacklist[$code]) ) { + $result[$check] = array(); + continue; + } + + $callback = array( $this->L, $checkFunctions[$check] ); + if ( !is_callable($callback ) ) { + throw new MWException( "Unkown check $check." ); + } + $results[$check] = call_user_func( $callback , $code ); + } + + return $results; + } + + protected function formatKey( $key, $code ) { + if ( $this->doLinks ) { + $displayKey = ucfirst( $key ); + if ( $code == $this->wikiCode ) { + return "[[MediaWiki:$displayKey|$key]]"; + } else { + return "[[MediaWiki:$displayKey/$code|$key]]"; + } + } else { + return $key; + } + } + + protected function outputText() { + foreach ( $this->results as $code => $results ) { + $translated = $this->L->getMessages( $code ); + $translated = count( $translated['translated'] ); + $translatable = $this->L->getGeneralMessages(); + $translatable = count( $translatable['translatable'] ); + foreach ( $results as $check => $messages ) { + $count = count( $messages ); + if ( $count ) { + $search = array( '$1', '$2', '$3' ); + $replace = array( $count, $check == 'untranslated' ? $translatable: $translated, $code ); + $descriptions = $this->getDescriptions(); + echo "\n" . str_replace( $search, $replace, $descriptions[$check] ) . "\n"; + if ( $this->level == 1 ) { + echo "[messages are hidden]\n"; + } else { + foreach ( $messages as $key => $value ) { + $displayKey = $this->formatKey( $key, $code ); + if ( $this->level == 2 ) { + echo "* $displayKey\n"; + } else { + echo "* $displayKey: '$value'\n"; + } + } + } + } + } + } + } + + /** + * Globals: $wgContLang, $IP + */ + function outputWiki() { + global $wgContLang, $IP; + $detailText = ''; + $rows[] = '! Language !! Code !! Total !! ' . implode( ' !! ', $this->checks ); + foreach ( $this->results as $code => $results ) { + $detailTextForLang = "==$code==\n"; + $numbers = array(); + $problems = 0; + $detailTextForLangChecks = array(); + foreach ( $results as $check => $messages ) { + $count = count( $messages ); + if ( $count ) { + $problems += $count; + $messageDetails = array(); + foreach ( $messages as $key => $details ) { + $displayKey = $this->formatKey( $key, $code ); + $messageDetails[] = $displayKey; + } + $detailTextForLangChecks[] = "===$code-$check===\n* " . implode( ', ', $messageDetails ); + $numbers[] = "'''[[#$code-$check|$count]]'''"; + } else { + $numbers[] = $count; + } + + } + + if ( count( $detailTextForLangChecks ) ) { + $detailText .= $detailTextForLang . implode( "\n", $detailTextForLangChecks ) . "\n"; + } + + if ( !$problems ) { continue; } // Don't list languages without problems + $language = $wgContLang->getLanguageName( $code ); + $rows[] = "| $language || $code || $problems || " . implode( ' || ', $numbers ); + } + + $tableRows = implode( "\n|-\n", $rows ); + + $version = SpecialVersion::getVersion( $IP ); + echo <<<EOL +'''Check results are for:''' <code>$version</code> + + +{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear:both;" +$tableRows +|} + +$detailText + +EOL; + } + + protected function isEmpty() { + $empty = true; + foreach( $this->results as $code => $results ) { + foreach( $results as $check => $messages ) { + if( !empty( $messages ) ) { + $empty = false; + break; + } + } + if( !$empty ) { + break; + } + } + return $empty; + } +} + +class CheckExtensionsCLI extends CheckLanguageCLI { + private $extensions; + + public function __construct( Array $options, $extension ) { + if ( isset( $options['help'] ) ) { + echo $this->help(); + exit(); + } + + if ( isset($options['lang']) ) { + $this->code = $options['lang']; + } else { + global $wgLanguageCode; + $this->code = $wgLanguageCode; + } + + if ( isset($options['level']) ) { + $this->level = $options['level']; + } + + $this->doLinks = isset($options['links']); + + if ( isset($options['wikilang']) ) { + $this->wikiCode = $options['wikilang']; + } + + if ( isset( $options['whitelist'] ) ) { + $this->checks = explode( ',', $options['whitelist'] ); + } elseif ( isset( $options['blacklist'] ) ) { + $this->checks = array_diff( + $this->defaultChecks, + explode( ',', $options['blacklist'] ) + ); + } else { + $this->checks = $this->defaultChecks; + } + + if ( isset($options['output']) ) { + $this->output = $options['output']; + } + + # Some additional checks not enabled by default + if ( isset( $options['duplicate'] ) ) { + $this->checks[] = 'duplicate'; + } + + $this->extensions = array(); + $extensions = new PremadeMediawikiExtensionGroups(); + $extensions->addAll(); + if( $extension == 'all' ) { + foreach( MessageGroups::singleton()->getGroups() as $group ) { + if( strpos( $group->getId(), 'ext-' ) === 0 && !$group->isMeta() ) { + $this->extensions[] = new extensionLanguages( $group ); + } + } + } elseif( $extension == 'wikimedia' ) { + $wikimedia = MessageGroups::getGroup( 'ext-0-wikimedia' ); + foreach( $wikimedia->wmfextensions() as $extension ) { + $group = MessageGroups::getGroup( $extension ); + $this->extensions[] = new extensionLanguages( $group ); + } + } else { + $extensions = explode( ',', $extension ); + foreach( $extensions as $extension ) { + $group = MessageGroups::getGroup( 'ext-' . $extension ); + if( $group ) { + $extension = new extensionLanguages( $group ); + $this->extensions[] = $extension; + } else { + print "No such extension $extension.\n"; + } + } + } + } + + protected function help() { + return <<<ENDS +Run this script to check the status of a specific language in extensions, or all of them. +Command line settings are in form --parameter[=value], except for the first one. +Parameters: + * First parameter (mandatory): Extension name, multiple extension names (separated by commas), "all" for all the extensions or "wikimedia" for extensions used by Wikimedia. + * lang: Language code (default: the installation default language). + * help: Show this help. + * level: Show the following level (default: 2). + * links: Link the message values (default off). + * wikilang: For the links, what is the content language of the wiki to display the output in (default en). + * whitelist: Do only the following checks (form: code,code). + * blacklist: Do not perform the following checks (form: code,code). + * duplicate: Additionally check for messages which are translated the same to English (default off). +Check codes (ideally, all of them should result 0; all the checks are executed by default (except duplicate and language specific check blacklists in checkLanguage.inc): + * untranslated: Messages which are required to translate, but are not translated. + * duplicate: Messages which translation equal to fallback + * obsolete: Messages which are untranslatable, but translated. + * variables: Messages without variables which should be used. + * empty: Empty messages. + * whitespace: Messages which have trailing whitespace. + * xhtml: Messages which are not well-formed XHTML (checks only few common errors). + * chars: Messages with hidden characters. + * links: Messages which contains broken links to pages (does not find all). + * unbalanced: Messages which contains unequal numbers of opening {[ and closing ]}. +Display levels (default: 2): + * 0: Skip the checks (useful for checking syntax). + * 1: Show only the stub headers and number of wrong messages, without list of messages. + * 2: Show only the headers and the message keys, without the message values. + * 3: Show both the headers and the complete messages, with both keys and values. + +ENDS; + } + + public function execute() { + $this->doChecks(); + } + + protected function checkLanguage( $code ) { + foreach( $this->extensions as $extension ) { + $this->L = $extension; + $this->results = array(); + $this->results[$code] = parent::checkLanguage( $code ); + + if( !$this->isEmpty() ) { + echo $extension->name() . ":\n"; + + if( $this->level > 0 ) { + switch( $this->output ) { + case 'plain': + $this->outputText(); + break; + case 'wiki': + $this->outputWiki(); + break; + default: + throw new MWException( "Invalid output type $this->output" ); + } + } + + echo "\n"; + } + } + } +} # Blacklist some checks for some languages $checkBlacklist = array( #'code' => array( 'check1', 'check2' ... ) 'gan' => array( 'plural' ), +'gn' => array( 'plural' ), 'hak' => array( 'plural' ), +'hu' => array( 'plural' ), 'ja' => array( 'plural' ), // Does not use plural +'ka' => array( 'plural' ), +'kk-arab' => array( 'plural' ), +'kk-cyrl' => array( 'plural' ), +'kk-latn' => array( 'plural' ), +'ko' => array( 'plural' ), +'mn' => array( 'plural' ), +'ms' => array( 'plural' ), 'my' => array( 'chars' ), // Uses a lot zwnj +'sah' => array( 'plural' ), +'sq' => array( 'plural' ), 'tet' => array( 'plural' ), 'th' => array( 'plural' ), 'wuu' => array( 'plural' ), +'xmf' => array( 'plural' ), 'yue' => array( 'plural' ), 'zh' => array( 'plural' ), 'zh-classical' => array( 'plural' ), diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php index 36d32a48..f8553a1e 100644 --- a/maintenance/language/checkLanguage.php +++ b/maintenance/language/checkLanguage.php @@ -2,313 +2,13 @@ /** * Check a language file. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ require_once( dirname(__FILE__).'/../commandLine.inc' ); +require_once( 'checkLanguage.inc' ); require_once( 'languages.inc' ); $cli = new CheckLanguageCLI( $options ); $cli->execute(); - -class CheckLanguageCLI { - private $code = null; - private $level = 2; - private $doLinks = false; - private $wikiCode = 'en'; - private $includeExif = false; - private $checkAll = false; - private $output = 'plain'; - private $checks = array(); - - private $defaultChecks = array( - 'untranslated', 'obsolete', 'variables', 'empty', 'plural', - 'whitespace', 'xhtml', 'chars', 'links', 'unbalanced' - ); - - private $L = null; - - /** - * GLOBALS: $wgLanguageCode; - */ - public function __construct( Array $options ) { - - if ( isset( $options['help'] ) ) { - echo $this->help(); - exit(); - } - - if ( isset($options['lang']) ) { - $this->code = $options['lang']; - } else { - global $wgLanguageCode; - $this->code = $wgLanguageCode; - } - - if ( isset($options['level']) ) { - $this->level = $options['level']; - } - - $this->doLinks = isset($options['links']); - $this->includeExif = !isset($options['noexif']); - $this->checkAll = isset($options['all']); - - if ( isset($options['wikilang']) ) { - $this->wikiCode = $options['wikilang']; - } - - if ( isset( $options['whitelist'] ) ) { - $this->checks = explode( ',', $options['whitelist'] ); - } elseif ( isset( $options['blacklist'] ) ) { - $this->checks = array_diff( - $this->defaultChecks, - explode( ',', $options['blacklist'] ) - ); - } else { - $this->checks = $this->defaultChecks; - } - - if ( isset($options['output']) ) { - $this->output = $options['output']; - } - - # Some additional checks not enabled by default - if ( isset( $options['duplicate'] ) ) { - $this->checks[] = 'duplicate'; - } - - $this->L = new languages( $this->includeExif ); - } - - protected function getChecks() { - $checks = array(); - $checks['untranslated'] = 'getUntranslatedMessages'; - $checks['duplicate'] = 'getDuplicateMessages'; - $checks['obsolete'] = 'getObsoleteMessages'; - $checks['variables'] = 'getMessagesWithoutVariables'; - $checks['plural'] = 'getMessagesWithoutPlural'; - $checks['empty'] = 'getEmptyMessages'; - $checks['whitespace'] = 'getMessagesWithWhitespace'; - $checks['xhtml'] = 'getNonXHTMLMessages'; - $checks['chars'] = 'getMessagesWithWrongChars'; - $checks['links'] = 'getMessagesWithDubiousLinks'; - $checks['unbalanced'] = 'getMessagesWithUnbalanced'; - return $checks; - } - - protected function getDescriptions() { - $descriptions = array(); - $descriptions['untranslated'] = '$1 message(s) of $2 are not translated to $3, but exist in en:'; - $descriptions['duplicate'] = '$1 message(s) of $2 are translated the same in en and $3:'; - $descriptions['obsolete'] = '$1 message(s) of $2 do not exist in en or are in the ignore list, but are in $3'; - $descriptions['variables'] = '$1 message(s) of $2 in $3 don\'t use some variables that en uses:'; - $descriptions['plural'] = '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:'; - $descriptions['empty'] = '$1 message(s) of $2 in $3 are empty or -:'; - $descriptions['whitespace'] = '$1 message(s) of $2 in $3 have trailing whitespace:'; - $descriptions['xhtml'] = '$1 message(s) of $2 in $3 contain illegal XHTML:'; - $descriptions['chars'] = '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:'; - $descriptions['links'] = '$1 message(s) of $2 in $3 have problematic link(s):'; - $descriptions['unbalanced'] = '$1 message(s) of $2 in $3 have unbalanced {[]}:'; - return $descriptions; - } - - protected function help() { - return <<<ENDS -Run this script to check a specific language file, or all of them. -Command line settings are in form --parameter[=value]. -Parameters: - * lang: Language code (default: the installation default language). - * all: Check all customized languages - * help: Show this help. - * level: Show the following level (default: 2). - * links: Link the message values (default off). - * wikilang: For the links, what is the content language of the wiki to display the output in (default en). - * whitelist: Do only the following checks (form: code,code). - * blacklist: Don't do the following checks (form: code,code). - * duplicate: Additionally check for messages which are translated the same to English (default off). - * noexif: Don't check for EXIF messages (a bit hard and boring to translate), if you know that they are currently not translated and want to focus on other problems (default off). -Check codes (ideally, all of them should result 0; all the checks are executed by default (except duplicate and language specific check blacklists in checkLanguage.inc): - * untranslated: Messages which are required to translate, but are not translated. - * duplicate: Messages which translation equal to fallback - * obsolete: Messages which are untranslatable, but translated. - * variables: Messages without variables which should be used. - * empty: Empty messages. - * whitespace: Messages which have trailing whitespace. - * xhtml: Messages which are not well-formed XHTML (checks only few common errors). - * chars: Messages with hidden characters. - * links: Messages which contains broken links to pages (does not find all). - * unbalanced: Messages which contains unequal numbers of opening {[ and closing ]}. -Display levels (default: 2): - * 0: Skip the checks (useful for checking syntax). - * 1: Show only the stub headers and number of wrong messages, without list of messages. - * 2: Show only the headers and the message keys, without the message values. - * 3: Show both the headers and the complete messages, with both keys and values. - -ENDS; - } - - private $results = array(); - - public function execute() { - $this->doChecks(); - if ( $this->level > 0 ) { - switch ($this->output) { - case 'plain': - $this->outputText(); - break; - case 'wiki': - $this->outputWiki(); - break; - default: - throw new MWException( "Invalid output type $this->output"); - } - } - } - - protected function doChecks() { - $ignoredCodes = array( 'en', 'enRTL' ); - - $this->results = array(); - # Check the language - if ( $this->checkAll ) { - foreach ( $this->L->getLanguages() as $language ) { - if ( !in_array($language, $ignoredCodes) ) { - $this->results[$language] = $this->checkLanguage( $language ); - } - } - } else { - if ( in_array($this->code, $ignoredCodes) ) { - throw new MWException("Cannot check code $this->code."); - } else { - $this->results[$this->code] = $this->checkLanguage( $this->code ); - } - } - } - - protected function getCheckBlacklist() { - static $checkBlacklist = null; - if ( $checkBlacklist === null ) { - $checkBlacklist = array(); - require( dirname(__FILE__) . '/checkLanguage.inc' ); - } - return $checkBlacklist; - } - - protected function checkLanguage( $code ) { - # Syntax check only - if ( $this->level === 0 ) { - $this->L->getMessages( $code ); - return; - } - - $results = array(); - $checkFunctions = $this->getChecks(); - $checkBlacklist = $this->getCheckBlacklist(); - foreach ( $this->checks as $check ) { - if ( isset($checkBlacklist[$code]) && - in_array($check, $checkBlacklist[$code]) ) { - $result[$check] = array(); - continue; - } - - $callback = array( $this->L, $checkFunctions[$check] ); - if ( !is_callable($callback ) ) { - throw new MWException( "Unkown check $check." ); - } - $results[$check] = call_user_func( $callback , $code ); - } - - return $results; - } - - protected function outputText( ) { - foreach ( $this->results as $code => $results ) { - $translated = $this->L->getMessages( $code ); - $translated = count( $translated['translated'] ); - foreach ( $results as $check => $messages ) { - $count = count( $messages ); - if ( $count ) { - $search = array( '$1', '$2', '$3' ); - $replace = array( $count, $translated, $code ); - $descriptions = $this->getDescriptions(); - echo "\n" . str_replace( $search, $replace, $descriptions[$check] ) . "\n"; - if ( $this->level == 1 ) { - echo "[messages are hidden]\n"; - } else { - foreach ( $messages as $key => $value ) { - if ( $this->doLinks ) { - $displayKey = ucfirst( $key ); - if ( $code == $this->wikiCode ) { - $displayKey = "[[MediaWiki:$displayKey|$key]]"; - } else { - $displayKey = "[[MediaWiki:$displayKey/$code|$key]]"; - } - } else { - $displayKey = $key; - } - if ( $this->level == 2 ) { - echo "* $displayKey\n"; - } else { - echo "* $displayKey: '$value'\n"; - } - } - } - } - } - } - } - - /** - * Globals: $wgContLang, $IP - */ - function outputWiki() { - global $wgContLang, $IP; - $detailText = ''; - $rows[] = '! Language !! Code !! Total !! ' . implode( ' !! ', $this->checks ); - foreach ( $this->results as $code => $results ) { - $detailTextForLang = "==$code==\n"; - $numbers = array(); - $problems = 0; - $detailTextForLangChecks = array(); - foreach ( $results as $check => $messages ) { - $count = count( $messages ); - if ( $count ) { - $problems += $count; - $messageDetails = array(); - foreach ( $messages as $key => $details ) { - $messageDetails[] = $key; - } - $detailTextForLangChecks[] = "===$code-$check===\n* " . implode( ', ', $messageDetails ); - $numbers[] = "'''[[#$code-$check|$count]]'''"; - } else { - $numbers[] = $count; - } - - } - - if ( count( $detailTextForLangChecks ) ) { - $detailText .= $detailTextForLang . implode( "\n", $detailTextForLangChecks ) . "\n"; - } - - if ( !$problems ) { continue; } // Don't list languages without problems - $language = $wgContLang->getLanguageName( $code ); - $rows[] = "| $language || $code || $problems || " . implode( ' || ', $numbers ); - } - - $tableRows = implode( "\n|-\n", $rows ); - - $version = SpecialVersion::getVersion( $IP ); - echo <<<EOL -'''Check results are for:''' <code>$version</code> - - -{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear:both;" -$tableRows -|} - -$detailText - -EOL; - } - -} diff --git a/maintenance/language/date-formats.php b/maintenance/language/date-formats.php index 1efa84b5..834d2bd8 100644 --- a/maintenance/language/date-formats.php +++ b/maintenance/language/date-formats.php @@ -1,4 +1,8 @@ <?php +/** + * @file + * @ingroup MaintenanceLanguage + */ $ts = '20010115123456'; diff --git a/maintenance/language/diffLanguage.php b/maintenance/language/diffLanguage.php index 05a6e4b1..389b01d5 100644 --- a/maintenance/language/diffLanguage.php +++ b/maintenance/language/diffLanguage.php @@ -35,7 +35,8 @@ * percentage of messages correctly localised and the number of messages to be * translated. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ /** This script run from the commandline */ diff --git a/maintenance/language/digit2html.php b/maintenance/language/digit2html.php index 3b690461..b020d812 100644 --- a/maintenance/language/digit2html.php +++ b/maintenance/language/digit2html.php @@ -1,4 +1,9 @@ <?php +/** + * @file + * @ingroup MaintenanceLanguage + */ + require( '../commandLine.inc' ); # A list of unicode numerals is available at: diff --git a/maintenance/language/dumpMessages.php b/maintenance/language/dumpMessages.php index e57bfeec..5669e58c 100644 --- a/maintenance/language/dumpMessages.php +++ b/maintenance/language/dumpMessages.php @@ -1,7 +1,8 @@ <?php /** * @todo document - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ /** */ diff --git a/maintenance/language/function-list.php b/maintenance/language/function-list.php index 67bcab03..f0c398a6 100644 --- a/maintenance/language/function-list.php +++ b/maintenance/language/function-list.php @@ -1,4 +1,8 @@ <?php +/** + * @file + * @ingroup MaintenanceLanguage + */ define( 'MEDIAWIKI', 1 ); define( 'NOT_REALLY_MEDIAWIKI', 1 ); diff --git a/maintenance/language/lang2po.php b/maintenance/language/lang2po.php index a5aa81aa..1009ed6c 100644 --- a/maintenance/language/lang2po.php +++ b/maintenance/language/lang2po.php @@ -5,6 +5,9 @@ * Todo: * - generate .po header * - fix escaping of \ + * + * @file + * @ingroup MaintenanceLanguage */ $optionsWithArgs[] = 'lang'; diff --git a/maintenance/language/langmemusage.php b/maintenance/language/langmemusage.php index 929976d3..9bfb3cdc 100644 --- a/maintenance/language/langmemusage.php +++ b/maintenance/language/langmemusage.php @@ -2,6 +2,9 @@ /** * Dumb program that tries to get the memory usage * for each language file. + * + * @file + * @ingroup MaintenanceLanguage */ /** This is a command line script */ diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc index 9472e254..6d16f80c 100644 --- a/maintenance/language/languages.inc +++ b/maintenance/language/languages.inc @@ -2,9 +2,13 @@ /** * Handle messages in the language files. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ +/** + * @ingroup MaintenanceLanguage + */ class languages { protected $mLanguages; # List of languages protected $mRawMessages; # Raw list of the messages in each language @@ -322,6 +326,8 @@ class languages { '<br *\\?>', '<hr/>', '<br/>', + '<hr>', + '<br>', ); $wrongPhrases = '~(' . implode( '|', $wrongPhrases ) . ')~sDu'; $nonXHTMLMessages = array(); @@ -418,4 +424,41 @@ class languages { } -?> +class extensionLanguages extends languages { + private $mMessageGroup; # The message group + + /** + * Load the messages group. + * @param $group The messages group. + */ + function __construct( MessageGroup $group ) { + $this->mMessageGroup = $group; + + $bools = $this->mMessageGroup->getBools(); + $this->mIgnoredMessages = $bools['ignored']; + $this->mOptionalMessages = $bools['optional']; + } + + /** + * Get the extension name. + * + * @return The extension name. + */ + public function name() { + return $this->mMessageGroup->getLabel(); + } + + /** + * Load the raw messages for a specific language. + * + * @param $code The language code. + */ + protected function loadRawMessages( $code ) { + if( !isset( $this->mRawMessages[$code] ) ) { + $this->mRawMessages[$code] = $this->mMessageGroup->load( $code ); + if( empty( $this->mRawMessages[$code] ) ) { + $this->mRawMessages[$code] = array(); + } + } + } +} diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 43ca41c2..67caaddd 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -2,10 +2,11 @@ /** * Several types of messages. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ -/** Ignored messages, which should be exist only in the English messages file. */ +/** Ignored messages, which should exist only in the English messages file. */ $wgIgnoredMessages = array( 'sidebar', 'accesskey-pt-userpage', @@ -39,7 +40,6 @@ $wgIgnoredMessages = array( 'accesskey-n-recentchanges', 'accesskey-n-randompage', 'accesskey-n-help', - 'accesskey-n-sitesupport', 'accesskey-t-whatlinkshere', 'accesskey-t-recentchangeslinked', 'accesskey-feed-rss', @@ -70,8 +70,8 @@ $wgIgnoredMessages = array( 'addsection', 'anonnotice', 'autoblock_whitelist', - 'catseparator', 'googlesearch', + 'opensearch-desc', 'exif-make-value', 'exif-model-value', 'exif-software-value', @@ -87,10 +87,10 @@ $wgIgnoredMessages = array( 'noarticletextanon', 'number_of_watching_users_RCview', 'pagecategorieslink', - 'patrol-log-header', 'pubmedurl', 'randompage-url', 'recentchanges-url', + 'cantcreateaccount-nonblock-text', 'revision-info-current', 'revision-nav', 'rfcurl', @@ -107,19 +107,12 @@ $wgIgnoredMessages = array( 'talkpagetext', 'trackback', 'trackbackexcerpt', -); - -/** Optional messages, which may be translated only if changed in the other language. */ -$wgOptionalMessages = array( - 'imgmultigotopost', - 'linkprefix', - 'editsection-brackets', - 'feed-atom', - 'feed-rss', - 'sectionlink', - 'unit-pixel', + 'uploadfooter', + 'listgrouprights-link', + 'search-interwiki-custom', 'allpages-summary', 'booksources-summary', + 'categories-summary', 'ipblocklist-summary', 'protectedtitles-summary', 'listusers-summary', @@ -127,8 +120,6 @@ $wgOptionalMessages = array( 'preferences-summary', 'specialpages-summary', 'whatlinkshere-summary', - 'whatlinkshere-barrow', - 'imagelist-summary', 'listredirects-summary', 'uncategorizedpages-summary', 'uncategorizedcategories-summary', @@ -147,7 +138,6 @@ $wgOptionalMessages = array( 'shortpages-summary', 'newpages-summary', 'ancientpages-summary', - 'newimages-summary', 'unwatchedpages-summary', 'userrights-summary', 'brokenredirects-summary', @@ -158,8 +148,19 @@ $wgOptionalMessages = array( 'lonelypages-summary', 'unusedtemplates-summary', 'fewestrevisions-summary', - 'withoutinterwiki-summary', + 'missingfiles-summary', 'upload-summary', +); + +/** Optional messages, which may be translated only if changed in the target language. */ +$wgOptionalMessages = array( + 'linkprefix', + 'editsection-brackets', + 'feed-atom', + 'feed-rss', + 'sectionlink', + 'unit-pixel', + 'userrights-irreversible-marker', 'tog-nolangconversion', 'yourvariant', 'variantname-zh-hans', @@ -167,12 +168,12 @@ $wgOptionalMessages = array( 'variantname-zh-cn', 'variantname-zh-tw', 'variantname-zh-hk', + 'variantname-zh-mo', + 'variantname-zh-my', 'variantname-zh-sg', 'variantname-zh', 'variantname-sr-ec', 'variantname-sr-el', - 'variantname-sr-jc', - 'variantname-sr-jl', 'variantname-sr', 'variantname-kk-arab', 'variantname-kk-cyrl', @@ -184,14 +185,31 @@ $wgOptionalMessages = array( 'variantname-ku-latn', 'variantname-ku-arab', 'variantname-ku', + 'variantname-tg-cyrl', + 'variantname-tg-latn', + 'variantname-tg', 'rc-change-size', 'resetpass_text', 'image_sample', 'media_sample', 'common.css', + 'standard.css', + 'nostalgia.css', + 'cologneblue.css', 'monobook.css', + 'myskin.css', + 'chick.css', + 'simple.css', + 'modern.css', 'common.js', + 'standard.js', + 'nostalgia.js', + 'cologneblue.js', 'monobook.js', + 'myskin.js', + 'chick.js', + 'simple.js', + 'modern.js', 'widthheight', 'exif-fnumber-format', 'exif-focallength-format', @@ -214,7 +232,6 @@ $wgOptionalMessages = array( 'exif-lightsource-23', 'exif-filesource-3', 'booksources-isbn', - 'isbn', 'sp-contributions-explain', 'sorbs', 'video-dims', @@ -224,6 +241,8 @@ $wgOptionalMessages = array( 'filerevert-backlink', 'filedelete-backlink', 'delete-backlink', + 'move-page-backlink', + 'protect-backlink', 'pagetitle', 'filename-prefix-blacklist', 'edittools', @@ -244,6 +263,18 @@ $wgOptionalMessages = array( 'iranian-calendar-m10', 'iranian-calendar-m11', 'iranian-calendar-m12', + 'hijri-calendar-m1', + 'hijri-calendar-m2', + 'hijri-calendar-m3', + 'hijri-calendar-m4', + 'hijri-calendar-m5', + 'hijri-calendar-m6', + 'hijri-calendar-m7', + 'hijri-calendar-m8', + 'hijri-calendar-m9', + 'hijri-calendar-m10', + 'hijri-calendar-m11', + 'hijri-calendar-m12', 'hebrew-calendar-m1', 'hebrew-calendar-m2', 'hebrew-calendar-m3', @@ -272,8 +303,14 @@ $wgOptionalMessages = array( 'hebrew-calendar-m10-gen', 'hebrew-calendar-m11-gen', 'hebrew-calendar-m12-gen', + 'catseparator', 'semicolon-separator', 'comma-separator', + 'colon-separator', + 'autocomment-prefix', + 'listgrouprights-right-display', + 'timezone-utc', + 'whatlinkshere-barrow', ); /** EXIF messages, which may be set as optional in several checks, but are generally mandatory */ diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 8b818d16..50d45e6e 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -2,7 +2,8 @@ /** * Define the messages structure in the messages file, for an automated rewriting. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ /** The structure of the messages, divided to blocks */ @@ -50,6 +51,7 @@ $wgMessageStructure = array( 'tog-nolangconversion', 'tog-ccmeonemails', 'tog-diffonly', + 'tog-showhiddencats', ), 'underline' => array( 'underline-always', @@ -111,14 +113,22 @@ $wgMessageStructure = array( 'nov', 'dec', ), - 'categories' => array( - 'categories', + 'categorypages' => array( 'pagecategories', 'pagecategorieslink', 'category_header', 'subcategories', 'category-media-header', 'category-empty', + 'hidden-categories', + 'hidden-category-category', + 'category-subcat-count', + 'category-subcat-count-limited', + 'category-article-count', + 'category-article-count-limited', + 'category-file-count', + 'category-file-count-limited', + 'listingcontinuesabbrev', ), 'mainpage' => array( 'linkprefix', @@ -164,7 +174,9 @@ $wgMessageStructure = array( 'permalink', 'print', 'edit', + 'create', 'editthispage', + 'create-this-page', 'delete', 'deletethispage', 'undelete_short', @@ -221,13 +233,12 @@ $wgMessageStructure = array( 'help', 'helppage', 'mainpage', + 'mainpage-description', 'policy-url', 'portal', 'portal-url', 'privacy', 'privacypage', - 'sitesupport', - 'sitesupport-url', ), 'badaccess' => array( 'badaccess', @@ -254,6 +265,7 @@ $wgMessageStructure = array( 'editsection', 'editsection-brackets', 'editold', + 'viewsourceold', 'editsectionhint', 'toc', 'showtoc', @@ -305,7 +317,9 @@ $wgMessageStructure = array( 'readonly', 'enterlockreason', 'readonlytext', - 'missingarticle', + 'missing-article', + 'missingarticle-rev', + 'missingarticle-diff', 'readonly_lag', 'internalerror', 'internalerror_info', @@ -341,6 +355,11 @@ $wgMessageStructure = array( 'ns-specialprotected', 'titleprotected', ), + 'virus' => array( + 'virus-badscanner', + 'virus-scanfailed', + 'virus-unknownscanner', + ), 'login' => array( 'logouttitle', 'logouttext', @@ -354,6 +373,7 @@ $wgMessageStructure = array( 'externaldberror', 'loginproblem', 'login', + 'nav-login-createaccount', 'loginprompt', 'userlogin', 'logout', @@ -370,6 +390,7 @@ $wgMessageStructure = array( 'youremail', 'username', 'uid', + 'prefs-memberingroups', 'yourrealname', 'yourlanguage', 'yourvariant', @@ -508,7 +529,6 @@ $wgMessageStructure = array( 'session_fail_preview_html', 'token_suffix_mismatch', 'editing', - 'editinguser', 'editingsection', 'editingcomment', 'editconflict', @@ -532,29 +552,40 @@ $wgMessageStructure = array( 'templatesusedsection', 'template-protected', 'template-semiprotected', + 'hiddencategories', 'edittools', 'nocreatetitle', 'nocreatetext', 'nocreate-loggedin', 'permissionserrors', 'permissionserrorstext', + 'permissionserrorstext-withaction', 'recreate-deleted-warn', ), + 'parserwarnings' => array( + 'expensive-parserfunction-warning', + 'expensive-parserfunction-category', + 'post-expand-template-inclusion-warning', + 'post-expand-template-inclusion-category', + 'post-expand-template-argument-warning', + 'post-expand-template-argument-category', + ), 'undo' => array( 'undo-success', 'undo-failure', + 'undo-norev', 'undo-summary', ), 'cantcreateaccount' => array( 'cantcreateaccounttitle', 'cantcreateaccount-text', + 'cantcreateaccount-nonblock-text', ), 'history' => array( 'viewpagelogs', 'nohistory', 'revnotfound', 'revnotfoundtext', - 'loadhist', 'currentrev', 'revisionasof', 'revision-info', @@ -566,7 +597,6 @@ $wgMessageStructure = array( 'cur', 'next', 'last', - 'orig', 'page_first', 'page_last', 'histlegend', @@ -613,10 +643,22 @@ $wgMessageStructure = array( 'logdelete-logaction', 'revdelete-success', 'logdelete-success', - ), - 'oversightlog' => array( - 'oversightlog', - 'overlogpagetext', + 'revdel-restore', + 'pagehist', + 'deletedhist', + 'revdelete-content', + 'revdelete-summary', + 'revdelete-uname', + 'revdelete-restricted', + 'revdelete-unrestricted', + 'revdelete-hid', + 'revdelete-unhid', + 'revdelete-log-message', + 'logdelete-log-message', + ), + 'suppression' => array( + 'suppressionlog', + 'suppressionlogtext', ), 'mergehistory' => array( 'mergehistory', @@ -635,6 +677,8 @@ $wgMessageStructure = array( 'mergehistory-no-destination', 'mergehistory-invalid-source', 'mergehistory-invalid-destination', + 'mergehistory-autocomment', + 'mergehistory-comment', ), 'mergelog' => array( 'mergelog', @@ -665,14 +709,37 @@ $wgMessageStructure = array( 'prevn', 'nextn', 'viewprevnext', + 'search-result-size', + 'search-result-score', + 'search-redirect', + 'search-section', + 'search-suggest', + 'search-interwiki-caption', + 'search-interwiki-default', + 'search-interwiki-custom', + 'search-interwiki-more', + 'search-mwsuggest-enabled', + 'search-mwsuggest-disabled', + 'search-relatedarticle', + 'mwsuggest-disable', + 'searchrelated', + 'searchall', 'showingresults', 'showingresultsnum', + 'showingresultstotal', 'nonefound', 'powersearch', - 'powersearchtext', + 'powersearch-legend', + 'powersearch-ns', + 'powersearch-redir', + 'powersearch-field', + 'search-external', 'searchdisabled', 'googlesearch', ), + 'opensearch' => array( + 'opensearch-desc', + ), 'preferences' => array( 'preferences', 'preferences-summary', @@ -731,50 +798,110 @@ $wgMessageStructure = array( 'servertime', 'guesstimezone', 'allowemail', + 'prefs-searchoptions', + 'prefs-namespaces', 'defaultns', 'default', 'files', ), 'userrights' => array( + 'userrights', + 'userrights-summary', 'userrights-lookup-user', 'userrights-user-editname', 'editusergroup', + 'editinguser', 'userrights-editusergroup', 'saveusergroups', 'userrights-groupsmember', - 'userrights-groupsremovable', - 'userrights-groupsavailable', - 'userrights-groupshelp', + 'userrights-groups-help', 'userrights-reason', - 'userrights-available-none', - 'userrights-available-add', - 'userrights-available-remove', - 'userrights-available-add-self', - 'userrights-available-remove-self', 'userrights-no-interwiki', 'userrights-nodatabase', 'userrights-nologin', 'userrights-notallowed', + 'userrights-changeable-col', + 'userrights-unchangeable-col', + 'userrights-irreversible-marker', ), 'group' => array( 'group', + 'group-user', 'group-autoconfirmed', 'group-bot', 'group-sysop', 'group-bureaucrat', + 'group-suppress', 'group-all', ), 'group-member' => array( + 'group-user-member', 'group-autoconfirmed-member', 'group-bot-member', 'group-sysop-member', 'group-bureaucrat-member', + 'group-suppress-member', ), 'grouppage' => array( + 'grouppage-user', 'grouppage-autoconfirmed', 'grouppage-bot', 'grouppage-sysop', 'grouppage-bureaucrat', + 'grouppage-suppress', + ), + 'right' => array( + 'right-read', + 'right-edit', + 'right-createpage', + 'right-createtalk', + 'right-createaccount', + 'right-minoredit', + 'right-move', + 'right-move-subpages', + 'right-suppressredirect', + 'right-upload', + 'right-reupload', + 'right-reupload-own', + 'right-reupload-shared', + 'right-upload_by_url', + 'right-purge', + 'right-autoconfirmed', + 'right-bot', + 'right-nominornewtalk', + 'right-apihighlimits', + 'right-writeapi', + 'right-delete', + 'right-bigdelete', + 'right-deleterevision', + 'right-deletedhistory', + 'right-browsearchive', + 'right-undelete', + 'right-suppressrevision', + 'right-suppressionlog', + 'right-block', + 'right-blockemail', + 'right-hideuser', + 'right-ipblock-exempt', + 'right-proxyunbannable', + 'right-protect', + 'right-editprotected', + 'right-editinterface', + 'right-editusercssjs', + 'right-rollback', + 'right-markbotedits', + 'right-noratelimit', + 'right-import', + 'right-importupload', + 'right-patrol', + 'right-autopatrol', + 'right-patrolmarks', + 'right-unwatchedpages', + 'right-trackback', + 'right-mergehistory', + 'right-userrights', + 'right-userrights-interwiki', + 'right-siteadmin', ), 'rightslog' => array( 'rightslog', @@ -818,6 +945,8 @@ $wgMessageStructure = array( 'recentchangeslinked-title', 'recentchangeslinked-noresult', 'recentchangeslinked-summary', + 'recentchangeslinked-page', + 'recentchangeslinked-to', ), 'upload' => array( 'upload', @@ -826,6 +955,7 @@ $wgMessageStructure = array( 'reuploaddesc', 'uploadnologin', 'uploadnologintext', + 'upload_directory_missing', 'upload_directory_read_only', 'uploaderror', 'upload-summary', @@ -833,6 +963,7 @@ $wgMessageStructure = array( 'upload-permitted', 'upload-preferred', 'upload-prohibited', + 'uploadfooter', 'uploadlog', 'uploadlogpage', 'uploadlogpagetext', @@ -862,6 +993,7 @@ $wgMessageStructure = array( 'file-thumbnail-no', 'fileexists-forbidden', 'fileexists-shared-forbidden', + 'file-exists-duplicate', 'successfulupload', 'uploadwarning', 'savefile', @@ -874,6 +1006,7 @@ $wgMessageStructure = array( 'uploadvirus', 'sourcefilename', 'destfilename', + 'upload-maxfilesize', 'watchthisupload', 'filewasdeleted', 'upload-wasdeleted', @@ -903,18 +1036,17 @@ $wgMessageStructure = array( 'upload_source_file', ), 'imagelist' => array( - 'imagelist', 'imagelist-summary', - 'imagelisttext', - 'getimagelist', - 'ilsubmit', - 'showlast', - 'byname', - 'bydate', - 'bysize', - 'imgdelete', - 'imgdesc', + 'imagelist_search_for', 'imgfile', + 'imagelist', + 'imagelist_date', + 'imagelist_name', + 'imagelist_user', + 'imagelist_size', + 'imagelist_description', + ), + 'imagedesciption' => array( 'filehist', 'filehist-help', 'filehist-deleteall', @@ -929,20 +1061,22 @@ $wgMessageStructure = array( 'imagelinks', 'linkstoimage', 'nolinkstoimage', + 'morelinkstoimage', + 'redirectstofile', + 'duplicatesoffile', 'sharedupload', 'shareduploadwiki', 'shareduploadwiki-desc', 'shareduploadwiki-linktext', 'shareddescriptionfollows', + 'shareduploadduplicate', + 'shareduploadduplicate-linktext', + 'shareduploadconflict', + 'shareduploadconflict-linktext', 'noimage', 'noimage-linktext', 'uploadnewversion-linktext', - 'imagelist_date', - 'imagelist_name', - 'imagelist_user', - 'imagelist_size', - 'imagelist_description', - 'imagelist_search_for', + 'imagepage-searchdupe', ), 'filerevert' => array( 'filerevert', @@ -971,6 +1105,7 @@ $wgMessageStructure = array( 'filedelete-otherreason', 'filedelete-reason-otherlist', 'filedelete-reason-dropdown', + 'filedelete-edit-reasonlist', ), 'mimesearch' => array( 'mimesearch', @@ -1020,6 +1155,8 @@ $wgMessageStructure = array( 'doubleredirects', 'doubleredirects-summary', 'doubleredirectstext', + 'double-redirect-fixed-move', + 'double-redirect-fixer', ), 'brokenredirects' => array( 'brokenredirects', @@ -1030,8 +1167,8 @@ $wgMessageStructure = array( ), 'withoutinterwiki' => array( 'withoutinterwiki', - 'withoutinterwiki-header', 'withoutinterwiki-summary', + 'withoutinterwiki-legend', 'withoutinterwiki-submit', ), 'fewestrevisions' => array( @@ -1066,6 +1203,8 @@ $wgMessageStructure = array( 'wantedcategories-summary', 'wantedpages', 'wantedpages-summary', + 'missingfiles', + 'missingfiles-summary', 'mostlinked', 'mostlinked-summary', 'mostlinkedcategories', @@ -1078,8 +1217,6 @@ $wgMessageStructure = array( 'mostimages-summary', 'mostrevisions', 'mostrevisions-summary', - 'allpages', - 'allpages-summary', 'prefixindex', 'prefixindex-summary', 'shortpages', @@ -1090,6 +1227,7 @@ $wgMessageStructure = array( 'deadendpages-summary', 'deadendpagestext', 'protectedpages', + 'protectedpages-indef', 'protectedpages-summary', 'protectedpagestext', 'protectedpagesempty', @@ -1099,24 +1237,22 @@ $wgMessageStructure = array( 'protectedtitlesempty', 'listusers', 'listusers-summary', - 'specialpages', - 'specialpages-summary', - 'spheading', - 'restrictedpheading', 'newpages', 'newpages-summary', 'newpages-username', 'ancientpages', 'ancientpages-summary', - 'intl', 'move', 'movethispage', 'unusedimagestext', 'unusedcategoriestext', 'notargettitle', 'notargettext', + 'nopagetitle', + 'nopagetext', 'pager-newer-n', 'pager-older-n', + 'suppress', ), 'booksources' => array( 'booksources', @@ -1126,17 +1262,9 @@ $wgMessageStructure = array( 'booksources-go', 'booksources-text', ), - 'specialpages2' => array( - 'categoriespagetext', - 'data', - 'userrights', - 'userrights-summary', - 'groups', - 'isbn', + 'magicwords' => array( 'rfcurl', 'pubmedurl', - 'alphaindexline', - 'version', ), 'logpages' => array( 'specialloguserlabel', @@ -1150,6 +1278,9 @@ $wgMessageStructure = array( 'log-title-wildcard', ), 'allpages' => array( + 'allpages', + 'allpages-summary', + 'alphaindexline', 'nextpage', 'prevpage', 'allpagesfrom', @@ -1163,11 +1294,28 @@ $wgMessageStructure = array( 'allpagesbadtitle', 'allpages-bad-ns', ), + 'categories' => array( + 'categories', + 'categories-summary', + 'categoriespagetext', + 'categoriesfrom', + 'special-categories-sort-count', + 'special-categories-sort-abc', + ), 'listusers' => array( 'listusersfrom', 'listusers-submit', 'listusers-noresult', ), + 'listgrouprights' => array( + 'listgrouprights', + 'listgrouprights-summary', + 'listgrouprights-group', + 'listgrouprights-rights', + 'listgrouprights-helppage', + 'listgrouprights-members', + 'listgrouprights-right-display', + ), 'emailuser' => array( 'mailnologin', 'mailnologintext', @@ -1187,6 +1335,7 @@ $wgMessageStructure = array( 'emailccsubject', 'emailsent', 'emailsenttext', + 'emailuserfooter', ), 'watchlist' => array( 'watchlist', @@ -1205,6 +1354,7 @@ $wgMessageStructure = array( 'unwatch', 'unwatchthispage', 'notanarticle', + 'notvisiblerev', 'watchnochange', 'watchlist-details', 'wlheader-enotif', @@ -1254,6 +1404,7 @@ $wgMessageStructure = array( 'actioncomplete', 'deletedtext', 'deletedarticle', + 'suppressedarticle', 'dellogpage', 'dellogpagetext', 'deletionlog', @@ -1262,6 +1413,7 @@ $wgMessageStructure = array( 'deleteotherreason', 'deletereasonotherlist', 'deletereason-dropdown', + 'delete-edit-reasonlist', 'delete-toobig', 'delete-warning-toobig', 'rollback', @@ -1279,13 +1431,14 @@ $wgMessageStructure = array( 'protectedarticle', 'modifiedarticleprotection', 'unprotectedarticle', - 'protectsub', + 'protect-title', + 'protect-backlink', + 'protect-legend', 'confirmprotect', 'protectcomment', 'protectexpiry', 'protect_expiry_invalid', 'protect_expiry_old', - 'unprotectsub', 'protect-unchain', 'protect-text', 'protect-locked-blocked', @@ -1310,6 +1463,7 @@ $wgMessageStructure = array( 'restriction-edit', 'restriction-move', 'restriction-create', + 'restriction-upload', ), 'restriction-levels' => array( 'restriction-level-sysop', @@ -1319,8 +1473,10 @@ $wgMessageStructure = array( 'undelete' => array( 'undelete', 'undeletepage', + 'undeletepagetitle', 'viewdeletedpage', 'undeletepagetext', + 'undelete-fieldset-title', 'undeleteextrahelp', 'undeleterevisions', 'undeletehistory', @@ -1361,8 +1517,6 @@ $wgMessageStructure = array( 'mycontris', 'contribsub2', 'nocontribs', - 'ucnote', - 'uclinks', 'uctop', 'month', 'year', @@ -1378,9 +1532,6 @@ $wgMessageStructure = array( 'sp-contributions-footer', 'sp-contributions-footer-anon', ), - 'newimages-showfrom' => array( - 'sp-newimages-showfrom', - ), 'whatlinkshere' => array( 'whatlinkshere', 'whatlinkshere-title', @@ -1393,12 +1544,19 @@ $wgMessageStructure = array( 'nolinkshere-ns', 'isredirect', 'istemplate', + 'isimage', 'whatlinkshere-prev', 'whatlinkshere-next', 'whatlinkshere-links', + 'whatlinkshere-hideredirs', + 'whatlinkshere-hidetrans', + 'whatlinkshere-hidelinks', + 'whatlinkshere-hideimages', + 'whatlinkshere-filters', ), 'block' => array( 'blockip', + 'blockip-legend', 'blockiptext', 'ipaddress', 'ipadressorusername', @@ -1416,6 +1574,7 @@ $wgMessageStructure = array( 'ipbotheroption', 'ipbotherreason', 'ipbhidename', + 'ipbwatchuser', 'badipaddress', 'blockipsuccesssub', 'blockipsuccesstext', @@ -1455,8 +1614,10 @@ $wgMessageStructure = array( 'block-log-flags-nocreate', 'block-log-flags-noautoblock', 'block-log-flags-noemail', + 'block-log-flags-angry-autoblock', 'range_block_disabled', 'ipb_expiry_invalid', + 'ipb_expiry_temp', 'ipb_already_blocked', 'ipb_cant_unblock', 'ipb_blocked_as_range', @@ -1488,7 +1649,9 @@ $wgMessageStructure = array( 'databasenotlocked', ), 'movepage' => array( - 'movepage', + 'move-page', + 'move-page-backlink', + 'move-page-legend', 'movepagetext', 'movepagetalktext', 'movearticle', @@ -1505,8 +1668,12 @@ $wgMessageStructure = array( 'talkexists', 'movedto', 'movetalk', - 'talkpagemoved', - 'talkpagenotmoved', + 'move-subpages', + 'move-talk-subpages', + 'movepage-page-exists', + 'movepage-page-moved', + 'movepage-page-unmoved', + 'movepage-max-pages', '1movedto2', '1movedto2_redir', 'movelogpage', @@ -1519,6 +1686,10 @@ $wgMessageStructure = array( 'delete_and_move_reason', 'selfmove', 'immobile_namespace', + 'imagenocrossnamespace', + 'imagetypemismatch', + 'imageinvalidfilename', + 'fix-double-redirects', ), 'export' => array( 'export', @@ -1577,6 +1748,7 @@ $wgMessageStructure = array( 'import-noarticle', 'import-nonewrevisions', 'xml-error-string', + 'import-upload', ), 'importlog' => array( 'importlogpage', @@ -1618,7 +1790,6 @@ $wgMessageStructure = array( 'accesskey-n-recentchanges', 'accesskey-n-randompage', 'accesskey-n-help', - 'accesskey-n-sitesupport', 'accesskey-t-whatlinkshere', 'accesskey-t-recentchangeslinked', 'accesskey-t-random', @@ -1680,7 +1851,6 @@ $wgMessageStructure = array( 'tooltip-n-recentchanges', 'tooltip-n-randompage', 'tooltip-n-help', - 'tooltip-n-sitesupport', 'tooltip-t-whatlinkshere', 'tooltip-t-recentchangeslinked', 'tooltip-t-random', @@ -1713,11 +1883,25 @@ $wgMessageStructure = array( ), 'stylesheets' => array( 'common.css', + 'standard.css', + 'nostalgia.css', + 'cologneblue.css', 'monobook.css', + 'myskin.css', + 'chick.css', + 'simple.css', + 'modern.css', ), 'scripts' => array( 'common.js', + 'standard.js', + 'nostalgia.js', + 'cologneblue.js', 'monobook.js', + 'myskin.js', + 'chick.js', + 'simple.js', + 'modern.js', ), 'metadata_cc' => array( 'nodublincore', @@ -1738,10 +1922,6 @@ $wgMessageStructure = array( 'spamprotectiontitle', 'spamprotectiontext', 'spamprotectionmatch', - 'subcategorycount', - 'categoryarticlecount', - 'category-media-count', - 'listingcontinuesabbrev', 'spambot_username', 'spam_reverting', 'spam_blanking', @@ -1809,9 +1989,13 @@ $wgMessageStructure = array( ), 'newimages' => array( 'newimages', + 'imagelisttext', 'newimages-summary', 'showhidebots', 'noimages', + 'ilsubmit', + 'bydate', + 'sp-newimages-showfrom', ), 'video-info' => array( 'video-dims', @@ -1828,14 +2012,14 @@ $wgMessageStructure = array( 'variantname-zh-cn', 'variantname-zh-tw', 'variantname-zh-hk', + 'variantname-zh-mo', 'variantname-zh-sg', + 'variantname-zh-my', 'variantname-zh', ), 'variantname-sr' => array( 'variantname-sr-ec', 'variantname-sr-el', - 'variantname-sr-jc', - 'variantname-sr-jl', 'variantname-sr', ), 'variantname-kk' => array( @@ -1852,6 +2036,11 @@ $wgMessageStructure = array( 'variantname-ku-latn', 'variantname-ku', ), + 'variantname-tg' => array( + 'variantname-tg-cyrl', + 'variantname-tg-latn', + 'variantname-tg', + ), 'metadata' => array( 'metadata', 'metadata-help', @@ -2192,6 +2381,8 @@ $wgMessageStructure = array( 'confirmemail_error', 'confirmemail_subject', 'confirmemail_body', + 'confirmemail_invalidated', + 'invalidateemail', ), 'scarytransclusion' => array( 'scarytranscludedisabled', @@ -2232,13 +2423,14 @@ $wgMessageStructure = array( 'catseparator', 'semicolon-separator', 'comma-separator', + 'colon-separator', + 'autocomment-prefix', ), 'imgmulti' => array( 'imgmultipageprev', 'imgmultipagenext', 'imgmultigo', - 'imgmultigotopre', - 'imgmultigotopost', + 'imgmultigoto', ), 'tablepager' => array( 'ascending_abbrev', @@ -2312,6 +2504,20 @@ $wgMessageStructure = array( 'iranian-calendar-m11', 'iranian-calendar-m12', ), + 'hijri-dates' => array( + 'hijri-calendar-m1', + 'hijri-calendar-m2', + 'hijri-calendar-m3', + 'hijri-calendar-m4', + 'hijri-calendar-m5', + 'hijri-calendar-m6', + 'hijri-calendar-m7', + 'hijri-calendar-m8', + 'hijri-calendar-m9', + 'hijri-calendar-m10', + 'hijri-calendar-m11', + 'hijri-calendar-m12', + ), 'hebrew-dates' => array( 'hebrew-calendar-m1', 'hebrew-calendar-m2', @@ -2345,11 +2551,13 @@ $wgMessageStructure = array( 'signatures' => array( 'signature', 'signature-anon', + 'timezone-utc', ), 'CoreParserFunctions' => array( 'unknown_extension_tag', ), 'version' => array( + 'version', 'version-extensions', 'version-specialpages', 'version-parserhooks', @@ -2375,12 +2583,44 @@ $wgMessageStructure = array( 'filepath-submit', 'filepath-summary', ), + 'fileduplicatesearch' => array( + 'fileduplicatesearch', + 'fileduplicatesearch-summary', + 'fileduplicatesearch-legend', + 'fileduplicatesearch-filename', + 'fileduplicatesearch-submit', + 'fileduplicatesearch-info', + 'fileduplicatesearch-result-1', + 'fileduplicatesearch-result-n', + ), + 'special-specialpages' => array( + 'specialpages', + 'specialpages-summary', + 'specialpages-note', + 'specialpages-group-maintenance', + 'specialpages-group-other', + 'specialpages-group-login', + 'specialpages-group-changes', + 'specialpages-group-media', + 'specialpages-group-users', + 'specialpages-group-highuse', + 'specialpages-group-pages', + 'specialpages-group-pagetools', + 'specialpages-group-wiki', + 'specialpages-group-redirects', + 'specialpages-group-spam', + ), + 'special-blank' => array( + 'blankpage', + 'intentionallyblankpage', + ), ); + /** Comments for each block */ $wgBlockComments = array( 'sidebar' => "The sidebar for MonoBook is generated from this message, lines that do not begin with * or ** are discarded, furthermore lines that do begin with ** and -do not contain | are also discarded, but don't depend on this behaviour for +do not contain | are also discarded, but do not depend on this behaviour for future releases. Also note that since each list value is wrapped in a unique XHTML id it should only appear once and include characters that are legal XHTML id names.", @@ -2388,7 +2628,7 @@ XHTML id names.", 'underline' => '', 'skinpreview' => '', 'dates' => 'Dates', - 'categories' => 'Bits of text used by many pages', + 'categorypages' => 'Categories related messages', 'mainpage' => '', 'miscellaneous1' => '', 'metadata_help' => 'Metadata in edit box', @@ -2400,25 +2640,29 @@ XHTML id names.", 'nstab' => "Short words for each namespace, by default used in the namespace tab in monobook", 'main' => 'Main script and global functions', 'errors' => 'General errors', + 'virus' => 'Virus scanner', 'login' => 'Login and logout pages', 'resetpass' => 'Password reset dialog', 'toolbar' => 'Edit page toolbar', 'edit' => 'Edit pages', + 'parserwarnings' => 'Parser/template warnings', 'undo' => '"Undo" feature', 'cantcreateaccount' => 'Account creation failure', 'history' => 'History pages', 'history-feed' => 'Revision feed', 'revdelete' => 'Revision deletion', - 'oversightlog' => 'Oversight log', + 'suppression' => 'Suppression log', 'mergehistory' => 'History merging', 'mergelog' => 'Merge log', 'diffs' => 'Diffs', 'search' => 'Search results', + 'opensearch' => 'OpenSearch description', 'preferences' => 'Preferences page', 'userrights' => 'User rights', 'group' => 'Groups', 'group-member' => '', 'grouppage' => '', + 'right' => 'Rights', 'rightslog' => 'User rights log', 'recentchanges' => 'Recent changes', 'recentchangeslinked' => 'Recent changes linked', @@ -2426,9 +2670,10 @@ XHTML id names.", 'upload-errors' => '', 'upload-curl-errors' => 'Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>', 'licenses' => '', - 'imagelist' => 'Image list', + 'imagelist' => 'Special:ImageList', + 'imagedesciption' => 'Image description page', 'filerevert' => 'File reversion', - 'filedelete' => 'File deletion', + 'filedelete' => 'File deletion', 'mimesearch' => 'MIME search', 'unwatchedpages' => 'Unwatched pages', 'listredirects' => 'List redirects', @@ -2443,13 +2688,15 @@ XHTML id names.", 'fewestrevisions' => '', 'specialpages' => 'Miscellaneous special pages', 'booksources' => 'Book sources', - 'specialpages2' => '', + 'magicwords' => 'Magic words', 'logpages' => 'Special:Log', - 'allpages' => 'Special:Allpages', - 'listusers' => 'Special:Listusers', + 'allpages' => 'Special:AllPages', + 'categories' => 'Special:Categories', + 'listusers' => 'Special:ListUsers', + 'listgrouprights' => 'Special:ListGroupRights', 'emailuser' => 'E-mail user', 'watchlist' => 'Watchlist', - 'watching' => 'Displayed when you click the "watch" button and it\'s in the process of watching', + 'watching' => 'Displayed when you click the "watch" button and it is in the process of watching', 'enotif' => '', 'deleteprotectrev' => 'Delete/protect/revert', 'restrictions' => 'Restrictions (nouns)', @@ -2458,7 +2705,6 @@ XHTML id names.", 'nsform' => 'Namespace form on various pages', 'contributions' => 'Contributions', 'sp-contributions' => '', - 'newimages-showfrom' => '', 'whatlinkshere' => 'What links here', 'block' => 'Block/unblock', 'developertools' => 'Developer tools', @@ -2481,7 +2727,7 @@ XHTML id names.", 'patrol-log' => 'Patrol log', 'imagedeletion' => 'Image deletion', 'browsediffs' => 'Browsing diffs', - 'newimages' => 'Special:Newimages', + 'newimages' => 'Special:NewImages', 'video-info' => 'Video information, used by Language::formatTimePeriod() to format lengths in the above messages', 'badimagelist' => 'Bad image list', 'variantname-zh' => "Short names for language variants used for language conversion links. @@ -2491,6 +2737,7 @@ Variants for Chinese language", 'variantname-sr' => 'Variants for Serbian language', 'variantname-kk' => 'Variants for Kazakh language', 'variantname-ku' => 'Variants for Kurdish language', + 'variantname-tg' => 'Variants for Tajiki language', 'media-info' => 'Media information', 'metadata' => 'Metadata', 'exif' => 'EXIF tags', @@ -2536,7 +2783,7 @@ Variants for Chinese language", 'htmldump' => 'HTML dump', 'purge' => 'action=purge', 'search2' => 'AJAX search', - 'separators' => 'Separators for various lists', + 'separators' => 'Separators for various lists, etc.', 'imgmulti' => 'Multipage image navigation', 'tablepager' => 'Table pager', 'autosumm' => 'Auto-summaries', @@ -2547,15 +2794,20 @@ Variants for Chinese language", 'watchlisteditor' => 'Watchlist editor', 'watchlisttools' => 'Watchlist editing tools', 'iranian-dates' => 'Iranian month names', + 'hijri-dates' => 'Hijri month names', 'hebrew-dates' => 'Hebrew month names', 'signatures' => 'Signatures', 'CoreParserFunctions' => 'Core parser functions', 'version' => 'Special:Version', - 'filepath' => 'Special:Filepath', + 'filepath' => 'Special:FilePath', + 'fileduplicatesearch' => 'Special:FileDuplicateSearch', + 'special-specialpages' => 'Special:SpecialPages', + 'special-blank' => 'Special:BlankPage', ); /** Short comments for standalone messages */ $wgMessageComments = array( + 'hidden-category-category' => 'Name of the category where hidden categories will be listed', 'lastmodifiedat' => '$1 date, $2 time', 'sitenotice' => 'the equivalent to wgSiteNotice', 'history-feed-item-nocomment' => 'user at time', @@ -2573,4 +2825,6 @@ $wgMessageComments = array( 'movepage-moved' => 'The two titles are passed in plain text as $3 and $4 to allow additional goodies in the message.', 'ipboptions' => 'display1:time1,display2:time2,...', 'metadata-fields' => 'Do not translate list items', + 'version' => 'Not used as normal message but as header for the special page itself', + 'userrights' => 'Not used as normal message but as header for the special page itself', ); diff --git a/maintenance/language/rebuildLanguage.php b/maintenance/language/rebuildLanguage.php index 6c2076eb..91fda3f4 100644 --- a/maintenance/language/rebuildLanguage.php +++ b/maintenance/language/rebuildLanguage.php @@ -1,8 +1,10 @@ <?php /** - * Rewrite the messages array in the files languages/messages/MessagesXX.php. + * Rewrite the messages array in the files languages/messages/MessagesXx.php. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage + * @defgroup MaintenanceLanguage MaintenanceLanguage */ require_once( dirname(__FILE__).'/../commandLine.inc' ); @@ -15,12 +17,13 @@ require_once( 'writeMessagesArray.inc' ); * @param $code The language code. * @param $write Write to the messages file? * @param $listUnknown List the unknown messages? + * @param $removeUnKnown Remove the unknown messages? */ -function rebuildLanguage( $code, $write, $listUnknown ) { +function rebuildLanguage( $code, $write, $listUnknown, $removeUnknown ) { global $wgLanguages; $messages = $wgLanguages->getMessages( $code ); $messages = $messages['all']; - MessageWriter::writeMessagesToFile( $messages, $code, $write, $listUnknown ); + MessageWriter::writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown ); } # Show help @@ -31,8 +34,9 @@ Parameters: * lang: Language code (default: the installation default language). You can also specify "all" to check all the languages. * help: Show this help. Options: - * dry-run: Don't write the array to the file. - * no-unknown: Don't list the unknown messages. + * dry-run: Do not write the array to the file. + * no-unknown: Do not list the unknown messages. + * remove-unknown: Remove unknown messages. END; exit(); @@ -48,6 +52,7 @@ if ( isset( $options['lang'] ) ) { # Get the options $wgWriteToFile = !isset( $options['dry-run'] ); $wgListUnknownMessages = !isset( $options['no-unknown'] ); +$wgRemoveUnknownMessages = isset( $options['remove-unknown'] ); # Get language objects $wgLanguages = new languages(); @@ -55,10 +60,8 @@ $wgLanguages = new languages(); # Write all the language if ( $wgCode == 'all' ) { foreach ( $wgLanguages->getLanguages() as $language ) { - rebuildLanguage( $language, $wgWriteToFile, $wgListUnknownMessages ); + rebuildLanguage( $language, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages ); } } else { - rebuildLanguage( $wgCode, $wgWriteToFile, $wgListUnknownMessages ); + rebuildLanguage( $wgCode, $wgWriteToFile, $wgListUnknownMessages, $wgRemoveUnknownMessages ); } - - diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php index 410bd695..ee2b844c 100644 --- a/maintenance/language/transstat.php +++ b/maintenance/language/transstat.php @@ -2,7 +2,8 @@ /** * Statistics about the localisation. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage * * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com> * @author Ashar Voultoiz <thoane@altern.org> diff --git a/maintenance/language/validate.php b/maintenance/language/validate.php index 5e96c2d2..e84aa29d 100644 --- a/maintenance/language/validate.php +++ b/maintenance/language/validate.php @@ -1,4 +1,8 @@ <?php +/** + * @file + * @ingroup MaintenanceLanguage + */ if ( !isset( $argv[1] ) ) { print "Usage: php {$argv[0]} <filename>\n"; diff --git a/maintenance/language/writeMessagesArray.inc b/maintenance/language/writeMessagesArray.inc index 2324785e..3a279cb6 100644 --- a/maintenance/language/writeMessagesArray.inc +++ b/maintenance/language/writeMessagesArray.inc @@ -2,14 +2,17 @@ /** * Write a messages array as a PHP text. * - * @addtogroup Maintenance + * @file + * @ingroup MaintenanceLanguage */ +/** + * @ingroup MaintenanceLanguage + */ class MessageWriter { static $optionalComment = 'only translate this message to other languages if you have to change it'; - static $ignoredComment = "don't translate or duplicate this message to other languages"; + static $ignoredComment = "do not translate or duplicate this message to other languages"; - static $loaded = false; static $messageStructure; static $blockComments; static $messageComments; @@ -24,9 +27,9 @@ class MessageWriter { * @param $write Write to the messages file? * @param $listUnknown List the unknown messages? */ - public static function writeMessagesToFile( $messages, $code, $write, $listUnknown ) { + public static function writeMessagesToFile( $messages, $code, $write, $listUnknown, $removeUnknown ) { # Rewrite the messages array - $messages = self::writeMessagesArray( $messages, $code == 'en' ); + $messages = self::writeMessagesArray( $messages, $code == 'en', false, $removeUnknown ); $messagesText = $messages[0]; $sortedMessages = $messages[1]; @@ -48,13 +51,16 @@ class MessageWriter { } } if( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) { - echo "\nThere are " . count( $sortedMessages['unknown'] ) . " unknown messages, please check them:\n"; + if ( $removeUnknown ) + echo "\nThe following " . count( $sortedMessages['unknown'] ) . " unknown messages have been removed:\n"; + else + echo "\nThere are " . count( $sortedMessages['unknown'] ) . " unknown messages, please check them:\n"; foreach( $sortedMessages['unknown'] as $key => $value ) { echo "* " . $key . "\n"; } } } else { - echo "Generated messages for language $code. There seems to be no messages array in the file.\n"; + echo "Generated messages for language $code. There seem to be no messages array in the file.\n"; } } @@ -66,20 +72,19 @@ class MessageWriter { * * @return Array of the PHP text and the sorted messages array. */ - public static function writeMessagesArray( $messages, $ignoredComments = false ) { + public static function writeMessagesArray( $messages, $ignoredComments = false, $prefix = false, $removeUnknown = false ) { # Load messages - if( !self::$loaded ) { - require( dirname( __FILE__ ) . '/messages.inc' ); - self::$messageStructure = $wgMessageStructure; - self::$blockComments = $wgBlockComments; - self::$messageComments = $wgMessageComments; + $dir = $prefix ? $prefix : dirname( __FILE__ ); - require( dirname( __FILE__ ) . '/messageTypes.inc' ); - self::$ignoredMessages = $wgIgnoredMessages; - self::$optionalMessages = $wgOptionalMessages; + require( $dir . '/messages.inc' ); + self::$messageStructure = $wgMessageStructure; + self::$blockComments = $wgBlockComments; + self::$messageComments = $wgMessageComments; + + require( $dir . '/messageTypes.inc' ); + self::$ignoredMessages = $wgIgnoredMessages; + self::$optionalMessages = $wgOptionalMessages; - self::$loaded = true; - } # Sort messages to blocks $sortedMessages['unknown'] = $messages; @@ -115,12 +120,13 @@ class MessageWriter { } # Write the unknown messages, alphabetically sorted. - # Of course, we don't have any comments for them, because the are unknown. - ksort( $sortedMessages['unknown'] ); - $messagesText .= self::writeMessagesBlock( 'Unknown messages', $sortedMessages['unknown'] ); + # Of course, we don't have any comments for them, because they are unknown. + if ( !$removeUnknown ) { + ksort( $sortedMessages['unknown'] ); + $messagesText .= self::writeMessagesBlock( 'Unknown messages', $sortedMessages['unknown'] ); + } $messagesText .= "); "; - return array( $messagesText, $sortedMessages ); } |