[pmwiki-users] Conditional extensions

Patrick R. Michaud pmichaud at pobox.com
Thu Apr 21 13:01:12 CDT 2005


(Resending to listserv w/correct address.)

On Thu, Apr 21, 2005 at 07:47:02PM +0200, Dominique Faure wrote:
> At Thursday, April 21, 2005 3:23 PM [GMT+1=CET], Patrick R. Michaud wrote:
> >Wow, what a clever (and impressive) implementation!
> >
> >Perhaps it can be shortened a bit...?
> >
> >$Conditions['expr'] = "ExprCondition(\$pagename, \$condparm)";
> >
> >function ExprCondition($pagename, $condparm) {
> > $condparm = str_replace('&&', '&&', $condparm);
> > $delims = '/(\\s*(and|or|xor|&&|\\|\\||!|\\(|\\))\\s*)/i';
> > $terms = preg_split($delims, $condparm, -1,
> >                     PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
> > foreach($terms as $i => $t)
> >   if(!preg_match($delims, $t))
> >     $terms[$i] = CondText($pagename, "if $t", 'TRUE') ? '1' : '0';
> > return @eval('return (' . implode(' ', $terms) . ');');
> >}
> 
> Thanks for the optimisation, but the space spec "\\s*" seems to be needed 
> within each operators in order *not* to be considered as a separator 
> itself. According to your regexp, the preg_split of "true || false" leads 
> to (quotes added):
> 
> $terms: Array
> (
>    [0] => true
>    [1] => " || "
>    [2] => "||"
>    [3] => false
> )
> 
> which can't be imploded easily

Oh.  Use this then:

   $delims = '/(\\s*(?:and|or|xor|&&|\\|\\||[!()])\\s*)/i';

The "?:" keeps the inner parens from being treated as a capture.  
Alternately, if you don't care about the \s*, you could probably do

   $delims = '/\\s*(?:and|or|xor|&&|\\|\\||[!()])\\s*/i';

and get the operands out without any spaces.

But beyond that, it's probably important to make sure that "and",
"or", and "xor" are on word boundaries, otherwise something like

   (:if expr match Main.WikiSandbox || author Pm:)

becomes

   $terms: Array(
      [0] => "match Main.WikiS"
      [1] => "and"
      [2] => "box"
      [3] => "||"
      [4] => "auth"
      [5] => "or"
      [6] => "Pm"
   )

But even \b and \B aren't good here, because of things like

   (:if expr match Galaxy.Andromeda:)
   (:if expr match Profiles.Author:)

so I think we have to actually delimit on required spaces and the 
ends of the string:

   $delims = '/(?:^|\\s+)(?:and|or|xor|&&|\\|\\||[!()])(?:\\s+|$)/i';

Pm



More information about the pmwiki-users mailing list