Summary: Talk page for improving CustomMarkup

Using Markup in a namespace

Giving a recipe a namespace is useful to encapsulate it to avoid name collisions and avoid side effects.

When supplying the callback function to Markup, or any other function that uses a callback, ensure that the namespace name is prepended to the function name, e.g.

Markup($name, $when, $pattern, __NAMESPACE__ . '\callback_function')

Remember to prepend global function names with a "\" to fully quality the function name, e.g.

\Keep () or \ParseArgs ()

This is great and indeed now with PHP 5.3 we can think about moving the PmWiki functions to our own namespace. I have moved it from the main page only to give it some thought how best to proceed and document it. ReviewMe --Petko

Is there any good way to integrate inside existing syntax?

For example, I have (:Mini:) directive or any other (:...:) directive. I want to add something to $HTMLHeaderFmt / $HTMLFooterFmt when this directive is called on wiki-page. Of course, keeping source recipe's code intaсt, using only (farm)config.php modification. Is there any way to do it?

Finar November 20, 2020, at 06:16 PM

It depends on the recipe but usually if you define in config.php, before including the recipe, a Markup() call with the same $name, $when and $pattern, and a custom $replace_function, then that replace function will be called instead of the one defined in the recipe. Your custom function can first do something you want and then call the recipe function. For example:

Markup('(:mini:)', 'directives', '/\\(:mini (.+):\\)/', "Finar_MiniConf");
function Finar_MiniConf($m) {
  # your custom code
  global $HTMLHeaderFmt, $HTMLFooterFmt;
  $HTMLHeaderFmt['Finar-mini'] = '<script...>';
  # call recipe function if needed
  return MiniConf($m);
# include the recipe here

This can also be done to core markup rules. --Petko November 20, 2020, at 06:32 PM

What symbols are recommended for use in Custom Markup?

If I want to create my Custom Markup (for example for <mark>marked</mark> html-code), what symbols are better to use for this?

For example:

 This is $$marked$$ or
 This is ~~marked~~ or
 This is ==marked== or
 ... ??

The question is mostly about future development: if I will create more custom markup, are there any recommended principles how to do it? Finar May 03, 2020, at 02:43 PM

If there is any way I could possibly use WikiStyles like %mark% some text %% I would use these and style span.mark in CSS. If there is a way to reuse some current markup you don't need, like the <ins>...</ins> markup {+inserted text+} inserted text I'd probably just style the "ins" tag in css to have a yellow background, or even redefine the markup to produce the <mark> tags instead of ins. If I must select a new markup, I'd first review what would be less likely to conflict with the most popular recipes listed at Cookbook:IndexByRating and for example Cookbook:MarkupExtensions. I would not select markup that may interfere with my content, for example "==" and "$$" may not work well for websites that contain documentation or programming code. Next, I'd try to use something that is less likely to be a normal punctuation, and has more chance to be easily remembered, like the *bulleted lists or the !headings. Finally, if there is any way, I'd select different opening and closing markups like {_..._} or {~...~} -- this will probably make it easier for you to maintain. --Petko May 12, 2020, at 02:22 PM

Thank you very much for so complex answer! Finar May 12, 2020, at 04:08 PM

Evaluation with $replace_function being the name of the function to call

What are the prerequisites for using Markup($name, $when, $pattern, $replace_function); # if evaluation is needed with $replace_function being the name of the function to call. - HansB June 15, 2017, at 10:13 AM

The feature is available and working since PmWiki 2.2.56 or newer for PHP 4.3 to 7.2+. But the PmWiki core as of 2.2.98 is not yet compatible with PHP 7.2. Also, the functions PCCF() and PPRE() will not be available for PHP 7.2 (if you use $*Patterns with evaluation), and Pm and I have not yet decided how to work around this. --Petko June 15, 2017, at 01:24 PM

Thank you! I have been making use of PPRE() quite a lot, and just now been working on fox.php to replace these calls with preg_replace_callback(). The result is looking better than the original, but I am not a PHP expert. And I am relying on PHP 5.4 or newer I think. Example new code snippet:

# {$$var} replacements
$str = preg_replace_callback('/\\{\\$\\$([a-z][-_\\w]*)\\}/i', 
    function($m) use($fx, $tg) { 
      return FoxValue($fx, $tg, $m[0], $m[1]);
    }, $str);

If I understand correctly, for anonymous functions use($var) can only be used with PHP 5.4 or newer. But it certainly helps to pass on other arguments to the function called (FoxValue() here) within the anonymous function, which does the replacement work. I do not know how to do this nicely for PHP versions before 5.4. - HansB June 15, 2017, at 01:53 PM

Yes, anon functions are available since 5.3, but I believe "use" was buggy until 5.3.7. Note, you may need to write "use(&$fx, &$tg)" if $fx and $tg change between calls. (For the moment, Pm prefers the core keep the PHP 5.2 compatibility, so I'll have to figure out another way, for the moment it is not pretty). --Petko June 15, 2017, at 02:13 PM

Thanks! In the end I decided to keep Fox in line with PmWiki regards PHP backwards compatibility. The code adapted is not so pretty, for the template variable replacements, instead of using "use($fx, $tg)" I rely on making a copy of these variables temporary global, to have them available in the callback function, and unsetting these globals straight afterwards. - HansB June 16, 2017, at 05:20 PM

If you like to type, you could use a utility singular class:

class MyReplaceCallback {
    public function replace ($pat, $rep, $in, $vars) {
        $this->rep  = $rep ;
        $this->vars = $vars;
        return preg_replace_callback($pat, array($this, 'cb'), $in);

    private function cb ($m) {
        $rep  = $this->rep;
        return $rep($m, $this->vars);

Example of usage:

$mr = new MyReplaceCallback;  # No parameters, so could be used multiple times.

$fx  = 'This is $fx';
$tg  = 'This is $tg';
$str = 'fx="{$$fx}", tg="{$$tg}" xx="{$$xx}"';

echo "\$str = '$str' before.\n";

$str = $mr->replace('/\\{\\$\\$([a-z][-_\\w]*)\\}/i',
    'FoxValueCB',    # Will be called with $m and 4th parm (below).
    compact('fx', 'tg')  # Passes array('fx'=>$fx, 'tg'=>$tg)

echo "\$str = '$str' after.\n";

function FoxValueCB($m, $vars) {
    extract($vars);  # Converts array passed in 4th parm back into variables.
    return FoxValue($fx, $tg, $m[0], $m[1]);

function FoxValue($fx, $tg, $m0, $m1) {  # Just a dumb example.
    return @$$m1 . "";  # Avoid warning if not defined.


$str = 'fx="{$$fx}", tg="{$$tg}" xx="{$$xx}"' before.
$str = 'fx="This is $fx", tg="This is $tg" xx=""' after.

ChuckG December 07, 2017, at 10:11 PM

How do you recommend updating a recipe that uses eregi?

Deprecated: Function eregi() is deprecated in /home/ttcorgnz/public_html/pmwiki/cookbook/totalcounter.php on line 228

Rewrite your script to use preg_match(), see --Petko July 21, 2014, at 07:32 AM

If you want a markup to produce something that is interpreted by wiki be careful. E.g. if I you want a style, I start by coding

  • Markup('{red}', '_begin', '/{red}/', '>>red<<');

However, PmWiki will show the text >>red<< instead of interpreting the style and changing the color. This is because the markup handling styles looks for &lt;&lt; .... &gt;&gt; . Thus, what I need is

  • Markup('{red}', '_begin', '/{red}/', '&lt;&lt;red&gt;&gt;');

To make sure the ouput of a markup is understood, one better reads the definition of the consumer, in this case in stdmarkup.php.

Using <br> , to break lines.

parallel use of the " <br> " symbol, to break lines

If you want to use the " <br> " symbol, to break lines,
like in .html pages
(parallel to the " \\ " symbol),
put the following in your config.php file:

## using <br> , to break lines.
## optional, if you may have <br clear='all'>
## Markup('<br clear=all>','inline','/&lt;br\\s+clear=([\'"]?)all\\1\\s*\\/?&gt;/i',"<br clear='all' />");
## One thing to know is that the symbols "<" and ">" are encoded in the page 
## source text as "&lt;" and "&gt;" and in custom markup the encoded ones should 
## be used.
Markup('<br>','inline','/&lt;br\\s*\\/?&gt;/i',"<br />");

How can I use Custom MarkUp Directives that include JavaScript references that use single and double quotes?

Well, now this one is tricky. Short answer is, inside the double quotes, only use single quotes and it should work fine. On a live site, one issue that was encountered was the inclusion of PHP scripting to perform text replacement inside JavaScript to add a username to the session of the site from the originating site if the _SESSION['username'] variable was already set on the site. Unfortunately, since the code markup to be retained was using double quotes to encapsulate the code, the inner code needed to use all single quotes which included the PHP markup as well. Theoretically, single back-quotes could have been used for the _SESSION array element perhaps, but mixing as little as possible will be more solid in the code base since there are so many with which to start. So, no pre-assigned username, but the rest works fine. (Also, in this example, the end credits tagline was reduced even though it could very well have been retained.

Markup('support', 'directives', '/\\(:support:\\)/', 
Keep("<!-- Powered by: Support Site Live Help Credits -->
<div id="supportsite">
<script type="text/javascript" 
echo'$_SESSION['username']'?> "></script>
<br><font style="font-family: verdana, helvetica, sans-serif; font-size: 8px; color: #000000;">Powered By:</font>
<a href="" alt="Support Site Live Help" target="_blank" 
style="font-family: verdana, helvetica, sans-serif; font-size: 10px; color: #11498e; text-decoration: none; 
font-weight: bold;">SupportSiteCredits</a>
<!-- copyright credits -->") );
Markup('support', 'directives', '/\\(:support:\\)/', 
Keep("<!-- Powered by: Support Site Live Help Credits -->
<div id='supportsite'>
<script type='text/javascript' 
<br></div> <!-- copyright credits -->") );

An example of removing Markup_e from a cookbook recipe.

With thanks to Dominique and Petko.

The original markup:

Markup_e( 'NZTopo', # an internal PmWiki function that defines the custom markup for the wiki (see PmWiki:CustomMarkup)
  "/\\(:nztopo (" . $qlocale . ")\s*(?:" . $qmods . "){0,7}\s*:\\)/i", # 
  "Keep(NZTopo_Parse(\$m[1], \$m[2], \$m[3], \$m[4], \$m[5], \$m[6], \$m[7], \$m[8], \$m[9]))" );

The updated markup

Markup( 'NZTopo',
    "/\\(:nztopo (" . $qlocale . ")\s*(?:" . $qmods . "){0,7}\s*:\\)/i", #

In additional the following was updated

function NZTopo_Parse($m) { # parameters p1, p2, ... p9 replaced
  list( , $p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $p9) = $m; # added line, note the first comma
... unchanged ...
  return Keep($retval . $debugval); # added Keep

This is a talk page for improving PmWiki.CustomMarkup.