verovioxide 0.1.1

Safe Rust bindings to the Verovio music notation engraving library
docs.rs failed to build verovioxide-0.1.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: verovioxide-0.0.1

Verovioxide

Safe Rust bindings to the Verovio music notation engraving library

Features

  • Multi-format input: Load MusicXML, MEI, ABC, Humdrum, and Plaine & Easie notation
  • Multi-format output: Render to SVG, export to MEI/Humdrum/PAE, generate MIDI
  • Bundled fonts: Leipzig, Bravura, Gootville, Leland, and Petaluma (SMuFL-compliant)
  • Type-safe API: Builder pattern for options with serde serialization
  • Zero runtime dependencies: Verovio statically linked
  • Production ready: Comprehensive error handling and 95%+ test coverage

Installation

cargo add verovioxide

The first build compiles the Verovio C++ library from source, which takes several minutes. Subsequent builds use cached artifacts and are fast.

Faster Builds with Prebuilt Binaries

For faster initial builds, use the prebuilt feature which downloads a pre-compiled Verovio library:

cargo add verovioxide-sys --features prebuilt
cargo add verovioxide

Or in your Cargo.toml:

[dependencies]
verovioxide = "0.1"
verovioxide-sys = { version = "0.1", features = ["prebuilt"] }

Prebuilt binaries are available for:

  • macOS (x86_64, aarch64)
  • Linux (x86_64, aarch64)
  • Windows (x86_64 MSVC)

If prebuilt binaries aren't available for your platform, it automatically falls back to compiling from source.

Quick Start

use verovioxide::{Toolkit, Options, Result};

fn main() -> Result<()> {
    // Create a toolkit with bundled resources
    let mut toolkit = Toolkit::new()?;

    // Load notation (format auto-detected)
    toolkit.load_file(Path::new("score.musicxml"))?;

    // Configure rendering
    let options = Options::builder()
        .scale(100)
        .adjust_page_height(true)
        .build();
    toolkit.set_options(&options)?;

    // Render to SVG
    let svg = toolkit.render_to_svg(1)?;
    std::fs::write("score.svg", &svg)?;

    Ok(())
}

Rendering

Single Page

let svg = toolkit.render_to_svg(1)?;  // Page numbers are 1-based

All Pages

let pages = toolkit.render_all_pages()?;
for (i, svg) in pages.iter().enumerate() {
    std::fs::write(format!("page-{}.svg", i + 1), svg)?;
}

With XML Declaration

let svg = toolkit.render_to_svg_with_declaration(1)?;
// Includes: <?xml version="1.0" encoding="UTF-8"?>

Page Information

let count = toolkit.page_count();
println!("Document has {} pages", count);

Format Conversion

Verovioxide can convert between multiple music notation formats:

Export to MEI

// Load any supported format
toolkit.load_file(Path::new("score.musicxml"))?;

// Export as MEI
let mei = toolkit.get_mei()?;
std::fs::write("score.mei", &mei)?;

// With options
let mei = toolkit.get_mei_with_options(r#"{"removeIds": false}"#)?;

Export to Humdrum

let humdrum = toolkit.get_humdrum()?;
std::fs::write("score.krn", &humdrum)?;

Export to Plaine & Easie (PAE)

let pae = toolkit.render_to_pae()?;

Generate MIDI

let midi_base64 = toolkit.render_to_midi()?;

// Decode and save
use base64::{Engine, engine::general_purpose::STANDARD};
let midi_bytes = STANDARD.decode(&midi_base64)?;
std::fs::write("score.mid", &midi_bytes)?;

Timing Data

// Get timemap for audio synchronization
let timemap = toolkit.render_to_timemap()?;  // JSON array

// Get expansion map for repeat handling
let expansion_map = toolkit.render_to_expansion_map()?;

Querying Elements

Find Elements by Time

// Get elements sounding at a specific time (milliseconds)
let elements_json = toolkit.get_elements_at_time(5000)?;

Get Time for Element

// Get timing for a specific element
let time_ms = toolkit.get_time_for_element("note-0000001")?;

Find Page by Element

// Find which page contains an element
let page = toolkit.get_page_with_element("measure-0000001")?;

Get Element Attributes

// Get attributes of an element as JSON
let attrs = toolkit.get_element_attr("note-0000001")?;

Configuration

Options Builder

The Options builder provides type-safe configuration:

use verovioxide::{Options, BreakMode, HeaderMode, FooterMode};

let options = Options::builder()
    // Page dimensions (MEI units, 10 units = 1mm)
    .page_width(2100)      // A4 width
    .page_height(2970)     // A4 height
    .adjust_page_height(true)

    // Margins
    .page_margin(50)
    .page_margin_top(100)

    // Scale and spacing
    .scale(100)            // Percentage
    .spacing_staff(12)
    .spacing_system(6)

    // Font
    .font("Leipzig")       // or "Bravura", "Gootville", "Leland", "Petaluma"
    .lyric_size(0.8)

    // Layout
    .breaks(BreakMode::Auto)
    .header(HeaderMode::None)
    .footer(FooterMode::None)

    // SVG output
    .svg_view_box(true)
    .svg_remove_xlink(true)
    .svg_css("svg { background: white; }")

    // MIDI generation
    .midi_tempo(120.0)
    .midi_velocity(80)

    // Transposition
    .transpose("M2")       // Up a major second

    .build();

toolkit.set_options(&options)?;

Available Options

Category Options
Page page_width, page_height, adjust_page_height, page_margin, page_margin_top, page_margin_bottom, page_margin_left, page_margin_right
Scale/Spacing scale, spacing_staff, spacing_system, spacing_linear, spacing_non_linear, even_note_spacing, min_measure_width
Font font, lyric_size
Layout breaks, condense, condense_first_page, condense_tempo_pages, header, footer
SVG svg_xml_declaration, svg_bounding_boxes, svg_view_box, svg_remove_xlink, svg_css, svg_format_raw, svg_font_face_include
MIDI midi_tempo, midi_velocity
Input input_from, mdiv_x_path_query, expansion
Transposition transpose, transpose_selected_only, transpose_to_sounding_pitch

Option Modes

// Break modes
BreakMode::Auto     // Automatic page/system breaks
BreakMode::None     // No automatic breaks
BreakMode::Encoded  // Use breaks from input file
BreakMode::Line     // Break at each line
BreakMode::Smart    // Smart break placement

// Condense modes
CondenseMode::None
CondenseMode::Auto
CondenseMode::Encoded

// Header/Footer modes
HeaderMode::None | HeaderMode::Auto | HeaderMode::Encoded
FooterMode::None | FooterMode::Auto | FooterMode::Encoded | FooterMode::Always

JSON Serialization

Options can be serialized/deserialized:

let json = options.to_json()?;
let options = Options::from_json(&json)?;

Supported Input Formats

Format Extensions Description
MusicXML .musicxml, .xml, .mxl Standard music interchange format
MEI .mei Music Encoding Initiative XML
ABC .abc Text-based notation format
Humdrum .krn, .hmd Kern and other Humdrum formats
PAE Plaine & Easie Code (RISM)

Format detection is automatic based on file content.

Supported Output Formats

Format Method Description
SVG render_to_svg() Scalable vector graphics for display
MEI get_mei() Music Encoding Initiative XML
Humdrum get_humdrum() Humdrum/Kern format
PAE render_to_pae() Plaine & Easie Code
MIDI render_to_midi() Base64-encoded MIDI for playback
Timemap render_to_timemap() JSON timing data for synchronization
Expansion Map render_to_expansion_map() JSON expansion/repeat data

Feature Flags

verovioxide

Feature Default Description
bundled-data Yes Include bundled SMuFL fonts and resources
font-leipzig Yes Leipzig SMuFL font (default font)
font-bravura No Bravura SMuFL font
font-gootville No Gootville SMuFL font
font-leland No Leland SMuFL font
font-petaluma No Petaluma SMuFL font
all-fonts No Enable all fonts

Note: Bravura baseline data is always included as it is required for Verovio's glyph name table.

verovioxide-sys

Feature Default Description
bundled Yes Compile Verovio C++ library from source
prebuilt No Download pre-built library from GitHub releases (faster)
force-rebuild No Force fresh compilation, bypassing cache

The prebuilt and bundled features can be used together - if prebuilt download fails, it falls back to compilation.

Enable Additional Fonts

[dependencies]
verovioxide = { version = "0.1", features = ["font-bravura", "font-leland"] }

Custom Resource Path

To use your own Verovio resources instead of bundled data:

[dependencies]
verovioxide = { version = "0.1", default-features = false }
let toolkit = Toolkit::with_resource_path(Path::new("/path/to/verovio/data"))?;

Building from Source

Clone with submodules:

git clone --recursive https://github.com/oxur/verovioxide.git
cd verovioxide

Build and test:

cargo build
cargo test

Build Caching

The Verovio C++ library is compiled once and cached at target/verovio-cache/. Subsequent builds link to the cached library and complete in seconds.

To force a fresh recompilation:

cargo build --features force-rebuild

Corporate/Restricted Networks

If your network blocks GitHub downloads, you can provide a local Verovio source:

VEROVIO_SOURCE_DIR=/path/to/verovio cargo build

Examples

Render MusicXML to SVG

cargo run --example render_musicxml -- \
  test-fixtures/musicxml/simple.musicxml \
  simple.svg

Render ABC Notation

cargo run --example render_abc

Render All Pages

mkdir output-dir
cargo run --example render_all_pages -- \
  "examples/Goldberg-Variationen-1-and-2.musicxml" \
  output-dir/
Creating Verovio toolkit with bundled resources...
Verovio version: 5.7.0
Setting page dimensions: width=2100, height=2970 (A4-like)
Loading file: examples/Goldberg-Variationen-1-and-2.musicxml (format auto-detected)
[Warning] MusicXML import: Dangling ending tag skipped
Document loaded successfully. Total pages: 3
Rendering 3 pages...
  Page 1/3: output-dir/-001.svg (380226 bytes)
  Page 2/3: output-dir/-002.svg (424047 bytes)
  Page 3/3: output-dir/-003.svg (121350 bytes)
Done! Rendered 3 pages.

Crate Structure

Crate Description
verovioxide High-level safe Rust API
verovioxide-sys Low-level FFI bindings to Verovio C API
verovioxide-data Bundled SMuFL fonts and resources

Technical Notes

Thread Safety

Toolkit implements Send but not Sync. You can move a toolkit between threads, but cannot share references across threads. For concurrent rendering, create separate toolkit instances.

Verovio Version

This release uses Verovio 5.7.0.

Logging

// Enable logging to stderr
Toolkit::enable_log(true);

// Or capture to buffer
Toolkit::enable_log_to_buffer(true);
// ... operations ...
let log = toolkit.get_log();

License

This project is licensed under the Apache License 2.0.

Dependencies:

  • Verovio is licensed under the LGPL-3.0
  • SMuFL fonts have their own licenses (see the respective font directories)