Highlight Theme
Represents a syntax highlighting theme backed by a Highlight.js CSS file.
The color map is lazily initialized and cached - CSS parsing happens at most once per theme. Background and text colors are derived from the already-parsed colorMap (the .hljs rule), avoiding double-parsing of the CSS file.
Built-in themes
The four built-in themes are precompiled at build time - they do not parse CSS at runtime and do not require a Context:
// Light themes
HighlightTheme.tomorrow()
HighlightTheme.atomOneLight()
// Dark themes
HighlightTheme.tomorrowNight()
HighlightTheme.atomOneDark()Custom theme from an asset file
Any Highlight.js CSS theme can be bundled in your app's assets/ folder and loaded at runtime. This is the recommended way to ship additional themes with your app.
// Place your .css file in src/main/assets/themes/github.css
val theme = HighlightTheme.fromAsset(
context = context,
assetPath = "themes/github.css",
name = "github",
)Note: fromAsset() is lazy - CSS parsing (and any ThemeNotFound error) occurs when the theme is first applied, not at factory-call time.
Custom theme from raw CSS
val theme = HighlightTheme.fromCss(
cssText = rawCssString,
name = "my-inline-theme",
)Custom theme from a precomputed color map
For maximum control - e.g. deriving colors from Material 3 dynamic color or any other source - you can supply the color map directly:
val colorMap: Map<String, SpanStyle> = mapOf(
"hljs" to SpanStyle(color = Color(0xFF24292E), background = Color(0xFFFFFFFF)),
"hljs-keyword" to SpanStyle(color = Color(0xFFD73A49), fontWeight = FontWeight.Bold),
"hljs-string" to SpanStyle(color = Color(0xFF032F62)),
// ... add more token types as needed
)
val theme = HighlightTheme.fromColorMap(
name = "my-dynamic-theme",
colorMap = colorMap,
backgroundColor = Color(0xFFFFFFFF),
defaultTextColor = Color(0xFF24292E),
)Any valid Highlight.js CSS theme works with fromAsset / fromCss. Community themes are at highlightjs/highlight.js/src/styles.
Theme identity
Two HighlightTheme instances are equal when they share the same name and the same content identity (derived from the CSS text, asset path, or color map used to create the theme). This means Compose APIs (remember, LaunchedEffect, key) correctly detect theme changes even when two themes share the same name but carry different color content.
val light = HighlightTheme.fromCss(lightCss, "custom")
val dark = HighlightTheme.fromCss(darkCss, "custom")
light == dark // false - same name but different CSS content
val a = HighlightTheme.fromCss(css, "custom")
val b = HighlightTheme.fromCss(css, "custom")
a == b // true - same name and same CSS contentProperties
Functions
Two themes are equal when they have the same name and the same content identity. This ensures that themes sharing a name but carrying different CSS or color-map content are treated as distinct, so Compose recomposition keys (remember, LaunchedEffect) correctly trigger a re-highlight when the theme content changes.