summaryrefslogtreecommitdiff
path: root/includes/Parser.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/Parser.php')
-rw-r--r--includes/Parser.php522
1 files changed, 161 insertions, 361 deletions
diff --git a/includes/Parser.php b/includes/Parser.php
index 8d67279d..8e36e170 100644
--- a/includes/Parser.php
+++ b/includes/Parser.php
@@ -2,8 +2,7 @@
/**
* File for Parser and related classes
*
- * @package MediaWiki
- * @subpackage Parser
+ * @addtogroup Parser
*/
/**
@@ -57,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:
@@ -86,10 +86,11 @@ define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 );
* * only within ParserOptions
* </pre>
*
- * @package MediaWiki
+ * @addtogroup Parser
*/
class Parser
{
+ const VERSION = MW_PARSER_VERSION;
/**#@+
* @private
*/
@@ -114,7 +115,7 @@ class Parser
$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
+ $mRevIdForTs; // The revision ID which was used to fetch the timestamp
/**#@-*/
@@ -162,6 +163,7 @@ class Parser
$this->setFunctionHook( 'numberofarticles', array( 'CoreParserFunctions', 'numberofarticles' ), SFH_NO_HASH );
$this->setFunctionHook( 'numberoffiles', array( 'CoreParserFunctions', 'numberoffiles' ), SFH_NO_HASH );
$this->setFunctionHook( 'numberofadmins', array( 'CoreParserFunctions', 'numberofadmins' ), SFH_NO_HASH );
+ $this->setFunctionHook( 'numberofedits', array( 'CoreParserFunctions', 'numberofedits' ), SFH_NO_HASH );
$this->setFunctionHook( 'language', array( 'CoreParserFunctions', 'language' ), SFH_NO_HASH );
$this->setFunctionHook( 'padleft', array( 'CoreParserFunctions', 'padleft' ), SFH_NO_HASH );
$this->setFunctionHook( 'padright', array( 'CoreParserFunctions', 'padright' ), SFH_NO_HASH );
@@ -211,7 +213,7 @@ class Parser
'titles' => array()
);
$this->mRevisionTimestamp = $this->mRevisionId = null;
-
+
/**
* Prefix for temporary replacement strings for the multipass parser.
* \x07 should never appear in input as it's disallowed in XML.
@@ -262,7 +264,6 @@ class Parser
* Convert wikitext to HTML
* Do not call this function recursively.
*
- * @private
* @param string $text Text we want to parse
* @param Title &$title A title object
* @param array $options
@@ -271,7 +272,7 @@ class Parser
* @param int $revid number to pass in {{REVISIONID}}
* @return ParserOutput a ParserOutput
*/
- function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) {
+ public function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) {
/**
* First pass--just handle <nowiki> sections, pass the rest off
* to internalParse() which does all the real work.
@@ -724,7 +725,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);
@@ -872,7 +873,7 @@ class Parser
array_push ( $td_history , false );
array_push ( $last_tag_history , '' );
}
- else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 ) == '|+' ) {
+ else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 ) == '|+' ) {
// This might be cell elements, td, th or captions
if ( substr ( $line , 0 , 2 ) == '|+' ) {
$first_character = '+';
@@ -1002,6 +1003,7 @@ class Parser
$text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) );
$text = $this->replaceVariables( $text, $args );
+ 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
@@ -1086,7 +1088,7 @@ class Parser
}
$url = wfMsg( $urlmsg, $id);
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
$la = $sk->getExternalLinkAttributes( $url, $keyword.$id );
$text = "<a href=\"{$url}\"{$la}>{$keyword} {$id}</a>";
}
@@ -1287,7 +1289,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;
}
@@ -1306,7 +1309,7 @@ class Parser
$fname = 'Parser::replaceExternalLinks';
wfProfileIn( $fname );
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
$bits = preg_split( EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
@@ -1395,7 +1398,7 @@ class Parser
$s = array_shift( $bits );
$i = 0;
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
while ( $i < count( $bits ) ){
$protocol = $bits[$i++];
@@ -1468,7 +1471,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.
@@ -1503,7 +1506,7 @@ class Parser
* @private
*/
function maybeMakeExternalImage( $url ) {
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
$imagesfrom = $this->mOptions->getAllowExternalImagesFrom();
$imagesexception = !empty($imagesfrom);
$text = false;
@@ -1533,7 +1536,7 @@ class Parser
# the % is needed to support urlencoded titles as well
if ( !$tc ) { $tc = Title::legalChars() . '#%'; }
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
#split the entire text string on occurences of [[
$a = explode( '[[', ' ' . $s );
@@ -1552,7 +1555,6 @@ class Parser
$e2 = wfMsgForContent( 'linkprefix' );
$useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
-
if( is_null( $this->mTitle ) ) {
throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
}
@@ -1569,10 +1571,11 @@ class Parser
$prefix = '';
}
- if($wgContLang->hasVariants())
+ if($wgContLang->hasVariants()) {
$selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
- else
+ } else {
$selflink = array($this->mTitle->getPrefixedText());
+ }
$useSubpages = $this->areSubpagesAllowed();
wfProfileOut( $fname.'-setup' );
@@ -1626,7 +1629,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
@@ -1640,7 +1643,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() . '))/', $m[1])) {
+ if (preg_match('/^\b(?:' . wfUrlProtocols() . ')/', $m[1])) {
$s .= $prefix . '[[' . $line ;
continue;
}
@@ -1723,8 +1726,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;
}
@@ -1778,11 +1781,12 @@ class Parser
}
}
- if( ( in_array( $nt->getPrefixedText(), $selflink ) ) &&
- ( $nt->getFragment() === '' ) ) {
- # Self-links are handled specially; generally de-link and change to bold.
- $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
- continue;
+ # Self-link checking
+ if( $nt->getFragment() === '' ) {
+ if( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
+ $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
+ continue;
+ }
}
# Special and Media are pseudo-namespaces; no pages actually exist in them
@@ -1862,7 +1866,7 @@ class Parser
*/
function makeKnownLinkHolder( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
list( $inside, $trail ) = Linker::splitTrail( $trail );
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
$link = $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix );
return $this->armorLinks( $link ) . $trail;
}
@@ -1923,9 +1927,9 @@ class Parser
# Look at the first character
if( $target != '' && $target{0} == '/' ) {
# / at end means we don't want the slash to be shown
- if( substr( $target, -1, 1 ) == '/' ) {
- $target = substr( $target, 1, -1 );
- $noslash = $target;
+ $trailingSlashes = preg_match_all( '%(/+)$%', $target, $m );
+ if( $trailingSlashes ) {
+ $noslash = $target = substr( $target, 1, -strlen($m[0][0]) );
} else {
$noslash = substr( $target, 1 );
}
@@ -2134,9 +2138,9 @@ class Parser
wfProfileIn( "$fname-paragraph" );
# No prefix (not in list)--go to paragraph mode
// XXX: use a stack for nestable elements like span, table and div
- $openmatch = preg_match('/(<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+ $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
$closematch = preg_match(
- '/(<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
+ '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
'<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t );
if ( $openmatch or $closematch ) {
$paragraphStack = false;
@@ -2538,6 +2542,8 @@ class Parser
return $varCache[$index] = $wgContLang->formatNum( SiteStats::pages() );
case 'numberofadmins':
return $varCache[$index] = $wgContLang->formatNum( SiteStats::admins() );
+ case 'numberofedits':
+ return $varCache[$index] = $wgContLang->formatNum( SiteStats::edits() );
case 'currenttimestamp':
return $varCache[$index] = wfTimestampNow();
case 'localtimestamp':
@@ -2852,7 +2858,7 @@ class Parser
return $text;
}
-
+
/// Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
static function createAssocArgs( $args ) {
$assocArgs = array();
@@ -2872,10 +2878,10 @@ class Parser
}
}
}
-
+
return $assocArgs;
}
-
+
/**
* Return the text of a template, after recursively
* replacing any variables or templates within the template.
@@ -2888,7 +2894,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' );
@@ -3031,6 +3037,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;
+
}
}
@@ -3066,6 +3085,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 ) {
@@ -3155,7 +3177,7 @@ class Parser
# If the template begins with a table or block-level
# element, it should be treated as beginning a new line.
- if (!$piece['lineStart'] && preg_match('/^({\\||:|;|#|\*)/', $text)) /*}*/{
+ if (!$piece['lineStart'] && preg_match('/^(?:{\\||:|;|#|\*)/', $text)) /*}*/{
$text = "\n" . $text;
}
} elseif ( !$noargs ) {
@@ -3271,7 +3293,7 @@ class Parser
return wfMsg('scarytranscludedisabled');
$url = $title->getFullUrl( "action=$action" );
-
+
if (strlen($url) > 255)
return wfMsg('scarytranscludetoolong');
return $this->fetchScaryTemplateMaybeFromCache($url);
@@ -3279,7 +3301,7 @@ class Parser
function fetchScaryTemplateMaybeFromCache($url) {
global $wgTranscludeCacheExpiry;
- $dbr =& wfGetDB(DB_SLAVE);
+ $dbr = wfGetDB(DB_SLAVE);
$obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
array('tc_url' => $url));
if ($obj) {
@@ -3294,7 +3316,7 @@ class Parser
if (!$text)
return wfMsg('scarytranscludefailed', $url);
- $dbw =& wfGetDB(DB_MASTER);
+ $dbw = wfGetDB(DB_MASTER);
$dbw->replace('transcache', array('tc_url'), array(
'tc_url' => $url,
'tc_time' => time(),
@@ -3395,7 +3417,7 @@ class Parser
global $wgMaxTocLevel, $wgContLang;
$doNumberHeadings = $this->mOptions->getNumberHeadings();
- if( !$this->mTitle->userCanEdit() ) {
+ if( !$this->mTitle->quickUserCan( 'edit' ) ) {
$showEditLink = 0;
} else {
$showEditLink = $this->mOptions->getEditSection();
@@ -3437,7 +3459,7 @@ class Parser
}
# We need this to perform operations on the HTML
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
# headline counter
$headlineCount = 0;
@@ -3723,11 +3745,7 @@ class Parser
}
# Trim trailing whitespace
- # __END__ tag allows for trailing
- # whitespace to be deliberately included
$text = rtrim( $text );
- $mw =& MagicWord::get( 'end' );
- $mw->matchAndRemove( $text );
return $text;
}
@@ -3847,7 +3865,7 @@ class Parser
wfProfileIn($fname);
- if ( $wgTitle ) {
+ if ( $wgTitle && !( $wgTitle instanceof FakeTitle ) ) {
$this->mTitle = $wgTitle;
} else {
$this->mTitle = Title::newFromText('msg');
@@ -3966,12 +3984,12 @@ class Parser
$pdbks = array();
$colours = array();
- $sk =& $this->mOptions->getSkin();
+ $sk = $this->mOptions->getSkin();
$linkCache =& LinkCache::singleton();
if ( !empty( $this->mLinkHolders['namespaces'] ) ) {
wfProfileIn( $fname.'-check' );
- $dbr =& wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_SLAVE );
$page = $dbr->tableName( 'page' );
$threshold = $wgUser->getOption('stubthreshold');
@@ -4161,8 +4179,8 @@ class Parser
if(isset($categoryMap[$vardbk])){
$oldkey = $categoryMap[$vardbk];
if($oldkey != $vardbk)
- $varCategories[$oldkey]=$vardbk;
- }
+ $varCategories[$oldkey]=$vardbk;
+ }
}
// rebuild the categories in original order (if there are replacements)
@@ -4303,6 +4321,7 @@ class Parser
*/
function renderImageGallery( $text, $params ) {
$ig = new ImageGallery();
+ $ig->setContextTitle( $this->mTitle );
$ig->setShowBytes( false );
$ig->setShowFilename( false );
$ig->setParsing();
@@ -4314,6 +4333,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 ) {
@@ -4359,10 +4387,8 @@ class Parser
* Parse image options text and use it to make an image
*/
function makeImage( $nt, $options ) {
- global $wgUseImageResize, $wgDjvuRenderer;
-
- $align = '';
-
+ # @TODO: let the MediaHandler specify its transform parameters
+ #
# 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
@@ -4372,61 +4398,74 @@ 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 = '';
- $width = $height = $framed = $thumb = false;
- $page = null;
+ $params = array();
+ $framed = $thumb = false;
$manual_thumb = '' ;
+ $align = $valign = '';
+ $sk = $this->mOptions->getSkin();
foreach( $part as $val ) {
- if ( $wgUseImageResize && ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
+ if ( !is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
$thumb=true;
} elseif ( ! is_null( $match = $mwManualThumb->matchVariableStartToEnd($val) ) ) {
# 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 ( ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) {
+ # Select a page in a multipage document
+ $params['page'] = $match;
+ } elseif ( !isset( $params['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 ) ) {
+ $params['width'] = intval( $m[1] );
+ $params['height'] = intval( $m[2] );
+ } else {
+ $params['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
@@ -4439,8 +4478,7 @@ class Parser
$alt = Sanitizer::stripAllTags( $alt );
# 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, $params, $framed, $thumb, $manual_thumb, $valign );
}
/**
@@ -4518,24 +4556,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",
- */
"/
(
^
@@ -4559,7 +4579,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 ) {
@@ -4614,8 +4635,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;
}
@@ -4628,34 +4651,35 @@ 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 );
}
/**
- * Get the timestamp associated with the current revision, adjusted for
+ * Get the timestamp associated with the current revision, adjusted for
* the default server-local timestamp
*/
function getRevisionTimestamp() {
if ( is_null( $this->mRevisionTimestamp ) ) {
wfProfileIn( __METHOD__ );
global $wgContLang;
- $dbr =& wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_SLAVE );
$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.
$timestamp = wfTimestamp( TS_MW, $timestamp );
-
+
// The cryptic '' timezone parameter tells to use the site-default
// timezone offset instead of the user settings.
//
@@ -4663,12 +4687,12 @@ class Parser
// 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__ );
}
return $this->mRevisionTimestamp;
}
-
+
/**
* Mutator for $mDefaultSort
*
@@ -4677,7 +4701,7 @@ class Parser
public function setDefaultSort( $sort ) {
$this->mDefaultSort = $sort;
}
-
+
/**
* Accessor for $mDefaultSort
* Will use the title/prefixed title if none is set
@@ -4693,241 +4717,13 @@ class Parser
: $this->mTitle->getPrefixedText();
}
}
-
-}
-
-/**
- * @todo document
- * @package MediaWiki
- */
-class ParserOutput
-{
- var $mText, # The output text
- $mLanguageLinks, # List of the full text of language links, in the order they appear
- $mCategories, # Map of category names to sort keys
- $mContainsOldMagic, # Boolean variable indicating if the input contained variables like {{CURRENTDAY}}
- $mCacheTime, # Time when this object was generated, or -1 for uncacheable. Used in ParserCache.
- $mVersion, # Compatibility check
- $mTitleText, # title text of the chosen language variant
- $mLinks, # 2-D map of NS/DBK to ID for the links in the document. ID=zero for broken.
- $mTemplates, # 2-D map of NS/DBK to ID for the template references. ID=zero for broken.
- $mImages, # DB keys of the images used, in the array key only
- $mExternalLinks, # External link URLs, in the key only
- $mHTMLtitle, # Display HTML title
- $mSubtitle, # Additional subtitle
- $mNewSection, # Show a new section link?
- $mNoGallery; # No gallery on category page? (__NOGALLERY__)
-
- function ParserOutput( $text = '', $languageLinks = array(), $categoryLinks = array(),
- $containsOldMagic = false, $titletext = '' )
- {
- $this->mText = $text;
- $this->mLanguageLinks = $languageLinks;
- $this->mCategories = $categoryLinks;
- $this->mContainsOldMagic = $containsOldMagic;
- $this->mCacheTime = '';
- $this->mVersion = MW_PARSER_VERSION;
- $this->mTitleText = $titletext;
- $this->mLinks = array();
- $this->mTemplates = array();
- $this->mImages = array();
- $this->mExternalLinks = array();
- $this->mHTMLtitle = "" ;
- $this->mSubtitle = "" ;
- $this->mNewSection = false;
- $this->mNoGallery = false;
- }
- function getText() { return $this->mText; }
- function &getLanguageLinks() { return $this->mLanguageLinks; }
- function getCategoryLinks() { return array_keys( $this->mCategories ); }
- function &getCategories() { return $this->mCategories; }
- function getCacheTime() { return $this->mCacheTime; }
- function getTitleText() { return $this->mTitleText; }
- function &getLinks() { return $this->mLinks; }
- function &getTemplates() { return $this->mTemplates; }
- function &getImages() { return $this->mImages; }
- function &getExternalLinks() { return $this->mExternalLinks; }
- function getNoGallery() { return $this->mNoGallery; }
- function getSubtitle() { return $this->mSubtitle; }
-
- function containsOldMagic() { return $this->mContainsOldMagic; }
- function setText( $text ) { return wfSetVar( $this->mText, $text ); }
- function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); }
- function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategories, $cl ); }
- function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
- function setCacheTime( $t ) { return wfSetVar( $this->mCacheTime, $t ); }
- function setTitleText( $t ) { return wfSetVar($this->mTitleText, $t); }
- function setSubtitle( $st ) { return wfSetVar( $this->mSubtitle, $st ); }
-
- function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; }
- function addImage( $name ) { $this->mImages[$name] = 1; }
- function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; }
- function addExternalLink( $url ) { $this->mExternalLinks[$url] = 1; }
-
- function setNewSection( $value ) {
- $this->mNewSection = (bool)$value;
- }
- function getNewSection() {
- return (bool)$this->mNewSection;
- }
-
- function addLink( $title, $id = null ) {
- $ns = $title->getNamespace();
- $dbk = $title->getDBkey();
- if ( !isset( $this->mLinks[$ns] ) ) {
- $this->mLinks[$ns] = array();
- }
- if ( is_null( $id ) ) {
- $id = $title->getArticleID();
- }
- $this->mLinks[$ns][$dbk] = $id;
- }
-
- function addTemplate( $title, $id ) {
- $ns = $title->getNamespace();
- $dbk = $title->getDBkey();
- if ( !isset( $this->mTemplates[$ns] ) ) {
- $this->mTemplates[$ns] = array();
- }
- $this->mTemplates[$ns][$dbk] = $id;
- }
-
- /**
- * Return true if this cached output object predates the global or
- * per-article cache invalidation timestamps, or if it comes from
- * an incompatible older version.
- *
- * @param string $touched the affected article's last touched timestamp
- * @return bool
- * @public
- */
- function expired( $touched ) {
- global $wgCacheEpoch;
- return $this->getCacheTime() == -1 || // parser says it's uncacheable
- $this->getCacheTime() < $touched ||
- $this->getCacheTime() <= $wgCacheEpoch ||
- !isset( $this->mVersion ) ||
- version_compare( $this->mVersion, MW_PARSER_VERSION, "lt" );
- }
}
/**
- * Set options of the Parser
- * @todo document
- * @package MediaWiki
+ * @todo document, briefly.
+ * @addtogroup Parser
*/
-class ParserOptions
-{
- # All variables are supposed to be private in theory, although in practise this is not the case.
- var $mUseTeX; # Use texvc to expand <math> tags
- var $mUseDynamicDates; # Use DateFormatter to format dates
- var $mInterwikiMagic; # Interlanguage links are removed and returned in an array
- var $mAllowExternalImages; # Allow external images inline
- var $mAllowExternalImagesFrom; # If not, any exception?
- var $mSkin; # Reference to the preferred skin
- var $mDateFormat; # Date format index
- var $mEditSection; # Create "edit section" links
- var $mNumberHeadings; # Automatically number headings
- var $mAllowSpecialInclusion; # Allow inclusion of special pages
- var $mTidy; # Ask for tidy cleanup
- var $mInterfaceMessage; # Which lang to call for PLURAL and GRAMMAR
- var $mMaxIncludeSize; # Maximum size of template expansions, in bytes
- var $mRemoveComments; # Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS
-
- var $mUser; # Stored user object, just used to initialise the skin
-
- function getUseTeX() { return $this->mUseTeX; }
- function getUseDynamicDates() { return $this->mUseDynamicDates; }
- function getInterwikiMagic() { return $this->mInterwikiMagic; }
- function getAllowExternalImages() { return $this->mAllowExternalImages; }
- function getAllowExternalImagesFrom() { return $this->mAllowExternalImagesFrom; }
- function getEditSection() { return $this->mEditSection; }
- function getNumberHeadings() { return $this->mNumberHeadings; }
- function getAllowSpecialInclusion() { return $this->mAllowSpecialInclusion; }
- function getTidy() { return $this->mTidy; }
- function getInterfaceMessage() { return $this->mInterfaceMessage; }
- function getMaxIncludeSize() { return $this->mMaxIncludeSize; }
- function getRemoveComments() { return $this->mRemoveComments; }
-
- function &getSkin() {
- if ( !isset( $this->mSkin ) ) {
- $this->mSkin = $this->mUser->getSkin();
- }
- return $this->mSkin;
- }
-
- function getDateFormat() {
- if ( !isset( $this->mDateFormat ) ) {
- $this->mDateFormat = $this->mUser->getDatePreference();
- }
- return $this->mDateFormat;
- }
-
- function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
- function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
- function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
- function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
- function setAllowExternalImagesFrom( $x ) { return wfSetVar( $this->mAllowExternalImagesFrom, $x ); }
- function setDateFormat( $x ) { return wfSetVar( $this->mDateFormat, $x ); }
- function setEditSection( $x ) { return wfSetVar( $this->mEditSection, $x ); }
- function setNumberHeadings( $x ) { return wfSetVar( $this->mNumberHeadings, $x ); }
- function setAllowSpecialInclusion( $x ) { return wfSetVar( $this->mAllowSpecialInclusion, $x ); }
- function setTidy( $x ) { return wfSetVar( $this->mTidy, $x); }
- function setSkin( $x ) { $this->mSkin = $x; }
- function setInterfaceMessage( $x ) { return wfSetVar( $this->mInterfaceMessage, $x); }
- function setMaxIncludeSize( $x ) { return wfSetVar( $this->mMaxIncludeSize, $x ); }
- function setRemoveComments( $x ) { return wfSetVar( $this->mRemoveComments, $x ); }
-
- function ParserOptions( $user = null ) {
- $this->initialiseFromUser( $user );
- }
-
- /**
- * Get parser options
- * @static
- */
- static function newFromUser( $user ) {
- return new ParserOptions( $user );
- }
-
- /** Get user options */
- function initialiseFromUser( $userInput ) {
- global $wgUseTeX, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
- global $wgAllowExternalImagesFrom, $wgAllowSpecialInclusion, $wgMaxArticleSize;
- $fname = 'ParserOptions::initialiseFromUser';
- wfProfileIn( $fname );
- if ( !$userInput ) {
- global $wgUser;
- if ( isset( $wgUser ) ) {
- $user = $wgUser;
- } else {
- $user = new User;
- }
- } else {
- $user =& $userInput;
- }
-
- $this->mUser = $user;
-
- $this->mUseTeX = $wgUseTeX;
- $this->mUseDynamicDates = $wgUseDynamicDates;
- $this->mInterwikiMagic = $wgInterwikiMagic;
- $this->mAllowExternalImages = $wgAllowExternalImages;
- $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
- $this->mSkin = null; # Deferred
- $this->mDateFormat = null; # Deferred
- $this->mEditSection = true;
- $this->mNumberHeadings = $user->getOption( 'numberheadings' );
- $this->mAllowSpecialInclusion = $wgAllowSpecialInclusion;
- $this->mTidy = false;
- $this->mInterfaceMessage = false;
- $this->mMaxIncludeSize = $wgMaxArticleSize * 1024;
- $this->mRemoveComments = true;
- wfProfileOut( $fname );
- }
-}
-
class OnlyIncludeReplacer {
var $output = '';
@@ -4940,6 +4736,10 @@ class OnlyIncludeReplacer {
}
}
+/**
+ * @todo document, briefly.
+ * @addtogroup Parser
+ */
class StripState {
var $general, $nowiki;