Parser cache moved to memcached
[lhc/web/wiklou.git] / includes / Parser.php
index ef2f494..200c8f4 100644 (file)
@@ -105,6 +105,10 @@ class Parser
                # Clean up special characters, only run once, next-to-last before doBlockLevels
                if(!$wgUseTidy) {
                        $fixtags = array(
+                               # french spaces, last one Guillemet-left
+                               "/ (\\?|:|!|\\302\\273)/i"=>" \\1", 
+                               # french spaces, Guillemet-right
+                               "/(\\302\\253) /i"=>"\\1 ", 
                                "/<hr *>/i" => '<hr/>',
                                "/<br *>/i" => '<br/>',
                                "/<center *>/i"=>'<div class="center">',
@@ -116,6 +120,10 @@ class Parser
                        $text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
                } else {
                        $fixtags = array(
+                               # french spaces, last one Guillemet-left
+                               "/ (\\?|:|!|\\302\\273)/i"=>"&nbsp;\\1", 
+                               # french spaces, Guillemet-right
+                               "/(\\302\\253) /i"=>"\\1&nbsp;", 
                                "/<center *>/i"=>'<div class="center">',
                                "/<\\/center *>/i" => '</div>'
                        );
@@ -578,6 +586,7 @@ class Parser
                $text = $this->doAllQuotes( $text );
                $text = $this->replaceExternalLinks( $text );
                $text = $this->replaceInternalLinks ( $text );
+               $text = $this->replaceInternalLinks ( $text );
                //$text = $this->doTokenizedParser ( $text );
                $text = $this->doTableStuff ( $text ) ;
                $text = $this->magicISBN( $text );
@@ -858,7 +867,7 @@ class Parser
                                        array_push( $this->mOutput->mLanguageLinks, $nt->getPrefixedText() );
                                        $s .= $prefix . $trail ;
                                        wfProfileOut( $fname );
-                                       return (trim($s) == '')? '': $s;
+                                       $s .= (trim($s) == '')? '': $s;
                                        continue;
                                }
                                if ( $ns == $image ) {
@@ -866,7 +875,8 @@ class Parser
                                        $wgLinkCache->addImageLinkObj( $nt );
                                        wfProfileOut( $fname );
                                        continue;
-                               } else if ( $ns == $category ) {
+                               }
+                               if ( $ns == $category ) {
                                        $t = $nt->getText() ;
                                        $nnt = Title::newFromText ( Namespace::getCanonicalName($category).":".$t ) ;
 
@@ -1210,9 +1220,8 @@ class Parser
                if ( $this->mOutputType == OT_HTML ) {
                        $text = preg_replace_callback( "/(\\n?){{{([$titleChars]*?)}}}/", "wfArgSubstitution", $text );
                }
-
                # Double brace substitution
-               $regex = "/(\\n?){{([$titleChars]*?)(\\|.*?|)}}/s";
+               $regex = "/(\\n?){{([$titleChars]*)(\\|.*?|)}}/s";
                $text = preg_replace_callback( $regex, "wfBraceSubstitution", $text );
 
                array_pop( $this->mArgStack );
@@ -1804,7 +1813,7 @@ class Parser
        {
                global $wgLang;
 
-               $a = split( "ISBN ", " $text" );
+               $a = split( "RFC ", " $text" );
                if ( count ( $a ) < 2 ) return $text;
                $text = substr( array_shift( $a ), 1);
                $valid = "0123456789";
@@ -1967,6 +1976,7 @@ class Parser
 class ParserOutput
 {
        var $mText, $mLanguageLinks, $mCategoryLinks, $mContainsOldMagic;
+       var $mTouched; # Used for caching
 
        function ParserOutput( $text = "", $languageLinks = array(), $categoryLinks = array(),
                $containsOldMagic = false )
@@ -1975,16 +1985,19 @@ class ParserOutput
                $this->mLanguageLinks = $languageLinks;
                $this->mCategoryLinks = $categoryLinks;
                $this->mContainsOldMagic = $containsOldMagic;
+               $this->mTouched = "";
        }
 
        function getText() { return $this->mText; }
        function getLanguageLinks() { return $this->mLanguageLinks; }
        function getCategoryLinks() { return $this->mCategoryLinks; }
+       function getTouched() { return $this->mTouched; }
        function containsOldMagic() { return $this->mContainsOldMagic; }
        function setText( $text ) { return wfSetVar( $this->mText, $text ); }
        function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); }
        function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategoryLinks, $cl ); }
        function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
+       function setTouched( $t ) { return wfSetVar( $this->mTouched, $t ); }
 
        function merge( $other ) {
                $this->mLanguageLinks = array_merge( $this->mLanguageLinks, $other->mLanguageLinks );
@@ -2071,6 +2084,29 @@ class ParserOptions
 function wfBraceSubstitution( $matches )
 {
        global $wgCurParser;
+       $titleChars = Title::legalChars();
+
+       # not really nested stuff, just multiple includes separated by titlechars
+       if(preg_match("/^([^}{]*)}}([^}{]*{{)(.*)$/s", $matches[2], $m)) {
+               $text = wfInternalBraceSubstitution( $m[1] );
+               $string = $text.$m[2].$m[3];
+               while(preg_match("/^([^}{]*){{([$titleChars]*?)(}}[^}{]*{{.*)?$/s", $string, $m)) {
+                       $text = wfInternalBraceSubstitution( $m[2] );
+                       $trail = !empty($m[3])? preg_replace("/^}}/", '', $m[3]):'';
+                       $string = $m[1].$text.$trail;
+               }
+               return $string;
+       }
+               
+       # Double brace substitution, expand bar in {{foo{{bar}}}}
+       $i = 0;
+       while(preg_match("/{{([$titleChars]*?)}}/", $matches[2], $internalmatches) and $i < 30) {
+               $text = wfInternalBraceSubstitution( $internalmatches[1] );
+               $matches[0] = str_replace($internalmatches[0], $text , $matches[0]);
+               $matches[2] = str_replace($internalmatches[0], $text , $matches[2]);
+               $i++;
+       }
+
        return $wgCurParser->braceSubstitution( $matches );
 }
 
@@ -2080,4 +2116,135 @@ function wfArgSubstitution( $matches )
        return $wgCurParser->argSubstitution( $matches );
 }
 
+# XXX: i don't think this is the most elegant way to do it..
+function wfInternalBraceSubstitution( $part1 ) {
+       global $wgLinkCache, $wgLang, $wgCurParser;
+       $fname = "wfInternalBraceSubstitution";
+       $found = false;
+       $nowiki = false;
+       $noparse = false;
+
+       $title = NULL;
+
+       # $newline is an optional newline character before the braces
+       # $part1 is the bit before the first |, and must contain only title characters
+       # $args is a list of arguments, starting from index 0, not including $part1
+
+       # SUBST
+       if ( !$found ) {
+               $mwSubst =& MagicWord::get( MAG_SUBST );
+               if ( $mwSubst->matchStartAndRemove( $part1 ) ) {
+                       if ( $wgCurParser->mOutputType != OT_WIKI ) {
+                               # Invalid SUBST not replaced at PST time
+                               # Return without further processing
+                               $text = $matches[0];
+                               $found = true;
+                               $noparse= true;
+                       }
+               } elseif ( $wgCurParser->mOutputType == OT_WIKI ) {
+                       # SUBST not found in PST pass, do nothing
+                       $text = $matches[0];
+                       $found = true;
+               }
+       }
+
+       # MSG, MSGNW and INT
+       if ( !$found ) {
+               # Check for MSGNW:
+               $mwMsgnw =& MagicWord::get( MAG_MSGNW );
+               if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
+                       $nowiki = true;
+               } else {
+                       # Remove obsolete MSG:
+                       $mwMsg =& MagicWord::get( MAG_MSG );
+                       $mwMsg->matchStartAndRemove( $part1 );
+               }
+
+               # Check if it is an internal message
+               $mwInt =& MagicWord::get( MAG_INT );
+               if ( $mwInt->matchStartAndRemove( $part1 ) ) {
+                       if ( $wgCurParser->incrementIncludeCount( "int:$part1" ) ) {
+                               $text = wfMsgReal( $part1, array(), true );
+                               $found = true;
+                       }
+               }
+       }
+
+       # NS
+       if ( !$found ) {
+               # Check for NS: (namespace expansion)
+               $mwNs = MagicWord::get( MAG_NS );
+               if ( $mwNs->matchStartAndRemove( $part1 ) ) {
+                       if ( intval( $part1 ) ) {
+                               $text = $wgLang->getNsText( intval( $part1 ) );
+                               $found = true;
+                       } else {
+                               $index = Namespace::getCanonicalIndex( strtolower( $part1 ) );
+                               if ( !is_null( $index ) ) {
+                                       $text = $wgLang->getNsText( $index );
+                                       $found = true;
+                               }
+                       }
+               }
+       }
+
+       # LOCALURL and LOCALURLE
+       if ( !$found ) {
+               $mwLocal = MagicWord::get( MAG_LOCALURL );
+               $mwLocalE = MagicWord::get( MAG_LOCALURLE );
+
+               if ( $mwLocal->matchStartAndRemove( $part1 ) ) {
+                       $func = 'getLocalURL';
+               } elseif ( $mwLocalE->matchStartAndRemove( $part1 ) ) {
+                       $func = 'escapeLocalURL';
+               } else {
+                       $func = '';
+               }
+
+               if ( $func !== '' ) {
+                       $title = Title::newFromText( $part1 );
+                       if ( !is_null( $title ) ) {
+                               $text = $title->$func();
+                               $found = true;
+                       }
+               }
+       }
+
+       # Internal variables
+       if ( !$found && array_key_exists( $part1, $wgCurParser->mVariables ) ) {
+               $text = $wgCurParser->mVariables[$part1];
+               $found = true;
+               $wgCurParser->mOutput->mContainsOldMagic = true;
+       }
+
+       # Load from database
+       if ( !$found ) {
+               $title = Title::newFromText( $part1, NS_TEMPLATE );
+               if ( !is_null( $title ) && !$title->isExternal() ) {
+                       # Check for excessive inclusion
+                       $dbk = $title->getPrefixedDBkey();
+                       if ( $wgCurParser->incrementIncludeCount( $dbk ) ) {
+                               $article = new Article( $title );
+                               $articleContent = $article->getContentWithoutUsingSoManyDamnGlobals();
+                               if ( $articleContent !== false ) {
+                                       $found = true;
+                                       $text = $articleContent;
+
+                               }
+                       }
+
+                       # If the title is valid but undisplayable, make a link to it
+                       if ( $wgCurParser->mOutputType == OT_HTML && !$found ) {
+                               $text = "[[" . $title->getPrefixedText() . "]]";
+                               $found = true;
+                       }
+               }
+       }
+
+       if ( !$found ) {
+               return $matches[0];
+       } else {
+               return $text;
+       }
+}
 ?>