Template-instance rendering — valkuilen¶
Doel: checklist voor agents die verder werken aan vsa-templates → MSCZ/MXL/PDF. Geen projectgeschiedenis; alleen probleem → oorzaak → regel.
Lees dit vóór je scripts/render_vsa_template_musicxml.py,
src/vsa/template_instance.py of corpus-PDF’s wijzigt.
Gerelateerd: mapping-vsa.md, open-points.md,
collapse_recite_for_print() in scripts/render_vsa_template_musicxml.py.
Twee exportkanalen¶
| Kanaal | Doel | Recite-printmodel |
|---|---|---|
| MSCZ (MuseScore / PDF) | leespartituur | collapse: \|\|O\|\| + slotlettergreep als kwart |
| MXL (Coria e.d.) | playback / solo per stem | geen collapse — elke syllabe een noot |
Regel: wijzigingen aan collapse_recite_for_print raken alleen MSCZ/print.
Coria-export via render_instance_musicxml houdt per-syllabe-noten.
Recite-collapse (print)¶
| Probleem | Oorzaak | Regel |
|---|---|---|
{moe__}, {Ni__}, {/en} verdwijnen in de breve |
Heuristieken: “zelfde toonhoogte”, “woord loopt door”, leading absorb | Collapse alleen aaneengesloten role=recite (ongemarkeerde VSA-syllaben). Elke VSA-scope blijft een eigen noot met VSA-duur — nooit breve, nooit opslokken. |
Te korte recite (Als de) op \|\|O\|\| |
Collapse bij 1–2 syllaben | Alleen bij ≥ 3 recite-syllaben (RECITE_COLLAPSE_MIN_SYLLABLES). Anders aparte kwarten. |
| Onduidelijk wat onder de breve hoort | Te veel speciale gevallen | Simpel: eerste body-lettergreep gecentreerd op de \|\|O\|\|; overige body-lettergrepen elk op een onzichtbare spacer-noot (naar rechts); laatste recite-syllabe = kwart; daarna template/cadens ongewijzigd. |
Punt achter de \|\|O\|\| (gestippelde whole/breve) |
Duur opgeblazen met dots=1 voor tekstbreedte |
Recite-printnoot: altijd half + headType breve + noStem, dots=0. Nooit dotted whole/longa als “ \|\|O\|\| ”. |
| Lege systemen / “rij rusten” | Maatduur opgeblazen (longa, 22/4) zodat MuseScore rare layout maakt |
Tekstruimte via onzichtbare spacer-noten (één per body-lettergreep) ná de \|\|O\|\|, niet via langere notehead-duur of één joined lyric + ticks. |
| Grote gap tussen einde recitaltekst en cadens-lettergreep | Eén joined lyric + te veel spacer-rusten | Rest-ruimte verdeelt MuseScore over de spacer-noten tussen de lettergrepen. |
| Melisma-extender onder recite-tekst | lyric_ticks op de \|\|O\|\| |
Geen extender op de recite-printnoot; ticks/slur alleen op echte VSA-melisma’s. |
Canonieke voorbeelden (T4-11):
{/en} het voor-beeld der zacht{moe__}dig{\heid_}→en|het(gecentreerd op\|\|O\|\|) |voor-beeldder(spacers) |zacht|moe(heel) |dig|heid{/Va}der … pries-ter {Ni__}ko{\laas_}→Va|der … pries-(eerste op\|\|O\|\|, rest spacers) |ter|Ni(heel) |ko|laas
MuseScore 4 (MSCZ)¶
| Probleem | Oorzaak | Regel |
|---|---|---|
| Binnen-strofe-maatstrepen blijven zichtbaar | Measure/endBarLineVisible wordt genegeerd |
Maatstreep-zichtbaarheid alleen via <BarLine><subtype>…</subtype><visible>0</visible></BarLine> in de voice. Roundtrip verifiëren. |
| Layout-splits midden in strofe vs “één maat” | split_events_for_layout voor instance |
Instance: één maat per strofe, geen binnen-strofe-knip. Coria idem. |
Recite-lyrics blijven gecentreerd ondanks <align>left |
MS 4.7: horizontale plaatsing = position, niet (alleen) align |
Eerste recite-lettergreep: geen position=left (default = gecentreerd op de nootkop). Overige body-lettergrepen op spacer-noten. align alleen = tekstinterne uitlijning. |
| Maatsoort-getallen zichtbaar | TimeSig in maat nodig voor len, maar stijl toont ze |
TimeSig mag in de maat; staff: showTimeSig=0, style: genCourtesyTimesig=0. |
| Stokken systematisch S/T omhoog, A/B omlaag | Twee stemmen per balk | Canoniek voor MSCZ: voice 1 + <stem>up</stem> (S/T), voice 2 + <stem>down</stem> (A/B), met <backup/>. |
| “Invisible” rusten of style verdwijnen na opslaan | MuseScore herschrijft bij save | Niet steunen op roundtrip-behoud van Style; opnieuw genereren vanuit script is bron van waarheid. |
| “Corrupt score” / ongelijke stemmen na melisma-collapse | MusicXML type=breve of gestipte som (half+dot, duration≠type) |
Partituur: zelfde-hoogte melisma alleen mergen naar ongestipte ≤ whole; maat-len gelijk over staves. Zie checklist S13 / leesbaarheid R7 (mvsa) en headType breve ≠ durationType. |
Mapping / hoogten (instance)¶
| Probleem | Oorzaak | Regel |
|---|---|---|
| Stil hold op verkeerde laddergraad | Soft mismatch | H9: hoogte-mismatch → harde TemplateInstanceError, geen stil hold. |
Slotcadens laatste vs frase 1 |
Template: laatste is mi–re–mi; frase 1 anders |
VSA voor laatste moet template pitches volgen; parallelle cadenspaden via YAML of (eerste passende pad). |
T.4 / T.N als zingbare syllabe |
Toon-aanduiding in VSA-regel | Geen T.N in de zingbare VSA-regel; inline-fragment in proza is geen lyric-pipeline. |
Corpus / tooling¶
| Probleem | Oorzaak | Regel |
|---|---|---|
Verwarring legacy *.pad-b.*-namen |
Legacy *.pad-b.* |
Corpus: T4-XX-….vsa/.mscz/.mxl; formule: template.mscz + template.mxl. |
| PDF in git vs lokaal | PDF is afgeleide MuseScore-export | PDF lokaal regenereren (--pdf / --pdf-only); niet als bron behandelen. |
| Tests groen, PDF “fout” | Tests toetsen MSCX-strings, niet visuele MuseScore-layout | Na layout-wijzigingen: PDF/MSCZ openen in MuseScore of screenshot; niet alleen pytest. |
| Grote verticale witruimte | MuseScore vult tot maxSystemDistance; MS4 leest Style vooral uit score_style.mss |
Doel 1,5× stafafruimte op scherm: titel = VBox+frameSystemDistance; systemDistance ×9/7 t.o.v. naïeve 1,5× (gemeten 7/6). |
| Eerste systeem springt in | MuseScore default enableIndentationOnFirstSystem |
Zet die op 0 (gelijke linker marge). |
Wat niet opnieuw proberen¶
- Leading/trailing “zelfde pitch” of “woord-hold” in
collapse_recite_for_printom scopes onder de breve te trekken. endBarLineVisibleopMeasurevoor verborgen maatstrepen in MS4.longa/ gestippelde whole als recite-duur om lyric-breedte te forceren.- Alle body-lettergrepen tot één left-aligned lyric +
lyric_ticks(extender onder de tekst; gap ná de recitaltekst). - Alleen
<align>left,…>verwachten voor left-attach aan de nootkop in MS 4.7+. - Recite-collapse in de Coria-MXL-pipeline.
Formuleblad vs instance (wat in git)¶
| Bestand | In git? | Regenereren |
|---|---|---|
template.yaml |
ja (bron) | handmatig |
template.mscz |
ja (afgeleid, formuleblad) | scripts\render_tropaar_toon4_corpus.py --template |
template.mxl |
ja (afgeleid) | idem |
template.pdf |
nee | --template --pdf |
corpus .vsa |
ja (bron) | curated |
corpus .mscz / .mxl |
ja (afgeleid instance) | scripts\render_tropaar_toon4_corpus.py |
*.pdf |
nee (.gitignore) |
--pdf / --pdf-only (MuseScore CLI) |
CI draait pytest (o.a. MSCX-strings); visuele PDF-check is lokaal. Formuleblad
heeft ankers/frase-ids/cycle-frames; instance niet. Instance-titel =
frontmatter-title (anders bestandsstem). Coria-MXL is instance zonder
recite-collapse.
Andere genres/tonen gebruiken dezelfde mapper (map_vsa_to_template) en
renderers; de corpus-CLI is tropaar-toon-4 totdat hun pitches_status geen
provisional meer is.
MVSA → MSCZ-partituur (niet template)¶
Voor litanie/LSATB-export (mvsa mscz) gelden aparte normaalvorm-regels:
geen mid-systeem-HBox, geen spacermaat met balklijnen, leidende |: zonder
lege maat, @tekst als SystemText. Zie
canonieke checklists — MSCZ S14–S19
en MSCZ-leesbaarheid — cues.
Template-HBox aan systeemeinde (cycle-tekst e.d.) blijft een apart patroon
en hoort niet mid-systeem.
Regenereren¶
cd /d C:\Git\orthodox-ronl\VSA-tooling
.\.venv\Scripts\python.exe -m pytest tests\test_vsa_template_instance.py tests\test_vsa_template_corpus_mscx.py -q
.\.venv\Scripts\python.exe scripts\render_tropaar_toon4_corpus.py
.\.venv\Scripts\python.exe scripts\render_tropaar_toon4_corpus.py --template
.\.venv\Scripts\python.exe scripts\render_tropaar_toon4_corpus.py --pdf-only