Customize Theme Styles
Keep fenced code upright, preserve Markdown emphasis, and change a theme's background with map_styles.
Some themes make Markdown's markup.raw.block scope italic, so a whole fenced
code block inherits that style. Transform the theme before rendering to remove
italics from code fences while keeping emphasis elsewhere.
These examples also change the block background. They preserve every other
style field and include language-specific scopes such as
markup.raw.block.markdown.
Build a customized stylesheet
import githubLight from '@lumis-sh/themes/github_light';
import { buildCss } from '@lumis-sh/themes';
import { mapStyles } from '@lumis-sh/lumis/themes';
const theme = mapStyles(githubLight, (scope, style) => {
if (
scope === 'markup.raw.block' ||
scope.startsWith('markup.raw.block.')
) {
return { ...style, italic: false };
}
if (scope === 'normal') {
return { ...style, bg: '#fafafa' };
}
return style;
});
const css = buildCss(theme);Save css as your stylesheet and load it alongside
linked HTML. Use this stylesheet instead
of the prebuilt github_light.css; changing a theme object does not change the
bundled CSS file.
Use the same theme for inline HTML
Inline HTML respects the theme's styles, including italics. These examples highlight Markdown source, not convert Markdown into a rendered document.
import { highlight } from '@lumis-sh/lumis';
import { htmlInline } from '@lumis-sh/lumis/formatters';
import markdown from '@lumis-sh/wasm-markdown';
const html = await highlight(
'*Emphasis*\n\n```javascript\nconst answer = 42;\n```\n',
htmlInline({ language: markdown, theme }),
);Install @lumis-sh/wasm-javascript as well to highlight the fenced block's
contents. In a browser, load injected languages
before highlighting.
The same theme works in terminal output and custom formatters. For multi-theme HTML, transform each theme before passing it to the formatter.
Remove italics everywhere
To remove all italic styles rather than only code-fence italics, replace the
callback with one that clears italic on every entry:
const upright = mapStyles(theme, (_scope, style) => ({ ...style, italic: false }));Mapping visits existing styles only and replaces each style with the callback's result. It does not add scopes or reset inherited CSS: clearing a code-fence style does not remove independently italic comments inside that fence, or an italic style applied by your page. See the theme transformation contract for ownership and fallback behavior.
Use a customized theme in the CLI
The CLI loads a theme from a JSON file. Customize the theme with map styles in
any runtime, save the result as JSON, and pass the file to --theme:
import { writeFileSync } from 'node:fs';
import frappe from '@lumis-sh/themes/catppuccin_frappe';
import { mapStyles } from '@lumis-sh/lumis/themes';
const upright = mapStyles(frappe, (_scope, style) => ({ ...style, italic: false }));
writeFileSync('catppuccin_frappe_upright.json', JSON.stringify(upright));lumis highlight main.rs -f html-inline --theme ./catppuccin_frappe_upright.jsonSee Local custom themes for every CLI command that accepts a theme file.