diff options
Diffstat (limited to 'includes/cbt')
-rw-r--r-- | includes/cbt/CBTCompiler.php | 35 | ||||
-rw-r--r-- | includes/cbt/CBTProcessor.php | 81 | ||||
-rw-r--r-- | includes/cbt/README | 44 |
3 files changed, 79 insertions, 81 deletions
diff --git a/includes/cbt/CBTCompiler.php b/includes/cbt/CBTCompiler.php index 17f43500..75955797 100644 --- a/includes/cbt/CBTCompiler.php +++ b/includes/cbt/CBTCompiler.php @@ -9,8 +9,8 @@ require_once( dirname( __FILE__ ) . '/CBTProcessor.php' ); -/** - * Push a value onto the stack +/** + * Push a value onto the stack * Argument 1: value */ define( 'CBT_PUSH', 1 ); @@ -51,7 +51,7 @@ class CBTOp { } function name() { - $opcodeNames = array( + $opcodeNames = array( CBT_PUSH => 'PUSH', CBT_CAT => 'CAT', CBT_CATS => 'CATS', @@ -102,7 +102,7 @@ class CBTCompiler { } else { $text = true; } - + return $text; } @@ -121,13 +121,13 @@ class CBTCompiler { /** * Recursive workhorse for text mode. - * - * Processes text mode starting from offset $p, until either $end is - * reached or a closing brace is found. If $needClosing is false, a + * + * Processes text mode starting from offset $p, until either $end is + * reached or a closing brace is found. If $needClosing is false, a * closing brace will flag an error, if $needClosing is true, the lack - * of a closing brace will flag an error. + * of a closing brace will flag an error. * - * The parameter $p is advanced to the position after the closing brace, + * The parameter $p is advanced to the position after the closing brace, * or after the end. A CBTValue is returned. * * @private @@ -136,7 +136,7 @@ class CBTCompiler { $in =& $this->mText; $start = $p; $atStart = true; - + $foundClosing = false; while ( $p < $end ) { $matchLength = strcspn( $in, CBT_BRACE, $p, $end - $p ); @@ -162,9 +162,9 @@ class CBTCompiler { $this->mOps[] = $this->op( CBT_CAT, substr( $in, $p, $matchLength ) ); } - // Advance the pointer + // Advance the pointer $p = $pToken + 1; - + // Check for closing brace if ( $in[$pToken] == '}' ) { $foundClosing = true; @@ -184,7 +184,7 @@ class CBTCompiler { $atStart = false; } else { $this->mOps[] = $this->op( CBT_CATS ); - } + } } if ( $foundClosing && !$needClosing ) { $this->error( 'Errant closing brace', $p ); @@ -200,12 +200,12 @@ class CBTCompiler { /** * Recursive workhorse for function mode. * - * Processes function mode starting from offset $p, until either $end is - * reached or a closing brace is found. If $needClosing is false, a + * Processes function mode starting from offset $p, until either $end is + * reached or a closing brace is found. If $needClosing is false, a * closing brace will flag an error, if $needClosing is true, the lack - * of a closing brace will flag an error. + * of a closing brace will flag an error. * - * The parameter $p is advanced to the position after the closing brace, + * The parameter $p is advanced to the position after the closing brace, * or after the end. A CBTValue is returned. * * @private @@ -364,4 +364,3 @@ class CBTCompiler { '; } } - diff --git a/includes/cbt/CBTProcessor.php b/includes/cbt/CBTProcessor.php index 31d1b60a..4fa1a93b 100644 --- a/includes/cbt/CBTProcessor.php +++ b/includes/cbt/CBTProcessor.php @@ -2,7 +2,7 @@ /** * PHP version of the callback template processor - * This is currently used as a test rig and is likely to be used for + * This is currently used as a test rig and is likely to be used for * compatibility purposes later, where the C++ extension is not available. */ @@ -44,9 +44,9 @@ function cbt_value( $text = '', $deps = array(), $isTemplate = false ) { /** * A dependency-tracking value class - * Callback functions should return one of these, unless they have + * Callback functions should return one of these, unless they have * no dependencies in which case they can return a string. - */ + */ class CBTValue { var $mText, $mDeps, $mIsTemplate; @@ -175,7 +175,7 @@ class CBTProcessor { /** * Execute the template. - * If $compile is true, produces an optimised template where functions with static + * If $compile is true, produces an optimised template where functions with static * dependencies have been replaced by their return values. */ function execute( $compile = false ) { @@ -204,7 +204,7 @@ class CBTProcessor { $context = rtrim( str_replace( "\t", " ", substr( $this->mText, $startLine, $endLine - $startLine ) ) ); $text .= htmlspecialchars( $context ) . "\n" . str_repeat( ' ', $pos - $startLine ) . "^\n</pre>\n"; - } + } wfProfileOut( $fname ); return $text; } @@ -223,7 +223,7 @@ class CBTProcessor { return $this->doOpenText( $start, $end, false ); } - /** + /** * Escape text for a template if we are producing a template. Do nothing * if we are producing plain text. */ @@ -237,13 +237,13 @@ class CBTProcessor { /** * Recursive workhorse for text mode. - * - * Processes text mode starting from offset $p, until either $end is - * reached or a closing brace is found. If $needClosing is false, a + * + * Processes text mode starting from offset $p, until either $end is + * reached or a closing brace is found. If $needClosing is false, a * closing brace will flag an error, if $needClosing is true, the lack - * of a closing brace will flag an error. + * of a closing brace will flag an error. * - * The parameter $p is advanced to the position after the closing brace, + * The parameter $p is advanced to the position after the closing brace, * or after the end. A CBTValue is returned. * * @private @@ -254,7 +254,7 @@ class CBTProcessor { $in =& $this->mText; $start = $p; $ret = new CBTValue( '', array(), $this->mCompiling ); - + $foundClosing = false; while ( $p < $end ) { $matchLength = strcspn( $in, CBT_BRACE, $p, $end - $p ); @@ -270,15 +270,15 @@ class CBTProcessor { // Output the text before the brace $ret->cat( substr( $in, $p, $matchLength ) ); - // Advance the pointer + // Advance the pointer $p = $pToken + 1; - + // Check for closing brace if ( $in[$pToken] == '}' ) { $foundClosing = true; break; } - + // Handle the "{fn}" special case if ( $pToken > 0 && $in[$pToken-1] == '"' ) { wfProfileOut( $fname ); @@ -290,7 +290,7 @@ class CBTProcessor { $ret->cat( $val ); } else { // Process the function mode component - wfProfileOut( $fname ); + wfProfileOut( $fname ); $ret->cat( $this->doOpenFunction( $p, $end ) ); wfProfileIn( $fname ); } @@ -300,19 +300,19 @@ class CBTProcessor { } elseif ( !$foundClosing && $needClosing ) { $this->error( 'Unclosed text section', $start ); } - wfProfileOut( $fname ); + wfProfileOut( $fname ); return $ret; } /** * Recursive workhorse for function mode. * - * Processes function mode starting from offset $p, until either $end is - * reached or a closing brace is found. If $needClosing is false, a + * Processes function mode starting from offset $p, until either $end is + * reached or a closing brace is found. If $needClosing is false, a * closing brace will flag an error, if $needClosing is true, the lack - * of a closing brace will flag an error. + * of a closing brace will flag an error. * - * The parameter $p is advanced to the position after the closing brace, + * The parameter $p is advanced to the position after the closing brace, * or after the end. A CBTValue is returned. * * @private @@ -383,8 +383,8 @@ class CBTProcessor { } } - // The dynamic parts of the string are still represented as functions, and - // function invocations have no dependencies. Thus the compiled result has + // The dynamic parts of the string are still represented as functions, and + // function invocations have no dependencies. Thus the compiled result has // no dependencies. $val = new CBTValue( "{{$compiled}}", array(), true ); } @@ -393,7 +393,7 @@ class CBTProcessor { /** * Execute a function, caching and returning the result value. - * $tokens is an array of CBTValue objects. $tokens[0] is the function + * $tokens is an array of CBTValue objects. $tokens[0] is the function * name, the others are arguments. $p is the string position, and is used * for error messages only. */ @@ -403,12 +403,12 @@ class CBTProcessor { } $fname = 'CBTProcessor::doFunction'; wfProfileIn( $fname ); - + $ret = new CBTValue; - + // All functions implicitly depend on their arguments, and the function name - // While this is not strictly necessary for all functions, it's true almost - // all the time and so convenient to do automatically. + // While this is not strictly necessary for all functions, it's true almost + // all the time and so convenient to do automatically. $ret->addDeps( $tokens ); $this->mCurrentPos = $p; @@ -453,25 +453,25 @@ class CBTProcessor { // If the output was a template, execute it $val->execute( $this ); - + if ( $this->mCompiling ) { // Escape any braces so that the output will be a valid template $val->templateEscape(); - } + } $val->removeDeps( $this->mIgnorableDeps ); $ret->addDeps( $val ); $ret->setText( $val->getText() ); if ( CBT_DEBUG ) { - wfDebug( "doFunction $func args = " - . var_export( $tokens, true ) - . "unexpanded return = " + wfDebug( "doFunction $func args = " + . var_export( $tokens, true ) + . "unexpanded return = " . var_export( $unexpanded, true ) - . "expanded return = " - . var_export( $ret, true ) + . "expanded return = " + . var_export( $ret, true ) ); } - + wfProfileOut( $fname ); return $ret; } @@ -500,12 +500,12 @@ class CBTProcessor { } if ( $condition->getText() != '' ) { - return new CBTValue( $trueBlock->getText(), + return new CBTValue( $trueBlock->getText(), array_merge( $condition->getDeps(), $trueBlock->getDeps() ), $trueBlock->mIsTemplate ); } else { if ( !is_null( $falseBlock ) ) { - return new CBTValue( $falseBlock->getText(), + return new CBTValue( $falseBlock->getText(), array_merge( $condition->getDeps(), $falseBlock->getDeps() ), $falseBlock->mIsTemplate ); } else { @@ -529,12 +529,11 @@ class CBTProcessor { return '}'; } - /** + /** * escape built-in. - * Escape text for inclusion in an HTML attribute + * Escape text for inclusion in an HTML attribute */ function bi_escape( $val ) { return new CBTValue( htmlspecialchars( $val->getText() ), $val->getDeps() ); } } - diff --git a/includes/cbt/README b/includes/cbt/README index cffcef2f..30581661 100644 --- a/includes/cbt/README +++ b/includes/cbt/README @@ -1,7 +1,7 @@ Overview -------- -CBT (callback-based templates) is an experimental system for improving skin +CBT (callback-based templates) is an experimental system for improving skin rendering time in MediaWiki and similar applications. The fundamental concept is a template language which contains tags which pull text from PHP callbacks. These PHP callbacks do not simply return text, they also return a description of @@ -15,24 +15,24 @@ efficiency gains and techniques. TemplateProcessor was the first element of this experiment. It is a class written in PHP which parses a template, and produces either an optimised template with dependencies removed, or the output text itself. I found that even with a heavily optimised template, this processor was -not fast enough to match the speed of the original MonoBook. +not fast enough to match the speed of the original MonoBook. To improve the efficiency, I wrote TemplateCompiler, which takes a template, preferably pre-optimised by TemplateProcessor, and generates PHP code from it. The generated code is a single expression, concatenating static text and -callback results. This approach turned out to be very efficient, making -significant time savings compared to the original MonoBook. +callback results. This approach turned out to be very efficient, making +significant time savings compared to the original MonoBook. -Despite this success, the code has been shelved for the time being. There were +Despite this success, the code has been shelved for the time being. There were a number of unresolved implementation problems, and I felt that there were more pressing priorities for MediaWiki development than solving them and bringing -this module to completion. I also believe that more research is needed into +this module to completion. I also believe that more research is needed into other possible template architectures. There is nothing fundamentally wrong with the CBT concept, and I would encourage others to continue its development. The problems I saw were: -* Extensibility. Can non-Wikimedia installations easily extend and modify CBT +* Extensibility. Can non-Wikimedia installations easily extend and modify CBT skins? Patching seems to be necessary, is this acceptable? MediaWiki extensions are another problem. Unless the interfaces allow them to return dependencies, any hooks will have to be marked dynamic and thus inefficient. @@ -51,14 +51,14 @@ The problems I saw were: Template syntax --------------- -There are two modes: text mode and function mode. The brace characters "{" +There are two modes: text mode and function mode. The brace characters "{" and "}" are the only reserved characters. Either one of them will switch from -text mode to function mode wherever they appear, no exceptions. +text mode to function mode wherever they appear, no exceptions. In text mode, all characters are passed through to the output. In function -mode, text is split into tokens, delimited either by whitespace or by +mode, text is split into tokens, delimited either by whitespace or by matching pairs of braces. The first token is taken to be a function name. The -other tokens are first processed in function mode themselves, then they are +other tokens are first processed in function mode themselves, then they are passed to the named function as parameters. The return value of the function is passed through to the output. @@ -68,39 +68,39 @@ Example: First brace switches to function mode. The function name is escape, the first and only parameter is {"hello"}. This parameter is executed. The braces around the parameter cause the parser to switch to text mode, thus the string "hello", -including the quotes, is passed back and used as an argument to the escape -function. +including the quotes, is passed back and used as an argument to the escape +function. Example: {if title {<h1>{title}</h1>}} -The function name is "if". The first parameter is the result of calling the +The function name is "if". The first parameter is the result of calling the function "title". The second parameter is a level 1 HTML heading containing -the result of the function "title". "if" is a built-in function which will +the result of the function "title". "if" is a built-in function which will return the second parameter only if the first is non-blank, so the effect of this is to return a heading element only if a title exists. As a shortcut for generation of HTML attributes, if a function mode segment is -surrounded by double quotes, quote characters in the return value will be -escaped. This only applies if the quote character immediately precedes the +surrounded by double quotes, quote characters in the return value will be +escaped. This only applies if the quote character immediately precedes the opening brace, and immediately follows the closing brace, with no whitespace. -User callback functions are defined by passing a function object to the +User callback functions are defined by passing a function object to the template processor. Function names appearing in the text are first checked against built-in function names, then against the method names in the function -object. The function object forms a sandbox for execution of the template, so +object. The function object forms a sandbox for execution of the template, so security-conscious users may wish to avoid including functions that allow arbitrary filesystem access or code execution. -The callback function will receive its parameters as strings. If the -result of the function depends only on the arguments, and certain things +The callback function will receive its parameters as strings. If the +result of the function depends only on the arguments, and certain things understood to be "static", such as the source code, then the callback function should return a string. If the result depends on other things, then the function should call cbt_value() to get a return value: return cbt_value( $text, $deps ); -where $deps is an array of string tokens, each one naming a dependency. As a +where $deps is an array of string tokens, each one naming a dependency. As a shortcut, if there is only one dependency, $deps may be a string. |