内容简介:by Bill WadgeThe Markup Macro Processor (MMP) is a text based macro system that uses a markup-like syntax, similar to (but much simpler than) XML.Markup? Who uses markup?
by Bill Wadge
The Markup Macro Processor (MMP) is a text based macro system that uses a markup-like syntax, similar to (but much simpler than) XML.
Markup? Who uses markup?
Not many people any more, Markdown being a small exception. Although you can also count Latex with its macros as a kind of markup.
Originally, markup seemed like a great idea. It allowed ordinary people with only a word processor to post Web pages. However those days are gone. Now if you want a snazzy looking Web page you have to know a lot of Javascript and CSS and this is beyond all but the experts. Or you can use some godawful GUI like Dreamweaver – I myself have never been able to master it.
The main reason that Good Old Fashioned Markup (GOFM) has been abandoned is that traditional systems have no abstraction mechanism. There’s nothing corresponding to functions (in a functional language) or methods (in an OO language). You can’t bundle up boilerplate and introduce new user defined tags that generate the boilerplate.
Well not quite nothing. There’s XSLT and other proposals but they’re so complex they’re not suitable for non-techies, in my opinion.
What I’m proposing is to revive GOFM and give the little guy/gal the possibility of creating sophisticated pages with a simple text editor.
I propose doing this with a stripped-down, super simple, XML independent, general purpose macro processor. MMP (Markup Macro Processor) and has been implemented (in a few thousand lines of Java) by Dr Paul Swoboda and myself.
MMP syntax is inspired by two sources: XML/HTML and groff (originally, troff) macros. MMP uses tags (opening, closing, and clopening) and tags can have arguments (arbitrary strings, possibly quoted). That’s it.
Here’s a typical MMP macro call
{page “Introducing Wadge Degrees”}
The {wiki “Wadge hierarchy” Wadge_hierarchy/} was discovered by {me/}.
{/page}
which (given the macro definitions given below) expands to
The https://en.wikipedia.org/wiki/Wadge_hierarchy”>Wadge Hierarchy was invented by Bill Wadge.
>
There are three MMP macros in the original source, namely page, wiki, and me. The calls to wiki and me occur inside the ‘body’ of the page macro – the body being the part between the opening and closing tags. Macro expansion is done inside out. The macros wiki and me are first expanded, then page is invoked with the new body.
Here is the definition of the me macro:
{de me}Bill Wadge{/de}
The de macro defines its first argument to be the body of its call.
Here is the definition of the wiki macro:
{de wiki}$1{/de}
Here $1 and $2 stand for the first and second arguments of the call to wiki .
Finally, here is the definition of the page macro
{de page>
$_
{/de}
As before, $1 stands for the first argument, and here $_ stands for the body.
In a sense, that’s about it. I’ve told you how macros are called, how they are expanded, and how they are defined. Those are the main three things you have to know about a macro processor.
As a non-trivial example, consider the droptext macro defined below. Droptext is hidden text (or other content) that drops into view when sensitive content is clicked. Our macro is especially simple, the sensitive content is a headline. So for example you may see
How to contact us
and when you click “ How to contact us ” you immediately see
How to contact us
call 1-800-123-4567
email info@bleen.com
and clicking on “ How to contact us ” causes the contact information to disappear again.
The droptext macro takes arguments which together form the headline, and a body containing the text that drops up and down. A call to the macro looks like this:
{droptext How to contact us}
call 1-800-123-4567
email info@bleen.com
{/droptext}
and the definition and associated Javascript is as follows
{de droptext}
onMouseOver=”this.style.cursor=’hand'”
onClick=”dt_toggle(this);”>$*
{/de}
function dt_toggle(t)
{ if ( t.parentNode.childNodes[3].style.display==’block’ )
{ t.parentNode.childNodes[3].style.display=’none’;
t.style.color = ‘blue’; }
else {
t.parentNode.childNodes[3].style.display=’block’;
t.style.color = ‘red’; }
}
The cleverness is all in the (non obvious) Javascript (which colors the headline blue when the text is hidden, red when it’s showing). But you (or me) has to figure it out only once, and enter it only once. Then to use it you put it in a file – say, droptext.i – and in your source have the macro call {import droptext.i/} . The import macro will include it with your source, unless it’s already been imported – import will not include multiple copies.
People can use droptext without knowing anything about Javascript. Incidentally, the droptext can be any content including nested calls to droptext.
The script above might seem a problem because MMP treats curly parentheses specially. There is, however, an easy way around this. MMP does not give special attention to open curly parentheses followed by a blank, nor to closed curly parentheses preceded by a blank. The Javascript above has been padded with blanks to avoid such special attention.
But of course there’s a lot more to know about MMP if you want to author macros, not just use them. For a start, there’s built-in ‘system’ macros that don’t work by string substitution. An example is the + macro which adds its arguments, so for example {+ 3 5 7} evaluates to 15 . Especially useful is the replacement macro r which applies regular-expression based substitutions to its body (using Java’s conventions). Thus
{r William Bill}I’m William Wadge{/r}
expands to
I’m Bill Wadge
Another complication is the definition macro: de is not the basic system macro, it has a definition, but treats $ specially. The system definition macro : does not do this, it uses pseudo macros for the arguments (e.g.{1/}) and body ({/_}). The page macro definition becomes
{” : page}
{html}
{_/}