Autumn

Autumn logo

Syntax highlighter powered by Tree-sitter and Neovim themes.

https://autumnus.dev

Hex VersionHex DocsMIT

Features

Installation

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

Usage

Basic Usage (HTML Inline)

iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir")
~s|<pre class="athl" style="color: #abb2bf; background-color: #282c34;"><code class="language-elixir" translate="no" tabindex="0"><span class="line" data-line="1"><span style="color: #e5c07b;">Atom</span><span style="color: #56b6c2;">.</span><span style="color: #61afef;">to_string</span><span style="color: #c678dd;">(</span><span style="color: #e06c75;">:elixir</span><span style="color: #c678dd;">)</span>
</span></code></pre>|

See the HTML Linked and Terminal formatters below for more options.

Language Auto-detection

iex> Autumn.highlight!("#!/usr/bin/env bash\nID=1")
~s|<pre class="athl" style="color: #abb2bf; background-color: #282c34;"><code class="language-bash" translate="no" tabindex="0"><span class="line" data-line="1"><span style="color: #c678dd;">#!/usr/bin/env bash</span>
</span><span class="line" data-line="2"><span style="color: #d19a66;">ID</span><span style="color: #56b6c2;">=</span><span style="color: #d19a66;">1</span>
</span></code></pre>|

Themes

Themes are sourced from popular Neovim colorschemes.

Use Autumn.available_themes/0 to list all available themes. You can specify a theme by name directly in the :theme option, or use Autumn.Theme.get/1 to get a specific theme struct if you need to inspect or manipulate its styles.

# Using theme name
iex> Autumn.highlight!("setTimeout(fun, 5000);", language: "js", theme: "github_light")
~s|<pre class="athl" style="color: #1f2328; background-color: #ffffff;"><code class="language-javascript" translate="no" tabindex="0"><span class="line" data-line="1"><span style="color: #6639ba;">setTimeout</span><span style="color: #1f2328;">(</span><span style="color: #1f2328;">fun</span><span style="color: #1f2328;">,</span> <span style="color: #0550ae;">5000</span><span style="color: #1f2328;">)</span><span style="color: #1f2328;">;</span>
</span></code></pre>|

# Using theme struct
iex> theme = Autumn.Theme.get("github_light")
iex> Autumn.highlight!("setTimeout(fun, 5000);", language: "js", theme: theme)

Bring Your Own Theme

You can also load custom themes from JSON files or strings:

# Load from JSON file
{:ok, theme} = Autumn.Theme.from_file("/path/to/your/theme.json")
Autumn.highlight!("your code", theme: theme)

# Load from JSON string
theme_json = ~s({"name": "my_theme", "appearance": "dark", "highlights": {"comment": {"fg": "#808080"}}})
{:ok, theme} = Autumn.Theme.from_json(theme_json)
Autumn.highlight!("your code", theme: theme)

Incomplete or Malformed code

It's also capable of handling incomplete or malformed code, useful for streaming like in a ChatGPT interface:

iex> Autumn.highlight!("const header = document.getEl", language: "js")
~s|<pre class="athl" style="color: #abb2bf; background-color: #282c34;"><code class="language-javascript" translate="no" tabindex="0"><span class="line" data-line="1"><span style="color: #c678dd;">const</span> <span style="color: #abb2bf;">header</span> <span style="color: #abb2bf;">=</span> <span style="color: #e86671;">document</span><span style="color: #848b98;">.</span><span style="color: #56b6c2;">getEl</span>
</span></code></pre>|

Formatters

Autumn supports three output formatters:

Both HTML formatters wrap each line in a <span class="line"> element with a data-line attribute containing the line number, making it easy to add line numbers or implement line-based features in your application.

HTML Inline (Default)

Generates HTML with inline styles for each token:

iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: :html_inline)
# or with options
iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: {:html_inline, pre_class: "my-code", italic: true, include_highlights: true})

Options:

Line Highlighting

# Default: theme-based highlighting using cursorline from current theme
highlight_lines = %{
  lines: [2..4, 6]  # Mix integers and ranges for flexible line specification
  # style defaults to :theme, which uses the cursorline highlight from theme
}

# Or with explicit theme styling  
theme_highlight_lines = %{
  lines: [1..2],
  style: :theme  # uses cursorline highlight from theme
}

# Or with custom CSS styling
custom_highlight_lines = %{
  lines: [2..4, 6],  # Multiple lines: 2..4, Single line: 6
  style: "background-color: #fff3cd; border-left: 3px solid #ffc107;"
}

Autumn.highlight!(code, language: "elixir", formatter: {:html_inline, highlight_lines: highlight_lines})

Custom HTML Wrapper

# Wrap code with custom HTML elements
header = %{
  open_tag: "<div class=&#39;code-wrapper&#39; data-language=&#39;elixir&#39;>",
  close_tag: "</div>"
}

Autumn.highlight!(code, language: "elixir", formatter: {:html_inline, header: header})

HTML Linked

Generates HTML with CSS classes for styling:

iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: :html_linked)
# or with options
iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: {:html_linked, pre_class: "my-code"})

Options:

Line Highlighting with CSS Classes

# Highlight lines with a CSS class
highlight_lines = %{
  lines: [1..3, 7..8],
  class: "highlighted-line"
}

Autumn.highlight!(code, language: "elixir", formatter: {:html_linked, highlight_lines: highlight_lines})

You'll need to style the CSS class in your stylesheet:

.highlighted-line {
  background-color: #fff3cd;
  border-left: 3px solid #ffc107;
}

To use linked styles, you need to include one of the available CSS themes in your app.

For Phoenix apps, add this to your endpoint.ex:

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

Then add the stylesheet to your template:

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

Terminal

Generates ANSI escape codes for terminal output:

iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: :terminal)
# or with options
iex> Autumn.highlight!("Atom.to_string(:elixir)", language: "elixir", formatter: {:terminal, italic: true})

Options:

Samples

Visit https://autumnus.dev to check out some examples.

Acknowledgements