# Syntax

> A quick reference to the whole Folio language, from document structure to escapes.

This page sums up the whole language in short tables. For step-by-step explanations, see the [guides](/docs/en/guides/writing/); for the values each attribute accepts, see [Attributes](/docs/en/reference/attributes/).

## Document structure

A document has two parts, in this order:

1. **Preamble** (optional): lines that start with `@`, only at the top of the file.
2. **Slides**: everything else. The first content that is not a definition starts slide 1, and each `---` starts a new slide.

```folio
@title Quarterly results
@theme paper

# First slide

--- {.dark align=center}
# Second slide
```

### Preamble definitions

| Definition | Form | Effect |
| --- | --- | --- |
| `@title` | `@title Text` | Presentation title. |
| `@author` | `@author Name` | Presentation author. |
| `@theme` | `@theme paper` | Built-in theme: `paper` (default), `ink` or `editorial`. |
| `@version` | `@version 1` | Language version. The only current version is `1`. |
| `@aspect` | `@aspect 16:9` | Aspect ratio: `16:9` (1920×1080, default) or `4:3` (1440×1080). |
| `@color` | `@color brand #ff6b4a` | Creates or replaces a color token. |
| `@font` | `@font title "Bebas Neue" 400 700` | Creates or replaces a font token (a Google Fonts family and weights from 100 to 900). |
| `@style` | `@style highlight {color=brand weight=bold}` | Creates a reusable style, applied with `.highlight`. |
| `@component` … `@end` | `@component name {param param=default}` | Defines a component. The body runs until the `@end` line. |
| `@header` … `@end` | `@header {attributes}` | Header repeated on every slide except the cover. See [Header and footer](/docs/en/guides/header-footer/). |
| `@footer` … `@end` | `@footer {attributes}` | Footer repeated on every slide except the cover. `@footer none` turns off the project theme's footer. |

Color, font, style and component names use lowercase letters, numbers and hyphens, starting with a letter. Blank lines and comments may appear between definitions. A definition after the first slide is an error ([F103](/docs/en/reference/errors/)).

### Slide separator

| Form | Effect |
| --- | --- |
| `---` | Starts a new slide. Three or more hyphens, alone on the line. |
| `--- {attributes}` | Starts a new slide and applies attributes to the whole slide. |
| `--- {#id}` | Gives the slide an id, used by internal links such as `[back](#id)`. |

- If the document starts with `---` right after the preamble, that separator configures the first slide; no empty slide is created.
- A `---` inside a code block does not split slides.
- The slide title (used by thumbnails and presenter mode) is the first `#` heading of the slide; without a heading, it is "Slide N".

## Supported Markdown

| Construct | Syntax | Notes |
| --- | --- | --- |
| Headings | `# Heading` … `###### Heading` | Six levels. A space after the `#` signs is required. |
| Paragraph | Consecutive lines of text | Every line break becomes a line break on the slide. A blank line separates paragraphs. |
| Bold | `**text**` | Asterisks only. |
| Italic | `*text*` | Asterisks only; `_text_` is not italic. |
| Strikethrough | `~~text~~` | |
| Inline code | `` `code` `` | The content is not interpreted. |
| Link | `[text](https://…)` | Accepts `https://`, `http://`, `mailto:` and `#slide-id`. |
| Span with attributes | `[text]{color=accent}` | The braces go right after the `]`. |
| Inline image | `![description](https://…)` | Inside a paragraph; accepts attached attributes: `![x](…){h=60}`. |
| Block image | `![description](https://…){fit=cover}` | Alone on its line. Accepts `https://`, `http://`, `data:image/…` and `asset:<id>`. |
| List | `- item`, `* item` or `+ item` | Nest items with indentation. Indented lines continue the item. |
| Numbered list | `1. item` or `1) item` | The first number sets where counting starts. |
| Quote | `> text` | May contain other blocks, such as lists and headings. |
| Code block | ` ```js ` … ` ``` ` | The language is optional; attributes may go at the end of the opening line. |
| Table | `\| A \| B \|` + `\| --- \| --- \|` | The second line is required. `:---`, `:---:` and `---:` align the column. |

HTML is not interpreted: `<b>` shows up as text on the slide.

## Attributes

Attributes go in braces and configure the block, span or slide they belong to.

| Form | Example | Meaning |
| --- | --- | --- |
| `.style` | `{.card}` | Applies a built-in style, a `@style` or a color token (`{.coral}` is the same as `{color=coral}`). |
| `#id` | `--- {#summary}` | Slide id. Only works on the separator. |
| `key=value` | `{size=5xl}` | Value without spaces. |
| `key="value"` | `{pad="sm lg"}` | Value with spaces, in double or single quotes. Use `\"` for a quote inside the value. |
| `key` | `{italic}` | Turns a boolean attribute on. To turn it off: `italic=false`. |

Boolean values accept `true`, `yes` and `sim` to turn on, and `false`, `no` and `não` to turn off.

### Where attributes go

| Where | Position | Example |
| --- | --- | --- |
| Headings, paragraphs, list items, opening line of code | At the end of the line, **with a space before** | `# Heading {size=5xl}` |
| `:::` and `::` blocks | At the end of the block line | `::: box {.card}` |
| Slide separator | After `---` | `--- {bg=ink color=white}` |
| Text span | **Attached** to the `]` | `[38%]{color=accent}` |
| Image | **Attached** to the `)` | `![Photo](https://…){fit=cover}` |

In a multi-line paragraph, attributes at the end of a line apply to the whole paragraph and end it. Styles (`.style`) are applied first, and `key=value` pairs written on the block itself override them.

## Blocks

| Form | Use |
| --- | --- |
| `::: name {attributes}` … `:::` | Container block. A `:::` alone on a line closes the last open block. |
| `:: name value {attributes}` | Single-line block, with no content. |

Blocks can be nested. Indentation is optional and only helps readability.

```folio
::: columns {widths="2 1"}
::: stack
## Left
Text
:::
:: icon rocket {size=3xl color=accent}
:::
```

| Block | Form | Purpose |
| --- | --- | --- |
| `columns` | `:::` | Side-by-side columns; each child is a column. |
| `stack` | `:::` | Stacks its children vertically. |
| `row` | `:::` | Lays its children out horizontally. |
| `grid` | `:::` | Grid with a fixed number of columns. |
| `box` | `:::` | Box with background, border and spacing. |
| `steps` | `:::` | Reveals each child, or each list item, one at a time. |
| `notes` | `:::` | Speaker notes; not shown on the slide. |
| `chart` | `:::` | Chart built from a table. |
| `slot` | `:::` | Fills a named slot of a component. |
| `icon` | `::` | Icon: `:: icon rocket`. |
| `spacer` | `::` | Empty space: `:: spacer lg`. |
| `divider` | `::` | Divider line. |

Details for each block in [Blocks](/docs/en/reference/blocks/).

## Components

| Form | Meaning |
| --- | --- |
| `@component name {a b=default}` | Defines the component `name` with the required parameter `a` and the parameter `b` with a default value. |
| `@end` | Ends the definition. |
| `:: name {a=value}` | Uses the component without content. |
| `::: name {a=value}` … `:::` | Uses the component with content, which goes to `$content`. |
| `::: slot side` … `:::` | Inside a component use, fills the named slot `$side`. |
| `{step=N}` on the use | Reveals the whole component at step `N`. |

Components only take named parameters: `.style`, `#id` and loose text after the name are errors. Components cannot use themselves, directly or indirectly.

## `$` placeholders

| Placeholder | Where | Effect |
| --- | --- | --- |
| `$param` | In a component body, in text or an attribute value | Replaced by the parameter value: `## $title`, `{color=$tone}`. |
| `$content` | Alone on a line of the body | Receives the content passed between `::: name` and `:::`. |
| `$name` | Alone on a line of the body, when `name` is not a parameter | Named slot, filled with `::: slot name`. It stays empty if not filled. |
| `$page`, `$pages`, `$title`, `$author`, `$date` | Inside `@header` and `@footer` | Slide number, total slides, title, author and today's date. Any other name is an error ([F522](/docs/en/reference/errors/)). |

Outside a component, `@header` and `@footer`, `$word` is plain text. The only exception is `$content` alone on a line, which is an error ([F401](/docs/en/reference/errors/)).

## Comments

A line that starts with `//` (with or without leading spaces) is ignored, both in the preamble and in slides.

```folio
// Check these numbers before the meeting
# Results
```

- `//` in the middle of a line is plain text.
- Inside code blocks and `::: notes`, lines with `//` are kept.

## Escapes

| Write | To get |
| --- | --- |
| `\*`, `\~`, `` \` ``, `\[`, `\]`, `\!` | The literal character, with no formatting. |
| `\{` | A literal brace; keeps a trailing `{…}` from becoming attributes. |
| `\\|` | A vertical bar inside a table cell. |
| `\#` at the start of a line | A literal `#`, not a heading. |
| `\"` inside a quoted value | A quote inside the value. |

A backslash escapes any ASCII punctuation mark. Before other characters, it shows up as is.

## Complete example

```folio
// Preamble: definitions only, at the top of the file
@title Quarterly report
@theme paper
@color brand #2f6fdb
@style highlight {color=brand weight=bold}
@component metric {value label tone=accent}
::: box {.card align=center}
$value {size=4xl weight=black color=$tone}
$label {.muted}
:::
@end

// Slide 1: the first content starts the slide
Quarterly report {.kicker}
# Revenue grew [38%]{.highlight} {size=5xl}
New customers, better retention
and a bigger team. {.lead}

// Slide 2: separator with an id and slide attributes
--- {#numbers align=center}
## Numbers that matter
::: grid {cols=3 gap=lg}
:: metric {value=+38% label=Revenue}
:: metric {value=12k label=Customers tone=green}
:: metric {value=4.8 label=Rating tone=blue}
:::

::: notes
Point out the customer rating.
:::

// Slide 3: gradient background and step-by-step reveal
--- {bg=ink..violet color=white}
## Next steps
::: steps
- Open two new regions
- Launch the annual plan
- Hire the support team
:::
Details on the [numbers slide](#numbers). {opacity=0.7}
```
