PmWiki /
Custom Markup
administrators (intermediate)
IntroductionPmWiki's markup translation engine is handled by a set of rules; each rule searches for a specific pattern in the markup text and replaces it with some replacement text. Internally, this is accomplished by using PHP's "preg_replace" function. Rules are added to the translation engine via PmWiki's Markup() function, which looks likeMarkup($name, $when, $pattern, $replace);
$name is a unique name (a string) given to the rule, $when says when the rule should be applied relative to other rules, $pattern is the pattern to be searched for in the markup text, and $replace is what the pattern should be replaced with.
For example, here's the code that creates the rule for ''emphasized text'' (in scripts/stdmarkup.php):
Markup("em", "inline", "/''(.*?)''/", "<em>$1</em>");
<em> and </em> .
The first two parameters to Markup() are used to specify the sequence in which rules should be applied. The first parameter provides a name for a rule -- "em " in the example above. We could've chosen other names such as "'' ", or even "twosinglequotes ". In general PmWiki uses the markup itself to name the rule (i.e., PmWiki uses "'' " instead of "em "), but to keep this example easier to read later on we'll use a mnemonic name for now.
The second parameter says that this rule is to be done along with the other "inline" markups. PmWiki divides the translation process into a number of phases:
_begin start of translation fulltext translations to be performed on the full text split conversion of the full markup text into lines to be processed directives directive processing inline inline markups links conversion of [[links]], url-links, and WikiWords block block markups style style handling _end end of translationThus, specifying "inline" for the second parameter says that this rule should be applied when the other "inline" rules are being performed. If we want a rule to be performed with the directives -- i.e., before inline rules are processed, we would specify "directives" or "<inline" for the second parameter. The third parameter is a Perl-compatible regular expression. Basically, it is a slash, a regular expression, another slash, and a set of optional modifiers. The example uses the pattern string "/''(.*?)''/" , which uses ''(.*)'' as the regular expression and no options. (The regular expression says "find two single quotes in succession, then as few arbitrary characters as are needed to make the match find something, then two additional single quotes in succession"; the parentheses "capture" a part of the wikitext for later use.)
The fourth parameter is the replacement text that should be inserted instead of the marked-up wikitext. You can use $1 , $2 , etc. to insert the text from the first, second etc. parenthesised part of the regular expression.
In the example, we have "<em>$1</em>" , which is an <em> , the text matched by the first parentheses (i.e. by the .*? section of the pattern), and </em> .
Here's a rule for @@monospaced@@ text:
Markup("@@", "inline", "/@@(.*?)@@/", "<code>$1</code>");
[:comment ...:] directive that is simply removed from the output:
Markup("comment", "directives", "/\\[:comment .*?:\\]/", '');
'''strong emphasis''' ? We have to be a bit careful here, because although this translation should be performed along with other inline markup, we also have to make sure that the rule for ''' is handled before the rule for '' , because ''' also contains '' . The second parameter to Markup() can be used to specify the new rule's relationship to any other rule:
Markup("strong", "<em", "/'''(.*?)'''/", "<strong>$1</strong>");
DisableMarkup("strong")
?action=ruleset ", which displays the set of defined markup rules in the sequence in which they will be processed. You can see it at CustomMarkup?action=ruleset.
Other common examplesDefine a custom markup to produce a specific HTML or Javascript sequenceSuppose an admin wants to have a simple "(:example:) " markup that will always produce a fixed HTML string in the output, such as for a webring, Google AdSense display, or Javascript. The Markup() call to do this would be:
Markup('example', 'directives', '/\\(:example:\\)/', Keep("<div class='example'><p>Here is a <a target='_blank' href='http://www.example.com'>link</a> to <em>example.com</em></p></div>") );
Define a markup to call a custom function that returns contentAn 'e' option on the$pattern parameter will cause the $replace parameter to be treated as a PHP expression to be evaluated instead of replacement text. Thus, a markup to produce a random number between 1 and 100 might look like:
Markup('random', 'directives', '/\\(:random:\\)/e', "rand(1, 10)"); Markup('randomargs', 'directives', '/\\(:random (\\d+) (\\d+):\\)/e', "rand('$1', '$2')"); (:random 50 100:) to generate a random number between 50 and 100.
Note: Be very careful with the /e modifier in regular expressions; malicious authors may be able to pass strings that cause arbitrary and undesirable PHP functions to be executed.
For a PmWiki function to help with parsing arbitrary sequences of arguments and key=value pairs, see Cookbook:ParseArgs.
<< Custom InterMap | Documentation Index | Custom WikiStyles >>
How can I embed JavaScript into a page's output? There are several ways to do this. The Cookbook:JavaScript recipe describes a simple means for embedding static JavaScript into web pages using custom markup. For editing JavaScript directly in wiki pages (which can pose various security risks), see the JavaScript-Editable recipe. For JavaScript that is to appear in headers or footers of pages, the skin template can be modified directly, or <script> statements can be inserted using the$HTMLHeaderFmt array.
|