(?:(?>[^()]*)|(?P>parenexpr))*)\\))";
$first = true;
while (preg_match("/^\\s*(?:$parenexpr|$oneterm)/", $x, $t))
{
if ($dbg) echo "MATCH: $x -> $t[0]
\n";
if ($dbg) echo "parenexpr=$t[parenexpr], paren=$t[paren], expr=$t[expr]
\n";
if ($dbg) echo "t=".print_r($t,true)."
\n";
if ($t['paren']) {
if ($dbg) echo "Got paren
\n";
switch ($t['op']) {
case ',':
case '|':
case '+':
$op = 'or';
break;
case '-':
case '!':
$op = 'not';
break;
case '^':
case '&':
$op = 'and';
break;
default:
if ($first) $op = 'or';
else $op = 'and';
break;
}
if ($dbg) echo "Calling PA2 with \"$t[expr]\"
\n";
$z[] = array($op, ParseArgs2Recurse($t['expr'], $optpat));
} else {
#$z = ParseArgs($t['expr2'], $optpat);
if ($dbg) echo "NO paren, expr2=$t[expr2]
\n";
$v = preg_replace("/$KeepToken(\\d.*?)$KeepToken/e", "\$KPV['$1']", $t['expr2']);
if ($dbg) echo "v=$v
\n";
if ($dbg) echo "optname=$t[6], prefix=$t[prefix], v=$v
\n";
if ($t['6']) { $z['#'][] = $t['6']; $z[$t['6']] = $v; }
else { $z['#'][] = $t['prefix']; $z[$t['prefix']][] = $v; }
$z['#'][] = $v;
if ($dbg) echo "z=".print_r($z,true)."
\n";
}
$x = substr($x, strlen($t[0]));
$first = false;
if ($dbg) echo "EOL: x=$x
\n";
}
if ($dbg) echo "returning ".print_r($z,true)."
\n";
return $z;
}
## load pagelist template from page
function FPLTemplateLoad($pagename, $matches, $opt, &$tparts) {
global $Cursor, $FPLTemplatePageFmt, $RASPageName, $PageListArgPattern, $FmtV, $FmtPV;
$template = @$opt['template'];
if (!$template) $template = @$opt['fmt'];
$ttext = RetrieveAuthSection($pagename, $template, $FPLTemplatePageFmt);
$ttext = PVSE(Qualify($RASPageName, $ttext));
## save any escapes
$ttext = MarkupEscape($ttext);
## remove any anchor markups to avoid duplications
$ttext = preg_replace('/\\[\\[#[A-Za-z][-.:\\w]*\\]\\]/', '', $ttext);
## extract portions of template
$tparts = preg_split('/\\(:(template)\\s+(\\w+)\\s*(.*?):\\)/i', $ttext, -1,
PREG_SPLIT_DELIM_CAPTURE);
} //}}}
## extract args from (:template defaults .....:) and merge with options from (:pagelist :)
function FPLTemplateDefaults($pagename, $matches, &$opt, &$tparts) {
global $PageListArgPattern;
$i = 0;
while ($i < count($tparts)) {
if ($tparts[$i] != 'template') { $i++; continue; }
if ($tparts[$i+1] != 'defaults' && $tparts[$i+1] != 'default') { $i+=4; continue; }
$opt = array_merge(ParseArgs($tparts[$i+2], $PageListArgPattern), $opt);
array_splice($tparts, $i, 3);
}
SDVA($opt, array('class' => 'fpltemplate', 'wrap' => 'div'));
} //}}}
/* Comment:
Added capability of merging pagelist with any list supplied previously
by custom function.
*/
## get list of pages by calling MakePageList;
## merge lists if any $matches are supplied previously
function FPLTemplatePageList($pagename, &$matches, $opt, $tparts) {
global $MakePageListOpt;
$dbg = false;
# if we have parens then we do all MakePageList() work within parentheses.
# There is no capability of mixing parenthesis and non-parentheses.
if (is_array($opt[0])) {
if ($dbg) echo "opt[0] is an array...
\n";
foreach ($opt as $k => $newopt) {
if (is_numeric($k)) {
if ($dbg) echo "NEWOPT: ".print_r($newopt,true)."
\n";
if ($dbg) echo "PRE-MATCHES: ".(sizeof($matches)>10?'('.sizeof($matches).')':print_r($matches,true))."
\n";
if (is_array($newopt[1][0])) {
if ($dbg) echo "Calling recursively...
\n";
FPLTemplatePageList($pagename, $matches, $newopt[1], $tparts);
}
if ($newopt[1]['#']) {
$newmatch = MakePageList($pagename, $newopt[1], 0);
switch ($newopt[0]) {
case 'and':
$matches = array_intersect($matches, $newmatch);
break;
case 'not':
$matches = array_diff($matches, $newmatch);
break;
case 'or':
default:
$matches = array_unique(array_merge($matches, $newmatch));
break;
}
if ($dbg) echo "NEWMATCHES: ".(sizeof($newmatch)>10?'('.sizeof($newmatch).')':print_r($newmatch,true))."
\n";
if ($dbg) echo "POST-MATCHES: ".(sizeof($matches)>10?'('.sizeof($matches).')':print_r($matches,true))."
\n";
}
}
}
SDVA($MakePageListOpt, array('list' => 'default'));
$opt = array_merge((array)$MakePageListOpt, (array)$opt);
if (!@$opt['order'] && !@$opt['trail']) $opt['order'] = 'name';
$opt['=phase'] = PAGELIST_PRE;
PageListSort($matches, $opt, $pagename, $page);
if ($dbg) echo "after pre-sort: ".print_r($opt,true)."
\n";
$opt['=phase'] = PAGELIST_POST;
PageListSort($matches, $opt, $pagename, $page);
$matches = array_values($matches); // re-set indices
if ($dbg) echo "after post-sort: ".print_r($opt,true)."
\n";
} elseif ($opt['#']) {
if ($dbg) echo "no parens...
\n";
if (is_array($matches) && !empty($matches))
$matches = array_intersect($matches, MakePageList($pagename, $opt, 0));
else
$matches = array_merge($matches, MakePageList($pagename, $opt, 0));
}
} //}}}
/* Comment:
Added a start= parameter for (:pagelist .. :)
Added a {$$PageListCount} template variable,
for total $matches count before any slicing of $matches.
*/
## slice matches according to count= and start=
function FPLTemplateSliceList($pagename, &$matches, &$opt, $tparts) {
## count matches before any slicing and save value as template var {$$PageListCount}
$opt['PageListCount'] = $pagelistcount = count($matches);
## extract page subset according to 'start=' parameter
if (@$opt['start']) {
if ($opt['start'] >= 0)
$matches = array_slice($matches, $opt['start']-1);
else
$matches = array_slice($matches, $pagelistcount+$opt['start']);
}
## further extract page subset according to 'count=' parameter
if (@$opt['count']) {
list($r0, $r1) = CalcRange($opt['count'], $pagelistcount);
if ($r1 < $r0)
$matches = array_reverse(array_slice($matches, $r1-1, $r0-$r1+1));
else
$matches = array_slice($matches, $r0-1, $r1-$r0+1);
}
} //}}}
/* Comment:
Added of (:template none:) optional template section.
The control structure for the main loop has been changed
to allow handling of 'no matches' cases.
*/
## format items according to template
function FPLTemplateFormat($pagename, &$matches, &$opt, &$tparts) {
global $Cursor;
#echo "FPLTemplateFormat: matches=".print_r($matches,true)."
\n";
$savecursor = $Cursor;
$pagecount = 0; $groupcount = 0; $grouppagecount = 0;
$pseudovars = array('{$$PageCount}' => &$pagecount,
'{$$GroupCount}' => &$groupcount,
'{$$GroupPageCount}' => &$grouppagecount);
foreach(preg_grep('/^[\\w$]/', array_keys($opt)) as $k)
if (!is_array($opt[$k]))
$pseudovars["{\$\$$k}"] = htmlspecialchars($opt[$k], ENT_NOQUOTES);
$vk = array_keys($pseudovars);
$vv = array_values($pseudovars);
$lgroup = ''; $out = '';
$mcount = count($matches);
for($i=0; $i <= $mcount; $i++) {
if($i>0 && $i==$mcount) break;
$pn = $matches[$i];
$group = PageVar($pn, '$Group');
if ($group != $lgroup) { $groupcount++; $grouppagecount = 0; $lgroup = $group; }
$grouppagecount++; $pagecount++;
$t = 0;
while ($t < count($tparts)) {
if ($tparts[$t] != 'template') {
if ($mcount!=0) $item = $tparts[$t];
$t++;
}
elseif ($mcount==0) {
if ($tparts[$t] == 'template' && $tparts[$t+1] == 'none')
$item = $tparts[$t+3];
$t+=4;
}
else {
list($when, $control, $item) = array_slice($tparts, $t+1, 3); $t+=4;
if (!$control) {
if ($when == 'none') continue;
if ($when == 'first' && $i != 0) continue;
if ($when == 'last' && $i != $mcount - 1) continue;
} else {
if ($when == 'none') continue;
if ($when == 'first' || !isset($last[$t])) {
$Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1];
$Cursor['='] = $pn;
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
$curr = str_replace($vk, $vv, $control);
$curr = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
"PageVar(\$pn, '$2', '$1')", $curr);
if ($when == 'first' && $i > 0 && $last[$t] == $curr) continue;
$last[$t] = $curr;
}
if ($when == 'last') {
$Cursor['<'] = $Cursor['<'] = $pn;
$Cursor['='] = (string)@$matches[$i+1];
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+2];
$next = str_replace($vk, $vv, $control);
$next = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
"PageVar(\$pn, '$2', '$1')", $next);
if ($next == $last[$t] && $i != count($matches) - 1) continue;
$last[$t] = $next;
}
}
}
$Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1];
$Cursor['='] = $pn;
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
$item = str_replace($vk, $vv, $item);
$item = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
"PVSE(PageVar(\$pn, '$2', '$1'))", $item);
$out .= MarkupRestore($item);
}
}
$class = preg_replace('/[^-a-zA-Z0-9\\x80-\\xff]/', ' ', @$opt['class']);
if ($class) $class = " class='$class'";
$wrap = @$opt['wrap'];
if ($wrap != 'inline') {
$out = MarkupToHTML($pagename, $out, array('escape' => 0, 'redirect'=>1));
if ($wrap != 'none') $out = "$out
";
}
$Cursor = $savecursor;
return $out;
} //}}}