[engine=mau]
----
= Main section
== Secondary section
---
::toc:
----
Block Engines and Custom Definitions
- “Impact minus twenty seconds, guys. . . ” said the computer.
- “Then turn the bloody engines back on!” bawled Zaphod.
- “OK, sure thing, guys,” said the computer.
Block engines
Mau blocks have an advanced feature called block engine that rules the way the system processes the primary and secondary content.
Mau currently defines the following engines:
default
footnotes
group
mau
raw
source
When a block doesn't define a specific engine the default
one is used.
The engines footnotes
, group
, and source
will be shown in detail in the next chapters.
Default
As we saw in the previous chapter, the engine default
processes the content of the block as Mau code using the variables defined previously in the document.
The text of the block is part of the Mau document, so variables, headers, and footnotes defined in the block become part of the document just as if they were defined outside the block.
This engine is used when no other engine is defined explicitly and is useful every time we need to customise the way the content is rendered in the final format but we want to keep the content as part of the document.
Quotes and admonitions use the default engine.
Mau
As we saw previously, the engine default
processes the content as Mau code and adds variables, headers and footnotes in the current document. The engine mau
instead treats primary and secondary content as isolated. You can use this engine in particular to keep headers from being collected and shown into the ToC.
For example, using a command ::toc:
in a block rendered by the engine mau
will include only the headers defined in the block itself.
Please note that with this engine the content of the block is still rendered in the current document. This means that with output formats like TeX that create their own TOC automatically such headers will still be part of the main document.
Raw
The engine raw
is useful every time we want to include text in the output format directly, as this engine doesn't process the content at all. For example, you might want to add custom HTML code.
The following is an example from the UI kit I used for this website
[engine=raw]
----
<button type="button" class="btn btn-primary">
Notifications <span class="badge badge-light ml-1">4</span>
</button>
----
Please note that while the content of the block is not processed by Mau it is still rendered as any other block through templates. See Basic templates to find out how to include custom content without any wrapper.
Custom block definitions
As we saw previously, blocks have many attributes that you can set on them. In Basic templates and Advanced templates we will also see how you can create and use custom attributes.
Setting the same parameters over and over can become tedious and error prone, so Mau provides a way to define blocks through the command ::defblock:ALIAS, ARGUMENTS
.
::defblock:python, engine=source, language=python
[*python]
----
class MyException(Exception):
pass
----
This is equivalent to
[engine=source, language=python]
----
class MyException(Exception):
pass
----
Mandatory arguments and defaults
The full syntax of a block definition is
::defblock:ALIAS, [*SUBTYPE], [UNNAMED ARGUMENTS], [NAMED ARGUMENTS]
but the aliasing mechanism doesn't work as a pure substitution.
SUBTYPE
is going to be the block subtype. If missing, the subtype will not be set on the block.UNNAMED ARGUMENTS
are interpreted as mandatory arguments.NAMED ARGUMENTS
are interpreted as defaults values.
For example, ::defblock:alias, *type1, name
means that whenever we use *alias
as the block subtype we also have to provide either an unnamed argument (which will be assigned the key name
) or a named argument called name
.
::defblock:alias, arg1, key1=value1
[*alias] <--------------------------- This is invalid, as it is
---- missing the unnamed argument
----
[*alias, alert] <-------------------- This is valid.
---- Unnamed arguments: []
---- Named arguments: {"arg1": "alert", "key1": "value1"}
[*alias, alert, red] <-------------- This is valid.
---- Unnamed arguments: ["red"]
---- Named arguments: {"arg1": "alert", "key1": "value1"}
[*alias, alert, red, key1=value2] <-- This is valid.
---- Unnamed arguments: ["red"]
---- Named arguments: {"arg1": "alert", "key1": "value2"}
[*alias, red, arg1=alert] <---------- This is valid.
---- Unnamed arguments: ["red"]
---- Named arguments: {"arg1": "alert", "key1": "value1"}.
As you can see, block definitions do not work exactly like functions in programming languages. Block attributes can always contain any number of unnamed and named arguments, and the block definition just specifies which named ones we are always expecting to see.
Recursive subtypes
Block definitions are not recursive, so it is perfectly fine to write a definition like
::defblock:alias, *alias, engine=raw, classes="myclass1,myclass2"
In this case the syntax [*alias]
will be converted to [*alias, engine=raw, classes="myclass1,myclass2]
and the block will still have the subtype alias
.
Predefined blocks
Mau provides some aliases out of the box, namely source
, footnote
, and admonition
. While these are created directly in the Python soruce code, they are equivalent to the following definitions
::defblock:source, language=text, engine=source
TODO
::defblock:admonition, *admonition, class, icon, label
The built-in block type quote
is not an alias and doesn't contain additional attributes, so it works just like a default block.
Block definitions in configuration
You can create block definitions through Mau's configuration setting the variable mau.parser.block_definitions
"mau" : {
"parser": {
"block_definitions": {
"alias": {
"subtype": "type",
"mandatory_args": ["arg1", "arg2"],
"defaults": {"key1": "value1"},
},
},
}
}