* @private
*/
# Persistent:
- var $mTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables;
+ var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables,
+ $mImageParams, $mImageParamsMagicArray;
# Cleared with clearState():
var $mOutput, $mAutonumber, $mDTopen, $mStripState;
*/
function Parser() {
$this->mTagHooks = array();
+ $this->mTransparentTagHooks = array();
$this->mFunctionHooks = array();
$this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
$this->mFirstCall = true;
wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) );
+//!JF Move to its own function
+
+ $uniq_prefix = $this->mUniqPrefix;
+ $matches = array();
+ $elements = array_keys( $this->mTransparentTagHooks );
+ $text = Parser::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 );
+ }
+ $text = $this->mStripState->unstripGeneral( $text );
+
$text = Sanitizer::normalizeCharReferences( $text );
if (($wgUseTidy and $this->mOptions->mTidy) or $wgAlwaysUseTidy) {
$inside = $p[4];
}
- $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . '-QINU';
+ $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . "-QINU\x07";
$stripped .= $marker;
if ( $close === '/>' ) {
$output = Xml::escapeTagsOnly( $content );
break;
case 'math':
- $output = $wgContLang->armourMath( MathRenderer::renderMath( $content ) );
+ $output = $wgContLang->armourMath(
+ MathRenderer::renderMath( $content, $params ) );
break;
case 'gallery':
$output = $this->renderImageGallery( $content, $params );
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
- 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.
+ 2 => array('file', wfGetNull(), 'a')
);
$pipes = array();
$process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes);
$text = strtr( $text, array( '<noinclude>' => '', '</noinclude>' => '') );
$text = StringUtils::delimiterReplace( '<includeonly>', '</includeonly>', '', $text );
- $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) );
+ $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ), array(), array_keys( $this->mTransparentTagHooks ) );
$text = $this->replaceVariables( $text, $args );
wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ) );
wfProfileIn( $fname );
$ret = $target; # default return value is no change
- # bug 7425
- $target = trim( $target );
-
# Some namespaces don't allow subpages,
# so only perform processing if subpages are allowed
if( $this->areSubpagesAllowed() ) {
+ $hash = strpos( $target, '#' );
+ if( $hash !== false ) {
+ $suffix = substr( $target, $hash );
+ $target = substr( $target, 0, $hash );
+ } else {
+ $suffix = '';
+ }
+ # bug 7425
+ $target = trim( $target );
# Look at the first character
if( $target != '' && $target{0} == '/' ) {
# / at end means we don't want the slash to be shown
$noslash = substr( $target, 1 );
}
- $ret = $this->mTitle->getPrefixedText(). '/' . trim($noslash);
+ $ret = $this->mTitle->getPrefixedText(). '/' . trim($noslash) . $suffix;
if( '' === $text ) {
- $text = $target;
+ $text = $target . $suffix;
} # this might be changed for ugliness reasons
} else {
# check for .. subpage backlinks
if( substr( $nodotdot, -1, 1 ) == '/' ) {
$nodotdot = substr( $nodotdot, 0, -1 );
if( '' === $text ) {
- $text = $nodotdot;
+ $text = $nodotdot . $suffix;
}
}
$nodotdot = trim( $nodotdot );
if( $nodotdot != '' ) {
$ret .= '/' . $nodotdot;
}
+ $ret .= $suffix;
}
}
}
return $oldVal;
}
+ function setTransparentTagHook( $tag, $callback ) {
+ $tag = strtolower( $tag );
+ $oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
+ $this->mTransparentTagHooks[$tag] = $callback;
+
+ return $oldVal;
+ }
+
/**
* Create a function, e.g. {{sum:1|2|3}}
* The callback function should have the form:
$ig->setShowBytes( false );
$ig->setShowFilename( false );
$ig->setParsing();
+ $ig->setAttributes( Sanitizer::validateTagAttributes( $params, 'table' ) );
$ig->useSkin( $this->mOptions->getSkin() );
$ig->mRevisionId = $this->mRevisionId;
return $ig->toHTML();
}
+ function getImageParams( $handler ) {
+ if ( $handler ) {
+ $handlerClass = get_class( $handler );
+ } else {
+ $handlerClass = '';
+ }
+ if ( !isset( $this->mImageParams[$handlerClass] ) ) {
+ // Initialise static lists
+ static $internalParamNames = array(
+ 'horizAlign' => array( 'left', 'right', 'center', 'none' ),
+ 'vertAlign' => array( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle',
+ 'bottom', 'text-bottom' ),
+ 'frame' => array( 'thumbnail', 'manualthumb', 'framed', 'frameless',
+ 'upright', 'border' ),
+ );
+ static $internalParamMap;
+ if ( !$internalParamMap ) {
+ $internalParamMap = array();
+ foreach ( $internalParamNames as $type => $names ) {
+ foreach ( $names as $name ) {
+ $magicName = str_replace( '-', '_', "img_$name" );
+ $internalParamMap[$magicName] = array( $type, $name );
+ }
+ }
+ }
+
+ // Add handler params
+ $paramMap = $internalParamMap;
+ if ( $handler ) {
+ $handlerParamMap = $handler->getParamMap();
+ foreach ( $handlerParamMap as $magic => $paramName ) {
+ $paramMap[$magic] = array( 'handler', $paramName );
+ }
+ }
+ $this->mImageParams[$handlerClass] = $paramMap;
+ $this->mImageParamsMagicArray[$handlerClass] = new MagicWordArray( array_keys( $paramMap ) );
+ }
+ return array( $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] );
+ }
+
/**
* Parse image options text and use it to make an image
*/
- function makeImage( $nt, $options ) {
+ function makeImage( $title, $options ) {
# @TODO: let the MediaHandler specify its transform parameters
#
# Check if the options text is of the form "options|alt text"
# * middle
# * bottom
# * text-bottom
+
+ $parts = array_map( 'trim', explode( '|', $options) );
+ $sk = $this->mOptions->getSkin();
+ # Give extensions a chance to select the file revision for us
+ $skip = $time = false;
+ wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$title, &$skip, &$time ) );
- $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 );
+ if ( $skip ) {
+ return $sk->makeLinkObj( $title );
}
- $mwThumb =& MagicWord::get( 'img_thumbnail' );
- $mwManualThumb =& MagicWord::get( 'img_manualthumb' );
- $mwWidth =& MagicWord::get( 'img_width' );
- $mwFramed =& MagicWord::get( 'img_framed' );
- $mwFrameless =& MagicWord::get( 'img_frameless' );
- $mwUpright =& MagicWord::get( 'img_upright' );
- $mwBorder =& MagicWord::get( 'img_border' );
- $mwPage =& MagicWord::get( 'img_page' );
- $caption = '';
- $params = array();
- $framed = $thumb = false;
- $manual_thumb = '' ;
- $align = $valign = '';
- $sk = $this->mOptions->getSkin();
+ # Get parameter map
+ $file = wfFindFile( $title, $time );
+ $handler = $file ? $file->getHandler() : false;
+
+ list( $paramMap, $mwArray ) = $this->getImageParams( $handler );
- foreach( $part as $val ) {
- if ( !is_null( $mwThumb->matchVariableStartToEnd($val) ) ) {
- $thumb=true;
- } elseif ( !is_null( $match = $mwUpright->matchVariableStartToEnd( $val ) ) ) {
- $params['upright'] = true;
- $params['upright_factor'] = floatval( $match );
- } elseif ( !is_null( $match = $mwFrameless->matchVariableStartToEnd( $val ) ) ) {
- $params['frameless'] = true;
- } elseif ( !is_null( $mwBorder->matchVariableStartToEnd( $val ) ) ) {
- $params['border'] = true;
- } elseif ( ! is_null( $match = $mwManualThumb->matchVariableStartToEnd($val) ) ) {
- # use manually specified thumbnail
- $thumb=true;
- $manual_thumb = $match;
+ # Process the input parameters
+ $caption = '';
+ $params = array( 'frame' => array(), 'handler' => array(),
+ 'horizAlign' => array(), 'vertAlign' => array() );
+ foreach( $parts as $part ) {
+ list( $magicName, $value ) = $mwArray->matchVariableStartToEnd( $part );
+ if ( isset( $paramMap[$magicName] ) ) {
+ list( $type, $paramName ) = $paramMap[$magicName];
+ $params[$type][$paramName] = $value;
} 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 {
- $caption = $val;
+ $caption = $part;
+ }
+ }
+
+ # Process alignment parameters
+ if ( $params['horizAlign'] ) {
+ $params['frame']['align'] = key( $params['horizAlign'] );
+ }
+ if ( $params['vertAlign'] ) {
+ $params['frame']['valign'] = key( $params['vertAlign'] );
+ }
+
+ # Validate the handler parameters
+ if ( $handler ) {
+ foreach ( $params['handler'] as $name => $value ) {
+ if ( !$handler->validateParam( $name, $value ) ) {
+ unset( $params['handler'][$name] );
}
}
}
+
# Strip bad stuff out of the alt text
$alt = $this->replaceLinkHoldersText( $caption );
$alt = $this->mStripState->unstripBoth( $alt );
$alt = Sanitizer::stripAllTags( $alt );
- # Give extensions a chance to select the file revision for us
- $skip = $time = false;
- wfRunHooks( 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time ) );
+ $params['frame']['alt'] = $alt;
+ $params['frame']['caption'] = $caption;
# Linker does the rest
- if( $skip ) {
- $link = $sk->makeLinkObj( $nt );
- } else {
- $link = $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $params, $framed, $thumb, $manual_thumb, $valign, $time );
+ $ret = $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'] );
+
+ # Give the handler a chance to modify the parser object
+ if ( $handler ) {
+ $handler->parserTransformHook( $this, $file );
}
-
- return $link;
+
+ return $ret;
}
/**
/**#@+
* Accessor
*/
- function getTags() { return array_keys( $this->mTagHooks ); }
+ function getTags() { return array_merge( array_keys($this->mTransparentTagHooks), array_keys( $this->mTagHooks ) ); }
/**#@-*/
# now that we can be sure that no pseudo-sections are in the source,
# split it up by section
$uniq = preg_quote( $this->uniqPrefix(), '/' );
- $comment = "(?:$uniq-!--.*?QINU)";
+ $comment = "(?:$uniq-!--.*?QINU\x07)";
$secs = preg_split(
"/
(
: $this->mTitle->getPrefixedText();
}
}
-
}
/**
return $text;
}
}
-
-?>