Added {{#tag:}}: generic adaptor from parser function syntax to XML-style extension...
authorTim Starling <tstarling@users.mediawiki.org>
Wed, 9 Jan 2008 07:13:54 +0000 (07:13 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Wed, 9 Jan 2008 07:13:54 +0000 (07:13 +0000)
includes/CoreParserFunctions.php
includes/Parser.php
languages/messages/MessagesEn.php

index 4f7b840..3f455f6 100644 (file)
@@ -211,5 +211,56 @@ class CoreParserFunctions {
                        return '';
                }
        }
+
+       /**
+        * Parser function to extension tag adaptor
+        */
+       public static function tagObj( $parser, $frame, $args ) {
+               $xpath = false;
+               if ( !count( $args ) ) {
+                       return '';
+               }
+               $tagName = strtolower( trim( $frame->expand( array_shift( $args ) ) ) );
+               $stripList = $parser->getStripList();
+               if ( !in_array( $tagName, $stripList ) ) {
+                       return '<span class="error">' . 
+                               wfMsg( 'unknown_extension_tag', $tagName ) . 
+                               '</span>';
+               }
+
+               $lastNumberedNode = false;
+               $attributes = array();
+               foreach ( $args as $arg ) {
+                       if ( !$xpath ) {
+                               $xpath = new DOMXPath( $arg->ownerDocument );
+                       }
+                       $names = $xpath->query( 'name', $arg );
+                       if ( $names->item( 0 )->hasAttributes() ) {
+                               $lastNumberedNode = $arg;
+                       } else {
+                               $name = $frame->expand( $names->item( 0 ), PPFrame::STRIP_COMMENTS );
+                               if ( preg_match( '/^\d+$/', $name ) ) {
+                                       // For = suppression syntax {{#tag|thing|1=2=3=4}}
+                                       $lastNumberedNode = $arg;
+                               } else {
+                                       $values = $xpath->query( 'value', $arg );
+                                       $attributes[$name] = trim( $frame->expand( $values->item( 0 ) ) );
+                               }
+                       }       
+               }
+
+               if ( !$lastNumberedNode ) {
+                       $inner = null;
+               } else {
+                       $values = $xpath->query( 'value', $lastNumberedNode );
+                       $inner = $frame->expand( $values->item( 0 ) );
+               }
+               $params = array(
+                       'name' => $tagName,
+                       'inner' => $inner,
+                       'attributes' => $attributes
+               );
+               return $parser->extensionSubstitution( $params, $frame );
+       }
 }
 
index ea02a6e..0e220cd 100644 (file)
@@ -166,6 +166,7 @@ class Parser
                $this->setFunctionHook( 'special',          array( 'CoreParserFunctions', 'special'          ) );
                $this->setFunctionHook( 'defaultsort',      array( 'CoreParserFunctions', 'defaultsort'      ), SFH_NO_HASH );
                $this->setFunctionHook( 'filepath',         array( 'CoreParserFunctions', 'filepath'         ), SFH_NO_HASH );
+               $this->setFunctionHook( 'tag',              array( 'CoreParserFunctions', 'tagObj'           ), SFH_OBJECT_ARGS );
 
                if ( $wgAllowDisplayTitle ) {
                        $this->setFunctionHook( 'displaytitle', array( 'CoreParserFunctions', 'displaytitle' ), SFH_NO_HASH );
@@ -3661,7 +3662,8 @@ class Parser
         *
         * @param array $params Associative array of parameters:
         *     name       DOMNode for the tag name
-        *     attrText   DOMNode for unparsed text where tag attributes are thought to be
+        *     attr       DOMNode 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
@@ -3671,15 +3673,18 @@ class Parser
                static $n = 1;
 
                $name = $frame->expand( $params['name'] );
-               $attrText = is_null( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
-               $content = is_null( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
+               $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
+               $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
 
                $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $n++) . $this->mMarkerSuffix;
                
                if ( $this->ot['html'] ) {
                        $name = strtolower( $name );
 
-                       $params = Sanitizer::decodeTagAttributes( $attrText );
+                       $attributes = Sanitizer::decodeTagAttributes( $attrText );
+                       if ( isset( $params['attributes'] ) ) {
+                               $attributes = $attributes + $params['attributes'];
+                       }
                        switch ( $name ) {
                                case 'html':
                                        if( $wgRawHtml ) {
@@ -3693,15 +3698,15 @@ class Parser
                                        break;
                                case 'math':
                                        $output = $wgContLang->armourMath(
-                                               MathRenderer::renderMath( $content, $params ) );
+                                               MathRenderer::renderMath( $content, $attributes ) );
                                        break;
                                case 'gallery':
-                                       $output = $this->renderImageGallery( $content, $params );
+                                       $output = $this->renderImageGallery( $content, $attributes );
                                        break;
                                default:
                                        if( isset( $this->mTagHooks[$name] ) ) {
                                                $output = call_user_func_array( $this->mTagHooks[$name],
-                                                       array( $content, $params, $this ) );
+                                                       array( $content, $attributes, $this ) );
                                        } else {
                                                throw new MWException( "Invalid call hook $name" );
                                        }
index 1e311fc..ec6737b 100644 (file)
@@ -335,6 +335,7 @@ $magicWords = array(
        'special'                => array( 0,    'special',               ),
        'defaultsort'            => array( 1,    'DEFAULTSORT:', 'DEFAULTSORTKEY:', 'DEFAULTCATEGORYSORT:' ),
        'filepath'               => array( 0,    'FILEPATH:'              ),
+       'tag'                    => array( 0,    'tag'                    ),
 );
 
 /**
@@ -3115,4 +3116,7 @@ $1',
 'signature'      => '[[{{ns:user}}:$1|$2]]', # don't translate or duplicate this message to other languages
 'signature-anon' => '[[{{#special:Contributions}}/$1|$2]]', # don't translate or duplicate this message to other languages
 
+# CoreParserFunctions
+'unknown_extension_tag'   => 'Unknown extension tag "$1"',
+
 );