Prettier plugin
@kadal/prettier-plugin formats deck files the way the engine reads them. It is the formatter
behind kadal-deck format and the VS Code extension, packaged for any editor or CI
that already runs Prettier 3.
You don’t need it to format a deck from the command line: npx kadal-deck formatpnpm exec kadal-deck formatyarn kadal-deck formatbunx kadal-deck format runs the same
formatter with no setup (see the CLI reference). Install the plugin when Prettier
already formats the rest of your project.
Install
Section titled “Install”npm install --save-dev prettier @kadal/prettier-pluginpnpm add -D prettier @kadal/prettier-pluginyarn add -D prettier @kadal/prettier-pluginbun add -D prettier @kadal/prettier-pluginAdd it to your Prettier configuration:
{ "plugins": ["@kadal/prettier-plugin"] }That is all: with the plugin loaded, a file named deck.mdx or slides.mdx is formatted as a
deck. Other deck files ask for it by parser:
{ "plugins": ["@kadal/prettier-plugin"], "overrides": [{ "files": ["talks/*.mdx"], "options": { "parser": "kadal-deck" } }]}Then format as usual:
npx prettier --write deck.mdxpnpm dlx prettier --write deck.mdxyarn dlx prettier --write deck.mdxbunx prettier --write deck.mdxWhat it changes
Section titled “What it changes”Given this:
---title: Messy talk---# Hello* one* two---layout: center---## Second slideit writes:
---title: Messy talk---
# Hello
- one- two
---layout: center---
## Second slide- Separators: exactly
---between slides and----for a slide beneath (a vertical stack), with one blank line around each. Empty pieces the engine would skip are removed. - Headmatter and frontmatter: the YAML through Prettier’s YAML printer. Comments stay, keys stay
in the order you wrote them, and the values are checked to be unchanged. A frontmatter written as
a
```yamlblock stays a block. - Slide bodies: Prettier’s Markdown printer:
-bullets,_emphasis_, aligned tables, one blank line between blocks. A thematic break is written***, since---would start a new slide.
Left exactly as written:
- code fences, with their steps, titles and
{monaco}options, and magic-move blocks; <Notes>and the HTML-comment notes at the end of a slide;<style>blocks;$$ … $$maths;::right::slot markers,::code-group…::,<<< @/snippetimports;- JSX and expressions.
Safety
Section titled “Safety”Prettier’s Markdown printer reads MDX the way MDX 1 did, and the engine compiles MDX 3. So every formatted slide is parsed again (as CommonMark, and as MDX 3 when the slide is valid MDX 3) and compared with the original as a syntax tree. A slide whose meaning would change keeps its text as written. The whole deck is then cut again and checked to have the same slides, stacked the same way, with the same frontmatter. If it hasn’t, the formatter stops with an error instead of writing.
To keep a slide exactly as you wrote it, put prettier-ignore anywhere in it, for example a
<!-- prettier-ignore --> line above the part that matters: a slide containing prettier-ignore
is left alone.
Options
Section titled “Options”| Option | Default | Meaning |
|---|---|---|
kadalDeckBodies |
true |
false formats only the separators and the frontmatter, and leaves every slide’s body as is |
On the command line it is --kadal-deck-bodies=false. Prettier’s own printWidth, tabWidth,
useTabs, proseWrap, singleQuote, bracketSpacing and endOfLine reach the YAML and Markdown
printers as usual.
Fail a build when a deck isn’t formatted:
npx prettier --check "**/deck.mdx"pnpm dlx prettier --check "**/deck.mdx"yarn dlx prettier --check "**/deck.mdx"bunx prettier --check "**/deck.mdx"or, without the plugin installed, npx kadal-deck format --checkpnpm exec kadal-deck format --checkyarn kadal-deck format --checkbunx kadal-deck format --check, which exits 1 when a file would
change and names it.
From your own code
Section titled “From your own code”import * as prettier from "prettier";import { formatDeck } from "@kadal/prettier-plugin";
const { text, changed, kept } = await formatDeck(source, prettier, { proseWrap: "preserve" });// kept: [{ slide, line, reason }] for each part left as written, and whyformatDeck throws a DeckFormatError when the result would not be the same deck.
The plugin is AGPL-3.0-or-later, like the engine; source.