summaryrefslogtreecommitdiff
path: root/maintenance/language
diff options
context:
space:
mode:
Diffstat (limited to 'maintenance/language')
-rw-r--r--maintenance/language/StatOutputs.php103
-rw-r--r--maintenance/language/checkLanguage.inc128
-rw-r--r--maintenance/language/checkLanguage.php323
-rw-r--r--maintenance/language/lang2po.php14
-rw-r--r--maintenance/language/languages.inc113
-rw-r--r--maintenance/language/messageTypes.inc70
-rw-r--r--maintenance/language/messages.inc297
-rw-r--r--maintenance/language/rebuildLanguage.php2
-rw-r--r--maintenance/language/splitLanguageFiles.inc1
-rw-r--r--maintenance/language/transstat.php96
-rw-r--r--maintenance/language/writeMessagesArray.inc360
11 files changed, 991 insertions, 516 deletions
diff --git a/maintenance/language/StatOutputs.php b/maintenance/language/StatOutputs.php
new file mode 100644
index 00000000..50829cbe
--- /dev/null
+++ b/maintenance/language/StatOutputs.php
@@ -0,0 +1,103 @@
+<?php
+if (!defined('MEDIAWIKI')) die();
+/**
+ * Statistic output classes.
+ *
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @author Ashar Voultoiz <thoane@altern.org>
+ */
+
+/** A general output object. Need to be overriden */
+class statsOutput {
+ function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
+ return @sprintf( '%.' . $accuracy . 'f%%', 100 * $subset / $total );
+ }
+
+ # Override the following methods
+ function heading() {
+ }
+ function footer() {
+ }
+ function blockstart() {
+ }
+ function blockend() {
+ }
+ function element( $in, $heading = false ) {
+ }
+}
+
+/** Outputs WikiText */
+class wikiStatsOutput extends statsOutput {
+ function heading() {
+ global $IP;
+ $version = SpecialVersion::getVersion( $IP );
+ echo "'''Statistics are based on:''' <code>" . $version . "</code>\n\n";
+ echo "'''Note:''' These statistics can be generated by running <code>php maintenance/language/transstat.php</code>.\n\n";
+ echo "For additional information on specific languages (the message names, the actual problems, etc.), run <code>php maintenance/language/checkLanguage.php --lang=foo</code>.\n\n";
+ echo '{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear:both;" width="100%"'."\n";
+ }
+ function footer() {
+ echo "|}\n";
+ }
+ function blockstart() {
+ echo "|-\n";
+ }
+ function blockend() {
+ echo '';
+ }
+ function element( $in, $heading = false ) {
+ echo ($heading ? '!' : '|') . " $in\n";
+ }
+ function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
+ $v = @round(255 * $subset / $total);
+ if ( $revert ) {
+ $v = 255 - $v;
+ }
+ if ( $v < 128 ) {
+ # Red to Yellow
+ $red = 'FF';
+ $green = sprintf( '%02X', 2 * $v );
+ } else {
+ # Yellow to Green
+ $red = sprintf('%02X', 2 * ( 255 - $v ) );
+ $green = 'FF';
+ }
+ $blue = '00';
+ $color = $red . $green . $blue;
+
+ $percent = statsOutput::formatPercent( $subset, $total, $revert, $accuracy );
+ return 'bgcolor="#'. $color .'" | '. $percent;
+ }
+}
+
+/** Outputs WikiText and appends category and text only used for Meta-Wiki */
+class metawikiStatsOutput extends wikiStatsOutput {
+ function heading() {
+ echo "See [[MediaWiki localisation]] to learn how you can help translating MediaWiki.\n\n";
+ parent::heading();
+ }
+ function footer() {
+ parent::footer();
+ echo "\n[[Category:Localisation|Statistics]]\n";
+ }
+}
+
+/** Output text. To be used on a terminal for example. */
+class textStatsOutput extends statsOutput {
+ function element( $in, $heading = false ) {
+ echo $in."\t";
+ }
+ function blockend() {
+ echo "\n";
+ }
+}
+
+/** csv output. Some people love excel */
+class csvStatsOutput extends statsOutput {
+ function element( $in, $heading = false ) {
+ echo $in . ";";
+ }
+ function blockend() {
+ echo "\n";
+ }
+}
diff --git a/maintenance/language/checkLanguage.inc b/maintenance/language/checkLanguage.inc
index 468db550..51de8014 100644
--- a/maintenance/language/checkLanguage.inc
+++ b/maintenance/language/checkLanguage.inc
@@ -1,109 +1,23 @@
<?php
-/**
- * Check a language.
- *
- * @param $languages The languages object.
- * @param $code The language code (default content language of the wiki running the script on).
- * @param: $links Show wiki links to messages (default false)?
- * @param: $wikiLanguage Language of the wiki to show the output in, if showing links (default en).
- * @param: $checks Checks to do (default all except for duplicates and plural).
- * @return Number of errors found.
- */
-function checkLanguage( $languages, $code = null, $displayLevel = 2, $links = false, $wikiLanguage = 'en', $checks = null ) {
- # Get messages
- $messages = $languages->getMessages( $code );
- $messagesNumber = count( $messages['translated'] );
- # Skip the checks if told so
- if ( $displayLevel == 0 ) {
- return;
- }
-
- # Initialize counts
- $problems = 0;
-
- # Set default language code and checks
- if ( !$code ) {
- global $wgContLang;
- $code = $wgContLang->getCode();
- }
- if ( !$checks ) {
- $checks = array( 'untranslated', 'obsolete', 'variables', 'empty', 'whitespace', 'xhtml', 'chars' );
- }
-
- # Untranslated messages
- if ( in_array( 'untranslated', $checks ) ) {
- $generalMessages = $languages->getGeneralMessages();
- $requiredMessagesNumber = count( $generalMessages['required'] );
- $untranslatedMessages = $languages->getUntranslatedMessages( $code );
- $untranslatedMessagesNumber = count( $untranslatedMessages );
- $languages->outputMessagesList( $untranslatedMessages, $code, "\n$untranslatedMessagesNumber messages of $requiredMessagesNumber are not translated to $code, but exist in en:", $displayLevel, $links, $wikiLanguage );
- $problems += $untranslatedMessagesNumber;
- }
-
- # Duplicate messages
- if ( in_array( 'duplicate', $checks ) ) {
- $duplicateMessages = $languages->getDuplicateMessages( $code );
- $duplicateMessagesNumber = count( $duplicateMessages );
- $languages->outputMessagesList( $duplicateMessages, $code, "\n$duplicateMessagesNumber messages of $messagesNumber are translated the same in en and $code:", $displayLevel, $links, $wikiLanguage );
- $problems += $duplicateMessagesNumber;
- }
-
- # Obsolete messages
- if ( in_array( 'obsolete', $checks ) ) {
- $obsoleteMessages = $messages['obsolete'];
- $obsoleteMessagesNumber = count( $obsoleteMessages );
- $languages->outputMessagesList( $obsoleteMessages, $code, "\n$obsoleteMessagesNumber messages of $messagesNumber do not exist in en (or are in the ignored list), but still exist in $code:", $displayLevel, $links, $wikiLanguage );
- $problems += $obsoleteMessagesNumber;
- }
-
- # Messages without variables
- if ( in_array( 'variables', $checks ) ) {
- $messagesWithoutVariables = $languages->getMessagesWithoutVariables( $code );
- $messagesWithoutVariablesNumber = count( $messagesWithoutVariables );
- $languages->outputMessagesList( $messagesWithoutVariables, $code, "\n$messagesWithoutVariablesNumber messages of $messagesNumber in $code don't use some variables while en uses them:", $displayLevel, $links, $wikiLanguage );
- $problems += $messagesWithoutVariablesNumber;
- }
-
- # Messages without plural
- if ( in_array( 'plural', $checks ) ) {
- $messagesWithoutPlural = $languages->getMessagesWithoutPlural( $code );
- $messagesWithoutPluralNumber = count( $messagesWithoutPlural );
- $languages->outputMessagesList( $messagesWithoutPlural, $code, "\n$messagesWithoutPluralNumber messages of $messagesNumber in $code don't use {{plural}} while en uses it:", $displayLevel, $links, $wikiLanguage );
- $problems += $messagesWithoutPluralNumber;
- }
-
- # Empty messages
- if ( in_array( 'empty', $checks ) ) {
- $emptyMessages = $languages->getEmptyMessages( $code );
- $emptyMessagesNumber = count( $emptyMessages );
- $languages->outputMessagesList( $emptyMessages, $code, "\n$emptyMessagesNumber messages of $messagesNumber in $code are empty or -:", $displayLevel, $links, $wikiLanguage );
- $problems += $emptyMessagesNumber;
- }
-
- # Messages with whitespace
- if ( in_array( 'whitespace', $checks ) ) {
- $messagesWithWhitespace = $languages->getMessagesWithWhitespace( $code );
- $messagesWithWhitespaceNumber = count( $messagesWithWhitespace );
- $languages->outputMessagesList( $messagesWithWhitespace, $code, "\n$messagesWithWhitespaceNumber messages of $messagesNumber in $code have a trailing whitespace:", $displayLevel, $links, $wikiLanguage );
- $problems += $messagesWithWhitespaceNumber;
- }
-
- # Non-XHTML messages
- if ( in_array( 'xhtml', $checks ) ) {
- $nonXHTMLMessages = $languages->getNonXHTMLMessages( $code );
- $nonXHTMLMessagesNumber = count( $nonXHTMLMessages );
- $languages->outputMessagesList( $nonXHTMLMessages, $code, "\n$nonXHTMLMessagesNumber messages of $messagesNumber in $code are not well-formed XHTML:", $displayLevel, $links, $wikiLanguage );
- $problems += $nonXHTMLMessagesNumber;
- }
-
- # Messages with wrong characters
- if ( in_array( 'chars', $checks ) ) {
- $messagesWithWrongChars = $languages->getMessagesWithWrongChars( $code );
- $messagesWithWrongCharsNumber = count( $messagesWithWrongChars );
- $languages->outputMessagesList( $messagesWithWrongChars, $code, "\n$messagesWithWrongCharsNumber messages of $messagesNumber in $code include hidden chars which should not be used in the messages:", $displayLevel, $links, $wikiLanguage );
- $problems += $messagesWithWrongCharsNumber;
- }
-
- return $problems;
-}
+# Blacklist some checks for some languages
+$checkBlacklist = array(
+#'code' => array( 'check1', 'check2' ... )
+'gan' => array( 'plural' ),
+'hak' => array( 'plural' ),
+'ja' => array( 'plural' ), // Does not use plural
+'my' => array( 'chars' ), // Uses a lot zwnj
+'tet' => array( 'plural' ),
+'th' => array( 'plural' ),
+'wuu' => array( 'plural' ),
+'yue' => array( 'plural' ),
+'zh' => array( 'plural' ),
+'zh-classical' => array( 'plural' ),
+'zh-cn' => array( 'plural' ),
+'zh-hans' => array( 'plural' ),
+'zh-hant' => array( 'plural' ),
+'zh-hk' => array( 'plural' ),
+'zh-sg' => array( 'plural' ),
+'zh-tw' => array( 'plural' ),
+'zh-yue' => array( 'plural' ),
+);
diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php
index 42a43c02..36d32a48 100644
--- a/maintenance/language/checkLanguage.php
+++ b/maintenance/language/checkLanguage.php
@@ -7,31 +7,137 @@
require_once( dirname(__FILE__).'/../commandLine.inc' );
require_once( 'languages.inc' );
-require_once( 'checkLanguage.inc' );
-# Show help
-if ( isset( $options['help'] ) ) {
- echo <<<ENDS
+$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). You can also specify "all" to check all the languages.
+ * 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: Make only the following checks (form: code,code).
- * blacklist: Don't make the following checks (form: code,code).
+ * 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).
- * plural: Additionally check for messages that don't use plural while English does (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):
+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.
+ * 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.
@@ -39,47 +145,170 @@ Display levels (default: 2):
* 3: Show both the headers and the complete messages, with both keys and values.
ENDS;
- exit();
-}
+ }
-# Get the parameters
-$wgCode = isset( $options['lang'] ) ? $options['lang'] : null;
-$wgDisplayLevel = isset( $options['level'] ) ? $options['level'] : 2;
-$wgLinks = isset( $options['links'] );
-$wgWikiLanguage = isset( $options['wikilang'] ) ? $options['wikilang'] : 'en';
-$wgCheckEXIF = !isset( $options['noexif'] );
-
-# Get the checks
-$wgChecks = array( 'untranslated', 'obsolete', 'variables', 'empty', 'whitespace', 'xhtml', 'chars' );
-if ( isset( $options['whitelist'] ) ) {
- $wgChecks = explode( ',', $options['whitelist'] );
-} elseif ( isset( $options['blacklist'] ) ) {
- $wgChecks = array_diff( $wgChecks, explode( ',', $options['blacklist'] ) );
-}
-if ( isset( $options['duplicate'] ) ) {
- $wgChecks[] = 'duplicate';
-}
-if ( isset( $options['plural'] ) ) {
- $wgChecks[] = 'plural';
-}
+ 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");
+ }
+ }
+ }
-# Get language object
-$wgLanguages = new languages( $wgCheckEXIF );
+ protected function doChecks() {
+ $ignoredCodes = array( 'en', 'enRTL' );
-# Check the language
-if ( $wgCode == 'all' ) {
- foreach ( $wgLanguages->getLanguages() as $language ) {
- if ( $language != 'en' && $language != 'enRTL' ) {
- checkLanguage( $wgLanguages, $language );
+ $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 );
+ }
}
}
-} else {
- # Can't check English or English RTL
- if ( $wgCode == 'en' ) {
- echo "Current selected language is English, which cannot be checked.\n";
- } else if ( $wgCode == 'enRTL' ) {
- echo "Current selected language is RTL English, which cannot be checked.\n";
- } else {
- checkLanguage( $wgLanguages, $wgCode, $wgDisplayLevel, $wgLinks, $wgWikiLanguage, $wgChecks );
+
+ 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/lang2po.php b/maintenance/language/lang2po.php
index 0ea3faaa..a5aa81aa 100644
--- a/maintenance/language/lang2po.php
+++ b/maintenance/language/lang2po.php
@@ -7,6 +7,8 @@
* - fix escaping of \
*/
+$optionsWithArgs[] = 'lang';
+
/** This is a command line script */
require_once(dirname(__FILE__).'/../commandLine.inc');
require_once(dirname(__FILE__).'/languages.inc');
@@ -73,7 +75,7 @@ function generatePo($langcode, $messages) {
$data = poHeader();
// Generate .po entries
- foreach($messages as $identifier => $content) {
+ foreach($messages['all'] as $identifier => $content) {
$data .= "msgid \"$identifier\"\n";
// Escape backslashes
@@ -134,11 +136,17 @@ echo "done.\n";
$langTool = new languages();
+if( $options['lang'] === ALL_LANGUAGES ) {
+ $codes = $langTool->getLanguages();
+} else {
+ $codes = array( $options['lang'] );
+}
+
// Do all languages
-foreach ( $langTool->getLanguages() as $langcode) {
+foreach ( $codes as $langcode) {
echo "Loading messages for $langcode:\n";
if( ! generatePo($langcode, $langTool->getMessages($langcode) ) ) {
- echo "ERROR: Failed to wrote file.\n";
+ echo "ERROR: Failed to write file.\n";
} else {
echo "Applying template:";
applyPot($langcode);
diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc
index a10cae9e..9472e254 100644
--- a/maintenance/language/languages.inc
+++ b/maintenance/language/languages.inc
@@ -5,8 +5,6 @@
* @addtogroup Maintenance
*/
-require_once( 'messageTypes.inc' );
-
class languages {
protected $mLanguages; # List of languages
protected $mRawMessages; # Raw list of the messages in each language
@@ -22,7 +20,7 @@ class languages {
* @param $exif Treat the EXIF messages?
*/
function __construct( $exif = true ) {
- global $wgIgnoredMessages, $wgOptionalMessages, $wgEXIFMessages;
+ require( dirname(__FILE__) . '/messageTypes.inc' );
$this->mIgnoredMessages = $wgIgnoredMessages;
if ( $exif ) {
$this->mOptionalMessages = array_merge( $wgOptionalMessages );
@@ -62,9 +60,9 @@ class languages {
}
/**
- * Load the raw messages for a specific langauge from the messages file.
+ * Load the raw messages for a specific language from the messages file.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*/
protected function loadRawMessages( $code ) {
if ( isset( $this->mRawMessages[$code] ) ) {
@@ -149,7 +147,7 @@ class languages {
}
/**
- * Get all the messages for a specific langauge (not English), without the
+ * Get all the messages for a specific language (not English), without the
* fallback language messages, divided to groups:
* all - all the messages.
* required - messages which should be translated in order to get a complete translation.
@@ -157,7 +155,7 @@ class languages {
* obsolete - messages which should not be translated, either because they are not exist, or they are ignored messages.
* translated - messages which are either required or optional, but translated from English and needed.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The messages in this language.
*/
@@ -184,7 +182,7 @@ class languages {
/**
* Get the untranslated messages for a specific language.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The untranslated messages for this language.
*/
@@ -203,7 +201,7 @@ class languages {
/**
* Get the duplicate messages for a specific language.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The duplicate messages for this language.
*/
@@ -219,10 +217,16 @@ class languages {
return $duplicateMessages;
}
+ public function getObsoleteMessages( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ return $this->mMessages[$code]['obsolete'];
+ }
+
/**
* Get the messages which do not use some variables.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The messages which do not use some variables in this language.
*/
@@ -249,7 +253,7 @@ class languages {
/**
* Get the messages which do not use plural.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The messages which do not use plural in this language.
*/
@@ -268,7 +272,7 @@ class languages {
/**
* Get the empty messages.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The empty messages for this language.
*/
@@ -287,7 +291,7 @@ class languages {
/**
* Get the messages with trailing whitespace.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The messages with trailing whitespace in this language.
*/
@@ -306,7 +310,7 @@ class languages {
/**
* Get the non-XHTML messages.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The non-XHTML messages for this language.
*/
@@ -332,7 +336,7 @@ class languages {
/**
* Get the messages which include wrong characters.
*
- * @param $code The langauge code.
+ * @param $code The language code.
*
* @return The messages which include wrong characters in this language.
*/
@@ -366,49 +370,52 @@ class languages {
return $wrongCharsMessages;
}
- /**
- * Output a messages list
- *
- * @param $messages The messages list
- * @param $code The language code
- * @param $text The text to show before the list (optional)
- * @param $level The display level (optional)
- * @param $links Show links (optional)
- * @param $wikilang The langauge of the wiki to display the list in, for the links (optional)
- */
- public function outputMessagesList( $messages, $code, $text = '', $level = 2, $links = false, $wikilang = null ) {
- if ( count( $messages ) == 0 ) {
- return;
- }
- if ( $text ) {
- echo "$text\n";
- }
- if ( $level == 1 ) {
- echo "[messages are hidden]\n";
- } else {
- foreach ( $messages as $key => $value ) {
- if ( $links ) {
- $displayKey = ucfirst( $key );
- if ( !isset( $wikilang ) ) {
- global $wgContLang;
- $wikilang = $wgContLang->getCode();
- }
- if ( $code == $wikilang ) {
- $displayKey = "[[MediaWiki:$displayKey|$key]]";
- } else {
- $displayKey = "[[MediaWiki:$displayKey/$code|$key]]";
- }
- } else {
- $displayKey = $key;
+ public function getMessagesWithDubiousLinks( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $tc = Title::legalChars() . '#%{}';
+ $messages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+ $matches = array();
+ preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $value, $matches);
+ for ($i = 0; $i < count($matches[0]); $i++ ) {
+ if ( preg_match( "/.*project.*/isDu", $matches[1][$i]) ) {
+ $messages[$key][] = $matches[0][$i];
}
- if ( $level == 2 ) {
- echo "* $displayKey\n";
- } else {
- echo "* $displayKey: '$value'\n";
+ }
+
+
+ if ( isset( $messages[$key] ) ) {
+ $messages[$key] = implode( $messages[$key],", " );
+ }
+ }
+ return $messages;
+ }
+
+ public function getMessagesWithUnbalanced( $code ) {
+ $this->loadGeneralMessages();
+ $this->loadMessages( $code );
+ $messages = array();
+ foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
+
+ $a = $b = $c = $d = 0;
+ foreach ( preg_split('//', $value) as $char ) {
+ switch ($char) {
+ case '[': $a++; break;
+ case ']': $b++; break;
+ case '{': $c++; break;
+ case '}': $d++; break;
}
}
+
+ if ( $a !== $b || $c !== $d ) {
+ $messages[$key] = "$a, $b, $c, $d";
+ }
+
}
+ return $messages;
}
+
}
?>
diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc
index 21734eb3..43ca41c2 100644
--- a/maintenance/language/messageTypes.inc
+++ b/maintenance/language/messageTypes.inc
@@ -30,6 +30,8 @@ $wgIgnoredMessages = array(
'accesskey-ca-watch',
'accesskey-ca-unwatch',
'accesskey-search',
+ 'accesskey-search-go',
+ 'accesskey-search-fulltext',
'accesskey-p-logo',
'accesskey-n-mainpage',
'accesskey-n-portal',
@@ -75,6 +77,7 @@ $wgIgnoredMessages = array(
'exif-software-value',
'history_copyright',
'licenses',
+ 'loginstart',
'loginend',
'loginlanguagelinks',
'markaspatrolledlink',
@@ -92,6 +95,8 @@ $wgIgnoredMessages = array(
'revision-nav',
'rfcurl',
'shareddescriptionfollows',
+ 'signature',
+ 'signature-anon',
'signupend',
'sitenotice',
'sitesubtitle',
@@ -116,6 +121,7 @@ $wgOptionalMessages = array(
'allpages-summary',
'booksources-summary',
'ipblocklist-summary',
+ 'protectedtitles-summary',
'listusers-summary',
'longpages-summary',
'preferences-summary',
@@ -153,6 +159,11 @@ $wgOptionalMessages = array(
'unusedtemplates-summary',
'fewestrevisions-summary',
'withoutinterwiki-summary',
+ 'upload-summary',
+ 'tog-nolangconversion',
+ 'yourvariant',
+ 'variantname-zh-hans',
+ 'variantname-zh-hant',
'variantname-zh-cn',
'variantname-zh-tw',
'variantname-zh-hk',
@@ -163,6 +174,9 @@ $wgOptionalMessages = array(
'variantname-sr-jc',
'variantname-sr-jl',
'variantname-sr',
+ 'variantname-kk-arab',
+ 'variantname-kk-cyrl',
+ 'variantname-kk-latn',
'variantname-kk-tr',
'variantname-kk-kz',
'variantname-kk-cn',
@@ -172,6 +186,12 @@ $wgOptionalMessages = array(
'variantname-ku',
'rc-change-size',
'resetpass_text',
+ 'image_sample',
+ 'media_sample',
+ 'common.css',
+ 'monobook.css',
+ 'common.js',
+ 'monobook.js',
'widthheight',
'exif-fnumber-format',
'exif-focallength-format',
@@ -203,7 +223,57 @@ $wgOptionalMessages = array(
'hours-abbrev',
'filerevert-backlink',
'filedelete-backlink',
+ 'delete-backlink',
'pagetitle',
+ 'filename-prefix-blacklist',
+ 'edittools',
+ 'patrol-log-diff',
+ 'size-bytes',
+ 'size-kilobytes',
+ 'size-megabytes',
+ 'size-gigabytes',
+ 'iranian-calendar-m1',
+ 'iranian-calendar-m2',
+ 'iranian-calendar-m3',
+ 'iranian-calendar-m4',
+ 'iranian-calendar-m5',
+ 'iranian-calendar-m6',
+ 'iranian-calendar-m7',
+ 'iranian-calendar-m8',
+ 'iranian-calendar-m9',
+ 'iranian-calendar-m10',
+ 'iranian-calendar-m11',
+ 'iranian-calendar-m12',
+ 'hebrew-calendar-m1',
+ 'hebrew-calendar-m2',
+ 'hebrew-calendar-m3',
+ 'hebrew-calendar-m4',
+ 'hebrew-calendar-m5',
+ 'hebrew-calendar-m6',
+ 'hebrew-calendar-m6a',
+ 'hebrew-calendar-m6b',
+ 'hebrew-calendar-m7',
+ 'hebrew-calendar-m8',
+ 'hebrew-calendar-m9',
+ 'hebrew-calendar-m10',
+ 'hebrew-calendar-m11',
+ 'hebrew-calendar-m12',
+ 'hebrew-calendar-m1-gen',
+ 'hebrew-calendar-m2-gen',
+ 'hebrew-calendar-m3-gen',
+ 'hebrew-calendar-m4-gen',
+ 'hebrew-calendar-m5-gen',
+ 'hebrew-calendar-m6-gen',
+ 'hebrew-calendar-m6a-gen',
+ 'hebrew-calendar-m6b-gen',
+ 'hebrew-calendar-m7-gen',
+ 'hebrew-calendar-m8-gen',
+ 'hebrew-calendar-m9-gen',
+ 'hebrew-calendar-m10-gen',
+ 'hebrew-calendar-m11-gen',
+ 'hebrew-calendar-m12-gen',
+ 'semicolon-separator',
+ 'comma-separator',
);
/** 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 00763033..8b818d16 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -142,6 +142,7 @@ $wgMessageStructure = array(
'mytalk',
'anontalk',
'navigation',
+ 'and',
),
'metadata_help' => array(
'metadata_help',
@@ -262,11 +263,17 @@ $wgMessageStructure = array(
'restorelink',
'feedlinks',
'feed-invalid',
+ 'feed-unavailable',
+ 'site-rss-feed',
+ 'site-atom-feed',
+ 'page-rss-feed',
+ 'page-atom-feed',
'feed-atom',
'feed-rss',
'sitenotice',
'anonnotice',
'newsectionheaderdefaultlevel',
+ 'red-link-title',
),
'nstab' => array(
'nstab-main',
@@ -321,6 +328,8 @@ $wgMessageStructure = array(
'wrong_wfQuery_params',
'viewsource',
'viewsourcefor',
+ 'actionthrottled',
+ 'actionthrottledtext',
'protectedpagetext',
'viewsourcetext',
'protectedinterface',
@@ -330,6 +339,7 @@ $wgMessageStructure = array(
'namespaceprotected',
'customcssjsprotected',
'ns-specialprotected',
+ 'titleprotected',
),
'login' => array(
'logouttitle',
@@ -370,6 +380,7 @@ $wgMessageStructure = array(
'prefs-help-realname',
'loginerror',
'prefs-help-email',
+ 'prefs-help-email-required',
'nocookiesnew',
'nocookieslogin',
'noname',
@@ -389,6 +400,7 @@ $wgMessageStructure = array(
'blocked-mailpassword',
'eauthentsent',
'throttled-mailpassword',
+ 'loginstart',
'loginend',
'signupend',
'mailerror',
@@ -400,6 +412,8 @@ $wgMessageStructure = array(
'invalidemailaddress',
'accountcreated',
'accountcreatedtext',
+ 'createaccount-title',
+ 'createaccount-text',
'loginlanguagelabel',
'loginlanguagelinks',
),
@@ -455,6 +469,7 @@ $wgMessageStructure = array(
'blockedtitle',
'blockedtext',
'autoblockedtext',
+ 'blockednoreason',
'blockedoriginalsource',
'blockededitsource',
'whitelistedittitle',
@@ -479,6 +494,7 @@ $wgMessageStructure = array(
'anontalkpagetext',
'noarticletext',
'noarticletextanon',
+ 'userpage-userdoesnotexist',
'clearyourcache',
'usercssjsyoucanpreview',
'usercsspreview',
@@ -510,6 +526,7 @@ $wgMessageStructure = array(
'protectedpagewarning',
'semiprotectedpagewarning',
'cascadeprotectedwarning',
+ 'titleprotectedwarning',
'templatesused',
'templatesusedpreview',
'templatesusedsection',
@@ -530,10 +547,9 @@ $wgMessageStructure = array(
),
'cantcreateaccount' => array(
'cantcreateaccounttitle',
- 'cantcreateaccounttext',
+ 'cantcreateaccount-text',
),
'history' => array(
- 'revhistory',
'viewpagelogs',
'nohistory',
'revnotfound',
@@ -602,13 +618,34 @@ $wgMessageStructure = array(
'oversightlog',
'overlogpagetext',
),
+ 'mergehistory' => array(
+ 'mergehistory',
+ 'mergehistory-header',
+ 'mergehistory-box',
+ 'mergehistory-from',
+ 'mergehistory-into',
+ 'mergehistory-list',
+ 'mergehistory-merge',
+ 'mergehistory-go',
+ 'mergehistory-submit',
+ 'mergehistory-empty',
+ 'mergehistory-success',
+ 'mergehistory-fail',
+ 'mergehistory-no-source',
+ 'mergehistory-no-destination',
+ 'mergehistory-invalid-source',
+ 'mergehistory-invalid-destination',
+ ),
+ 'mergelog' => array(
+ 'mergelog',
+ 'pagemerge-logentry',
+ 'revertmerge',
+ 'mergelogpagetext',
+ ),
'diffs' => array(
+ 'history-title',
'difference',
- 'loadingrev',
'lineno',
- 'editcurrent',
- 'selectnewerversionfordiff',
- 'selectolderversionfordiff',
'compareselectedversions',
'editundo',
'diff-multi',
@@ -619,6 +656,8 @@ $wgMessageStructure = array(
'searchsubtitle',
'searchsubtitleinvalid',
'noexactmatch',
+ 'noexactmatch-nocreate',
+ 'toomanymatches',
'titlematches',
'notitlematches',
'textmatches',
@@ -703,12 +742,19 @@ $wgMessageStructure = array(
'userrights-editusergroup',
'saveusergroups',
'userrights-groupsmember',
+ 'userrights-groupsremovable',
'userrights-groupsavailable',
'userrights-groupshelp',
'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',
),
'group' => array(
'group',
@@ -782,7 +828,11 @@ $wgMessageStructure = array(
'uploadnologintext',
'upload_directory_read_only',
'uploaderror',
+ 'upload-summary',
'uploadtext',
+ 'upload-permitted',
+ 'upload-preferred',
+ 'upload-prohibited',
'uploadlog',
'uploadlogpage',
'uploadlogpagetext',
@@ -798,12 +848,14 @@ $wgMessageStructure = array(
'illegalfilename',
'badfilename',
'filetype-badmime',
- 'filetype-badtype',
+ 'filetype-unwanted-type',
+ 'filetype-banned-type',
'filetype-missing',
'large-file',
'largefileserver',
'emptyfile',
'fileexists',
+ 'filepageexists',
'fileexists-extension',
'fileexists-thumb',
'fileexists-thumbnail-yes',
@@ -824,6 +876,9 @@ $wgMessageStructure = array(
'destfilename',
'watchthisupload',
'filewasdeleted',
+ 'upload-wasdeleted',
+ 'filename-bad-prefix',
+ 'filename-prefix-blacklist',
),
'upload-errors' => array(
'upload-proto-error',
@@ -876,6 +931,7 @@ $wgMessageStructure = array(
'nolinkstoimage',
'sharedupload',
'shareduploadwiki',
+ 'shareduploadwiki-desc',
'shareduploadwiki-linktext',
'shareddescriptionfollows',
'noimage',
@@ -912,6 +968,9 @@ $wgMessageStructure = array(
'filedelete-nofile',
'filedelete-nofile-old',
'filedelete-iscurrent',
+ 'filedelete-otherreason',
+ 'filedelete-reason-otherlist',
+ 'filedelete-reason-dropdown',
),
'mimesearch' => array(
'mimesearch',
@@ -933,6 +992,11 @@ $wgMessageStructure = array(
'unusedtemplatestext',
'unusedtemplateswlh',
),
+ 'randompage' => array(
+ 'randompage',
+ 'randompage-nopages',
+ 'randompage-url',
+ ),
'randomredirect' => array(
'randomredirect',
'randomredirect-nopages',
@@ -968,6 +1032,7 @@ $wgMessageStructure = array(
'withoutinterwiki',
'withoutinterwiki-header',
'withoutinterwiki-summary',
+ 'withoutinterwiki-submit',
),
'fewestrevisions' => array(
'fewestrevisions',
@@ -1017,9 +1082,6 @@ $wgMessageStructure = array(
'allpages-summary',
'prefixindex',
'prefixindex-summary',
- 'randompage',
- 'randompage-nopages',
- 'randompage-url',
'shortpages',
'shortpages-summary',
'longpages',
@@ -1031,13 +1093,16 @@ $wgMessageStructure = array(
'protectedpages-summary',
'protectedpagestext',
'protectedpagesempty',
+ 'protectedtitles',
+ 'protectedtitles-summary',
+ 'protectedtitlestext',
+ 'protectedtitlesempty',
'listusers',
'listusers-summary',
'specialpages',
'specialpages-summary',
'spheading',
'restrictedpheading',
- 'rclsub',
'newpages',
'newpages-summary',
'newpages-username',
@@ -1048,6 +1113,10 @@ $wgMessageStructure = array(
'movethispage',
'unusedimagestext',
'unusedcategoriestext',
+ 'notargettitle',
+ 'notargettext',
+ 'pager-newer-n',
+ 'pager-older-n',
),
'booksources' => array(
'booksources',
@@ -1177,8 +1246,9 @@ $wgMessageStructure = array(
'excontentauthor',
'exbeforeblank',
'exblank',
- 'confirmdelete',
- 'deletesub',
+ 'delete-confirm',
+ 'delete-backlink',
+ 'delete-legend',
'historywarning',
'confirmdeletetext',
'actioncomplete',
@@ -1189,6 +1259,11 @@ $wgMessageStructure = array(
'deletionlog',
'reverted',
'deletecomment',
+ 'deleteotherreason',
+ 'deletereasonotherlist',
+ 'deletereason-dropdown',
+ 'delete-toobig',
+ 'delete-warning-toobig',
'rollback',
'rollback_short',
'rollbacklink',
@@ -1224,6 +1299,7 @@ $wgMessageStructure = array(
'protect-summary-cascade',
'protect-expiring',
'protect-cascade',
+ 'protect-cantedit',
'restriction-type',
'restriction-level',
'minimum-size',
@@ -1233,6 +1309,7 @@ $wgMessageStructure = array(
'restrictions' => array(
'restriction-edit',
'restriction-move',
+ 'restriction-create',
),
'restriction-levels' => array(
'restriction-level-sysop',
@@ -1251,7 +1328,9 @@ $wgMessageStructure = array(
'undeletehistorynoadmin',
'undelete-revision',
'undeleterevision-missing',
+ 'undelete-nodiff',
'undeletebtn',
+ 'undeletelink',
'undeletereset',
'undeletecomment',
'undeletedarticle',
@@ -1289,10 +1368,6 @@ $wgMessageStructure = array(
'year',
),
'sp-contributions' => array(
- 'sp-contributions-newest',
- 'sp-contributions-oldest',
- 'sp-contributions-newer',
- 'sp-contributions-older',
'sp-contributions-newbies',
'sp-contributions-newbies-sub',
'sp-contributions-blocklog',
@@ -1310,9 +1385,8 @@ $wgMessageStructure = array(
'whatlinkshere',
'whatlinkshere-title',
'whatlinkshere-summary',
+ 'whatlinkshere-page',
'whatlinkshere-barrow',
- 'notargettitle',
- 'notargettext',
'linklistsub',
'linkshere',
'nolinkshere',
@@ -1384,9 +1458,12 @@ $wgMessageStructure = array(
'range_block_disabled',
'ipb_expiry_invalid',
'ipb_already_blocked',
+ 'ipb_cant_unblock',
+ 'ipb_blocked_as_range',
'ip_range_invalid',
+ 'blockme',
'proxyblocker',
- 'ipb_cant_unblock',
+ 'proxyblocker-disabled',
'proxyblockreason',
'proxyblocksuccess',
'sorbs',
@@ -1424,6 +1501,7 @@ $wgMessageStructure = array(
'pagemovedsub',
'movepage-moved',
'articleexists',
+ 'cantmove-titleprotected',
'talkexists',
'movedto',
'movetalk',
@@ -1451,6 +1529,7 @@ $wgMessageStructure = array(
'export-addcattext',
'export-addcat',
'export-download',
+ 'export-templates',
),
'allmessages' => array(
'allmessages',
@@ -1464,7 +1543,6 @@ $wgMessageStructure = array(
),
'thumbnails' => array(
'thumbnail-more',
- 'missingimage',
'filemissing',
'thumbnail_error',
'djvu_page_error',
@@ -1492,7 +1570,13 @@ $wgMessageStructure = array(
'importhistoryconflict',
'importnosources',
'importnofile',
- 'importuploaderror',
+ 'importuploaderrorsize',
+ 'importuploaderrorpartial',
+ 'importuploaderrortemp',
+ 'import-parse-failure',
+ 'import-noarticle',
+ 'import-nonewrevisions',
+ 'xml-error-string',
),
'importlog' => array(
'importlogpage',
@@ -1525,6 +1609,8 @@ $wgMessageStructure = array(
'accesskey-ca-watch',
'accesskey-ca-unwatch',
'accesskey-search',
+ 'accesskey-search-go',
+ 'accesskey-search-fulltext',
'accesskey-p-logo',
'accesskey-n-mainpage',
'accesskey-n-portal',
@@ -1535,6 +1621,7 @@ $wgMessageStructure = array(
'accesskey-n-sitesupport',
'accesskey-t-whatlinkshere',
'accesskey-t-recentchangeslinked',
+ 'accesskey-t-random',
'accesskey-feed-rss',
'accesskey-feed-atom',
'accesskey-t-contributions',
@@ -1584,6 +1671,8 @@ $wgMessageStructure = array(
'tooltip-ca-watch',
'tooltip-ca-unwatch',
'tooltip-search',
+ 'tooltip-search-go',
+ 'tooltip-search-fulltext',
'tooltip-p-logo',
'tooltip-n-mainpage',
'tooltip-n-portal',
@@ -1594,6 +1683,7 @@ $wgMessageStructure = array(
'tooltip-n-sitesupport',
'tooltip-t-whatlinkshere',
'tooltip-t-recentchangeslinked',
+ 'tooltip-t-random',
'tooltip-feed-rss',
'tooltip-feed-atom',
'tooltip-t-contributions',
@@ -1638,7 +1728,6 @@ $wgMessageStructure = array(
'anonymous',
'siteuser',
'lastmodifiedatby',
- 'and',
'othercontribs',
'others',
'siteusers',
@@ -1734,6 +1823,8 @@ $wgMessageStructure = array(
'bad_image_list',
),
'variantname-zh' => array(
+ 'variantname-zh-hans',
+ 'variantname-zh-hant',
'variantname-zh-cn',
'variantname-zh-tw',
'variantname-zh-hk',
@@ -1748,9 +1839,12 @@ $wgMessageStructure = array(
'variantname-sr',
),
'variantname-kk' => array(
- 'variantname-kk-tr',
'variantname-kk-kz',
+ 'variantname-kk-tr',
'variantname-kk-cn',
+ 'variantname-kk-cyrl',
+ 'variantname-kk-latn',
+ 'variantname-kk-arab',
'variantname-kk',
),
'variantname-ku' => array(
@@ -2132,9 +2226,12 @@ $wgMessageStructure = array(
'searchnamed',
'articletitles',
'hideresults',
+ 'useajaxsearch',
),
- 'catseparator' => array(
+ 'separators' => array(
'catseparator',
+ 'semicolon-separator',
+ 'comma-separator',
),
'imgmulti' => array(
'imgmultipageprev',
@@ -2142,7 +2239,6 @@ $wgMessageStructure = array(
'imgmultigo',
'imgmultigotopre',
'imgmultigotopost',
- 'imgmultiparseerror',
),
'tablepager' => array(
'ascending_abbrev',
@@ -2183,11 +2279,6 @@ $wgMessageStructure = array(
'watchlisteditor' => array(
'watchlistedit-numitems',
'watchlistedit-noitems',
- 'watchlistedit-clear-title',
- 'watchlistedit-clear-legend',
- 'watchlistedit-clear-confirm',
- 'watchlistedit-clear-submit',
- 'watchlistedit-clear-done',
'watchlistedit-normal-title',
'watchlistedit-normal-legend',
'watchlistedit-normal-explain',
@@ -2206,7 +2297,83 @@ $wgMessageStructure = array(
'watchlisttools-view',
'watchlisttools-edit',
'watchlisttools-raw',
- 'watchlisttools-clear',
+ ),
+ 'iranian-dates' => array(
+ 'iranian-calendar-m1',
+ 'iranian-calendar-m2',
+ 'iranian-calendar-m3',
+ 'iranian-calendar-m4',
+ 'iranian-calendar-m5',
+ 'iranian-calendar-m6',
+ 'iranian-calendar-m7',
+ 'iranian-calendar-m8',
+ 'iranian-calendar-m9',
+ 'iranian-calendar-m10',
+ 'iranian-calendar-m11',
+ 'iranian-calendar-m12',
+ ),
+ 'hebrew-dates' => array(
+ 'hebrew-calendar-m1',
+ 'hebrew-calendar-m2',
+ 'hebrew-calendar-m3',
+ 'hebrew-calendar-m4',
+ 'hebrew-calendar-m5',
+ 'hebrew-calendar-m6',
+ 'hebrew-calendar-m6a',
+ 'hebrew-calendar-m6b',
+ 'hebrew-calendar-m7',
+ 'hebrew-calendar-m8',
+ 'hebrew-calendar-m9',
+ 'hebrew-calendar-m10',
+ 'hebrew-calendar-m11',
+ 'hebrew-calendar-m12',
+ 'hebrew-calendar-m1-gen',
+ 'hebrew-calendar-m2-gen',
+ 'hebrew-calendar-m3-gen',
+ 'hebrew-calendar-m4-gen',
+ 'hebrew-calendar-m5-gen',
+ 'hebrew-calendar-m6-gen',
+ 'hebrew-calendar-m6a-gen',
+ 'hebrew-calendar-m6b-gen',
+ 'hebrew-calendar-m7-gen',
+ 'hebrew-calendar-m8-gen',
+ 'hebrew-calendar-m9-gen',
+ 'hebrew-calendar-m10-gen',
+ 'hebrew-calendar-m11-gen',
+ 'hebrew-calendar-m12-gen',
+ ),
+ 'signatures' => array(
+ 'signature',
+ 'signature-anon',
+ ),
+ 'CoreParserFunctions' => array(
+ 'unknown_extension_tag',
+ ),
+ 'version' => array(
+ 'version-extensions',
+ 'version-specialpages',
+ 'version-parserhooks',
+ 'version-variables',
+ 'version-other',
+ 'version-mediahandlers',
+ 'version-hooks',
+ 'version-extension-functions',
+ 'version-parser-extensiontags',
+ 'version-parser-function-hooks',
+ 'version-skin-extension-functions',
+ 'version-hook-name',
+ 'version-hook-subscribedby',
+ 'version-version',
+ 'version-license',
+ 'version-software',
+ 'version-software-product',
+ 'version-software-version',
+ ),
+ 'filepath' => array(
+ 'filepath',
+ 'filepath-page',
+ 'filepath-submit',
+ 'filepath-summary',
),
);
/** Comments for each block */
@@ -2230,7 +2397,7 @@ XHTML id names.",
'badaccess' => '',
'versionrequired' => '',
'miscellaneous3' => '',
- 'nstab' => "Short words for each namespace, by default used in the 'article' tab in monobook",
+ 'nstab' => "Short words for each namespace, by default used in the namespace tab in monobook",
'main' => 'Main script and global functions',
'errors' => 'General errors',
'login' => 'Login and logout pages',
@@ -2242,7 +2409,9 @@ XHTML id names.",
'history' => 'History pages',
'history-feed' => 'Revision feed',
'revdelete' => 'Revision deletion',
- 'oversightlog' => 'Oversight log',
+ 'oversightlog' => 'Oversight log',
+ 'mergehistory' => 'History merging',
+ 'mergelog' => 'Merge log',
'diffs' => 'Diffs',
'search' => 'Search results',
'preferences' => 'Preferences page',
@@ -2264,6 +2433,7 @@ XHTML id names.",
'unwatchedpages' => 'Unwatched pages',
'listredirects' => 'List redirects',
'unusedtemplates' => 'Unused templates',
+ 'randompage' => 'Random page',
'randomredirect' => 'Random redirect',
'statistics' => 'Statistics',
'disambiguations' => '',
@@ -2356,26 +2526,32 @@ Variants for Chinese language",
'exif-gpsmeasuremode' => '',
'exif-gpsspeed' => 'Pseudotags used for GPSSpeedRef and GPSDestDistanceRef',
'exif-gpsdirection' => 'Pseudotags used for GPSTrackRef, GPSImgDirectionRef and GPSDestBearingRef',
- 'edit-externally' => 'External editor support',
- 'all' => "'all' in various places, this might be different for inflected languages",
- 'confirmemail' => 'E-mail address confirmation',
- 'scarytransclusion' => 'Scary transclusion',
- 'trackbacks' => 'Trackbacks',
- 'deleteconflict' => 'Delete conflict',
- 'unit-pixel' => '',
- 'htmldump' => 'HTML dump',
- 'purge' => 'action=purge',
- 'search2' => 'AJAX search',
- 'catseparator' => 'Separator for categories in page lists',
- 'imgmulti' => 'Multipage image navigation',
- 'tablepager' => 'Table pager',
- 'autosumm' => 'Auto-summaries',
- 'autoblock_whitelist' => 'Autoblock whitelist',
- 'sizeunits' => 'Size units',
- 'livepreview' => 'Live preview',
- 'lagwarning' => 'Friendlier slave lag warnings',
- 'watchlisteditor' => 'Watchlist editor',
- 'watchlisttools' => 'Watchlist editing tools',
+ 'edit-externally' => 'External editor support',
+ 'all' => "'all' in various places, this might be different for inflected languages",
+ 'confirmemail' => 'E-mail address confirmation',
+ 'scarytransclusion' => 'Scary transclusion',
+ 'trackbacks' => 'Trackbacks',
+ 'deleteconflict' => 'Delete conflict',
+ 'unit-pixel' => '',
+ 'htmldump' => 'HTML dump',
+ 'purge' => 'action=purge',
+ 'search2' => 'AJAX search',
+ 'separators' => 'Separators for various lists',
+ 'imgmulti' => 'Multipage image navigation',
+ 'tablepager' => 'Table pager',
+ 'autosumm' => 'Auto-summaries',
+ 'autoblock_whitelist' => 'Autoblock whitelist',
+ 'sizeunits' => 'Size units',
+ 'livepreview' => 'Live preview',
+ 'lagwarning' => 'Friendlier slave lag warnings',
+ 'watchlisteditor' => 'Watchlist editor',
+ 'watchlisttools' => 'Watchlist editing tools',
+ 'iranian-dates' => 'Iranian month names',
+ 'hebrew-dates' => 'Hebrew month names',
+ 'signatures' => 'Signatures',
+ 'CoreParserFunctions' => 'Core parser functions',
+ 'version' => 'Special:Version',
+ 'filepath' => 'Special:Filepath',
);
/** Short comments for standalone messages */
@@ -2384,6 +2560,7 @@ $wgMessageComments = array(
'sitenotice' => 'the equivalent to wgSiteNotice',
'history-feed-item-nocomment' => 'user at time',
'editcomment' => 'only shown if there is an edit comment',
+ 'revertpage' => 'Additional available: $3: revid of the revision reverted to, $4: timestamp of the revision reverted to, $5: revid of the revision reverted from, $6: timestamp of the revision reverted from',
'lastmodifiedatby' => '$1 date, $2 time, $3 user',
'exif-orientation-1' => '0th row: top; 0th column: left',
'exif-orientation-2' => '0th row: top; 0th column: right',
@@ -2393,13 +2570,7 @@ $wgMessageComments = array(
'exif-orientation-6' => '0th row: right; 0th column: top',
'exif-orientation-7' => '0th row: right; 0th column: bottom',
'exif-orientation-8' => '0th row: left; 0th column: bottom',
- 'movepage-moved' => 'The two titles are passed in plain text as $3 and $4 to allow additional goodies in the message.'
-);
-
-/** Messages which contain dollar signs (which are not followed by numbers), and therefore should use a single apostrophe */
-$wgMessagseWithDollarSigns = array(
- 'linkprefix',
- 'enotif_subject',
- 'enotif_body',
- 'allmessagesnotsupportedDB',
+ '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',
);
diff --git a/maintenance/language/rebuildLanguage.php b/maintenance/language/rebuildLanguage.php
index 304f8b5c..6c2076eb 100644
--- a/maintenance/language/rebuildLanguage.php
+++ b/maintenance/language/rebuildLanguage.php
@@ -20,7 +20,7 @@ function rebuildLanguage( $code, $write, $listUnknown ) {
global $wgLanguages;
$messages = $wgLanguages->getMessages( $code );
$messages = $messages['all'];
- writeMessagesToFile( $messages, $code, $write, $listUnknown );
+ MessageWriter::writeMessagesToFile( $messages, $code, $write, $listUnknown );
}
# Show help
diff --git a/maintenance/language/splitLanguageFiles.inc b/maintenance/language/splitLanguageFiles.inc
index 500d2cdc..a57744bd 100644
--- a/maintenance/language/splitLanguageFiles.inc
+++ b/maintenance/language/splitLanguageFiles.inc
@@ -1122,7 +1122,6 @@ $commonMsg = array (
'movelogpagetext',
'thumbnail-more',
-'missingimage',
'filemissing',
'monobook.css',
'nodublincore',
diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php
index 6a1423a8..410bd695 100644
--- a/maintenance/language/transstat.php
+++ b/maintenance/language/transstat.php
@@ -10,9 +10,12 @@
* Output is posted from time to time on:
* http://meta.wikimedia.org/wiki/Localization_statistics
*/
+$optionsWithArgs = array( 'output' );
require_once( dirname(__FILE__).'/../commandLine.inc' );
require_once( 'languages.inc' );
+require_once( dirname(__FILE__).'/StatOutputs.php' );
+
if ( isset( $options['help'] ) ) {
showUsage();
@@ -39,100 +42,7 @@ END;
exit();
}
-/** A general output object. Need to be overriden */
-class statsOutput {
- function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
- return @sprintf( '%.' . $accuracy . 'f%%', 100 * $subset / $total );
- }
-
- # Override the following methods
- function heading() {
- }
- function footer() {
- }
- function blockstart() {
- }
- function blockend() {
- }
- function element( $in, $heading = false ) {
- }
-}
-
-/** Outputs WikiText */
-class wikiStatsOutput extends statsOutput {
- function heading() {
- global $IP;
- $version = SpecialVersion::getVersion( $IP );
- echo "'''Statistics are based on:''' <code>" . $version . "</code>\n\n";
- echo "'''Note:''' These statistics can be generated by running <code>php maintenance/language/transstat.php</code>.\n\n";
- echo "For additional information on specific languages (the message names, the actual problems, etc.), run <code>php maintenance/language/checkLanguage.php --lang=foo</code>.\n\n";
- echo '{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear:both;" width="100%"'."\n";
- }
- function footer() {
- echo "|}\n";
- }
- function blockstart() {
- echo "|-\n";
- }
- function blockend() {
- echo '';
- }
- function element( $in, $heading = false ) {
- echo ($heading ? '!' : '|') . " $in\n";
- }
- function formatPercent( $subset, $total, $revert = false, $accuracy = 2 ) {
- $v = @round(255 * $subset / $total);
- if ( $revert ) {
- $v = 255 - $v;
- }
- if ( $v < 128 ) {
- # Red to Yellow
- $red = 'FF';
- $green = sprintf( '%02X', 2 * $v );
- } else {
- # Yellow to Green
- $red = sprintf('%02X', 2 * ( 255 - $v ) );
- $green = 'FF';
- }
- $blue = '00';
- $color = $red . $green . $blue;
-
- $percent = statsOutput::formatPercent( $subset, $total, $revert, $accuracy );
- return 'bgcolor="#'. $color .'" | '. $percent;
- }
-}
-
-/** Outputs WikiText and appends category and text only used for Meta-Wiki */
-class metawikiStatsOutput extends wikiStatsOutput {
- function heading() {
- echo "See [[MediaWiki localisation]] to learn how you can help translating MediaWiki.\n\n";
- parent::heading();
- }
- function footer() {
- parent::footer();
- echo "\n[[Category:Localisation|Statistics]]\n";
- }
-}
-
-/** Output text. To be used on a terminal for example. */
-class textStatsOutput extends statsOutput {
- function element( $in, $heading = false ) {
- echo $in."\t";
- }
- function blockend() {
- echo "\n";
- }
-}
-/** csv output. Some people love excel */
-class csvStatsOutput extends statsOutput {
- function element( $in, $heading = false ) {
- echo $in . ";";
- }
- function blockend() {
- echo "\n";
- }
-}
# Select an output engine
switch ( $options['output'] ) {
diff --git a/maintenance/language/writeMessagesArray.inc b/maintenance/language/writeMessagesArray.inc
index bcbf05ee..2324785e 100644
--- a/maintenance/language/writeMessagesArray.inc
+++ b/maintenance/language/writeMessagesArray.inc
@@ -5,187 +5,251 @@
* @addtogroup Maintenance
*/
-require_once( 'messages.inc' );
-require_once( 'messageTypes.inc' );
-
-/**
- * Write a messages array as a PHP text and write it to the messages file.
- *
- * @param $messages The messages array.
- * @param $code The language code.
- * @param $write Write to the messages file?
- * @param $listUnknown List the unknown messages?
- */
-function writeMessagesToFile( $messages, $code, $write, $listUnknown ) {
- # Rewrite the messages array
- $messages = writeMessagesArray( $messages, $code == 'en' );
- $messagesText = $messages[0];
- $sortedMessages = $messages[1];
-
- # Write to the file
- $filename = Language::getMessagesFileName( $code );
- $contents = file_get_contents( $filename );
- if ( strpos( $contents, '$messages' ) !== false ) {
- $contents = explode( '$messages', $contents );
- if ( $messagesText == '$messages' . $contents[1] ) {
- echo "Generated messages for language $code. Same as the current file.\n";
- } else {
- if ( $write ) {
- $new = $contents[0];
- $new .= $messagesText;
- file_put_contents( $filename, $new );
- echo "Generated and wrote messages for language $code.\n";
+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 $loaded = false;
+ static $messageStructure;
+ static $blockComments;
+ static $messageComments;
+ static $ignoredMessages;
+ static $optionalMessages;
+
+ /**
+ * Write a messages array as a PHP text and write it to the messages file.
+ *
+ * @param $messages The messages array.
+ * @param $code The language code.
+ * @param $write Write to the messages file?
+ * @param $listUnknown List the unknown messages?
+ */
+ public static function writeMessagesToFile( $messages, $code, $write, $listUnknown ) {
+ # Rewrite the messages array
+ $messages = self::writeMessagesArray( $messages, $code == 'en' );
+ $messagesText = $messages[0];
+ $sortedMessages = $messages[1];
+
+ # Write to the file
+ $filename = Language::getMessagesFileName( $code );
+ $contents = file_get_contents( $filename );
+ if( strpos( $contents, '$messages' ) !== false ) {
+ $contents = explode( '$messages', $contents );
+ if( $messagesText == '$messages' . $contents[1] ) {
+ echo "Generated messages for language $code. Same as the current file.\n";
} else {
- echo "Generated messages for language $code. Please run the script again (without the parameter \"dry-run\") to write the array to the file.\n";
+ if( $write ) {
+ $new = $contents[0];
+ $new .= $messagesText;
+ file_put_contents( $filename, $new );
+ echo "Generated and wrote messages for language $code.\n";
+ } else {
+ echo "Generated messages for language $code. Please run the script again (without the parameter \"dry-run\") to write the array to the file.\n";
+ }
}
- }
- if ( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) {
- echo "\nThere are " . count( $sortedMessages['unknown'] ) . " unknown messages, please check them:\n";
- foreach ( $sortedMessages['unknown'] as $key => $value ) {
- echo "* " . $key . "\n";
+ if( $listUnknown && isset( $sortedMessages['unknown'] ) && !empty( $sortedMessages['unknown'] ) ) {
+ 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";
}
- } else {
- echo "Generated messages for language $code. There seems to be no messages array in the file.\n";
}
-}
-/**
- * Write a messages array as a PHP text.
- *
- * @param $messages The messages array.
- * @param $ignoredComments Show comments about ignored and optional messages? (For English.)
- *
- * @return Array of the PHP text and the sorted messages array.
- */
-function writeMessagesArray( $messages, $ignoredComments = false ) {
- global $wgMessageStructure, $wgBlockComments;
-
- # Sort messages to blocks
- $sortedMessages['unknown'] = $messages;
- foreach ( $wgMessageStructure as $blockName => $block ) {
- foreach ( $block as $key ) {
- if ( array_key_exists( $key, $sortedMessages['unknown'] ) ) {
- $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key];
- unset( $sortedMessages['unknown'][$key] );
+ /**
+ * Write a messages array as a PHP text.
+ *
+ * @param $messages The messages array.
+ * @param $ignoredComments Show comments about ignored and optional messages? (For English.)
+ *
+ * @return Array of the PHP text and the sorted messages array.
+ */
+ public static function writeMessagesArray( $messages, $ignoredComments = false ) {
+ # Load messages
+ if( !self::$loaded ) {
+ require( dirname( __FILE__ ) . '/messages.inc' );
+ self::$messageStructure = $wgMessageStructure;
+ self::$blockComments = $wgBlockComments;
+ self::$messageComments = $wgMessageComments;
+
+ require( dirname( __FILE__ ) . '/messageTypes.inc' );
+ self::$ignoredMessages = $wgIgnoredMessages;
+ self::$optionalMessages = $wgOptionalMessages;
+
+ self::$loaded = true;
+ }
+
+ # Sort messages to blocks
+ $sortedMessages['unknown'] = $messages;
+ foreach( self::$messageStructure as $blockName => $block ) {
+ foreach( $block as $key ) {
+ if( array_key_exists( $key, $sortedMessages['unknown'] ) ) {
+ $sortedMessages[$blockName][$key] = $sortedMessages['unknown'][$key];
+ unset( $sortedMessages['unknown'][$key] );
+ }
}
}
- }
- # Write all the messages
- $messagesText = "\$messages = array(
+ # Write all the messages
+ $messagesText = "\$messages = array(
";
- foreach( $sortedMessages as $block => $messages ) {
- # Skip if it's the block of unknown messages - handle that in the end of file
- if ( $block == 'unknown' ) {
- continue;
+ foreach( $sortedMessages as $block => $messages ) {
+ # Skip if it's the block of unknown messages - handle that in the end of file
+ if( $block == 'unknown' ) {
+ continue;
+ }
+
+ if( $ignoredComments ) {
+ $ignored = self::$ignoredMessages;
+ $optional = self::$optionalMessages;
+ } else {
+ $ignored = array();
+ $optional = array();
+ }
+ $comments = self::makeComments( array_keys($messages), self::$messageComments, $ignored, $optional );
+
+ # Write the block
+ $messagesText .= self::writeMessagesBlock( self::$blockComments[$block], $messages, $comments );
}
- # Write the block
- $messagesText .= writeMessagesBlock( $block, $wgBlockComments[$block], $messages, $ignoredComments );
- }
- ksort( $sortedMessages['unknown'] );
- $messagesText .= writeMessagesBlock( 'unknown', 'Unknown messages', $sortedMessages['unknown'], $ignoredComments ); # Write the unknown messages, alphabetically sorted
- $messagesText .= ");
+ # 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'] );
+ $messagesText .= ");
";
- return array( $messagesText, $sortedMessages );
-}
+ return array( $messagesText, $sortedMessages );
+ }
-/**
- * Write a block of messages to PHP.
- *
- * @param $name The block name.
- * @param $comment The block comment.
- * @param $messages The block messages.
- * @param $ignoredComments Show comments about ignored and optional messages? (For English.)
- *
- * @return The block, formatted in PHP.
- */
-function writeMessagesBlock( $name, $comment, $messages, $ignoredComments ) {
- global $wgMessageComments, $wgMessagseWithDollarSigns;
- global $wgIgnoredMessages, $wgOptionalMessages;
- $blockText = '';
-
- # Skip the block if it includes no messages
- if ( empty( $messages ) ) {
- return '';
+ /**
+ * Generates an array of comments for messages.
+ *
+ * @param $messages Key of messages.
+ * @param $comments Comments for messages, indexed by key.
+ * @param $ignored List of ingored message keys.
+ * @param $optional List of optional message keys.
+ */
+ public static function makeComments( $messages, $comments, $ignored, $optional ) {
+ # Comment collector
+ $commentArray = array();
+
+ # List of keys only
+ foreach( $messages as $key ) {
+ $commentsForKey = array();
+
+ # Add descriptive comment for this message if there is one
+ if( array_key_exists( $key, $comments ) ) {
+ $commentsForKey[] = $comments[$key];
+ }
+
+ # For translator information only
+ if( in_array( $key, $ignored ) ) {
+ $commentsForKey[] = self::$ignoredComment;
+ } elseif( in_array( $key, $optional ) ) {
+ $commentsForKey[] = self::$optionalComment;
+ }
+
+ # Format one or more comments nicely and store in array
+ if( count( $commentsForKey ) ) {
+ $commentArray[$key] = ' # ' . implode( '; ', $commentsForKey );
+ }
+ }
+
+ return $commentArray;
}
- # Format the block comment (if exists); check for multiple lines comments
- if ( !empty( $comment ) ) {
- if ( strpos( $comment, "\n" ) === false ) {
- $blockText .= "# $comment
+ /**
+ * Write a block of messages to PHP.
+ *
+ * @param $blockComment The comment of whole block.
+ * @param $messages The block messages.
+ * @param $messageComments Optional comments for messages in this block.
+ * @param $prefix Prefix for every line, for indenting purposes.
+ *
+ * @return The block, formatted in PHP.
+ */
+ public static function writeMessagesBlock( $blockComment, $messages,
+ $messageComments = array(), $prefix = '' ) {
+
+ $blockText = '';
+
+ # Skip the block if it includes no messages
+ if( empty( $messages ) ) {
+ return '';
+ }
+
+ # Format the block comment (if exists); check for multiple lines comments
+ if( !empty( $blockComment ) ) {
+ if( strpos( $blockComment, "\n" ) === false ) {
+ $blockText .= "$prefix# $blockComment
";
- } else {
- $blockText .= "/*
-$comment
+ } else {
+ $blockText .= "$prefix/*
+$blockComment
*/
";
+ }
}
- }
- # Get max key length
- $maxKeyLength = max( array_map( 'strlen', array_keys( $messages ) ) );
+ # Get max key length
+ $maxKeyLength = max( array_map( 'strlen', array_keys( $messages ) ) );
- # Format the messages
- foreach( $messages as $key => $value ) {
- # Add the key name
- $blockText .= "'$key'";
+ # Format the messages
+ foreach( $messages as $key => $value ) {
+ # Add the key name
+ $blockText .= "$prefix'$key'";
- # Add the appropriate block whitespace
- $blockText .= str_repeat( ' ', $maxKeyLength - strlen( $key ) );
+ # Add the appropriate block whitespace
+ $blockText .= str_repeat( ' ', $maxKeyLength - strlen( $key ) );
- # Refer to the value
- $blockText .= ' => ';
+ # Refer to the value
+ $blockText .= ' => ';
- # Check for the appropriate apostrophe and add the value
- if ( strpos( $value, "'" ) === false ) {
- $blockText .= "'$value'";
- } elseif ( strpos( $value, '"' ) === false && !in_array( $key, $wgMessagseWithDollarSigns ) ) {
- $blockText .= "\"$value\"";
- } else {
- # Pick the less numerous one to escape
- $quote = substr_count( $value, '"' ) + substr_count( $value, '$' ) >= substr_count( $value, "'" ) ? "'" : '"';
- if ('"' == $quote) { $extra = '$'; }
- else { $extra = ''; }
- $blockText .= $quote . addcslashes( $value, $quote.'\\'.$extra ) . $quote;
- }
+ # Check for the appropriate apostrophe and add the value
+ # Quote \ here, because it needs always escaping
+ $value = addcslashes( $value, '\\' );
+
+ # For readability
+ $single = "'";
+ $double = '"';
- # Comma
- $blockText .= ',';
-
- $ignoredComment = "don't translate or duplicate this message to other languages";
- $optionalComment = "only translate this message to other languages if you have to change it";
- $showIgnoredOrOptionalComment = in_array( $key, $wgIgnoredMessages ) || in_array( $key, $wgOptionalMessages );
- if ( $ignoredComments ) {
- if ( array_key_exists( $key, $wgMessageComments ) ) {
- $blockText .= ' # ' . $wgMessageComments[$key];
- if ( $showIgnoredOrOptionalComment ) {
- $blockText .= '; ';
+ if( strpos( $value, $single ) === false ) {
+ # Nothing ugly, just use '
+ $blockText .= $single.$value.$single;
+ } elseif( strpos( $value, $double ) === false && !preg_match('/\$[a-zA-Z_\x7f-\xff]/', $value) ) {
+ # No "-quotes, no variables that need quoting, use "
+ $blockText .= $double.$value.$double;
+ } else {
+ # Something needs quoting, pick the quote which causes less quoting
+ $quote = substr_count( $value, $double ) + substr_count( $value, '$' ) >= substr_count( $value, $single ) ? $single : $double;
+ if( $quote === $double ) {
+ $extra = '$';
+ } else {
+ $extra = '';
}
- } elseif ( $showIgnoredOrOptionalComment ) {
- $blockText .= ' # ';
+ $blockText .= $quote . addcslashes( $value, $quote . $extra ) . $quote;
}
- if ( in_array( $key, $wgIgnoredMessages ) ) {
- $blockText .= $ignoredComment;
- } elseif ( in_array( $key, $wgOptionalMessages ) ) {
- $blockText .= $optionalComment;
+
+ # Comma
+ $blockText .= ',';
+
+ # Add comments, if there is any
+ if( array_key_exists( $key, $messageComments ) ) {
+ $blockText .= $messageComments[$key];
}
- } elseif ( array_key_exists( $key, $wgMessageComments ) ) {
- $blockText .= ' # ' . $wgMessageComments[$key];
- }
- # Newline
- $blockText .= "
+ # Newline
+ $blockText .= "
";
- }
+ }
- # Newline to end the block
- $blockText .= "
+ # Newline to end the block
+ $blockText .= "
";
- return $blockText;
+ return $blockText;
+ }
}
-
-?>