An imported theme colours the preview, not only the editor - #736
Merged
Conversation
…itor (#682) A VS Code theme file has two halves. `colors` painted the whole app, preview included; `tokenColors` — which is where `markup.bold`, `markup.heading` and the rest live — only ever reached Monaco. So an imported theme arrived on the editor and stopped at the splitter, and the reporter of #676 saw the colours they came for on one half of the window. The preview renders the same constructs the editor tokenizes, but as HTML with the markup gone: `**bold**` is a `<strong>`, `##` is an `<h2>`. So the colours reach it through CSS variables rather than through a token rule, and land on the construct's text, which is all that is left of it. Seven constructs, each with the value its rule already had as the fallback: a theme that names none of them, or a built-in theme with no `tokenColors` at all, renders the preview exactly as before. Verified: the suite, plus computed colours read out of a page built from `styles.css` — every construct takes the theme's colour under `data-theme="vscode"`, keeps its old one without it, and a fenced block stays with the `--hljs-*` rules rather than taking the inline-code colour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
An imported VS Code theme now colours the preview's headings, bold, italic,
inline code, links, strikethrough and blockquotes, the way it already coloured
them in the editor.
Fallgrim, who reported #676, tested 2.7.6 and said in
#682 (comment) that the
editor colouring arrived but "nothing has changed for the preview mode", and
that preview is where it matters more for them because they open existing files
there. This does not close #682 — that issue asks for arbitrary custom CSS,
which is a different and much larger question.
Mechanism
A VS Code theme file has two halves and only one of them reached the preview.
theme.colors—editor.background,editor.foreground,textLink.foreground,terminal.ansi*— is turned into--color-*and--hljs-*inparseAndApplyVscodeTheme, so the preview's background, body text, links andfenced-code highlighting have always followed an imported theme.
theme.tokenColors— which is wheremarkup.bold,markup.heading,markup.inline.rawand the rest live — went tomonacoTokenRulesanddefineThemeand nowhere else. #678, #684, #686 and #689 all worked on thatpath. So an imported theme arrived on the editor and stopped at the splitter,
and every construct the reporter came for kept
--color-fg-defaultin thepreview.
The preview renders the same constructs the editor tokenizes, but as HTML with
the markup gone:
**bold**is a<strong>,##is an<h2>. So the coloursreach it as CSS variables rather than as token rules, and they land on the
construct's text, which is all that is left of it.
importedThemeRulesalreadybuilt a kind-to-colour map to rewrite its base rules; that map is now a named
function the importer also reads, and seven of its kinds are written into the
same
:root[data-theme="vscode"]block the rest of the variables go into.Scope
Every rule keeps the value it already had as its
var()fallback, so a themenaming none of these kinds, and a built-in theme with no
tokenColorsat all,render the preview exactly as before. No setting: importing a theme is the
opt-in, the same way #684 gave the built-in themes their editor colours without
one.
Deliberately left alone:
different decision — VS Code's own markdown preview colours none of this, and
Obsidian ships
--h1-color,--bold-colorand--italic-colordefaulting tothe body colour for the user to fill in. If it is ever wanted, the variables
are now there and it is a value per theme block.
markandins.==highlight==and++insert++have nomarkup.*scope,so there is nothing in a theme file to read for them.
--hljs-*rules.--md-codeis scoped to:not(pre) > codeso a code block is not repainted with the inline-codecolour.
markup.*settings carryfontStyle, not a family, andfont-srcis'self'.Tests
Three in
scripts/markdownTokenColours.test.ts, beside the #676 ones:markdownKindColorsreturns a colour per construct, and drops a non-Markdownscope and a rule with only a
fontStyle.tokenColors—undefined,null,[], a non-array —yields an empty map, which is what leaves the built-in themes alone.
styles.csswith a fallback.The two halves are joined by a variable name and nothing else: no type or
import holds
--md-strongintheme.tsto--md-strongin the stylesheet,and renaming one silently drops the colour. The anchor is the variable name
and the comma after it, both of which are the contract rather than today's
spelling of a call site. Dropping either half of the change turns it red.
Verification
The colours themselves were read out of a browser rather than reasoned about:
a page built from
src/styles.csswith the:root[data-theme="vscode"]blockthe importer would write, then
getComputedStyle().colorfor each constructwith and without the attribute. Without it every element keeps today's value
(
#1f2328body,#656d76forh6and blockquote,#0969dalinks); with iteach takes its own colour and the fenced block stays on the body colour.
Not verified: a real import in the running app on Windows or Linux, and the
--md-*block travelling into an exported HTML file. The export copies thegenerated
<style>tag with the rest of the stylesheet, so it should follow,but I reasoned about that rather than exporting a document and opening it.