Mau - A template-based markup language
Source code blocks
The older authorities seemed rather more helpful than the newer ones, and Armitage concluded that the code of the manuscript was one of great antiquity, no doubt handed down through a long line of mystical experimenters.
H.P. Lovecraft, The Dunwich Horror (1929)
For programmers, one of the most useful features of a markup language is that of adding source code blocks. Mau provides full support to source code highlighting, and allows you to highlight single lines and add callouts to the code to mark specific steps of the process or to add explanations.
Basic source blocks¶
Literal paragraphs and source code can be printed using blocks of type source
. Source code
[source]
----
This is all literal.
== This is not a header
[These are not attributes]
----
This is all literal.
== This is not a header
[These are not attributes]
Highlighting is provided by Pygments, so you can specify the language for the highlighting using one of the supported languages.
[source,python]
----
def header_anchor(text, level):
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]
) # pragma: no cover
----
def header_anchor(text, level):
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]
) # pragma: no cover
Callouts¶
Source blocks support callouts, that allow you to add notes to specific lines of code. Callouts are added at the end of the line between colons (e.g. :1:
) the relative text is added to the secondary content of the block
[source,python]
----
def header_anchor(text, level)::1:
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]:2:
) # pragma: no cover
----
1: The name of the function
2: Some memory-related wizardry
def header_anchor(text, level): 1
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8] 2
) # pragma: no cover
1 | The name of the function |
2 | Some memory-related wizardry |
Callouts are rendered with span
s and the relative text is rendered in a table
[source,python]
----
a=5:1:
----
1: A simple assignment
<div class="source">
<div class="content">
<div class="highlight">
<pre>
<span/>
<span class="n">a</span>
<span class="o">=</span>
<span class="mi">5</span>
<span class="callout">1</span>
</pre>
</div>
</div>
<div class="callouts">
<table>
<tbody>
<tr>
<td>
<span class="callout">1</span>
</td>
<td>A simple assignment</td>
</tr>
</tbody>
</table>
</div>
</div>
The default delimiter for callouts is the colon :
, but if that clashes with the syntax of your language you can pick a different one with the attribute callouts
[source, python, callouts="|"]
----
def header_anchor(text, level):|1|
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]|2|
) # pragma: no cover
----
1: The name of the function
2: Some memory-related wizardry
def header_anchor(text, level): 1
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8] 2
) # pragma: no cover
1 | The name of the function |
2 | Some memory-related wizardry |
Callouts names are just strings, not manipulated by Mau, so you can use them out of order
[source,python]
----
def header_anchor(text, level)::1:
return "h{}-{}-{}".format(:3:
level, quote(text.lower())[:20], str(id(text))[:8]:2:
) # pragma: no cover
----
1: The name of the function
2: Some memory-related wizardry
3: This is the return value
def header_anchor(text, level): 1
return "h{}-{}-{}".format( 3
level, quote(text.lower())[:20], str(id(text))[:8] 2
) # pragma: no cover
1 | The name of the function |
2 | Some memory-related wizardry |
3 | This is the return value |
Callouts are not limited to digits, you can use non-numeric labels
[source,python]
----
def header_anchor(text, level)::step1:
return "h{}-{}-{}".format(:step3:
level, quote(text.lower())[:20], str(id(text))[:8]:step2:
) # pragma: no cover
----
step1: The name of the function
step2: Some memory-related wizardry
step3: This is the return value
def header_anchor(text, level): step1
return "h{}-{}-{}".format( step3
level, quote(text.lower())[:20], str(id(text))[:8] step2
) # pragma: no cover
step1 | The name of the function |
step2 | Some memory-related wizardry |
step3 | This is the return value |
Callouts do not need to have a definition
[source,python]
----
def header_anchor(text, level)::1:
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]:2:
) # pragma: no cover
----
def header_anchor(text, level): 1
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8] 2
) # pragma: no cover
And you can reference them 1 in the text. Here, I used [class](1, callout)
to create a span
with the same class used in the source code, and have the same CSS style applied to it.
Highlight lines¶
You can highlight lines using a callout with the special name @
[source,python]
----
def header_anchor(text, level)::@:
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]:@:
) # pragma: no cover
----
def header_anchor(text, level):
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]
) # pragma: no cover
Should you prefer to list the lines you want to highlight you can use Pygments directly, passing the configuration value hl_lines
under the namespace pygments
[source,python,pygments.hl_lines="1,3"]
----
def header_anchor(text, level):
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]
) # pragma: no cover
----
def header_anchor(text, level):
return "h{}-{}-{}".format(
level, quote(text.lower())[:20], str(id(text))[:8]
) # pragma: no cover