Skip to content

Blocks

Blocks add pages, tables, images, and other elements to novem markdown. This reference describes their syntax, configuration, and shared styling options.

AI-assisted, human-approvednovem uses AI to review and keep our documentation up to date.

Available in: documents and e-mails.

Block format

A block is written as {{ name … }} with its config as key: value pairs. There are two shapes. Leaf blocks embed a resource or insert a marker and have no closing tag:

{{ page orientation: landscape, cols: 2 }}
{{ vis ref: /u/novem_demo/p/nei, width: 80%, title: true }}
{{ button href: https://example.com/report, label: "Read the report" }}

Character references decode in config strings as they do in text, so caption: "at 30 September" keeps its non-breaking space. Only well-formed references count (&name;, —): R&D stays as written.

Container blocks wrap a body and end with a matching closing tag:

{{ box bg: gray-100, p: a4, id: summary }}
## Quarterly review

Revenue increased **12%**.

{{ button href: https://example.com/report, label: "Open report" }}
{{ /box }}

Config is written either inline, with commas or semicolons between pairs, or as YAML across several lines. The two forms are equivalent for every block, including page.

{{ paragraph
  fg: blue-700
  p: [l2, r4]
  b: l3 blue-500
}}
A styled paragraph.
{{ /paragraph }}

# is literal inside configs, so fg: #336699 is a colour. Put comments outside configs using <!-- a comment --> or {/* a comment */}. Quote text containing commas, colons, or other YAML punctuation.

What a container may hold depends on the block: box accepts nested blocks; cols accepts col containers or flows its children across equal columns; paragraph and callout bodies accept Markdown, including lists and tables; a table wrapper contains one Markdown table; kpis contains kpi tiles. The reference tables below list each block, what it can contain, and where it is available.

Styling

Blocks, heading suffixes, and styled spans share the styling keys fg bg sz st al m p s b.

# Results {fg: blue-700, id: results}

Revenue [[increased 12%]]{fg: green-600, st: b}.

{{ para m: t4 b2, p: x3 y2, b: [l1 red-500, r1 green-500] }}
The spacing directions are a (all), x (left and right), y (top and bottom),
and t, b, l, r for individual edges.
{{ /para }}

Spacing takes non-negative integer scale units; the default unit is 2px. Border widths are pixels. sz ranges from xxxs through xxxl; use s for small. Combine font styles with spaces: st: b i u.

Theme colours adapt to light and dark mode. Use a named token such as blue-500, a colour alias, or a hex literal. A --light or --dark suffix pins a token to that mode. See colours.

Widths accept fractions (1/2), percentages (55%), decimals (0.5), full, or pixels (240px). Column widths accept shares only. Heights accept intrinsic, fill, or pixels; percentages are not supported.

Default block spacing

Paragraphs and lists normally have 4 units (8px) between them. Charts, images, tables and boxes generally request 8 units (16px).

All heading levels request 4 units (8px) above and keep the following content close with 2 units (4px) below, equivalent to b2. Consecutive headings use that same small gap. Explicit margins and blank-line spacing still follow the collapsing rules below. A heading at a page or column start has no automatic top gap.

Collapsing vertical margins

Documents and e-mails use the larger of the margins between adjacent blocks. For example:

{{ para m: b5 }}First paragraph.{{ /para }}

{{ para m: t6 }}Second paragraph.{{ /para }}

The gap is 6 units (12px). With b5 and t5, it is 5 units (10px). An explicit adjoining margin replaces automatic block spacing; b0 or t0 can remove that automatic gap. Margins on the opposite edges do not affect it.

A run of two or more blank lines requests 8 units (16px). That spacing collapses with the adjoining margins too: b5, blank lines, and t6 give 8 units, while b10 with the same blank lines gives 10 units. Adding more blank lines does not accumulate more space. A single blank line separates Markdown blocks and uses their normal spacing.

To add real empty lines, write a paragraph of lone backslashes: each \ on a line of its own is one blank line, so four such lines are four empty lines between the paragraphs around them. A \\ prints a backslash and is not a spacer.

Each nested container has its own flow. Padding and horizontal margins remain separate. At the start of a document page or column, only the first block's own top margin remains; the preceding page's bottom margin is dropped.

Hooks and keeping blocks together

Every block accepts id, classlist and keep. An authored id becomes data-id and classlist adds classes, so a theme can select a particular block; every rendered block also carries data-kind and its source data-line. keep: together keeps a block on one page when it fits; keep: with-next keeps it with the following block. Oversized content can still split. Headings default to staying with the next block; tables and KPI rows default to staying together.

Unknown keys, invalid values, unavailable blocks and unclosed containers produce diagnostics with source line numbers. Inspect these before exporting or sending a document or e-mail.

Pages, covers and running bands are on Pages; columns, containers and layout pages on Layout.

Math and equations

Set latex: true in document frontmatter to enable $...$ inline math and $$...$$ display math starting on its own line. See Math and equations for syntax and examples.

Grammar reference

The following tables list accepted block names, aliases, and config values.

BlockAliasesBodyAvailable in
paragraphparamarkdownboth
visualisationvisnoneboth
imageimgnoneboth
attachmentattachnonee-mails
callout—markdownboth
html—raw (sanitized)both
table—GFM tableboth
kpi—noneboth
kpis—kpi blocksboth
toc—nonedocuments
box—flowboth
button—noneboth
cols—col blocks / flowboth
col—flowboth
header—flowdocuments
footer—flowdocuments
frontpage—nonedocuments
tocpage—optional listdocuments
startpagination—nonedocuments
page—nonedocuments
authorauthnoneboth
preview—paragraphse-mails
colbreak—nonedocuments

Config keys

All blocks accept id, classlist, and keep. Styling keys also apply to heading suffixes and styled spans.

KeyAliasesValueApplies to
id—Identifier: a letter, then letters, digits, - or _; at most 64 characters.all
classlist—Up to 16 CSS classes, each at most 64 characters.all
keep—together, with-nextall
area—Grid area name from the page's theme layout: a letter, then letters, digits, - or _.all
fgforegroundTheme token or alias, optional --light/--dark pin, or hex literal.paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
bgbackgroundTheme token or alias, optional --light/--dark pin, or hex literal.paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
szfont size, font_sizexxxs, xxs, xs, s, m, l, xl, xxl, xxxlparagraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
stfont style, font_styleSpace-separated b/bold, i/italic, u/underline (s/strong also means bold).paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
alalign, font align, font_align-, <, >, ^, c, center, j, justify, l, left, r, right, vparagraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, button, cols, col, header, footer
mmarginScale units: a3, t4 b2, x3 y2.paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
ppaddingScale units: a3, t4 b2, x3 y2.paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, col, header, footer
sspace, spacinginteger, ≥ 0 or Scale units.paragraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
bborderSide, pixel width, optional colour: l3 red-500; use an array for multiple edges.paragraph, heading, span, visualisation, image, html, table, kpi, kpis, box, button, cols, col, header, footer
colspanspanallparagraph, heading, span, visualisation, image, callout, html, table, kpi, kpis, box, button, cols, col, header, footer
height—fill, intrinsic, or pixels. or integer, ≥ 0paragraph, callout, html, box
ref—stringvisualisation, image
width—Fraction, percent, decimal, full, or pixels. or number, ≤ 1visualisation, image
height—fill, intrinsic, or pixels. or integer, ≥ 0visualisation, image
title—boolean or stringvisualisation, image
caption—boolean or stringvisualisation, image
float—left, rightvisualisation, image
bleed—list of top, right, bottom, left, x, y, all or Page edges to run out to: top, right, bottom, left, x, y or all.visualisation, image, box
include_linkinclude linkbooleanvisualisation
fact—integervisualisation
clsclassstringvisualisation
link—stringimage
alt—stringimage
fit—cover, containimage
ref—stringattachment
format—png, pdf, pptxattachment
name—stringattachment, author
disposition—attachment, inlineattachment
mode—light, darkattachment
size—xs, sm, md, lg, xl, xxl, xxxlattachment
b—Side, pixel width, optional colour: l3 red-500; use an array for multiple edges.callout
type—alert, danger, err, error, info, succ, success, warn, warningcallout
title—stringcallout, frontpage, page
border—booleancallout
widths—Positive column ratios, percentages, or fr tokens.table
density—compact, normal, relaxedtable
sentiment—integer, ≥ 1 or list of integer, ≥ 1 or One-based column numbers.table
heat—integer, ≥ 1 or list of integer, ≥ 1 or string or One-based column numbers or ranges, e.g. 2-11.table
heat_maxheat maxnumber or A positive magnitude, e.g. 6 or 6%.table
bars—integer, ≥ 1 or list of integer, ≥ 1 or string or One-based column numbers or ranges, e.g. 2-11.table
bars_maxbars maxnumber or A positive magnitude, e.g. 6 or 6%.table
bar_colorbar colorinteger, ≥ 1, ≤ 64table
waterfall—booleantable
stack—booleantable
labels—booleantable
vertical—booleantable
steps—integer, ≥ 1 or list of integer, ≥ 1 or string or One-based column numbers or ranges, e.g. 2-11.table
caption—string / number / booleantable
source—string / number / booleantable
value—string / number / booleankpi
label—string / number / booleankpi, button
desc—string / number / booleankpi
sentiment—good, bad, autokpi
variant—cardkpi
cols—integer, ≥ 1, ≤ 12kpis
levels—integer, ≥ 1, ≤ 6 or list of integer, ≥ 1, ≤ 6 or Depth, or explicit heading levels as a list.toc
leader—dots, line, nonetoc, tocpage
al—-, <, >, ^, c, center, j, justify, l, left, r, right, vbox
width—Fraction, percent, decimal, full, or pixels. or number, ≤ 1box, button
align—left, center, rightbox
href—HTTP(S), mailto, tel, or a relative resource path.button
variant—primary, secondary, linkbutton
p—Scale units: a3, t4 b2, x3 y2.cols
count—integer, ≥ 1, ≤ 12cols
valign—top, center, bottomcols
separator—stringcols
gappaddingintegercols
width—Fraction, percent, or decimal share. or number, ≤ 1col
cascade—booleanheader, footer
orientationorientportrait, landscapefrontpage, page
subtitle—stringfrontpage, page
date—stringfrontpage, page
author—stringfrontpage, page
section—string / number / booleantocpage, page
depth—integer, ≥ 1, ≤ 6tocpage
include_pagenuminclude pagenumbooleantocpage
numbering—1, i, I, 1startpagination
type—Page type hook: a letter, then letters, digits, - or _; at most 32 characters (e.g. cover, toc).page
autopaginate—booleanpage
latex—booleanpage
cols—integer, ≥ 1, ≤ 12 or Positive track ratios, e.g. 2 1.page
column_fillcolumn-fill, column fillauto, balancepage
ref—stringpage
header—boolean or stringpage
footer—boolean or stringpage
pnum—boolean or integer or stringpage
username—stringauthor
pfx—stringauthor
include_pictureinclude picturebooleanauthor
include_bioinclude biobooleanauthor
override_biooverride biostringauthor

A visualisation's title defaults to visible in documents and hidden in e-mails; title: true or title: false overrides it. Required keys: ref for visualisations/images, value for KPI tiles, and href for buttons. Omitted style values use the theme. Config values are separated by commas on one line or by newlines in YAML. Hide content with <!-- ... --> or {/* ... */} comments (inline or multiline). Comments are ignored before parsing, including any blocks, references and attachments inside them. Code spans and fenced code blocks keep comment markers literal. Comments do not nest; an unclosed comment hides the remaining content.