glimra
Zero runtime syntax highlighter for lustre/ssg
.
In Swedish,
glimra
describes the brilliant gleam or lustre that comes from a polished, reflective surface, capturing the essence of light shining off something smooth and glossy.
Platform support
glimra
uses NIFs to extract syntax highlighting events provided by the tree-sitter
and tree-sitter-highlight
crates. This allows glimra
to provide syntax highlighting for a wide range of languages with minimal effort.
Unfortunately, this also means that glimra
only works with the Erlang target. You can use the provided precompiled binaries for the supported platforms or compile the NIFs yourself with the Rust toolchain.
Currently, the following operating systems and architectures are supported:
OS | Architecture(s) |
---|---|
Linux | x86_64 |
macOS | aarch64, x86_64 |
Windows | x86_64 |
Installation
gleam add glimra
Usage
glimra
can be used to highlight source code snippets in a variety of languages. While the primary use case is to provide syntax highlighting for code snippets in the lustre/ssg
static site generator, it can also be used in a more standalone fashion:
import glimra
import glimra/theme
pub fn main() {
let syntax_highlighter =
glimra.new_syntax_highlighter() |> glimra.set_theme(theme.default_theme())
let source = "let greeting = \"Hello, Joe!\""
let language = "gleam"
let highlighted_snippet =
syntax_highlighter
|> glimra.syntax_highlight(source:, language:)
let css = syntax_highlighter |> glimra.to_css()
}
Usage with lustre/ssg
glimra
provides a set of utilities to make it easier to work with glimra
and lustre/ssg
.
Given a typical lustre/ssg
build.gleam
file with the following main()
function, you can generate and add the static stylesheet using the add_static_stylesheet
builder:
import glimra
import glimra/theme
pub fn main() {
let syntax_highlighter =
glimra.new_syntax_highlighter()
|> glimra.set_theme(theme.default_theme())
let build = ssg.new("./priv")
|> ssg.add_static_route("/", index.view())
|> ssg.add_static_route("/blog", blog.view(posts.all()))
// the `add_static_stylesheet` builder works with your existing `lustre/ssg` config
|> glimra.add_static_stylesheet(syntax_highlighter: syntax_highlighter)
|> ssg.build
}
You can also link to the generated static stylesheet in your header:
import glimra
fn head(title: String, description: String) {
html.head([], [
html.title([], title),
html.meta([attribute.attribute("charset", "utf-8")]),
html.meta([
attribute.attribute("name", "viewport"),
attribute.attribute("content", "width=device-width, initial-scale=1"),
]),
html.link([attribute.href("/style.css"), attribute.rel("stylesheet")]),
// `link_static_stylesheet` will use the same path as `add_static_stylesheet`
glimra.link_static_stylesheet(),
])
}
Finally, you can use the included codeblock_renderer
with your lustre/ssg/djot
render configuration:
pub fn parse(
from filepath: String,
// pass in the same `syntax_highlighter` you used to generate the stylesheet
syntax_highlighter syntax_highlighter: Config(HasTheme),
) -> String {
let renderer =
djot.Renderer(
..djot.default_renderer(),
// this will use `codeblock_renderer` to highlight code snippets
codeblock: glimra.codeblock_renderer(syntax_highlighter),
)
let content = {
use file <- result.try(
simplifile.read(filepath) |> result.replace_error(Nil),
)
djot.render(file, renderer)
}
case content {
Ok(content) -> content
Error(_) -> {
let error_message = "could not parse content from file: " <> filepath
panic as error_message
}
}
}
Configuration
glimra
can be configured to include line numbers, to keep or trim whitespace, and to use a custom theme. The following configuration options are available:
pub type Config(HasTheme) {
line_numbers: Bool,
trim_whitespace: Bool,
theme: theme.Theme,
}
These are set with the builder pattern:
let syntax_highlighter =
glimra.new_syntax_highlighter()
|> glimra.set_line_numbers(true)
|> glimra.set_trim_whitespace(true)
|> glimra.set_theme(theme.default_theme())
Note that the theme
is required for any CSS generation to work!
Further documentation can be found at https://hexdocs.pm/glimra.
Development
gleam test # run the tests