Mermaid and KaTeX
Mermaid and KaTeX
Diagrams and math, no plugins needed.
Mermaid diagrams
Use a fenced code block with language mermaid:
```mermaid
flowchart LR
Idea --> Note
Note --> Draft
Draft --> Published
Draft --> Archived
```
Lettuce ships Mermaid 11 bundled in the app and the static site, so diagrams render without an internet connection. Supported diagram types include:
flowchart/graph— DAGs and treessequenceDiagram— interaction over timestateDiagram-v2— state machinesclassDiagram— UMLerDiagram— entity-relationshipgantt— project timelinespie— pie chartsmindmap— radial outlinesjourney— user journey mapsgitGraph— git history
Full reference: https://mermaid.js.org/intro/.
Theme
Mermaid uses Lettuce’s current theme automatically (light or dark). Override per-diagram:
```mermaid
%%{init: { 'theme': 'forest' } }%%
flowchart LR
A --> B
```
Data-driven charts
For quantitative data (rather than node-and-edge diagrams), use a fenced code block with language
chart and a small JSON spec. Lettuce renders it to an inline SVG with a bundled, dependency-free
renderer — no network, works in the app, the static site, and slide decks:
```chart
{
"type": "bar",
"title": "Notes added per month",
"labels": ["Jan", "Feb", "Mar"],
"series": [{ "name": "2026", "data": [12, 19, 14] }]
}
```
type—bar(default),line, orpie.bar/lineaccept multipleseries(grouped bars / overlaid lines, with a legend);pieuses the first series.labels— the x-axis (or pie slice) labels.series—[{ "name": "...", "data": [n, n, …] }, …].Shorthand for a single series:
"data": [["Jan", 12], ["Feb", 19]](label/value pairs).
If the spec isn’t valid JSON the block degrades to its readable source text rather than failing.
Charts inherit the page’s text color (currentColor) so they track light/dark automatically. For
flowcharts, sequence diagrams, and the like, use Mermaid above; for data series, use chart.
Dynamic note queries
A query (or dataview) fenced block resolves at publish time into a static table or list of
the notes that match — so an index page can list “every note tagged #fruit, sorted by date”
without you hand-maintaining the list. The spec is line-based key: value:
```query
from: #fruit
fields: title, status
sort: -date
limit: 20
```
from— which notes to include: a#tag(nested-aware, so#topicalso matches#topic/ml) or a folder path (Concepts). Omit it to match every published note.fields— the columns. Usetitle,path,name,tags, or any frontmatter key. With one field the block renders as a bulleted list of links; with several it renders as a table whose first column links to the note.sort— a field name; prefix-for descending. Defaults totitle.limit— cap the number of rows.as—table(default) orlist.
The block is resolved by lettuce publish (which has every note’s frontmatter), so it reflects the
vault at build time — re-publish to refresh it. In the in-app reader the block shows its readable
spec rather than the resolved table; the live table appears on the published site. See
The LLM-wiki pattern for using queries to build self-updating index pages.
KaTeX math
Inline math with $...$:
Einstein famously wrote $E = mc^2$.
Display math with $$...$$:
$$
\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}
$$
KaTeX is bundled (no CDN call needed). It supports a large subset of LaTeX — see the KaTeX function list.
Performance
Both Mermaid and KaTeX render lazily — only when the block is visible in the viewport. A note with 100 diagrams stays responsive; only the on-screen ones cost render time.
Gotchas
Mermaid quirk with pipes: sequence diagrams treat
|specially. Escape with\|in node text.Dollar signs in regular text: if you write “$5” in prose, Lettuce won’t try to parse it as math (it requires balanced delimiters and adjacent non-space chars). But “$x = 5$” will render. Use a
\to escape:\$5.
Related
Core concepts/06 Callouts — for non-code visual emphasis
Publishing/02 The static site — Mermaid/KaTeX in published HTML