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 componentsfmtagno 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.
Document
Section titled “Document”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.
Heading
Section titled “Heading”| 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.
InlineCode
Section titled “InlineCode”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 }. Withoutorderedit 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,
listIndent2em,listHanging2em. - Without a type, levels rotate: ordered
decimal→lower-alpha→lower-roman; unordereddisc→circle→square. - Parts:
level1…level9for a level,markerfor the number or bullet,itemfor 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.
PageBreak
Section titled “PageBreak”Starts a new page. No props.
"break": { "type": "PageBreak" }Plain html shows no page breaks; they appear when printing or with --paged.
Section
Section titled “Section”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) andbody. - 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
bodypart has no effect there. - Real pptx output comes in version 2.
- Styles: where styles go and how they combine.
- Tables, Images, Sections, headers and footers.