X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fparser%2FBlockLevelPass.php;h=599fbf61de1617c0d1a29a7c6711bd89fb478016;hb=33e4ac5b220b0edbef6774b3d961a3313fbf76e9;hp=cbacd34811f61e59d4cbf707cc90367dba6578b8;hpb=69d88777dc51268d0b67b0f4706883b7b07087dc;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/parser/BlockLevelPass.php b/includes/parser/BlockLevelPass.php
index cbacd34811..599fbf61de 100644
--- a/includes/parser/BlockLevelPass.php
+++ b/includes/parser/BlockLevelPass.php
@@ -38,6 +38,7 @@ class BlockLevelPass {
const COLON_STATE_COMMENT = 5;
const COLON_STATE_COMMENTDASH = 6;
const COLON_STATE_COMMENTDASHDASH = 7;
+ const COLON_STATE_LC = 8;
/**
* Make lists from lines starting with ':', '*', '#', etc.
@@ -285,20 +286,20 @@ class BlockLevelPass {
# @todo consider using a stack for nestable elements like span, table and div
$openMatch = preg_match(
'/(?:
closeParagraph();
if ( $preOpenMatch && !$preCloseMatch ) {
$this->inPre = true;
@@ -352,7 +353,7 @@ class BlockLevelPass {
}
}
}
- # somewhere above we forget to get out of pre block (bug 785)
+ # somewhere above we forget to get out of pre block (T2785)
if ( $preCloseMatch && $this->inPre ) {
$this->inPre = false;
}
@@ -389,15 +390,14 @@ class BlockLevelPass {
* @return string The position of the ':', or false if none found
*/
private function findColonNoLinks( $str, &$before, &$after ) {
- $colonPos = strpos( $str, ':' );
- if ( $colonPos === false ) {
+ if ( !preg_match( '/:|<|-\{/', $str, $m, PREG_OFFSET_CAPTURE ) ) {
# Nothing to find!
return false;
}
- $ltPos = strpos( $str, '<' );
- if ( $ltPos === false || $ltPos > $colonPos ) {
+ if ( $m[0][0] === ':' ) {
# Easy; no tag nesting to worry about
+ $colonPos = $m[0][1];
$before = substr( $str, 0, $colonPos );
$after = substr( $str, $colonPos + 1 );
return $colonPos;
@@ -405,9 +405,10 @@ class BlockLevelPass {
# Ugly state machine to walk through avoiding tags.
$state = self::COLON_STATE_TEXT;
- $level = 0;
+ $ltLevel = 0;
+ $lcLevel = 0;
$len = strlen( $str );
- for ( $i = 0; $i < $len; $i++ ) {
+ for ( $i = $m[0][1]; $i < $len; $i++ ) {
$c = $str[$i];
switch ( $state ) {
@@ -418,7 +419,7 @@ class BlockLevelPass {
$state = self::COLON_STATE_TAGSTART;
break;
case ":":
- if ( $level === 0 ) {
+ if ( $ltLevel === 0 ) {
# We found it!
$before = substr( $str, 0, $i );
$after = substr( $str, $i + 1 );
@@ -428,35 +429,44 @@ class BlockLevelPass {
break;
default:
# Skip ahead looking for something interesting
- $colonPos = strpos( $str, ':', $i );
- if ( $colonPos === false ) {
+ if ( !preg_match( '/:|<|-\{/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
# Nothing else interesting
return false;
}
- $ltPos = strpos( $str, '<', $i );
- if ( $level === 0 ) {
- if ( $ltPos === false || $colonPos < $ltPos ) {
- # We found it!
- $before = substr( $str, 0, $colonPos );
- $after = substr( $str, $colonPos + 1 );
- return $i;
- }
+ if ( $m[0][0] === '-{' ) {
+ $state = self::COLON_STATE_LC;
+ $lcLevel++;
+ $i = $m[0][1] + 1;
+ } else {
+ # Skip ahead to next interesting character.
+ $i = $m[0][1] - 1;
}
- if ( $ltPos === false ) {
- # Nothing else interesting to find; abort!
- # We're nested, but there's no close tags left. Abort!
- break 2;
+ break;
+ }
+ break;
+ case self::COLON_STATE_LC:
+ # In language converter markup -{ ... }-
+ if ( !preg_match( '/-\{|\}-/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
+ # Nothing else interesting to find; abort!
+ # We're nested in language converter markup, but there
+ # are no close tags left. Abort!
+ break 2;
+ } elseif ( $m[0][0] === '-{' ) {
+ $i = $m[0][1] + 1;
+ $lcLevel++;
+ } elseif ( $m[0][0] === '}-' ) {
+ $i = $m[0][1] + 1;
+ $lcLevel--;
+ if ( $lcLevel === 0 ) {
+ $state = self::COLON_STATE_TEXT;
}
- # Skip ahead to next tag start
- $i = $ltPos;
- $state = self::COLON_STATE_TAGSTART;
}
break;
case self::COLON_STATE_TAG:
# In a
switch ( $c ) {
case ">":
- $level++;
+ $ltLevel++;
$state = self::COLON_STATE_TEXT;
break;
case "/":
@@ -486,10 +496,12 @@ class BlockLevelPass {
case self::COLON_STATE_CLOSETAG:
# In a
if ( $c === ">" ) {
- $level--;
- if ( $level < 0 ) {
+ if ( $ltLevel > 0 ) {
+ $ltLevel--;
+ } else {
+ # ignore the excess close tag, but keep looking for
+ # colons. (This matches Parsoid behavior.)
wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
- return false;
}
$state = self::COLON_STATE_TEXT;
}
@@ -526,8 +538,11 @@ class BlockLevelPass {
throw new MWException( "State machine error in " . __METHOD__ );
}
}
- if ( $level > 0 ) {
- wfDebug( __METHOD__ . ": Invalid input; not enough close tags (level $level, state $state)\n" );
+ if ( $ltLevel > 0 || $lcLevel > 0 ) {
+ wfDebug(
+ __METHOD__ . ": Invalid input; not enough close tags " .
+ "(level $ltLevel/$lcLevel, state $state)\n"
+ );
return false;
}
return false;