Index: trunk/extensions/Translate/MessageChecks.php |
— | — | @@ -25,6 +25,7 @@ |
26 | 26 | 'freecol' => array( |
27 | 27 | 'checkFreeColMissingVars', |
28 | 28 | 'checkFreeColExtraVars', |
| 29 | + 'checkFreeColEscapes', |
29 | 30 | ), |
30 | 31 | 'mantis' => array( |
31 | 32 | 'checkPrintfMissingVars', |
— | — | @@ -391,6 +392,19 @@ |
392 | 393 | } |
393 | 394 | } |
394 | 395 | |
| 396 | + protected function checkFreeColEscapes( TMessage $message, $code, &$desc = null ) { |
| 397 | + $varPattern = '\\\\[^nt\'"]'; |
| 398 | + preg_match_all( "/$varPattern/U", $message->translation, $transVars ); |
| 399 | + |
| 400 | + if ( $count = count( $transVars[0] ) ) { |
| 401 | + $desc = array( 'translate-checks-escape', |
| 402 | + '<tt><nowiki>' . implode( ', ', $transVars[0] ) . '</nowiki></tt>' ); |
| 403 | + return true; |
| 404 | + } else { |
| 405 | + return false; |
| 406 | + } |
| 407 | + } |
| 408 | + |
395 | 409 | /** |
396 | 410 | * Checks for translations not containing vars %d or %s that are in the |
397 | 411 | * definition. |
Index: trunk/extensions/Translate/Translate.i18n.php |
— | — | @@ -122,6 +122,7 @@ |
123 | 123 | 'translate-checks-plural' => 'Definition uses <nowiki>{{PLURAL:}}</nowiki> but translation does not.', |
124 | 124 | 'translate-checks-pagename' => 'Namespace changed from the definition', |
125 | 125 | 'translate-checks-format' => 'This translation does not follow the definition or has invalid syntax: $1', |
| 126 | + 'translate-checks-escape' => 'The following escapes may be accidental: <strong>$1</strong>', |
126 | 127 | |
127 | 128 | 'tog-translate-nonewsletter' => 'Do not send me e-mail newsletters (relevant only for users with a confirmed e-mail address)', |
128 | 129 | 'right-translate' => 'Edit using the translate interface', |
Index: trunk/extensions/Translate/TranslateUtils.php |
— | — | @@ -29,6 +29,13 @@ |
30 | 30 | return $cache[$message] . '/' . $code; |
31 | 31 | } |
32 | 32 | |
| 33 | + public static function figureMessage( $text ) { |
| 34 | + $pos = strrpos( $text, '/' ); |
| 35 | + $code = substr( $text, $pos + 1 ); |
| 36 | + $key = substr( $text, 0, $pos ); |
| 37 | + return array( $key, $code ); |
| 38 | + } |
| 39 | + |
33 | 40 | /** |
34 | 41 | * Fills the actual translation from database, if any. |
35 | 42 | * |
Index: trunk/extensions/Translate/SpecialMagic.php |
— | — | @@ -482,11 +482,16 @@ |
483 | 483 | # |
484 | 484 | # Export |
485 | 485 | # |
| 486 | + public function validate( &$errors = array() ) { } |
486 | 487 | |
487 | 488 | public function export() { |
| 489 | + $errors = array(); |
| 490 | + $this->validate( $errors ); |
488 | 491 | $groups = $this->getGroups(); |
489 | 492 | $text = ''; |
490 | 493 | |
| 494 | + foreach( $errors as $_ ) $text .= "#!!# $_\n"; |
| 495 | + |
491 | 496 | foreach ( $groups as $group => $data ) { |
492 | 497 | |
493 | 498 | |
— | — | @@ -616,6 +621,33 @@ |
617 | 622 | return $values; |
618 | 623 | } |
619 | 624 | |
| 625 | + public function validate( &$errors = array() ) { |
| 626 | + $used = array(); |
| 627 | + foreach ( array_keys( $this->data ) as $group ) { |
| 628 | + foreach ( $this->getIterator( $group ) as $key ) { |
| 629 | + $values = $this->val( $group, self::LANG_CURRENT, $key ); |
| 630 | + foreach ( $values as $i => $_ ) { |
| 631 | + $title = Title::makeTitleSafe( NS_SPECIAL, $_ ); |
| 632 | + if ( $title === null ) { |
| 633 | + $errors[] = "$_ is invalid title in $key"; |
| 634 | + continue; |
| 635 | + } else { |
| 636 | + $text = $title->getText(); |
| 637 | + $dbkey = $title->getDBKey(); |
| 638 | + if( $text !== $_ && $dbkey !== $_ ) { |
| 639 | + $errors[] = "$_ is not in normalised form, which is $text or $dbkey"; |
| 640 | + } |
| 641 | + if ( isset($used[$dbkey]) ) { |
| 642 | + $errors[] = "$_ is used twice for $used[$dbkey] and $key"; |
| 643 | + continue; |
| 644 | + } |
| 645 | + $used[$dbkey] = $key; |
| 646 | + } |
| 647 | + } |
| 648 | + } |
| 649 | + } |
| 650 | + } |
| 651 | + |
620 | 652 | } |
621 | 653 | |
622 | 654 | class MagicWordsCM extends ComplexMessages { |