r72862 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72861‎ | r72862 | r72863 >
Date:14:56, 12 September 2010
Author:nikerabbit
Status:ok
Tags:
Comment:
Handle plurals properly on export side
Modified paths:
  • /trunk/extensions/Translate/ffs/Gettext.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Translate/ffs/Gettext.php
@@ -361,7 +361,12 @@
362362 * @ingroup FFS
363363 */
364364 class GettextFFS extends SimpleFFS {
 365+ protected $offlineMode = false;
365366
 367+ public function setOfflineMode( $value ) {
 368+ $this->offlineMode = $value;
 369+ }
 370+
366371 public function readFromVariable( $data ) {
367372 $authors = array();
368373
@@ -520,7 +525,7 @@
521526 $matches = array();
522527 if ( preg_match_all( '/^#(.?) (.*)$/m', $section, $matches, PREG_SET_ORDER ) ) {
523528 foreach ( $matches as $match ) {
524 - if ( $match[1] !== ',' ) {
 529+ if ( $match[1] !== ',' && strpos( $match[1], '[Wiki]' ) !== 0 ) {
525530 $item['comments'][$match[1]][] = $match[2];
526531 }
527532 }
@@ -624,61 +629,22 @@
625630 protected function writeReal( MessageCollection $collection ) {
626631 $pot = $this->read( 'en' );
627632 $template = $this->read( $collection->code );
628 - $output = $this->doGettextHeader( $collection, $template );
 633+ $pluralCount = false;
 634+ $output = $this->doGettextHeader( $collection, $template, $pluralCount );
 635+
629636 foreach ( $collection as $key => $m ) {
630637 $transTemplate = isset( $template['TEMPLATE'][$key] ) ?
631638 $template['TEMPLATE'][$key] : array();
632639 $potTemplate = isset( $pot['TEMPLATE'][$key] ) ?
633640 $pot['TEMPLATE'][$key] : array();
634 -
635 - $comments = array();
636 - if ( isset( $potTemplate['comments'] ) ) {
637 - $comments = $potTemplate['comments'];
638 - } elseif ( isset( $transTemplate['comments'] ) ) {
639 - $comments = $transTemplate['comments'];
640 - }
641 -
642 - $header = '';
643 -
644 - $header .= self::formatDocumentation( $key );
645 - foreach ( $comments as $type => $typecomments ) {
646 - foreach ( $typecomments as $comment ) {
647 - if ( strpos( $comment, '[Wiki]' ) === 0 ) continue;
648 - $header .= "#$type $comment\n";
649 - }
650 - }
651 -
652 - $tags = $m->getTags();
653 - $flags = isset( $transTemplate['flags'] ) ? $transTemplate['flags'] : array();
654641
655 - $outFlags = array_unique( array_merge( $tags, $flags ) );
656 -
657 - if ( $outFlags ) {
658 - sort( $outFlags );
659 - $header .= "#, " . implode( ', ', $outFlags ) . "\n";
660 - }
661 -
662 - if ( $header ) {
663 - $output .= $header;
664 - } else {
665 - // Must be at least empty comment
666 - $output .= "#\n";
667 - }
668 -
669 - if ( isset( $potTemplate['msgctxt'] ) ) {
670 - $output .= 'msgctxt ' . self::escape( $potTemplate['msgctxt'] ) . "\n";
671 - }
672 -
673 - $translation = str_replace( TRANSLATE_FUZZY, '', $m->translation() );
674 -
675 - $output .= 'msgid ' . self::escape( $m->definition() ) . "\n";
676 - $output .= 'msgstr ' . self::escape( $translation ) . "\n\n";
 642+ $output .= $this->formatMessageBlock( $key, $m, $transTemplate, $potTemplate, $pluralCount );
677643 }
678644
679645 return $output;
680646 }
681647
682 - protected function doGettextHeader( MessageCollection $collection, $template ) {
 648+ protected function doGettextHeader( MessageCollection $collection, $template, &$pluralCount ) {
683649 global $wgSitename, $wgServer;
684650 $code = $collection->code;
685651 $name = TranslateUtils::getLanguageName( $code );
@@ -722,6 +688,10 @@
723689 $specs['Plural-Forms'] = 'nplurals=2; plural=(n != 1);';
724690 }
725691
 692+ $match = array();
 693+ preg_match( '/nplurals=(\d+);/', $specs['Plural-Forms'], $match );
 694+ $pluralCount = $match[1];
 695+
726696 $output .= 'msgid ""' . "\n";
727697 $output .= 'msgstr ""' . "\n";
728698 $output .= '""' . "\n";
@@ -747,6 +717,70 @@
748718 return $output;
749719 }
750720
 721+ protected function formatMessageBlock( $key, $m, $trans, $pot, $pluralCount ) {
 722+ $header = $this->formatDocumentation( $key );
 723+
 724+ $comments = self::chainGetter( 'comments', $pot, $trans, array() );
 725+ foreach ( $comments as $type => $typecomments ) {
 726+ foreach ( $typecomments as $comment ) {
 727+ $header .= "#$type $comment\n";
 728+ }
 729+ }
 730+
 731+ $flags = self::chainGetter( 'flags', $pot, $trans, array() );
 732+ $flags = array_unique( array_merge( $m->getTags(), $flags ) );
 733+
 734+
 735+ $ctxt = self::chainGetter( 'msgctxt', $pot, $trans, false );
 736+ if ( $ctxt ) {
 737+ $output .= 'msgctxt ' . self::escape( $ctxt ) . "\n";
 738+ }
 739+
 740+ $msgid = $m->definition();
 741+ $msgstr = str_replace( TRANSLATE_FUZZY, '', $m->translation() );
 742+
 743+ if ( preg_match( '/{{PLURAL:GETTEXT/i', $msgid ) ) {
 744+ $forms = $this->splitPlural( $msgid, 2 );
 745+ $content = 'msgid ' . $this->escape( $forms[0] ) . "\n";
 746+ $content .= 'msgid_plural ' . $this->escape( $forms[1] ) . "\n";
 747+
 748+ try {
 749+ $forms = $this->splitPlural( $msgstr, $pluralCount );
 750+ foreach ( $forms as $index => $form ) {
 751+ $content .= "msgstr[$index] " . $this->escape( $form ) . "\n";
 752+ }
 753+ } catch ( GettextPluralException $e ) {
 754+ $flags[] = 'x-invalid-plural';
 755+ for ( $i = 0; $i < $pluralCount; $i++ ) {
 756+ $content .= "msgstr[$i] \"\"\n";
 757+ }
 758+ }
 759+
 760+ } else {
 761+ $content = 'msgid ' . self::escape( $msgid ) . "\n";
 762+ $content .= 'msgstr ' . self::escape( $msgstr ) . "\n";
 763+ }
 764+
 765+ if ( $flags ) {
 766+ sort( $flags );
 767+ $header .= "#, " . implode( ', ', $flags ) . "\n";
 768+ }
 769+
 770+ $output = $header ? $header : "#\n";
 771+ $output .= $content . "\n";
 772+ return $output;
 773+ }
 774+
 775+ protected static function chainGetter( $key, $a, $b, $default ) {
 776+ if ( isset( $a[$key] ) ) {
 777+ return $a[$key];
 778+ } elseif ( isset( $b[$key] ) ) {
 779+ return $b[$key];
 780+ } else {
 781+ return $default;
 782+ }
 783+ }
 784+
751785 protected static function formatTime( $time ) {
752786 $lang = Language::factory( 'en' );
753787 return $lang->sprintfDate( 'xnY-xnm-xnd xnH:xni:xns+0000', $time );
@@ -762,13 +796,15 @@
763797 "; Translate extension (" . TRANSLATE_VERSION . ")";
764798 }
765799
766 - protected static function formatDocumentation( $key ) {
 800+ protected function formatDocumentation( $key ) {
767801 global $wgTranslateDocumentationLanguageCode;
768802
 803+ if ( !$this->offlineMode ) return '';
 804+
769805 $code = $wgTranslateDocumentationLanguageCode;
770806 if ( !$code ) return '';
771807
772 - $documentation = TranslateUtils::getMessageContent( $key, $code );
 808+ $documentation = TranslateUtils::getMessageContent( $key, $code, $this->group->getNamespace() );
773809 if ( !is_string( $documentation ) ) return '';
774810
775811 $lines = explode( "\n", $documentation );
@@ -805,4 +841,34 @@
806842 return '';
807843 }
808844
 845+ protected function splitPlural( $text, $forms ) {
 846+ if ( $forms === 1 ) {
 847+ return $text;
 848+ }
 849+
 850+ $splitPlurals = array();
 851+ for ( $i = 0; $i < $forms; $i++ ) {
 852+ $plurals = array();
 853+ $match = preg_match_all( '/{{PLURAL:GETTEXT\|(.*)}}/iU', $text, $plurals );
 854+
 855+ if ( !$match ) {
 856+ throw new GettextPluralException( "Failed to parse plural for: $text" );
 857+ }
 858+
 859+ $pluralForm = $text;
 860+ foreach ( $plurals[0] as $index => $definition ) {
 861+ $parsedFormsArray = explode( '|', $plurals[1][$index] );
 862+ if ( !isset( $parsedFormsArray[$i] ) ) {
 863+ error_log( "Too few plural forms in: $text" );
 864+ $pluralForm = '';
 865+ } else {
 866+ $pluralForm = str_replace( $pluralForm, $definition, $parsedFormsArray[$i] );
 867+ }
 868+ }
 869+ $splitPlurals[$i] = $pluralForm;
 870+ }
 871+
 872+ return $splitPlurals;
 873+ }
 874+
809875 }

Status & tagging log