Extension:Control Structure Functions

From MediaWiki.org

Jump to: navigation, search

           

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
Control Structure Functions

Release status: beta

Implementation  Parser extension, Parser function
Description A collection of functions to regulate flow control such as branching instructions and loops.
Author(s)  David M. Sledge
Last Version  0.9.3 (2007-10-15)
MediaWiki  1.11.0 ≤ version < 1.12 (might work on earlier versions); See Loops for versions 1.12 and higher
License GNU GPL 2.0 or later
Download see below

check usage (experimental)

The Control Structure Functions (named after the group of php statements that regulate the flow of code execution) is a collection of functions for flow-control. The functions simulate while loops, do-while loops, if statements, and switch statements.

There are seven functions in this extension: #if, #ifeq, #ifexpr, #switch, #ifexist, #dowhile, and #while.

Note: This extension is obsolete for versions 1.12 and higher of MediaWiki, due to the changes in the preprocessor. (In fact, it doesn't even work under v1.12+.) Except for the loops, the latest version of Help:ParserFunctions under MW v1.12+ accomplishes everything that this extension does without the need for Character Escapes. For loop functionality, see the Loops extension, which was written specifically for v1.12+.

Contents

[edit] Don't These Parser Functions Already Exist?

Yes and no. The ParserFunctions extension has #if, #ifeq, #ifexpr, #switch, and #ifexist, and Loop Functions extension has #for and #foreach. The limitation of all those parser functions is that wiki markup is parsed before any parameters are passed to the underlying function. These functions bypass that limitation through character escapes (see below), and allow wiki markup to be parsed after the parameters have been passed.

It's possible that an extension (or more) already exists to overcome these limitations, but this one was written because they weren't found at the time of conception.

[edit] Characters Escapes

Many thanks to Gero Scholz (an author of DPL2) for pointing out this functionality in the DPL2 extension.

Sometimes it is desired that wiki markup be parsed (or remain unparsed) under certain conditions. Since certain characters or character sequences are processed before reaching the parser function, we have to escapes to prevent markup being parsed prematurely. MediaWiki does not have built-in mechanic for this, so we have to make our own:

  • \l (less than) is translated to <
  • \g (greater than) is translated to >

  • \o (open double curly braces) is translated to {{
  • \c (close double curly braces) is translated to }}
  • \p (pipe) is translated to |

  • \\ is translated to \

  • \n is translated to a newline

The first two translations make it possible to embed a wiki tag extension into a parameter of a parser function call. The next three translations make it possible to call a template, invoke a magic word, or call a parser function which prevents them from executing until conditions dictate that the results of such a call will be displayed. The next one is for times where you want to display text like "\p" without having it converted into a pipe, which is done by writing it as "\\p". The last one "\n" is not really necessary for parser functions, but it's defined by the character escapes tag extension, which the Control Structure Functions uses to translate the character escapes.

[edit] Example

The wiki code:

* {{ #vardefine: i | 0 }}{{
  #ifexpr:
  | {{ #var: i }} < 5
  | \o #vardefine: i \p \o #expr: \o #var: i \c + 1 \c \c
  | \o #vardefine: i \p \o #expr: \o #var: i \c - 1 \c \c
}}{{ #var: i }}

produces the following result:

  • 1

Alternatively, the escapes can be generated with the <esc> tag:

* {{ #vardefine: i | 0 }}{{
  #ifexpr:
  | {{ #var: i }} < 5
  | <esc>{{ #vardefine: i | {{ #expr: {{ #var: i }} + 1 }} }}</esc>
  | <esc>{{ #vardefine: i | {{ #expr: {{ #var: i }} + 2 }} }}</esc>
}}{{ #var: i }}

Normally without escapes, all the wiki markup is evaluated, resulting in:

  • 3

Note that both examples use the variables extension, and the latter example uses character escapes extension.

[edit] Functions

[edit] #if, #ifeq, #ifexpr, #switch, #ifexist

The syntax for these Control Structure Functions are similar to the ParserFunctions' version. The important difference is that nested templates, magic words, tags, other parser functions, and wiki tables may be nested without them being executed/parsed/evaluated before being passed to the underlying function. This is done with using escapes (see above).

[edit] Syntax

{{ #if: <condition string> | <then text (escaped)> | <else text (escaped, optional)> }}
{{ #ifeq: <text 1> | <text 2> | <equal text (escaped)> | <not equal text (escaped, optional)> }}
{{ #ifexist: <page name> | <page exists text (escaped)> | <page does not exist text (escaped, optional)> }}
{{ #ifexpr: <expression> | <then text (escaped)> | <else text (escaped, optional)> }}
{{#switch: <comparison value>
 | <value 1> = <result 1 (escaped)>
 | <value 2> = <result 2 (escaped)>
 | ...
 | <value n> = <result n (escaped)>
 | <default result (escaped)>
}}

{{#switch: <comparison value>
 | <value 1> = <result 1 (escaped)>
 | #default = <default result (escaped)>
 | <value 2> = <result 2 (escaped)>
 | ...
 | <value n> = <result n (escaped)>
}}

{{#switch: <comparison value>
| <value 1>
| <value 2>
| <value 3> = <result 1, 2, 3 (escaped)>
| ...
| <value n> = <result n (escaped)>
| <default result (escaped)>
}}

[edit] #while

{{#while}} performs a loop (i.e. it repeatedly parses a given wiki markup block statement) so long as a given condition is met.

{{
  #while: < "if" | "" >
  | <condition text (escaped)>
  | <block statement (escaped)>
}}

{{
  #while: < "ifeq" | "eq" >
  | <condition text 1 (escaped)>
  | <condition text 2 (escaped)>
  | <block statement (escaped)>
}}

{{
  #while: < "ifexpr" | "expr" >
  | <condition text (escaped)>
  | <block statement (escaped)>
}}

The first parameter specifies how the loop conditions are evaluated. The following control structures are supported: "if", "ifeq", and "ifexpr"—which can be written shorthand as "", "eq", and "expr" respectively. The conditions are evaluated as if those control structure functions had been called. Note: the "ifeq" function requires two condition parameters before the block statement.

The wiki markup:

{{ #vardefine: i | 0 }}{{
  #while: expr
  | <esc>{{ #var: i }} < 5</esc>
  |* <esc>{{ #var: i }}{{ #vardefine: i | {{ #expr: {{ #var: i }} + 1 }} }}</esc>
}}

produces the following:

  • 0
  • 1
  • 2
  • 3
  • 4

[edit] #dowhile

{{#dowhile}} performs exactly like {{#while}}, with the exception that the block statement is guaranteed to be parsed and displayed (if it results in displayable text) at least once.

[edit] Installation

There are two ways to install Control Structure Functions: by replacing ParserFunctions, or alongside ParserFunctions. Both installations require the character escapes tag extension.

[edit] Replacing ParserFunctions with Control Structure Functions

The Control Structure Functions require the character escapes tag extension and the LO Parser Functions extensions. Since Control Structure Functions only contain the functions dealing with flow-control, the remaining functions—#expr, #time, and #rel2abs—are in the LO Parser Functions extension.

Once the required extensions are installed, create the directory ControlStructureFunctions in your extensions directory. Then create two files in the new directory, named ControlStructureFunctions.php and ControlStructureFunctions.i18n.php. (Follow the links to get the source.)

Then put the following at the end of your LocalSettings.php:

require_once( "$IP/extensions/ControlStructureFunctions/ControlStructureFunctions.php" );

[edit] Alongside ParserFunctions

Note: With this installation the words "if", "ifeq", "ifexpr", "switch", "default", and "ifexist" are already in use with the ParserFunctions extension, so Control Structure Function extension uses the words "if2", "ifeq2", "ifexpr2", "switch2", "default2", and "ifexist2" instead.

The Control Structure Functions require the character escapes tag extension and the Expr.php file of the ParserFunctions extension.

Once the required components are installed, create the directory ControlStructureFunctions in your extensions directory. Then create two files in the new directory, named ControlStructureFunctions2.php and ControlStructureFunctions2.i18n.php. (Follow the links to get the source.)

Then put the following at the end of your LocalSettings.php:

require_once( "$IP/extensions/ControlStructureFunctions/ControlStructureFunctions2.php" );

[edit] Configuration Parameters

[edit] ExtCtrlStructFunc::$mMaxLoops

The static member ExtCtrlStructFunc::$mMaxLoops determines the total number of loops allowed by the #while and #dowhile parser functions. Setting it to zero disables the loop functions, and setting it to a negative value allows it to run within the limits of PHP's environment.

[edit] See also