View Source Autumn (Autumn v0.2.4)

Autumn logo

Syntax highlighter for source code parsed with Tree-Sitter and styled with Helix Editor themes.

Hex Version Hex Docs MIT

Features

Installation

Add :autumn dependency:

def deps do
  [
    {:autumn, "~> 0.2"}
  ]
end

Usage

Autumn.highlight!("elixir", "Atom.to_string(:elixir)") |> IO.puts()
#=> <pre class="autumn-hl" style="background-color: #282C34; color: #ABB2BF;">
#=>   <code class="language-elixir" translate="no">
#=>     <span class="ahl-namespace" style="color: #61AFEF;">Atom</span><span class="ahl-operator" style="color: #C678DD;">.</span><span class="ahl-function" style="color: #61AFEF;">to_string</span><span class="ahl-punctuation ahl-bracket" style="color: #ABB2BF;">(</span><span class="ahl-string ahl-special ahl-symbol" style="color: #98C379;">:elixir</span><span class="ahl-punctuation ahl-bracket" style="color: #ABB2BF;">)</span>
#=>   </code>
#=> </pre>

Styles mode

There are 2 modes to syntax highlight source code, the default is embedding inline styles in each one of the generated tokens, and the other more effective is relying on CSS classes to style the tokens.

Inline

Inlining styles will look like:

<span class="ahl-operator" style="color: #C678DD;">Atom</span>

That mode is easy and works fine for simple cases but in pages with multiple code blocks you might want to use CSS instead.

Linked

First you need to disable inline styles by passing false to the :inline_style option:

Autumn.highlight!("elixir", "Atom.to_string(:elixir)", inline_style: false) |> IO.puts()
# rest ommited for brevity
# `style` is no longer generated
#=> <span class="ahl-operator">

And then you need to serve any of of the available CSS themes in your app.

If you're using Phoenix you can serve them from your app, just add the following Plug into your app's endpoint.ex file:

plug Plug.Static,
  at: "/themes",
  from: {:autumn, "priv/static/css/"},
  only: ["dracula.css"] # choose any theme you want

The style will be served at /themes/dracula.css. In your local environemnt that resolves to http://localhost:4000/themes/dracula.css so finally add to your template:

<link phx-track-static rel="stylesheet" href={~p"/themes/dracula.css"} />

You can also copy the content of that theme file into a <style> tag in your template or serve that file from a CDN.

Samples

Visit https://autumn-30n.pages.dev to see all available samples like the ones below:

Elixir source code in onedark themeElixir source code in github_light theme

Looking for help with your Elixir project?

DockYard logo

At DockYard we are ready to help you build your next Elixir project. We have a unique expertise in Elixir and Phoenix development that is unmatched and we love to write about Elixir.

Have a project in mind? Get in touch!

Acknowledgements

Summary

Types

A language name, filename, or extesion.

Types

lang_filename_ext()

@type lang_filename_ext() :: String.t() | nil

A language name, filename, or extesion.

Examples

- "elixir"
- "main.rb"
- ".rs"
- "php"

Functions

highlight(source_code, opts \\ [])

@spec highlight(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}

Highlights the source_code.

Options

  • :language (default: nil) - the language to use for highlighting. Besides a language name, you can also pass a filename or extension. Note that an invalid language or nil will fallback to rendering plain text (no colors) using the background and foreground colors defined by the current theme.
  • :theme (default: "onedark") - accepts any theme listed here. You should pass the filename without special chars and without extension, for example pass theme: "adwaita_dark" to use the Adwaita Dark theme or theme: "penumbra" to use the Penumbra+ theme.
  • :pre_class (default: nil) - the CSS class to inject into the wrapping parent <pre> tag. By default it renders a <pre> tag with the autumn-hl class which will be merged with the class passed into this option.
  • :inline_style (default: true) - see more info on the module doc.

Examples

Passing a language name:

iex> {:ok, hl} = Autumn.highlight("Atom.to_string(:elixir)", language: "elixir")
iex> IO.puts(hl)
#=> <pre class="autumn-hl" style="background-color: #282C34; color: #ABB2BF;"><code class="language-elixir" translate="no"><span class="ahl-namespace" style="color: #61AFEF;">Atom</span><span class="ahl-operator" style="color: #C678DD;">.</span><span class="ahl-function" style="color: #61AFEF;">to_string</span><span class="ahl-punctuation ahl-bracket" style="color: #ABB2BF;">(</span><span class="ahl-string ahl-special ahl-symbol" style="color: #98C379;">:elixir</span><span class="ahl-punctuation ahl-bracket" style="color: #ABB2BF;">)</span></code></pre>

Or more options with a file extension:

iex> {:ok, hl} = Autumn.highlight("Atom.to_string(:elixir)", language: ".ex", inline_style: false, pre_class: "my-app-code")
iex> IO.puts(hl)
#=> <pre class="autumn-hl my-app-code"><code class="language-elixir" translate="no"><span class="ahl-namespace">Atom</span><span class="ahl-operator">.</span><span class="ahl-function">to_string</span><span class="ahl-punctuation ahl-bracket">(</span><span class="ahl-string ahl-special ahl-symbol">:elixir</span><span class="ahl-punctuation ahl-bracket">)</span></code></pre>

And no language results in plain text:

iex> {:ok, hl} = Autumn.highlight("Atom.to_string(:elixir)")
iex> IO.puts(hl)
#=> <pre class="autumn-hl" style="background-color: #282C34; color: #ABB2BF;"><code class="language-plaintext" translate="no">Atom.to_string(:elixir)</code></pre>

highlight(lang_filename_ext, source_code, opts)

This function is deprecated. Use highlight/2 instead.

highlight!(source_code, opts \\ [])

@spec highlight!(
  String.t(),
  keyword()
) :: String.t()

Same as highlight/2 but raises in case of failure.

highlight!(lang_filename_ext, source_code, opts)

This function is deprecated. Use highlight!/2 instead.