Skip to content

Built-in components

There are ten built-in components, plus InlineCode, which only lives inside runs. To see the full props definitions:

终端窗口
fmtagno catalog # list components
fmtagno catalog --json # JSON Schema of every component's props
Component Purpose Container Parts
Document Root container; also for grouping yes —
Heading Heading, levels 1–6 no —
Text A paragraph no —
Code A code block no —
List List, can nest no level1…level9 marker item
Table Table no see Tables
Image Image no caption
PageBreak Page break no —
Section Section yes —
Slide One slide yes title body

Each component’s built-in default style is listed below. To change it, see Styles.

The root container; lays out its children in order. No props.

"doc": { "type": "Document", "children": ["title", "intro"] }

Document can be nested: put a few paragraphs in one, style it, and text fields flow down to each child. Custom component templates often use it as their root.

Prop Type Required Meaning
level integer 1–6 yes Heading level
text string or runs yes Heading text
"title": { "type": "Heading", "props": { "level": 1, "text": "Quarterly report" } }
  • Defaults: bold, keepWithNext, 12pt before, 6pt after, line height 1.25. Sizes: level 1 20pt (18pt before), 2 16pt, 3 14pt, 4 12pt, 5 and 6 11pt.
  • Style a single level with the component keys Heading.1 … Heading.6.
  • In docx, headings also get Word’s “Heading 1–6” styles, so the navigation pane and TOC work.
Prop Type Required Meaning
text string or runs yes Paragraph text; runs are explained in Document structure
"intro": { "type": "Text", "props": { "text": ["Run ", { "type": "InlineCode", "text": "fmtagno check" }, " to validate."] } }
  • Default: 6pt after.
  • An empty string "" still takes up one line, in all three formats.

Inline code. Not an element on its own; it only appears in runs:

{ "type": "InlineCode", "text": "fmtagno render doc.json -o out.pdf" }

Default: monospace (Menlo, Consolas, DejaVu Sans Mono) on #F0F1F3. Change it with the InlineCode component style.

A code block; spaces and line breaks are kept.

Prop Type Required Meaning
code string yes The code; use \n for new lines
language string no Language name. Only a label: html writes class="language-xxx"; no syntax highlighting
lineNumbers boolean no Show line numbers, default false
"sample": {
"type": "Code",
"props": { "language": "json", "code": "{\n \"type\": \"Text\"\n}", "lineNumbers": true }
}

Defaults: monospace, 9pt, line height 1.4, background #F6F8FA, padding 8pt, 8pt after, keepTogether.

docx paragraphs only use padding when they have a border, so code blocks get no padding in docx and you’ll see one warning. For padding, add a border in the background color.

Prop Type Required Meaning
items array yes List items
ordered boolean no Numbered, default false

Each item can be:

  • a string: "Write JSON"
  • a runs array: [{ "text": "fmtagno render", "type": "InlineCode" }, " to get files"]
  • an object with a sub-list: { "text": …, "items": [...], "ordered": true }. Without ordered it follows the parent level.
"list": {
"type": "List",
"props": {
"ordered": true,
"items": [
"Prepare data",
{ "text": "Pick a style set", "items": ["report", "slides"] },
"Render"
]
},
"style": { "listStyleType": "upper-roman", "listMarkerFormat": "%1." },
"parts": { "level2": { "listStyleType": "decimal", "listMarkerFormat": "%1.%2" } }
}
  • Defaults: 6pt after, listIndent 2em, listHanging 2em.
  • Without a type, levels rotate: ordered decimal → lower-alpha → lower-roman; unordered disc → circle → square.
  • Parts: level1…level9 for a level, marker for the number or bullet, item for each item’s text.
  • Numbering and indent fields: List style.
Prop Type Required Meaning
columns array of cells no Header row; if present it is the first row
rows 2-D array of cells yes Data rows
widths array no Column widths: ratio, fixed length or "auto"
rowHeights array no Row heights
look object no Which parts are active
"price": {
"type": "Table",
"props": {
"columns": ["Item", "Price"],
"widths": [3, 1],
"rows": [["Apple", "3.50"], ["Pear", "4.00"]]
},
"parts": { "header": { "background": "#1A73E8", "color": "#FFFFFF" } }
}

Defaults: 0.5pt solid #999999 borders, cellPadding 4pt, repeatHeader on, 8pt after; header bold on #F3F3F3.

Merged cells, per-cell styles, row heights and parts are in Tables.

Prop Type Required Meaning
src string yes Local path or URL. Relative paths resolve from the document’s directory
alt string no Alt text, shown when the image can’t be embedded
width number (pt) no Width
height number (pt) no Height. Give one and the other keeps the aspect ratio
caption string no Caption shown below the image
"logo": { "type": "Image", "props": { "src": "logo.png", "alt": "fmtagno", "width": 90, "caption": "Figure 1. Logo" } }

Defaults: 6pt after; caption 9pt #666666 (part caption). Format support and positioning: Images.

Starts a new page. No props.

"break": { "type": "PageBreak" }

Plain html shows no page breaks; they appear when printing or with --paged.

A section. Each one starts on a new page and can set its own paper size, orientation, margins, columns, headers and footers, and page-number start. Sections can only sit directly under the root.

"body": {
"type": "Section",
"props": { "landscape": true, "pageNumberStart": 1, "footer": "ftr" },
"children": ["h1", "p1"]
}

Props and usage: Sections, headers and footers.

One 16:9 slide; children are laid out inside.

Prop Type Required Meaning
title string no Slide title
"cover": { "type": "Slide", "props": { "title": "Cover" }, "children": ["cover-text"] }
  • Parts: title (default 20pt bold) and body.
  • In html and pdf each slide takes one page.
  • In docx a slide becomes a level-2 heading plus its content, followed by a page break; the body part has no effect there.
  • Real pptx output comes in version 2.