--- name: write-md-to-docx description: >- Use when authoring or editing Markdown that will be converted to .docx with the md-to-docx tool. Covers its directive system (@config / @doc / @header / @footer / @pagebreak), inline & block @style, {doc.*}/{vars.*}/{date} variables, internal #slug links, heading numbering, tables, and mermaid. Write to this dialect — not plain Markdown — and verify by running the converter and reading its warnings. --- # Writing Markdown for md-to-docx md-to-docx is **not** CommonMark. It is a line-by-line parser with an HTML-comment directive layer. Author to the rules below, then **always run the validation loop** at the end. Full detail (every config key, default, and unit) is in [`reference.md`](reference.md). This file is the working cheat-sheet — read `reference.md` when you need a value you don't see here. ## Rule #1 — config lives in directives, NOT YAML frontmatter There is **no `---` frontmatter**. A leading `---` is parsed as a horizontal rule. All document config goes in `` / `` comment blocks (mini-YAML body). ```markdown ``` `@doc` keys → `{doc.*}` variables. `@config vars:` → `{vars.*}`. Later blocks win on key collision. **Spacing** — every block type (`body`, `heading` + per-level `h1`…`h6`, `list`, `quote`, `table`, `code`) takes `line_spacing` (multiple; default `1.5`, but `code`/`table` = `1.0`), `space_before`, and `space_after` (pt). `heading.line_spacing` is shared by all levels unless a level overrides it. ## Directives | Directive | Purpose | Example | |:--|:--|:--| | `@config` | Document styling/layout (mini-YAML body) | see above | | `@doc` | Metadata → `{doc.*}` vars (mini-YAML body) | see above | | `@header` / `@footer` | Running header/footer, 3 zones | `` | | `@pagebreak` | Hard page break | `` | | `@style` | Inline / block run styling | see below | Header/footer args: `left=`, `center=`, `right=` (quote values with spaces), plus `size`, `color`, `font`, `border_top`/`border_bottom`, `skip_on_first_page` (bool, or an int N to leave the first N `@pagebreak` segments un-numbered and restart page numbering at 1 after them). `{page}`/`{pages}` become real page-number fields **only here** (in body they stay literal). ## @style — three forms ```markdown Inline (wrapping): This is important text. Self-close (to end of line): Price: 1,000,000 VND Self-close alone (styles the NEXT line; align only works here): Centered Title On Its Own Line ``` Keys: `color`, `bg`, `highlight`, `bold`, `italic`, `underline`, `strike`, `sup`, `sub`, `font`, `size` (pt), `align` (`left`/`center`/`right`, **paragraph-level — only when @style starts the line**). Colors: named (`red`, `blue`, `green`, `orange`, `gray`, …) or hex (`#cc0000` / `cc0000`). Markdown still parses inside a styled span. ## Variables - `{doc.*}`, `{vars.*}`, `{date}`, `{now}` — expand **everywhere**: prose, headings, list items, table cells, bold/italic spans, link labels, and header/footer. - `{page}` / `{pages}` — page-number fields **in header/footer only**; literal in body. - Inside inline code `` `{doc.title}` `` they are **not** expanded (verbatim). - Unknown refs stay literal and emit a `var` warning (so typos are caught). ## Standard Markdown + parser gotchas Bold `**x**`, italic `*x*`, inline code `` `x` ``, external `[t](https://…)`, **internal `[t](#heading-slug)`** (slug = GitHub-style: lowercase, spaces→`-`, punctuation stripped; Vietnamese diacritics kept; duplicate headings get `-1`, `-2`). Tables, fenced code, images `![alt](path)`, `>` blockquotes, `---` HR all work. Watch out — these differ from CommonMark: - **No paragraph merging.** Each non-blank line is its own block. To extend a list item onto more lines, let them ride as **lazy continuation**: an unmarked line *immediately after* a bullet/numbered item is appended to that item **on a new line** (the newline becomes a hard line break, not a space; no blank line between). - **List nesting caps at level 2**; indent is relative (2- or 4-space schemes both work). Any heading/code/table/quote/image/HR resets the list. - **A line starting with `