+ protected function recursiveConvertRule( $text, $variant, &$startPos, $depth = 0 ) {
+ // Quick sanity check (no function calls)
+ if ( $text[$startPos] !== '-' || $text[$startPos + 1] !== '{' ) {
+ throw new MWException( __METHOD__ . ': invalid input string' );
+ }
+
+ $startPos += 2;
+ $inner = '';
+ $warningDone = false;
+ $length = strlen( $text );
+
+ while ( $startPos < $length ) {
+ $m = false;
+ preg_match( '/-\{|\}-/', $text, $m, PREG_OFFSET_CAPTURE, $startPos );
+ if ( !$m ) {
+ // Unclosed rule
+ break;
+ }
+
+ $token = $m[0][0];
+ $pos = $m[0][1];
+
+ // Markup found
+ // Append initial segment
+ $inner .= substr( $text, $startPos, $pos - $startPos );
+
+ // Advance position
+ $startPos = $pos;
+
+ switch ( $token ) {
+ case '-{':
+ // Check max depth
+ if ( $depth >= $this->mMaxDepth ) {
+ $inner .= '-{';
+ if ( !$warningDone ) {
+ $inner .= '<span class="error">' .
+ wfMsgForContent( 'language-converter-depth-warning',
+ $this->mMaxDepth ) .
+ '</span>';
+ $warningDone = true;
+ }
+ $startPos += 2;
+ continue;
+ }
+ // Recursively parse another rule
+ $inner .= $this->recursiveConvertRule( $text, $variant, $startPos, $depth + 1 );
+ break;
+ case '}-':
+ // Apply the rule
+ $startPos += 2;
+ $rule = new ConverterRule( $inner, $this );
+ $rule->parse( $variant );
+ $this->applyManualConv( $rule );
+ return $rule->getDisplay();
+ default:
+ throw new MWException( __METHOD__ . ': invalid regex match' );
+ }
+ }
+
+ // Unclosed rule
+ if ( $startPos < $length ) {
+ $inner .= substr( $text, $startPos );
+ }
+ $startPos = $length;
+ return '-{' . $this->autoConvert( $inner, $variant );
+ }
+
+ /**
+ * If a language supports multiple variants, it is possible that
+ * non-existing link in one variant actually exists in another variant.
+ * This function tries to find it. See e.g. LanguageZh.php
+ *
+ * @param $link String: the name of the link
+ * @param $nt Mixed: the title object of the link
+ * @param $ignoreOtherCond Boolean: to disable other conditions when
+ * we need to transclude a template or update a category's link
+ * @return Null, the input parameters may be modified upon return
+ */
+ public function findVariantLink( &$link, &$nt, $ignoreOtherCond = false ) {