This page describes a possible new class based macro interface.

= Interface =

{{{
#!python
class MacroInterface(Interface):
    # The output of a immutable macro only depends on the arguments and the content
    immutable = False

    def __init__(request, page_name, alt, context, args=None):
        """"
        @arg request: The request object
        @arg page_name: Absolute name of page
        @arg alt: Alternative text. Can be used if macro is unapplicable in the given context
        @arg context: Context of macro, only "block" and "inline" are specified.
        @arg args: The unparsed arguments string.
        """

    def __call__(content=()):
        """
        @arg content: The macro content if applicable.
        @return Macro body
        """
}}}

= Implementation =

{{{
#!python
class MacroBase(object):
    """
    Macro base class.
    Supports argument parsing with wikiutil.invoke_extension_function.
    """

    # The output of a immutable macro only depends on the arguments
    immutable = False

    def __init__(self, request, alt, context, args=None):
        self.request, self.alt, self.context, self._args = request, alt, context, args

    def call_macro(self, content):
        return wikiutil.invoke_extension_function(request, self.macro, self._args)

    def macro(self):
        raise NotImplementedError

class MacroBlockBase(MacroBase):
    """
    Macro base class for block element macros.
    The macro gets only expanded in block context. In inline context the
    alternative text is used instead.
    """
    def __call__(self, content=()):
        if self.context == 'block':
            return self.call_macro(content)
        return self.alt

class MacroInlineBase(MacroBase):
    """
    Macro base class for inline element macros.
    The macro is wrapped into a paragraph in block context.
    """
    def __call__(self, content=()):
        ret = self.call_macro(content)
        if self.context == 'inline':
            return ret
        return ET.Element(ET.QName('p', namespaces.moin_page), children=[ret])

class MacroInlineOnlyBase(MacroBase):
    """
    Macro base class for strict inline element macros.
    The macro is expanded to nothing in block context.
    """
    def __call__(self, content=()):
        if self.context == 'inline':
            return self.call_macro(content)
}}}