Skip to content

sonovice/tusk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

700 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tusk

Tusk

The Ultimate Score Konverter. A bidirectional music notation format converter in Rust.

License: MIT Language: Rust

Tusk converts between MusicXML, MEI, and LilyPond. Its internal model is based on MEI (Music Encoding Initiative) and extended where needed to cover concepts from other formats. Every conversion passes through this shared model, preserving as much musical information as possible across formats.

Formats

From \ To MusicXML MEI LilyPond Extensions
MusicXML .musicxml, .mxl
MEI .mei
LilyPond .ly

Output versions: MusicXML 4.1, MEI 6.0-dev, LilyPond 2.24. Older input versions are accepted but mileage may vary.

CLI

tusk convert <INPUT> <OUTPUT>

Formats are detected from file extensions, with content-based fallback for the input. Use --from / --to to override detection, and - for stdin/stdout.

$ tusk convert score.musicxml score.mei
score.musicxml (MusicXML) → score.mei (MEI)

$ tusk convert score.mei score.ly
score.mei (MEI) → score.ly (LilyPond)

$ tusk convert concert.mxl concert.mei
concert.mxl (MusicXML (.mxl)) → concert.mei (MEI)

# Pipe through stdin/stdout
$ cat score.mei | tusk convert - -t musicxml > score.musicxml

# List supported formats
$ tusk formats

Library

use tusk_musicxml::MusicXmlFormat;
use tusk_mei::MeiFormat;
use tusk_format::{Importer, Exporter};

let (base, ext) = MusicXmlFormat.import_from_str(&musicxml_string)?;
let mei_xml = MeiFormat.export_to_string(&base, &ext)?;

Building

Requires Rust (edition 2024). No other external dependencies.

git clone https://github.com/sonovice/tusk.git
cd tusk
cargo build --release

Binary ends up at target/release/tusk.

Tests

cargo test

Additional regression tests against upstream MEI and LilyPond test suites are available via git submodules. These are not needed for the standard test suite.

git submodule update --init                                       # all submodules
git submodule update --init tests/fixtures/mei/sample-encodings   # MEI only
git submodule update --init tests/fixtures/lilypond/lilypond-repo # LilyPond only

cargo test -- --ignored   # run regression tests

Project layout

crates/
├── core/
│   ├── model/          MEI data model, generated from RNG schema
│   └── format/         Format traits (Importer, Exporter, FormatRegistry)
├── formats/
│   ├── mei/            MEI parser, serializer, version migration
│   │   └── codegen/    RNG to Rust code generator
│   ├── musicxml/       MusicXML parser, serializer, MEI conversion
│   │   └── codegen/    XSD to Rust code generator
│   └── lilypond/       LilyPond lexer, parser, serializer, MEI conversion
└── bindings/
    └── cli/            Command-line interface

The MEI model is generated from the official RNG schema at build time. No manual codegen step required.

License

MIT

About

The Ultimate Score Konverter

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages