Markers¶
1. Cos’è un Marker¶
Un marker è un elemento strutturale non musicale che identifica un punto significativo nel flusso del brano. I marker non si riferiscono a un elemento sonoro, non hanno durata musicale propria e non influiscono direttamente sul contenuto musicale (note, accordi, ritmi), ma servono a:
- segmentare il brano in sezioni logiche;
- facilitare la lettura e l’orientamento umano;
- fornire ancoraggi semantici per il rendering, la navigazione e il playback;
- supportare forme musicali, ripetizioni e riferimenti.
I marker fanno parte del datapack musicale, ma appartengono alla sfera della struttura, non della notazione musicale.
Appartenenza semantica¶
Un marker appartiene semanticamente a una misura.
Esso identifica, etichetta o qualifica una misura come unità strutturale del brano e non è legato al flusso musicale o all’ordine di esecuzione.
2. Riga dei Markers¶
I marker sono contenuti in una riga di markers, che può essere:
- dichiarata esplicitamente con il marcatore di riga
M); - dedotta implicitamente dal contenuto della riga.
2.1 Posizione nel datapack¶
- La riga dei markers, se presente, è la prima riga del datapack.
- È opzionale.
- Può comparire una sola riga di markers per datapack.
Best practice: collocare nella riga dei markers anche i decoratori di misura (volta, segno, coda, ecc.), per concentrare la struttura formale in un unico punto.
3. Sintassi dei Markers¶
Un marker è espresso in due forme container, che differiscono per il ruolo strutturale e per la presenza del box grafico:
[<testo>]— sezione: unità strutturale del brano, con box;"<testo>"— annotazione: testo descrittivo, senza box.
[Intro] sezione (con box)
[A] sezione
"freely" annotazione
"swing feel" annotazione
Il marker ammette il markup testuale definito in
neumaRk_text_markup.md. Lo stile di default è bold, size body, in
entrambe le forme.
3.1 Sezione vs annotazione¶
I due container hanno valore semantico diverso:
| Forma | Tipo | Valore strutturale | Target PLAY/FORM | Chiude scope collapsible |
|---|---|---|---|---|
[…] |
sezione | sì (unità del brano) | sì | sì |
"…" |
annotazione | no (testo descrittivo) | no | no |
Una sezione identifica un'unità strutturale ricorribile e
referenziabile (Intro, Verse, Chorus, A, B, …). Le sezioni sono i
target di PLAY) / FORM) (vedi neumaRk_play_and_form.md §3.1) e
delimitano lo scope delle sezioni collassabili (vedi §4).
Un'annotazione è un testo libero senza valore strutturale (es.
"freely", "swing feel", "con feeling"). Le annotazioni non sono
referenziabili da PLAY) / FORM) e non chiudono lo scope di una
sezione collassabile.
Nota normativa. Questa distinzione è un raffinamento della spec 0.5, dove
[…]e"…"erano considerate semanticamente equivalenti. Documenti esistenti sono retrocompatibili (le annotazioni"…"continuano a esistere come testo); l'unica differenza operativa è il binding selettivo da PLAY/FORM e il comportamento di[? …](vedi §4).
3.2 Ancoraggio temporale¶
- Un marker si riferisce all'inizio della battuta in cui compare.
- Se preceduto da una barline e nella forma con box
[…], deve essere separato da essa da almeno uno spazio, per evitare ambiguità con i decoratori di volta. - La forma
"…"non collide con i decoratori di volta e può essere adiacente alla barline; resta tuttavia raccomandato lo spazio per leggibilità.
Esempio valido:
| [A]
| "freely"
Esempio non valido:
|[A] // ambiguo: potrebbe essere interpretato come volta
4. Sezioni collassabili¶
Una sezione può essere dichiarata collassabile (anche detta
opzionale) anteponendo il prefisso ? (carattere ? seguito da
uno spazio) all'interno del marker:
[? Verse]
[? Solo 2]
[? Outro]
Una sezione collassabile è una proprietà UX del marker: l'utente
può espandere/comprimere la sezione nell'interfaccia di lettura
(accordion). Lo stato espanso/compresso è preference utente, salvato in
user-index (Firestore users/{uid}/song_view_state/{songId}) e non
nel file NRK.
4.1 Scope della sezione collassabile¶
Lo scope di [? NAME] si estende dalla misura del marker fino al
primo dei seguenti eventi:
- inizio di un'altra sezione
[…](di qualsiasi nome, collassabile o no, incluso il marker anonimo[!]di §4.2); - fine del documento.
Le annotazioni "…" interposte non chiudono lo scope:
appartengono comunque alla sezione collassabile corrente.
M) [? Verse] | … | "freely" | … | [Chorus] | …
└─────── scope di Verse ─────┘
└ Chorus apre nuovo scope
4.2 Marker anonimo [!] (chiusura implicita di sezione opzionale)¶
Quando una sezione opzionale termina e non c'è un marker successivo
che la chiude naturalmente (perché segue flusso "anonimo", non
strutturato come sezione), si usa il token speciale [!] (parentesi
quadre con un singolo !, senza spazi).
[!] è semanticamente un marker di apertura di sezione non-opzionale
anonima: aderisce alla convenzione "marker = inizio-misura" (§3.2)
e la chiusura dello scope precedente è il side-effect naturale della
regola §4.1.
M) [? Coda] | … | … | [!] | … |
└── scope di Coda ─┘
└ flusso non-collassabile, anonimo
Proprietà:
- Non renderizzato come marker (nessun box, nessuna etichetta).
- Non referenziabile da
PLAY)/FORM): non ha NAME. Se usato come reference è reference-broken (vedineumaRk_play_and_form.md§7.3). - Ammesso ovunque:
[!]non richiede una sezione opzionale aperta. Se non c'è scope da chiudere il token è ridondante (warning W146, non bloccante).
4.3 Niente annidamento¶
Una [? Inner] interna a un'altra [? Outer] chiude lo scope di
Outer e apre quello di Inner, secondo la regola generale §4.1. Non
esiste un meccanismo di sezioni collassabili annidate.
M) [? Outer] | … | [? Inner] | … |
└ Outer ──┘ └─ Inner ─────…
4.4 Stato di default¶
All'apertura di un brano per la prima volta, le sezioni collassabili sono espanse. L'utente le collassa esplicitamente; lo stato è poi persistente in user-index.
Il ? nel marker è ben evidenziato in UI (chevron nel margine, stile
distinto del titolo) perché la presenza di sezioni collassabili sia
immediatamente riconoscibile, anche quando tutte espanse.
4.5 Riferimenti da PLAY/FORM¶
Una sezione [? NAME] è referenziata da PLAY) / FORM) usando il
solo NAME, senza prefisso ?:
M) [? Verse] | … | [Chorus] | …
PLAY) [Verse] [Chorus]
Il prefisso ? è una proprietà UX della sezione, non parte del nome
strutturale. Il binding fra PLAY) e M) è per text-equality sul
NAME, ignorando il prefisso ?.
4.6 Esecuzione¶
Lo stato collassato/espanso è UX-only: il player esegue una sezione collassabile esattamente come una sezione ordinaria, indipendentemente dal fatto che l'utente l'abbia collassata o espansa nella vista.
Una sezione collassata non viene "saltata" dal player. Per omettere
una sezione dall'esecuzione esistono altri meccanismi (versioni,
PLAY) esplicita che la esclude).
4.7 Vincolo a inizio rigo¶
Una sezione collassabile deve iniziare e finire a inizio rigo (= a inizio di un system / datapack). Concretamente:
- il marker
[? NAME]deve comparire nella prima misura del system in cui appare; - la chiusura dello scope (qualsiasi altro
[…]o[!]) deve a sua volta comparire nella prima misura del system in cui appare; - lo scope termina anche a EOF (caso valido).
Razionale: l'accordion UX comprime righe intere; una sezione che inizia o finisce a metà rigo produrrebbe una resa ambigua (mezzo rigo sparirebbe, lasciando moncheria visiva).
In caso di violazione:
- emessa W151 (warning, non bloccante);
- la sezione non è collassabile lato UX: il toggle utente è ignorato sul render (la sezione resta sempre espansa).
5. Rilevanza identitaria¶
Il prefisso ~ su un marker di sezione la dichiara identitaria: ne
segnala il tema come quello che caratterizza il brano ("la parte che
fa riconoscere il pezzo"). È una proprietà strutturale e portabile
della composizione — viaggia col file — non un dato dell'host.
M) [Intro] | … |
M) [~ Tema] | … | ← sezione identitaria del brano
M) [Coda] | … |
~ non è renderizzato (nessun box, nessuna etichetta aggiuntiva: la
sezione si disegna come una [Tema] normale) ed è preservato in
round-trip dal serializer.
La rilevanza identitaria è un'annotazione musicale, non un'etichetta host: indica quale musica caratterizza il brano. Il marker è agnostico alla dimensione d'analisi: l'host può derivarne ciò che serve sotto qualunque profilo — melodia, armonia, ritmo, ritmo armonico, ecc. (elenco non esaustivo). Lo spec definisce quale regione è identitaria; cosa se ne estrae e su quale dimensione è fuori dal linguaggio.
5.1 Scope della regione di rilevanza¶
Lo scope di [~ NAME] si estende dalla misura del marker fino al
primo dei seguenti eventi:
- l'inizio di una nuova sezione
[…]priva del prefisso~; - la fine del documento.
Una sezione successiva che porta anch'essa ~ non chiude la
regione: la continua. Sezioni ~ consecutive formano quindi
un'unica area di rilevanza; solo una sezione senza ~ la chiude.
M) [~ A] | … | [~ B] | … | [C] | … | [~ D] | …
└──── area di rilevanza 1 (A+B) ────┘ └ area 2 (D)
└ C non rilevante, chiude l'area 1
Le annotazioni "…" interposte non chiudono lo scope (come in §4.1).
5.2 Più aree per brano¶
Sono ammesse più aree di rilevanza melodica nello stesso brano (le
~ non consecutive sono aree distinte, vedi [~ D] sopra). Il modo in
cui l'host usa una o più aree (es. quale considerare per quale scopo)
non è materia di linguaggio.
5.3 Default (nessun marker ~)¶
In assenza di qualsiasi [~ …] nel brano, la regione melodicamente
rilevante è implicitamente il tratto dall'inizio del brano fino
alla prima sezione esclusa (o fino a EOF se non ci sono sezioni). I
brani che non usano il marker hanno quindi una regione di rilevanza
ben definita e host-independent.
5.4 Marker anonimo [~]¶
[~] (parentesi quadre con un solo ~, senza spazi) è una sezione
anonima identitaria: si comporta come il marker anonimo
[!] (§4.2) — apre una sezione non-opzionale e chiude lo scope
precedente — ma è flaggata ~. Serve a marcare "da qui è
rilevante" quando il tema non è una sezione nominata. Specularmente, un
[!] (senza ~) che segue una regione di rilevanza la chiude
(è una sezione priva di ~, §5.1).
5.5 Composizione con ? (collassabile + rilevante)¶
Una sezione può essere insieme collassabile e identitaria. I due
prefissi si accettano in ordine libero in input: [?~ NAME] e
[~? NAME] sono equivalenti. Essendo semanticamente identiche, il
serializer le normalizza alla forma canonica [?~ NAME] (come già
normalizza spaziatura e altri aspetti dei marker).
M) [?~ Bridge] | … | ≡ M) [~? Bridge] | … |
5.6 Riferimenti da PLAY/FORM¶
Come per ? (§4.5), una sezione [~ NAME] è referenziata da PLAY) /
FORM) con il solo NAME, senza prefisso. Il binding è per
text-equality sul NAME, ignorando i prefissi ~ e ?.
M) [~ Tema] | … |
PLAY) [Intro] [Tema] [Coda]
5.7 Ancoraggio¶
[~ NAME] / [~] seguono l'ancoraggio delle sezioni (§3.2, §4.7):
compaiono a inizio misura; i confini di scope (sezione senza ~, o EOF)
cadono a inizio rigo come ogni altro confine di sezione.
6. Play directive in riga M)¶
La riga M) ammette, oltre ai marker testuali […] / "…", anche
play directive nella forma (=Style,Tempo) per cambiare lo style
e/o il tempo del brano a partire da una misura specifica. Vedi
neumaRk_play_directive.md per la spec completa.
La play directive convive liberamente con i marker testuali nella stessa misura. La disambiguazione fra i token è per delimitatori:
| Token | Tipo |
|---|---|
[…] |
sezione (marker strutturale) |
[? …] |
sezione collassabile (vedi §4) |
[~ …] |
sezione identitaria (§5) |
[!] |
sezione anonima non-opzionale (§4.2) |
[~] |
sezione anonima identitaria (§5.4) |
"…" |
annotazione (testo descrittivo) |
(=…) |
play directive |
Esempio:
M) | [Intro] (=Rock,120bpm) | | | [A] (=swing,140bpm) |
7. Regole di Validità¶
Una riga di markers è valida se:
- contiene solo sezioni
[…]/[? …]/[~ …], marker anonimi[!]/[~], annotazioni"…"e play directive(=…), separati da spazi e segni di battuta; - non contiene pattern riconducibili a note o accordi;
- rispetta le regole di separazione da barline.
In caso di violazione:
- la riga non viene riconosciuta come riga di markers;
- il parsing del datapack prosegue secondo le regole di deduzione standard.
7.1 Codici diagnostici¶
| Codice | Severità | Descrizione |
|---|---|---|
| W146 | WARNING | [!] ridondante: nessuna sezione opzionale da chiudere |
| W151 | WARNING | Sezione opzionale non-collassabile: [? NAME] o la sua chiusura non a inizio rigo (§4.7) |