Index: includes/parser/Parser.php =================================================================== --- includes/parser/Parser.php (revision 108087) +++ includes/parser/Parser.php (working copy) @@ -100,6 +100,7 @@ # Persistent: var $mTagHooks = array(); + var $mTagPSTHooks = array(); var $mTransparentTagHooks = array(); var $mFunctionHooks = array(); var $mFunctionSynonyms = array( 0 => array(), 1 => array() ); @@ -3727,6 +3728,25 @@ extract( $flags ); } } else { + + if ( $this->ot['wiki'] ) { + //we're in preSaveTransform, allow the tag extension to transform its contents + $lcname = strtolower( $name ); + $attributes = Sanitizer::decodeTagAttributes( $attrText ); + if ( isset( $params['attributes'] ) ) { + $attributes = $attributes + $params['attributes']; + } + + if ( isset( $this->mTagPSTHooks[$lcname] ) ) { + # Workaround for PHP bug 35229 and similar + if ( !is_callable( $this->mTagPSTHooks[$lcname] ) ) { + throw new MWException( "Tag PST hook for $lcname is not callable\n" ); + } + $content = call_user_func_array( $this->mTagPSTHooks[$lcname], + array( $content, $attributes, $this, $frame ) ); + } + } + if ( is_null( $attrText ) ) { $attrText = ''; } @@ -4583,6 +4603,26 @@ return $oldVal; } +/** + * As setHook(), but the callback set here will be called during preSaveTransform + * This allows extension tags to do pre-save transformations on their input, + * + * @param $tag Mixed: the tag to use, e.g. 'hook' for + * @param $callback Mixed: the callback function (and object) to use for the tag + * @return The old value of the mTagPSTHooks array associated with the hook + */ + public function setPSTHook( $tag, $callback ) { + $tag = strtolower( $tag ); + if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) throw new MWException( "Invalid character {$m[0]} in setPSTHook('$tag', ...) call" ); + $oldVal = isset( $this->mTagPSTHooks[$tag] ) ? $this->mTagPSTHooks[$tag] : null; + $this->mTagPSTHooks[$tag] = $callback; + if ( !in_array( $tag, $this->mStripList ) ) { + $this->mStripList[] = $tag; + } + + return $oldVal; + } + /** * As setHook(), but letting the contents be parsed. * @@ -4614,6 +4654,7 @@ function clearTagHooks() { $this->mTagHooks = array(); $this->mFunctionTagHooks = array(); + $this->mTagPSTHooks = array(); $this->mStripList = $this->mDefaultStripList; } @@ -5155,7 +5196,8 @@ * @return array */ function getTags() { - return array_merge( array_keys( $this->mTransparentTagHooks ), array_keys( $this->mTagHooks ), array_keys( $this->mFunctionTagHooks ) ); + return array_unique( array_merge( array_keys( $this->mTransparentTagHooks ), array_keys( $this->mTagHooks ), + array_keys( $this->mFunctionTagHooks ), array_keys( $this->mTagPSTHooks ) ) ); } /** Index: includes/parser/CoreTagHooks.php =================================================================== --- includes/parser/CoreTagHooks.php (revision 108087) +++ includes/parser/CoreTagHooks.php (working copy) @@ -19,6 +19,7 @@ $parser->setHook( 'pre', array( __CLASS__, 'pre' ) ); $parser->setHook( 'nowiki', array( __CLASS__, 'nowiki' ) ); $parser->setHook( 'gallery', array( __CLASS__, 'gallery' ) ); + $parser->setPSTHook( 'gallery', array( __CLASS__, 'galleryPST' ) ); if ( $wgRawHtml ) { $parser->setHook( 'html', array( __CLASS__, 'html' ) ); } @@ -102,4 +103,41 @@ static function gallery( $content, $attributes, $parser ) { return $parser->renderImageGallery( $content, $attributes ); } + + /** + * Core parser tag preSaveTransform hook function for 'gallery'. + * + * This function applies preSaveTransform to the image descriptions. + * + * @param string $content + * @param array $attributes + * @param Parser $parser + * @return string wikitext + */ + static function galleryPST( $content, $attributes, $parser ) { + + $lines = StringUtils::explode( "\n", $content ); + $transformed = array(); + foreach ( $lines as $line ) { + # match lines like these: + # Image:someimage.jpg|This is some image + $matches = array(); + preg_match( "/^([^|]+)(\\|(.*))?$/", $line, $matches ); + # Skip empty lines + if ( count( $matches ) == 0 ) { + $transformed[] = $line; + continue; + } + + if ( isset( $matches[3] ) ) { + //pre-save transform the second match, which is wikitext + $presaved = $parser->preSaveTransform( $matches[2], $parser->getTitle(), $parser->getOptions()->getUser(), $parser->getOptions(), false ); + $transformed[] = $matches[1] . $presaved;// $matches[2]; + } else { + $transformed[] = $line; + } + + } + return implode( "\n", $transformed ); + } }