Add function-like tag hooks. They are tags, which content is not preprocessed. Those...
authorVictor Vasiliev <vasilievvv@users.mediawiki.org>
Sat, 11 Jul 2009 13:03:35 +0000 (13:03 +0000)
committerVictor Vasiliev <vasilievvv@users.mediawiki.org>
Sat, 11 Jul 2009 13:03:35 +0000 (13:03 +0000)
RELEASE-NOTES
includes/parser/Parser.php

index 74aed7c..374c17c 100644 (file)
@@ -120,6 +120,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 19576) Moved id attribues from anchors accompanying section headers to
   the section headers themselves, removing the redundant anchor elements.
 * Removed name attribute from <a id="top"></a>.
+* Parser::setFunctionTagHook now can be used to add a new tag which is parsed at
+  preprocesor level.
 
 === Bug fixes in 1.16 ===
 
index dbc6e39..8755157 100644 (file)
@@ -92,7 +92,8 @@ class Parser
        # Persistent:
        var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables,
                $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex, $mPreprocessor,
-               $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList, $mVarCache, $mConf;
+               $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList, $mVarCache, $mConf,
+               $mFunctionTagHooks;
 
 
        # Cleared with clearState():
@@ -127,6 +128,7 @@ class Parser
                $this->mTagHooks = array();
                $this->mTransparentTagHooks = array();
                $this->mFunctionHooks = array();
+               $this->mFunctionTagHooks = array();
                $this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
                $this->mDefaultStripList = $this->mStripList = array( 'nowiki', 'gallery' );
                $this->mUrlProtocols = wfUrlProtocols();
@@ -3255,9 +3257,10 @@ class Parser
 
                $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
 
-               if ( $this->ot['html'] ) {
+               $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower($name)] ) &&
+                       ( $this->ot['html'] || $this->ot['pre'] );
+               if ( $this->ot['html'] || $isFunctionTag ) {
                        $name = strtolower( $name );
-
                        $attributes = Sanitizer::decodeTagAttributes( $attrText );
                        if ( isset( $params['attributes'] ) ) {
                                $attributes = $attributes + $params['attributes'];
@@ -3289,6 +3292,13 @@ class Parser
                                                }
                                                $output = call_user_func_array( $this->mTagHooks[$name],
                                                        array( $content, $attributes, $this ) );
+                                       } elseif( isset( $this->mFunctionTagHooks[$name] ) ) {
+                                               list( $callback, $flags ) = $this->mFunctionTagHooks[$name];
+                                               if( !is_callable( $callback ) )
+                                                       throw new MWException( "Tag hook for $name is not callable\n" );
+
+                                               $output = call_user_func_array( $callback,
+                                                       array( &$this, $frame, $content, $attributes ) );
                                        } else {
                                                $output = '<span class="error">Invalid tag extension name: ' .
                                                        htmlspecialchars( $name ) . '</span>';
@@ -3312,7 +3322,9 @@ class Parser
                        }
                }
 
-               if ( $name === 'html' || $name === 'nowiki' ) {
+               if( $isFunctionTag ) {
+                       return $output;
+               } elseif ( $name === 'html' || $name === 'nowiki' ) {
                        $this->mStripState->nowiki->setPair( $marker, $output );
                } else {
                        $this->mStripState->general->setPair( $marker, $output );
@@ -4233,6 +4245,24 @@ class Parser
                return array_keys( $this->mFunctionHooks );
        }
 
+       /**
+        * Create a tag function, e.g. <test>some stuff</test>.
+        * Unlike tag hooks, tag functions are parsed at preprocessor level.
+        * Unlike parser functions, their content is not preprocessed.
+        */
+       function setFunctionTagHook( $tag, $callback, $flags ) {
+               $tag = strtolower( $tag );
+               $old = isset( $this->mFunctionTagHooks[$tag] ) ?
+                       $this->mFunctionTagHooks[$tag] : null;
+               $this->mFunctionTagHooks[$tag] = array( $callback, $flags );
+
+               if( !in_array( $tag, $this->mStripList ) ) {
+                       $this->mStripList[] = $tag;
+               }
+
+               return $old;
+       }
+
        /**
         * FIXME: update documentation. makeLinkObj() is deprecated.
         * Replace <!--LINK--> link placeholders with actual links, in the buffer