Extending Creoleparser Using Macros 101

(updated for 0.6)

Say you have a function that takes some textual input and returns HTML. It's very easy to make a Creoleparser macro so your fuction can by used in a wiki (or whatever). In the example below, let's call our function itex. This function takes some itex math markup and returns HTML.

Were are going to make a macro of the same name, that could be used something like this:

<<itex>>$ e^{i\pi}+1=0 $<</itex>>

The key to getting your function's HTML into Genshi output is wrapping it in a Markup object:

import genshi.builder as bldr
from genshi.core import Markup

def wrap_html(text):
    return Markup(text)   
             
def macro_func(macro_name, arg_string,body,isblock,environ):
    if macro_name == 'itex':
        return wrap_html(itex(body))
    ## the elif directly below has nothing to do with <<itex>>
    ## instead, it's another macro for allowing raw html (i.e., an <<html>> macro)
    ## not recommended for public wikis!
    elif macro_name == 'html':
        return wrap_html(body)

That's about it. You now just need to pass in this macro_func when instantiating your Parser. That part is described pretty well here.

Of course, there are a few extra features you may want to add:

def html2element(text, isblock):
    wrapped = Markup(text)
    # we will place our output in a div or a span, depending on the context (see below)
    # and add a class attribute (note that and underscore is needed because class is a keyword)
    if isblock:      
        element = bldr.tag.div(wrapped,class_="itex")
    else:
        element = bldr.tag.span(wrapped,class_="itex")
    return element 

def macro_func(macro_name, arg_string,body,isblock,environ):
    if macro_name == 'itex' and arg_string == None: #let's require that no arg_string is present
        return html2element(itex(body),isblock)

The isblock parameter will only be true here if the macro is called as follows (with some fresh sample input):

<<itex>>
\[ \sum_{n=1}^\infty \frac{1}{n} \text{ is divergent, but } \lim_{n \to \infty} \sum_{i=1}^n
\frac{1}{i} - \ln n \text{ exists.}\]
<</itex>>

Note that both the opening and closing macro tags must be on a line by themselves and have no leading spaces.

The macro_func here is pretty basic. If other macros were in use, it should probably at least parse the arg_string before passing it along. And it doesn't have to ignore unrecognized macro names (it could return an error message instead).

see also: DivMacroExample