* included. Default is to assume a direct page view.
*
* The generated DOM tree must depend only on the input text and the flags.
- * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
+ * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of T6899.
*
* Any flag added to the $flags parameter here, or any other parameter liable to cause a
* change in the DOM tree for a given text, must be passed through the section identifier
* @return PPNode_Hash_Tree
*/
public function preprocessToObj( $text, $flags = 0 ) {
+ global $wgDisableLangConversion;
+
$tree = $this->cacheGetTree( $text, $flags );
if ( $tree !== false ) {
$store = json_decode( $tree );
$stack = new PPDStack_Hash;
$searchBase = "[{<\n";
+ if ( !$wgDisableLangConversion ) {
+ $searchBase .= '-';
+ }
+
// For fast reverse searches
$revText = strrev( $text );
$lengthText = strlen( $text );
$search = $searchBase;
if ( $stack->top === false ) {
$currentClosing = '';
+ } elseif (
+ $stack->top->close === '}-' &&
+ $stack->top->count > 2
+ ) {
+ # adjust closing for -{{{...{{
+ $currentClosing = '}';
+ $search .= $currentClosing;
} else {
$currentClosing = $stack->top->close;
$search .= $currentClosing;
break;
}
} else {
- $curChar = $text[$i];
+ $curChar = $curTwoChar = $text[$i];
+ if ( ( $i + 1 ) < $lengthText ) {
+ $curTwoChar .= $text[$i + 1];
+ }
if ( $curChar == '|' ) {
$found = 'pipe';
} elseif ( $curChar == '=' ) {
} else {
$found = 'line-start';
}
+ } elseif ( $curTwoChar == $currentClosing ) {
+ $found = 'close';
+ $curChar = $curTwoChar;
} elseif ( $curChar == $currentClosing ) {
$found = 'close';
+ } elseif ( isset( $this->rules[$curTwoChar] ) ) {
+ $curChar = $curTwoChar;
+ $found = 'open';
+ $rule = $this->rules[$curChar];
} elseif ( isset( $this->rules[$curChar] ) ) {
$found = 'open';
$rule = $this->rules[$curChar];
} else {
- # Some versions of PHP have a strcspn which stops on null characters
- # Ignore and continue
+ # Some versions of PHP have a strcspn which stops on
+ # null characters; ignore these and continue.
+ # We also may get '-' and '}' characters here which
+ # don't match -{ or $currentClosing. Add these to
+ # output and continue.
+ if ( $curChar == '-' || $curChar == '}' ) {
+ self::addLiteral( $accum, $curChar );
+ }
++$i;
continue;
}
// input pointer.
} elseif ( $found == 'open' ) {
# count opening brace characters
- $count = strspn( $text, $curChar, $i );
+ $curLen = strlen( $curChar );
+ $count = ( $curLen > 1 ) ?
+ # allow the final character to repeat
+ strspn( $text, $curChar[$curLen-1], $i+1 ) + 1 :
+ strspn( $text, $curChar, $i );
# we need to add to stack only if opening brace count is enough for one of the rules
if ( $count >= $rule['min'] ) {
$piece = $stack->top;
# lets check if there are enough characters for closing brace
$maxCount = $piece->count;
- $count = strspn( $text, $curChar, $i, $maxCount );
+ if ( $piece->close === '}-' && $curChar === '}' ) {
+ $maxCount--; # don't try to match closing '-' as a '}'
+ }
+ $curLen = strlen( $curChar );
+ $count = ( $curLen > 1 ) ? $curLen :
+ strspn( $text, $curChar, $i, $maxCount );
# check for maximum matching characters (if there are 5 closing
# characters, we will probably need only 3 - depending on the rules)
$rule = $this->rules[$piece->open];
+ if ( $piece->close === '}-' && $piece->count > 2 ) {
+ # tweak for -{..{{ }}..}-
+ $rule = $this->rules['{'];
+ }
if ( $count > $rule['max'] ) {
# The specified maximum exists in the callback array, unless the caller
# has made an error
if ( $matchingCount <= 0 ) {
# No matching element found in callback array
# Output a literal closing brace and continue
- self::addLiteral( $accum, str_repeat( $curChar, $count ) );
+ $endText = substr( $text, $i, $count );
+ self::addLiteral( $accum, $endText );
$i += $count;
continue;
}
$name = $rule['names'][$matchingCount];
if ( $name === null ) {
// No element, just literal text
+ $endText = substr( $text, $i, $matchingCount );
$element = $piece->breakSyntax( $matchingCount );
- self::addLiteral( $element, str_repeat( $rule['end'], $matchingCount ) );
+ self::addLiteral( $element, $endText );
} else {
# Create XML element
$parts = $piece->parts;
$stack->push( $piece );
$accum =& $stack->getAccum();
} else {
- self::addLiteral( $accum, str_repeat( $piece->open, $piece->count ) );
+ $s = substr( $piece->open, 0, -1 );
+ $s .= str_repeat(
+ substr( $piece->open, -1 ),
+ $piece->count - strlen( $s )
+ );
+ self::addLiteral( $accum, $s );
}
}
$accum[] = [ 'equals', [ '=' ] ];
$stack->getCurrentPart()->eqpos = count( $accum ) - 1;
++$i;
+ } elseif ( $found == 'dash' ) {
+ self::addLiteral( $accum, '-' );
+ ++$i;
}
}
if ( $openingCount === false ) {
$openingCount = $this->count;
}
- $accum = [ str_repeat( $this->open, $openingCount ) ];
+ $s = substr( $this->open, 0, -1 );
+ $s .= str_repeat(
+ substr( $this->open, -1 ),
+ $openingCount - strlen( $s )
+ );
+ $accum = [ $s ];
$lastIndex = 0;
$first = true;
foreach ( $this->parts as $part ) {