HowTo: Create a MediaWiki Pretty Printer Extension
By Eric Hartwell - latest revision
April 8, 2006
This
article describes a pretty printer extension for
MediaWiki, the software that runs the various Wikimedia
projects.
- multiple languages, starting with PHP
- auto-language detection
- style sheets or inline font
- braces
WikiMedia Extensions
MediaWiki, the software that runs the various Wikimedia projects, allows
developers to write their own
extensions to
the wiki markup. An extension defines an XML-style tag which can be used in the
wiki editor like this:
<tagname attribute="some attribute"> some text </tagname>
The attributes and the text between the tags get passed on to a PHP function
you implement. This function can then return a HTML string that gets inserted
into the output in place of the tags and text. Note that the return string
should be HTML, not wiki markup.
Step 1: Basic PHP Pretty Printer Extension
A pretty printer for PHP is easy to implement in PHP, since the built-in
highlight_string function does
the parsing and coloring. It doesn't adjust the brackets or spacing, though.
The most basic PrettyPrinter extension simply uses highlight_string to apply
HTML formatting to the source text:
<?php
# PrettyPrinter WikiMedia extension
# With WikiMedia's extension mechanism it is possible to define new
tags of the form
# <PrettyPrinter> some text </PrettyPrinter>
# The function registered by the extension gets the text between the
tags as input and can transform it into arbitrary HTML code.
# Note: The output is not interpreted as WikiText but directly
included in the HTML output. So Wiki markup is not supported.
# To activate the extension, include it from your LocalSettings.php
with: include("extensions/PrettyPrinter.php");
$wgExtensionFunctions[]
= "wfPrettyPrinter";
function wfPrettyPrinter()
{
global $wgParser;
# Register the extension with the
WikiText parser.
# The first parameter is the name of the new tag. In this case
it defines the tag <PrettyPrinter> ... </PrettyPrinter>
# The second parameter is the callback function for processing
the text between the tags
$wgParser->setHook(
"PrettyPrintert",
"renderPrettyPrinter"
);
}
# The callback function for converting
the input text to HTML output
function
renderPrettyPrinterTranscript(
$input,
$argv ) {
# $argv is an array containing any
arguments passed to the extension like <example argument="foo"
bar>..
$output
= highlight_string(
$input, TRUE
);
return
$output;
}
?>
Install the extension by adding it to the end of your LocalSettings.php file (above the ?>):
include("extensions/PrettyPrinter.php");
Step 2: Smart PHP Pretty Printer Extension
We can considerably improve the utility of the extension by adding a few
simple features.
- The highlight_string() function requires a starting "<?php" and
ending "?>" before it will transform the text, but you're more likely
to use code snippets in a wiki. If they're missing, the extension
automatically adds them before the transform, then strips them from the
output.
- The highlight_string() adds leading and trailing line feeds. The
extension removes these.
- The source language can be specified through the src=""
attribute. Theoretically, it could be inferred from the input if not
specified.
- Common HTML tags (div, span, p, pre, code, blockquote) can be specified
as attributes. If a value is given for the attribute, it is output as the
class. For example,
<PrettyPrinter span="snippet"> ... </PrettyPrinter>
wraps the formatted output with
<span class="snippet"> ... </span>
- The extension passes unrecognized attribute/value pairs through to the
output unchanged: attribute or attribute="value".
<?php
# PrettyPrinter WikiMedia extension
# With WikiMedia's extension mechanism it is possible to define new tags of the
form <PrettyPrinter> some text </PrettyPrinter>
# The function registered by the extension gets the text between the tags as
input and can transform it into arbitrary HTML code.
# Note: The output is not interpreted as WikiText but directly included in the
HTML output. So Wiki markup is not supported.
# To activate the extension, include it from your LocalSettings.php with:
include("extensions/PrettyPrinter.php");
$wgExtensionFunctions[]
= "wfPrettyPrinter";
function wfPrettyPrinter()
{
# Register the extension with the WikiText
parser.
# The first parameter is the name of the new tag. In this case it defines
the tag <PrettyPrinter> ... </PrettyPrinter>
# The second parameter is the callback function for processing the text
between the tags
global $wgParser;
$wgParser->setHook(
"PrettyPrinter",
"renderPrettyPrinter"
);
}
# The callback function for converting the input
text to HTML output
function
renderPrettyPrinter(
$input, $argv
) {
# $argv is an array containing any arguments
passed to the extension like <example argument="foo" bar>..
# default language is php
$src =
"php";
# Parse the arguments. If there's a parameter
for a html tag, translate it to a class: span="code" => span class="code"
foreach ( $argv
as $name=>$value
) {
# No argument: argument is passed as
noarg=noarg
if ( $value
== $name) $value
= null;
# Special processing for certain tags
switch (
strtolower($name)
) {
case "src":
$src =
$value;
break;
case "div":
case "span":
case "p":
case "pre":
case "code":
case "blockquote":
if ( $value
) $prefix
.= "<"
. $name
. ' class="'
. $value
. '">';
else $prefix
.= "<"
. $name
. ">";
$postfix =
"</" .
$name .
">" .
$postfix;
break;
default:
# Unknown tag: pass through unchanged
tag=value
if (
$value ) $prefix
.= "<"
. $name
. '="'
. $value
. '">';
else $prefix
.= "<"
. $name
. ">";
$postfix =
"</" .
$name .
">" .
$postfix;
break;
}
}
# Language-specific processing
switch ($src)
{
case 'C':
case 'c':
break;
case 'php':
case 'PHP':
# Add ?php prefix and ? suffix if not
already there (required for parser)
if ( strncmp(
ltrim(
$input ) ,
"<?php",
5) !=
0) {
$strip =
true;
$input =
"<?php\n" .
$input .
"\n?>";
}
$output .=
highlight_string ($input,
TRUE );
if ($strip)
{
$output =
preg_replace(
"@<span.*?/span>@",
"",
$output,
1);
$output =
preg_replace(
"@<br /><br />.*?\?>@",
"",
$output,
1);
}
$output =
str_replace(
"\n",
"",
$output );
break;
}
return $prefix .
$output .
$postfix;
}
?>
Generic Pretty Printer
Wikipedia points to the open source
PrettyPrinter
source code formatter/beautifier at BerliOS Developer. It's written in C++,
which might be translated to php ...
Revision History
- April 8, 2006 - initial version