Theming
A bundled stylesheet is embedded automatically. It covers standard tree-sitter and nvim-treesitter capture names and follows mdBook’s built-in colour schemes, so most books need no CSS of their own.
The embedded stylesheet sits in the mdbook-tsitter cascade layer, so any rule
in your own [output.html] additional-css overrides it, whatever its
specificity. Add a stylesheet only for what you want to change, such as custom
capture names or colours for a custom mdBook theme:
[output.html]
additional-css = ["theme/highlighting.css"]
Each capture gets the ts- prefix, dots become hyphens, and every prefix is
emitted so broad rules can cascade into more specific ones:
| capture | generated classes |
|---|---|
keyword | ts-keyword |
keyword.operator | ts-keyword ts-keyword-operator |
string.regexp | ts-string ts-string-regexp |
For example:
.ts-comment {
font-style: italic;
}
code[data-language="rust"] .ts-function-macro {
color: var(--ts-purple);
}
Each highlighted block carries its fence tag as data-language, so a
code[data-language="…"] selector scopes a rule to one language.
Theme directory
Like mdBook’s own theme files,
the highlighting stylesheet can be replaced from the book’s theme directory
(theme/, or [output.html] theme). A highlight_ts.css there is embedded
instead of the bundled stylesheet, as mdBook uses a highlight.css there
instead of its highlight.js theme. Start from the bundled one:
mdbook-tsitter css > theme/highlight_ts.css
Without a highlight_ts.css, a theme that only replaces mdBook’s highlight.js
stylesheets still colours tree-sitter blocks: the bundled stylesheet takes each
role’s colour from the matching highlight.js class (.hljs-keyword for
keywords, .hljs-string for strings, and so on). A replaced highlight.css
applies to the light, rust, and custom themes, tomorrow-night.css to coal and
navy, and ayu-highlight.css to ayu, as in mdBook.
Set default-css = false under [preprocessor.tsitter] to embed no
highlighting stylesheet at all.
There is no fixed capture list in the preprocessor. Capture names come directly
from each grammar’s queries; names beginning with _ are treated as internal
and left unstyled.
Example: a custom mdBook theme
This book adds Everforest to mdBook’s
theme picker; choose it from the brush icon in the menu bar. It is added with
mdBook’s theme overrides,
and mdBook sets the chosen theme’s name as a class on <html>, so everything
the theme defines is scoped to .everforest.
Template
theme/index.hbs is mdBook’s own template, written out with
mdbook init --theme, with one entry added to the theme list:
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-everforest">Everforest</button></li>
mdBook uses any file in theme/ named like one of its own in place of it.
Since this one replaces mdBook’s template, refresh it from
mdbook init --theme when upgrading mdBook.
Colours
theme/everforest.css
sets mdBook’s interface variables, the same ones the built-in themes set in
css/variables.css, and the highlighting colours: Everforest’s palette as the
hues, and every colour role mapped to the hue Everforest gives that kind of
syntax, so none of the bundled stylesheet’s choices remain:
.everforest {
/* Tree-sitter hues: Everforest's palette. */
--ts-red: #e67e80;
--ts-orange: #e69875;
--ts-yellow: #dbbc7f;
--ts-green: #a7c080;
--ts-cyan: #83c092;
--ts-blue: #7fbbb3;
--ts-purple: #d699b6;
--ts-gray: #859289;
/* Every colour role, as Everforest colours that kind of syntax. The
highlight.js rules below use them; tree-sitter captures are styled
individually at the end of this file. */
--ts-comment: var(--ts-gray);
--ts-keyword: var(--ts-red);
--ts-string: var(--ts-cyan);
--ts-escape: var(--ts-green);
--ts-number: var(--ts-purple);
--ts-function: var(--ts-green);
--ts-declaration: var(--ts-green);
--ts-type: var(--ts-yellow);
--ts-special: var(--ts-orange);
--ts-namespace: var(--ts-yellow);
--ts-attribute: var(--ts-purple);
--ts-heading: var(--ts-orange);
--ts-link: var(--ts-blue);
}
Beyond the roles, every tree-sitter capture is styled as Everforest’s Neovim
colour scheme highlights it: each @capture group’s colour, italic, bold, and
underline, such as italic comments, bold headings, and underlined URLs. The
same file styles highlight.js classes in the same roles, so blocks left to
mdBook match the tree-sitter ones.
Code editors
mdBook gives editable blocks its light editor theme for any theme it does not
know; a short theme/everforest.js switches them to the dark one.
The stylesheet and the script are registered in book.toml:
[output.html]
additional-css = ["theme/comparison.css", "theme/everforest.css"]
additional-js = ["theme/everforest.js"]