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]
             [--random-ids-length RANDOM_IDS_LENGTH] [--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)
  --random-ids-length RANDOM_IDS_LENGTH
                        If using random IDs, use this length for the
                        random IDs. Defaults to 4
  --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.4.tar.gz (45.0 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.4-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.4.tar.gz
Algorithm Hash digest
SHA256 23c31f82ca3672f7cbbe12d98af344a3b92e993bfae865b62024880161c25a77
MD5 b231265576136dbee21f7c8fb832026e
BLAKE2b-256 2a239c6fe1c5db9e1388da10ab9ea502e68a66d9d9e0ef89ce7f9aa9eb705a3a

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 c34965f18f212df1a5e92bf6dd48a656d50e99a2984310c9cf482b2bd3ebf12e
MD5 42d19228ce64b322eac12ce67cd23be9
BLAKE2b-256 cb0ea33f8092fd57eb843a4b3af1fb899458d06a5c8da9d85060da140b221e92

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 files

0.1.3

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