[pmwiki-devel] Proposal: "Directives" Registry

Patrick R. Michaud pmichaud at pobox.com
Thu Aug 9 09:06:15 CDT 2007

On Thu, Aug 09, 2007 at 08:46:35AM -0400, Ben Wilson wrote:
> What I propose is to have PmWiki automatically parse (:directive
> args:), where 'directive' is a key to a Directive Registry that maps
> to the correspondnig function, and 'args' are already processed via
> ParseArgs(). There would be a RegisterDirective() function to help add
> new directives. This has the advantage of not requiring recipe authors
> to use Markup(), write the regex, etc. 

Would this be used only for directives that appear with a $when
argument of 'directives' and don't otherwise have any specific
ordering requirements?  I.e., it wouldn't seem to be usable for
directives that operate at the fulltext, block, or other stages
of processing.  It also doesn't easily allow other markups to be
position relative to one of these directives.

I'd also be concerned that new recipe authors would be confused
by the two mechanisms for creating directives -- RegisterDirective()
for directives that operate at the "directive" stage, and Markup()
for other things that use the (:...:) syntax but occur at other
locations in processing.

Here's a counter-proposal:  Instead of trying to come up with a
single markup rule to handle lots of things of the form
(:directive args:) and keeping track of yet another table of
markups ($DirectiveRegistry), how about a MarkupDirective() function 
that wraps the existing Markup() function with the standard 
calling interface for directives?  Something like:

  function MarkupDirective($id, $fn, $when='directives') {
    $pat = "/\\(:($id)( .*?)?:\\)/ei";
    $rep = "$fn(\$pagename, '$1', ParseArgs(PSS('$2')))";
    Markup($id, $when, $pat, $rep);

The interface used by a recipe would then be:

  ##  add a new (:gma-map [args]:) directive
  MarkupDirective('gma-map', 'GmaMap');
  function GmaMap($pagename, $directive, $opt) { ... }

Another advantage of this approach is that it allows an
optional 'when' parameter to define directives at other
stages of processing:

  ##  process (:pmform:) directives before any input directives
  MarkupDirective('pmform', 'PmFormMarkup', '<input');

One very nice advantage of the ProcessDirectives() approach is
that it could replace a large number of core and recipe markup
rules with a single rule.  Currently the core has about 20
items in the 'directives' stage of processing -- replacing those
separate rules with a single rule could substantially improve
markup processing.

However, we could easily do this within the MarkupDirective()
function I've given above, by using something like ProcessDirectives()
for directives with a $when parameter of 'directives', but
using the normal Markup() table for everything else.  That
could be a big win.

> Probably the former. This is too much new behavior to fit into 
> the 2.2 beta series, which should probably be near stable.

If we go with something like MarkupDirectives() above, I don't
think it's at all too radical to fit into 2.2.  Especially since
existing directives and recipes would continue to work exactly
as before.


More information about the pmwiki-devel mailing list