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 );
173 if ( $choice ===
false ) {
174 $error = preg_last_error();
175 $errorText = preg_last_error_msg();
176 LoggerFactory::getInstance(
'parser' )->warning(
177 'ConverterRule preg_split error: {code} {errorText}',
180 'errorText' => $errorText
185 $choice = str_replace(
"\x01",
';', $choice );
187 foreach ( $choice as $c ) {
188 $v = explode(
':', $c, 2 );
189 if ( count( $v ) !== 2 ) {
195 $u = explode(
'=>', $v, 2 );
196 $vv = $this->mConverter->validateVariant( $v );
199 if ( count( $u ) === 1 && $to !==
'' && $vv ) {
200 $bidtable[$vv] = $to;
201 } elseif ( count( $u ) === 2 ) {
202 $from = trim( $u[0] );
204 $vv = $this->mConverter->validateVariant( $v );
206 if ( array_key_exists( $vv, $unidtable )
207 && !is_array( $unidtable[$vv] )
210 $unidtable[$vv] = [ $from => $to ];
211 } elseif ( $from !==
'' && $vv ) {
212 $unidtable[$vv][$from] = $to;
216 if ( !isset( $this->mConverter->getVariantNames()[$vv] ) ) {
222 $this->mBidtable = $bidtable;
223 $this->mUnidtable = $unidtable;
229 private function getRulesDesc() {
230 $codesep = $this->mConverter->getDescCodeSeparator();
231 $varsep = $this->mConverter->getDescVarSeparator();
233 foreach ( $this->mBidtable as $k => $v ) {
234 $text .= $this->mConverter->getVariantNames()[$k] .
"$codesep$v$varsep";
236 foreach ( $this->mUnidtable as $k => $a ) {
237 foreach ( $a as $from => $to ) {
238 $text .= $from .
'⇒' . $this->mConverter->getVariantNames()[$k] .
239 "$codesep$to$varsep";
252 private function getRuleConvertedStr( $variant ) {
256 if ( count( $bidtable ) + count( $unidtable ) === 0 ) {
263 if ( $disp ===
false ) {
265 $this->mConverter->getVariantFallbacks( $variant ) );
268 if ( $disp ===
false && array_key_exists( $variant, $unidtable ) ) {
269 $disp = array_values( $unidtable[$variant] )[0];
272 if ( $disp ===
false && $this->mConverter->getManualLevel()[$variant] ===
'disable' ) {
273 if ( count( $bidtable ) > 0 ) {
274 $disp = array_values( $bidtable )[0];
276 $disp = array_values( array_values( $unidtable )[0] )[0];
293 private function getRuleConvertedTitle( $variant ) {
294 if ( $variant === $this->mConverter->getMainCode() ) {
303 if ( array_key_exists( $variant, $this->mUnidtable ) ) {
304 $disp = array_values( $this->mUnidtable[$variant] )[0];
310 return $this->getRuleConvertedStr( $variant );
316 private function generateConvTable() {
318 if ( !$this->mBidtable && !$this->mUnidtable ) {
319 $this->mConvTable = [];
325 $manLevel = $this->mConverter->getManualLevel();
328 foreach ( $this->mConverter->getVariants() as $v ) {
332 if ( !isset( $bidtable[$v] ) ) {
334 $this->mConverter->getVariantFallbacks( $v );
341 if ( isset( $bidtable[$v] ) ) {
342 foreach ( $vmarked as $vo ) {
348 if ( $manLevel[$v] ===
'bidirectional' ) {
349 $this->mConvTable[$v][$bidtable[$vo]] = $bidtable[$v];
351 if ( $manLevel[$vo] ===
'bidirectional' ) {
352 $this->mConvTable[$vo][$bidtable[$v]] = $bidtable[$vo];
358 if ( ( $manLevel[$v] ===
'bidirectional' || $manLevel[$v] ===
'unidirectional' )
359 && isset( $unidtable[$v] )
361 if ( isset( $this->mConvTable[$v] ) ) {
362 $this->mConvTable[$v] = $unidtable[$v] + $this->mConvTable[$v];
364 $this->mConvTable[$v] = $unidtable[$v];
374 public function parse( $variant =
null ) {
376 $variant = $this->mConverter->getPreferredVariant();
384 if ( $this->mVariantFlags ) {
386 if ( isset( $this->mVariantFlags[$variant] ) ) {
388 $this->mRules = $this->mConverter->autoConvert( $this->mRules,
394 $this->mConverter->getVariantFallbacks( $variant );
395 if ( is_array( $variantFallbacks ) ) {
396 foreach ( $variantFallbacks as $variantFallback ) {
398 if ( isset( $this->mVariantFlags[$variantFallback] ) ) {
401 $this->mConverter->autoConvert( $this->mRules,
408 $this->mFlags = $flags = [
'R' => true ];
411 if ( !isset( $flags[
'R'] ) && !isset( $flags[
'N'] ) ) {
413 $this->mRules = str_replace(
'=>',
'=>', $this->mRules );
418 if ( !$this->mBidtable && !$this->mUnidtable ) {
419 if ( isset( $flags[
'+'] ) || isset( $flags[
'-'] ) ) {
421 if ( $rules !==
'' ) {
422 foreach ( $this->mConverter->getVariants() as $v ) {
423 $this->mBidtable[$v] = $rules;
426 } elseif ( !isset( $flags[
'N'] ) && !isset( $flags[
'T'] ) ) {
427 $this->mFlags = $flags = [
'R' => true ];
431 $this->mRuleDisplay =
false;
432 foreach ( $flags as $flag => $unused ) {
436 $this->mRuleDisplay = $rules;
440 $ruleVar = trim( $rules );
441 $this->mRuleDisplay = $this->mConverter->getVariantNames()[$ruleVar] ??
'';
445 $this->mRuleDisplay = $this->getRulesDesc();
449 $this->mRuleDisplay =
'';
452 $this->mRulesAction =
'remove';
453 $this->mRuleDisplay =
'';
456 $this->mRulesAction =
'add';
457 $this->mRuleDisplay =
'';
460 $this->mRuleDisplay = $this->getRuleConvertedStr( $variant );
463 $this->mRuleTitle = $this->getRuleConvertedTitle( $variant );
464 $this->mRuleDisplay =
'';
470 if ( $this->mRuleDisplay ===
false ) {
471 $this->mRuleDisplay =
'<span class="error">'
472 .
wfMessage(
'converter-manual-rule-error' )->inContentLanguage()->escaped()
476 $this->generateConvTable();
484 return $this->mRules !==
'';