Sonx

Elixir library for parsing and formatting chord sheets. An Elixir rewrite of ChordSheetJS (v14).

Run in Livebook | Interactive demo

Supported formats

Input (parsers):

Format Atom Example
ChordPro:chord_pro{title: My Song}\n[Am]Hello
Chords over words :chords_over_wordsAm\nHello
Ultimate Guitar :ultimate_guitar[Verse]\nAm\nHello
Typst/conchord:typst[Am] Hello [G] world
LaTeX (songs package) :latex_songs\beginsong{Title}[by={Artist}]

Output (formatters):

Format Atom
Plain text :text
ChordPro :chord_pro
Chords over words :chords_over_words
Ultimate Guitar :ultimate_guitar
HTML (div-based) :html_div
HTML (table-based) :html_table
LaTeX (songs package) :latex_songs
Typst/conchord:typst

Installation

Add sonx to your list of dependencies in mix.exs:

def deps do
  [
    {:sonx, "~> 0.1"}
  ]
end

Quick start

Parse a ChordPro string, inspect metadata, and format as plain text:

{:ok, song} = Sonx.parse(:chord_pro, "{title: My Song}\n{key: C}\n[Am]Hello [G]world")

Sonx.title(song)
# => "My Song"

Sonx.get_chords(song)
# => ["Am", "G"]

Sonx.format(:text, song)
# => "My Song\n\nAm    G\nHello world"

Transposing and changing key

transposed = Sonx.transpose(song, 3)
Sonx.get_chords(transposed)
# => ["Cm", "A#"]

changed = Sonx.change_key(song, "G")
Sonx.get_chords(changed)
# => ["Em", "D"]

Switching accidentals

{:ok, song} = Sonx.parse(:chord_pro, "[C#]Hello")
flat = Sonx.use_accidental(song, :flat)
Sonx.get_chords(flat)
# => ["Db"]

HTML formatting with CSS

The HTML formatters provide default CSS via css_string/1:

alias Sonx.Formatter.HtmlDivFormatter

html = Sonx.format(:html_div, song)
css = HtmlDivFormatter.css_string()

"<style>#{css}</style>\n#{html}"

HtmlTableFormatter.css_string/1 works the same way.

Chord diagrams

The :chord_diagrams option enables guitar chord diagrams (opt-in, default false). Only supported by the :latex_songs and :typst formatters.

# LaTeX: inserts \gtab{Chord}{Frets} commands
Sonx.format(:latex_songs, song, chord_diagrams: true)

# Typst: adds sized-chordlib import and call
Sonx.format(:typst, song, chord_diagrams: true)

Serialization

Songs can be serialized to JSON and back:

json = Sonx.to_json(song)
{:ok, restored} = Sonx.from_json(json)

Architecture

Input String → Parser → %Song{} → Formatter → Output String

All parsers produce a Sonx.ChordSheet.Song struct (the intermediate representation). All formatters consume one. This makes it easy to mix and match any input format with any output format, and to apply transformations (transpose, key change) in between.

See the Sonx module documentation for the full API reference.

License

GPL-3.0-or-later. See LICENSE.md.