Skip to content

Commit f1b4446

Browse files
committed
Fix dark highlighting themes missing base text color
Dark syntax highlighting themes like zenburn and espresso define text-color at the top level of the theme JSON but omit "Normal" from text-styles. generateThemeCssClasses() only checked text-styles for the base span color, so no `code.sourceCode > span` rule was emitted for these themes. When layered over a light theme that does emit a span-level color (e.g., kate), the light theme's near-black text persists in dark mode, making unhighlighted tokens invisible. Add a fallback after the text-styles loop: if no base text color was generated (no "" key in tokenCssByAbbr), check the top-level text-color and emit the same CSS rules that Normal would have produced. Uses generateCssKeyValues() to stay consistent with the existing code path. Fixes #14099
1 parent d1c3de0 commit f1b4446

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/command/render/pandoc-html.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,30 @@ function generateThemeCssClasses(
565565
}
566566
});
567567

568+
// If no "Normal" style was found in text-styles, fall back to the
569+
// theme's top-level "text-color" for the base .sourceCode > span rule.
570+
// Several themes (zenburn, espresso, etc.) define text-color at the
571+
// top level but omit "Normal" from text-styles, which leaves the base
572+
// code color unset. When dark CSS is layered on light, the light
573+
// theme's near-black base color persists and makes code unreadable.
574+
if (!tokenCssByAbbr[""] && themeJson["text-color"]) {
575+
const cssValues = generateCssKeyValues({
576+
"text-color": themeJson["text-color"],
577+
});
578+
if (cssValues.length > 0) {
579+
toCSS("", "Normal", cssValues);
580+
[
581+
"pre > code.sourceCode > span",
582+
"code.sourceCode > span",
583+
"div.sourceCode,\ndiv.sourceCode pre.sourceCode",
584+
].forEach((selector) => {
585+
otherLines.push(`\n${selector} {`);
586+
otherLines.push(...cssValues);
587+
otherLines.push("}\n");
588+
});
589+
}
590+
}
591+
568592
// Sort tokenCssLines by abbr and flatten them
569593
// Ensure empty abbr ("") comes first by using a custom sort function
570594
const sortedTokenCssLines: string[] = [];

0 commit comments

Comments
 (0)