Documentation tweaks to help documentation systems (Doxygen + PHPDocumentor)
[lhc/web/wiklou.git] / includes / Parser.php
index 8f04aa2..4b85c1a 100644 (file)
@@ -56,9 +56,10 @@ define( 'MW_COLON_STATE_COMMENTDASH', 6 );
 define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 );
 
 /**
- * PHP Parser
- *
- * Processes wiki markup
+ * PHP Parser - Processes wiki markup (which uses a more user-friendly 
+ * syntax, such as "[[link]]" for making links), and provides a one-way
+ * transformation of that wiki markup it into XHTML output / markup
+ * (which in turn the browser understands, and can display).
  *
  * <pre>
  * There are four main entry points into the Parser class:
@@ -722,7 +723,7 @@ class Parser
                $descriptorspec = array(
                        0 => array('pipe', 'r'),
                        1 => array('pipe', 'w'),
-                       2 => array('file', '/dev/null', 'a')
+                       2 => array('file', '/dev/null', 'a')  // FIXME: this line in UNIX-specific, it generates a warning on Windows, because /dev/null is not a valid Windows file.
                );
                $pipes = array();
                $process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes);
@@ -1000,6 +1001,7 @@ class Parser
                $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) );
 
                $text = $this->replaceVariables( $text, $args );
+               wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text ) );
 
                // Tables need to come after variable replacement for things to work
                // properly; putting them before other transformations should keep
@@ -1285,7 +1287,8 @@ class Parser
                                $output .= '</i>';
                        if ($state == 'bi')
                                $output .= '</b>';
-                       if ($state == 'both')
+                       # There might be lonely ''''', so make sure we have a buffer
+                       if ($state == 'both' && $buffer)
                                $output .= '<b><i>'.$buffer.'</i></b>';
                        return $output;
                }
@@ -1466,7 +1469,7 @@ class Parser
         * @param string
         * @return string
         * @static
-        * @fixme This can merge genuinely required bits in the path or query 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
         *        statistical records, not for actual linking/output.
@@ -1624,7 +1627,7 @@ class Parser
                                $might_be_img = true;
                                $text = $m[2];
                                if ( strpos( $m[1], '%' ) !== false ) {
-                                      $m[1] = urldecode($m[1]);
+                                       $m[1] = urldecode($m[1]);
                                }
                                $trail = "";
                        } else { # Invalid form; output directly
@@ -1721,8 +1724,8 @@ class Parser
                                wfProfileIn( "$fname-interwiki" );
                                if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw ) ) {
                                        $this->mOutput->addLanguageLink( $nt->getFullText() );
-                                       $s = rtrim($s . "\n");
-                                       $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
+                                       $s = rtrim($s . $prefix);
+                                       $s .= trim($trail, "\n") == '' ? '': $prefix . $trail;
                                        wfProfileOut( "$fname-interwiki" );
                                        continue;
                                }
@@ -2887,7 +2890,7 @@ class Parser
         * @private
         */
        function braceSubstitution( $piece ) {
-               global $wgContLang, $wgLang, $wgAllowDisplayTitle;
+               global $wgContLang, $wgLang, $wgAllowDisplayTitle, $wgNonincludableNamespaces;
                $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
                wfProfileIn( $fname );
                wfProfileIn( __METHOD__.'-setup' );
@@ -3030,6 +3033,19 @@ class Parser
                        } else {
                                # set $text to cached message.
                                $text = $linestart . $this->mTemplates[$piece['title']];
+                               #treat title for cached page the same as others
+                               $ns = NS_TEMPLATE;
+                               $subpage = '';
+                               $part1 = $this->maybeDoSubpageLink( $part1, $subpage );
+                               if ($subpage !== '') {
+                                 $ns = $this->mTitle->getNamespace();
+                               }
+                               $title = Title::newFromText( $part1, $ns );
+                               //used by include size checking
+                               $titleText = $title->getPrefixedText();
+                               //used by edit section links
+                               $replaceHeadings = true;
+                               
                        }
                }
 
@@ -3065,6 +3081,9 @@ class Parser
                                                        $isHTML = true;
                                                        $this->disableCache();
                                                }
+                                       } else if ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) {
+                                               $found = false; //access denied
+                                               wfDebug( "$fname: template inclusion denied for " . $title->getPrefixedDBkey() );
                                        } else {
                                                $articleContent = $this->fetchTemplate( $title );
                                                if ( $articleContent !== false ) {
@@ -4310,6 +4329,15 @@ class Parser
                        $caption = $this->replaceInternalLinks( $caption );
                        $ig->setCaptionHtml( $caption );
                }
+               if( isset( $params['perrow'] ) ) {
+                       $ig->setPerRow( $params['perrow'] );
+               }
+               if( isset( $params['widths'] ) ) {
+                       $ig->setWidths( $params['widths'] );
+               }
+               if( isset( $params['heights'] ) ) {
+                       $ig->setHeights( $params['heights'] );
+               }
 
                $lines = explode( "\n", $text );
                foreach ( $lines as $line ) {
@@ -4357,8 +4385,6 @@ class Parser
        function makeImage( $nt, $options ) {
                global $wgUseImageResize, $wgDjvuRenderer;
 
-               $align = '';
-
                # Check if the options text is of the form "options|alt text"
                # Options are:
                #  * thumbnail          make a thumbnail with enlarge-icon and caption, alignment depends on lang
@@ -4368,16 +4394,26 @@ class Parser
                #  * ___px              scale to ___ pixels width, no aligning. e.g. use in taxobox
                #  * center             center the image
                #  * framed             Keep original image size, no magnify-button.
-
-               $part = explode( '|', $options);
-
+               # vertical-align values (no % or length right now):
+               #  * baseline
+               #  * sub
+               #  * super
+               #  * top
+               #  * text-top
+               #  * middle
+               #  * bottom
+               #  * text-bottom
+
+               $part = array_map( 'trim', explode( '|', $options) );
+
+               $mwAlign = array();
+               $alignments = array( 'left', 'right', 'center', 'none', 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom' );
+               foreach ( $alignments as $alignment ) {
+                       $mwAlign[$alignment] =& MagicWord::get( 'img_'.$alignment );
+               }
                $mwThumb  =& MagicWord::get( 'img_thumbnail' );
                $mwManualThumb =& MagicWord::get( 'img_manualthumb' );
-               $mwLeft   =& MagicWord::get( 'img_left' );
-               $mwRight  =& MagicWord::get( 'img_right' );
-               $mwNone   =& MagicWord::get( 'img_none' );
                $mwWidth  =& MagicWord::get( 'img_width' );
-               $mwCenter =& MagicWord::get( 'img_center' );
                $mwFramed =& MagicWord::get( 'img_framed' );
                $mwPage   =& MagicWord::get( 'img_page' );
                $caption = '';
@@ -4385,6 +4421,7 @@ class Parser
                $width = $height = $framed = $thumb = false;
                $page = null;
                $manual_thumb = '' ;
+               $align = $valign = '';
 
                foreach( $part as $val ) {
                        if ( $wgUseImageResize && ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
@@ -4393,36 +4430,37 @@ class Parser
                                # use manually specified thumbnail
                                $thumb=true;
                                $manual_thumb = $match;
-                       } elseif ( ! is_null( $mwRight->matchVariableStartToEnd($val) ) ) {
-                               # remember to set an alignment, don't render immediately
-                               $align = 'right';
-                       } elseif ( ! is_null( $mwLeft->matchVariableStartToEnd($val) ) ) {
-                               # remember to set an alignment, don't render immediately
-                               $align = 'left';
-                       } elseif ( ! is_null( $mwCenter->matchVariableStartToEnd($val) ) ) {
-                               # remember to set an alignment, don't render immediately
-                               $align = 'center';
-                       } elseif ( ! is_null( $mwNone->matchVariableStartToEnd($val) ) ) {
-                               # remember to set an alignment, don't render immediately
-                               $align = 'none';
-                       } elseif ( isset( $wgDjvuRenderer ) && $wgDjvuRenderer
-                                  && ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) {
-                               # Select a page in a multipage document
-                               $page = $match;
-                       } elseif ( $wgUseImageResize && !$width && ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
-                               wfDebug( "img_width match: $match\n" );
-                               # $match is the image width in pixels
-                               $m = array();
-                               if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
-                                       $width = intval( $m[1] );
-                                       $height = intval( $m[2] );
+                       } else {
+                               foreach( $alignments as $alignment ) {
+                                       if ( ! is_null( $mwAlign[$alignment]->matchVariableStartToEnd($val) ) ) {
+                                               switch ( $alignment ) {
+                                                       case 'left': case 'right': case 'center': case 'none':
+                                                               $align = $alignment; break;
+                                                       default:
+                                                               $valign = $alignment;
+                                               }
+                                               continue 2;
+                                       }
+                               }
+                               if ( isset( $wgDjvuRenderer ) && $wgDjvuRenderer
+                               && ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) {
+                                       # Select a page in a multipage document
+                                       $page = $match;
+                               } elseif ( $wgUseImageResize && !$width && ! is_null( $match = $mwWidth->matchVariableStartToEnd($val) ) ) {
+                                       wfDebug( "img_width match: $match\n" );
+                                       # $match is the image width in pixels
+                                       $m = array();
+                                       if ( preg_match( '/^([0-9]*)x([0-9]*)$/', $match, $m ) ) {
+                                               $width = intval( $m[1] );
+                                               $height = intval( $m[2] );
+                                       } else {
+                                               $width = intval($match);
+                                       }
+                               } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
+                                       $framed=true;
                                } else {
-                                       $width = intval($match);
+                                       $caption = $val;
                                }
-                       } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) {
-                               $framed=true;
-                       } else {
-                               $caption = $val;
                        }
                }
                # Strip bad stuff out of the alt text
@@ -4436,7 +4474,7 @@ class Parser
 
                # Linker does the rest
                $sk = $this->mOptions->getSkin();
-               return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page );
+               return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page, $valign );
        }
 
        /**
@@ -4514,24 +4552,6 @@ class Parser
                $uniq = preg_quote( $this->uniqPrefix(), '/' );
                $comment = "(?:$uniq-!--.*?QINU)";
                $secs = preg_split(
-               /*
-                       "/
-                       ^(
-                       (?:$comment|<\/?noinclude>)* # Initial comments will be stripped
-                       (?:
-                               (=+) # Should this be limited to 6?
-                               .+?  # Section title...
-                               \\2  # Ending = count must match start
-                       |
-                               ^
-                               <h([1-6])\b.*?>
-                               .*?
-                               <\/h\\3\s*>
-                       )
-                       (?:$comment|<\/?noinclude>|\s+)* # Trailing whitespace ok
-                       )$
-                       /mix",
-               */
                        "/
                        (
                                ^
@@ -4555,7 +4575,8 @@ class Parser
                                // "Section 0" returns the content before any other section.
                                $rv = $secs[0];
                        } else {
-                               $rv = "";
+                               //track missing section, will replace if found.
+                               $rv = $newtext;
                        }
                } elseif( $mode == "replace" ) {
                        if( $section == 0 ) {
@@ -4610,8 +4631,10 @@ class Parser
                                }
                        }
                }
-               # reinsert stripped tags
-               $rv = trim( $stripState->unstripBoth( $rv ) );
+               if (is_string($rv))
+                       # reinsert stripped tags
+                       $rv = trim( $stripState->unstripBoth( $rv ) );
+
                return $rv;
        }
 
@@ -4624,13 +4647,14 @@ class Parser
         *
         * @param $text String: text to look in
         * @param $section Integer: section number
+        * @param $deftext: default to return if section is not found
         * @return string text of the requested section
         */
-       function getSection( $text, $section ) {
-               return $this->extractSections( $text, $section, "get" );
+       public function getSection( $text, $section, $deftext='' ) {
+               return $this->extractSections( $text, $section, "get", $deftext );
        }
 
-       function replaceSection( $oldtext, $section, $text ) {
+       public function replaceSection( $oldtext, $section, $text ) {
                return $this->extractSections( $oldtext, $section, "replace", $text );
        }
 
@@ -4692,6 +4716,9 @@ class Parser
 
 }
 
+/**
+ * @todo document, briefly.
+ */
 class OnlyIncludeReplacer {
        var $output = '';
 
@@ -4704,6 +4731,9 @@ class OnlyIncludeReplacer {
        }
 }
 
+/**
+ * @todo document, briefly.
+ */
 class StripState {
        var $general, $nowiki;