(bug 22784) Fix normalization of whitespace in autocomment links
[lhc/web/wiklou.git] / includes / parser / Parser.php
index 298aa3d..2a68198 100644 (file)
  * (which in turn the browser understands, and can display).
  *
  * <pre>
- * There are six main entry points into the Parser class:
+ * There are five main entry points into the Parser class:
  * parse()
- *   produces HTML output
+ *     produces HTML output
  * preSaveTransform().
- *   produces altered wiki markup.
+ *     produces altered wiki markup.
  * preprocess()
- *   removes HTML comments and expands templates
+ *     removes HTML comments and expands templates
  * cleanSig()
- *   Cleans a signature before saving it to preferences
+ *     Cleans a signature before saving it to preferences
  * extractSections()
- *   Extracts sections from an article for section editing
- * getTransclusionText()
- *   Extracts the text of a template with only <includeonly>, etc., parsed
+ *     Extracts sections from an article for section editing
+ * getPreloadText()
+ *     Removes <noinclude> sections, and <includeonly> tags.
  *
  * Globals used:
  *    objects:   $wgLang, $wgContLang
@@ -45,8 +45,7 @@
  *
  * @ingroup Parser
  */
-class Parser
-{
+class Parser {
        /**
         * Update this version number when the ParserOutput format
         * changes in an incompatible way, so the parser cache
@@ -65,7 +64,7 @@ class Parser
        const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)([^][<>"\\x00-\\x20\\x7F]+)
                \\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sx';
 
-       // State constants for the definition list colon extraction
+       # State constants for the definition list colon extraction
        const COLON_STATE_TEXT = 0;
        const COLON_STATE_TAG = 1;
        const COLON_STATE_TAGSTART = 2;
@@ -75,28 +74,25 @@ class Parser
        const COLON_STATE_COMMENTDASH = 6;
        const COLON_STATE_COMMENTDASHDASH = 7;
 
-       // Flags for preprocessToDom
+       # Flags for preprocessToDom
        const PTD_FOR_INCLUSION = 1;
 
-       // Allowed values for $this->mOutputType
-       // Parameter to startExternalParse().
-       const OT_HTML = 1;
-       const OT_WIKI = 2;
-       const OT_PREPROCESS = 3;
+       # Allowed values for $this->mOutputType
+       # Parameter to startExternalParse().
+       const OT_HTML = 1; # like parse()
+       const OT_WIKI = 2; # like preSaveTransform()
+       const OT_PREPROCESS = 3; # like preprocess()
        const OT_MSG = 3;
-       const OT_INCLUDES = 4;
+       const OT_PLAIN = 4; # like extractSections() - portions of the original are returned unchanged.
 
-       // Marker Suffix needs to be accessible staticly.
+       # Marker Suffix needs to be accessible staticly.
        const MARKER_SUFFIX = "-QINU\x7f";
 
-       /**#@+
-        * @private
-        */
        # Persistent:
-       var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables,
-               $mSubstWords, $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex,
-               $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList,
-               $mVarCache, $mConf, $mFunctionTagHooks;
+       var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables;
+       var $mSubstWords, $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex;
+       var $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList;
+       var $mVarCache, $mConf, $mFunctionTagHooks;
 
 
        # Cleared with clearState():
@@ -104,21 +100,19 @@ class Parser
        var $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
        var $mLinkHolders, $mLinkID;
        var $mIncludeSizes, $mPPNodeCount, $mDefaultSort;
-       var $mTplExpandCache; // empty-frame expansion cache
+       var $mTplExpandCache; # empty-frame expansion cache
        var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
-       var $mExpensiveFunctionCount; // number of expensive parser function calls
+       var $mExpensiveFunctionCount; # number of expensive parser function calls
 
        # Temporary
        # These are variables reset at least once per parse regardless of $clearState
-       var $mOptions,      // ParserOptions object
-               $mTitle,        // Title context, used for self-link rendering and similar things
-               $mOutputType,   // Output type, one of the OT_xxx constants
-               $ot,            // Shortcut alias, see setOutputType()
-               $mRevisionId,   // ID to display in {{REVISIONID}} tags
-               $mRevisionTimestamp, // The timestamp of the specified revision ID
-               $mRevIdForTs;   // The revision ID which was used to fetch the timestamp
-
-       /**#@-*/
+       var $mOptions;      # ParserOptions object
+       var $mTitle;        # Title context, used for self-link rendering and similar things
+       var $mOutputType;   # Output type, one of the OT_xxx constants
+       var $ot;            # Shortcut alias, see setOutputType()
+       var $mRevisionId;   # ID to display in {{REVISIONID}} tags
+       var $mRevisionTimestamp; # The timestamp of the specified revision ID
+       var $mRevIdForTs;   # The revision ID which was used to fetch the timestamp
 
        /**
         * Constructor
@@ -135,12 +129,12 @@ class Parser
                $this->mDefaultStripList = $this->mStripList = array();
                $this->mUrlProtocols = wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'.
-                       '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x0a\\x0d]*?)\]/S';
+                       '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/S';
                $this->mVarCache = array();
                if ( isset( $conf['preprocessorClass'] ) ) {
                        $this->mPreprocessorClass = $conf['preprocessorClass'];
                } elseif ( extension_loaded( 'domxml' ) ) {
-                       // PECL extension that conflicts with the core DOM extension (bug 13770)
+                       # PECL extension that conflicts with the core DOM extension (bug 13770)
                        wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" );
                        $this->mPreprocessorClass = 'Preprocessor_Hash';
                } elseif ( extension_loaded( 'dom' ) ) {
@@ -216,7 +210,7 @@ class Parser
                 * Must not consist of all title characters, or else it will change
                 * the behaviour of <nowiki> in a link.
                 */
-               #$this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();
+               # $this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();
                # Changed to \x7f to allow XML double-parsing -- TS
                $this->mUniqPrefix = "\x7fUNIQ" . self::getRandomString();
 
@@ -245,51 +239,6 @@ class Parser
                wfProfileOut( __METHOD__ );
        }
 
-       function setOutputType( $ot ) {
-               $this->mOutputType = $ot;
-               // Shortcut alias
-               $this->ot = array(
-                       'html' => $ot == self::OT_HTML,
-                       'wiki' => $ot == self::OT_WIKI,
-                       'pre' => $ot == self::OT_PREPROCESS,
-               );
-       }
-
-       /**
-        * Set the context title
-        */
-       function setTitle( $t ) {
-               if ( !$t || $t instanceof FakeTitle ) {
-                       $t = Title::newFromText( 'NO TITLE' );
-               }
-
-               if ( strval( $t->getFragment() ) !== '' ) {
-                       # Strip the fragment to avoid various odd effects
-                       $this->mTitle = clone $t;
-                       $this->mTitle->setFragment( '' );
-               } else {
-                       $this->mTitle = $t;
-               }
-       }
-
-       /**
-        * Accessor for mUniqPrefix.
-        *
-        * @public
-        */
-       function uniqPrefix() {
-               if( !isset( $this->mUniqPrefix ) ) {
-                       // @todo Fixme: this is probably *horribly wrong*
-                       // LanguageConverter seems to want $wgParser's uniqPrefix, however
-                       // if this is called for a parser cache hit, the parser may not
-                       // have ever been initialized in the first place.
-                       // Not really sure what the heck is supposed to be going on here.
-                       return '';
-                       //throw new MWException( "Accessing uninitialized mUniqPrefix" );
-               }
-               return $this->mUniqPrefix;
-       }
-
        /**
         * Convert wikitext to HTML
         * Do not call this function recursively.
@@ -308,7 +257,7 @@ class Parser
                 * to internalParse() which does all the real work.
                 */
 
-               global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang, $wgDisableLangConversion;
+               global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang, $wgDisableLangConversion, $wgDisableTitleConversion;
                $fname = __METHOD__.'-' . wfGetCaller();
                wfProfileIn( __METHOD__ );
                wfProfileIn( $fname );
@@ -318,11 +267,11 @@ class Parser
                }
 
                $this->mOptions = $options;
-               $this->setTitle( $title ); // Page title has to be set for the pre-processor
+               $this->setTitle( $title ); # Page title has to be set for the pre-processor
 
                $oldRevisionId = $this->mRevisionId;
                $oldRevisionTimestamp = $this->mRevisionTimestamp;
-               if( $revid !== null ) {
+               if ( $revid !== null ) {
                        $this->mRevisionId = $revid;
                        $this->mRevisionTimestamp = null;
                }
@@ -338,62 +287,84 @@ class Parser
                $fixtags = array(
                        # french spaces, last one Guillemet-left
                        # only if there is something before the space
-                       '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => '\\1&nbsp;\\2',
+                       '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => '\\1&#160;\\2',
                        # french spaces, Guillemet-right
-                       '/(\\302\\253) /' => '\\1&nbsp;',
-                       '/&nbsp;(!\s*important)/' => ' \\1', #Beware of CSS magic word !important, bug #11874.
+                       '/(\\302\\253) /' => '\\1&#160;',
+                       '/&#160;(!\s*important)/' => ' \\1', # Beware of CSS magic word !important, bug #11874.
                );
-               $text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
+               $text = preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text );
 
                $text = $this->doBlockLevels( $text, $linestart );
 
                $this->replaceLinkHolders( $text );
 
-               // The position of the convert() call should not be changed. it
-               // assumes that the links are all replaced and the only thing left
-               // is the <nowiki> mark.
+               /**
+                * The page doesn't get language converted if
+                * a) It's disabled
+                * b) Content isn't converted
+                * c) It's a conversion table
+                */
                if ( !( $wgDisableLangConversion
                                || isset( $this->mDoubleUnderscores['nocontentconvert'] )
-                               || $this->mTitle->isTalkPage()
                                || $this->mTitle->isConversionTable() ) ) {
+
+                       # The position of the convert() call should not be changed. it
+                       # assumes that the links are all replaced and the only thing left
+                       # is the <nowiki> mark.
+
                        $text = $wgContLang->convert( $text );
                }
 
-               // A title may have been set in a conversion rule.
-               // Note that if a user tries to set a title in a conversion
-               // rule but content conversion was not done, then the parser
-               // won't pick it up.  This is probably expected behavior.
-               if ( $wgContLang->getConvRuleTitle() ) {
-                       $this->mOutput->setTitleText( $wgContLang->getConvRuleTitle() );
+               /**
+                * A page get its title converted except:
+                * a) Language conversion is globally disabled
+                * b) Title convert is globally disabled
+                * c) The page is a redirect page
+                * d) User request with a "linkconvert" set to "no"
+                * e) A "nocontentconvert" magic word has been set
+                * f) A "notitleconvert" magic word has been set
+                * g) User sets "noconvertlink" in his/her preference
+                *
+                * Note that if a user tries to set a title in a conversion
+                * rule but content conversion was not done, then the parser
+                * won't pick it up.  This is probably expected behavior.
+                */
+               if ( !( $wgDisableLangConversion
+                               || $wgDisableTitleConversion
+                               || isset( $this->mDoubleUnderscores['nocontentconvert'] )
+                               || isset( $this->mDoubleUnderscores['notitleconvert'] )
+                               || $this->mOutput->getDisplayTitle() !== false ) ) 
+               {
+                       $convruletitle = $wgContLang->getConvRuleTitle();
+                       if ( $convruletitle ) {
+                               $this->mOutput->setTitleText( $convruletitle );
+                       } else {
+                               $titleText = $wgContLang->convertTitle( $title );
+                               $this->mOutput->setTitleText( $titleText );
+                       }
                }
 
                $text = $this->mStripState->unstripNoWiki( $text );
 
                wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) );
 
-               if ( $this->mTransparentTagHooks ) {
-                       //!JF Move to its own function
-                       $uniq_prefix = $this->mUniqPrefix;
-                       $matches = array();
-                       $elements = array_keys( $this->mTransparentTagHooks );
-                       $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
-
-                       foreach( $matches as $marker => $data ) {
-                               list( $element, $content, $params, $tag ) = $data;
-                               $tagName = strtolower( $element );
-                               if( isset( $this->mTransparentTagHooks[$tagName] ) ) {
-                                       $output = call_user_func_array( $this->mTransparentTagHooks[$tagName],
-                                               array( $content, $params, $this ) );
-                               } else {
-                                       $output = $tag;
-                               }
-                               $this->mStripState->general->setPair( $marker, $output );
+//!JF Move to its own function
+
+               $uniq_prefix = $this->mUniqPrefix;
+               $matches = array();
+               $elements = array_keys( $this->mTransparentTagHooks );
+               $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
+
+               foreach ( $matches as $marker => $data ) {
+                       list( $element, $content, $params, $tag ) = $data;
+                       $tagName = strtolower( $element );
+                       if ( isset( $this->mTransparentTagHooks[$tagName] ) ) {
+                               $output = call_user_func_array( $this->mTransparentTagHooks[$tagName], array( $content, $params, $this ) );
+                       } else {
+                               $output = $tag;
                        }
+                       $this->mStripState->general->setPair( $marker, $output );
                }
-
-               # This was originally inserted for transparent tag hooks (now deprecated)
-               # but some extensions (notably <poem>) rely on the extra unstripGeneral()
-               # after unstripNoWiki() so they can modify the contents of <nowiki> tags.
                $text = $this->mStripState->unstripGeneral( $text );
 
                $text = Sanitizer::normalizeCharReferences( $text );
@@ -436,7 +407,6 @@ class Parser
 
                # Information on include size limits, for the benefit of users who try to skirt them
                if ( $this->mOptions->getEnableLimitReport() ) {
-                       global $wgExpensiveParserFunctionLimit;
                        $max = $this->mOptions->getMaxIncludeSize();
                        $PFreport = "Expensive parser function count: {$this->mExpensiveFunctionCount}/$wgExpensiveParserFunctionLimit\n";
                        $limitReport =
@@ -465,7 +435,7 @@ class Parser
         * If $frame is not provided, then template variables (e.g., {{{1}}}) within $text are not expanded
         *
         * @param $text String: text extension wants to have parsed
-        * @param PPFrame $frame: The frame to use for expanding any template variables
+        * @param $frame PPFrame: The frame to use for expanding any template variables
         */
        function recursiveTagParse( $text, $frame=false ) {
                wfProfileIn( __METHOD__ );
@@ -486,7 +456,7 @@ class Parser
                $this->setOutputType( self::OT_PREPROCESS );
                $this->mOptions = $options;
                $this->setTitle( $title );
-               if( $revid !== null ) {
+               if ( $revid !== null ) {
                        $this->mRevisionId = $revid;
                }
                wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
@@ -498,23 +468,21 @@ class Parser
        }
 
        /**
-        * Get the wikitext of a page as though it was transcluded.
-        *
-        * Specifically <includeonly> etc. are parsed, redirects are followed, comments
-        * are removed, but templates arguments and parser functions are untouched.
+        * Process the wikitext for the ?preload= feature. (bug 5210)
         *
-        * This is not called by the parser itself, see braceSubstitution for its transclusion. 
+        * <noinclude>, <includeonly> etc. are parsed as for template transclusion,
+        * comments, templates, arguments, tags hooks and parser functions are untouched.
         */
-       public function getTransclusionText( $title, $options ) {
-               // Must initialize first
+       public function getPreloadText( $text, $title, $options ) {
+               # Parser (re)initialisation
                $this->clearState();
-               $this->setOutputType( self::OT_INCLUDES );
+               $this->setOutputType( self::OT_PLAIN );
                $this->mOptions = $options;
-               $this->setTitle( new FakeTitle ); 
+               $this->setTitle( $title );
 
-               list( $text, $title ) = $this->getTemplateDom( $title );
                $flags = PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES;
-               return $this->getPreprocessor()->newFrame()->expand( $text, $flags );
+               $dom = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION );
+               return $this->getPreprocessor()->newFrame()->expand( $dom, $flags );
        }
 
        /**
@@ -524,14 +492,120 @@ class Parser
         * @static
         */
        function getRandomString() {
-               return dechex(mt_rand(0, 0x7fffffff)) . dechex(mt_rand(0, 0x7fffffff));
+               return dechex( mt_rand( 0, 0x7fffffff ) ) . dechex( mt_rand( 0, 0x7fffffff ) );
+       }
+
+       /**
+        * Accessor for mUniqPrefix.
+        *
+        * @return String
+        */
+       public function uniqPrefix() {
+               if ( !isset( $this->mUniqPrefix ) ) {
+                       # @todo Fixme: this is probably *horribly wrong*
+                       # LanguageConverter seems to want $wgParser's uniqPrefix, however
+                       # if this is called for a parser cache hit, the parser may not
+                       # have ever been initialized in the first place.
+                       # Not really sure what the heck is supposed to be going on here.
+                       return '';
+                       # throw new MWException( "Accessing uninitialized mUniqPrefix" );
+               }
+               return $this->mUniqPrefix;
+       }
+
+       /**
+        * Set the context title
+        */
+       function setTitle( $t ) {
+               if ( !$t || $t instanceof FakeTitle ) {
+                       $t = Title::newFromText( 'NO TITLE' );
+               }
+
+               if ( strval( $t->getFragment() ) !== '' ) {
+                       # Strip the fragment to avoid various odd effects
+                       $this->mTitle = clone $t;
+                       $this->mTitle->setFragment( '' );
+               } else {
+                       $this->mTitle = $t;
+               }
        }
 
-       function &getTitle() { return $this->mTitle; }
-       function getOptions() { return $this->mOptions; }
-       function getRevisionId() { return $this->mRevisionId; }
-       function getOutput() { return $this->mOutput; }
-       function nextLinkID() { return $this->mLinkID++; }
+       /**
+        * Accessor for the Title object
+        *
+        * @return Title object
+        */
+       function &getTitle() {
+               return $this->mTitle;
+       }
+
+       /**
+        * Accessor/mutator for the Title object
+        *
+        * @param $x New Title object or null to just get the current one
+        * @return Title object
+        */
+       function Title( $x = null ) {
+               return wfSetVar( $this->mTitle, $x );
+       }
+
+       /**
+        * Set the output type
+        *
+        * @param $ot Integer: new value
+        */
+       function setOutputType( $ot ) {
+               $this->mOutputType = $ot;
+               # Shortcut alias
+               $this->ot = array(
+                       'html' => $ot == self::OT_HTML,
+                       'wiki' => $ot == self::OT_WIKI,
+                       'pre' => $ot == self::OT_PREPROCESS,
+                       'plain' => $ot == self::OT_PLAIN,
+               );
+       }
+
+       /**
+        * Accessor/mutator for the output type
+        *
+        * @param $x New value or null to just get the current one
+        * @return Integer
+        */
+       function OutputType( $x = null ) {
+               return wfSetVar( $this->mOutputType, $x );
+       }
+
+       /**
+        * Get the ParserOutput object
+        *
+        * @return ParserOutput object
+        */
+       function getOutput() {
+               return $this->mOutput;
+       }
+
+       /**
+        * Get the ParserOptions object
+        *
+        * @return ParserOptions object
+        */
+       function getOptions() {
+               return $this->mOptions;
+       }
+
+       /**
+        * Accessor/mutator for the ParserOptions object
+        *
+        * @param $x New value or null to just get the current one
+        * @return Current ParserOptions object
+        */
+       function Options( $x = null ) {
+               return wfSetVar( $this->mOptions, $x );
+       }
+
+       function nextLinkID() {
+               return $this->mLinkID++;
+       }
 
        function getFunctionLang() {
                global $wgLang, $wgContLang;
@@ -546,6 +620,8 @@ class Parser
 
        /**
         * Get a preprocessor object
+        *
+        * @return Preprocessor instance
         */
        function getPreprocessor() {
                if ( !isset( $this->mPreprocessor ) ) {
@@ -568,12 +644,13 @@ class Parser
         *
         * @param $elements list of element names. Comments are always extracted.
         * @param $text Source text string.
+        * @param $matches Out parameter, Array: extarcted tags
         * @param $uniq_prefix
+        * @return String: stripped text
         *
-        * @public
         * @static
         */
-       function extractTagsAndParams($elements, $text, &$matches, $uniq_prefix = ''){
+       public function extractTagsAndParams( $elements, $text, &$matches, $uniq_prefix = '' ) {
                static $n = 1;
                $stripped = '';
                $matches = array();
@@ -584,40 +661,40 @@ class Parser
                while ( $text != '' ) {
                        $p = preg_split( $start, $text, 2, PREG_SPLIT_DELIM_CAPTURE );
                        $stripped .= $p[0];
-                       if( count( $p ) < 5 ) {
+                       if ( count( $p ) < 5 ) {
                                break;
                        }
-                       if( count( $p ) > 5 ) {
-                               // comment
+                       if ( count( $p ) > 5 ) {
+                               # comment
                                $element    = $p[4];
                                $attributes = '';
                                $close      = '';
                                $inside     = $p[5];
                        } else {
-                               // tag
+                               # tag
                                $element    = $p[1];
                                $attributes = $p[2];
                                $close      = $p[3];
                                $inside     = $p[4];
                        }
 
-                       $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . self::MARKER_SUFFIX;
+                       $marker = "$uniq_prefix-$element-" . sprintf( '%08X', $n++ ) . self::MARKER_SUFFIX;
                        $stripped .= $marker;
 
                        if ( $close === '/>' ) {
-                               // Empty element tag, <tag />
+                               # Empty element tag, <tag />
                                $content = null;
                                $text = $inside;
                                $tail = null;
                        } else {
-                               if( $element === '!--' ) {
+                               if ( $element === '!--' ) {
                                        $end = '/(-->)/';
                                } else {
                                        $end = "/(<\\/$element\\s*>)/i";
                                }
                                $q = preg_split( $end, $inside, 2, PREG_SPLIT_DELIM_CAPTURE );
                                $content = $q[0];
-                               if( count( $q ) < 3 ) {
+                               if ( count( $q ) < 3 ) {
                                        # No end tag -- let it run out to the end of the text.
                                        $tail = '';
                                        $text = '';
@@ -645,7 +722,7 @@ class Parser
        /**
         * @deprecated use replaceVariables
         */
-       function strip( $text, $state, $stripcomments = false , $dontstrip = array () ) {
+       function strip( $text, $state, $stripcomments = false , $dontstrip = array() ) {
                return $text;
        }
 
@@ -705,191 +782,237 @@ class Parser
         *
         * @private
         */
-       function doTableStuff ( $text ) {
+       function doTableStuff( $text ) {
                wfProfileIn( __METHOD__ );
-
+               
                $lines = StringUtils::explode( "\n", $text );
+               $text = null;
                $out = '';
-               $td_history = array (); // Is currently a td tag open?
-               $last_tag_history = array (); // Save history of last lag activated (td, th or caption)
-               $tr_history = array (); // Is currently a tr tag open?
-               $tr_attributes = array (); // history of tr attributes
-               $has_opened_tr = array(); // Did this table open a <tr> element?
-               $indent_level = 0; // indent level of the table
+               $td_history = array(); # Is currently a td tag open?
+               $last_tag_history = array(); # Save history of last lag activated (td, th or caption)
+               $tr_history = array(); # Is currently a tr tag open?
+               $tr_attributes = array(); # history of tr attributes
+               $has_opened_tr = array(); # Did this table open a <tr> element?
+               $indent_level = 0; # indent level of the table
+
+               $table_tag = 'table';
+               $tr_tag = 'tr';
+               $th_tag = 'th';
+               $td_tag = 'td';
+               $caption_tag = 'caption';
+
+               $extra_table_attribs = null;
+               $extra_tr_attribs = null;
+               $extra_td_attribs = null;
+
+               $convert_style = false;
 
                foreach ( $lines as $outLine ) {
                        $line = trim( $outLine );
 
-                       if( $line == '' ) { // empty line, go to next line
+                       if ( $line === '' ) { # empty line, go to next line                     
                                $out .= $outLine."\n";
                                continue;
                        }
+
                        $first_character = $line[0];
                        $matches = array();
 
                        if ( preg_match( '/^(:*)\{\|(.*)$/', $line , $matches ) ) {
-                               // First check if we are starting a new table
+                               # First check if we are starting a new table
                                $indent_level = strlen( $matches[1] );
 
                                $attributes = $this->mStripState->unstripBoth( $matches[2] );
-                               $attributes = Sanitizer::fixTagAttributes ( $attributes , 'table' );
 
-                               $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
+                               $attr = Sanitizer::decodeTagAttributes( $attributes );
+
+                               $mode = @$attr['mode'];
+                               if ( !$mode ) $mode = 'data';
+
+                               if ( $mode == 'grid' || $mode == 'layout' ) {
+                                       $table_tag = 'div';
+                                       $tr_tag = 'div';
+                                       $th_tag = 'div';
+                                       $td_tag = 'div';
+                                       $caption_tag = 'div';
+
+                                       $extra_table_attribs = array( 'class' => 'grid-table' );
+                                       $extra_tr_attribs = array( 'class' => 'grid-row' );
+                                       $extra_td_attribs = array( 'class' => 'grid-cell' );
+
+                                       $convert_style = true;
+                               } 
+
+                               if ($convert_style) $attr['style'] = Sanitizer::styleFromAttributes( $attr );
+                               $attr = Sanitizer::validateTagAttributes( $attr, $table_tag );
+                               $attributes = Sanitizer::collapseTagAttributes( $attr, $extra_table_attribs );
+
+                               $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<$table_tag{$attributes}>";
                                array_push( $td_history , false );
                                array_push( $last_tag_history , '' );
                                array_push( $tr_history , false );
                                array_push( $tr_attributes , '' );
                                array_push( $has_opened_tr , false );
-                       } else if ( count ( $td_history ) == 0 ) {
-                               // Don't do any of the following
+                       } elseif ( count( $td_history ) == 0 ) {
+                               # Don't do any of the following
                                $out .= $outLine."\n";
                                continue;
-                       } else if ( substr ( $line , 0 , 2 ) === '|}' ) {
-                               // We are ending a table
-                               $line = '</table>' . substr ( $line , 2 );
-                               $last_tag = array_pop ( $last_tag_history );
+                       } elseif ( substr( $line , 0 , 2 ) === '|}' ) {
+                               # We are ending a table
+                               $line = "</$table_tag>" . substr( $line , 2 );
+                               $last_tag = array_pop( $last_tag_history );
 
-                               if ( !array_pop ( $has_opened_tr ) ) {
-                                       $line = "<tr><td></td></tr>{$line}";
+                               if ( !array_pop( $has_opened_tr ) ) {
+                                       $line = "<$tr_tag><$td_tag></$td_tag></$tr_tag>{$line}";
                                }
 
-                               if ( array_pop ( $tr_history ) ) {
-                                       $line = "</tr>{$line}";
+                               if ( array_pop( $tr_history ) ) {
+                                       $line = "</$tr_tag>{$line}";
                                }
 
-                               if ( array_pop ( $td_history ) ) {
+                               if ( array_pop( $td_history ) ) {
                                        $line = "</{$last_tag}>{$line}";
                                }
-                               array_pop ( $tr_attributes );
+                               array_pop( $tr_attributes );
                                $outLine = $line . str_repeat( '</dd></dl>' , $indent_level );
-                       } else if ( substr ( $line , 0 , 2 ) === '|-' ) {
-                               // Now we have a table row
+                       } elseif ( substr( $line , 0 , 2 ) === '|-' ) {
+                               # Now we have a table row
                                $line = preg_replace( '#^\|-+#', '', $line );
 
-                               // Whats after the tag is now only attributes
+                               # Whats after the tag is now only attributes
                                $attributes = $this->mStripState->unstripBoth( $line );
-                               $attributes = Sanitizer::fixTagAttributes( $attributes, 'tr' );
+
+                               $attr = Sanitizer::decodeTagAttributes( $attributes );
+                               if ($convert_style) $attr['style'] = Sanitizer::styleFromAttributes( $attr );
+                               $attr = Sanitizer::validateTagAttributes( $attr, $tr_tag );
+                               $attributes = Sanitizer::collapseTagAttributes( $attr, $extra_tr_attribs );
+
                                array_pop( $tr_attributes );
                                array_push( $tr_attributes, $attributes );
 
                                $line = '';
-                               $last_tag = array_pop ( $last_tag_history );
-                               array_pop ( $has_opened_tr );
-                               array_push ( $has_opened_tr , true );
+                               $last_tag = array_pop( $last_tag_history );
+                               array_pop( $has_opened_tr );
+                               array_push( $has_opened_tr , true );
 
-                               if ( array_pop ( $tr_history ) ) {
-                                       $line = '</tr>';
+                               if ( array_pop( $tr_history ) ) {
+                                       $line = "</$tr_tag>";
                                }
 
-                               if ( array_pop ( $td_history ) ) {
+                               if ( array_pop( $td_history ) ) {
                                        $line = "</{$last_tag}>{$line}";
                                }
 
                                $outLine = $line;
-                               array_push ( $tr_history , false );
-                               array_push ( $td_history , false );
-                               array_push ( $last_tag_history , '' );
-                       }
-                       else if ( $first_character === '|' || $first_character === '!' || substr ( $line , 0 , 2 )  === '|+' ) {
-                               // This might be cell elements, td, th or captions
-                               if ( substr ( $line , 0 , 2 ) === '|+' ) {
+                               array_push( $tr_history , false );
+                               array_push( $td_history , false );
+                               array_push( $last_tag_history , '' );
+                       } elseif ( $first_character === '|' || $first_character === '!' || substr( $line , 0 , 2 )  === '|+' ) {
+                               # This might be cell elements, td, th or captions
+                               if ( substr( $line , 0 , 2 ) === '|+' ) {
                                        $first_character = '+';
-                                       $line = substr ( $line , 1 );
+                                       $line = substr( $line , 1 );
                                }
 
-                               $line = substr ( $line , 1 );
+                               $line = substr( $line , 1 );
 
                                if ( $first_character === '!' ) {
-                                       $line = str_replace ( '!!' , '||' , $line );
+                                       $line = str_replace( '!!' , '||' , $line );
                                }
 
-                               // Split up multiple cells on the same line.
-                               // FIXME : This can result in improper nesting of tags processed
-                               // by earlier parser steps, but should avoid splitting up eg
-                               // attribute values containing literal "||".
+                               # Split up multiple cells on the same line.
+                               # FIXME : This can result in improper nesting of tags processed
+                               # by earlier parser steps, but should avoid splitting up eg
+                               # attribute values containing literal "||".
                                $cells = StringUtils::explodeMarkup( '||' , $line );
 
                                $outLine = '';
 
-                               // Loop through each table cell
-                               foreach ( $cells as $cell )
-                               {
+                               # Loop through each table cell
+                               foreach ( $cells as $cell ) {
                                        $previous = '';
-                                       if ( $first_character !== '+' )
-                                       {
-                                               $tr_after = array_pop ( $tr_attributes );
-                                               if ( !array_pop ( $tr_history ) ) {
-                                                       $previous = "<tr{$tr_after}>\n";
+                                       if ( $first_character !== '+' ) {
+                                               $tr_after = array_pop( $tr_attributes );
+                                               if ( !array_pop( $tr_history ) ) {
+                                                       $previous = "<$tr_tag{$tr_after}>\n";
                                                }
-                                               array_push ( $tr_history , true );
-                                               array_push ( $tr_attributes , '' );
-                                               array_pop ( $has_opened_tr );
-                                               array_push ( $has_opened_tr , true );
+                                               array_push( $tr_history , true );
+                                               array_push( $tr_attributes , '' );
+                                               array_pop( $has_opened_tr );
+                                               array_push( $has_opened_tr , true );
                                        }
 
-                                       $last_tag = array_pop ( $last_tag_history );
+                                       $last_tag = array_pop( $last_tag_history );
 
-                                       if ( array_pop ( $td_history ) ) {
+                                       if ( array_pop( $td_history ) ) {
                                                $previous = "</{$last_tag}>{$previous}";
                                        }
 
                                        if ( $first_character === '|' ) {
-                                               $last_tag = 'td';
-                                       } else if ( $first_character === '!' ) {
-                                               $last_tag = 'th';
-                                       } else if ( $first_character === '+' ) {
-                                               $last_tag = 'caption';
+                                               $last_tag = $td_tag;
+                                       } elseif ( $first_character === '!' ) {
+                                               $last_tag = $th_tag;
+                                       } elseif ( $first_character === '+' ) {
+                                               $last_tag = $caption_tag;
                                        } else {
                                                $last_tag = '';
                                        }
 
-                                       array_push ( $last_tag_history , $last_tag );
+                                       array_push( $last_tag_history , $last_tag );
 
-                                       // A cell could contain both parameters and data
-                                       $cell_data = explode ( '|' , $cell , 2 );
+                                       # A cell could contain both parameters and data
+                                       $cell_data = explode( '|' , $cell , 2 );
 
-                                       // Bug 553: Note that a '|' inside an invalid link should not
-                                       // be mistaken as delimiting cell parameters
+                                       $attributes = '';
+
+                                       # Bug 553: Note that a '|' inside an invalid link should not
+                                       # be mistaken as delimiting cell parameters
                                        if ( strpos( $cell_data[0], '[[' ) !== false ) {
-                                               $cell = "{$previous}<{$last_tag}>{$cell}";
-                                       } else if ( count ( $cell_data ) == 1 )
-                                               $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
-                                       else {
+                                               if ($extra_td_attribs) $attributes = Sanitizer::collapseTagAttributes( $extra_td_attribs );
+                                               $cell = "{$previous}<{$last_tag}{$attributes}>{$cell}";
+                                       } elseif ( count( $cell_data ) == 1 ) {
+                                               if ($extra_td_attribs) $attributes = Sanitizer::collapseTagAttributes( $extra_td_attribs );
+                                               $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[0]}";
+                                       } else {
                                                $attributes = $this->mStripState->unstripBoth( $cell_data[0] );
-                                               $attributes = Sanitizer::fixTagAttributes( $attributes , $last_tag );
+
+                                               $attr = Sanitizer::decodeTagAttributes( $attributes );
+                                               if ($convert_style) $attr['style'] = Sanitizer::styleFromAttributes( $attr );
+                                               $attr = Sanitizer::validateTagAttributes( $attr, $last_tag );
+                                               $attributes = Sanitizer::collapseTagAttributes( $attr, $extra_td_attribs );
+
                                                $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
                                        }
 
                                        $outLine .= $cell;
-                                       array_push ( $td_history , true );
+                                       array_push( $td_history , true );
                                }
                        }
                        $out .= $outLine . "\n";
                }
 
-               // Closing open td, tr && table
-               while ( count ( $td_history ) > 0 )
-               {
-                       if ( array_pop ( $td_history ) ) {
-                               $out .= "</td>\n";
+               # Closing open td, tr && table
+               while ( count( $td_history ) > 0 ) {
+                       if ( array_pop( $td_history ) ) {
+                               $out .= "</$td_tag>\n";
                        }
-                       if ( array_pop ( $tr_history ) ) {
-                               $out .= "</tr>\n";
+                       if ( array_pop( $tr_history ) ) {
+                               $out .= "</$tr_tag>\n";
                        }
-                       if ( !array_pop ( $has_opened_tr ) ) {
-                               $out .= "<tr><td></td></tr>\n" ;
+                       if ( !array_pop( $has_opened_tr ) ) {
+                               $out .= "<$tr_tag><$td_tag></$td_tag></$tr_tag>\n" ;
                        }
 
-                       $out .= "</table>\n";
+                       $out .= "</$table_tag>\n";
                }
 
-               // Remove trailing line-ending (b/c)
+               # Remove trailing line-ending (b/c)
                if ( substr( $out, -1 ) === "\n" ) {
                        $out = substr( $out, 0, -1 );
                }
 
-               // special case: don't return empty table
-               if( $out === "<table>\n<tr><td></td></tr>\n</table>" ) {
+               # special case: don't return empty table
+               if ( $out === "<$table_tag>\n<$tr_tag><$td_tag></$td_tag></$tr_tag>\n</$table_tag>" ) {
                        $out = '';
                }
 
@@ -915,29 +1038,29 @@ class Parser
                        return $text ;
                }
 
-               // if $frame is provided, then use $frame for replacing any variables
-               if ($frame) {
-                       // use frame depth to infer how include/noinclude tags should be handled
-                       // depth=0 means this is the top-level document; otherwise it's an included document
-                       if( !$frame->depth )
+               # if $frame is provided, then use $frame for replacing any variables
+               if ( $frame ) {
+                       # use frame depth to infer how include/noinclude tags should be handled
+                       # depth=0 means this is the top-level document; otherwise it's an included document
+                       if ( !$frame->depth ) {
                                $flag = 0;
-                       else
+                       } else {
                                $flag = Parser::PTD_FOR_INCLUSION;
+                       }
                        $dom = $this->preprocessToDom( $text, $flag );
                        $text = $frame->expand( $dom );
-               }
-               // if $frame is not provided, then use old-style replaceVariables
-               else {
+               } else {
+                       # if $frame is not provided, then use old-style replaceVariables
                        $text = $this->replaceVariables( $text );
                }
 
                $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ), false, array_keys( $this->mTransparentTagHooks ) );
                wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ) );
 
-               // Tables need to come after variable replacement for things to work
-               // properly; putting them before other transformations should keep
-               // exciting things like link expansions from showing up in surprising
-               // places.
+               # Tables need to come after variable replacement for things to work
+               # properly; putting them before other transformations should keep
+               # exciting things like link expansions from showing up in surprising
+               # places.
                $text = $this->doTableStuff( $text );
 
                $text = preg_replace( '/(^|\n)-----*/', '\\1<hr />', $text );
@@ -945,7 +1068,7 @@ class Parser
                $text = $this->doDoubleUnderscore( $text );
 
                $text = $this->doHeadings( $text );
-               if( $this->mOptions->getUseDynamicDates() ) {
+               if ( $this->mOptions->getUseDynamicDates() ) {
                        $df = DateFormatter::getInstance();
                        $text = $df->reformat( $this->mOptions->getDateFormat(), $text );
                }
@@ -955,7 +1078,7 @@ class Parser
 
                # replaceInternalLinks may sometimes leave behind
                # absolute URLs, which have to be masked to hide them from replaceExternalLinks
-               $text = str_replace($this->mUniqPrefix.'NOPARSE', '', $text);
+               $text = str_replace( $this->mUniqPrefix.'NOPARSE', '', $text );
 
                $text = $this->doMagicLinks( $text );
                $text = $this->formatHeadings( $text, $origText, $isMain );
@@ -977,7 +1100,7 @@ class Parser
                $urlChar = self::EXT_LINK_URL_CLASS;
                $text = preg_replace_callback(
                        '!(?:                           # Start cases
-                               (<a.*?</a>) |               # m[1]: Skip link text
+                               (<a[ \t\r\n>].*?</a>) |     # m[1]: Skip link text
                                (<.*?>) |                   # m[2]: Skip stuff inside HTML elements' . "
                                (\\b(?:$prots)$urlChar+) |  # m[3]: Free external links" . '
                                (?:RFC|PMID)\s+([0-9]+) |   # m[4]: RFC or PMID, capture number
@@ -1016,7 +1139,7 @@ class Parser
                                $id = $m[4];
                        } else {
                                throw new MWException( __METHOD__.': unrecognised match type "' .
-                                       substr($m[0], 0, 20 ) . '"' );
+                                       substr( $m[0], 0, 20 ) . '"' );
                        }
                        $url = wfMsg( $urlmsg, $id);
                        $sk = $this->mOptions->getSkin();
@@ -1055,9 +1178,9 @@ class Parser
                # removeHTMLtags()) should not be included in
                # URLs, per RFC 2396.
                $m2 = array();
-               if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
-                       $trail = substr($url, $m2[0][1]) . $trail;
-                       $url = substr($url, 0, $m2[0][1]);
+               if ( preg_match( '/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE ) ) {
+                       $trail = substr( $url, $m2[0][1] ) . $trail;
+                       $url = substr( $url, 0, $m2[0][1] );
                }
 
                # Move trailing punctuation to $trail
@@ -1119,7 +1242,7 @@ class Parser
                foreach ( $lines as $line ) {
                        $outtext .= $this->doQuotes( $line ) . "\n";
                }
-               $outtext = substr($outtext, 0,-1);
+               $outtext = substr( $outtext, 0,-1 );
                wfProfileOut( __METHOD__ );
                return $outtext;
        }
@@ -1129,39 +1252,38 @@ class Parser
         */
        public function doQuotes( $text ) {
                $arr = preg_split( "/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE );
-               if ( count( $arr ) == 1 )
+               if ( count( $arr ) == 1 ) {
                        return $text;
-               else
-               {
+               } else {
                        # First, do some preliminary work. This may shift some apostrophes from
                        # being mark-up to being text. It also counts the number of occurrences
                        # of bold and italics mark-ups.
                        $i = 0;
                        $numbold = 0;
                        $numitalics = 0;
-                       foreach ( $arr as $r )
-                       {
-                               if ( ( $i % 2 ) == 1 )
-                               {
+                       foreach ( $arr as $r ) {
+                               if ( ( $i % 2 ) == 1 ) {
                                        # If there are ever four apostrophes, assume the first is supposed to
                                        # be text, and the remaining three constitute mark-up for bold text.
-                                       if ( strlen( $arr[$i] ) == 4 )
-                                       {
+                                       if ( strlen( $arr[$i] ) == 4 ) {
                                                $arr[$i-1] .= "'";
                                                $arr[$i] = "'''";
-                                       }
-                                       # If there are more than 5 apostrophes in a row, assume they're all
-                                       # text except for the last 5.
-                                       else if ( strlen( $arr[$i] ) > 5 )
-                                       {
+                                       } elseif ( strlen( $arr[$i] ) > 5 ) {
+                                               # If there are more than 5 apostrophes in a row, assume they're all
+                                               # text except for the last 5.
                                                $arr[$i-1] .= str_repeat( "'", strlen( $arr[$i] ) - 5 );
                                                $arr[$i] = "'''''";
                                        }
                                        # Count the number of occurrences of bold and italics mark-ups.
                                        # We are not counting sequences of five apostrophes.
-                                       if ( strlen( $arr[$i] ) == 2 )      { $numitalics++;             }
-                                       else if ( strlen( $arr[$i] ) == 3 ) { $numbold++;                }
-                                       else if ( strlen( $arr[$i] ) == 5 ) { $numitalics++; $numbold++; }
+                                       if ( strlen( $arr[$i] ) == 2 ) {
+                                               $numitalics++;
+                                       } elseif ( strlen( $arr[$i] ) == 3 ) {
+                                               $numbold++;
+                                       } elseif ( strlen( $arr[$i] ) == 5 ) {
+                                               $numitalics++;
+                                               $numbold++;
+                                       }
                                }
                                $i++;
                        }
@@ -1170,48 +1292,46 @@ class Parser
                        # that one of the bold ones was meant to be an apostrophe followed
                        # by italics. Which one we cannot know for certain, but it is more
                        # likely to be one that has a single-letter word before it.
-                       if ( ( $numbold % 2 == 1 ) && ( $numitalics % 2 == 1 ) )
-                       {
+                       if ( ( $numbold % 2 == 1 ) && ( $numitalics % 2 == 1 ) ) {
                                $i = 0;
                                $firstsingleletterword = -1;
                                $firstmultiletterword = -1;
                                $firstspace = -1;
-                               foreach ( $arr as $r )
-                               {
-                                       if ( ( $i % 2 == 1 ) and ( strlen( $r ) == 3 ) )
-                                       {
-                                               $x1 = substr ($arr[$i-1], -1);
-                                               $x2 = substr ($arr[$i-1], -2, 1);
-                                               if ($x1 === ' ') {
-                                                       if ($firstspace == -1) $firstspace = $i;
-                                               } else if ($x2 === ' ') {
-                                                       if ($firstsingleletterword == -1) $firstsingleletterword = $i;
+                               foreach ( $arr as $r ) {
+                                       if ( ( $i % 2 == 1 ) and ( strlen( $r ) == 3 ) ) {
+                                               $x1 = substr( $arr[$i-1], -1 );
+                                               $x2 = substr( $arr[$i-1], -2, 1 );
+                                               if ( $x1 === ' ' ) {
+                                                       if ( $firstspace == -1 ) {
+                                                               $firstspace = $i;
+                                                       }
+                                               } elseif ( $x2 === ' ') {
+                                                       if ( $firstsingleletterword == -1 ) {
+                                                               $firstsingleletterword = $i;
+                                                       }
                                                } else {
-                                                       if ($firstmultiletterword == -1) $firstmultiletterword = $i;
+                                                       if ( $firstmultiletterword == -1 ) {
+                                                               $firstmultiletterword = $i;
+                                                       }
                                                }
                                        }
                                        $i++;
                                }
 
                                # If there is a single-letter word, use it!
-                               if ($firstsingleletterword > -1)
-                               {
-                                       $arr [ $firstsingleletterword ] = "''";
-                                       $arr [ $firstsingleletterword-1 ] .= "'";
-                               }
-                               # If not, but there's a multi-letter word, use that one.
-                               else if ($firstmultiletterword > -1)
-                               {
-                                       $arr [ $firstmultiletterword ] = "''";
-                                       $arr [ $firstmultiletterword-1 ] .= "'";
-                               }
-                               # ... otherwise use the first one that has neither.
-                               # (notice that it is possible for all three to be -1 if, for example,
-                               # there is only one pentuple-apostrophe in the line)
-                               else if ($firstspace > -1)
-                               {
-                                       $arr [ $firstspace ] = "''";
-                                       $arr [ $firstspace-1 ] .= "'";
+                               if ( $firstsingleletterword > -1 ) {
+                                       $arr[$firstsingleletterword] = "''";
+                                       $arr[$firstsingleletterword-1] .= "'";
+                               } elseif ( $firstmultiletterword > -1 ) {
+                                       # If not, but there's a multi-letter word, use that one.
+                                       $arr[$firstmultiletterword] = "''";
+                                       $arr[$firstmultiletterword-1] .= "'";
+                               } elseif ( $firstspace > -1 ) {
+                                       # ... otherwise use the first one that has neither.
+                                       # (notice that it is possible for all three to be -1 if, for example,
+                                       # there is only one pentuple-apostrophe in the line)
+                                       $arr[$firstspace] = "''";
+                                       $arr[$firstspace-1] .= "'";
                                }
                        }
 
@@ -1220,71 +1340,70 @@ class Parser
                        $buffer = '';
                        $state = '';
                        $i = 0;
-                       foreach ($arr as $r)
-                       {
-                               if (($i % 2) == 0)
-                               {
-                                       if ($state === 'both')
+                       foreach ( $arr as $r ) {
+                               if ( ( $i % 2 ) == 0 ) {
+                                       if ( $state === 'both' ) {
                                                $buffer .= $r;
-                                       else
+                                       } else {
                                                $output .= $r;
-                               }
-                               else
-                               {
-                                       if (strlen ($r) == 2)
-                                       {
-                                               if ($state === 'i')
-                                               { $output .= '</i>'; $state = ''; }
-                                               else if ($state === 'bi')
-                                               { $output .= '</i>'; $state = 'b'; }
-                                               else if ($state === 'ib')
-                                               { $output .= '</b></i><b>'; $state = 'b'; }
-                                               else if ($state === 'both')
-                                               { $output .= '<b><i>'.$buffer.'</i>'; $state = 'b'; }
-                                               else # $state can be 'b' or ''
-                                               { $output .= '<i>'; $state .= 'i'; }
-                                       }
-                                       else if (strlen ($r) == 3)
-                                       {
-                                               if ($state === 'b')
-                                               { $output .= '</b>'; $state = ''; }
-                                               else if ($state === 'bi')
-                                               { $output .= '</i></b><i>'; $state = 'i'; }
-                                               else if ($state === 'ib')
-                                               { $output .= '</b>'; $state = 'i'; }
-                                               else if ($state === 'both')
-                                               { $output .= '<i><b>'.$buffer.'</b>'; $state = 'i'; }
-                                               else # $state can be 'i' or ''
-                                               { $output .= '<b>'; $state .= 'b'; }
                                        }
-                                       else if (strlen ($r) == 5)
-                                       {
-                                               if ($state === 'b')
-                                               { $output .= '</b><i>'; $state = 'i'; }
-                                               else if ($state === 'i')
-                                               { $output .= '</i><b>'; $state = 'b'; }
-                                               else if ($state === 'bi')
-                                               { $output .= '</i></b>'; $state = ''; }
-                                               else if ($state === 'ib')
-                                               { $output .= '</b></i>'; $state = ''; }
-                                               else if ($state === 'both')
-                                               { $output .= '<i><b>'.$buffer.'</b></i>'; $state = ''; }
-                                               else # ($state == '')
-                                               { $buffer = ''; $state = 'both'; }
+                               } else {
+                                       if ( strlen( $r ) == 2 ) {
+                                               if ( $state === 'i' ) {
+                                                       $output .= '</i>'; $state = '';
+                                               } elseif ( $state === 'bi' ) {
+                                                       $output .= '</i>'; $state = 'b';
+                                               } elseif ( $state === 'ib' ) {
+                                                       $output .= '</b></i><b>'; $state = 'b';
+                                               } elseif ( $state === 'both' ) {
+                                                       $output .= '<b><i>'.$buffer.'</i>'; $state = 'b';
+                                               } else { # $state can be 'b' or ''
+                                                       $output .= '<i>'; $state .= 'i';
+                                               }
+                                       } elseif ( strlen( $r ) == 3 ) {
+                                               if ( $state === 'b' ) {
+                                                       $output .= '</b>'; $state = '';
+                                               } elseif ( $state === 'bi' ) {
+                                                       $output .= '</i></b><i>'; $state = 'i';
+                                               } elseif ( $state === 'ib' ) {
+                                                       $output .= '</b>'; $state = 'i';
+                                               } elseif ( $state === 'both' ) {
+                                                       $output .= '<i><b>'.$buffer.'</b>'; $state = 'i';
+                                               } else { # $state can be 'i' or ''
+                                                       $output .= '<b>'; $state .= 'b';
+                                               }
+                                       } elseif ( strlen( $r ) == 5 ) {
+                                               if ( $state === 'b' ) {
+                                                       $output .= '</b><i>'; $state = 'i';
+                                               } elseif ( $state === 'i' ) {
+                                                       $output .= '</i><b>'; $state = 'b';
+                                               } elseif ( $state === 'bi' ) {
+                                                       $output .= '</i></b>'; $state = '';
+                                               } elseif ( $state === 'ib' ) {
+                                                       $output .= '</b></i>'; $state = '';
+                                               } elseif ( $state === 'both' ) {
+                                                       $output .= '<i><b>'.$buffer.'</b></i>'; $state = '';
+                                               } else { # ($state == '')
+                                                       $buffer = ''; $state = 'both';
+                                               }
                                        }
                                }
                                $i++;
                        }
                        # Now close all remaining tags.  Notice that the order is important.
-                       if ($state === 'b' || $state === 'ib')
+                       if ( $state === 'b' || $state === 'ib' ) {
                                $output .= '</b>';
-                       if ($state === 'i' || $state === 'bi' || $state === 'ib')
+                       }
+                       if ( $state === 'i' || $state === 'bi' || $state === 'ib' ) {
                                $output .= '</i>';
-                       if ($state === 'bi')
+                       }
+                       if ( $state === 'bi' ) {
                                $output .= '</b>';
+                       }
                        # There might be lonely ''''', so make sure we have a buffer
-                       if ($state === 'both' && $buffer)
+                       if ( $state === 'both' && $buffer ) {
                                $output .= '<b><i>'.$buffer.'</i></b>';
+                       }
                        return $output;
                }
        }
@@ -1317,9 +1436,9 @@ class Parser
                        # removeHTMLtags()) should not be included in
                        # URLs, per RFC 2396.
                        $m2 = array();
-                       if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
-                               $text = substr($url, $m2[0][1]) . ' ' . $text;
-                               $url = substr($url, 0, $m2[0][1]);
+                       if ( preg_match( '/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE ) ) {
+                               $text = substr( $url, $m2[0][1] ) . ' ' . $text;
+                               $url = substr( $url, 0, $m2[0][1] );
                        }
 
                        # If the link text is an image URL, replace it with an <img> tag
@@ -1332,12 +1451,12 @@ class Parser
                        $dtrail = '';
 
                        # Set linktype for CSS - if URL==text, link is essentially free
-                       $linktype = ($text === $url) ? 'free' : 'text';
+                       $linktype = ( $text === $url ) ? 'free' : 'text';
 
                        # No link text, e.g. [http://domain.tld/some.link]
                        if ( $text == '' ) {
                                # Autonumber if allowed. See bug #5918
-                               if ( strpos( wfUrlProtocols(), substr($protocol, 0, strpos($protocol, ':')) ) !== false ) {
+                               if ( strpos( wfUrlProtocols(), substr( $protocol, 0, strpos( $protocol, ':' ) ) ) !== false ) {
                                        $langObj = $this->getFunctionLang();
                                        $text = '[' . $langObj->formatNum( ++$this->mAutonumber ) . ']';
                                        $linktype = 'autonumber';
@@ -1352,13 +1471,13 @@ class Parser
                                list( $dtrail, $trail ) = Linker::splitTrail( $trail );
                        }
 
-                       $text = $wgContLang->markNoConversion($text);
+                       $text = $wgContLang->markNoConversion( $text );
 
                        $url = Sanitizer::cleanUrl( $url );
 
                        # Use the encoded URL
                        # This means that users can paste URLs directly into the text
-                       # Funny characters like &ouml; aren't valid in URLs anyway
+                       # Funny characters like Ã¶ aren't valid in URLs anyway
                        # This was changed in August 2004
                        $s .= $sk->makeExternalLink( $url, $text, false, $linktype,
                                $this->getExternalLinkAttribs( $url ) ) . $dtrail . $trail;
@@ -1380,15 +1499,15 @@ class Parser
         * (depending on configuration, namespace, and the URL's domain) and/or a
         * target attribute (depending on configuration).
         *
-        * @param string $url Optional URL, to extract the domain from for rel =>
+        * @param $url String: optional URL, to extract the domain from for rel =>
         *   nofollow if appropriate
-        * @return array Associative array of HTML attributes
+        * @return Array: associative array of HTML attributes
         */
        function getExternalLinkAttribs( $url = false ) {
                $attribs = array();
                global $wgNoFollowLinks, $wgNoFollowNsExceptions;
                $ns = $this->mTitle->getNamespace();
-               if( $wgNoFollowLinks && !in_array($ns, $wgNoFollowNsExceptions) ) {
+               if ( $wgNoFollowLinks && !in_array( $ns, $wgNoFollowNsExceptions ) ) {
                        $attribs['rel'] = 'nofollow';
 
                        global $wgNoFollowDomainExceptions;
@@ -1396,8 +1515,7 @@ class Parser
                                $bits = wfParseUrl( $url );
                                if ( is_array( $bits ) && isset( $bits['host'] ) ) {
                                        foreach ( $wgNoFollowDomainExceptions as $domain ) {
-                                               if( substr( $bits['host'], -strlen( $domain ) )
-                                               == $domain ) {
+                                               if ( substr( $bits['host'], -strlen( $domain ) ) == $domain ) {
                                                        unset( $attribs['rel'] );
                                                        break;
                                                }
@@ -1414,9 +1532,10 @@ class Parser
 
        /**
         * Replace unusual URL escape codes with their equivalent characters
-        * @param string
-        * @return string
-        * @static
+        *
+        * @param $url String
+        * @return String
+        *
         * @todo  This can merge genuinely required bits in the path or query string,
         *        breaking legit URLs. A proper fix would treat the various parts of
         *        the URL differently; as a workaround, just use the output for
@@ -1430,18 +1549,16 @@ class Parser
        /**
         * Callback function used in replaceUnusualEscapes().
         * Replaces unusual URL escape codes with their equivalent character
-        * @static
-        * @private
         */
        private static function replaceUnusualEscapesCallback( $matches ) {
                $char = urldecode( $matches[0] );
                $ord = ord( $char );
-               // Is it an unsafe or HTTP reserved character according to RFC 1738?
+               # Is it an unsafe or HTTP reserved character according to RFC 1738?
                if ( $ord > 32 && $ord < 127 && strpos( '<>"#{}|\^~[]`;/?', $char ) === false ) {
-                       // No, shouldn't be escaped
+                       # No, shouldn't be escaped
                        return $char;
                } else {
-                       // Yes, leave it escaped
+                       # Yes, leave it escaped
                        return $matches[0];
                }
        }
@@ -1454,19 +1571,19 @@ class Parser
        function maybeMakeExternalImage( $url ) {
                $sk = $this->mOptions->getSkin();
                $imagesfrom = $this->mOptions->getAllowExternalImagesFrom();
-               $imagesexception = !empty($imagesfrom);
+               $imagesexception = !empty( $imagesfrom );
                $text = false;
                # $imagesfrom could be either a single string or an array of strings, parse out the latter
-               if( $imagesexception && is_array( $imagesfrom ) ) {
+               if ( $imagesexception && is_array( $imagesfrom ) ) {
                        $imagematch = false;
-                       foreach( $imagesfrom as $match ) {
-                               if( strpos( $url, $match ) === 0 ) {
+                       foreach ( $imagesfrom as $match ) {
+                               if ( strpos( $url, $match ) === 0 ) {
                                        $imagematch = true;
                                        break;
                                }
                        }
-               } elseif( $imagesexception ) {
-                       $imagematch = (strpos( $url, $imagesfrom ) === 0);
+               } elseif ( $imagesexception ) {
+                       $imagematch = ( strpos( $url, $imagesfrom ) === 0 );
                } else {
                        $imagematch = false;
                }
@@ -1477,14 +1594,15 @@ class Parser
                                $text = $sk->makeExternalImage( $url );
                        }
                }
-               if( !$text && $this->mOptions->getEnableImageWhitelist()
+               if ( !$text && $this->mOptions->getEnableImageWhitelist()
                         && preg_match( self::EXT_IMAGE_REGEX, $url ) ) {
                        $whitelist = explode( "\n", wfMsgForContent( 'external_image_whitelist' ) );
-                       foreach( $whitelist as $entry ) {
+                       foreach ( $whitelist as $entry ) {
                                # Sanitize the regex fragment, make it case-insensitive, ignore blank entries/comments
-                               if( strpos( $entry, '#' ) === 0 || $entry === '' )
+                               if ( strpos( $entry, '#' ) === 0 || $entry === '' ) {
                                        continue;
-                               if( preg_match( '/' . str_replace( '/', '\\/', $entry ) . '/i', $url ) ) {
+                               }
+                               if ( preg_match( '/' . str_replace( '/', '\\/', $entry ) . '/i', $url ) ) {
                                        # Image matches a whitelist entry
                                        $text = $sk->makeExternalImage( $url );
                                        break;
@@ -1522,7 +1640,7 @@ class Parser
                if ( !$tc ) {
                        $tc = Title::legalChars() . '#%';
                        # Match a link having the form [[namespace:link|alternate]]trail
-                       $e1 = "/^([{$tc}]*)(\\|.*?)?]](.*)\$/sD";
+                       $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
                        # Match cases where there is no "]]", which might still be images
                        $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
                }
@@ -1530,9 +1648,9 @@ class Parser
                $sk = $this->mOptions->getSkin();
                $holders = new LinkHolderArray( $this );
 
-               #split the entire text string on occurences of [[
+               # split the entire text string on occurences of [[
                $a = StringUtils::explode( '[[', ' ' . $s );
-               #get the first element (all text up to first [[), and remove the space we added
+               # get the first element (all text up to first [[), and remove the space we added
                $s = $a->current();
                $a->next();
                $line = $a->current(); # Workaround for broken ArrayIterator::next() that returns "void"
@@ -1546,7 +1664,7 @@ class Parser
                        $e2 = wfMsgForContent( 'linkprefix' );
                }
 
-               if( is_null( $this->mTitle ) ) {
+               if ( is_null( $this->mTitle ) ) {
                        wfProfileOut( __METHOD__.'-setup' );
                        wfProfileOut( __METHOD__ );
                        throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
@@ -1564,10 +1682,10 @@ class Parser
                        $prefix = '';
                }
 
-               if($wgContLang->hasVariants()) {
-                       $selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
+               if ( $wgContLang->hasVariants() ) {
+                       $selflink = $wgContLang->convertLinkToAllVariants( $this->mTitle->getPrefixedText() );
                } else {
-                       $selflink = array($this->mTitle->getPrefixedText());
+                       $selflink = array( $this->mTitle->getPrefixedText() );
                }
                $useSubpages = $this->areSubpagesAllowed();
                wfProfileOut( __METHOD__.'-setup' );
@@ -1591,7 +1709,7 @@ class Parser
                                        $prefix='';
                                }
                                # first link
-                               if($first_prefix) {
+                               if ( $first_prefix ) {
                                        $prefix = $first_prefix;
                                        $first_prefix = false;
                                }
@@ -1602,15 +1720,7 @@ class Parser
 
                        wfProfileIn( __METHOD__."-e1" );
                        if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
-
-                               if( $m[2] === '' ) {
-                                       $text = '';
-                               } elseif( $m[2] === '|' ) { 
-                                       $text = $this->getPipeTrickText( $m[1] );
-                               } else {
-                                       $text = substr( $m[2], 1 );
-                               }
-
+                               $text = $m[2];
                                # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
                                # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row fucks up,
                                # the real problem is with the $e1 regex
@@ -1619,28 +1729,26 @@ class Parser
                                # Still some problems for cases where the ] is meant to be outside punctuation,
                                # and no image is in sight. See bug 2095.
                                #
-                               if( $text !== '' &&
+                               if ( $text !== '' &&
                                        substr( $m[3], 0, 1 ) === ']' &&
-                                       strpos($text, '[') !== false
+                                       strpos( $text, '[' ) !== false
                                )
                                {
                                        $text .= ']'; # so that replaceExternalLinks($text) works later
                                        $m[3] = substr( $m[3], 1 );
                                }
-
-                               # Handle pipe-trick for [[|<blah>]]
-                               $lnk = $m[1] === '' ? $this->getPipeTrickLink( $text ) : $m[1];
                                # fix up urlencoded title texts
-                               if( strpos( $lnk, '%' ) !== false ) {
+                               if ( strpos( $m[1], '%' ) !== false ) {
                                        # Should anchors '#' also be rejected?
-                                       $lnk = str_replace( array('<', '>'), array('&lt;', '&gt;'), urldecode($lnk) );
+                                       $m[1] = str_replace( array('<', '>'), array('&lt;', '&gt;'), 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
+                       } 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];
-                               $lnk = strpos( $m[1], '%' ) === false ? $m[1] : urldecode( $m[1] );
+                               if ( strpos( $m[1], '%' ) !== false ) {
+                                       $m[1] = urldecode( $m[1] );
+                               }
                                $trail = "";
                        } else { # Invalid form; output directly
                                $s .= $prefix . '[[' . $line ;
@@ -1653,7 +1761,7 @@ class Parser
                        # Don't allow internal links to pages containing
                        # PROTO: where PROTO is a valid URL protocol; these
                        # should be external links.
-                       if ( preg_match( '/^\b(?:' . wfUrlProtocols() . ')/', $lnk ) ) {
+                       if ( preg_match( '/^\b(?:' . wfUrlProtocols() . ')/', $m[1] ) ) {
                                $s .= $prefix . '[[' . $line ;
                                wfProfileOut( __METHOD__."-misc" );
                                continue;
@@ -1661,13 +1769,13 @@ class Parser
 
                        # Make subpage if necessary
                        if ( $useSubpages ) {
-                               $link = $this->maybeDoSubpageLink( $lnk, $text );
+                               $link = $this->maybeDoSubpageLink( $m[1], $text );
                        } else {
-                               $link = $lnk;
+                               $link = $m[1];
                        }
 
-                       $noforce = (substr( $lnk, 0, 1 ) !== ':');
-                       if (!$noforce) {
+                       $noforce = ( substr( $m[1], 0, 1 ) !== ':' );
+                       if ( !$noforce ) {
                                # Strip off leading ':'
                                $link = substr( $link, 1 );
                        }
@@ -1687,10 +1795,10 @@ class Parser
 
                        if ( $might_be_img ) { # if this is actually an invalid link
                                wfProfileIn( __METHOD__."-might_be_img" );
-                               if ( $ns == NS_FILE && $noforce ) { #but might be an image
+                               if ( $ns == NS_FILE && $noforce ) { # but might be an image
                                        $found = false;
                                        while ( true ) {
-                                               #look at the next 'line' to see if we can close it there
+                                               # look at the next 'line' to see if we can close it there
                                                $a->next();
                                                $next_line = $a->current();
                                                if ( $next_line === false || $next_line === null ) {
@@ -1704,24 +1812,24 @@ class Parser
                                                        $trail = $m[2];
                                                        break;
                                                } elseif ( count( $m ) == 2 ) {
-                                                       #if there's exactly one ]] that's fine, we'll keep looking
+                                                       # if there's exactly one ]] that's fine, we'll keep looking
                                                        $text .= "[[{$m[0]}]]{$m[1]}";
                                                } else {
-                                                       #if $next_line is invalid too, we need look no further
+                                                       # 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
-                                               #but don't ignore what might be perfectly normal links in the text we've examined
+                                               # but don't ignore what might be perfectly normal links in the text we've examined
                                                $holders->merge( $this->replaceInternalLinks2( $text ) );
                                                $s .= "{$prefix}[[$link|$text";
                                                # note: no $trail, because without an end, there *is* no trail
                                                wfProfileOut( __METHOD__."-might_be_img" );
                                                continue;
                                        }
-                               } else { #it's not an image, so output it raw
+                               } 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
                                        wfProfileOut( __METHOD__."-might_be_img" );
@@ -1731,7 +1839,9 @@ class Parser
                        }
 
                        $wasblank = ( $text  == '' );
-                       if ( $wasblank ) $text = $link;
+                       if ( $wasblank ) {
+                               $text = $link;
+                       }
 
                        # Link not escaped by : , create the various objects
                        if ( $noforce ) {
@@ -1740,8 +1850,8 @@ class Parser
                                wfProfileIn( __METHOD__."-interwiki" );
                                if ( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw ) ) {
                                        $this->mOutput->addLanguageLink( $nt->getFullText() );
-                                       $s = rtrim($s . $prefix);
-                                       $s .= trim($trail, "\n") == '' ? '': $prefix . $trail;
+                                       $s = rtrim( $s . $prefix );
+                                       $s .= trim( $trail, "\n" ) == '' ? '': $prefix . $trail;
                                        wfProfileOut( __METHOD__."-interwiki" );
                                        continue;
                                }
@@ -1760,7 +1870,7 @@ class Parser
                                                        # 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->replaceExternalLinks( $text );
                                                        $holders->merge( $this->replaceInternalLinks2( $text ) );
                                                }
                                                # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
@@ -1776,7 +1886,7 @@ class Parser
 
                                if ( $ns == NS_CATEGORY ) {
                                        wfProfileIn( __METHOD__."-category" );
-                                       $s = rtrim($s . "\n"); # bug 87
+                                       $s = rtrim( $s . "\n" ); # bug 87
 
                                        if ( $wasblank ) {
                                                $sortkey = $this->getDefaultSort();
@@ -1792,7 +1902,7 @@ class Parser
                                         * Strip the whitespace Category links produce, see bug 87
                                         * @todo We might want to use trim($tmp, "\n") here.
                                         */
-                                       $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
+                                       $s .= trim( $prefix . $trail, "\n" ) == '' ? '': $prefix . $trail;
 
                                        wfProfileOut( __METHOD__."-category" );
                                        continue;
@@ -1800,8 +1910,8 @@ class Parser
                        }
 
                        # Self-link checking
-                       if( $nt->getFragment() === '' && $ns != NS_SPECIAL ) {
-                               if( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
+                       if ( $nt->getFragment() === '' && $ns != NS_SPECIAL ) {
+                               if ( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
                                        $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
                                        continue;
                                }
@@ -1809,7 +1919,7 @@ class Parser
 
                        # NS_MEDIA is a pseudo-namespace for linking directly to a file
                        # FIXME: Should do batch file existence checks, see comment below
-                       if( $ns == NS_MEDIA ) {
+                       if ( $ns == NS_MEDIA ) {
                                wfProfileIn( __METHOD__."-media" );
                                # Give extensions a chance to select the file revision for us
                                $skip = $time = false;
@@ -1832,7 +1942,7 @@ class Parser
                        #
                        # FIXME: isAlwaysKnown() can be expensive for file links; we should really do
                        # batch file existence checks for NS_FILE and NS_MEDIA
-                       if( $iw == '' && $nt->isAlwaysKnown() ) {
+                       if ( $iw == '' && $nt->isAlwaysKnown() ) {
                                $this->mOutput->addLink( $nt );
                                $s .= $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix );
                        } else {
@@ -1864,17 +1974,17 @@ class Parser
         * breaking URLs in the following text without breaking trails on the
         * wiki links, it's been made into a horrible function.
         *
-        * @param Title $nt
-        * @param string $text
-        * @param string $query
-        * @param string $trail
-        * @param string $prefix
-        * @return string HTML-wikitext mix oh yuck
+        * @param $nt Title
+        * @param $text String
+        * @param $query String
+        * @param $trail String
+        * @param $prefix String
+        * @return String: HTML-wikitext mix oh yuck
         */
        function makeKnownLinkHolder( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
                list( $inside, $trail ) = Linker::splitTrail( $trail );
                $sk = $this->mOptions->getSkin();
-               // FIXME: use link() instead of deprecated makeKnownLinkObj()
+               # FIXME: use link() instead of deprecated makeKnownLinkObj()
                $link = $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix );
                return $this->armorLinks( $link ) . $trail;
        }
@@ -1886,8 +1996,8 @@ class Parser
         * Not needed quite as much as it used to be since free links are a bit
         * more sensible these days. But bracketed links are still an issue.
         *
-        * @param string more-or-less HTML
-        * @return string less-or-more HTML with NOPARSE bits
+        * @param $text String: more-or-less HTML
+        * @return String: less-or-more HTML with NOPARSE bits
         */
        function armorLinks( $text ) {
                return preg_replace( '/\b(' . wfUrlProtocols() . ')/',
@@ -1896,7 +2006,7 @@ class Parser
 
        /**
         * Return true if subpage links should be expanded on this page.
-        * @return bool
+        * @return Boolean
         */
        function areSubpagesAllowed() {
                # Some namespaces don't allow subpages
@@ -1905,39 +2015,21 @@ class Parser
 
        /**
         * Handle link to subpage if necessary
-        * @param string $target the source of the link
-        * @param string &$text the link text, modified as necessary
+        *
+        * @param $target String: the source of the link
+        * @param &$text String: the link text, modified as necessary
         * @return string the full name of the link
         * @private
         */
-       function maybeDoSubpageLink($target, &$text) {
+       function maybeDoSubpageLink( $target, &$text ) {
                return Linker::normalizeSubpageLink( $this->mTitle, $target, $text );
        }
 
-       /**
-        * From the [[title|]] return link-text as though the used typed [[title|link-text]]
-        * @param string $link from [[$link|]]
-        * @return string $text for [[$link|$text]]
-        */
-       function getPipeTrickText( $link ) {
-               return Linker::getPipeTrickText( $link );
-       }
-
-       /**
-        * From the [[|link-text]] return the title as though the user typed [[title|link-text]]
-        * @param string $text from [[|$text]]
-        * @param Title $title to resolve the link against
-        * @return string $link for [[$link|$text]]
-        */
-       function getPipeTrickLink( $text ) {
-               return Linker::getPipeTrickLink( $text, $this->mTitle );
-       }
-
        /**#@+
         * Used by doBlockLevels()
         * @private
         */
-       /* private */ function closeParagraph() {
+       function closeParagraph() {
                $result = '';
                if ( $this->mLastSection != '' ) {
                        $result = '</' . $this->mLastSection  . ">\n";
@@ -1946,42 +2038,64 @@ class Parser
                $this->mLastSection = '';
                return $result;
        }
-       # getCommon() returns the length of the longest common substring
-       # of both arguments, starting at the beginning of both.
-       #
-       /* private */ function getCommon( $st1, $st2 ) {
+
+       /**
+        * getCommon() returns the length of the longest common substring
+        * of both arguments, starting at the beginning of both.
+        * @private
+        */
+       function getCommon( $st1, $st2 ) {
                $fl = strlen( $st1 );
                $shorter = strlen( $st2 );
-               if ( $fl < $shorter ) { $shorter = $fl; }
+               if ( $fl < $shorter ) {
+                       $shorter = $fl;
+               }
 
                for ( $i = 0; $i < $shorter; ++$i ) {
-                       if ( $st1{$i} != $st2{$i} ) { break; }
+                       if ( $st1{$i} != $st2{$i} ) {
+                               break;
+                       }
                }
                return $i;
        }
-       # These next three functions open, continue, and close the list
-       # element appropriate to the prefix character passed into them.
-       #
-       /* private */ function openList( $char ) {
+
+       /**
+        * These next three functions open, continue, and close the list
+        * element appropriate to the prefix character passed into them.
+        * @private
+        */
+       function openList( $char ) {
                $result = $this->closeParagraph();
 
-               if ( '*' === $char ) { $result .= '<ul><li>'; }
-               elseif ( '#' === $char ) { $result .= '<ol><li>'; }
-               elseif ( ':' === $char ) { $result .= '<dl><dd>'; }
-               elseif ( ';' === $char ) {
+               if ( '*' === $char ) {
+                       $result .= '<ul><li>';
+               } elseif ( '#' === $char ) {
+                       $result .= '<ol><li>';
+               } elseif ( ':' === $char ) {
+                       $result .= '<dl><dd>';
+               } elseif ( ';' === $char ) {
                        $result .= '<dl><dt>';
                        $this->mDTopen = true;
+               } else {
+                       $result = '<!-- ERR 1 -->';
                }
-               else { $result = '<!-- ERR 1 -->'; }
 
                return $result;
        }
 
-       /* private */ function nextItem( $char ) {
-               if ( '*' === $char || '#' === $char ) { return '</li><li>'; }
-               elseif ( ':' === $char || ';' === $char ) {
+       /**
+        * TODO: document
+        * @param $char String
+        * @private
+        */
+       function nextItem( $char ) {
+               if ( '*' === $char || '#' === $char ) {
+                       return '</li><li>';
+               } elseif ( ':' === $char || ';' === $char ) {
                        $close = '</dd>';
-                       if ( $this->mDTopen ) { $close = '</dt>'; }
+                       if ( $this->mDTopen ) {
+                               $close = '</dt>';
+                       }
                        if ( ';' === $char ) {
                                $this->mDTopen = true;
                                return $close . '<dt>';
@@ -1993,18 +2107,26 @@ class Parser
                return '<!-- ERR 2 -->';
        }
 
-       /* private */ function closeList( $char ) {
-               if ( '*' === $char ) { $text = '</li></ul>'; }
-               elseif ( '#' === $char ) { $text = '</li></ol>'; }
-               elseif ( ':' === $char ) {
+       /**
+        * TODO: document
+        * @param $char String
+        * @private
+        */
+       function closeList( $char ) {
+               if ( '*' === $char ) {
+                       $text = '</li></ul>';
+               } elseif ( '#' === $char ) {
+                       $text = '</li></ol>';
+               } elseif ( ':' === $char ) {
                        if ( $this->mDTopen ) {
                                $this->mDTopen = false;
                                $text = '</dt></dl>';
                        } else {
                                $text = '</dd></dl>';
                        }
+               } else {
+                       return '<!-- ERR 3 -->';
                }
-               else {  return '<!-- ERR 3 -->'; }
                return $text."\n";
        }
        /**#@-*/
@@ -2012,7 +2134,8 @@ class Parser
        /**
         * Make lists from lines starting with ':', '*', '#', etc. (DBL)
         *
-        * @param $linestart bool whether or not this is at the start of a line.
+        * @param $text String
+        * @param $linestart Boolean: whether or not this is at the start of a line.
         * @private
         * @return string the lists rendered as HTML
         */
@@ -2037,24 +2160,24 @@ class Parser
                                $linestart = true;
                                continue;
                        }
-                       // * = ul
-                       // # = ol
-                       // ; = dt
-                       // : = dd
+                       # * = ul
+                       # # = ol
+                       # ; = dt
+                       # : = dd
 
                        $lastPrefixLength = strlen( $lastPrefix );
-                       $preCloseMatch = preg_match('/<\\/pre/i', $oLine );
-                       $preOpenMatch = preg_match('/<pre/i', $oLine );
-                       // If not in a <pre> element, scan for and figure out what prefixes are there.
+                       $preCloseMatch = preg_match( '/<\\/pre/i', $oLine );
+                       $preOpenMatch = preg_match( '/<pre/i', $oLine );
+                       # If not in a <pre> element, scan for and figure out what prefixes are there.
                        if ( !$this->mInPre ) {
                                # Multiple prefixes may abut each other for nested lists.
                                $prefixLength = strspn( $oLine, '*#:;' );
                                $prefix = substr( $oLine, 0, $prefixLength );
 
                                # eh?
-                               // ; and : are both from definition-lists, so they're equivalent
-                               //  for the purposes of determining whether or not we need to open/close
-                               //  elements.
+                               # ; and : are both from definition-lists, so they're equivalent
+                               #  for the purposes of determining whether or not we need to open/close
+                               #  elements.
                                $prefix2 = str_replace( ';', ':', $prefix );
                                $t = substr( $oLine, $prefixLength );
                                $this->mInPre = (bool)$preOpenMatch;
@@ -2066,7 +2189,7 @@ class Parser
                        }
 
                        # List generation
-                       if( $prefixLength && $lastPrefix === $prefix2 ) {
+                       if ( $prefixLength && $lastPrefix === $prefix2 ) {
                                # Same as the last item, so no need to deal with nesting or opening stuff
                                $output .= $this->nextItem( substr( $prefix, -1 ) );
                                $paragraphStack = false;
@@ -2077,37 +2200,37 @@ class Parser
                                        # So we check for : in the remainder text to split up the
                                        # title and definition, without b0rking links.
                                        $term = $t2 = '';
-                                       if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+                                       if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
                                                $t = $t2;
                                                $output .= $term . $this->nextItem( ':' );
                                        }
                                }
-                       } elseif( $prefixLength || $lastPrefixLength ) {
-                               // We need to open or close prefixes, or both.
+                       } elseif ( $prefixLength || $lastPrefixLength ) {
+                               # We need to open or close prefixes, or both.
 
                                # Either open or close a level...
                                $commonPrefixLength = $this->getCommon( $prefix, $lastPrefix );
                                $paragraphStack = false;
 
-                               // Close all the prefixes which aren't shared.
-                               while( $commonPrefixLength < $lastPrefixLength ) {
+                               # Close all the prefixes which aren't shared.
+                               while ( $commonPrefixLength < $lastPrefixLength ) {
                                        $output .= $this->closeList( $lastPrefix[$lastPrefixLength-1] );
                                        --$lastPrefixLength;
                                }
 
-                               // Continue the current prefix if appropriate.
+                               # Continue the current prefix if appropriate.
                                if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
                                        $output .= $this->nextItem( $prefix[$commonPrefixLength-1] );
                                }
 
-                               // Open prefixes where appropriate.
+                               # Open prefixes where appropriate.
                                while ( $prefixLength > $commonPrefixLength ) {
                                        $char = substr( $prefix, $commonPrefixLength, 1 );
                                        $output .= $this->openList( $char );
 
                                        if ( ';' === $char ) {
                                                # FIXME: This is dupe of code above
-                                               if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+                                               if ( $this->findColonNoLinks( $t, $term, $t2 ) !== false ) {
                                                        $t = $t2;
                                                        $output .= $term . $this->nextItem( ':' );
                                                }
@@ -2117,11 +2240,11 @@ class Parser
                                $lastPrefix = $prefix2;
                        }
 
-                       // If we have no prefixes, go to paragraph mode.
-                       if( 0 == $prefixLength ) {
+                       # If we have no prefixes, go to paragraph mode.
+                       if ( 0 == $prefixLength ) {
                                wfProfileIn( __METHOD__."-paragraph" );
                                # No prefix (not in list)--go to paragraph mode
-                               // XXX: use a stack for nestable elements like span, table and div
+                               # 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 );
                                $closematch = preg_match(
                                        '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
@@ -2138,24 +2261,24 @@ class Parser
                                        } else {
                                                $inBlockElem = true;
                                        }
-                               } else if ( !$inBlockElem && !$this->mInPre ) {
-                                       if ( ' ' == substr( $t, 0, 1 ) and ( $this->mLastSection === 'pre' or trim($t) != '' ) ) {
-                                               // pre
-                                               if ($this->mLastSection !== 'pre') {
+                               } elseif ( !$inBlockElem && !$this->mInPre ) {
+                                       if ( ' ' == substr( $t, 0, 1 ) and ( $this->mLastSection === 'pre' || trim( $t ) != '' ) ) {
+                                               # pre
+                                               if ( $this->mLastSection !== 'pre' ) {
                                                        $paragraphStack = false;
                                                        $output .= $this->closeParagraph().'<pre>';
                                                        $this->mLastSection = 'pre';
                                                }
                                                $t = substr( $t, 1 );
                                        } else {
-                                               // paragraph
-                                               if ( trim($t) == '' ) {
+                                               # paragraph
+                                               if ( trim( $t ) === '' ) {
                                                        if ( $paragraphStack ) {
                                                                $output .= $paragraphStack.'<br />';
                                                                $paragraphStack = false;
                                                                $this->mLastSection = 'p';
                                                        } else {
-                                                               if ($this->mLastSection !== 'p' ) {
+                                                               if ( $this->mLastSection !== 'p' ) {
                                                                        $output .= $this->closeParagraph();
                                                                        $this->mLastSection = '';
                                                                        $paragraphStack = '<p>';
@@ -2168,7 +2291,7 @@ class Parser
                                                                $output .= $paragraphStack;
                                                                $paragraphStack = false;
                                                                $this->mLastSection = 'p';
-                                                       } else if ($this->mLastSection !== 'p') {
+                                                       } elseif ( $this->mLastSection !== 'p' ) {
                                                                $output .= $this->closeParagraph().'<p>';
                                                                $this->mLastSection = 'p';
                                                        }
@@ -2177,11 +2300,11 @@ class Parser
                                }
                                wfProfileOut( __METHOD__."-paragraph" );
                        }
-                       // somewhere above we forget to get out of pre block (bug 785)
-                       if($preCloseMatch && $this->mInPre) {
+                       # somewhere above we forget to get out of pre block (bug 785)
+                       if ( $preCloseMatch && $this->mInPre ) {
                                $this->mInPre = false;
                        }
-                       if ($paragraphStack === false) {
+                       if ( $paragraphStack === false ) {
                                $output .= $t."\n";
                        }
                }
@@ -2201,31 +2324,32 @@ class Parser
        /**
         * Split up a string on ':', ignoring any occurences inside tags
         * to prevent illegal overlapping.
-        * @param string $str the string to split
-        * @param string &$before set to everything before the ':'
-        * @param string &$after set to everything after the ':'
-        * return string the position of the ':', or false if none found
+        *
+        * @param $str String: the string to split
+        * @param &$before String: set to everything before the ':'
+        * @param &$after String: set to everything after the ':'
+        * return String: the position of the ':', or false if none found
         */
-       function findColonNoLinks($str, &$before, &$after) {
+       function findColonNoLinks( $str, &$before, &$after ) {
                wfProfileIn( __METHOD__ );
 
                $pos = strpos( $str, ':' );
-               if( $pos === false ) {
-                       // Nothing to find!
+               if ( $pos === false ) {
+                       # Nothing to find!
                        wfProfileOut( __METHOD__ );
                        return false;
                }
 
                $lt = strpos( $str, '<' );
-               if( $lt === false || $lt > $pos ) {
-                       // Easy; no tag nesting to worry about
+               if ( $lt === false || $lt > $pos ) {
+                       # Easy; no tag nesting to worry about
                        $before = substr( $str, 0, $pos );
                        $after = substr( $str, $pos+1 );
                        wfProfileOut( __METHOD__ );
                        return $pos;
                }
 
-               // Ugly state machine to walk through avoiding tags.
+               # Ugly state machine to walk through avoiding tags.
                $state = self::COLON_STATE_TEXT;
                $stack = 0;
                $len = strlen( $str );
@@ -2233,67 +2357,67 @@ class Parser
                        $c = $str{$i};
 
                        switch( $state ) {
-                       // (Using the number is a performance hack for common cases)
-                       case 0: // self::COLON_STATE_TEXT:
+                       # (Using the number is a performance hack for common cases)
+                       case 0: # self::COLON_STATE_TEXT:
                                switch( $c ) {
                                case "<":
-                                       // Could be either a <start> tag or an </end> tag
+                                       # Could be either a <start> tag or an </end> tag
                                        $state = self::COLON_STATE_TAGSTART;
                                        break;
                                case ":":
-                                       if( $stack == 0 ) {
-                                               // We found it!
+                                       if ( $stack == 0 ) {
+                                               # We found it!
                                                $before = substr( $str, 0, $i );
                                                $after = substr( $str, $i + 1 );
                                                wfProfileOut( __METHOD__ );
                                                return $i;
                                        }
-                                       // Embedded in a tag; don't break it.
+                                       # Embedded in a tag; don't break it.
                                        break;
                                default:
-                                       // Skip ahead looking for something interesting
+                                       # Skip ahead looking for something interesting
                                        $colon = strpos( $str, ':', $i );
-                                       if( $colon === false ) {
-                                               // Nothing else interesting
+                                       if ( $colon === false ) {
+                                               # Nothing else interesting
                                                wfProfileOut( __METHOD__ );
                                                return false;
                                        }
                                        $lt = strpos( $str, '<', $i );
-                                       if( $stack === 0 ) {
-                                               if( $lt === false || $colon < $lt ) {
-                                                       // We found it!
+                                       if ( $stack === 0 ) {
+                                               if ( $lt === false || $colon < $lt ) {
+                                                       # We found it!
                                                        $before = substr( $str, 0, $colon );
                                                        $after = substr( $str, $colon + 1 );
                                                        wfProfileOut( __METHOD__ );
                                                        return $i;
                                                }
                                        }
-                                       if( $lt === false ) {
-                                               // Nothing else interesting to find; abort!
-                                               // We're nested, but there's no close tags left. Abort!
+                                       if ( $lt === false ) {
+                                               # Nothing else interesting to find; abort!
+                                               # We're nested, but there's no close tags left. Abort!
                                                break 2;
                                        }
-                                       // Skip ahead to next tag start
+                                       # Skip ahead to next tag start
                                        $i = $lt;
                                        $state = self::COLON_STATE_TAGSTART;
                                }
                                break;
-                       case 1: // self::COLON_STATE_TAG:
-                               // In a <tag>
+                       case 1: # self::COLON_STATE_TAG:
+                               # In a <tag>
                                switch( $c ) {
                                case ">":
                                        $stack++;
                                        $state = self::COLON_STATE_TEXT;
                                        break;
                                case "/":
-                                       // Slash may be followed by >?
+                                       # Slash may be followed by >?
                                        $state = self::COLON_STATE_TAGSLASH;
                                        break;
                                default:
-                                       // ignore
+                                       # ignore
                                }
                                break;
-                       case 2: // self::COLON_STATE_TAGSTART:
+                       case 2: # self::COLON_STATE_TAGSTART:
                                switch( $c ) {
                                case "/":
                                        $state = self::COLON_STATE_CLOSETAG;
@@ -2302,18 +2426,18 @@ class Parser
                                        $state = self::COLON_STATE_COMMENT;
                                        break;
                                case ">":
-                                       // Illegal early close? This shouldn't happen D:
+                                       # Illegal early close? This shouldn't happen D:
                                        $state = self::COLON_STATE_TEXT;
                                        break;
                                default:
                                        $state = self::COLON_STATE_TAG;
                                }
                                break;
-                       case 3: // self::COLON_STATE_CLOSETAG:
-                               // In a </tag>
-                               if( $c === ">" ) {
+                       case 3: # self::COLON_STATE_CLOSETAG:
+                               # In a </tag>
+                               if ( $c === ">" ) {
                                        $stack--;
-                                       if( $stack < 0 ) {
+                                       if ( $stack < 0 ) {
                                                wfDebug( __METHOD__.": Invalid input; too many close tags\n" );
                                                wfProfileOut( __METHOD__ );
                                                return false;
@@ -2322,28 +2446,28 @@ class Parser
                                }
                                break;
                        case self::COLON_STATE_TAGSLASH:
-                               if( $c === ">" ) {
-                                       // Yes, a self-closed tag <blah/>
+                               if ( $c === ">" ) {
+                                       # Yes, a self-closed tag <blah/>
                                        $state = self::COLON_STATE_TEXT;
                                } else {
-                                       // Probably we're jumping the gun, and this is an attribute
+                                       # Probably we're jumping the gun, and this is an attribute
                                        $state = self::COLON_STATE_TAG;
                                }
                                break;
-                       case 5: // self::COLON_STATE_COMMENT:
-                               if( $c === "-" ) {
+                       case 5: # self::COLON_STATE_COMMENT:
+                               if ( $c === "-" ) {
                                        $state = self::COLON_STATE_COMMENTDASH;
                                }
                                break;
                        case self::COLON_STATE_COMMENTDASH:
-                               if( $c === "-" ) {
+                               if ( $c === "-" ) {
                                        $state = self::COLON_STATE_COMMENTDASHDASH;
                                } else {
                                        $state = self::COLON_STATE_COMMENT;
                                }
                                break;
                        case self::COLON_STATE_COMMENTDASHDASH:
-                               if( $c === ">" ) {
+                               if ( $c === ">" ) {
                                        $state = self::COLON_STATE_TEXT;
                                } else {
                                        $state = self::COLON_STATE_COMMENT;
@@ -2353,7 +2477,7 @@ class Parser
                                throw new MWException( "State machine error in " . __METHOD__ );
                        }
                }
-               if( $stack > 0 ) {
+               if ( $stack > 0 ) {
                        wfDebug( __METHOD__.": Invalid input; not enough close tags (stack $stack, state $state)\n" );
                        return false;
                }
@@ -2472,7 +2596,7 @@ class Parser
                                $value = wfUrlEncode( str_replace( ' ', '_', $this->mTitle->getBaseText() ) );
                                break;
                        case 'talkpagename':
-                               if( $this->mTitle->canTalk() ) {
+                               if ( $this->mTitle->canTalk() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = wfEscapeWikiText( $talkPage->getPrefixedText() );
                                } else {
@@ -2480,7 +2604,7 @@ class Parser
                                }
                                break;
                        case 'talkpagenamee':
-                               if( $this->mTitle->canTalk() ) {
+                               if ( $this->mTitle->canTalk() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = $talkPage->getPrefixedUrl();
                                } else {
@@ -2495,71 +2619,70 @@ class Parser
                                $subjPage = $this->mTitle->getSubjectPage();
                                $value = $subjPage->getPrefixedUrl();
                                break;
-                       case 'pipetrick':
-                               $text = $this->mTitle->getText();
-                               $value = $this->getPipeTrickText( $text );
-                               break;
-                       case 'pipetricke':
-                               $text = $this->mTitle->getText();
-                               $value = wfUrlEncode( str_replace( ' ', '_', $this->getPipeTrickText( $text ) ) );
-                               break;
                        case 'revisionid':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision...\n" );
                                $value = $this->mRevisionId;
                                break;
                        case 'revisionday':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONDAY}} used, setting vary-revision...\n" );
                                $value = intval( substr( $this->getRevisionTimestamp(), 6, 2 ) );
                                break;
                        case 'revisionday2':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONDAY2}} used, setting vary-revision...\n" );
                                $value = substr( $this->getRevisionTimestamp(), 6, 2 );
                                break;
                        case 'revisionmonth':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONMONTH}} used, setting vary-revision...\n" );
+                               $value = substr( $this->getRevisionTimestamp(), 4, 2 );
+                               break;
+                       case 'revisionmonth1':
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
+                               $this->mOutput->setFlag( 'vary-revision' );
+                               wfDebug( __METHOD__ . ": {{REVISIONMONTH1}} used, setting vary-revision...\n" );
                                $value = intval( substr( $this->getRevisionTimestamp(), 4, 2 ) );
                                break;
                        case 'revisionyear':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONYEAR}} used, setting vary-revision...\n" );
                                $value = substr( $this->getRevisionTimestamp(), 0, 4 );
                                break;
                        case 'revisiontimestamp':
-                               // Let the edit saving system know we should parse the page
-                               // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONTIMESTAMP}} used, setting vary-revision...\n" );
                                $value = $this->getRevisionTimestamp();
                                break;
                        case 'revisionuser':
-                                // Let the edit saving system know we should parse the page
-                                // *after* a revision ID has been assigned. This is for null edits.
+                               # Let the edit saving system know we should parse the page
+                               # *after* a revision ID has been assigned. This is for null edits.
                                $this->mOutput->setFlag( 'vary-revision' );
                                wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-revision...\n" );
                                $value = $this->getRevisionUser();
                                break;
                        case 'namespace':
-                               $value = str_replace('_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) );
+                               $value = str_replace( '_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) );
                                break;
                        case 'namespacee':
                                $value = wfUrlencode( $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
                                break;
                        case 'talkspace':
-                               $value = $this->mTitle->canTalk() ? str_replace('_',' ',$this->mTitle->getTalkNsText()) : '';
+                               $value = $this->mTitle->canTalk() ? str_replace( '_',' ',$this->mTitle->getTalkNsText() ) : '';
                                break;
                        case 'talkspacee':
                                $value = $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
@@ -2583,8 +2706,8 @@ class Parser
                                $value = $wgContLang->formatNum( gmdate( 'H', $ts ), true );
                                break;
                        case 'currentweek':
-                               // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
-                               // int to remove the padding
+                               # @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
+                               # int to remove the padding
                                $value = $wgContLang->formatNum( (int)gmdate( 'W', $ts ) );
                                break;
                        case 'currentdow':
@@ -2603,8 +2726,8 @@ class Parser
                                $value = $wgContLang->formatNum( $localHour, true );
                                break;
                        case 'localweek':
-                               // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
-                               // int to remove the padding
+                               # @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
+                               # int to remove the padding
                                $value = $wgContLang->formatNum( (int)$localWeek );
                                break;
                        case 'localdow':
@@ -2626,7 +2749,7 @@ class Parser
                                $value = $wgContLang->formatNum( SiteStats::pages() );
                                break;
                        case 'numberofadmins':
-                               $value = $wgContLang->formatNum( SiteStats::numberingroup('sysop') );
+                               $value = $wgContLang->formatNum( SiteStats::numberingroup( 'sysop' ) );
                                break;
                        case 'numberofedits':
                                $value = $wgContLang->formatNum( SiteStats::edits() );
@@ -2660,10 +2783,11 @@ class Parser
                                return $wgContLanguageCode;
                        default:
                                $ret = null;
-                               if ( wfRunHooks( 'ParserGetVariableValueSwitch', array( &$this, &$this->mVarCache, &$index, &$ret, &$frame ) ) )
+                               if ( wfRunHooks( 'ParserGetVariableValueSwitch', array( &$this, &$this->mVarCache, &$index, &$ret, &$frame ) ) ) {
                                        return $ret;
-                               else
+                               } else {
                                        return null;
+                               }
                }
 
                if ( $index )
@@ -2673,7 +2797,7 @@ class Parser
        }
 
        /**
-        * initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers 
+        * initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers
         *
         * @private
         */
@@ -2691,8 +2815,8 @@ class Parser
         * Preprocess some wikitext and return the document tree.
         * This is the ghost of replace_variables().
         *
-        * @param string $text The text to parse
-        * @param integer flags Bitwise combination of:
+        * @param $text String: The text to parse
+        * @param $flags Integer: bitwise combination of:
         *          self::PTD_FOR_INCLUSION    Handle <noinclude>/<includeonly> as if the text is being
         *                                     included. Default is to assume a direct page view.
         *
@@ -2709,12 +2833,12 @@ class Parser
         *
         * @private
         */
-       function preprocessToDom ( $text, $flags = 0 ) {
+       function preprocessToDom( $text, $flags = 0 ) {
                $dom = $this->getPreprocessor()->preprocessToObj( $text, $flags );
                return $dom;
        }
 
-       /*
+       /**
         * Return a three-element array: leading whitespace, string contents, trailing whitespace
         */
        public static function splitWhitespace( $s ) {
@@ -2740,11 +2864,11 @@ class Parser
         *  self::OT_PREPROCESS: templates but not extension tags
         *  self::OT_HTML: all templates and extension tags
         *
-        * @param string $tex The text to transform
-        * @param PPFrame $frame Object describing the arguments passed to the template.
+        * @param $text String: the text to transform
+        * @param $frame PPFrame Object describing the arguments passed to the template.
         *        Arguments may also be provided as an associative array, as was the usual case before MW1.12.
         *        Providing arguments this way may be useful for extensions wishing to perform variable replacement explicitly.
-        * @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion
+        * @param $argsOnly Boolean: only do argument (triple-brace) expansion, not double-brace expansion
         * @private
         */
        function replaceVariables( $text, $frame = false, $argsOnly = false ) {
@@ -2758,7 +2882,7 @@ class Parser
                        $frame = $this->getPreprocessor()->newFrame();
                } elseif ( !( $frame instanceof PPFrame ) ) {
                        wfDebug( __METHOD__." called using plain parameters instead of a PPFrame instance. Creating custom frame.\n" );
-                       $frame = $this->getPreprocessor()->newCustomFrame($frame);
+                       $frame = $this->getPreprocessor()->newCustomFrame( $frame );
                }
 
                $dom = $this->preprocessToDom( $text );
@@ -2769,11 +2893,11 @@ class Parser
                return $text;
        }
 
-       /// Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
+       # Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
        static function createAssocArgs( $args ) {
                $assocArgs = array();
                $index = 1;
-               foreach( $args as $arg ) {
+               foreach ( $args as $arg ) {
                        $eqpos = strpos( $arg, '=' );
                        if ( $eqpos === false ) {
                                $assocArgs[$index++] = $arg;
@@ -2796,15 +2920,22 @@ class Parser
         * Warn the user when a parser limitation is reached
         * Will warn at most once the user per limitation type
         *
-        * @param string $limitationType, should be one of:
-        *   'expensive-parserfunction' (corresponding messages: 'expensive-parserfunction-warning', 'expensive-parserfunction-category')
-        *   'post-expand-template-argument' (corresponding messages: 'post-expand-template-argument-warning', 'post-expand-template-argument-category')
-        *   'post-expand-template-inclusion' (corresponding messages: 'post-expand-template-inclusion-warning', 'post-expand-template-inclusion-category')
-        * @params int $current, $max When an explicit limit has been
+        * @param $limitationType String: should be one of:
+        *   'expensive-parserfunction' (corresponding messages:
+        *       'expensive-parserfunction-warning',
+        *       'expensive-parserfunction-category')
+        *   'post-expand-template-argument' (corresponding messages:
+        *       'post-expand-template-argument-warning',
+        *       'post-expand-template-argument-category')
+        *   'post-expand-template-inclusion' (corresponding messages:
+        *       'post-expand-template-inclusion-warning',
+        *       'post-expand-template-inclusion-category')
+        * @param $current Current value
+        * @param $max Maximum allowed, when an explicit limit has been
         *       exceeded, provide the values (optional)
         */
        function limitationWarn( $limitationType, $current=null, $max=null) {
-               //does no harm if $current and $max are present but are unnecessary for the message
+               does no harm if $current and $max are present but are unnecessary for the message
                $warning = wfMsgExt( "$limitationType-warning", array( 'parsemag', 'escape' ), $current, $max );
                $this->mOutput->addWarning( $warning );
                $this->addTrackingCategory( "$limitationType-category" );
@@ -2814,12 +2945,12 @@ class Parser
         * Return the text of a template, after recursively
         * replacing any variables or templates within the template.
         *
-        * @param array $piece The parts of the template
+        * @param $piece Array: the parts of the template
         *  $piece['title']: the title, i.e. the part before the |
         *  $piece['parts']: the parameter array
         *  $piece['lineStart']: whether the brace was at the start of a line
-        * @param PPFrame The current frame, contains template arguments
-        * @return string the text of the template
+        * @param $frame PPFrame The current frame, contains template arguments
+        * @return String: the text of the template
         * @private
         */
        function braceSubstitution( $piece, $frame ) {
@@ -2848,7 +2979,7 @@ class Parser
                $originalTitle = $part1;
 
                # $args is a list of argument nodes, starting from index 0, not including $part1
-               $args = (null == $piece['parts']) ? array() : $piece['parts'];
+               $args = ( null == $piece['parts'] ) ? array() : $piece['parts'];
                wfProfileOut( __METHOD__.'-setup' );
 
                # SUBST
@@ -2859,8 +2990,7 @@ class Parser
 
                        # Possibilities for substMatch: "subst", "safesubst" or FALSE
                        # Decide whether to expand template or keep wikitext as-is.
-                       if ( $this->ot['wiki'] )
-                       {
+                       if ( $this->ot['wiki'] ) {
                                if ( $substMatch === false ) {
                                        $literal = true;  # literal when in PST with no prefix
                                } else {
@@ -2885,8 +3015,9 @@ class Parser
                        $id = $this->mVariables->matchStartToEnd( $part1 );
                        if ( $id !== false ) {
                                $text = $this->getVariableValue( $id, $frame );
-                               if (MagicWord::getCacheTTL($id)>-1)
+                               if ( MagicWord::getCacheTTL( $id ) > -1 ) {
                                        $this->mOutput->mContainsOldMagic = true;
+                               }
                                $found = true;
                        }
                }
@@ -2967,8 +3098,8 @@ class Parser
                                                        unset( $result[0] );
                                                }
 
-                                               // Extract flags into the local scope
-                                               // This allows callers to set flags such as nowiki, found, etc.
+                                               # Extract flags into the local scope
+                                               # This allows callers to set flags such as nowiki, found, etc.
                                                extract( $result );
                                        } else {
                                                $text = $result;
@@ -2989,21 +3120,23 @@ class Parser
                        # Split the title into page and subpage
                        $subpage = '';
                        $part1 = $this->maybeDoSubpageLink( $part1, $subpage );
-                       if ($subpage !== '') {
+                       if ( $subpage !== '' ) {
                                $ns = $this->mTitle->getNamespace();
                        }
                        $title = Title::newFromText( $part1, $ns );
                        if ( $title ) {
                                $titleText = $title->getPrefixedText();
                                # Check for language variants if the template is not found
-                               if($wgContLang->hasVariants() && $title->getArticleID() == 0){
+                               if ( $wgContLang->hasVariants() && $title->getArticleID() == 0 ) {
                                        $wgContLang->findVariantLink( $part1, $title, true );
                                }
                                # Do recursion depth check
                                $limit = $this->mOptions->getMaxTemplateDepth();
                                if ( $frame->depth >= $limit ) {
                                        $found = true;
-                                       $text = '<span class="error">' . wfMsgForContent( 'parser-template-recursion-depth-warning', $limit ) . '</span>';
+                                       $text = '<span class="error">'
+                                               . wfMsgForContent( 'parser-template-recursion-depth-warning', $limit )
+                                               . '</span>';
                                }
                        }
                }
@@ -3012,15 +3145,18 @@ class Parser
                if ( !$found && $title ) {
                        wfProfileIn( __METHOD__ . '-loadtpl' );
                        if ( !$title->isExternal() ) {
-                               if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html'] ) {
+                               if ( $title->getNamespace() == NS_SPECIAL
+                                       && $this->mOptions->getAllowSpecialInclusion()
+                                       && $this->ot['html'] )
+                               {
                                        $text = SpecialPage::capturePath( $title );
                                        if ( is_string( $text ) ) {
                                                $found = true;
                                                $isHTML = true;
                                                $this->disableCache();
                                        }
-                               } else if ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) {
-                                       $found = false; //access denied
+                               } elseif ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) {
+                                       $found = false; access denied
                                        wfDebug( __METHOD__.": template inclusion denied for " . $title->getPrefixedDBkey() );
                                } else {
                                        list( $text, $title ) = $this->getTemplateDom( $title );
@@ -3036,13 +3172,13 @@ class Parser
                                        $found = true;
                                }
                        } elseif ( $title->isTrans() ) {
-                               // Interwiki transclusion
+                               # Interwiki transclusion
                                if ( $this->ot['html'] && !$forceRawInterwiki ) {
                                        $text = $this->interwikiTransclude( $title, 'render' );
                                        $isHTML = true;
                                } else {
                                        $text = $this->interwikiTransclude( $title, 'raw' );
-                                       // Preprocess it like a template
+                                       # Preprocess it like a template
                                        $text = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION );
                                        $isChildObj = true;
                                }
@@ -3097,22 +3233,31 @@ class Parser
                # immediately preceding headings
                if ( $isHTML ) {
                        $text = "\n\n" . $this->insertStripItem( $text );
-               }
-               # Escape nowiki-style return values
-               elseif ( $nowiki && ( $this->ot['html'] || $this->ot['pre'] ) ) {
+               } elseif ( $nowiki && ( $this->ot['html'] || $this->ot['pre'] ) ) {
+                       # Escape nowiki-style return values
                        $text = wfEscapeWikiText( $text );
-               }
-               # Bug 529: if the template begins with a table or block-level
-               # element, it should be treated as beginning a new line.
-               # This behaviour is somewhat controversial.
-               elseif ( is_string( $text ) && !$piece['lineStart'] && preg_match('/^(?:{\\||:|;|#|\*)/', $text)) /*}*/{
+               } elseif ( is_string( $text )
+                       && !$piece['lineStart']
+                       && preg_match( '/^(?:{\\||:|;|#|\*)/', $text ) )
+               {
+                       # Bug 529: if the template begins with a table or block-level
+                       # element, it should be treated as beginning a new line.
+                       # This behaviour is somewhat controversial.
                        $text = "\n" . $text;
                }
 
                if ( is_string( $text ) && !$this->incrementIncludeSize( 'post-expand', strlen( $text ) ) ) {
                        # Error, oversize inclusion
-                       $text = "[[$originalTitle]]" .
-                               $this->insertStripItem( '<!-- WARNING: template omitted, post-expand include size too large -->' );
+                       if ( $titleText !== false ) {
+                               # Make a working, properly escaped link if possible (bug 23588)
+                               $text = "[[:$titleText]]";
+                       } else {
+                               # This will probably not be a working link, but at least it may
+                               # provide some hint of where the problem is
+                               preg_replace( '/^:/', '', $originalTitle );
+                               $text = "[[:$originalTitle]]";
+                       }
+                       $text .= $this->insertStripItem( '<!-- WARNING: template omitted, post-expand include size too large -->' );
                        $this->limitationWarn( 'post-expand-template-inclusion' );
                }
 
@@ -3143,7 +3288,7 @@ class Parser
                        return array( $this->mTplDomCache[$titleText], $title );
                }
 
-               // Cache miss, go to the database
+               # Cache miss, go to the database
                list( $text, $title ) = $this->fetchTemplateAndTitle( $title );
 
                if ( $text === false ) {
@@ -3154,7 +3299,7 @@ class Parser
                $dom = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION );
                $this->mTplDomCache[ $titleText ] = $dom;
 
-               if (! $title->equals($cacheTitle)) {
+               if ( !$title->equals( $cacheTitle ) ) {
                        $this->mTplRedirCache[$cacheTitle->getPrefixedDBkey()] =
                                array( $title->getNamespace(),$cdb = $title->getDBkey() );
                }
@@ -3175,11 +3320,11 @@ class Parser
                                $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
                        }
                }
-               return array($text,$finalTitle);
+               return array( $text, $finalTitle );
        }
 
        function fetchTemplate( $title ) {
-               $rv = $this->fetchTemplateAndTitle($title);
+               $rv = $this->fetchTemplateAndTitle( $title );
                return $rv[0];
        }
 
@@ -3192,13 +3337,13 @@ class Parser
                $finalTitle = $title;
                $deps = array();
 
-               // Loop to fetch the article, with up to 1 redirect
+               # Loop to fetch the article, with up to 1 redirect
                for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {
                        # Give extensions a chance to select the revision instead
-                       $id = false; // Assume current
+                       $id = false; # Assume current
                        wfRunHooks( 'BeforeParserFetchTemplateAndtitle', array( $parser, &$title, &$skip, &$id ) );
 
-                       if( $skip ) {
+                       if ( $skip ) {
                                $text = false;
                                $deps[] = array(
                                        'title' => $title,
@@ -3208,8 +3353,8 @@ class Parser
                        }
                        $rev = $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title );
                        $rev_id = $rev ? $rev->getId() : 0;
-                       // If there is no current revision, there is no page
-                       if( $id === false && !$rev ) {
+                       # If there is no current revision, there is no page
+                       if ( $id === false && !$rev ) {
                                $linkCache = LinkCache::singleton();
                                $linkCache->addBadLinkObj( $title );
                        }
@@ -3219,13 +3364,13 @@ class Parser
                                'page_id' => $title->getArticleID(),
                                'rev_id' => $rev_id );
 
-                       if( $rev ) {
+                       if ( $rev ) {
                                $text = $rev->getText();
-                       } elseif( $title->getNamespace() == NS_MEDIAWIKI ) {
+                       } elseif ( $title->getNamespace() == NS_MEDIAWIKI ) {
                                global $wgContLang;
                                $message = $wgContLang->lcfirst( $title->getText() );
                                $text = wfMsgForContentNoTrans( $message );
-                               if( wfEmptyMsg( $message, $text ) ) {
+                               if ( wfEmptyMsg( $message, $text ) ) {
                                        $text = false;
                                        break;
                                }
@@ -3235,7 +3380,7 @@ class Parser
                        if ( $text === false ) {
                                break;
                        }
-                       // Redirect?
+                       # Redirect?
                        $finalTitle = $title;
                        $title = Title::newFromRedirect( $text );
                }
@@ -3251,35 +3396,39 @@ class Parser
        function interwikiTransclude( $title, $action ) {
                global $wgEnableScaryTranscluding;
 
-               if (!$wgEnableScaryTranscluding)
+               if ( !$wgEnableScaryTranscluding ) {
                        return wfMsg('scarytranscludedisabled');
+               }
 
                $url = $title->getFullUrl( "action=$action" );
 
-               if (strlen($url) > 255)
-                       return wfMsg('scarytranscludetoolong');
-               return $this->fetchScaryTemplateMaybeFromCache($url);
+               if ( strlen( $url ) > 255 ) {
+                       return wfMsg( 'scarytranscludetoolong' );
+               }
+               return $this->fetchScaryTemplateMaybeFromCache( $url );
        }
 
-       function fetchScaryTemplateMaybeFromCache($url) {
+       function fetchScaryTemplateMaybeFromCache( $url ) {
                global $wgTranscludeCacheExpiry;
-               $dbr = wfGetDB(DB_SLAVE);
+               $dbr = wfGetDB( DB_SLAVE );
                $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
-               $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
-                               array('tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
-               if ($obj) {
+               $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ),
+                               array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
+               if ( $obj ) {
                        return $obj->tc_contents;
                }
 
-               $text = Http::get($url);
-               if (!$text)
-                       return wfMsg('scarytranscludefailed', $url);
+               $text = Http::get( $url );
+               if ( !$text ) {
+                       return wfMsg( 'scarytranscludefailed', $url );
+               }
 
-               $dbw = wfGetDB(DB_MASTER);
-               $dbw->replace('transcache', array('tc_url'), array(
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'transcache', array('tc_url'), array(
                        'tc_url' => $url,
                        'tc_time' => $dbw->timestamp( time() ),
-                       'tc_contents' => $text));
+                       'tc_contents' => $text)
+               );
                return $text;
        }
 
@@ -3333,13 +3482,13 @@ class Parser
         * Return the text to be used for a given extension tag.
         * This is the ghost of strip().
         *
-        * @param array $params Associative array of parameters:
+        * @param $params Associative array of parameters:
         *     name       PPNode for the tag name
         *     attr       PPNode for unparsed text where tag attributes are thought to be
         *     attributes Optional associative array of parsed attributes
         *     inner      Contents of extension element
         *     noClose    Original text did not have a close tag
-        * @param PPFrame $frame
+        * @param $frame PPFrame
         */
        function extensionSubstitution( $params, $frame ) {
                global $wgRawHtml, $wgContLang;
@@ -3347,7 +3496,7 @@ class Parser
                $name = $frame->expand( $params['name'] );
                $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
                $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
-               $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
+               $marker = "{$this->mUniqPrefix}-$name-" . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX;
 
                $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower($name)] ) &&
                        ( $this->ot['html'] || $this->ot['pre'] );
@@ -3363,27 +3512,27 @@ class Parser
                                $attributes = $attributes + $params['attributes'];
                        }
 
-                       if( isset( $this->mTagHooks[$name] ) ) {
+                       if ( isset( $this->mTagHooks[$name] ) ) {
                                # Workaround for PHP bug 35229 and similar
                                if ( !is_callable( $this->mTagHooks[$name] ) ) {
                                        throw new MWException( "Tag hook for $name is not callable\n" );
                                }
                                $output = call_user_func_array( $this->mTagHooks[$name],
                                        array( $content, $attributes, $this, $frame ) );
-                       } elseif( isset( $this->mFunctionTagHooks[$name] ) ) {
+                       } elseif ( isset( $this->mFunctionTagHooks[$name] ) ) {
                                list( $callback, $flags ) = $this->mFunctionTagHooks[$name];
-                               if( !is_callable( $callback ) )
+                               if ( !is_callable( $callback ) ) {
                                        throw new MWException( "Tag hook for $name is not callable\n" );
+                               }
 
-                               $output = call_user_func_array( $callback,
-                                       array( &$this, $frame, $content, $attributes ) );
+                               $output = call_user_func_array( $callback, array( &$this, $frame, $content, $attributes ) );
                        } else {
                                $output = '<span class="error">Invalid tag extension name: ' .
                                        htmlspecialchars( $name ) . '</span>';
                        }
 
                        if ( is_array( $output ) ) {
-                               // Extract flags to local scope (to override $markerType)
+                               # Extract flags to local scope (to override $markerType)
                                $flags = $output;
                                $output = $flags[0];
                                unset( $flags[0] );
@@ -3407,7 +3556,7 @@ class Parser
                        }
                }
 
-               if( $markerType === 'none' ) {
+               if ( $markerType === 'none' ) {
                        return $output;
                } elseif ( $markerType === 'nowiki' ) {
                        $this->mStripState->nowiki->setPair( $marker, $output );
@@ -3422,9 +3571,9 @@ class Parser
        /**
         * Increment an include size counter
         *
-        * @param string $type The type of expansion
-        * @param integer $size The size of the text
-        * @return boolean False if this inclusion would take it over the maximum, true otherwise
+        * @param $type String: the type of expansion
+        * @param $size Integer: the size of the text
+        * @return Boolean: false if this inclusion would take it over the maximum, true otherwise
         */
        function incrementIncludeSize( $type, $size ) {
                if ( $this->mIncludeSizes[$type] + $size > $this->mOptions->getMaxIncludeSize( $type ) ) {
@@ -3438,12 +3587,12 @@ class Parser
        /**
         * Increment the expensive function count
         *
-        * @return boolean False if the limit has been exceeded
+        * @return Boolean: false if the limit has been exceeded
         */
        function incrementExpensiveFunctionCount() {
                global $wgExpensiveParserFunctionLimit;
                $this->mExpensiveFunctionCount++;
-               if($this->mExpensiveFunctionCount <= $wgExpensiveParserFunctionLimit) {
+               if ( $this->mExpensiveFunctionCount <= $wgExpensiveParserFunctionLimit ) {
                        return true;
                }
                return false;
@@ -3456,20 +3605,20 @@ class Parser
        function doDoubleUnderscore( $text ) {
                wfProfileIn( __METHOD__ );
 
-               // The position of __TOC__ needs to be recorded
+               # The position of __TOC__ needs to be recorded
                $mw = MagicWord::get( 'toc' );
-               if( $mw->match( $text ) ) {
+               if ( $mw->match( $text ) ) {
                        $this->mShowToc = true;
                        $this->mForceTocPosition = true;
 
-                       // Set a placeholder. At the end we'll fill it in with the TOC.
+                       # Set a placeholder. At the end we'll fill it in with the TOC.
                        $text = $mw->replace( '<!--MWTOC-->', $text, 1 );
 
-                       // Only keep the first one.
+                       # Only keep the first one.
                        $text = $mw->replace( '', $text );
                }
 
-               // Now match and remove the rest of them
+               # Now match and remove the rest of them
                $mwa = MagicWord::getDoubleUnderscoreArray();
                $this->mDoubleUnderscores = $mwa->matchAndRemove( $text );
 
@@ -3487,11 +3636,11 @@ class Parser
                #
                # FIXME (bug 14899): __INDEX__ always overrides __NOINDEX__ here!  This
                # is not desirable, the last one on the page should win.
-               if( isset( $this->mDoubleUnderscores['noindex'] ) && $this->mTitle->canUseNoindex() ) {
+               if ( isset( $this->mDoubleUnderscores['noindex'] ) && $this->mTitle->canUseNoindex() ) {
                        $this->mOutput->setIndexPolicy( 'noindex' );
                        $this->addTrackingCategory( 'noindex-category' );
                }
-               if( isset( $this->mDoubleUnderscores['index'] ) && $this->mTitle->canUseNoindex() ){
+               if ( isset( $this->mDoubleUnderscores['index'] ) && $this->mTitle->canUseNoindex() ) {
                        $this->mOutput->setIndexPolicy( 'index' );
                        $this->addTrackingCategory( 'index-category' );
                }
@@ -3503,14 +3652,17 @@ class Parser
        /**
         * Add a tracking category, getting the title from a system message,
         * or print a debug message if the title is invalid.
-        * @param $msg String message key
-        * @return Bool whether the addition was successful
+        *
+        * @param $msg String: message key
+        * @return Boolean: whether the addition was successful
         */
-       protected function addTrackingCategory( $msg ){
+       protected function addTrackingCategory( $msg ) {
                $cat = wfMsgForContent( $msg );
 
                # Allow tracking categories to be disabled by setting them to "-"
-               if( $cat === '-' ) return false;
+               if ( $cat === '-' ) {
+                       return false;
+               }
 
                $containerCategory = Title::makeTitleSafe( NS_CATEGORY, $cat );
                if ( $containerCategory ) {
@@ -3532,9 +3684,9 @@ class Parser
         * It loops through all headlines, collects the necessary data, then splits up the
         * string and re-inserts the newly formatted headlines.
         *
-        * @param string $text
-        * @param string $origText Original, untouched wikitext
-        * @param boolean $isMain
+        * @param $text String
+        * @param $origText String: original, untouched wikitext
+        * @param $isMain Boolean
         * @private
         */
        function formatHeadings( $text, $origText, $isMain=true ) {
@@ -3543,8 +3695,8 @@ class Parser
                $doNumberHeadings = $this->mOptions->getNumberHeadings();
                $showEditLink = $this->mOptions->getEditSection();
 
-               // Do not call quickUserCan unless necessary
-               if( $showEditLink && !$this->mTitle->quickUserCan( 'edit' ) ) {
+               # Do not call quickUserCan unless necessary
+               if ( $showEditLink && !$this->mTitle->quickUserCan( 'edit' ) ) {
                        $showEditLink = 0;
                }
 
@@ -3561,7 +3713,7 @@ class Parser
                # if there are fewer than 4 headlines in the article, do not show TOC
                # unless it's been explicitly enabled.
                $enoughToc = $this->mShowToc &&
-                       (($numMatches >= 4) || $this->mForceTocPosition);
+                       ( ( $numMatches >= 4 ) || $this->mForceTocPosition );
 
                # Allow user to stipulate that a page should have a "new section"
                # link added via __NEWSECTIONLINK__
@@ -3611,20 +3763,20 @@ class Parser
                $byteOffset = 0;
                $tocraw = array();
 
-               foreach( $matches[3] as $headline ) {
+               foreach ( $matches[3] as $headline ) {
                        $isTemplate = false;
                        $titleText = false;
                        $sectionIndex = false;
                        $numbering = '';
                        $markerMatches = array();
-                       if (preg_match("/^$markerRegex/", $headline, $markerMatches)) {
+                       if ( preg_match("/^$markerRegex/", $headline, $markerMatches ) ) {
                                $serial = $markerMatches[1];
                                list( $titleText, $sectionIndex ) = $this->mHeadings[$serial];
-                               $isTemplate = ($titleText != $baseTitleText);
-                               $headline = preg_replace("/^$markerRegex/", "", $headline);
+                               $isTemplate = ( $titleText != $baseTitleText );
+                               $headline = preg_replace( "/^$markerRegex/", "", $headline );
                        }
 
-                       if( $toclevel ) {
+                       if ( $toclevel ) {
                                $prevlevel = $level;
                                $prevtoclevel = $toclevel;
                        }
@@ -3634,30 +3786,30 @@ class Parser
                                # Increase TOC level
                                $toclevel++;
                                $sublevelCount[$toclevel] = 0;
-                               if( $toclevel<$wgMaxTocLevel ) {
+                               if ( $toclevel<$wgMaxTocLevel ) {
                                        $prevtoclevel = $toclevel;
                                        $toc .= $sk->tocIndent();
                                        $numVisible++;
                                }
-                       }
-                       elseif ( $level < $prevlevel && $toclevel > 1 ) {
+                       } elseif ( $level < $prevlevel && $toclevel > 1 ) {
                                # Decrease TOC level, find level to jump to
 
-                               for ($i = $toclevel; $i > 0; $i--) {
+                               for ( $i = $toclevel; $i > 0; $i-- ) {
                                        if ( $levelCount[$i] == $level ) {
                                                # Found last matching level
                                                $toclevel = $i;
                                                break;
-                                       }
-                                       elseif ( $levelCount[$i] < $level ) {
+                                       } elseif ( $levelCount[$i] < $level ) {
                                                # Found first matching level below current level
                                                $toclevel = $i + 1;
                                                break;
                                        }
                                }
-                               if( $i == 0 ) $toclevel = 1;
-                               if( $toclevel<$wgMaxTocLevel ) {
-                                       if($prevtoclevel < $wgMaxTocLevel) {
+                               if ( $i == 0 ) {
+                                       $toclevel = 1;
+                               }
+                               if ( $toclevel<$wgMaxTocLevel ) {
+                                       if ( $prevtoclevel < $wgMaxTocLevel ) {
                                                # Unindent only if the previous toc level was shown :p
                                                $toc .= $sk->tocUnindent( $prevtoclevel - $toclevel );
                                                $prevtoclevel = $toclevel;
@@ -3665,10 +3817,9 @@ class Parser
                                                $toc .= $sk->tocLineEnd();
                                        }
                                }
-                       }
-                       else {
+                       } else {
                                # No change in level, end TOC line
-                               if( $toclevel<$wgMaxTocLevel ) {
+                               if ( $toclevel<$wgMaxTocLevel ) {
                                        $toc .= $sk->tocLineEnd();
                                }
                        }
@@ -3679,8 +3830,8 @@ class Parser
                        @$sublevelCount[$toclevel]++;
                        $dot = 0;
                        for( $i = 1; $i <= $toclevel; $i++ ) {
-                               if( !empty( $sublevelCount[$i] ) ) {
-                                       if( $dot ) {
+                               if ( !empty( $sublevelCount[$i] ) ) {
+                                       if ( $dot ) {
                                                $numbering .= '.';
                                        }
                                        $numbering .= $wgContLang->formatNum( $sublevelCount[$i] );
@@ -3701,15 +3852,14 @@ class Parser
                        # Strip out HTML (other than plain <sup> and <sub>: bug 8393)
                        $tocline = preg_replace(
                                array( '#<(?!/?(sup|sub)).*?'.'>#', '#<(/?(sup|sub)).*?'.'>#' ),
-                               array( '',                          '<$1>'),
+                               array( '',                          '<$1>' ),
                                $safeHeadline
                        );
                        $tocline = trim( $tocline );
 
                        # For the anchor, strip out HTML-y stuff period
                        $safeHeadline = preg_replace( '/<.*?'.'>/', '', $safeHeadline );
-                       $safeHeadline = preg_replace( '/[ _]+/', ' ', $safeHeadline );
-                       $safeHeadline = trim( $safeHeadline );
+                       $safeHeadline = Sanitizer::normalizeSectionNameWhitespace( $safeHeadline );
 
                        # Save headline for section edit hint before it's escaped
                        $headlineHint = $safeHeadline;
@@ -3762,7 +3912,7 @@ class Parser
                        }
 
                        # Don't number the heading if it is the only one (looks silly)
-                       if( $doNumberHeadings && count( $matches[3] ) > 1) {
+                       if ( $doNumberHeadings && count( $matches[3] ) > 1) {
                                # the two are different if the line contains a link
                                $headline = $numbering . ' ' . $headline;
                        }
@@ -3776,9 +3926,9 @@ class Parser
                        if ( $legacyHeadline !== false && $refers[$legacyArrayKey] > 1 ) {
                                $legacyAnchor .= '_' . $refers[$legacyArrayKey];
                        }
-                       if( $enoughToc && ( !isset($wgMaxTocLevel) || $toclevel<$wgMaxTocLevel ) ) {
-                               $toc .= $sk->tocLine($anchor, $tocline,
-                                       $numbering, $toclevel, ($isTemplate ? false : $sectionIndex));
+                       if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
+                               $toc .= $sk->tocLine( $anchor, $tocline,
+                                       $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
                        }
 
                        # Add the section to the section tree
@@ -3798,20 +3948,20 @@ class Parser
                                'level' => $level,
                                'line' => $tocline,
                                'number' => $numbering,
-                               'index' => ($isTemplate ? 'T-' : '' ) . $sectionIndex,
+                               'index' => ( $isTemplate ? 'T-' : '' ) . $sectionIndex,
                                'fromtitle' => $titleText,
                                'byteoffset' => ( $isTemplate ? null : $byteOffset ),
                                'anchor' => $anchor,
                        );
 
                        # give headline the correct <h#> tag
-                       if( $showEditLink && $sectionIndex !== false ) {
-                               if( $isTemplate ) {
+                       if ( $showEditLink && $sectionIndex !== false ) {
+                               if ( $isTemplate ) {
                                        # Put a T flag in the section identifier, to indicate to extractSections()
                                        # that sections inside <includeonly> should be counted.
-                                       $editlink = $sk->doEditSectionLink(Title::newFromText( $titleText ), "T-$sectionIndex");
+                                       $editlink = $sk->doEditSectionLink( Title::newFromText( $titleText ), "T-$sectionIndex" );
                                } else {
-                                       $editlink = $sk->doEditSectionLink($this->mTitle, $sectionIndex, $headlineHint);
+                                       $editlink = $sk->doEditSectionLink( $this->mTitle, $sectionIndex, $headlineHint );
                                }
                        } else {
                                $editlink = '';
@@ -3826,12 +3976,12 @@ class Parser
                $this->setOutputType( $oldType );
 
                # Never ever show TOC if no headers
-               if( $numVisible < 1 ) {
+               if ( $numVisible < 1 ) {
                        $enoughToc = false;
                }
 
-               if( $enoughToc ) {
-                       if( $prevtoclevel > 0 && $prevtoclevel < $wgMaxTocLevel ) {
+               if ( $enoughToc ) {
+                       if ( $prevtoclevel > 0 && $prevtoclevel < $wgMaxTocLevel ) {
                                $toc .= $sk->tocUnindent( $prevtoclevel - 1 );
                        }
                        $toc = $sk->tocList( $toc );
@@ -3847,8 +3997,8 @@ class Parser
                $blocks = preg_split( '/<H[1-6].*?' . '>.*?<\/H[1-6]>/i', $text );
                $i = 0;
 
-               foreach( $blocks as $block ) {
-                       if( $showEditLink && $headlineCount > 0 && $i == 0 && $block !== "\n" ) {
+               foreach ( $blocks as $block ) {
+                       if ( $showEditLink && $headlineCount > 0 && $i == 0 && $block !== "\n" ) {
                                # This is the [edit] link that appears for the top block of text when
                                # section editing is enabled
 
@@ -3857,17 +4007,17 @@ class Parser
                                # $full .= $sk->editSectionLink(0);
                        }
                        $full .= $block;
-                       if( $enoughToc && !$i && $isMain && !$this->mForceTocPosition ) {
+                       if ( $enoughToc && !$i && $isMain && !$this->mForceTocPosition ) {
                                # Top anchor now in skin
                                $full = $full.$toc;
                        }
 
-                       if( !empty( $head[$i] ) ) {
+                       if ( !empty( $head[$i] ) ) {
                                $full .= $head[$i];
                        }
                        $i++;
                }
-               if( $this->mForceTocPosition ) {
+               if ( $this->mForceTocPosition ) {
                        return str_replace( '<!--MWTOC-->', $toc, $full );
                } else {
                        return $full;
@@ -3879,12 +4029,13 @@ class Parser
         * $section in $tree1 and its descendants with the sections in $tree2.
         * Note that in the returned section tree, only the 'index' and
         * 'byteoffset' fields are guaranteed to be correct.
-        * @param $tree1 array Section tree from ParserOutput::getSectons()
-       *  @param $tree2 array Section tree
-        * @param $section int Section index
-        * @param $title Title Title both section trees come from
-        * @param $len2 int Length of the original wikitext for $tree2
-        * @return array Merged section tree
+        *
+        * @param $tree1 Array: section tree from ParserOutput::getSectons()
+       *  @param $tree2 Array: section tree
+        * @param $section Integer: section index
+        * @param $title Title: Title both section trees come from
+        * @param $len2 Integer: length of the original wikitext for $tree2
+        * @return Array: merged section tree
         */
        public static function mergeSectionTrees( $tree1, $tree2, $section, $title, $len2 ) {
                global $wgContLang;
@@ -3897,22 +4048,24 @@ class Parser
                $titletext = $title->getPrefixedDBkey();
                foreach ( $tree1 as $s ) {
                        if ( $targetLevel !== false ) {
-                               if ( $s['level'] <= $targetLevel )
-                                       // We've skipped enough
+                               if ( $s['level'] <= $targetLevel ) {
+                                       # We've skipped enough
                                        $targetLevel = false;
-                               else
+                               } else {
                                        continue;
+                               }
                        }
                        if ( $s['index'] != $section ||
                                        $s['fromtitle'] != $titletext ) {
                                self::incrementNumbering( $numbering,
                                        $s['toclevel'], $lastLevel );
 
-                               // Rewrite index, byteoffset and number
+                               # Rewrite index, byteoffset and number
                                if ( $s['fromtitle'] == $titletext ) {
                                        $s['index'] = $nextIndex++;
-                                       if ( $merged )
+                                       if ( $merged ) {
                                                $s['byteoffset'] += $len2;
+                                       }
                                }
                                $s['number']  = implode( '.', array_map(
                                        array( $wgContLang, 'formatnum' ),
@@ -3920,11 +4073,11 @@ class Parser
                                $lastLevel = $s['toclevel'];
                                $newTree[] = $s;
                        } else {
-                               // We're at $section
-                               // Insert sections from $tree2 here
+                               # We're at $section
+                               # Insert sections from $tree2 here
                                foreach ( $tree2 as $s2 ) {
-                                       // Rewrite the fields in $s2
-                                       // before inserting it
+                                       # Rewrite the fields in $s2
+                                       # before inserting it
                                        $s2['toclevel'] += $s['toclevel'] - 1;
                                        $s2['level'] += $s['level'] - 1;
                                        $s2['index'] = $nextIndex++;
@@ -3938,7 +4091,7 @@ class Parser
                                        $lastLevel = $s2['toclevel'];
                                        $newTree[] = $s2;
                                }
-                               // Skip all descendants of $section in $tree1
+                               # Skip all descendants of $section in $tree1
                                $targetLevel = $s['level'];
                                $merged = true;
                        }
@@ -3948,35 +4101,37 @@ class Parser
 
        /**
         * Increment a section number. Helper function for mergeSectionTrees()
-        * @param $number array Array representing a section number
-        * @param $level int Current TOC level (depth)
-        * @param $lastLevel int Level of previous TOC entry
+        *
+        * @param $number Array representing a section number
+        * @param $level Integer: current TOC level (depth)
+        * @param $lastLevel Integer: level of previous TOC entry
         */
        private static function incrementNumbering( &$number, $level, $lastLevel ) {
-               if ( $level > $lastLevel )
+               if ( $level > $lastLevel ) {
                        $number[$level - 1] = 1;
-               else if ( $level < $lastLevel ) {
+               } elseif ( $level < $lastLevel ) {
                        foreach ( $number as $key => $unused )
-                               if ( $key >= $level )
+                               if ( $key >= $level ) {
                                        unset( $number[$key] );
+                               }
                        $number[$level - 1]++;
-               } else
+               } else {
                        $number[$level - 1]++;
+               }
        }
 
        /**
         * Transform wiki markup when saving a page by doing \r\n -> \n
         * conversion, substitting signatures, {{subst:}} templates, etc.
         *
-        * @param string $text the text to transform
-        * @param Title &$title the Title object for the current article
-        * @param User $user the User object describing the current user
-        * @param ParserOptions $options parsing options
-        * @param bool $clearState whether to clear the parser state first
-        * @return string the altered wiki markup
-        * @public
+        * @param $text String: the text to transform
+        * @param &$title Title: the Title object for the current article
+        * @param $user User: the User object describing the current user
+        * @param $options ParserOptions: parsing options
+        * @param $clearState Boolean: whether to clear the parser state first
+        * @return String: the altered wiki markup
         */
-       function preSaveTransform( $text, Title $title, $user, $options, $clearState = true ) {
+       public function preSaveTransform( $text, Title $title, $user, $options, $clearState = true ) {
                $this->mOptions = $options;
                $this->setTitle( $title );
                $this->setOutputType( self::OT_WIKI );
@@ -4001,13 +4156,11 @@ class Parser
        function pstPass2( $text, $user ) {
                global $wgContLang, $wgLocaltimezone;
 
-               /* Note: This is the timestamp saved as hardcoded wikitext to
-                * the database, we use $wgContLang here in order to give
-                * everyone the same signature and use the default one rather
-                * than the one selected in each user's preferences.
-                *
-                * (see also bug 12815)
-                */
+               # Note: This is the timestamp saved as hardcoded wikitext to
+               # the database, we use $wgContLang here in order to give
+               # everyone the same signature and use the default one rather
+               # than the one selected in each user's preferences.
+               # (see also bug 12815)
                $ts = $this->mOptions->getTimestamp();
                if ( isset( $wgLocaltimezone ) ) {
                        $tz = $wgLocaltimezone;
@@ -4021,13 +4174,14 @@ class Parser
                $ts = date( 'YmdHis', $unixts );
                $tzMsg = date( 'T', $unixts );  # might vary on DST changeover!
 
-               /* Allow translation of timezones trough wiki. date() can return
-                * whatever crap the system uses, localised or not, so we cannot
-                * ship premade translations.
-                */
+               # Allow translation of timezones through wiki. date() can return
+               # whatever crap the system uses, localised or not, so we cannot
+               # ship premade translations.
                $key = 'timezone-' . strtolower( trim( $tzMsg ) );
                $value = wfMsgForContent( $key );
-               if ( !wfEmptyMsg( $key, $value ) ) $tzMsg = $value;
+               if ( !wfEmptyMsg( $key, $value ) ) {
+                       $tzMsg = $value;
+               }
 
                date_default_timezone_set( $oldtz );
 
@@ -4045,11 +4199,31 @@ class Parser
                        '~~~' => $sigText
                ) );
 
-               # Links of the form [[|<blah>]] or [[<blah>|]] perform pipe tricks
-               # Note this only allows the # in the position it works.
+               # Context links: [[|name]] and [[name (context)|]]
                global $wgLegalTitleChars;
-               $pipeTrickRe = "/\[\[(?:(\\|)([$wgLegalTitleChars]+)|([#$wgLegalTitleChars]+)\\|)\]\]/";
-               $text = preg_replace_callback( $pipeTrickRe, array( $this, 'pstPipeTrickCallback' ), $text );
+               $tc = "[$wgLegalTitleChars]";
+               $nc = '[ _0-9A-Za-z\x80-\xff-]'; # Namespaces can use non-ascii!
+
+               $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\))\\|]]/";            # [[ns:page (context)|]]
+               $p4 = "/\[\[(:?$nc+:|:|)($tc+?)(($tc+))\\|]]/";             # [[ns:page(context)|]]
+               $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\)|)(, $tc+|)\\|]]/";  # [[ns:page (context), context|]]
+               $p2 = "/\[\[\\|($tc+)]]/";                                      # [[|page]]
+
+               # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
+               $text = preg_replace( $p1, '[[\\1\\2\\3|\\2]]', $text );
+               $text = preg_replace( $p4, '[[\\1\\2\\3|\\2]]', $text );
+               $text = preg_replace( $p3, '[[\\1\\2\\3\\4|\\2]]', $text );
+
+               $t = $this->mTitle->getText();
+               $m = array();
+               if ( preg_match( "/^($nc+:|)$tc+?( \\($tc+\\))$/", $t, $m ) ) {
+                       $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+               } elseif ( preg_match( "/^($nc+:|)$tc+?(, $tc+|)$/", $t, $m ) && "$m[1]$m[2]" != '' ) {
+                       $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+               } else {
+                       # if there's no context, don't bother duplicating the title
+                       $text = preg_replace( $p2, '[[\\1]]', $text );
+               }
 
                # Trim trailing whitespace
                $text = rtrim( $text );
@@ -4057,32 +4231,16 @@ class Parser
                return $text;
        }
 
-       /**
-        * Called from pstPass2 to perform the pipe trick on links.
-        * Original was either [[|text]] or [[link|]]
-        *
-        * @param Array ("|" or "", text, link) $m
-        */
-       function pstPipeTrickCallback( $m )
-       {
-               if( $m[1] ) { # [[|<blah>]]
-                       $text = $m[2];
-                       $link = $this->getPipeTrickLink( $text );
-               } else { # [[<blah>|]]
-                       $link = $m[3];
-                       $text = $this->getPipeTrickText( $link );
-               }
-
-               return $link === $text ? "[[$link]]" : "[[$link|$text]]";
-       }
-
        /**
         * Fetch the user's signature text, if any, and normalize to
         * validated, ready-to-insert wikitext.
         * If you have pre-fetched the nickname or the fancySig option, you can
         * specify them here to save a database query.
         *
-        * @param User $user
+        * @param $user User
+        * @param $nickname String: nickname to use or false to use user's default nickname
+        * @param $fancySig Boolean: whether the nicknname is the complete signature
+        *                  or null to use default value
         * @return string
         */
        function getUserSig( &$user, $nickname = false, $fancySig = null ) {
@@ -4090,21 +4248,22 @@ class Parser
 
                $username = $user->getName();
 
-               // If not given, retrieve from the user object.
+               # If not given, retrieve from the user object.
                if ( $nickname === false )
                        $nickname = $user->getOption( 'nickname' );
 
-               if ( is_null( $fancySig ) )
+               if ( is_null( $fancySig ) ) {
                        $fancySig = $user->getBoolOption( 'fancysig' );
+               }
 
                $nickname = $nickname == null ? $username : $nickname;
 
-               if( mb_strlen( $nickname ) > $wgMaxSigChars ) {
+               if ( mb_strlen( $nickname ) > $wgMaxSigChars ) {
                        $nickname = $username;
                        wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
-               } elseif( $fancySig !== false ) {
+               } elseif ( $fancySig !== false ) {
                        # Sig. might contain markup; validate this
-                       if( $this->validateSig( $nickname ) !== false ) {
+                       if ( $this->validateSig( $nickname ) !== false ) {
                                # Validated; clean up (if needed) and return it
                                return $this->cleanSig( $nickname, true );
                        } else {
@@ -4114,7 +4273,7 @@ class Parser
                        }
                }
 
-               // Make sure nickname doesnt get a sig in a sig
+               # Make sure nickname doesnt get a sig in a sig
                $nickname = $this->cleanSigInSig( $nickname );
 
                # If we're still here, make it a link to the user page
@@ -4130,7 +4289,7 @@ class Parser
        /**
         * Check that the user's signature contains no bad XML
         *
-        * @param string $text
+        * @param $text String
         * @return mixed An expanded string, or false if invalid.
         */
        function validateSig( $text ) {
@@ -4143,9 +4302,9 @@ class Parser
         * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures @see cleanSigInSig
         * 2) Substitute all transclusions
         *
-        * @param string $text
+        * @param $text String
         * @param $parsing Whether we're cleaning (preferences save) or parsing
-        * @return string Signature text
+        * @return String: signature text
         */
        function cleanSig( $text, $parsing = false ) {
                if ( !$parsing ) {
@@ -4182,8 +4341,9 @@ class Parser
 
        /**
         * Strip ~~~, ~~~~ and ~~~~~ out of signatures
-        * @param string $text
-        * @return string Signature text with /~{3,5}/ removed
+        *
+        * @param $text String
+        * @return String: signature text with /~{3,5}/ removed
         */
        function cleanSigInSig( $text ) {
                $text = preg_replace( '/~{3,5}/', '', $text );
@@ -4193,9 +4353,8 @@ class Parser
        /**
         * Set up some variables which are usually set up in parse()
         * so that an external function can call some class members with confidence
-        * @public
         */
-       function startExternalParse( &$title, $options, $outputType, $clearState = true ) {
+       public function startExternalParse( &$title, $options, $outputType, $clearState = true ) {
                $this->setTitle( $title );
                $this->mOptions = $options;
                $this->setOutputType( $outputType );
@@ -4207,12 +4366,11 @@ class Parser
        /**
         * Wrapper for preprocess()
         *
-        * @param string $text the text to preprocess
-        * @param ParserOptions $options  options
-        * @return string
-        * @public
+        * @param $text String: the text to preprocess
+        * @param $options ParserOptions: options
+        * @return String
         */
-       function transformMsg( $text, $options ) {
+       public function transformMsg( $text, $options ) {
                global $wgTitle;
                static $executing = false;
 
@@ -4222,43 +4380,38 @@ class Parser
                }
                $executing = true;
 
-               wfProfileIn(__METHOD__);
+               wfProfileIn( __METHOD__ );
                $text = $this->preprocess( $text, $wgTitle, $options );
 
                $executing = false;
-               wfProfileOut(__METHOD__);
+               wfProfileOut( __METHOD__ );
                return $text;
        }
 
        /**
         * Create an HTML-style tag, e.g. <yourtag>special text</yourtag>
         * The callback should have the following form:
-        *    function myParserHook( $text, $params, &$parser ) { ... }
+        *    function myParserHook( $text, $params, $parser ) { ... }
         *
         * Transform and return $text. Use $parser for any required context, e.g. use
         * $parser->getTitle() and $parser->getOptions() not $wgTitle or $wgOut->mParserOptions
         *
-        * @public
-        *
-        * @param mixed $tag The tag to use, e.g. 'hook' for <hook>
-        * @param mixed $callback The callback function (and object) to use for the tag
-        *
+        * @param $tag Mixed: the tag to use, e.g. 'hook' for <hook>
+        * @param $callback Mixed: the callback function (and object) to use for the tag
         * @return The old value of the mTagHooks array associated with the hook
         */
-       function setHook( $tag, $callback ) {
+       public function setHook( $tag, $callback ) {
                $tag = strtolower( $tag );
                $oldVal = isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null;
                $this->mTagHooks[$tag] = $callback;
-               if( !in_array( $tag, $this->mStripList ) ) {
+               if ( !in_array( $tag, $this->mStripList ) ) {
                        $this->mStripList[] = $tag;
                }
 
                return $oldVal;
        }
 
-       /* An old work-around for bug 2257 - deprecated 2010-02-13 */
        function setTransparentTagHook( $tag, $callback ) {
-               wfDeprecated( __METHOD__ );
                $tag = strtolower( $tag );
                $oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
                $this->mTransparentTagHooks[$tag] = $callback;
@@ -4290,11 +4443,9 @@ class Parser
         *   nowiki                    Wiki markup in the return value should be escaped
         *   isHTML                    The returned text is HTML, armour it against wikitext transformation
         *
-        * @public
-        *
-        * @param string $id The magic word ID
-        * @param mixed $callback The callback function (and object) to use
-        * @param integer $flags a combination of the following flags:
+        * @param $id String: The magic word ID
+        * @param $callback Mixed: the callback function (and object) to use
+        * @param $flags Integer: a combination of the following flags:
         *     SFH_NO_HASH   No leading hash, i.e. {{plural:...}} instead of {{#if:...}}
         *
         *     SFH_OBJECT_ARGS   Pass the template arguments as PPNode objects instead of text. This
@@ -4318,7 +4469,7 @@ class Parser
         *
         * @return The old callback function for this name, if any
         */
-       function setFunctionHook( $id, $callback, $flags = 0 ) {
+       public function setFunctionHook( $id, $callback, $flags = 0 ) {
                global $wgContLang;
 
                $oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null;
@@ -4326,7 +4477,7 @@ class Parser
 
                # Add to function cache
                $mw = MagicWord::get( $id );
-               if( !$mw )
+               if ( !$mw )
                        throw new MWException( __METHOD__.'() expecting a magic word identifier.' );
 
                $synonyms = $mw->getSynonyms();
@@ -4353,7 +4504,7 @@ class Parser
        /**
         * Get all registered function hook identifiers
         *
-        * @return array
+        * @return Array
         */
        function getFunctionHooks() {
                return array_keys( $this->mFunctionHooks );
@@ -4370,7 +4521,7 @@ class Parser
                        $this->mFunctionTagHooks[$tag] : null;
                $this->mFunctionTagHooks[$tag] = array( $callback, $flags );
 
-               if( !in_array( $tag, $this->mStripList ) ) {
+               if ( !in_array( $tag, $this->mStripList ) ) {
                        $this->mStripList[] = $tag;
                }
 
@@ -4390,8 +4541,9 @@ class Parser
        /**
         * Replace <!--LINK--> link placeholders with plain text of links
         * (not HTML-formatted).
-        * @param string $text
-        * @return string
+        *
+        * @param $text String
+        * @return String
         */
        function replaceLinkHoldersText( $text ) {
                return $this->mLinkHolders->replaceText( $text );
@@ -4417,19 +4569,24 @@ class Parser
                $ig->useSkin( $this->mOptions->getSkin() );
                $ig->mRevisionId = $this->mRevisionId;
 
-               if( isset( $params['caption'] ) ) {
+               if ( isset( $params['showfilename'] ) ) {
+                       $ig->setShowFilename( true );
+               } else {
+                       $ig->setShowFilename( false );
+               }
+               if ( isset( $params['caption'] ) ) {
                        $caption = $params['caption'];
                        $caption = htmlspecialchars( $caption );
                        $caption = $this->replaceInternalLinks( $caption );
                        $ig->setCaptionHtml( $caption );
                }
-               if( isset( $params['perrow'] ) ) {
+               if ( isset( $params['perrow'] ) ) {
                        $ig->setPerRow( $params['perrow'] );
                }
-               if( isset( $params['widths'] ) ) {
+               if ( isset( $params['widths'] ) ) {
                        $ig->setWidths( $params['widths'] );
                }
-               if( isset( $params['heights'] ) ) {
+               if ( isset( $params['heights'] ) ) {
                        $ig->setHeights( $params['heights'] );
                }
 
@@ -4446,11 +4603,12 @@ class Parser
                                continue;
                        }
 
-                       if ( strpos( $matches[0], '%' ) !== false )
+                       if ( strpos( $matches[0], '%' ) !== false ) {
                                $matches[1] = urldecode( $matches[1] );
-                       $tp = Title::newFromText( $matches[1]/*, NS_FILE*/ );
+                       }
+                       $tp = Title::newFromText( $matches[1] );
                        $nt =& $tp;
-                       if( is_null( $nt ) ) {
+                       if ( is_null( $nt ) ) {
                                # Bogus title. Ignore these so we don't bomb out later.
                                continue;
                        }
@@ -4479,7 +4637,7 @@ class Parser
                        $handlerClass = '';
                }
                if ( !isset( $this->mImageParams[$handlerClass]  ) ) {
-                       // Initialise static lists
+                       # Initialise static lists
                        static $internalParamNames = array(
                                'horizAlign' => array( 'left', 'right', 'center', 'none' ),
                                'vertAlign' => array( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle',
@@ -4498,7 +4656,7 @@ class Parser
                                }
                        }
 
-                       // Add handler params
+                       # Add handler params
                        $paramMap = $internalParamMap;
                        if ( $handler ) {
                                $handlerParamMap = $handler->getParamMap();
@@ -4514,9 +4672,10 @@ class Parser
 
        /**
         * Parse image options text and use it to make an image
-        * @param Title $title
-        * @param string $options
-        * @param LinkHolderArray $holders
+        *
+        * @param $title Title
+        * @param $options String
+        * @param $holders LinkHolderArray
         */
        function makeImage( $title, $options, $holders = false ) {
                # Check if the options text is of the form "options|alt text"
@@ -4567,15 +4726,15 @@ class Parser
                $caption = '';
                $params = array( 'frame' => array(), 'handler' => array(),
                        'horizAlign' => array(), 'vertAlign' => array() );
-               foreach( $parts as $part ) {
+               foreach ( $parts as $part ) {
                        $part = trim( $part );
                        list( $magicName, $value ) = $mwArray->matchVariableStartToEnd( $part );
                        $validated = false;
-                       if( isset( $paramMap[$magicName] ) ) {
+                       if ( isset( $paramMap[$magicName] ) ) {
                                list( $type, $paramName ) = $paramMap[$magicName];
 
-                               // Special case; width and height come in one variable together
-                               if( $type === 'handler' && $paramName === 'width' ) {
+                               # Special case; width and height come in one variable together
+                               if ( $type === 'handler' && $paramName === 'width' ) {
                                        $m = array();
                                        # (bug 13500) In both cases (width/height and width only),
                                        # permit trailing "px" for backward compatibility.
@@ -4596,7 +4755,7 @@ class Parser
                                                        $params[$type]['width'] = $width;
                                                        $validated = true;
                                                }
-                                       } // else no validation -- bug 13436
+                                       } # else no validation -- bug 13436
                                } else {
                                        if ( $type === 'handler' ) {
                                                # Validate handler parameter
@@ -4606,9 +4765,9 @@ class Parser
                                                switch( $paramName ) {
                                                case 'manualthumb':
                                                case 'alt':
-                                                       // @todo Fixme: possibly check validity here for
-                                                       // manualthumb? downstream behavior seems odd with
-                                                       // missing manual thumbs.
+                                                       # @todo Fixme: possibly check validity here for
+                                                       # manualthumb? downstream behavior seems odd with
+                                                       # missing manual thumbs.
                                                        $validated = true;
                                                        $value = $this->stripAltText( $value, $holders );
                                                        break;
@@ -4636,7 +4795,7 @@ class Parser
                                                        }
                                                        break;
                                                default:
-                                                       // Most other things appear to be empty or numeric...
+                                                       # Most other things appear to be empty or numeric...
                                                        $validated = ( $value === false || is_numeric( trim( $value ) ) );
                                                }
                                        }
@@ -4744,15 +4903,17 @@ class Parser
         */
        function disableCache() {
                wfDebug( "Parser output marked as uncacheable.\n" );
-               $this->mOutput->mCacheTime = -1;
+               $this->mOutput->setCacheTime( -1 ); // old style, for compatibility
+               $this->mOutput->updateCacheExpiry( 0 ); // new style, for consistency
        }
 
-       /**#@+
+       /**
         * Callback from the Sanitizer for expanding items found in HTML attribute
         * values, so they can be safely tested and escaped.
-        * @param string $text
-        * @param PPFrame $frame
-        * @return string
+        *
+        * @param $text String
+        * @param $frame PPFrame
+        * @return String
         * @private
         */
        function attributeStripCallback( &$text, $frame = false ) {
@@ -4761,22 +4922,12 @@ class Parser
                return $text;
        }
 
-       /**#@-*/
-
-       /**#@+
-        * Accessor/mutator
-        */
-       function Title( $x = null ) { return wfSetVar( $this->mTitle, $x ); }
-       function Options( $x = null ) { return wfSetVar( $this->mOptions, $x ); }
-       function OutputType( $x = null ) { return wfSetVar( $this->mOutputType, $x ); }
-       /**#@-*/
-
-       /**#@+
+       /**
         * Accessor
         */
-       function getTags() { return array_merge( array_keys($this->mTransparentTagHooks), array_keys( $this->mTagHooks ) ); }
-       /**#@-*/
-
+       function getTags() {
+               return array_merge( array_keys( $this->mTransparentTagHooks ), array_keys( $this->mTagHooks ) );
+       }
 
        /**
         * Break wikitext input into sections, and either pull or replace
@@ -4784,8 +4935,8 @@ class Parser
         *
         * External callers should use the getSection and replaceSection methods.
         *
-        * @param string $text Page wikitext
-        * @param string $section A section identifier string of the form:
+        * @param $text String: Page wikitext
+        * @param $section String: a section identifier string of the form:
         *   <flag1> - <flag2> - ... - <section number>
         *
         * Currently the only recognised flag is "T", which means the target section number
@@ -4798,21 +4949,21 @@ class Parser
         * pull the given section along with its lower-level subsections. If the section is
         * not found, $mode=get will return $newtext, and $mode=replace will return $text.
         *
-        * @param string $mode One of "get" or "replace"
-        * @param string $newText Replacement text for section data.
-        * @return string for "get", the extracted section text.
-        *                for "replace", the whole page with the section replaced.
+        * @param $mode String: one of "get" or "replace"
+        * @param $newText String: replacement text for section data.
+        * @return String: for "get", the extracted section text.
+        *                 for "replace", the whole page with the section replaced.
         */
        private function extractSections( $text, $section, $mode, $newText='' ) {
                global $wgTitle;
                $this->clearState();
-               $this->setTitle( $wgTitle ); // not generally used but removes an ugly failure mode
+               $this->setTitle( $wgTitle ); # not generally used but removes an ugly failure mode
                $this->mOptions = new ParserOptions;
-               $this->setOutputType( self::OT_WIKI );
+               $this->setOutputType( self::OT_PLAIN );
                $outText = '';
                $frame = $this->getPreprocessor()->newFrame();
 
-               // Process section extraction flags
+               # Process section extraction flags
                $flags = 0;
                $sectionParts = explode( '-', $section );
                $sectionIndex = array_pop( $sectionParts );
@@ -4821,23 +4972,23 @@ class Parser
                                $flags |= self::PTD_FOR_INCLUSION;
                        }
                }
-               // Preprocess the text
+               # Preprocess the text
                $root = $this->preprocessToDom( $text, $flags );
 
-               // <h> nodes indicate section breaks
-               // They can only occur at the top level, so we can find them by iterating the root's children
+               # <h> nodes indicate section breaks
+               # They can only occur at the top level, so we can find them by iterating the root's children
                $node = $root->getFirstChild();
 
-               // Find the target section
+               # Find the target section
                if ( $sectionIndex == 0 ) {
-                       // Section zero doesn't nest, level=big
+                       # Section zero doesn't nest, level=big
                        $targetLevel = 1000;
                } else {
-            while ( $node ) {
-                if ( $node->getName() === 'h' ) {
-                    $bits = $node->splitHeading();
+                       while ( $node ) {
+                               if ( $node->getName() === 'h' ) {
+                                       $bits = $node->splitHeading();
                                        if ( $bits['i'] == $sectionIndex ) {
-                                       $targetLevel = $bits['level'];
+                                               $targetLevel = $bits['level'];
                                                break;
                                        }
                                }
@@ -4849,7 +5000,7 @@ class Parser
                }
 
                if ( !$node ) {
-                       // Not found
+                       # Not found
                        if ( $mode === 'get' ) {
                                return $newText;
                        } else {
@@ -4857,7 +5008,7 @@ class Parser
                        }
                }
 
-               // Find the end of the section, including nested sections
+               # Find the end of the section, including nested sections
                do {
                        if ( $node->getName() === 'h' ) {
                                $bits = $node->splitHeading();
@@ -4872,13 +5023,13 @@ class Parser
                        $node = $node->getNextSibling();
                } while ( $node );
 
-               // Write out the remainder (in replace mode only)
+               # Write out the remainder (in replace mode only)
                if ( $mode === 'replace' ) {
-                       // Output the replacement text
-                       // Add two newlines on -- trailing whitespace in $newText is conventionally
-                       // stripped by the editor, so we need both newlines to restore the paragraph gap
-                       // Only add trailing whitespace if there is newText
-                       if($newText != "") {
+                       # Output the replacement text
+                       # Add two newlines on -- trailing whitespace in $newText is conventionally
+                       # stripped by the editor, so we need both newlines to restore the paragraph gap
+                       # Only add trailing whitespace if there is newText
+                       if ( $newText != "" ) {
                                $outText .= $newText . "\n\n";
                        }
 
@@ -4889,7 +5040,7 @@ class Parser
                }
 
                if ( is_string( $outText ) ) {
-                       // Re-insert stripped tags
+                       # Re-insert stripped tags
                        $outText = rtrim( $this->mStripState->unstripBoth( $outText ) );
                }
 
@@ -4903,9 +5054,9 @@ class Parser
         *
         * If a section contains subsections, these are also returned.
         *
-        * @param string $text text to look in
-        * @param string $section section identifier
-        * @param string $deftext default to return if section is not found
+        * @param $text String: text to look in
+        * @param $section String: section identifier
+        * @param $deftext String: default to return if section is not found
         * @return string text of the requested section
         */
        public function getSection( $text, $section, $deftext='' ) {
@@ -4916,6 +5067,15 @@ class Parser
                return $this->extractSections( $oldtext, $section, "replace", $text );
        }
 
+       /**
+        * Get the ID of the revision we are parsing
+        *
+        * @return Mixed: integer or null
+        */
+       function getRevisionId() {
+               return $this->mRevisionId;
+       }
+
        /**
         * Get the timestamp associated with the current revision, adjusted for
         * the default server-local timestamp
@@ -4928,18 +5088,18 @@ class Parser
                        $timestamp = $dbr->selectField( 'revision', 'rev_timestamp',
                                        array( 'rev_id' => $this->mRevisionId ), __METHOD__ );
 
-                       // Normalize timestamp to internal MW format for timezone processing.
-                       // This has the added side-effect of replacing a null value with
-                       // the current time, which gives us more sensible behavior for
-                       // previews.
+                       # Normalize timestamp to internal MW format for timezone processing.
+                       # This has the added side-effect of replacing a null value with
+                       # the current time, which gives us more sensible behavior for
+                       # previews.
                        $timestamp = wfTimestamp( TS_MW, $timestamp );
 
-                       // The cryptic '' timezone parameter tells to use the site-default
-                       // timezone offset instead of the user settings.
-                       //
-                       // Since this value will be saved into the parser cache, served
-                       // to other users, and potentially even used inside links and such,
-                       // it needs to be consistent for all visitors.
+                       # The cryptic '' timezone parameter tells to use the site-default
+                       # timezone offset instead of the user settings.
+                       #
+                       # Since this value will be saved into the parser cache, served
+                       # to other users, and potentially even used inside links and such,
+                       # it needs to be consistent for all visitors.
                        $this->mRevisionTimestamp = $wgContLang->userAdjust( $timestamp, '' );
 
                        wfProfileOut( __METHOD__ );
@@ -4949,11 +5109,13 @@ class Parser
 
        /**
         * Get the name of the user that edited the last revision
+        *
+        * @return String: user name
         */
        function getRevisionUser() {
-               // if this template is subst: the revision id will be blank,
-               // so just use the current user's name
-               if( $this->mRevisionId ) {
+               # if this template is subst: the revision id will be blank,
+               # so just use the current user's name
+               if ( $this->mRevisionId ) {
                        $revision = Revision::newFromId( $this->mRevisionId );
                        $revuser = $revision->getUserText();
                } else {
@@ -4980,10 +5142,11 @@ class Parser
         */
        public function getDefaultSort() {
                global $wgCategoryPrefixedDefaultSortkey;
-               if( $this->mDefaultSort !== false ) {
+               if ( $this->mDefaultSort !== false ) {
                        return $this->mDefaultSort;
-               } elseif ($this->mTitle->getNamespace() == NS_CATEGORY ||
-                       !$wgCategoryPrefixedDefaultSortkey) {
+               } elseif ( $this->mTitle->getNamespace() == NS_CATEGORY ||
+                       !$wgCategoryPrefixedDefaultSortkey )
+               {
                        return $this->mTitle->getText();
                } else {
                        return $this->mTitle->getPrefixedText();
@@ -5008,19 +5171,8 @@ class Parser
        public function guessSectionNameFromWikiText( $text ) {
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
-               $headline = Sanitizer::decodeCharReferences( $text );
-               # strip out HTML
-               $headline = StringUtils::delimiterReplace( '<', '>', '', $headline );
-               $headline = trim( $headline );
-               $sectionanchor = '#' . urlencode( str_replace( ' ', '_', $headline ) );
-               $replacearray = array(
-                       '%3A' => ':',
-                       '%' => '.'
-               );
-               return str_replace(
-                       array_keys( $replacearray ),
-                       array_values( $replacearray ),
-                       $sectionanchor );
+               $text = Sanitizer::normalizeSectionNameWhitespace( $text );
+               return '#' . Sanitizer::escapeId( $text, 'noninitial' );
        }
 
        /**
@@ -5033,22 +5185,22 @@ class Parser
         * to create valid section anchors by mimicing the output of the
         * parser when headings are parsed.
         *
-        * @param $text string Text string to be stripped of wikitext
+        * @param $text String: text string to be stripped of wikitext
         * for use in a Section anchor
         * @return Filtered text string
         */
        public function stripSectionName( $text ) {
                # Strip internal link markup
-               $text = preg_replace('/\[\[:?([^[|]+)\|([^[]+)\]\]/','$2',$text);
-               $text = preg_replace('/\[\[:?([^[]+)\|?\]\]/','$1',$text);
+               $text = preg_replace( '/\[\[:?([^[|]+)\|([^[]+)\]\]/', '$2', $text );
+               $text = preg_replace( '/\[\[:?([^[]+)\|?\]\]/', '$1', $text );
 
                # Strip external link markup (FIXME: Not Tolerant to blank link text
                # I.E. [http://www.mediawiki.org] will render as [1] or something depending
                # on how many empty links there are on the page - need to figure that out.
-               $text = preg_replace('/\[(?:' . wfUrlProtocols() . ')([^ ]+?) ([^[]+)\]/','$2',$text);
+               $text = preg_replace( '/\[(?:' . wfUrlProtocols() . ')([^ ]+?) ([^[]+)\]/', '$2', $text );
 
                # Parse wikitext quotes (italics & bold)
-               $text = $this->doQuotes($text);
+               $text = $this->doQuotes( $text );
 
                # Strip HTML tags
                $text = StringUtils::delimiterReplace( '<', '>', '', $text );
@@ -5064,7 +5216,7 @@ class Parser
         */
        function testSrvus( $text, $title, $options, $outputType = self::OT_HTML ) {
                $this->clearState();
-               if ( ! ( $title instanceof Title ) ) {
+               if ( !$title instanceof Title ) {
                        $title = Title::newFromText( $title );
                }
                $this->mTitle = $title;
@@ -5078,14 +5230,14 @@ class Parser
 
        function testPst( $text, $title, $options ) {
                global $wgUser;
-               if ( ! ( $title instanceof Title ) ) {
+               if ( !$title instanceof Title ) {
                        $title = Title::newFromText( $title );
                }
                return $this->preSaveTransform( $text, $title, $wgUser, $options );
        }
 
        function testPreprocess( $text, $title, $options ) {
-               if ( ! ( $title instanceof Title ) ) {
+               if ( !$title instanceof Title ) {
                        $title = Title::newFromText( $title );
                }
                return $this->testSrvus( $text, $title, $options, self::OT_PREPROCESS );
@@ -5119,11 +5271,13 @@ class Parser
                $data = array();
                $data['text'] = $text;
 
-               // First, find all strip markers, and store their
-               //  data in an array.
+               # First, find all strip markers, and store their
+               #  data in an array.
                $stripState = new StripState;
                $pos = 0;
-               while( ( $start_pos = strpos( $text, $this->mUniqPrefix, $pos ) ) && ( $end_pos = strpos( $text, self::MARKER_SUFFIX, $pos ) ) ) {
+               while ( ( $start_pos = strpos( $text, $this->mUniqPrefix, $pos ) )
+                       && ( $end_pos = strpos( $text, self::MARKER_SUFFIX, $pos ) ) )
+               {
                        $end_pos += strlen( self::MARKER_SUFFIX );
                        $marker = substr( $text, $start_pos, $end_pos-$start_pos );
 
@@ -5142,17 +5296,17 @@ class Parser
                }
                $data['stripstate'] = $stripState;
 
-               // Now, find all of our links, and store THEIR
-               //  data in an array! :)
+               # Now, find all of our links, and store THEIR
+               #  data in an array! :)
                $links = array( 'internal' => array(), 'interwiki' => array() );
                $pos = 0;
 
-               // Internal links
-               while( ( $start_pos = strpos( $text, '<!--LINK ', $pos ) ) ) {
+               # Internal links
+               while ( ( $start_pos = strpos( $text, '<!--LINK ', $pos ) ) ) {
                        list( $ns, $trail ) = explode( ':', substr( $text, $start_pos + strlen( '<!--LINK ' ) ), 2 );
 
-                       $ns = trim($ns);
-                       if (empty( $links['internal'][$ns] )) {
+                       $ns = trim( $ns );
+                       if ( empty( $links['internal'][$ns] ) ) {
                                $links['internal'][$ns] = array();
                        }
 
@@ -5163,8 +5317,8 @@ class Parser
 
                $pos = 0;
 
-               // Interwiki links
-               while( ( $start_pos = strpos( $text, '<!--IWLINK ', $pos ) ) ) {
+               # Interwiki links
+               while ( ( $start_pos = strpos( $text, '<!--IWLINK ', $pos ) ) ) {
                        $data = substr( $text, $start_pos );
                        $key = trim( substr( $data, 0, strpos( $data, '-->' ) ) );
                        $links['interwiki'][] = $this->mLinkHolders->interwiki[$key];
@@ -5176,22 +5330,29 @@ class Parser
                return $data;
        }
 
-       function unserialiseHalfParsedText( $data, $intPrefix = null /* Unique identifying prefix */ ) {
-               if (!$intPrefix)
+       /**
+        * TODO: document
+        * @param $data Array
+        * @param $intPrefix String unique identifying prefix
+        * @return String
+        */
+       function unserialiseHalfParsedText( $data, $intPrefix = null ) {
+               if ( !$intPrefix ) {
                        $intPrefix = $this->getRandomString();
+               }
 
-               // First, extract the strip state.
+               # First, extract the strip state.
                $stripState = $data['stripstate'];
                $this->mStripState->general->merge( $stripState->general );
                $this->mStripState->nowiki->merge( $stripState->nowiki );
 
-               // Now, extract the text, and renumber links
+               # Now, extract the text, and renumber links
                $text = $data['text'];
                $links = $data['linkholder'];
 
-               // Internal...
-               foreach( $links['internal'] as $ns => $nsLinks ) {
-                       foreach( $nsLinks as $key => $entry ) {
+               # Internal...
+               foreach ( $links['internal'] as $ns => $nsLinks ) {
+                       foreach ( $nsLinks as $key => $entry ) {
                                $newKey = $intPrefix . '-' . $key;
                                $this->mLinkHolders->internals[$ns][$newKey] = $entry;
 
@@ -5199,15 +5360,15 @@ class Parser
                        }
                }
 
-               // Interwiki...
-               foreach( $links['interwiki'] as $key => $entry ) {
+               # Interwiki...
+               foreach ( $links['interwiki'] as $key => $entry ) {
                        $newKey = "$intPrefix-$key";
                        $this->mLinkHolders->interwikis[$newKey] = $entry;
 
                        $text = str_replace( "<!--IWLINK $key-->", "<!--IWLINK $newKey-->", $text );
                }
 
-               // Should be good to go.
+               # Should be good to go.
                return $text;
        }
 }