[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