Compiler-assisted LilyPond to MusicXML conversion
Project description
ly-to-musicxml
Compiler-assisted conversion from LilyPond .ly files to MusicXML 4.0.
This project has been manually validated both from the local source tree and from an installed TestPyPI package.
Approach
This converter does not statically parse LilyPond source and it does not use PDF or optical music recognition.
It runs LilyPond itself in a no-print extraction mode, lets LilyPond resolve \include files and embedded Scheme, exports LilyPond's internal music tree to XML, then translates that compiler-resolved XML into MusicXML.
Normal conversion does not generate PDF output.
Installation
Install the project in editable mode:
pip install -e .
For packaging, testing, and documentation tasks, use a standard CPython install or a normal virtual environment. Avoid using LilyPond's bundled Python as your main project interpreter because it does not include normal packaging tooling such as pip, build, or twine.
You can also run it without installation:
$env:PYTHONPATH = (Resolve-Path .\src)
python -m ly_to_musicxml "input.ly" -o "output.musicxml"
Install from PyPI once published:
pip install ly-to-musicxml
This package depends on an external LilyPond installation at runtime. Installing with pip only installs the Python package and CLI; it does not install LilyPond itself.
Requirements
- Python 3.10 or newer
- A working LilyPond installation available either through
--lilypond-bin,LY_TO_MUSICXML_LILYPOND_BIN, or the default configured path
The converter executes LilyPond during every run, so a missing or incompatible LilyPond install is the most common setup problem.
Usage
ly-to-musicxml "input.ly" -o "output.musicxml"
If -o is omitted, the converter writes the first output file next to the input using the same stem and a .musicxml extension.
LilyPond Binary Selection
The converter looks for LilyPond in this order:
--lilypond-binLY_TO_MUSICXML_LILYPOND_BIN- The reference path from the project brief:
C:\Users\kkris\Documents\lilypond-2.26.0-mingw-x86_64\lilypond-2.26.0\bin\lilypond.exe
Example:
ly-to-musicxml "input.ly" -o "output.musicxml" --lilypond-bin "C:\path\to\lilypond.exe"
Or via environment variable:
$env:LY_TO_MUSICXML_LILYPOND_BIN = "C:\path\to\lilypond.exe"
ly-to-musicxml "input.ly" -o "output.musicxml"
Multi-Score Inputs
If the input produces multiple non-empty scores or books, the converter preserves them by writing multiple MusicXML files.
- The first non-empty score is written to the requested output path.
- Additional non-empty scores are written into a sibling directory named
stem.exports/using the patternbook-NN-score-NN.musicxml. - Empty scores are skipped with warnings.
If you rerun the converter for the same output path, it clears the previous stem.exports/ directory and any legacy stem.bookNN.scoreNN.musicxml files before writing fresh outputs.
Example output layout for a multi-score input:
Shostakovich-String-Quartet-8.musicxml
Shostakovich-String-Quartet-8.exports/
book-01-score-02.musicxml
book-02-score-01.musicxml
...
What Is Currently Mapped
The current translator maps these runtime LilyPond constructs to MusicXML:
- Parts and staves
- Notes, rests, chords, tuplets, and unfolded repeats
- Key signatures, time signatures, pickups, and barlines
- Ties, slurs, dynamics, text directions, tempo marks, and wedges
- Breath marks, ottava shifts, fermatas, and common articulation/bowing marks
Scheme Handling
If the source file contains embedded Scheme syntax, the converter emits a warning that the output reflects one compiler evaluation. This is intentional: the converter uses the actual LilyPond runtime result instead of guessing what the Scheme might do.
Troubleshooting
If the CLI reports that it cannot find LilyPond:
$env:LY_TO_MUSICXML_LILYPOND_BIN = "C:\path\to\lilypond.exe"
ly-to-musicxml "input.ly" -o "output.musicxml"
If a conversion writes multiple files unexpectedly, check for a sibling stem.exports/ directory next to the main output file. That directory contains additional non-empty scores extracted from the same LilyPond input.
If the output looks wrong in another notation program, first confirm you are opening the newly generated .musicxml file rather than an older export from a previous run.
If VS Code auto-selects LilyPond's bundled Python for this workspace, switch to a standard CPython interpreter or a normal venv before doing package builds, pip install, or twine upload. The bundled interpreter can run LilyPond internals but is not a good development environment for this project.
Test
Run the focused regression test with:
python -m unittest tests.test_converter
Manual smoke tests used during validation:
$env:PYTHONPATH = (Resolve-Path .\src)
python -m ly_to_musicxml --help
python -m ly_to_musicxml "Shostakovich-String-Quartet-8.ly" -o "local-manual-smoke.musicxml" --lilypond-bin "C:\Users\kkris\Documents\lilypond-2.26.0-mingw-x86_64\lilypond-2.26.0\bin\lilypond.exe"
TestPyPI smoke test after publishing:
py -3.13 -m venv .testpypi-venv
.\.testpypi-venv\Scripts\python.exe -m pip install --upgrade pip
.\.testpypi-venv\Scripts\python.exe -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple ly-to-musicxml
.\.testpypi-venv\Scripts\ly-to-musicxml.exe "Shostakovich-String-Quartet-8.ly" -o "testpypi-smoke.musicxml" --lilypond-bin "C:\Users\kkris\Documents\lilypond-2.26.0-mingw-x86_64\lilypond-2.26.0\bin\lilypond.exe"
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ly_to_musicxml-0.1.1.tar.gz.
File metadata
- Download URL: ly_to_musicxml-0.1.1.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ca3bc5286ad8e8cf130ccb9c7bb09d3147273aa9cf8da1f5bdf6a9f63311e4c
|
|
| MD5 |
4b3a864589eca4ad2a667d7f359a034c
|
|
| BLAKE2b-256 |
a4da05255e67cbc3db5fffc4a8f2d9f8a934296c1b7ae4191adee0cd4d5d5a4f
|
Provenance
The following attestation bundles were made for ly_to_musicxml-0.1.1.tar.gz:
Publisher:
publish.yml on xvb8/ly-to-musicxml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ly_to_musicxml-0.1.1.tar.gz -
Subject digest:
8ca3bc5286ad8e8cf130ccb9c7bb09d3147273aa9cf8da1f5bdf6a9f63311e4c - Sigstore transparency entry: 1427458435
- Sigstore integration time:
-
Permalink:
xvb8/ly-to-musicxml@d46e6c2cb519f801b68c1ad1c81f33d810be8893 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/xvb8
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d46e6c2cb519f801b68c1ad1c81f33d810be8893 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ly_to_musicxml-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ly_to_musicxml-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be14f4194e38f48d7f540615ee85a5a69ded84cb9df72713e7b74c67ab593417
|
|
| MD5 |
db5f99b9376c1c935ec5f7435f55cac6
|
|
| BLAKE2b-256 |
4f91bb9d8f2e75dbbe15e031ba82700563453d124a983ef0a202d8b947106a4b
|
Provenance
The following attestation bundles were made for ly_to_musicxml-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on xvb8/ly-to-musicxml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ly_to_musicxml-0.1.1-py3-none-any.whl -
Subject digest:
be14f4194e38f48d7f540615ee85a5a69ded84cb9df72713e7b74c67ab593417 - Sigstore transparency entry: 1427458821
- Sigstore integration time:
-
Permalink:
xvb8/ly-to-musicxml@d46e6c2cb519f801b68c1ad1c81f33d810be8893 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/xvb8
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d46e6c2cb519f801b68c1ad1c81f33d810be8893 -
Trigger Event:
release
-
Statement type: