Guide

YAML guide

Learn document blocks, styles, composition, tables, visuals, and reusable authoring patterns.

View Markdown source

RusDox is designed so the YAML reads like the document.

The basic shape is always:

version: 1
output_name: my-document
blocks:
  - type: title
    text: My Document
  - type: body
    text: This is a paragraph.

Top-Level Fields

version

  • Required for new files
  • Current value: 1
  • Use rusdox migrate legacy.yaml --in-place for legacy unversioned files

output_name

  • Optional
  • Controls the file name of the generated output
  • If omitted, RusDox uses the spec file stem

metadata

  • Optional
  • Controls DOCX package properties such as title, author, subject, keywords, and custom properties

blocks

  • Required for real documents
  • Ordered from top to bottom
  • This is the document structure

styles

  • Optional
  • Defines reusable named paragraph, run, and table styles
  • Supports inheritance through based_on
  • Paragraph styles can also set next

variables

  • Optional
  • Defines reusable values for nested interpolation, repeat blocks, and bounded conditions

Metadata

Use metadata when generated documents need clean properties in Word, search tools, or downstream automation.

metadata:
  title: Client Rollout Plan
  author: RusDox Studio
  subject: Q4 regional rollout
  language: en-US
  keywords:
    - rollout
    - planning
  custom_properties:
    Client: Northwind Health
    Sponsor: Maya Chen

Supported metadata fields:

  • title
  • author
  • subject
  • language: a BCP 47-style document language such as en-US, fr, or mul
  • keywords
  • custom_properties

custom_properties values are stored as string custom properties in the DOCX package.

Variables, Includes, And Repeaters

Use these features when one YAML file would otherwise become repetitive.

Variables use {{name}} placeholders:

variables:
  client: Northwind Health
  quarter: Q4 2026

blocks:
  - type: title
    text: "{{client}} Rollout Plan"
  - type: subtitle
    text: "{{quarter}} program snapshot"

Includes inline reusable block fragments relative to the current YAML file:

blocks:
  - type: include
    path: fragments/summary.yaml
    variables:
      sponsor: Maya Chen

An included YAML fragment can be:

  • a single block mapping
  • a sequence of blocks
  • a mapping with optional variables plus blocks

Repeaters expand a block template for each item in a sequence:

variables:
  regions:
    - name: North America
      owner: Maya
    - name: EMEA
      owner: Leon

blocks:
  - type: repeat
    variable: regions
    as: region
    blocks:
      - type: section
        text: "{{region.name}}"
      - type: body
        text: "Owner: {{region.owner}}"

Supported repeat fields:

  • variable: name of a sequence variable to iterate
  • items: inline sequence to iterate
  • as: loop variable name, defaults to item
  • blocks: template block list

Each repeat iteration also exposes:

  • repeat_index: zero-based index
  • repeat_number: one-based index

Conditions, filters, and escaping

Use a bounded when block for truthiness or exact scalar equality:

variables: customer: active: true blocks:

  • type: when path: customer.active equals: true blocks:
  • type: body text: Active customer otherwise:
  • type: body text: Inactive customer

Expressions support nested mapping/array paths and exactly five deterministic filters: upper, lower, title, trim, and default("text").

text: "{{ customer.name | trim | title }}" text: "{{ customer.owner | default(\"unassigned\") | upper }}"

Write four opening braces and four closing braces for literal double braces. Expression values always become document text; they cannot inject raw OOXML or execute code. The same expression behavior is available to JSON and TOML specs. See Spec Versioning and Authoring Tools.

Named Styles

Use named styles when the document needs stable reusable formatting instead of repeating direct properties on every block.

Example:

styles:
  paragraph:
    - id: lead
      based_on: Normal
      next: body
      paragraph:
        alignment: center
        spacing_after: 180
        keep_next: true
      run:
        bold: true
        color: "0F172A"
        font_family: Georgia
        font_size: 28
  run:
    - id: accent
      based_on: DefaultParagraphFont
      properties:
        italic: true
        color: "AA5500"
  table:
    - id: grid
      based_on: TableNormal
      properties:
        width: 9360

blocks:
  - type: paragraph
    spec:
      style_id: lead
      runs:
        - text: Styled
        - text: " emphasis"
          style_id: accent
  - type: table
    spec:
      style_id: grid
      columns:
        - label: Metric
          width: 4680
      rows:
        - cells:
            - kind: text
              text: ARR

Style definition groups:

  • styles.paragraph
  • styles.run
  • styles.table

Paragraph style fields:

  • id
  • name
  • based_on
  • next
  • paragraph.list
  • paragraph.alignment
  • paragraph.spacing_before
  • paragraph.spacing_after
  • paragraph.keep_next
  • paragraph.page_break_before
  • run.bold
  • run.italic
  • run.underline
  • run.strikethrough
  • run.small_caps
  • run.shadow
  • run.color
  • run.font_family
  • run.font_size
  • run.vertical_align

Run style fields:

  • id
  • name
  • based_on
  • properties.bold
  • properties.italic
  • properties.underline
  • properties.strikethrough
  • properties.small_caps
  • properties.shadow
  • properties.color
  • properties.font_family
  • properties.font_size
  • properties.vertical_align

Table style fields:

  • id
  • name
  • based_on
  • properties.width
  • properties.borders

Units:

  • paragraph spacing and table widths use twips
  • run font_size uses OOXML half-points, so 24 means 12pt

Simple Block Types

Use these when you want readable documents with strong defaults:

  • cover_title
  • title
  • subtitle
  • hero
  • centered_note
  • page_heading
  • section
  • body
  • tagline
  • image
  • logo
  • signature
  • chart
  • spacer

Example:

blocks:
  - type: cover_title
    text: Board Report
  - type: subtitle
    text: March 2026
  - type: hero
    text: Prepared automatically with RusDox
  - type: centered_note
    text: Internal use only
  - type: page_heading
    text: Board Narrative
  - type: body
    text: Revenue expanded faster than forecast.

page_heading starts a new page before the heading.

spacer adds vertical space when you want breathing room between sections.

Visual Blocks

Use visual blocks when the document needs brand marks, screenshots, signatures, or SVG charts.

Example:

- type: logo
  path: ../assets/rusdox-mark.svg
  alt_text: RusDox logo
  max_width_twips: 2200

- type: image
  path: ../assets/template-gallery.png
  alt_text: RusDox template gallery
  max_width_twips: 7200

- type: chart
  path: ../assets/benchmark-stress-1000-pages.svg
  alt_text: RusDox benchmark chart
  max_width_twips: 7200

- type: signature
  path: ../assets/signature-demo.svg
  alt_text: Automated approval signature
  max_width_twips: 2800

Supported visual fields:

  • path
  • alt_text
  • alignment: left, center, right, justified
  • width_twips
  • height_twips
  • max_width_twips
  • max_height_twips

Supported file formats:

  • PNG
  • JPEG
  • SVG

alt_text is required and must be meaningful. It is preserved in the DOCX drawing properties and checked against the PDF semantic projection; a file name or blank string does not satisfy validation. See the international and accessibility contract.

List Blocks

bullets

- type: bullets
  items:
    - Confirm launch date
    - Finalize sales enablement
    - Publish support macros

label_values

Good for notes, metadata, meeting headers, and document summaries.

- type: label_values
  items:
    - label: Date
      value: 2026-03-10
    - label: Owner
      value: Operations

metrics

Good for dashboard-style cards.

Available tones:

  • positive
  • neutral
  • warning
  • risk
- type: metrics
  items:
    - label: ARR
      value: $18.7M
      tone: positive
    - label: Cash Runway
      value: 24 mo
      tone: warning

Tables

Tables use explicit columns and rows.

Each column needs:

  • label
  • width

Each row has cells.

Each cell can be:

  • kind: text
  • kind: status

Example:

- type: table
  spec:
    style_id: grid
    columns:
      - label: Category
        width: 2800
      - label: Current
        width: 2000
      - label: Status
        width: 1600
    rows:
      - cells:
          - kind: text
            text: ARR
          - kind: text
            text: $18.7M
          - kind: status
            text: Strong
            tone: positive

width values are DOCX table widths in twips.

You usually only need to copy a working table from an example and edit the content.

Custom Paragraphs

Use paragraph when you need mixed formatting inside one paragraph.

Example:

- type: paragraph
  spec:
    alignment: center
    spacing_after_twips: 120
    runs:
      - text: "This is "
      - text: important
        bold: true
      - text: " and "
      - text: styled
        italic: true
        color: D00000

Supported paragraph fields:

  • runs
  • style_id
  • alignment: left, center, right, justified
  • spacing_before_twips
  • spacing_after_twips
  • page_break_before
  • section_break_before

Supported run fields:

  • text
  • style_id
  • bold
  • italic
  • underline
  • strikethrough
  • small_caps
  • shadow
  • color
  • font_family
  • size_pt
  • vertical_align
  • hyperlink: https://, http://, mailto:, or #bookmark
  • bookmark: 1–40 ASCII letters, digits, or underscores
  • field: currently table_of_contents
  • footnote

Underline values:

  • single
  • double
  • dotted
  • dash
  • wavy
  • words
  • none

Vertical align values:

  • superscript
  • subscript
  • baseline

Shared Page Controls And Semantic Blocks

page_setup, header, footer, and page_numbering are consumed by both DOCX and PDF. Orientation is explicit and must agree with width and height.

page_setup:
  width_twips: 15840
  height_twips: 12240
  orientation: landscape
  margin_top_twips: 1080
  margin_right_twips: 900
  margin_bottom_twips: 1080
  margin_left_twips: 900
header:
  text: Quarterly review
  alignment: right
footer:
  text: Page {page} of {pages}
  alignment: center
page_numbering:
  start_at: 3
  format: lower_roman
blocks:
  - type: table_of_contents
    title: Contents
  - type: page_break
  - type: section_break

The DOCX TOC is an updateable Word field. PDF emits the heading list known from the spec at render time and does not invent page numbers.

Rich Table Rows And Cells

Rows accept repeat_as_header and allow_split_across_pages. A kind: rich cell accepts paragraphs, horizontal grid_span, background_color, and an optional nested_table. See dual_output_contract.yaml for a complete, parity-tested example.

Best Practices

  • Use variables for repeated values, not for every sentence in the document.
  • Reach for include and repeat before moving to Rust if the workflow is still mostly static content.
  • Prefer title, section, body, bullets, metrics, and table before reaching for custom paragraphs.
  • Let config control styling instead of repeating style values everywhere.
  • Copy a close example and edit the content.

See Real Files