Markup Macros

inyoka.utils.macros

The module contains the core macros and the logic to find macros.

The term macro is derived from the MoinMoin wiki engine which refers to macros as small pieces of dynamic snippets that are exanded at rendering time. For inyoka macros are pretty much the same just they are always expanded at parsing time. However, for the sake of dynamics macros can mark themselves as runtime macros. In that case during parsing the macro is inserted directly into the parsing as as block (or inline, depending on the macro settings) node and called once the data is loaded from the serialized instructions.

This leads to the limitation that macros must be pickleable. So if you feel the urge of creating a closure or something similar in your macro initializer remember that and move the code into the render method.

For example macro implementations have a look at this module’s sourcecode which implements all the builtin macros.

copyright:
  1. 2007-2024 by the Inyoka Team, see AUTHORS for more details.

license:

BSD, see LICENSE for more details.

class inyoka.markup.macros.Anchor(*args, **orig_kw)

This macro creates an anchor accessible by url.

allowed_context = ['forum', 'ikhaya', 'wiki']

The render context this macro is allowed in. Restrictive by default

arguments = (('id', <class 'str'>, None),)

the arguments this macro expects

build_node()

If this is a static macro this method has to return a node. If it’s a runtime node a context and format parameter is passed.

A static macro has to return a node, runtime macros can either have a look at the passed format and return a string for that format or return a normal node which is then rendered into that format.

is_static = True

if a macro is static this has to be true.

names = ('Anchor', 'Anker')

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

class inyoka.markup.macros.Date(*args, **orig_kw)

This macro accepts an iso8601 string or unix timestamp (the latter in UTC) and formats it using the format_datetime function.

allowed_context = ['ikhaya', 'wiki']

The render context this macro is allowed in. Restrictive by default

arguments = (('date', <class 'str'>, None),)

the arguments this macro expects

build_node(context, format)

If this is a static macro this method has to return a node. If it’s a runtime node a context and format parameter is passed.

A static macro has to return a node, runtime macros can either have a look at the passed format and return a string for that format or return a normal node which is then rendered into that format.

names = ('Date', 'Datum')

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

class inyoka.markup.macros.Macro(*args, **orig_kw)

Baseclass for macros. All macros should extend from that or implement the same attributes. The preferred way however is subclassing.

allowed_context = None

The render context this macro is allowed in. Restrictive by default

arguments = ()

the arguments this macro expects

build_node(context=None, format=None)

If this is a static macro this method has to return a node. If it’s a runtime node a context and format parameter is passed.

A static macro has to return a node, runtime macros can either have a look at the passed format and return a string for that format or return a normal node which is then rendered into that format.

has_argument_parser = False

set this to True if you want to do the argument parsing yourself.

is_block_tag = False

true if this macro returns a block level node in dynamic rendering. This does not affect static rendering.

is_static = False

if a macro is static this has to be true.

is_tree_processor = False

unused in Macro but not TreeMacro.

metadata = None

if a macro is dynamic it’s unable to emit metadata normally. This slot allows one to store a list of nodes that are sent to the stream before the macro itself is emited and removed from the macro right afterwards so that it consumes less storage pickled.

names = ()

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

render(context, format)

Dispatch to the correct render method.

class inyoka.markup.macros.Newline(*args, **orig_kw)

This macro just forces a new line.

allowed_context = ['forum', 'ikhaya', 'wiki']

The render context this macro is allowed in. Restrictive by default

build_node()

If this is a static macro this method has to return a node. If it’s a runtime node a context and format parameter is passed.

A static macro has to return a node, runtime macros can either have a look at the passed format and return a string for that format or return a normal node which is then rendered into that format.

is_static = True

if a macro is static this has to be true.

names = ('BR',)

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

class inyoka.markup.macros.Span(*args, **orig_kw)
allowed_context = ['forum', 'ikhaya', 'wiki']

The render context this macro is allowed in. Restrictive by default

arguments = (('content', <class 'str'>, ''), ('class_', <class 'str'>, None), ('style', <class 'str'>, None))

the arguments this macro expects

build_node()

If this is a static macro this method has to return a node. If it’s a runtime node a context and format parameter is passed.

A static macro has to return a node, runtime macros can either have a look at the passed format and return a string for that format or return a normal node which is then rendered into that format.

is_static = True

if a macro is static this has to be true.

names = ('SPAN',)

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

class inyoka.markup.macros.TableOfContents(*args, **orig_kw)

Show a table of contents. We do not embedd the TOC in a DIV so far and there is also no title on it.

allowed_context = ['ikhaya', 'wiki']

The render context this macro is allowed in. Restrictive by default

arguments = (('max_depth', <class 'int'>, 3), ('type', {'ALPHABETH': 'alphaupper', 'ROMAN': 'romanupper', 'alphabeth': 'alphalower', 'arabic': 'arabic', 'arabic0': 'arabiczero', 'roman': 'romanlower', 'unordered': 'unordered'}, 'arabic'))

the arguments this macro expects

build_node(tree)

Queries for all nodes.Headline nodes and constructs a nodes.List representing the headlines. The optimal result will look like:

= Foo1 =
== Bar1 ==
== Bar2 ==
=== Buz1 ===
= Foo2 =
== Bar3 ==

1. Foo1
  1. Bar1
  2. Bar2
    1. Buz1
2. Foo2
  1. Bar3

But due to some reasons, there are situations where the headlines are not used as one would expect. The level is increased by something larger than 1:

= Foo1 =
=== Buz1 ===
== Bar1 ==
=== Buz1 ===
= Foo2 =
== Bar3 ==

1. Foo1
    1. Buz1
  2. Bar1
    1. Baz1
2. Foo2
  1. Bar3
is_block_tag = True

true if this macro returns a block level node in dynamic rendering. This does not affect static rendering.

names = ('TableOfContents', 'Inhaltsverzeichnis')

The canonical names for this macro. A macro may have multiple aliases e.g to support multiple languages.

stage = 'final'

When the macro should be expanded. Possible values are:

final

the macro is expanded at the end of the transforming process.

initial

the macro is expanded at the end of the parsing process, before the transformers and other tree macro levels (default).

late

Like initial, but after initial macros.

class inyoka.markup.macros.TreeMacro(*args, **orig_kw)

Special macro that is processed after the whole tree was created. This is useful for a TableOfContents macro that has to look for headline tags etc.

If a macro is a tree processor the build_node function is passed a tree as only argument. That being said it’s impossible to use a tree macro as runtime macro.

build_node(tree)

Works like a normal build_node function but it’s passed a node that represents the syntax tree. It can be queried using the query interface attached to nodes.

The return value must be a node, even if the macro shouldn’t output anything. In that situation it’s recommended to return just an empty nodes.Text.

is_static = True

if a macro is static this has to be true.

is_tree_processor = True

unused in Macro but not TreeMacro.

render(context, format)

A tree macro is not a runtime macro. Never static

stage = 'initial'

When the macro should be expanded. Possible values are:

final

the macro is expanded at the end of the transforming process.

initial

the macro is expanded at the end of the parsing process, before the transformers and other tree macro levels (default).

late

Like initial, but after initial macros.

inyoka.markup.macros.get_macro(name, args, kwargs)

Instantiate a new macro or return None if it doesn’t exist. This is used by the parser when it encounters a macro_begin token. Usually there is no need to call this function from outside the parser. There may however be macros that want to extend the functionality of an already existing macro.

inyoka.markup.macros.register(cls)