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