swatch 🎨

Package Version Downloads Hex Docs Test License

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.

Search Document