* Fix regression(?) in behavior of initial-whitespace-pre in <center>
[lhc/web/wiklou.git] / includes / Parser.php
index bd58a3c..60aaaed 100644 (file)
@@ -47,11 +47,12 @@ define( 'STRIP_COMMENTS', 'HTMLCommentStrip' );
 define( 'HTTP_PROTOCOLS', 'http:\/\/|https:\/\/' );
 # Everything except bracket, space, or control characters
 define( 'EXT_LINK_URL_CLASS', '[^][<>"\\x00-\\x20\\x7F]' );
-# Including space
-define( 'EXT_LINK_TEXT_CLASS', '[^\]\\x00-\\x1F\\x7F]' );
+# Including space, but excluding newlines
+define( 'EXT_LINK_TEXT_CLASS', '[^\]\\x0a\\x0d]' );
 define( 'EXT_IMAGE_FNAME_CLASS', '[A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]' );
 define( 'EXT_IMAGE_EXTENSIONS', 'gif|png|jpg|jpeg' );
-define( 'EXT_LINK_BRACKETED',  '/\[(\b(' . wfUrlProtocols() . ')'.EXT_LINK_URL_CLASS.'+) *('.EXT_LINK_TEXT_CLASS.'*?)\]/S' );
+define( 'EXT_LINK_BRACKETED',  '/\[(\b(' . wfUrlProtocols() . ')'.
+       EXT_LINK_URL_CLASS.'+) *('.EXT_LINK_TEXT_CLASS.'*?)\]/S' );
 define( 'EXT_IMAGE_REGEX',
        '/^('.HTTP_PROTOCOLS.')'.  # Protocol
        '('.EXT_LINK_URL_CLASS.'+)\\/'.  # Hostname and path
@@ -132,6 +133,7 @@ class Parser
                $this->mTagHooks = array();
                $this->mFunctionHooks = array();
                $this->clearState();
+               $this->setHook( 'pre', array( $this, 'renderPreTag' ) );
        }
 
        /**
@@ -247,7 +249,6 @@ class Parser
                        '/(.) (?=\\?|:|;|!|\\302\\273)/' => '\\1&nbsp;\\2',
                        # french spaces, Guillemet-right
                        '/(\\302\\253) /' => '\\1&nbsp;',
-                       '/<center *>(.*)<\\/center *>/i' => '<div class="center">\\1</div>',
                );
                $text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
 
@@ -422,7 +423,7 @@ class Parser
                $commentState = array();
                
                $elements = array_merge(
-                       array( 'nowiki', 'pre', 'gallery' ),
+                       array( 'nowiki', 'gallery' ),
                        array_keys( $this->mTagHooks ) );
                global $wgRawHtml;
                if( $wgRawHtml ) {
@@ -463,11 +464,6 @@ class Parser
                                case 'math':
                                        $output = MathRenderer::renderMath( $content );
                                        break;
-                               case 'pre':
-                                       // Backwards-compatibility hack
-                                       $content = preg_replace( '!<nowiki>(.*?)</nowiki>!is', '\\1', $content );
-                                       $output = '<pre>' . wfEscapeHTMLTagsOnly( $content ) . '</pre>';
-                                       break;
                                case 'gallery':
                                        $output = $this->renderImageGallery( $content );
                                        break;
@@ -476,7 +472,7 @@ class Parser
                                                $output = call_user_func_array( $this->mTagHooks[$tagName],
                                                        array( $content, $params, $this ) );
                                        } else {
-                                               wfDebugDieBacktrace( "Invalid call hook $element" );
+                                               throw new MWException( "Invalid call hook $element" );
                                        }
                                }
                        } else {
@@ -1334,7 +1330,7 @@ class Parser
                $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
 
                if( is_null( $this->mTitle ) ) {
-                       wfDebugDieBacktrace( 'nooo' );
+                       throw new MWException( 'nooo' );
                }
                $nottalk = !$this->mTitle->isTalkPage();
 
@@ -1895,10 +1891,10 @@ class Parser
                                wfProfileIn( "$fname-paragraph" );
                                # No prefix (not in list)--go to paragraph mode
                                // XXX: use a stack for nestable elements like span, table and div
-                               $openmatch = preg_match('/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+                               $openmatch = preg_match('/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/center|<\\/tr|<\\/td|<\\/th)/iS', $t );
                                $closematch = preg_match(
                                        '/(<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
-                                       '<td|<th|<div|<\\/div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol)/iS', $t );
+                                       '<td|<th|<div|<\\/div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<center)/iS', $t );
                                if ( $openmatch or $closematch ) {
                                        $paragraphStack = false;
                                        # TODO bug 5718: paragraph closed
@@ -2124,7 +2120,7 @@ class Parser
                                }
                                break;
                        default:
-                               wfDebugDieBacktrace( "State machine error in $fname" );
+                               throw new MWException( "State machine error in $fname" );
                        }
                }
                if( $stack > 0 ) {
@@ -2253,6 +2249,9 @@ class Parser
                                return $wgScriptPath;
                        case MAG_DIRECTIONMARK:
                                return $wgContLang->getDirMark();
+                       case MAG_CONTENTLANGUAGE:
+                               global $wgContLanguageCode;
+                               return $wgContLanguageCode;
                        default:
                                $ret = null;
                                if ( wfRunHooks( 'ParserGetVariableValueSwitch', array( &$this, &$varCache, &$index, &$ret ) ) )
@@ -2748,8 +2747,9 @@ class Parser
                if ( !$found && $argc >= 2 ) {
                        $mwPluralForm =& MagicWord::get( MAG_PLURAL );
                        if ( $mwPluralForm->matchStartAndRemove( $part1 ) ) {
-                               if ($argc==2) {$args[2]=$args[1];}
-                               $text = $linestart . $lang->convertPlural( $part1, $args[0], $args[1], $args[2]);
+                               while ( count($args) < 5 ) { $args[] = $args[count($args)-1]; }
+                               $text = $linestart . $lang->convertPlural( $part1, $args[0], $args[1],
+                                       $args[2], $args[3], $args[4]);
                                $found = true;
                        }
                }
@@ -4031,6 +4031,19 @@ class Parser
                return $matches[0];
        }
 
+       /**
+        * Tag hook handler for 'pre'.
+        */
+       function renderPreTag( $text, $attribs, $parser ) {
+               // Backwards-compatibility hack
+               $content = preg_replace( '!<nowiki>(.*?)</nowiki>!is', '\\1', $text );
+               
+               $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' );
+               return wfOpenElement( 'pre', $attribs ) .
+                       wfEscapeHTMLTagsOnly( $content ) .
+                       '</pre>';
+       }
+       
        /**
         * Renders an image gallery from a text with one line per image.
         * text labels may be given by using |-style alternative text. E.g.