Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuring languages

Everything lives under [preprocessor.tsitter]. New options arrive in minor releases: the public Config and LanguageConfig structs are #[non_exhaustive], so adding one never breaks code that uses them.

Preprocessor options

keydefaultmeaning
injecttrueHighlight embedded languages using configured injection queries. Only configured languages are used. Set this to false to disable injections globally.
everforestfalseInclude the Everforest dark theme, its theme-picker entry, and complete tree-sitter and highlight.js styles on every chapter.
default-csstrueEmbed the highlighting stylesheet (the theme directory’s highlight_ts.css, or the bundled one) in chapters with highlighted blocks. See Theming.

Language options

Add one entry to [preprocessor.tsitter.languages] per grammar. A language from the built-in list needs no keys at all; any other grammar needs git as its source. Paths are relative to the book root.

keyrequiredmeaning
gitfor unlisted languagesURL of the grammar’s git repository, or a path to a local one, fetched and compiled on demand. Defaults to the built-in list’s repository.
revnoTag, branch, or commit to use. Defaults to the built-in list’s pinned revision, or for other repositories their default branch.
locationnoSubdirectory holding the grammar, for repositories with several grammars. Usually found automatically.
highlightsnoPath to a highlights query, used instead of the grammar’s.
injectionsnoPath to an injections query for embedded languages, used instead of the grammar’s.
localsnoPath to a locals query for scope-aware highlighting, used instead of the grammar’s.
aliasesnoCode-fence names handled by this grammar; defaults to the entry’s name.
lspnofalse by default. Set true to read § as a token marker in every block of the language, not only those marked lsp; see Hand-marked tokens.

A language may need its own table when it carries several keys:

[preprocessor.tsitter.languages.markdown]
aliases = ["md", "markdown"]
injections = "queries/markdown/injections.scm"

Injection queries can select another configured grammar using standard @injection.language and @injection.content captures. All grammars share the same capture-class table during a build, so embedded and host languages use the same theme consistently.

Rust Playground and hidden lines

Highlighted blocks keep mdBook’s code-block features. Rust blocks stay runnable in the Rust Playground, with the book’s [rust] edition, the implicit fn main wrapper, and annotations such as ignore, noplayground, mdbook-runnable, or edition2021 handled as mdBook handles them. Hidden lines (# in Rust, or a prefix from hidelines= or [output.html.code.hidelines]) are collapsed behind mdBook’s toggle:

```rust
# use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("tree-sitter", 1);
```

Editable playgrounds (editable with [output.html.playground] editable = true) are replaced by mdBook’s in-page editor, so they are always left to mdBook.

Leaving a block to mdBook

Processing a block replaces its Markdown with highlighted HTML. Add the notreesitter annotation when a block should keep mdBook’s highlight.js highlighting instead:

```rust,notreesitter
let highlighted = "by mdBook";
```

Side-by-side blocks

Blocks labelled with pane="…" are shown side by side, and compare shows one block as tree-sitter and highlight.js highlight it. See Side-by-side blocks.

Hand-marked tokens

§token|text§ in a block marked lsp styles text as an LSP semantic token. See Hand-marked tokens.

Alongside other preprocessors

mdBook runs preprocessors in the order set by their before and after keys, and otherwise alphabetically by name. A highlighted block becomes HTML, so a preprocessor that generates code blocks, or that must see a block as a code fence, has to run before this one:

[preprocessor.tsitter]
after = ["links", "my-code-generator"]

Blocks are found with mdBook’s own Markdown settings, so a block is highlighted exactly when mdBook would render it as a code block. In highlighted code, $ and \ are written as HTML entities, so math preprocessors such as mdbook-katex leave the code alone whichever of the two runs first.