CustomMarkup-Talk

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).
    $str,
    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.
}

Outputs:

$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?

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

Rewrite your script to use preg_match(), see http://php.net/manual/en/reference.pcre.pattern.posix.php. --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.


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.
Example:

  • ORIGINAL
## CONFIG.PHP ADD-ON MARKUP SCRIPTING
Markup('support', 'directives', '/\\(:support:\\)/', 
Keep("<!-- Powered by: Support Site Live Help Credits -->
<div id="supportsite">
<script type="text/javascript" 
src="http://cs.supportsite.com/livehelp_js.php?eo=1&department=6&amp;serversession=1&amp;pingtimes=15&amp;username=<? 
echo'$_SESSION['username']'?> "></script>
<br><font style="font-family: verdana, helvetica, sans-serif; font-size: 8px; color: #000000;">Powered By:</font>
<a href="http://www.SupportSiteSource.com" 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>
</div>
<!-- copyright credits -->") );
  • MODIFICATION
## CONFIG.PHP ADD-ON MARKUP SCRIPTING
Markup('support', 'directives', '/\\(:support:\\)/', 
Keep("<!-- Powered by: Support Site Live Help Credits -->
<div id='supportsite'>
<script type='text/javascript' 
src='http://cs.supportsite.com/livehelp_js.php?eo=1&department=6&amp;serversession=1&amp;pingtimes=15&amp;'></script>
<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 http://www.pmwiki.org/wiki/PmWiki/CustomMarkup)
  'directives',
  "/\\(: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',
    'directives',
    "/\\(:nztopo (" . $qlocale . ")\s*(?:" . $qmods . "){0,7}\s*:\\)/i", #
    "NZTopo_Parse");

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.