64 $this->mConverter = $converter;
74 $variants = (array)$variants;
78 foreach ( $variants as $variant ) {
79 if ( isset( $this->mBidtable[$variant] ) ) {
80 return $this->mBidtable[$variant];
89 private function parseFlags() {
94 $sepPos = strpos( $text,
'|' );
95 if ( $sepPos !==
false ) {
96 $validFlags = $this->mConverter->getFlags();
97 $f = StringUtils::explode(
';', substr( $text, 0, $sepPos ) );
98 foreach ( $f as $ff ) {
100 if ( isset( $validFlags[$ff] ) ) {
101 $flags[$validFlags[$ff]] =
true;
104 $text = strval( substr( $text, $sepPos + 1 ) );
109 } elseif ( isset( $flags[
'R'] ) ) {
111 $flags = [
'R' => true ];
112 } elseif ( isset( $flags[
'N'] ) ) {
114 $flags = [
'N' => true ];
115 } elseif ( isset( $flags[
'-'] ) ) {
117 $flags = [
'-' => true ];
118 } elseif ( count( $flags ) === 1 && isset( $flags[
'T'] ) ) {
120 } elseif ( isset( $flags[
'H'] ) ) {
122 $temp = [
'+' =>
true,
'H' => true ];
123 if ( isset( $flags[
'T'] ) ) {
126 if ( isset( $flags[
'D'] ) ) {
131 if ( isset( $flags[
'A'] ) ) {
135 if ( isset( $flags[
'D'] ) ) {
136 unset( $flags[
'S'] );
140 $variantFlags = array_intersect( array_keys( $flags ), $this->mConverter->getVariants() );
141 if ( $variantFlags ) {
142 $variantFlags = array_fill_keys( $variantFlags,
true );
146 $this->mVariantFlags = $variantFlags;
147 $this->mRules = $text;
148 $this->mFlags = $flags;
154 private function parseRules() {
158 $varsep_pattern = $this->mConverter->getVarSeparatorPattern();
161 $rules = preg_replace(
'/(&[#a-zA-Z0-9]+);/',
"$1\x01", $rules );
162 $choice = preg_split( $varsep_pattern, $rules );
164 if ( $choice ===
false ) {
165 $error = preg_last_error();
166 $errorText = preg_last_error_msg();
167 LoggerFactory::getInstance(
'parser' )->warning(
168 'ConverterRule preg_split error: {code} {errorText}',
171 'errorText' => $errorText
176 $choice = str_replace(
"\x01",
';', $choice );
178 foreach ( $choice as $c ) {
179 $v = explode(
':', $c, 2 );
180 if ( count( $v ) !== 2 ) {
186 $u = explode(
'=>', $v, 2 );
187 $vv = $this->mConverter->validateVariant( $v );
190 if ( count( $u ) === 1 && $to !==
'' && $vv ) {
191 $bidtable[$vv] = $to;
192 } elseif ( count( $u ) === 2 ) {
193 $from = trim( $u[0] );
195 $vv = $this->mConverter->validateVariant( $v );
197 if ( array_key_exists( $vv, $unidtable )
198 && !is_array( $unidtable[$vv] )
201 $unidtable[$vv] = [ $from => $to ];
202 } elseif ( $from !==
'' && $vv ) {
203 $unidtable[$vv][$from] = $to;
207 if ( !isset( $this->mConverter->getVariantNames()[$vv] ) ) {
213 $this->mBidtable = $bidtable;
214 $this->mUnidtable = $unidtable;
220 private function getRulesDesc() {
221 $codesep = $this->mConverter->getDescCodeSeparator();
222 $varsep = $this->mConverter->getDescVarSeparator();
224 foreach ( $this->mBidtable as $k => $v ) {
225 $text .= $this->mConverter->getVariantNames()[$k] .
"$codesep$v$varsep";
227 foreach ( $this->mUnidtable as $k => $a ) {
228 foreach ( $a as $from => $to ) {
229 $text .= $from .
'⇒' . $this->mConverter->getVariantNames()[$k] .
230 "$codesep$to$varsep";
243 private function getRuleConvertedStr( $variant ) {
247 if ( count( $bidtable ) + count( $unidtable ) === 0 ) {
254 if ( $disp ===
false ) {
256 $this->mConverter->getVariantFallbacks( $variant ) );
259 if ( $disp ===
false && array_key_exists( $variant, $unidtable ) ) {
260 $disp = array_values( $unidtable[$variant] )[0];
263 if ( $disp ===
false && $this->mConverter->getManualLevel()[$variant] ===
'disable' ) {
264 if ( count( $bidtable ) > 0 ) {
265 $disp = array_values( $bidtable )[0];
267 $disp = array_values( array_values( $unidtable )[0] )[0];
284 private function getRuleConvertedTitle( $variant ) {
285 if ( $variant === $this->mConverter->getMainCode() ) {
294 if ( array_key_exists( $variant, $this->mUnidtable ) ) {
295 $disp = array_values( $this->mUnidtable[$variant] )[0];
301 return $this->getRuleConvertedStr( $variant );
307 private function generateConvTable() {
309 if ( !$this->mBidtable && !$this->mUnidtable ) {
310 $this->mConvTable = [];
316 $manLevel = $this->mConverter->getManualLevel();
319 foreach ( $this->mConverter->getVariants() as $v ) {
323 if ( !isset( $bidtable[$v] ) ) {
325 $this->mConverter->getVariantFallbacks( $v );
332 if ( isset( $bidtable[$v] ) ) {
333 foreach ( $vmarked as $vo ) {
339 if ( $manLevel[$v] ===
'bidirectional' ) {
340 $this->mConvTable[$v][$bidtable[$vo]] = $bidtable[$v];
342 if ( $manLevel[$vo] ===
'bidirectional' ) {
343 $this->mConvTable[$vo][$bidtable[$v]] = $bidtable[$vo];
349 if ( ( $manLevel[$v] ===
'bidirectional' || $manLevel[$v] ===
'unidirectional' )
350 && isset( $unidtable[$v] )
352 if ( isset( $this->mConvTable[$v] ) ) {
353 $this->mConvTable[$v] = $unidtable[$v] + $this->mConvTable[$v];
355 $this->mConvTable[$v] = $unidtable[$v];
365 public function parse( $variant =
null ) {
367 $variant = $this->mConverter->getPreferredVariant();
375 if ( $this->mVariantFlags ) {
377 if ( isset( $this->mVariantFlags[$variant] ) ) {
379 $this->mRules = $this->mConverter->autoConvert( $this->mRules,
385 $this->mConverter->getVariantFallbacks( $variant );
386 if ( is_array( $variantFallbacks ) ) {
387 foreach ( $variantFallbacks as $variantFallback ) {
389 if ( isset( $this->mVariantFlags[$variantFallback] ) ) {
392 $this->mConverter->autoConvert( $this->mRules,
399 $this->mFlags = $flags = [
'R' => true ];
402 if ( !isset( $flags[
'R'] ) && !isset( $flags[
'N'] ) ) {
404 $this->mRules = str_replace(
'=>',
'=>', $this->mRules );
409 if ( !$this->mBidtable && !$this->mUnidtable ) {
410 if ( isset( $flags[
'+'] ) || isset( $flags[
'-'] ) ) {
412 if ( $rules !==
'' ) {
413 foreach ( $this->mConverter->getVariants() as $v ) {
414 $this->mBidtable[$v] = $rules;
417 } elseif ( !isset( $flags[
'N'] ) && !isset( $flags[
'T'] ) ) {
418 $this->mFlags = $flags = [
'R' => true ];
422 $this->mRuleDisplay =
false;
423 foreach ( $flags as $flag => $unused ) {
427 $this->mRuleDisplay = $rules;
431 $ruleVar = trim( $rules );
432 $this->mRuleDisplay = $this->mConverter->getVariantNames()[$ruleVar] ??
'';
436 $this->mRuleDisplay = $this->getRulesDesc();
440 $this->mRuleDisplay =
'';
443 $this->mRulesAction =
'remove';
444 $this->mRuleDisplay =
'';
447 $this->mRulesAction =
'add';
448 $this->mRuleDisplay =
'';
451 $this->mRuleDisplay = $this->getRuleConvertedStr( $variant );
454 $this->mRuleTitle = $this->getRuleConvertedTitle( $variant );
455 $this->mRuleDisplay =
'';
461 if ( $this->mRuleDisplay ===
false ) {
462 $this->mRuleDisplay =
'<span class="error">'
463 .
wfMessage(
'converter-manual-rule-error' )->inContentLanguage()->escaped()
467 $this->generateConvTable();
475 return $this->mRules !==
'';