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.2.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.2-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: svgly-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 899d575ed32e13cd482156663b27460d4c8de9d6614c54d7af1c71b8f0398e13
MD5 1f50f893b31ae336e4590a61f91464f6
BLAKE2b-256 213b79bced296a6e0072be85a862df09e5a66a4e071fc482fefecdedcaa4a9e2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1b3bad81e5b7db91477c1e1d1e1ea58b6caf7f4dbeb7ce2bdc5bcb7024bacc6a
MD5 a13d3224ea55e25f62bce29fbaee2e62
BLAKE2b-256 3acf42b2710ed00f6004969c5b1872086765a8183b0edfc8d58da7e7e93a1575

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

This release

0.1.2 This release

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