HighlightTheme

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 content

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Background color from the .hljs CSS rule. Unspecified if not present in theme.

Link copied to clipboard
Link copied to clipboard

Default text color from the .hljs CSS rule. Unspecified if not present in theme.

Link copied to clipboard

Display name for this theme. Used together with contentIdentity by equals and hashCode.

Functions

Link copied to clipboard
open operator override fun equals(other: Any?): Boolean

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.

Link copied to clipboard
open override fun hashCode(): Int
Link copied to clipboard
open override fun toString(): String