5.4.1 <al-macro>

##
5.4.1 `<al-macro>`

The `<al-macro>` tag is used to define a macro. All enclosed content becomes part of the macro definition.

Executing the macro registers the macro with the execution context via the `register_macro()` method using the name in the `name` (5.4.1.1) attribute.

Note that the execution of the macro content is deferred until later when the macro is expanded via the `<al-expand>` (5.4.3) tag. This means that executing a macro definition produces no output. Output is produced only when the macro is expanded.

    >>> import albatross
    >>> ctx = albatross.SimpleContext('.')
    >>> albatross.Template(ctx, '<magic>', '''
    ... <al-macro name="noargs">
    ...  Will be executed when macro is expanded.
    ... </al-macro>
    ... ''').to_html(ctx)
    >>> ctx.flush_content()
    >>> albatross.Template(ctx, '<magic>', '''
    ... <al-expand name="noargs"/>
    ... ''').to_html(ctx)
    >>> ctx.flush_content()
    Will be executed when macro is expanded.

The deferred execution also means that you can include content that only works within the context of the `<al-expand>` tag.

    >>> import albatross
    >>> ctx = albatross.SimpleContext('.')
    >>> albatross.Template(ctx, '<magic>', '''
    ... <al-macro name="oops">
    ...  <al-value expr="oops">
    ... </al-macro>
    ... ''').to_html(ctx)
    >>> ctx.flush_content()
    >>> templ = albatross.Template(ctx, '<magic>', '''
    ... <al-expand name="oops"/>
    ... ''')
    >>> try:
    ...     templ.to_html(ctx)
    ...     ctx.flush_content()
    ... except NameError, e:
    ...     print e
    ...
    name 'oops' is not defined
    >>> ctx.locals.oops = 'there is now'
    >>> templ.to_html(ctx)
    >>> ctx.flush_content()
    there is now

In the above example the content of the macro makes reference to a oops that is not defined in the execution context when the macro was defined.

Inside a macro definition you can use as yet undefined macros.

    >>> import albatross
    >>> ctx = albatross.SimpleContext('.')
    >>> albatross.Template(ctx, '<magic>', '''
    ... <al-macro name="bold-red">
    ... <font color="red">more <al-expand name="bold"><al-usearg></al-expand> please</font>
    ... <font color="red"><al-expand name="bold">more <al-usearg> please</al-expand></font>
    ... </al-macro>
    ...
    ... <al-macro name="bold">
    ...  <b><al-usearg></b></al-macro>
    ... ''').to_html(ctx)
    >>> ctx.flush_content()
    >>> albatross.Template(ctx, '<magic>', '''
    ... <al-expand name="bold-red">spam</al-expand>
    ... ''').to_html(ctx)
    >>> ctx.flush_content()
    <font color="red">more <b>spam</b> please</font>
    <font color="red"><b>more spam please</b></font>

Care must by taken to ensure that you do not make circular macro references else you will cause a stack overflow.