[pmwiki-users] When to generate final tags?
Joachim Durchholz
jo at durchholz.org
Wed Jun 29 10:24:07 CDT 2005
Patrick R. Michaud wrote:
> On Tue, Jun 28, 2005 at 09:33:57AM +0200, Joachim Durchholz wrote:
>
>>Similarly, if somebody starts a (:table:) within an (:input start:) -
>>(:input end:) pair, the table must be finished off before (:input end:),
>>whether the wiki author has specified a (:tableend:) or not.
>>
>>What's the proper way to do this?
>
> At the moment there isn't one -- nested blocks are a bit of a pain.
> I've been thinking of generalizing the Block() call to be able to
> handle arbitrary nested block structures, but doing so would
> change a number of exposed PmWiki internals and could break a
> number of recipes. So I've been thinking that would need to wait
> for 2.1.
I understand.
I've given nested blocks a bit of thought, and have come with a general
strategy. I don't know what your thoughs have been, so I don't know
whether it's any improvement, but here goes anyway:
Parsing nested stuff via regular expressions directly is impossible. But
you can use a repetitive process that matches non-greedily, replaces the
so-found innermost block (we already have Keep() in place which can do
that), and repeats the process until done.
Add a new variant of Markup, NestableMarkup. Instead of a pattern for
the entire markup, it gives two: one for markup start and one for markup
end. (It would probably also need two $rep parameters.)
NestableMarkup does just the standard thing, but it also extends the
$BeginNest and $EndNest arrays.
After all of the recipes have installed their markup, PmWiki installs
this one:
Markup(
'nesting',
'<split',
'/(' . implode ('|', $BeginNest) . ')(.?*)'
. '(' . implode ('|', $EndNest) . ')/em',
'Keep(\'$0\', \'nest\')');
This markup must be repeatedly applied until it doesn't find anything
anymore.
Then another markup that re-expands all strings saved with a 'nest' tag,
and wraps them like this:
(:nest N:)$kept_string(:unnest N:)
where N is a serial number that identifies each nest-unnest pair (might
be useful for scripts that try to find the (:unnest:) for a (:nest:), or
vice versa).
What I currently don't know how to handle well are nestable structures
like (:if:) (:else:) (:ifend:) - the (:else:) doesn't have a good place
in this scheme: it would be desirable to annotate it with, say, (:innest
N:), but that would require some inventive parameter passing for
NestableMarkup and some regex hackery in the Markup() call above (all
probably doable but nontrivial).
(:nest N:) would do $NestingId = N (note that N need not be numeric). It
would also set $NestedRule['N'] to the $name of the nestable markup
(some markup might want to scan the $NestedRule for some given markups).
(:unnest N:) would call the functions installed in
$UnnestFunctions['N']. It would also drop the last element in the
$NestedRule and $UnnestFunctiosn arrays (this makes them into stacks
that get pushed and popped according to the nesting we're in).
Markups can then install "unnest handlers" in
$UnnestFunctions[$NestingId] - which is the whole point of the exercise.
Regards,
Jo
More information about the pmwiki-users
mailing list