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

Uploaded Python 3

File details

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

File metadata

  • Download URL: svgly-0.1.0.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.0.tar.gz
Algorithm Hash digest
SHA256 0ae6fc54ee7fcd904e3ee92203ab0c2e55c392f35796ad72937bc43f831fe1fe
MD5 f28a1bc2a7b1ec6afebadc67d184d3ae
BLAKE2b-256 9551674c3947394a754b368dca1a0f43fc17ea8af2abfaba515f4fb312298eba

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for svgly-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 033665c7c5e0715c0c6029605dd022f59c0c22beec93edaf5e1621110379701c
MD5 b6e9eb3fa4bd7d13c537eb2b7979b758
BLAKE2b-256 f808c701603659f460e9522d500dccd54cd0a4e89b1b4953936ff673676141f8

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

0.1.1

2 files

This release

0.1.0 This release

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