Skip to content

fix(themes): an imported theme's bold and italic colours reach the editor (#676) - #678

Merged
PathGao merged 1 commit into
masterfrom
fix/676-markdown-emphasis-token-colours
Aug 18, 2026
Merged

fix(themes): an imported theme's bold and italic colours reach the editor (#676)#678
PathGao merged 1 commit into
masterfrom
fix/676-markdown-emphasis-token-colours

Conversation

@PathGao

@PathGao PathGao commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

What this is

Addresses #676, asked by @Fallgrim, whose note-taking depends on telling bold and italic apart at a glance: they had tried several VS Code themes and found that headings took colour while **bold**, *italic* and `code` never did, and concluded the editor could not style them.

After this, importing a theme that defines markup.bold / markup.italic / markup.inline.raw / markup.underline.link colours those spans in the editor. Measured with a probe theme (markup.bold.markdown: #ff0000, markup.italic.markdown: #008000, neither carrying a fontStyle), reading computed style off the rendered token spans:

span before after
**bold text** mtk1 mtkb — default foreground, bold mtk4 mtkbrgb(255, 0, 0), bold
*italic text* mtk1 mtki — default foreground, italic mtk8 mtkirgb(0, 128, 0), italic

The weight and slant survive because a theme entry without a fontStyle produces a rule without one, which Monaco reads as FontStyle.NotSet and merges with acceptOverwrite — the base theme's strong: bold and emphasis: italic stay standing. Spelling it regular instead would have flattened text the theme was only asked to colour.

Mechanism

parseAndApplyVscodeTheme copied each tokenColors entry's scope straight into a Monaco rule's token. Monaco resolves those against a trie of the names its grammars emit, and basic-languages/markdown/markdown.js emits strong, emphasis, variable for inline code and string.link — never markup.bold. So the rules were parsed, inserted under a token nothing produces, and never matched. Nothing failed and nothing logged; the theme just arrived partly applied.

Headings, lists and table pipes were the exception because they tokenize as keyword, which is also a TextMate scope themes define — the coincidence that made this look like "themes can only colour headings".

Scope

Only the four scopes Monaco can receive are renamed. ~~strikethrough~~, ==highlight== and ++insert++ are absent from the tokenizer entirely — it never leaves linecontent for them — so no rename reaches them; the preview renders all three (comrak's strikethrough, highlight, insert extensions), and closing that gap means owning a fork of the monarch grammar. Worth its own issue, not this change.

The built-in app-theme-light / app-theme-dark still ship rules: [], so out of the box the editor colours markdown exactly as before — this only unblocks imported themes. Giving the built-ins their own emphasis colours would change the default look for every user and is a design decision, not a defect.

Also left alone: the reporter's second ask, a place to add custom CSS. That is a feature request and belongs in its own issue.

The scope-splitting is in because it is the same defect one layer up: an entry written "scope": "comment, markup.bold" became a single token containing a comma and coloured nothing at all. Splitting it activates rules those themes always intended, which is a visible change for themes that use that spelling — and the direction the issue asks for.

Tests

scripts/markdownTokenColours.test.ts, five behaviour tests against monacoTokenRules, which this change extracts from parseAndApplyVscodeTheme so the rule construction can be run without a DOM or a Monaco instance. Drop the alias push and keep the tests: four of the five go red. The fifth is the "unusable entry is dropped" case, which is about the pre-existing guard rather than the fix.

Verification

npm audit             0 vulnerabilities
npm run check         801 files, 0 errors, 0 warnings
npm test              927 pass, 0 fail
npm run test:vitest   41 files, 365 pass
cargo test            148 pass

The before/after table was measured in Chromium against the dev server, with window.__TAURI_INTERNALS__ stubbed so the frontend boots outside Tauri, applying the probe theme through parseAndApplyVscodeTheme directly. Not measured: the import-a-theme-file path itself, which goes through Tauri and is unchanged here, and how any specific published theme spells its scopes — the prefix match covers markup.bold and markup.bold.markdown, but a theme that colours emphasis under some other scope entirely still will not arrive.

…itor (#676)

A VS Code theme colours TextMate scopes; Monaco's markdown tokenizer
emits names of its own. `markup.bold` was handed to `defineTheme`
unchanged and matched nothing, so every emphasis rule an imported theme
ships has been inert. Headings and lists took colour only because they
tokenize as `keyword`, which themes define under that same name.

Rename the four scopes Monaco can actually receive — bold, italic,
inline code, link — keeping the original rule beside the alias, and
split scopes written as one comma-separated string, which were missing
for the same reason.
@PathGao
PathGao merged commit ed2a3d3 into master Aug 18, 2026
4 checks passed
@PathGao
PathGao deleted the fix/676-markdown-emphasis-token-colours branch August 18, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant