73 $this->mConverter = $converter;
83 $variants = (array)$variants;
87 foreach ( $variants as $variant ) {
88 if ( isset( $this->mBidtable[$variant] ) ) {
89 return $this->mBidtable[$variant];
98 private function parseFlags() {
103 $sepPos = strpos( $text,
'|' );
104 if ( $sepPos !==
false ) {
105 $validFlags = $this->mConverter->getFlags();
106 $f = StringUtils::explode(
';', substr( $text, 0, $sepPos ) );
107 foreach ( $f as $ff ) {
109 if ( isset( $validFlags[$ff] ) ) {
110 $flags[$validFlags[$ff]] =
true;
113 $text = strval( substr( $text, $sepPos + 1 ) );
118 } elseif ( isset( $flags[
'R'] ) ) {
120 $flags = [
'R' => true ];
121 } elseif ( isset( $flags[
'N'] ) ) {
123 $flags = [
'N' => true ];
124 } elseif ( isset( $flags[
'-'] ) ) {
126 $flags = [
'-' => true ];
127 } elseif ( count( $flags ) === 1 && isset( $flags[
'T'] ) ) {
129 } elseif ( isset( $flags[
'H'] ) ) {
131 $temp = [
'+' =>
true,
'H' => true ];
132 if ( isset( $flags[
'T'] ) ) {
135 if ( isset( $flags[
'D'] ) ) {
140 if ( isset( $flags[
'A'] ) ) {
144 if ( isset( $flags[
'D'] ) ) {
145 unset( $flags[
'S'] );
149 $variantFlags = array_intersect( array_keys( $flags ), $this->mConverter->getVariants() );
150 if ( $variantFlags ) {
151 $variantFlags = array_fill_keys( $variantFlags,
true );
155 $this->mVariantFlags = $variantFlags;
156 $this->mRules = $text;
157 $this->mFlags = $flags;
163 private function parseRules() {
167 $varsep_pattern = $this->mConverter->getVarSeparatorPattern();
170 $rules = preg_replace(
'/(&[#a-zA-Z0-9]+);/',
"$1\x01", $rules );
171 $choice = preg_split( $varsep_pattern, $rules );
172 if ( $choice ===
false ) {
173 $error = preg_last_error();
174 $errorText = preg_last_error_msg();
175 LoggerFactory::getInstance(
'parser' )->warning(
176 'ConverterRule preg_split error: {code} {errorText}',
179 'errorText' => $errorText
184 $choice = str_replace(
"\x01",
';', $choice );
186 foreach ( $choice as $c ) {
187 $v = explode(
':', $c, 2 );
188 if ( count( $v ) !== 2 ) {
194 $u = explode(
'=>', $v, 2 );
195 $vv = $this->mConverter->validateVariant( $v );
198 if ( count( $u ) === 1 && $to !==
'' && $vv ) {
199 $bidtable[$vv] = $to;
200 } elseif ( count( $u ) === 2 ) {
201 $from = trim( $u[0] );
203 $vv = $this->mConverter->validateVariant( $v );
205 if ( array_key_exists( $vv, $unidtable )
206 && !is_array( $unidtable[$vv] )
209 $unidtable[$vv] = [ $from => $to ];
210 } elseif ( $from !==
'' && $vv ) {
211 $unidtable[$vv][$from] = $to;
215 if ( !isset( $this->mConverter->getVariantNames()[$vv] ) ) {
221 $this->mBidtable = $bidtable;
222 $this->mUnidtable = $unidtable;
228 private function getRulesDesc() {
229 $codesep = $this->mConverter->getDescCodeSeparator();
230 $varsep = $this->mConverter->getDescVarSeparator();
232 foreach ( $this->mBidtable as $k => $v ) {
233 $text .= $this->mConverter->getVariantNames()[$k] .
"$codesep$v$varsep";
235 foreach ( $this->mUnidtable as $k => $a ) {
236 foreach ( $a as $from => $to ) {
237 $text .= $from .
'⇒' . $this->mConverter->getVariantNames()[$k] .
238 "$codesep$to$varsep";
251 private function getRuleConvertedStr( $variant ) {
255 if ( count( $bidtable ) + count( $unidtable ) === 0 ) {
262 if ( $disp ===
false ) {
264 $this->mConverter->getVariantFallbacks( $variant ) );
267 if ( $disp ===
false && array_key_exists( $variant, $unidtable ) ) {
268 $disp = array_values( $unidtable[$variant] )[0];
271 if ( $disp ===
false && $this->mConverter->getManualLevel()[$variant] ===
'disable' ) {
272 if ( count( $bidtable ) > 0 ) {
273 $disp = array_values( $bidtable )[0];
275 $disp = array_values( array_values( $unidtable )[0] )[0];
292 private function getRuleConvertedTitle( $variant ) {
293 if ( $variant === $this->mConverter->getMainCode() ) {
302 if ( array_key_exists( $variant, $this->mUnidtable ) ) {
303 $disp = array_values( $this->mUnidtable[$variant] )[0];
309 return $this->getRuleConvertedStr( $variant );
315 private function generateConvTable() {
317 if ( !$this->mBidtable && !$this->mUnidtable ) {
318 $this->mConvTable = [];
324 $manLevel = $this->mConverter->getManualLevel();
327 foreach ( $this->mConverter->getVariants() as $v ) {
331 if ( !isset( $bidtable[$v] ) ) {
333 $this->mConverter->getVariantFallbacks( $v );
340 if ( isset( $bidtable[$v] ) ) {
341 foreach ( $vmarked as $vo ) {
347 if ( $manLevel[$v] ===
'bidirectional' ) {
348 $this->mConvTable[$v][$bidtable[$vo]] = $bidtable[$v];
350 if ( $manLevel[$vo] ===
'bidirectional' ) {
351 $this->mConvTable[$vo][$bidtable[$v]] = $bidtable[$vo];
357 if ( ( $manLevel[$v] ===
'bidirectional' || $manLevel[$v] ===
'unidirectional' )
358 && isset( $unidtable[$v] )
360 if ( isset( $this->mConvTable[$v] ) ) {
361 $this->mConvTable[$v] = $unidtable[$v] + $this->mConvTable[$v];
363 $this->mConvTable[$v] = $unidtable[$v];
373 public function parse( $variant =
null ) {
375 $variant = $this->mConverter->getPreferredVariant();
383 if ( $this->mVariantFlags ) {
385 if ( isset( $this->mVariantFlags[$variant] ) ) {
387 $this->mRules = $this->mConverter->autoConvert( $this->mRules,
393 $this->mConverter->getVariantFallbacks( $variant );
394 if ( is_array( $variantFallbacks ) ) {
395 foreach ( $variantFallbacks as $variantFallback ) {
397 if ( isset( $this->mVariantFlags[$variantFallback] ) ) {
400 $this->mConverter->autoConvert( $this->mRules,
407 $this->mFlags = $flags = [
'R' => true ];
410 if ( !isset( $flags[
'R'] ) && !isset( $flags[
'N'] ) ) {
412 $this->mRules = str_replace(
'=>',
'=>', $this->mRules );
417 if ( !$this->mBidtable && !$this->mUnidtable ) {
418 if ( isset( $flags[
'+'] ) || isset( $flags[
'-'] ) ) {
420 if ( $rules !==
'' ) {
421 foreach ( $this->mConverter->getVariants() as $v ) {
422 $this->mBidtable[$v] = $rules;
425 } elseif ( !isset( $flags[
'N'] ) && !isset( $flags[
'T'] ) ) {
426 $this->mFlags = $flags = [
'R' => true ];
430 $this->mRuleDisplay =
false;
431 foreach ( $flags as $flag => $unused ) {
435 $this->mRuleDisplay = $rules;
439 $ruleVar = trim( $rules );
440 $this->mRuleDisplay = $this->mConverter->getVariantNames()[$ruleVar] ??
'';
444 $this->mRuleDisplay = $this->getRulesDesc();
448 $this->mRuleDisplay =
'';
451 $this->mRulesAction =
'remove';
452 $this->mRuleDisplay =
'';
455 $this->mRulesAction =
'add';
456 $this->mRuleDisplay =
'';
459 $this->mRuleDisplay = $this->getRuleConvertedStr( $variant );
462 $this->mRuleTitle = $this->getRuleConvertedTitle( $variant );
463 $this->mRuleDisplay =
'';
469 if ( $this->mRuleDisplay ===
false ) {
470 $this->mRuleDisplay =
'<span class="error">'
471 .
wfMessage(
'converter-manual-rule-error' )->inContentLanguage()->escaped()
475 $this->generateConvTable();
483 return $this->mRules !==
'';