r37186 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r37185‎ | r37186 | r37187 >
Date:17:23, 6 July 2008
Author:rainman
Status:old
Tags:
Comment:
(bug 14604#c6): Fix regression in variant conversion when semicolon is within -{}- tags. Patch by fdcn, thanks!
Modified paths:
  • /trunk/phase3/languages/LanguageConverter.php (modified) (history)
  • /trunk/phase3/languages/classes/LanguageZh.php (modified) (history)

Diff [purge]

Index: trunk/phase3/languages/LanguageConverter.php
@@ -17,7 +17,6 @@
1818 var $mTitleDisplay='';
1919 var $mDoTitleConvert=true, $mDoContentConvert=true;
2020 var $mManualLevel; // 'bidirectional' 'unidirectional' 'disable' for each variants
21 - var $mManualCodeError='<span style="color: red;">code error!</span>';
2221 var $mTitleFromFlag = false;
2322 var $mCacheKey;
2423 var $mLangObj;
@@ -105,26 +104,6 @@
106105 }
107106
108107 /**
109 - * check if variants array in convert array
110 - *
111 - * @param string $variant Variant language code
112 - * @param array $carray convert array
113 - * @param string $text Text to convert
114 - * @return string Translated text
115 - * @private
116 - */
117 - function getTextInCArray($variants,$carray){
118 - if(is_string($variants)){ $variants=array($variants); }
119 - if(!is_array($variants)) return false;
120 - foreach ($variants as $variant){
121 - if(array_key_exists($variant, $carray)){
122 - return $carray[$variant];
123 - }
124 - }
125 - return false;
126 - }
127 -
128 - /**
129108 * get preferred language variants.
130109 * @param boolean $fromUser Get it from $wgUser's preferences
131110 * @return string the preferred language code
@@ -346,191 +325,19 @@
347326 }
348327
349328 /**
350 - * Parse flags with syntax -{FLAG| ... }-
351 - * @private
352 - */
353 - function parseFlags($marked){
354 - $flags = array();
355 -
356 - // for multi-FLAGs
357 - if(strlen($marked) < 2 )
358 - return array($marked,array('R'));
359 -
360 - $tt = explode($this->mMarkup['flagsep'], $marked, 2);
361 -
362 - if(count($tt) == 2) {
363 - $f = explode($this->mMarkup['varsep'], $tt[0]);
364 - foreach($f as $ff) {
365 - $ff = trim($ff);
366 - if(array_key_exists($ff, $this->mFlags) &&
367 - !in_array($this->mFlags[$ff], $flags))
368 - $flags[] = $this->mFlags[$ff];
369 - }
370 - $rules = $tt[1];
371 - } else {
372 - $rules = $marked;
373 - }
374 -
375 - if( !in_array('R',$flags) ){
376 - //FIXME: may cause trouble here...
377 - //strip &nbsp; since it interferes with the parsing, plus,
378 - //all spaces should be stripped in this tag anyway.
379 - $rules = str_replace('&nbsp;', '', $rules);
380 - $rules = str_replace('=&gt;','=>',$rules);
381 - }
382 -
383 - //check flags
384 - if( in_array('R',$flags) ){
385 - $flags = array('R');// remove other flags
386 - } elseif ( in_array('N',$flags) ){
387 - $flags = array('N');// remove other flags
388 - } elseif ( in_array('-',$flags) ){
389 - $flags = array('-');// remove other flags
390 - } elseif (count($flags)==1 && $flags[0]=='T'){
391 - $flags[]='H';
392 - } elseif ( in_array('H',$flags) ){
393 - // replace A flag, and remove other flags except T
394 - $temp=array('+','H');
395 - if(in_array('T',$flags)) $temp[] = 'T';
396 - if(in_array('D',$flags)) $temp[] = 'D';
397 - $flags = $temp;
398 - } else {
399 - if ( in_array('A',$flags)) {
400 - $flags[]='+';
401 - $flags[]='S';
402 - }
403 - if ( in_array('D',$flags) )
404 - $flags=array_diff($flags,array('S'));
405 - }
406 - if ( count($flags)==0 )
407 - $flags = array('S');
408 - return array($rules,$flags);
409 - }
410 -
411 - /**
412 - * @private
413 - */
414 - function getRulesDesc($bidtable,$unidtable){
415 - $text='';
416 - foreach($bidtable as $k => $v)
417 - $text .= $this->mVariantNames[$k].':'.$v.';';
418 - foreach($unidtable as $k => $a)
419 - foreach($a as $from=>$to)
420 - $text.=$from.'⇒'.$this->mVariantNames[$k].':'.$to.';';
421 - return $text;
422 - }
423 -
424 - /**
425 - * parse the manually marked conversion rule
426 - * @param string $rule the text of the rule
427 - * @return array of the translation in each variant
428 - * @private
429 - */
430 - function getConvTableFromRules($rules,$flags=array()) {
431 - $bidtable = array();
432 - $unidtable = array();
433 - $choice = explode($this->mMarkup['varsep'], $rules );
434 - foreach($choice as $c) {
435 - $v = explode($this->mMarkup['codesep'], $c);
436 - if(count($v) != 2)
437 - continue;// syntax error, skip
438 - $to=trim($v[1]);
439 - $v=trim($v[0]);
440 - $u = explode($this->mMarkup['unidsep'], $v);
441 - if(count($u) == 1) {
442 - $bidtable[$v] = $to;
443 - } else if(count($u) == 2){
444 - $from=trim($u[0]);$v=trim($u[1]);
445 - if( array_key_exists($v,$unidtable) && !is_array($unidtable[$v]) )
446 - $unidtable[$v]=array($from=>$to);
447 - else
448 - $unidtable[$v][$from]=$to;
449 - }
450 - // syntax error, pass
451 - }
452 - return array($bidtable,$unidtable);
453 - }
454 -
455 - /**
456 - * get display text on markup -{...}-
457 - * @param string $rules the original code
458 - * @param array $flags FLAGs
459 - * @param array $bidtable bidirectional convert table
460 - * @param string $unidtable unidirectional convert table
461 - * @param string $variant the current variant
462 - * @param bool $$doConvert if do convert
463 - * @private
464 - */
465 - function getRulesDisplay($rules,$flags,
466 - $bidtable,$unidtable,
467 - $variant=false,$doConvert=true){
468 - if(!$variant) $variant = $this->getPreferredVariant();
469 - $is_mc_disable = $this->mManualLevel[$variant]=='disable';
470 -
471 - if( in_array('R',$flags) ) {
472 - // if we don't do content convert, still strip the -{}- tags
473 - $disp = $rules;
474 - } elseif ( in_array('N',$flags) ){
475 - // proces N flag: output current variant name
476 - $disp = $this->mVariantNames[trim($rules)];
477 - } elseif ( in_array('D',$flags) ){
478 - // proces D flag: output rules description
479 - $disp = $this->getRulesDesc($bidtable,$unidtable);
480 - } elseif ( in_array('H',$flags) || in_array('-',$flags) ) {
481 - // proces H,- flag or T only: output nothing
482 - $disp = '';
483 - } elseif ( in_array('S',$flags) ){
484 - if( count($bidtable) + count($unidtable) == 0 ){
485 - $disp = $rules;
486 - } elseif ($doConvert){// the text converted
487 - // display current variant in bidirectional array
488 - $disp = $this->getTextInCArray($variant,$bidtable);
489 - // or display current variant in fallbacks
490 - if(!$disp)
491 - $disp = $this->getTextInCArray($this->getVariantFallbacks($variant),$bidtable);
492 - // or display current variant in unidirectional array
493 - if(!$disp && array_key_exists($variant,$unidtable)){
494 - $disp = array_values($unidtable[$variant]);
495 - $disp = $disp[0];
496 - }
497 - // or display frist text under disable manual convert
498 - if(!$disp && $is_mc_disable) {
499 - if(count($bidtable)>0){
500 - $disp = array_values($bidtable);
501 - $disp = $disp[0];
502 - } else {
503 - $disp = array_values($unidtable);
504 - $disp = array_values($disp[0]);
505 - $disp = $disp[0];
506 - }
507 - }
508 - } else {// no convert
509 - $disp = $rules;
510 - }
511 - } elseif ( in_array('T',$flags) ) {
512 - // proces T flag : output nothing
513 - $disp = '';
514 - }
515 - else
516 - $disp= $this->mManualCodeError;
517 -
518 - return $disp;
519 - }
520 -
521 - /**
522329 * @access private
523330 */
524 - function applyManualFlag($rules,$flags,$bidtable,$unidtable,$variant=false){
 331+ function applyManualConv($convRule,$variant){
525332 if(!$variant) $variant = $this->getPreferredVariant();
 333+ $rules = $convRule->getRules();
 334+ $flags = $convRule->getFlags();
 335+ list($bidtable, $unidtable) = $convRule->getConvTable();
526336
527337 $is_title_flag = in_array('T', $flags);
528338 // use syntax -{T|zh:TitleZh;zh-tw:TitleTw}- for custom conversion in title
529339 if($is_title_flag){
530340 $this->mTitleFromFlag = true;
531 - $this->mTitleDisplay = $this->getRulesDisplay($rules,array('S'),
532 - $bidtable,$unidtable,
533 - $variant,
534 - $this->mDoTitleConvert);
 341+ $this->mTitleDisplay = $convRule->getRulesTitle();
535342 }
536343
537344 if($this->mManualLevel[$variant]=='disable') return;
@@ -546,7 +353,7 @@
547354 fill in the missing variants, if any,
548355 with fallbacks */
549356 if($is_bidMC && !array_key_exists($v, $bidtable)) {
550 - $vf = $this->getTextInCArray($this->getVariantFallbacks($v),$bidtable);
 357+ $vf = $convRule->getTextInBidtable($this->getVariantFallbacks($v) );
551358 if($vf) $bidtable[$v] = $vf;
552359 }
553360 if($is_bidMC && array_key_exists($v,$bidtable)){
@@ -578,26 +385,6 @@
579386 }
580387
581388 /**
582 - * Parse rules and flags
583 - * @private
584 - */
585 - function parseRules($rules,$flags,$variant=false){
586 - if(!$variant) $variant = $this->getPreferredVariant();
587 -
588 - list($bidtable,$unidtable) = $this->getConvTableFromRules($rules, $flags);
589 - if(count($bidtable)==0 && count($unidtable)==0
590 - && !in_array('N',$flags) && !in_array('T',$flags) )
591 - $flags = array('R');
592 - $disp = $this->getRulesDisplay($rules,$flags,
593 - $bidtable,$unidtable,
594 - $variant,
595 - $this->mDoContentConvert);
596 - $this->applyManualFlag($rules,$flags,$bidtable,$unidtable);
597 -
598 - return $disp;
599 - }
600 -
601 - /**
602389 * convert title
603390 * @private
604391 */
@@ -671,10 +458,17 @@
672459 $marked = explode($this->mMarkup['end'], $txt, 2);
673460
674461 // strip the flags from syntax like -{T| ... }-
675 - list($rules,$flags) = $this->parseFlags($marked[0]);
 462+ $crule = new ConverterRule($marked[0],
 463+ $this->mMarkup, $this->mFlags,
 464+ $this->mVariantNames,
 465+ $this->mDoContentConvert,
 466+ $this->mDoTitleConvert);
 467+ $crule->parseRules($plang,
 468+ $this->getVariantFallbacks($plang),
 469+ $this->mManualLevel[$plang]=='disable');
 470+ $text .= $crule->getRulesDisplay();
 471+ $this->applyManualConv($crule,$plang);
676472
677 - $text .= $this->parseRules($rules,$flags,$plang);
678 -
679473 if(array_key_exists(1, $marked)){
680474 if( $this->mDoContentConvert )
681475 $text .= $this->autoConvert($marked[1],$plang);
@@ -1003,3 +797,293 @@
1004798 return $ret;
1005799 }
1006800 }
 801+
 802+/**
 803+ * @ingroup Language
 804+ * @author fdcn <fdcn64@gmail.com>
 805+ */
 806+class ConverterRule {
 807+ var $mText; // original text in -{text}-
 808+ var $mVariantNames;
 809+ var $mMarkup;
 810+ var $mRules;
 811+ var $mFlags;
 812+ var $mManualCodeError='<span style="color: red;">code error!</span>';
 813+ var $mDoTitleConvert=true, $mDoContentConvert=true;
 814+ var $ruleDisplay = '',$ruleTitle=false;
 815+ var $rules = '';// string $rule the text of the rule
 816+ var $flags = array();
 817+ var $bidtable = array();// array of the translation in each variant
 818+ var $unidtable = array();// array of the translation in each variant
 819+
 820+ /**
 821+ * Constructor
 822+ *
 823+ * @param string $text the text between -{ and }-
 824+ * @param array $markup the supported markup for conversion
 825+ * @param array $flags the supported flags for conversion
 826+ * @param array $variantNames the names list of supported language
 827+ * @param bool $doTitleConvert if do title convert
 828+ * @param bool $doContentConvert if do content convert
 829+ * @access public
 830+ */
 831+ function __construct($text,$markup,$flags,$variantNames,
 832+ $doTitleConvert=true, $doContentConvert=true){
 833+ $this->mText = $text;
 834+ $this->mMarkup = $markup;
 835+ $this->mFlags = $flags;
 836+ $this->mVariantNames = $variantNames;
 837+ $this->mDoTitleConvert=$doTitleConvert;
 838+ $this->mDoContentConvert=$doContentConvert;
 839+ }
 840+
 841+ /**
 842+ * check if variants array in convert array
 843+ *
 844+ * @param string $variant Variant language code
 845+ * @return string Translated text
 846+ * @public
 847+ */
 848+ function getTextInBidtable($variants){
 849+ if(is_string($variants)){ $variants=array($variants); }
 850+ if(!is_array($variants)) return false;
 851+ foreach ($variants as $variant){
 852+ if(array_key_exists($variant, $this->bidtable)){
 853+ return $this->bidtable[$variant];
 854+ }
 855+ }
 856+ return false;
 857+ }
 858+
 859+ /**
 860+ * Parse flags with syntax -{FLAG| ... }-
 861+ * @private
 862+ */
 863+ function parseFlags(){
 864+ $flags = array();
 865+ $text = $this->mText;
 866+
 867+ // for multi-FLAGs
 868+ if(strlen($text) < 2 )
 869+ return array($text,array('R'));
 870+
 871+ $tt = explode($this->mMarkup['flagsep'], $text, 2);
 872+
 873+ if(count($tt) == 2) {
 874+ $f = explode($this->mMarkup['varsep'], $tt[0]);
 875+ foreach($f as $ff) {
 876+ $ff = trim($ff);
 877+ if(array_key_exists($ff, $this->mFlags) &&
 878+ !in_array($this->mFlags[$ff], $flags))
 879+ $flags[] = $this->mFlags[$ff];
 880+ }
 881+ $rules = $tt[1];
 882+ } else {
 883+ $rules = $text;
 884+ }
 885+
 886+ if( !in_array('R',$flags) ){
 887+ //FIXME: may cause trouble here...
 888+ //strip &nbsp; since it interferes with the parsing, plus,
 889+ //all spaces should be stripped in this tag anyway.
 890+ $rules = str_replace('&nbsp;', '', $rules);
 891+ $rules = str_replace('=&gt;','=>',$rules);
 892+ }
 893+
 894+ //check flags
 895+ if( in_array('R',$flags) ){
 896+ $flags = array('R');// remove other flags
 897+ } elseif ( in_array('N',$flags) ){
 898+ $flags = array('N');// remove other flags
 899+ } elseif ( in_array('-',$flags) ){
 900+ $flags = array('-');// remove other flags
 901+ } elseif (count($flags)==1 && $flags[0]=='T'){
 902+ $flags[]='H';
 903+ } elseif ( in_array('H',$flags) ){
 904+ // replace A flag, and remove other flags except T
 905+ $temp=array('+','H');
 906+ if(in_array('T',$flags)) $temp[] = 'T';
 907+ if(in_array('D',$flags)) $temp[] = 'D';
 908+ $flags = $temp;
 909+ } else {
 910+ if ( in_array('A',$flags)) {
 911+ $flags[]='+';
 912+ $flags[]='S';
 913+ }
 914+ if ( in_array('D',$flags) )
 915+ $flags=array_diff($flags,array('S'));
 916+ }
 917+ if ( count($flags)==0 )
 918+ $flags = array('S');
 919+ $this->rules=$rules;
 920+ $this->flags=$flags;
 921+ }
 922+
 923+ /**
 924+ * generate conversion table
 925+ * @private
 926+ */
 927+ function generateConvTable() {
 928+ $rules = $this->rules;
 929+ $flags = $this->flags;
 930+ $bidtable = array();
 931+ $unidtable = array();
 932+ $choice = explode($this->mMarkup['varsep'], $rules );
 933+ foreach($choice as $c) {
 934+ $v = explode($this->mMarkup['codesep'], $c);
 935+ if(count($v) != 2)
 936+ continue;// syntax error, skip
 937+ $to=trim($v[1]);
 938+ $v=trim($v[0]);
 939+ $u = explode($this->mMarkup['unidsep'], $v);
 940+ if(count($u) == 1) {
 941+ $bidtable[$v] = $to;
 942+ } else if(count($u) == 2){
 943+ $from=trim($u[0]);$v=trim($u[1]);
 944+ if( array_key_exists($v,$unidtable) && !is_array($unidtable[$v]) )
 945+ $unidtable[$v]=array($from=>$to);
 946+ else
 947+ $unidtable[$v][$from]=$to;
 948+ }
 949+ // syntax error, pass
 950+ if (!array_key_exists($v,$this->mVariantNames))
 951+ return;
 952+ }
 953+ $this->bidtable = $bidtable;
 954+ $this->unidtable = $unidtable;
 955+ }
 956+
 957+ /**
 958+ * @private
 959+ */
 960+ function getRulesDesc(){
 961+ $text='';
 962+ foreach($this->bidtable as $k => $v)
 963+ $text .= $this->mVariantNames[$k].':'.$v.';';
 964+ foreach($this->unidtable as $k => $a)
 965+ foreach($a as $from=>$to)
 966+ $text.=$from.'⇒'.$this->mVariantNames[$k].':'.$to.';';
 967+ return $text;
 968+ }
 969+
 970+ /**
 971+ * Parse rules conversion
 972+ * @private
 973+ */
 974+ function getRuleConvertedStr($variant,$variantFallbacks,
 975+ $doConvert,$isMCDisable=false){
 976+ $bidtable = $this->bidtable;
 977+ $unidtable = $this->unidtable;
 978+
 979+ if( count($bidtable) + count($unidtable) == 0 ){
 980+ return $this->rules;
 981+ } elseif ($doConvert){// the text converted
 982+ // display current variant in bidirectional array
 983+ $disp = $this->getTextInBidtable($variant);
 984+ // or display current variant in fallbacks
 985+ if(!$disp)
 986+ $disp = $this->getTextInBidtable($variantFallbacks);
 987+ // or display current variant in unidirectional array
 988+ if(!$disp && array_key_exists($variant,$unidtable)){
 989+ $disp = array_values($unidtable[$variant]);
 990+ $disp = $disp[0];
 991+ }
 992+ // or display frist text under disable manual convert
 993+ if(!$disp && $isMCDisable) {
 994+ if(count($bidtable)>0){
 995+ $disp = array_values($bidtable);
 996+ $disp = $disp[0];
 997+ } else {
 998+ $disp = array_values($unidtable);
 999+ $disp = array_values($disp[0]);
 1000+ $disp = $disp[0];
 1001+ }
 1002+ }
 1003+ return $disp;
 1004+ } else {// no convert
 1005+ return $this->rules;
 1006+ }
 1007+ }
 1008+ /**
 1009+ * Parse rules and flags
 1010+ * @public
 1011+ */
 1012+ function parseRules($variant,$variantFallbacks,$isMCDisable=false){
 1013+ $this->parseFlags();
 1014+ $this->generateConvTable();
 1015+
 1016+ $rules = $this->rules;
 1017+ $flags = $this->flags;
 1018+
 1019+ if(count($this->bidtable)==0 && count($this->unidtable)==0
 1020+ && !in_array('N',$flags) && !in_array('T',$flags) )
 1021+ $this->flags = array('R');
 1022+
 1023+ if( in_array('R',$flags) ) {
 1024+ // if we don't do content convert, still strip the -{}- tags
 1025+ $this->ruleDisplay = $rules;
 1026+ } elseif ( in_array('N',$flags) ){
 1027+ // proces N flag: output current variant name
 1028+ $this->ruleDisplay = $this->mVariantNames[trim($rules)];
 1029+ } elseif ( in_array('D',$flags) ){
 1030+ // proces D flag: output rules description
 1031+ $this->ruleDisplay = $this->getRulesDesc();
 1032+ } elseif ( in_array('H',$flags) || in_array('-',$flags) ) {
 1033+ // proces H,- flag or T only: output nothing
 1034+ $this->ruleDisplay = '';
 1035+ } elseif ( in_array('S',$flags) ){
 1036+ $this->ruleDisplay = $this->getRuleConvertedStr(
 1037+ $variant,$variantFallbacks,
 1038+ $this->mDoContentConvert,$isMCDisable);
 1039+ } else {
 1040+ $this->ruleDisplay= $this->mManualCodeError;
 1041+ }
 1042+ // proces T flag : output nothing
 1043+ if ( in_array('T',$flags) ) {
 1044+ $this->ruleTitle = $this->getRuleConvertedStr(
 1045+ $variant,$variantFallbacks,
 1046+ $this->mDoTitleConvert,$isMCDisable);
 1047+ }
 1048+ }
 1049+
 1050+ /**
 1051+ * get display text on markup -{...}-
 1052+ * @param string $variant the current variant
 1053+ * @public
 1054+ */
 1055+ function getRulesDisplay(){
 1056+ return $this->ruleDisplay;
 1057+ }
 1058+ /**
 1059+ * get converted title
 1060+ * @param string $variant the current variant
 1061+ * @public
 1062+ */
 1063+ function getRulesTitle(){
 1064+ return $this->ruleTitle;
 1065+ }
 1066+
 1067+ /**
 1068+ * get conversion table ( bidirectional and unidirectional conversion table )
 1069+ * @public
 1070+ */
 1071+ function getConvTable(){
 1072+ return array($this->bidtable, $this->unidtable);
 1073+ }
 1074+
 1075+ /**
 1076+ * get conversion rules string
 1077+ * @public
 1078+ */
 1079+ function getRules(){
 1080+ return $this->rules;
 1081+ }
 1082+
 1083+ /**
 1084+ * get conversion flags
 1085+ * @public
 1086+ */
 1087+ function getFlags(){
 1088+ return $this->flags;
 1089+ }
 1090+}
Index: trunk/phase3/languages/classes/LanguageZh.php
@@ -98,7 +98,7 @@
9999 'zh-hant' => array('zh-tw','zh-hk','zh-mo'),
100100 'zh-cn' => array('zh-hans','zh-sg','zh-my'),
101101 'zh-sg' => array('zh-hans','zh-cn','zh-my'),
102 - 'zh-my' => array('zh-hant','zh-sg','zh-cn'),
 102+ 'zh-my' => array('zh-hans','zh-sg','zh-cn'),
103103 'zh-tw' => array('zh-hant','zh-hk','zh-mo'),
104104 'zh-hk' => array('zh-hant','zh-mo','zh-tw'),
105105 'zh-mo' => array('zh-hant','zh-hk','zh-tw'),

Follow-up revisions

RevisionCommit summaryAuthorDate
r37373* (bug 14604) Update LanguageConverter for compatibility on -{*|xxx}- usage...shinjiman08:16, 9 July 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r36664* (bug 14604) Introduced the following features for the LanguageConverter: Mu...shinjiman03:00, 26 June 2008
r37058* (bug 14604) Update LanguageConverter for T (Title) conversion...shinjiman15:01, 4 July 2008

Status & tagging log