Blocks reference#
Blocks are YMPrint’s special content types for things plain YAML prose can’t express — images, admonitions, code, figures, and more. Some mirror markdown (images, code blocks); others extend it (admonitions, styled horizontal rules, executable Python).
Block syntax#
A block is a key that begins with an underscore, e.g. _img or _spacer. Its value is
a block-specific data structure, typically either a scalar or a mapping that allows several arguments to be passed.
Blocks appear wherever content is allowed, typically as list items:
Report:
- Photos:
_img:
source: photo.png
caption: "Figure 1"
- _info: A short informational note.
- _pagebreak:
All block codes accept an optional, user-defined id after a second underscore, e.g. _hrule_red and
_hrule_blue are both handled by the _hrule block — the id simply keeps the YAML keys
unique when you use several in one list and allows you to meaningfully identify them if you are using several in a row.
The id does not affect how the block is executed. It is simply an optional identifier.
The block code runs up to the second underscore. A key is only a block if that
code is registered, so _py_setup is a _py block (id setup), but _pysetup is not:
its code would be _pysetup. An unregistered key like that is rendered as an ordinary
heading.
You can add your own blocks by building a custom application.
Block catalogue#
Block |
Purpose |
|---|---|
Embed an image with an optional caption. |
|
Embed a matplotlib figure object with an optional caption. |
|
Callout boxes. |
|
A quotation with attribution. |
|
A non-executable code block. |
|
Execute Python and optionally show the syntax-highlighted source. |
|
Run Python and typeset it as handcalcs calculations. Needs |
|
Load variables into the document from a JSON file. |
|
Write variables from the document to a JSON file. |
|
A table from data, with column, format, sort and row-style options. |
|
A standalone paragraph, with a selectable text style. |
|
An unordered (bulleted) list. |
|
An ordered (numbered) list. |
|
Force a page break, optionally switching page template. |
|
Arm the page template to switch to at the next break. |
|
Choose a slide’s layout and template; route content into a frame. Slide mode only. |
|
A customizable horizontal rule. |
|
Insert vertical whitespace. |
_img — Images#
Embed a raster image (PNG, JPEG, …) with a caption. Paths are relative to the report file (or absolute).
_img:
source: catpuccin.png
caption: "Figure 1: The catpuccin cat"
width_ratio: 0.3
Parameter |
Required |
Default |
Meaning |
|---|---|---|---|
|
✅ |
— |
Path to the image, relative to the |
|
— |
Optional caption text shown below the image. Omit it for an image with no caption. |
|
|
|
Scale factor relative to the available content width. The image is automatically shrunk to fit the frame if it would overflow. ( |
_matplotfig — Matplotlib figures#
Embed a matplotlib Figure object that you built in a _py block.
Pass the figure through the $var syntax.
Report:
- _py:
echo: false
source: |
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])
- _matplotfig:
fig: $fig
caption: "Figure 1: A computed plot"
scale_ratio: 0.8
Parameter |
Required |
Default |
Meaning |
|---|---|---|---|
|
✅ |
— |
A matplotlib |
|
|
Caption text shown below the figure. |
|
|
|
Scale factor relative to the available content width. The figure image is automatically shrunk to fit the frame if it would overflow. |
Note
matplotlib is an optional dependency — install it in the same environment as YMPrint to
use this block.
Admonitions#
Callout boxes for drawing attention. Five variants are available, each taking the callout text as its value:
Report:
- _info: Here is an "info" admonition.
- _warning: Here is a "warning" admonition.
- _danger: Here is a danger admonition.
- _tip: Here is a helpful tip.
- _note: This is useful when you want to give a note.
Block |
Use for |
|---|---|
|
General information. |
|
Something the reader should be careful about. |
|
A serious caution. |
|
A helpful suggestion. |
|
An aside worth remembering. |
Admonition text and padding scale with the document’s body size: they are designed for a 10 pt body, so with a 40 pt body (a 1080p slide) they are drawn four times as large. Block quotes and image captions scale the same way.
_blockquote — Block quotes#
A quotation with an attribution line.
_blockquote:
quote: “What you do makes a difference, and you have to decide what kind of difference you want to make.”
attribution: Jane Goodall
Parameter |
Required |
Meaning |
|---|---|---|
|
✅ |
The quotation text. |
|
Who said it. |
_code — Preformatted code#
A non-executable, code block for pre-formatted text. Use this to display code or config verbatim.
_code:
source: |
yaml_data: is being shown
you can put: any yaml data together
more examples:
- - cell-padding
- cell_size
Parameter |
Required |
Meaning |
|---|---|---|
|
✅ |
The literal text to display. Use a YAML block scalar (` |
|
— |
|
|
— |
|
|
|
To run code instead of just showing it, use _py.
_py — Executable Python#
Execute Python with exec(). The document’s variable dictionary is the global scope, so
any _vars you defined are available to the code, and any variables the code creates become
available to the rest of the document (and to blocks via $var).
_py:
echo: true
line_numbers: true
namespace: py1
caption: >
Once this executes, the variables are accessible under the py1 namespace.
source: |
import math
a = 3
b = 4
c = math.sin(a / b)
Note
The | after source: tells the YAML parser that this is preformatted text, to respect the line breaks exactly as written, and that text should not be wrapped.
This is in contrast to the > character, often used when writing paragraph content, which allows you to break lines wherever you want in the YAML without breaking lines in the finished document.
Both the | and > character are part of the YAML spec.
Parameter |
Required |
Default |
Meaning |
|---|---|---|---|
|
✅ |
— |
Python source to execute. |
|
|
Whether to render the source as a highlighted code block. Set |
|
|
— |
Show line numbers alongside the rendered source. |
|
|
— |
Caption shown with the rendered code. |
|
|
— |
Nest the created variables under this name (access as |
|
|
|
Width of the rendered code block relative to the content width. |
Warning
_py runs exec() in the same Python environment as YMPrint. External subprocess
isolation is not currently implemented. Only run documents you trust.
YMPrint is not intended to be operated as a public-facing web app.
After execution the variables are usable everywhere:
- - a = {{py1.a}}
- b = {{py1.b}}
- c = {{py1.c}}
See Variables → Computing variables in Python.
_hc — Handcalcs calculations#
Run Python and typeset it with handcalcs:
each line shows the symbolic expression, the values substituted in, and the result.
_hc is available when ym-handcalcs is
installed (pip install "ymprint[hc]").
_vars:
w_DL: 2.5
w_LL: 4.0
Beam design:
- _hc: |
## Factored load
L = 6.0 # span, m
w_f = 1.25 * w_DL + 1.5 * w_LL
M_f = w_f * L**2 / 8
- The factored moment is {{ M_f }} kN·m.
Like _py, the source runs in the document’s variables: it can use _vars and the
results of earlier blocks, and anything it creates is available to the rest of the
document. As in handcalcs, ## ... comments are headings, # ... comments are prose,
inline comments annotate their line, and # hc: commands work as usual.
The value is the source itself, as above, or a mapping:
_hc_moment:
source: |
M_f = w_f * L**2 / 8
theme_color: "#7A1F1F"
Parameter |
Required |
Default |
Meaning |
|---|---|---|---|
|
✅ |
— |
Python source to run and render. |
|
|
A dark |
|
|
the body text size |
Font size, in points, that every calculation style scales from. |
Warning
Like _py, _hc runs its source in the same Python environment as YMPrint. Only render
documents you trust.
_loadjson — Load JSON variables#
Read a JSON file into your variable context at render time, optionally under a namespace.
Tip
For data that several documents use, declare it once in the project config with
_data instead; documents then use it by name, with no path.
_loadjson:
path: extra_vars.json
namespace: extra_vars
Parameter |
Required |
Meaning |
|---|---|---|
|
✅ |
Path to the JSON file, relative to the report file. |
|
Nest the loaded values under this name (access as |
- - bn = {{extra_vars.bn}}
- dx = {{extra_vars.dx}}
_dumpjson — Write JSON variables#
Write variables to a JSON file at render time: the counterpart of _loadjson. Any variable
defined at the block’s position can be written: from _vars, or made by an earlier _py,
_hc or _loadjson block.
Tip
For values that other documents in the project use, declare them with
_export instead; YMPrint then writes them and orders the
build for you.
_vars:
beam: {span: 6.0, load: 12}
phi: 0.9
Report:
- _dumpjson:
path: out/values.json
vars: [beam.span, phi] # {"beam": {"span": 6.0}, "phi": 0.9}
- _dumpjson:
path: out/beam.json
namespace: beam
vars: [span, load] # {"span": 6.0, "load": 12}
Parameter |
Required |
Meaning |
|---|---|---|
|
✅ |
Path to the JSON file, relative to the report file (or absolute). May use |
|
✅ |
The variables to write. A dotted name ( |
|
Look the names up inside this mapping and write them at the top level, so |
The file is replaced whole on each render, and left untouched when its content would not
change. Values are written as _export writes them:
a value with no JSON form (and no registered serializer) is an error.
_table — Tables from data#
Render tabular data (a list of mappings) with presentation options. For a plain table of
computed data, - $rows is enough; see Tables from data.
- _table:
data: $rows # or the name of a _data source: utilizations
columns: [Member, Check, DCR]
headers: {DCR: "D/C"}
format: {DCR: "{:.2f}"}
sort: [-DCR]
row_style: "{{ 'danger' if row.DCR > 1.0 else ('warning' if row.DCR > 0.9 else '') }}"
caption: "Table 1: Member utilizations"
Parameter |
Required |
Meaning |
|---|---|---|
|
✅ |
The rows: a |
|
The columns to show, in order. Default: every key, in order of first appearance. |
|
|
Header text per column. Default: the column name. |
|
|
A Python format string per column, e.g. |
|
|
Columns to sort the rows by, in priority order; prefix |
|
|
A Jinja template, with |
|
|
Text shown below the table. |
Cells are values, not Jinja templates. Format strings work on anything that supports Python’s format specs, including units-aware quantities.
_p — Standalone paragraphs#
Emit a paragraph on its own, without first introducing a heading key. This is handy for body text that follows another block — a note after an admonition, a caption-like line under a figure — where you don’t want a heading and a bare list item wouldn’t let you choose the text style.
The quickest form takes the text directly:
Report:
- _info: Something worth noting.
- _p: A follow-up paragraph, no heading required.
Use the mapping form to pick a text style — any family defined in
_style.styles:
Report:
- _matplotfig:
fig: $fig
caption: "Figure 1"
- _p:
content: Figures are approximate; see the appendix for exact values.
style: fine-print
Parameter |
Required |
Default |
Meaning |
|---|---|---|---|
|
✅ |
— |
The paragraph text. |
|
|
Name of the text style family to render the paragraph in. |
Paragraph text supports the same inline markdown and {{variable}} interpolation as
ordinary body text. An unknown style raises an error listing the available styles.
_ul — Unordered lists#
A bulleted list. A bare YAML list is a sequence of paragraphs/sub-sections, so bullets are
written explicitly with _ul. Nest a list inside an item to indent (the bullet glyph
changes with depth, default hierarchy •‣⁃∘).
Findings:
_ul:
- The handrail is loose on the north stair.
- Two ceiling tiles are water-stained in the lobby.
- - a nested sub-point
- another sub-point
_ul works as the value of a heading key (as above) or as a list item
(- _ul: [...]). Bullet glyph, colour, and indentation come from _style.body.bullets
(see Configuration → Text styles).
_ol — Ordered lists#
A numbered list. Numbering is automatic by position; nesting a list inside an item creates a nested numbered list.
Recommended actions:
_ol:
- Re-secure the handrail.
- Replace the stained ceiling tiles.
- - Nested step one
- Nested step two
_pagebreak — Page breaks#
Force a page break. Called with no value, it just breaks the page and keeps the current page template. Pass the name or 0-based index of a page template to switch to it for the pages that follow.
Report:
- >
This content ends the page.
- _pagebreak: # break, keep the current template
- >
This content starts a new page.
- _pagebreak: body # break AND switch to the "body" template
- _pagebreak: 1 # equivalently, by index
_nextpagetemplate — Switch template at the next break#
Arm the page template to switch to at the next page break, without inserting a break itself. Useful when the break is produced elsewhere (for example, by content overflowing the page). Takes the template name or 0-based index.
Report:
- _nextpagetemplate: body # the next page break will switch to "body"
- >
Long content that flows onto a second page, which will use the "body" template.
_textstyle — Switch text style#
Activate a named text style for the rest of the section it
appears in, and for every nested descendant. Takes a style name (declared under
_style.styles) or the special name default. It renders nothing of its own.
The switch is scoped to its list: it restyles every following sibling plus their descendants, then reverts automatically when the section ends — no manual switch-back is needed unless you want to change style again within the same section. Switching swaps the whole family, so body paragraphs, bullet lists, and derived headings all follow the active style. An undeclared style name raises an error.
If a _textstyle switch is the first content item under a heading, that heading adopts
the switched style too — so writing it at the top of a section restyles the whole section,
title included.
Legal disclaimer:
- _textstyle: fine-print # applies from here down in THIS section
- This paragraph is fine-print.
- Sub-clause:
- Inherited fine-print (a nested descendant).
- _textstyle: default # switch back within the same section
- Back to the default style.
Next section:
- Body style again — the disclaimer's scope ended with its list.
See Switching text styles for the full behaviour.
_slide / _frame — Slide layout#
Only in slide mode (_doc: slides: true). _slide must be the first item of a
slide and takes a layout name or a mapping of layout and template. _frame sends the
content that follows into the named frame of the slide’s layout.
Here is what people were doing in 1966:
- _slide: two-column
- Text in the left column
- _frame: right
- _img:
source: bbc_1966.png
See Slide presentations for layouts, frames and overflow.
_hrule — Horizontal rules#
Unlike a markdown rule, _hrule is configurable — width, thickness, colour, and line cap.
Use ids (_hrule_red, _hrule_blue) to keep multiple rules unique in one list.
- _hrule_default: null
- _hrule_red:
width_ratio: 0.8
thickness: 2
color: "#bb3322"
- _hrule_blue:
width_ratio: 0.6
thickness: 3
color: "#4422dd"
cap: round
Parameter |
Default |
Meaning |
|---|---|---|
|
|
Rule width as a fraction of the content width. |
|
|
Line thickness in points. |
|
|
Rule colour. |
|
|
Line-cap style: |
Passing null (as with _hrule_default: null) draws a rule with all defaults.
_spacer — Vertical space#
Insert an arbitrary amount of vertical whitespace, measured in points, to nudge content positioning by hand.
Report:
- _spacer: 5
- There is a 5 pt spacer above.
- _spacer: 20
- There is a 20 pt spacer above.
The value is the height of the space in points.
Tip
A _spacer: 0 is a handy trick to stop a
paragraph being misinterpreted as a bullet when it’s immediately followed by a list.