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).

How it works

  • Expect lilypond music as stdin
  • Transform it into an 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.1.tar.gz (44.7 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.1-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.1.tar.gz
Algorithm Hash digest
SHA256 25b5978b0ad452bf42b1b32c0a26ac7f79d436124f9c8ed5b87b850da28f8cfe
MD5 44fb4b016b6e26e29998203fad4a378d
BLAKE2b-256 b95f2e40387e90ee0a3121f7f602cb1b9acf56afc59b7e9d29828423d9b79b32

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8d52cd11bd04b7e6a9ecdab864b8c6526e79d940dfa977f4c8be3c9a4df5102d
MD5 0773f7dd8215597d89aa215e81b6368b
BLAKE2b-256 205e9d382f170f2f0e25615da754b441b505431f3c7d589afccfc5f2972b368f

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

This release

0.1.1 This release

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