Spaces:
Running
Running
Fallback generated previews without ties
Browse files- apps/theme_lab/app.py +26 -1
apps/theme_lab/app.py
CHANGED
|
@@ -13,6 +13,7 @@ import threading
|
|
| 13 |
import uuid
|
| 14 |
from pathlib import Path
|
| 15 |
from typing import Literal
|
|
|
|
| 16 |
|
| 17 |
from fastapi import FastAPI, HTTPException, Query
|
| 18 |
from fastapi.responses import FileResponse
|
|
@@ -382,11 +383,32 @@ def has_python_verovio_renderer() -> bool:
|
|
| 382 |
return True
|
| 383 |
|
| 384 |
|
| 385 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
try:
|
| 387 |
import verovio
|
| 388 |
|
| 389 |
musicxml_data = musicxml_path.read_text(encoding="utf-8")
|
|
|
|
|
|
|
| 390 |
toolkit = verovio.toolkit()
|
| 391 |
toolkit.setOptions({"scale": 42})
|
| 392 |
svg = toolkit.renderData(musicxml_data, {}) if hasattr(toolkit, "renderData") else ""
|
|
@@ -406,6 +428,9 @@ def render_musicxml_with_python_verovio(musicxml_path: Path, svg_path: Path) ->
|
|
| 406 |
def render_musicxml_to_svg(musicxml_path: Path) -> Path | None:
|
| 407 |
svg_path = musicxml_path.with_suffix(".svg")
|
| 408 |
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path)
|
|
|
|
|
|
|
|
|
|
| 409 |
if python_svg is not None:
|
| 410 |
return python_svg
|
| 411 |
verovio = shutil.which("verovio")
|
|
|
|
| 13 |
import uuid
|
| 14 |
from pathlib import Path
|
| 15 |
from typing import Literal
|
| 16 |
+
from xml.etree import ElementTree as ET
|
| 17 |
|
| 18 |
from fastapi import FastAPI, HTTPException, Query
|
| 19 |
from fastapi.responses import FileResponse
|
|
|
|
| 383 |
return True
|
| 384 |
|
| 385 |
|
| 386 |
+
def musicxml_without_ties(musicxml_data: str) -> str | None:
|
| 387 |
+
try:
|
| 388 |
+
root = ET.fromstring(musicxml_data)
|
| 389 |
+
except ET.ParseError:
|
| 390 |
+
return None
|
| 391 |
+
for note in root.findall(".//note"):
|
| 392 |
+
for tie in list(note.findall("tie")):
|
| 393 |
+
note.remove(tie)
|
| 394 |
+
notations = note.find("notations")
|
| 395 |
+
if notations is None:
|
| 396 |
+
continue
|
| 397 |
+
for tied in list(notations.findall("tied")):
|
| 398 |
+
notations.remove(tied)
|
| 399 |
+
if len(notations) == 0:
|
| 400 |
+
note.remove(notations)
|
| 401 |
+
ET.indent(root)
|
| 402 |
+
return ET.tostring(root, encoding="unicode", short_empty_elements=True)
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
def render_musicxml_with_python_verovio(musicxml_path: Path, svg_path: Path, *, strip_ties: bool = False) -> Path | None:
|
| 406 |
try:
|
| 407 |
import verovio
|
| 408 |
|
| 409 |
musicxml_data = musicxml_path.read_text(encoding="utf-8")
|
| 410 |
+
if strip_ties:
|
| 411 |
+
musicxml_data = musicxml_without_ties(musicxml_data) or musicxml_data
|
| 412 |
toolkit = verovio.toolkit()
|
| 413 |
toolkit.setOptions({"scale": 42})
|
| 414 |
svg = toolkit.renderData(musicxml_data, {}) if hasattr(toolkit, "renderData") else ""
|
|
|
|
| 428 |
def render_musicxml_to_svg(musicxml_path: Path) -> Path | None:
|
| 429 |
svg_path = musicxml_path.with_suffix(".svg")
|
| 430 |
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path)
|
| 431 |
+
if python_svg is not None:
|
| 432 |
+
return python_svg
|
| 433 |
+
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path, strip_ties=True)
|
| 434 |
if python_svg is not None:
|
| 435 |
return python_svg
|
| 436 |
verovio = shutil.which("verovio")
|