Skip to content

bernsteining/scoryst

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

36 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

logo

Scoryst - Music Engraving Plugin for Typst

A Typst plugin to render music notation from multiple formats using Verovio, compiled to WASM.

Features

  • 8 input formats: ABC, MusicXML, MEI, Humdrum, EsAC, PAE, Volpiano, CMME
  • 5 SMuFL-compliant music fonts: Leipzig (default), Bravura, Gootville, Leland, Petaluma
  • Full Verovio options: scale, font, page layout, and all toolkit options
  • Multi-page support: render individual pages of long scores
  • Binary font loading: fonts pre-compiled to binary for instant init

Check the documentation for a full demonstration with examples.

Usage

Some formats are too verbose to write inline here, so only compact formats are written inline here.

#import "@preview/scoryst:0.1.2": score, pages

// ABC notation (auto-detected)
#score("X:1\nM:4/4\nK:C\nCDEF|GABc|")

// MusicXML (auto-detected)
#score(read("adagio.xml"))

// MEI (auto-detected)
#score(read("schubert.mei"))

// Humdrum (auto-detected)
#score(read("sample-humdrum.krn"))

// EsAC - Essen Associative Code (auto-detected)
#score(read("hildebrandslied.esac"))

// PAE - Plaine & Easie Code (requires explicit format)
#score("@clef:G-2\n@keysig:\n@timesig:4/4\n@data:''4CDEF/GABc", options: (input-from: "pae"))

// Volpiano (requires explicit format)
#score("1---g--h-ij---hgf--g--hg---k--lk--k7", options: (input-from: "volpiano"))

// CMME (requires explicit format)
#score(read("cmme.xml"), options: (input-from: "cmme"))

// Change font
#score(data, options: (font: "Petaluma"))

// Multi-page
#let data = read("adagio.xml")
#let n = pages(data)
#for p in range(1, n + 1) {
  score(data, page: p)
}

API

score(data, options: none, page: 1, ..args)

Renders music notation to an SVG image. data is a string in any supported format. ..args are forwarded to Typst's image() function (width, height, fit, alt).

pages(data, options: none)

Returns the number of pages for the given music data.

Verovio Options

Options are passed as a Typst dictionary and map directly to Verovio's toolkit options. Both kebab-case and camelCase keys are accepted (e.g. adjust-page-height or adjustPageHeight).

Option Default Description
adjust-page-height true Crop SVG height to content
adjust-page-width false Crop SVG width to content
scale 100 Scale factor (percent)
font "Leipzig" Music font: Leipzig, Bravura, Gootville, Leland, Petaluma
input-from "auto" Format: auto, mei, musicxml, abc, humdrum, esac, pae, volpiano, cmme
page-width 2100 Page width (MEI units)
page-height 2970 Page height (MEI units)
page-margin-top 50 Top margin
page-margin-bottom 50 Bottom margin
page-margin-left 50 Left margin
page-margin-right 50 Right margin
landscape false Landscape orientation
breaks "auto" Line breaks: auto, line, encoded, none
condense "auto" Condense: auto, none, encoded
transpose "" Transpose (e.g. "M2" for major second up)
header "auto" Header: auto, none, encoded
footer "auto" Footer: auto, none, encoded
spacing-staff 12 Spacing between staves
spacing-system 12 Spacing between systems
spacing-linear 0.25 Linear spacing factor
spacing-non-linear 0.6 Non-linear spacing factor
unit 9 Base unit size (half staff space)
stem-width 0.2 Stem width
bar-line-width 0.3 Bar line width
staff-line-width 0.15 Staff line width
lyric-size 4.5 Lyrics font size
hairpin-size 3.0 Hairpin height
svg-view-box false Use viewBox instead of width/height
svg-remove-xlink false Use href instead of xlink:href
svg-bounding-boxes false Add bounding box rects (debug)
remove-ids false Strip element IDs from SVG
smufl-text-font "embedded" SMuFL text font: embedded, linked, none

Building

Requires Emscripten and wasi-stub.

make submodule       # init verovio submodule + apply patches
make -j$(nproc) wasm # compile to WASM
make install         # install to ~/.local/share/typst/packages/

Docker build

make build    # submodule + docker image + compile + install

Regenerating binary fonts

Fonts are pre-converted from Verovio's XML glyph data to a compact binary format. To regenerate after updating the Verovio submodule:

python3 scripts/fonts_to_binary.py

Architecture

Verovio patches

The plugin applies minimal patches to the Verovio C++ source (scripts/verovio-typst.patch), applied automatically by make submodule:

  • Binary font loading: embed font data directly in the WASM binary, avoiding parsing ~2600 XML glyph files at init time
  • PAE support: rewrite the Plaine & Easie parser to avoid WASI syscalls incompatible with Typst's WASM environment
  • Text font: use Liberation Serif instead of Times, which Typst's SVG renderer can't resolve
  • Performance: std::bitset for attribute class lookups, unordered_map for glyph dedup and font tables
  • Slim build: strip unused data to reduce WASM size

Known limitations

  • DARMS unsupported: It worked but it looks like nobody uses this format so we dropped it.

License

LGPLv3 - Verovio's licensing