Vai al contenuto

Versioni del brano

Questo documento definisce la sintassi e la semantica delle versioni in neumaRk: meccanismo per rappresentare nello stesso file più varianti dello stesso brano (arrangiamenti alternativi, riarmonizzazioni di singole sezioni, intere riscritture).

L'utente sceglie quale variante visualizzare/eseguire tramite UI; la preferenza è persistente in user-index e non nel file NRK.


1. Definizione

Una versione è una variante alternativa di una porzione del brano, delimitata da un blocco named della forma:

%%NAME
… contenuto …
%%end

Esistono due classi di blocchi:

  • Default — blocco %%NAME senza label, fa parte del flusso lineare del brano (è la versione "canonica" che il lettore vede di base);
  • Variante — blocco %%NAME "label" con label, vive a lato del flusso. Si attiva esplicitamente dall'utente.

Una variante sostituisce tutte le occorrenze del blocco default omonimo durante l'esecuzione/rendering.

1.1 Esempio minimale

M) [Intro]
… intro originale …

%%BRIDGE
M) [Bridge]
… bridge originale …
%%end

M) [A]
… A finale originale …

%%BRIDGE "Bill Evans version"
M) [Bridge]
… bridge Bill Evans …
%%end

L'utente apre il brano e vede la versione canonica. Selezionando "Bill Evans version" dal selettore UI, il blocco %%BRIDGE viene sostituito dalla variante; il resto del brano (Intro, A) resta invariato.


2. Sintassi

2.1 Apertura del blocco

%%NAME                       blocco default
%%NAME "label"               blocco variante
  • %% deve essere all'inizio della riga (eventualmente preceduto da soli spazi, secondo le regole generali di whitespace di neumaRk).
  • NAME è un identificatore: una o più lettere/cifre/underscore, case-sensitive. Niente spazi interni.
  • "label" (opzionale, presente solo nelle varianti) è un container testuale "…" adiacente al NAME, con uno spazio di separazione. Ammette il markup unificato (neumaRk_text_markup.md).

2.2 Chiusura del blocco

%%end
  • Anche %%end deve essere all'inizio della riga.
  • Chiude il blocco aperto più recente.
  • Un %%end senza blocco aperto produce warning W148.

2.3 Contenuto del blocco

Un blocco contiene uno o più datapack validi (vedi neumaRk_datapack.md). Tutte le regole musicali (marker, accordi, note, dinamiche, ecc.) si applicano normalmente dentro il blocco.

2.4 Annidamento non ammesso

Un blocco %%NAME non può essere aperto dentro un altro blocco. Il parser produce warning W149 se incontra %%X mentre un blocco è aperto.

2.5 Riservato: %%

La sequenza %% ad inizio riga è riservata per i blocchi versions. Non è ammessa in altri contesti del linguaggio (i commenti NRK usano //, vedi neumaRk_datapack.md per la spec dei commenti single-line).


3. Posizione strutturale

3.1 Standalone fra datapack

I blocchi %%NAME vivono fra datapack musicali, non al loro interno. La struttura del documento è una sequenza alternata di:

  • datapack normali (flusso comune a tutte le versioni);
  • blocchi default %%NAME (sezioni named del flusso);
  • blocchi variante %%NAME "label" (varianti delle sezioni named).
[datapack] [datapack] %%BRIDGE [datapack] %%end [datapack]
                     └─ default ─┘
[datapack] %%BRIDGE "Bill Evans" [datapack] %%end
          └─────────── variante ───────────┘

3.2 Posizione delle varianti

Le varianti %%NAME "label" possono apparire in qualsiasi posizione del documento (raccomandato: subito dopo il blocco default omonimo, o in coda al documento). Il matching è per nome, non per posizione.


4. Semantica della sostituzione

4.1 Regola fondamentale

Quando l'utente attiva la variante %%NAME "label", tutte le occorrenze del blocco default %%NAME nel documento vengono sostituite dal contenuto della variante.

Le porzioni del brano fuori da blocchi (datapack normali) restano invariate in tutte le versioni: appartengono al "tronco comune".

4.2 Multi-occorrenze del default

Se un blocco %%NAME default appare più volte (es. AABA con tre %%A distinti), una singola variante %%NAME "label" sostituisce tutte le occorrenze.

%%A
… A original …
%%end

%%B
… B …
%%end

%%A
… A original (seconda occorrenza, può essere musicalmente identica
   o variata) …
%%end

%%A "miles"
… A Miles version …
%%end

Attivando "miles": entrambe le %%A default sono sostituite dalla versione Miles. Per varianti per posizione (es. solo la seconda A è diversa), usare nomi distinti: %%A1, %%A2.

4.3 Marker M) ortogonali

I marker della riga M) interni a un blocco %%NAME sono indipendenti dal nome del blocco. Il parser non richiede che M) [Bridge] appaia dentro %%BRIDGE: convention dell'autore nominarli uguale, ma non è vincolato.

%%PEDAL
M) [A pedal]
… …
%%end

PEDAL è il nome del blocco (per il selettore versioni); A pedal è il marker della sezione (per PLAY/FORM, render, navigazione).

4.4 Riscritture totali

Per arrangiamenti completi (es. "Round Midnight, arrangiamento Miles"), l'autore può racchiudere l'intero brano in un blocco %%NAME default (con nome a scelta: %%SONG, %%MAIN, ecc.) e fornire la riscrittura come variante.

%%SONG
M) [Intro]
… brano completo originale …
M) [Outro]
…
%%end

%%SONG "Miles Davis arrangement"
M) [Intro Miles]
… arrangiamento completo Miles …
M) [Coda]
…
%%end

Non esiste una keyword riservata per "tutto il brano": qualsiasi nome funziona, l'autore sceglie quello che preferisce.


5. Header opzionale HV)

L'header del documento (neumaRk_header.md) ammette una nuova voce opzionale HV) per dichiarare esplicitamente le versioni disponibili e quella di default:

HV) versions: [original, miles, jarrett] default=original

5.1 Sintassi

HV) versions: [<label1>, <label2>, …] [default=<label>]
  • versions: parola chiave obbligatoria.
  • Lista di label fra parentesi quadre, separate da virgole.
  • default=<label> opzionale: specifica quale variante mostrare alla prima apertura (in assenza di preferenza utente). In assenza di default=, il default è il flusso default (blocchi %%NAME senza label).

5.2 Funzioni dell'HV)

  • Documentazione: rende esplicite le versioni del brano nell'header.
  • Ordinamento UI: le label sono presentate nel selettore UI nell'ordine dichiarato.
  • Label nominata del default: senza HV), il default è "unnamed"; con HV) può ricevere un nome (es. original) e apparire nel selettore insieme alle varianti.

5.3 HV) opzionale

In assenza di HV), le varianti sono dedotte dai blocchi %%NAME "label" presenti nel documento. L'ordine è quello di apparizione nel file. Il default è il flusso non-etichettato.

5.4 Discrepanze

Una label dichiarata in HV) ma assente nel documento (o viceversa) non è un errore: il selettore UI mostra solo le varianti effettivamente presenti. È responsabilità dell'autore mantenere coerenza.


6. Preferenza utente

Lo stato "versione corrente" è una preference utente salvata in user-index Firestore (es. users/{uid}/song_view_state/{songId}.version).

  • Alla prima apertura, il documento mostra il default (flusso senza blocchi %%NAME etichettati, oppure quanto dichiarato in HV) default=).
  • L'utente cambia versione tramite selettore UI (badge con tendina).
  • La scelta è persistente per quel brano specifico per quell'utente.

Lo stato della versione non viene mai scritto nel file NRK: il file è immutabile rispetto alla preferenza di lettura.


7. Diagnostica

7.1 Codici diagnostici

Codice Descrizione
W147 Blocco %%NAME non chiuso (manca %%end entro fine documento)
W148 %%end orfano (nessun blocco aperto)
W149 Blocco %%NAME annidato dentro un altro blocco
W150 HV) malformato (atteso versions: [list] [default=label])

7.2 Non-errori

  • Variante senza default omonimo (%%X "label" ma nessun %%X default): la variante è ignorata in esecuzione, ma resta nel file. Render UI può segnalarla come "orfana".
  • Default senza varianti (%%X solo): consentito; il blocco è una semplice sezione "preparata per future varianti".
  • Label %%X "label" ripetuta più volte: l'ultima vince (silently), oppure render mostra warning UI.

8. Esempi

8.1 Days of Wine and Roses con Bill Evans bridge

HT) Days of Wine and Roses
HC) Henry Mancini
HK) F
HM) 4/4
HV) versions: [original, bill_evans] default=original

M) [Intro]
… intro …

M) [A]
… A original …

%%BRIDGE
M) [Bridge]
… bridge original …
%%end

M) [A]
… A finale original …

%%BRIDGE "bill_evans"
M) [Bridge]
… bridge ri-armonizzato Bill Evans …
%%end

8.2 Round Midnight, riscrittura totale Miles

HT) Round Midnight
HC) Thelonious Monk
HV) versions: [original, miles] default=original

%%SONG
M) [Intro]
… intro standard …
M) [A]
… A originale …
M) [B]
… B originale …
M) [A]
… A finale …
%%end

%%SONG "miles"
M) [Intro Miles]
… intro Miles …
M) [A]
… A con accordi cambiati …
M) [B]
… B con frase aggiunta …
M) [Coda]
… coda Miles …
%%end

L'utente sceglie "miles" dal selettore → il blocco %%SONG originale è sostituito dalla riscrittura.

8.3 AABA con A "miles" che sostituisce tutte le A

%%A
… A originale …
%%end

%%A
… (seconda occorrenza, identica o variata) …
%%end

%%B
… B …
%%end

%%A
… A finale …
%%end

%%A "miles"
… Miles version dell'A …
%%end

Attivando "miles": le tre %%A default sono sostituite dalla variante. Il %%B resta invariato.

8.4 Variante per posizione (nomi distinti)

%%A1
… prima A …
%%end

%%B
… B …
%%end

%%A2
… seconda A (lievemente diversa) …
%%end

%%A2 "minor key"
… A2 in minor mode …
%%end

Solo la seconda A è sostituibile dalla variante "minor key". La prima A non è coinvolta perché ha nome diverso (%%A1).


9. Riassunto

Concetto Sintassi Sezione
Blocco default %%NAME … %%end §2.1
Blocco variante %%NAME "label" … %%end §2.1
Chiusura blocco %%end §2.2
Posizione blocchi standalone fra datapack, no annidamento §3.1
Sostituzione variante sostituisce tutte le %%NAME default §4.1
Marker M) ortogonali al nome del blocco §4.3
Riscrittura totale racchiudere il brano in un blocco unico (es. %%SONG) §4.4
Header HV) versions: [list] default=label (opzionale) §5
Preference utente user-index Firestore, non NRK §6

Questo documento definisce le versioni del brano in neumaRk: meccanismo robusto e granulare per rappresentare arrangiamenti alternativi, ri-armonizzazioni puntuali e riscritture complete dello stesso brano dentro un singolo file.