swatch 🎨

Package VersionDownloadsHex DocsTestLicense

A CSS syntax highlighter for Gleam. Renders directly to HTML or ANSI-colored terminal output, or hands back a classified token stream for custom rendering.

Install

gleam add swatch@1

Quick start

import gleam/io
import swatch
pub fn main() {
let source =
"@media (min-width: 600px) {
.btn {
--brand: #f00;
color: var(--brand);
padding: 8px 12px;
}
.btn:hover {
color: rgb(255 0 0 / 0.8) !important;
}
}"
// ANSI colors for the terminal
swatch.to_ansi(source) |> io.println
// HTML with `<span>` wrappers per token kind
let html = swatch.to_html(source)
io.println("<pre><code>" <> html <> "</code></pre>")
// Raw tokens for custom rendering or analysis
let _tokens = swatch.to_tokens(source)
}

Further documentation can be found at https://hexdocs.pm/swatch.

HTML output

swatch.to_html wraps each token in a <span class="hl-…"> describing its kind. Whitespace passes through unwrapped. Content is HTML-escaped.

TokenClassTokenClass
Commenthl-commentStringhl-string
Selectorhl-selectorNumberhl-number
ClassSelectorhl-classUnithl-unit
IdSelectorhl-idHexColorhl-hex
PseudoSelectorhl-pseudoFunctionhl-function
AttributeNamehl-attributeKeywordhl-keyword
AttributeValuehl-attribute-valueImportanthl-important
AttributeFlaghl-attribute-flagOperatorhl-operator
AtRulehl-at-rulePunctuationhl-punctuation
Propertyhl-propertyOtherhl-other
Variablehl-variable

A starter stylesheet:

pre code .hl-comment { color: #6a737d; font-style: italic }
pre code .hl-selector,
pre code .hl-at-rule,
pre code .hl-operator,
pre code .hl-important { color: #d73a49 }
pre code .hl-important { font-weight: bold }
pre code .hl-class,
pre code .hl-id,
pre code .hl-pseudo,
pre code .hl-attribute,
pre code .hl-attribute-flag,
pre code .hl-function { color: #6f42c1 }
pre code .hl-string,
pre code .hl-attribute-value { color: #032f62 }
pre code .hl-property,
pre code .hl-number,
pre code .hl-unit,
pre code .hl-hex { color: #005cc5 }
pre code .hl-variable { color: #e36209 }
pre code .hl-keyword { color: #22863a }

If you already have a token list, swatch.tokens_to_html renders it without re-tokenizing.

ANSI output

swatch.to_ansi renders for the terminal using gleam_community_ansi.

ColorTokens
yellowselectors (element, class, id, pseudo, attribute, flag), keywords
cyanproperties, custom properties
greenstrings, numbers, units, hex colors, unquoted attribute values
bluefunction names
magentaat-rules, operators
bold red!important
italic graycomments
resetwhitespace, punctuation, fallback

Structural tokens use ansi.reset so an unclosed attribute from upstream text can't bleed into characters like { and }.

If you already have a token list, swatch.tokens_to_ansi renders it without re-tokenizing.

Tokens

swatch.to_tokens returns a list of swatch.Token. Every variant carries a single String, so concatenation reproduces the input.

The full list: Whitespace, Comment, Selector, ClassSelector, IdSelector, PseudoSelector, AttributeName, AttributeValue, AttributeFlag, AtRule, Property, Variable, String, Number, Unit, HexColor, Function, Keyword, Important, Operator, Punctuation, Other.

Tokens are round-trip safe; concatenating each token's string payload reproduces the original source byte-for-byte, including whitespace, comments, escapes, and formatting.

Malformed input (unmatched brackets, invalid escapes, trailing identifiers past the attribute-flag slot) surfaces as Other rather than being dropped, so round-trip holds even on broken CSS.

CSS coverage

Development

gleam build # Compile the project
gleam test # Run the tests

See CONTRIBUTING.md for the full workflow.

Inspired by contour and just.