This page describes how to implement macros (i.e, extensions) in a wiki engine. For end user usage, please see Syntax.
macro_func is an optional argument used during instantiation of a dialect object. Most often, this function will act as a dispatcher and call other functions based on macro_name‘s that are encountered while a Parser is working. Using this method, the macro_func can be very simple, particularly if the actual macros have compatible signatures.
A simple macro_func:
from creoleparser import parse_args
def macro_dispatcher(macro_name,arg_string,body,isblock,environ):
if macro_name in environ['macros']:
macro = {'name': macro_name,
'arg_string': arg_string,
'body': body,
'isblock': isblock
}
pos, kw = parse_args(arg_string)
return environ['macros'][macro_name](macro, environ, *pos, **kw)
In the code above, eniviron['macros'] is a dictionary of functions. Note that if macro_name is not in the dictionary, or if a macro returns None, creoleparser will treat the macro as unknown and render the raw wikitext unaltered.
Additional information about macro_func is documented with the create_dialect() factory function.
In order for a macro to return raw HTML, the HTML must be wrapped in a genshi.Markup object. See an example here
Don’t forget that macros can return simple strings (preferably as unicode objects) rather than genshi objects. These will be processed as Creole markup (potentially including other macros!) in their new context.
Creoleparser tries not to use paragraphs if the content they would enclose are valid children of the body element (according to xhtml1 strict). For example, if a section of wiki text is enclosed entirely in a regular bodied macro, and that macro outputs an Element with a div tag, no p tag will be added.
For block type macros (i.e., when isblock is true), creole parser will add a p tag if the macro’s return value indicates it isn’t a valid child of the body element.
Return a Fragment to always apply a p tag (unless the macro appears in other block level markup) e.g.:
return genshi.builder.tag(my_output)
Return a Stream (using the generate method) or Markup object to never apply a p tag, e.g.:
return genshi.builder.tag(my_output).generate()
or
return genshi.Markup('<div>...</div>')
Return a string or Element to let creoleparser decide, e.g.:
return 'some string (raw html will be escaped!)'
or
return genshi.builder.tag.div(my_output)
Generally, returning a string or Element will reliably produce valid xhtml. When returning other objects, you should follow the rules above.