From: Wil Mahan Date: Tue, 5 Oct 2004 03:55:41 +0000 (+0000) Subject: Don't call Parser::replaceInternalLinks twice, but instead X-Git-Tag: 1.5.0alpha1~1654 X-Git-Url: http://git.heureux-cyclage.org/?a=commitdiff_plain;h=f9841742904f845b88f870a15659680239512522;p=lhc%2Fweb%2Fwiklou.git Don't call Parser::replaceInternalLinks twice, but instead recursively replace links inside of image captions. Patch by Rowan Collins (IMSoP), loosely based on a patch by me. Fixes bug 637. --- diff --git a/includes/Parser.php b/includes/Parser.php index f1fc4b56f9..53aa59aa2d 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -669,8 +669,6 @@ class Parser } $text = $this->doAllQuotes( $text ); $text = $this->replaceInternalLinks ( $text ); - # Another call to replace links and images inside captions of images - $text = $this->replaceInternalLinks ( $text ); $text = $this->replaceExternalLinks( $text ); $text = $this->doMagicLinks( $text ); $text = $this->doTableStuff( $text ); @@ -1076,19 +1074,23 @@ class Parser $redirect = MagicWord::get ( MAG_REDIRECT ) ; + #split the entire text string on occurences of [[ $a = explode( '[[', ' ' . $s ); + #get the first element (all text up to first [[), and remove the space we added $s = array_shift( $a ); $s = substr( $s, 1 ); # Match a link having the form [[namespace:link|alternate]]trail static $e1 = FALSE; if ( !$e1 ) { $e1 = "/^([{$tc}]+)(?:\\|([^]]+))?]](.*)\$/sD"; } + # Match cases where there is no "]]", which might still be images + static $e1_img = FALSE; + if ( !$e1_img ) { $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD"; } # Match the end of a line for a word that's not followed by whitespace, # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched static $e2 = '/^(.*?)([a-zA-Z\x80-\xff]+)$/sD'; $useLinkPrefixExtension = $wgContLang->linkPrefixExtension(); - # Special and Media are pseudo-namespaces; no pages actually exist in them $nottalk = !Namespace::isTalk( $this->mTitle->getNamespace() ); @@ -1105,8 +1107,9 @@ class Parser wfProfileOut( $fname.'-setup' ); - # start procedeeding each line - foreach ( $a as $line ) { + # Loop for each link + for ($k = 0; isset( $a[$k] ); $k++) { + $line = $a[$k]; wfProfileIn( $fname.'-prefixhandling' ); if ( $useLinkPrefixExtension ) { if ( preg_match( $e2, $s, $m ) ) { @@ -1123,11 +1126,18 @@ class Parser } wfProfileOut( $fname.'-prefixhandling' ); + $might_be_img = false; + if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt $text = $m[2]; # fix up urlencoded title texts if(preg_match('/%/', $m[1] )) $m[1] = urldecode($m[1]); $trail = $m[3]; + } elseif( preg_match($e1_img, $line, $m) ) { # Invalid, but might be an image with a link in its caption + $might_be_img = true; + $text = $m[2]; + if(preg_match('/%/', $m[1] )) $m[1] = urldecode($m[1]); + $trail = ""; } else { # Invalid form; output directly $s .= $prefix . '[[' . $line ; continue; @@ -1150,9 +1160,6 @@ class Parser $link = substr($link, 1); } - $wasblank = ( '' == $text ); - if( $wasblank ) $text = $link; - $nt = Title::newFromText( $link ); if( !$nt ) { $s .= $prefix . '[[' . $line; @@ -1185,6 +1192,44 @@ class Parser $ns = $nt->getNamespace(); $iw = $nt->getInterWiki(); + if ($might_be_img) { # if this is actually an invalid link + if ($ns == NS_IMAGE && $noforce) { #but might be an image + $found = false; + while (isset ($a[$k+1]) ) { + #look at the next 'line' to see if we can close it there + $next_line = array_shift(array_splice( $a, $k + 1, 1) ); + if( preg_match("/^(.*?]].*?)]](.*)$/sD", $next_line, $m) ) { + # the first ]] closes the inner link, the second the image + $found = true; + $text .= '[[' . $m[1]; + $trail = $m[2]; + break; + } elseif( preg_match("/^.*?]].*$/sD", $next_line, $m) ) { + #if there's exactly one ]] that's fine, we'll keep looking + $text .= '[[' . $m[0]; + } else { + #if $next_line is invalid too, we need look no further + $text .= '[[' . $next_line; + break; + } + } + if ( !$found ) { + # we couldn't find the end of this imageLink, so output it raw + $s .= $prefix . '[[' . $link . '|' . $text; + # note: no $trail, because without an end, there *is* no trail + continue; + } + } else { #it's not an image, so output it raw + $s .= $prefix . '[[' . $link . '|' . $text; + # note: no $trail, because without an end, there *is* no trail + continue; + } + } + + $wasblank = ( '' == $text ); + if( $wasblank ) $text = $link; + + # Link not escaped by : , create the various objects if( $noforce ) { @@ -1197,19 +1242,25 @@ class Parser } if ( $ns == NS_IMAGE ) { - $s .= $prefix . $sk->makeImageLinkObj( $nt, $text ) . $trail; + # recursively parse links inside the image caption + # actually, this will parse them in any other parameters, too, + # but it might be hard to fix that, and it doesn't matter ATM + $text = $this->replaceExternalLinks($text); + $text = $this->replaceInternalLinks($text); + + # replace the image with a link-holder so that replaceExternalLinks() can't mess with it + $s .= $prefix . $this->insertStripItem( $sk->makeImageLinkObj( $nt, $text ), $this->mStripState ) . $trail; $wgLinkCache->addImageLinkObj( $nt ); continue; } if ( $ns == NS_CATEGORY ) { $t = $nt->getText() ; - $nnt = Title::newFromText ( Namespace::getCanonicalName(NS_CATEGORY).':'.$t ) ; $wgLinkCache->suspend(); # Don't save in links/brokenlinks $pPLC=$sk->postParseLinkColour(); $sk->postParseLinkColour( false ); - $t = $sk->makeLinkObj( $nnt, $t, '', '' , $prefix ); + $t = $sk->makeLinkObj( $nt, $t, '', '' , $prefix ); $sk->postParseLinkColour( $pPLC ); $wgLinkCache->resume(); @@ -1236,6 +1287,7 @@ class Parser continue; } + # Special and Media are pseudo-namespaces; no pages actually exist in them if( $ns == NS_MEDIA ) { $s .= $prefix . $sk->makeMediaLinkObj( $nt, $text ) . $trail; $wgLinkCache->addImageLinkObj( $nt ); diff --git a/includes/Skin.php b/includes/Skin.php index b079659144..3e4af78173 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -1356,7 +1356,7 @@ class Skin { } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) { $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix ); } elseif ( ( -1 == $nt->getNamespace() ) || - ( Namespace::getImage() == $nt->getNamespace() ) ) { + ( NS_IMAGE == $nt->getNamespace() ) ) { $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix ); } else { if ( $this->postParseLinkColour() ) { @@ -1773,6 +1773,7 @@ class Skin { if ( empty( $alt ) ) { $alt = preg_replace( '/\.(.+?)^/', '', $img->getName() ); } + $alt = preg_replace( '/<[^>]*>/', '', $alt ); $alt = htmlspecialchars( $alt ); $u = $nt->escapeLocalURL();