Skip to main content

SVG Lilypond

Given some lilypond music in stdin, output optimized svg resulting from that music.

Currently supports version 2.24.1 of lilypond (more recent version were not tested. Older versions don't work).

Installation

pip install svgly

or clone this repository and run pip install . or uv sync.

Make sure you have the necessary dependencies installed (see below).

How it works

  • Expect lilypond music as stdin
  • Transform it into one (or multiple; see --one-svg-per-measure) svg tag (<svg ...> ... </svg>)
  • Allow for other options:
    • CSS styling
    • lilypond \relative to note

$ svgly --help yields:

usage: svgly [-h] [-k KEY] [-t TIME_SIGNATURE] [-c CLEF] [-r RELATIVE] [-p PAPER] [-l LAYOUT]
             [--padding PADDING] [--one-svg-per-measure] [--id-list ID_LIST]
             [--html-attribute ATTR=VALUE] [--hide-all] [-v] [--min-svg-width MIN_SVG_WIDTH]
             [--staff-size STAFF_SIZE] [--ly-block LY_BLOCK] [--all-keys] [--random-ids] [--use-cache]
             music [music ...]

Convert lilypond music to svg

positional arguments:
  music                 Lilypond music expression

options:
  -h, --help            show this help message and exit
  -k, --key KEY         Key signature
  -t, --time-signature TIME_SIGNATURE
                        Time signature
  -c, --clef CLEF       Clef
  -r, --relative RELATIVE
                        Relative of music expression
  -p, --paper PAPER     Paper options
  -l, --layout LAYOUT   Layout options
  --padding PADDING     Add padding to generated svg
  --one-svg-per-measure
                        Output one svg per measure. Only the first will containclef, key and time
                        signature. Measures are split by the character "|".
  --id-list ID_LIST     List of ids already taken, to avoid id duplication
  --html-attribute ATTR=VALUE
                        Add html attribute to top level svg
  --hide-all            Hide clef, key and time signature
  -v, --verbose         Print output of subprocesses
  --min-svg-width MIN_SVG_WIDTH
                        The minimum width of an generated svg, in pixels, when using --one-svg-per-
                        measure. If this options is set, this script will effectively generate one svg
                        for every few measures. Defaults to 0.
  --staff-size STAFF_SIZE
                        Choose the size of the staff. Default is 20
  --ly-block LY_BLOCK   Add arbitrary lilypond boilerplate
  --all-keys            Generate svgs transposed for all keys
  --random-ids          Change ids to use unique identifiers
  --use-cache           Use cache for calculations

This code can also be used as a module by using from svgly import svgly, SVGLYOptions and calling (additional options are enabled when calling the function directly):

from svgly import svgly, SVGLYOptions

# class SVGLYOptions:
#     music: str
#     key: str = r"c \major"
#     time_signature: str = "4/4"
#     clef: str = "treble"
#     relative: str = "c''"
#     paper: str = ""
#     layout: str = ""
#     padding: float = 0.0
#     one_svg_per_measure: bool = False
#     id_list: set[str] = field(default_factory=set)
#     html_attributes: dict[str, str] = field(default_factory=dict)
#     hide_all: bool = False
#     verbose: bool = False
#     min_svg_width: float = 0.0
#     staff_size: float = 20.0
#     ly_block: str = ""
#     all_keys: bool = False
#     random_ids: bool = False
#     use_cache: bool = False
#     ly_log_file: TextIO | None = None
#     use_docker: bool = False

svgly(SVGLYOptions(...))

Using docker

When using lilypond with user-input data, it is important to isolate the it's execution environment. If use_docker is set, svgly will try to use the codello/lilypond docker image to compile the svgs. It expects docker to be installed, and expects to be able to sudo into it. To avoid needing root execution, add the following to any sudoers file (e.g. visudo /etc/sudoers.d/10-www-data-lilypond):

www-data ALL=(root:root) NOPASSWD:/usr/bin/docker ^run -v /tmp/tmp[a-z0-9_]+:/work codello/lilypond --svg -o tmp tmp\.ly$
www-data ALL=(root:root) NOPASSWD:/usr/bin/chown ^www-data:www-data( /tmp[a-z0-9_]+/tmp(-[0-9]+)?.svg)+$

This assumes you are running with the www-data user and that docker and chown are in the /usr/bin folder. Also needs sudo version >= 1.9.10 for regex support.

Optimizing resulting HTML

Svgly generates a lot of repeated and uncecessary svg objects. After building your html page with svgly, pass it through htmlo to reduce its size. Informal experiments showed that for a 7 bar long sheet, html reduces ~80% of it's size compared to regular svgly results.

From the command line, htmlo --help yields:

usage: htmlo [-h] [--wrap] [--random-ids] [--use-cache] input

Optimize SVGs in HTML

positional arguments:
  input         Input HTML content (use - for stdin)

options:
  -h, --help    show this help message and exit
  --wrap        Wrap the input in a div
  --random-ids  Use random IDs for paths (avoiding collisions for multiple optimizations in the same
                document)
  --use-cache   Use cached optimization

Typical usage:

svgly - < music.ly | htmlo - > music.html

Usage as library:

from htmlo import optimize

content = "<svg>...</svg>"

optimize(
  content,
  wrap=True,
  random_ids=True,
  use_cache=True
)

Why this

We use it to generate chords + lyrics + sheet music at Wikicifras.

Dependencies

  • python libs:
    • jinja2
    • svgpathtools
    • bs4
    • cachetools
    • shelved_cache
  • LilyPond
  • svgo

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

svgly-0.1.3.tar.gz (44.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

svgly-0.1.3-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

File details

Details for the file svgly-0.1.3.tar.gz.

File metadata

  • Download URL: svgly-0.1.3.tar.gz
  • Upload date:
  • Size: 44.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.15

File hashes

Hashes for svgly-0.1.3.tar.gz
Algorithm Hash digest
SHA256 15c6f753265fea655383c9702b6abd9584d4c8973a5676a47261cd84436de529
MD5 22bc693231c50ec5c8a6b3a8557a96c2
BLAKE2b-256 f2629cd0f5497f94248d93631c7c703bebeacd5f3c6c2c31e63462094be629f8

See more details on using hashes here.

File details

Details for the file svgly-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: svgly-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.15

File hashes

Hashes for svgly-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 fa3e9fdca13595cb49a7f848ce83c41e2c04a1755d88ddde8b9a0f6a87e1994c
MD5 31188b09366238bb460e63cecd7aab35
BLAKE2b-256 a3ecfaecbb0cac6e81d2ee7270fd5590175b40992085ef9e3df3cc2a785b1053

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

This release

0.1.3 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page