ANSI themes
Smalto renders syntax-highlighted text with ANSI terminal color codes. The AnsiTheme type lets you control which colors are applied to each token type.
Default theme
The default theme applies these colors:
| Token | Style |
|---|---|
| Keyword | Yellow |
| String | Green |
| Number | Green |
| Function | Blue |
| Comment | Gray italic |
| Module | Cyan |
| Type | Cyan |
| Operator | Magenta |
| Punctuation | Gray |
| Tag | Red |
| Builtin | Bright blue |
| Attribute | Yellow |
| Property | Yellow |
| Selector | Cyan |
| Regex | Green |
| Constant | Bright magenta |
| Variable | Bright yellow |
| Whitespace | No styling |
| Other | No styling |
| Custom | No styling (see below) |
The default theme also includes styles for markup tokens commonly produced by the Markdown grammar:
| Custom token | Style |
|---|---|
important |
Bold bright yellow |
bold |
Bold |
italic |
Italic |
strike |
Strikethrough |
code |
Green |
url |
Underline cyan |
Use smalto.to_ansi() to render with the default theme:
import smalto
import smalto/languages/python
let colored = smalto.to_ansi("print('hello')", python.grammar())
Custom themes
Build a custom theme with ansi_theme.new() and per-token setter functions:
import gleam_community/ansi
import smalto
import smalto/ansi_theme
import smalto/languages/python
let theme =
ansi_theme.new()
|> ansi_theme.keyword(ansi.bright_magenta)
|> ansi_theme.string(ansi.bright_green)
|> ansi_theme.number(ansi.bright_yellow)
|> ansi_theme.function(ansi.bright_cyan)
|> ansi_theme.comment(fn(v) { ansi.italic(ansi.bright_black(v)) })
|> ansi_theme.operator(ansi.red)
let colored = smalto.to_ansi_with("print('hello')", python.grammar(), theme)
Tokens without a setter in the theme are rendered as plain text.
Setter functions
Each setter takes the theme and a styling function fn(String) -> String:
| Setter | Token type |
|---|---|
ansi_theme.keyword(theme, style) |
Keywords |
ansi_theme.string(theme, style) |
String literals |
ansi_theme.number(theme, style) |
Numbers |
ansi_theme.comment(theme, style) |
Comments |
ansi_theme.function(theme, style) |
Function names |
ansi_theme.operator(theme, style) |
Operators |
ansi_theme.punctuation(theme, style) |
Punctuation |
ansi_theme.type_(theme, style) |
Type names |
ansi_theme.module(theme, style) |
Module names |
ansi_theme.variable(theme, style) |
Variables |
ansi_theme.constant(theme, style) |
Constants |
ansi_theme.builtin(theme, style) |
Built-in functions |
ansi_theme.tag(theme, style) |
HTML/XML tags |
ansi_theme.attribute(theme, style) |
Attributes |
ansi_theme.selector(theme, style) |
CSS selectors |
ansi_theme.property(theme, style) |
Properties |
ansi_theme.regex(theme, style) |
Regular expressions |
ansi_theme.whitespace(theme, style) |
Whitespace |
ansi_theme.other(theme, style) |
Unmatched text |
ansi_theme.custom(theme, name, style) |
Custom token by name |
Composing styles
The styling function is fn(String) -> String, so you can compose multiple ANSI effects:
import gleam_community/ansi
// Bold cyan
ansi_theme.keyword(theme, fn(v) { ansi.bold(ansi.cyan(v)) })
// Italic gray (like the default comment style)
ansi_theme.comment(theme, fn(v) { ansi.italic(ansi.gray(v)) })
// Underlined bright red
ansi_theme.tag(theme, fn(v) { ansi.underline(ansi.bright_red(v)) })
Extending the default theme
Start from the default and override specific tokens:
import gleam_community/ansi
import smalto/ansi_theme
let theme =
ansi_theme.default()
|> ansi_theme.keyword(ansi.bright_magenta)
|> ansi_theme.comment(fn(v) { ansi.italic(ansi.bright_black(v)) })
Custom token styles
Grammars may produce Custom tokens for language-specific categories. Style them with ansi_theme.custom():
import gleam_community/ansi
import smalto/ansi_theme
let theme =
ansi_theme.default()
|> ansi_theme.custom("decorator", ansi.bright_yellow)
|> ansi_theme.custom("annotation", ansi.bright_cyan)