Datapack¶
1. Concetto di datapack¶
Un datapack è l’unità strutturale fondamentale del contenuto musicale in neumaRk.
Rappresenta un blocco verticale di informazione musicale sincronizzata nel tempo, tipicamente corrispondente a uno o più righi allineati:
- markers
- accordi
- note
- articolazioni
- dinamiche
- lyrics
- formattazione
Ogni datapack descrive una sequenza temporale coerente (una o più misure consecutive). I datapack musicali sono separati tra loro da uno o più righi vuoti, che hanno valore di delimitazione strutturale. La presenza di una riga vuota implica la conlusione del datapack precedente.
2. Tipi di righe¶
Ogni riga del datapack ha un tipo semantico.
Il tipo può essere:
- esplicito, tramite marcatore
- implicito, dedotto dal contenuto e dalla posizione
2.1 Marcatori espliciti di riga¶
I marcatori espliciti sono:
- una, due o tre lettere maiuscole
- seguite da
) - seguite da uno spazio
| Marcatore | Tipo |
|---|---|
M) |
Markers |
C) |
Chords |
A) |
Articulations |
N) |
Notes |
D) |
Dynamics |
L) |
Lyrics |
F) |
Format |
I marcatori sono opzionali.
Il marker N) ammette due varianti morfologiche di 2 caratteri,
previste esplicitamente dalla specifica:
N+— nuovo rigo introdotto in questo datapack (§4.5);N2— seconda voce sullo stesso rigo (vedineumaRk_voices.md).
La cifra 2 e il segno + sostituiscono la ), preservando
l'invariante di larghezza a 2 caratteri necessaria all'allineamento
verticale.
Analogamente, il marker C) ammette una variante:
C+— riga di accordi alternativi sopra la riga base (comment-label e scope di riga inneumaRk_chords.md§7).
Il segno + sostituisce la ) come in N+, preservando la stessa
invariante di larghezza.
3. Ordine logico delle righe (deduzione implicita)¶
In assenza di marcatori espliciti, il tipo delle righe viene dedotto seguendo l’ordine logico:
- Markers (al massimo una riga, opzionale)
- Chords
- zero o più righe
- l’ultima è considerata la riga principale
- Gruppi di note, ciascuno composto da:
- una riga di Articulations (opzionale, prima)
- una riga di Notes (obbligatoria in assenza di chords)
- una riga di Dynamics (opzionale, dopo — vedi
neumaRk_dynamics.md) - una riga di Lyrics (opzionale, ultima)
Un datapack può contenere da 1 a 4 gruppi di note: ogni gruppo corrisponde a un rigo del sistema (vedi §4). 4. Format (al massimo una riga, opzionale, sempre finale)
3.bis Deduzione del tipo di riga (algoritmo normativo)¶
Il §3 dà l'ordine logico dei tipi; questa sezione ne formalizza l'algoritmo di deduzione: come, in assenza di marcatore esplicito, il tipo di una riga è determinato da contenuto + posizione. La regola qui scritta è normativa — è la lingua, non un dettaglio d'implementazione. Un marcatore esplicito (§2.1) vince sempre: l'algoritmo che segue si applica solo alle righe senza marcatore.
3.bis.1 Struttura del datapack¶
Solo Markers e Chords sono unici per datapack (sono condivisi dall'intero sistema, §4.1); tutto il resto è un gruppo di note ripetuto, una volta per (rigo × voce):
datapack ::= [Markers]? Testa Gruppo{1..8} [Format]?
Testa ::= ( [A]? Chord )* // 0+ chord-row, ognuna eventualmente
// decorata da un'A) sopra
Gruppo ::= [A]? N [D]? [L]? // un (rigo × voce)
- Testa (Markers + Chords): unica, condivisa. La riga di articolazioni
può precedere una chord-row per decorarla (una chord-row può portare ritmo
proprio,
neumaRk_chords.md §4); per questoA)è ammessa prima diC). - Gruppo: si ripete fino a 8 volte = max 4 righi (§4) × 2 voci
per rigo (§4.6). La voce 2 non è deducibile implicitamente — non esiste
modo di distinguere dal solo contenuto "voce 2 dello stesso rigo" da "nuovo
rigo": va sempre dichiarata col marcatore esplicito
N2. Quindi la deduzione implicita da sola produce fino a 4 gruppi (i righi); gli 8 si raggiungono solo conN2. - Format: unica, sempre finale (§9).
3.bis.2 Modello di calcolo¶
La deduzione è un automa a passo singolo, per-datapack, che scorre le righe in ordine di sorgente mantenendo due elementi di stato:
lastType— il tipo dell'ultima riga (initEmpty);headClosed—falsefinché non compare la prima riga Notes del datapack, poitrueper sempre. Marca il confine fra Testa e Gruppi.
I guard lastType sono la funzione di transizione dell'automa: codificano
sia l'ordine dentro un gruppo, sia il loop-back che apre il gruppo
successivo (rientro su A o su N). headClosed impedisce a Chords di
ricomparire una volta entrati nei righi.
3.bis.3 Pre-filtro: righe decorative¶
Prima della cascata, una riga puramente decorativa — composta solo da
segni di battuta semplici, :, forme compatte di ritornello (neumaRk_flow_and_repeats.md §6.1),
punti, spazi e tab — viene saltata e non riceve un tipo musicale (resta
strutturale, le sue decorazioni di battuta appartengono semanticamente alle
altre righe). Eccezione: il rescue >/^ in §3.bis.6.
3.bis.4 Cascata di classificazione (precedenza normativa)¶
Sulle righe non-decorative senza marcatore, si applica una cascata first-match-wins. L'ordine è vincolante: i predicati di contenuto sono volutamente permissivi e non sovra-matchano solo grazie a (a) questo ordine e (b) la guardia di posizione. Il trittico che definisce ogni tipo è predicato + guardia + esclusioni.
| # | Tipo | Predicato (contenuto) | Guardia (posizione) | Esclusioni |
|---|---|---|---|---|
| 1 | Markers | solo […] / barline / spazi |
è la prima riga del datapack | — |
| 2 | Chords | ≥1 accordo valido (neumaRk_chords.md §3) + barline / . / % / comment-label / spazi — oppure soli % (TB1bis) |
testa aperta (!headClosed) |
non slash-only (TB2); non rest-only r/! (TB1) |
| 3 | Articulations | charset del vocabolario A) (neumaRk_articulations.md) |
lastType ≠ Articulations |
non ^-only (TB3); non notes-line valida (TB4) |
| 4 | Dynamics | charset dinamiche (< > c d f m p s z - . \| :) |
lastType == Notes |
— |
| 5 | Lyrics | word-char + . - _ ' \| : (il più permissivo) |
lastType ∈ {Notes, Dynamics, Lyrics} |
— |
| 6 | Notes | default / sink | qualsiasi | — |
Note sulle guardie:
- Markers (riga 1): la deduzione implicita di Markers avviene solo
sulla prima riga del datapack. Una riga markers-shaped più in basso non è
Markers (un
M)esplicito resta possibile ovunque la spec lo consenta). - Chords (riga 2): la condizione normativa è testa aperta. Equivale a
dire che gli accordi vivono solo prima della prima riga di note: gli accordi
sono unici e condivisi (§4.1), nessun datapack valido ha una chord-row dopo
una notes-row. Il parser realizza il vincolo col flag posizionale
headClosed(chiuso alla prima riga Notes del datapack) — allineato a §3.bis dal 2026-05-25 (FU.3a). - Lyrics (riga 5): il predicato è il più permissivo (matcha quasi ogni testo). È intenzionale: la permissività è contenuta dalla guardia di posizione, e in ogni caso il tipo di default è Notes. Non si restringe (sarebbe non-monotòno e rischierebbe di cambiare la classificazione di brani esistenti).
- Default Notes: la riga 6 è il sink — ogni riga che arriva in fondo alla
cascata è una riga di note. È anche il meccanismo del loop-back: due
N)consecutive (entrambe sink) sono due righi distinti.
3.bis.5 Tiebreaker¶
Tre disambiguazioni risolvono casi in cui un predicato permissivo matcherebbe il tipo sbagliato:
- TB1 — rest-only → Notes. Una riga composta solo da rest-token
(
r/!), barline,.,%e spazi appartiene allo stave (è una riga di note di soli silenzi), non a una chord-row vuota. Vale dopo Chords/Alt e dopo Articulations:
A7 ← Chords | > . ← Articulations
r ← Notes (TB1) r ← Notes (TB1)
Realizzato dal 2026-05-25 come regola unica «rest-only forza Notes»: la riga è intercettata prima di Chords e Articulations, a prescindere da
lastType(FU.3b dopo Articulations + FU.3c dopo Chords — entrambi davano il tipo sbagliato, rispettivamente chord-row vuota e Articolazioni). Una guardia richiede un rest-tokenr/!o%reale, così| > |(anacrusi) resta gestito dal rescue (§3.bis.6).
- TB1bis —
%-only senza chord-row → Chords. Una riga composta solo da%(più barline,., spazi — nessun rest-tokenr/!) in testa aperta (!headClosed) e in assenza di una chord-row reale nel datapack è una chord-row di sole ripetizioni di misura: ogni%ripete l'ultima misura-accordo (anche dal datapack precedente — il lookback dei measure-repeat è cross-datapack). È l'eccezione a TB1: i%senza rest-token non vengono forzati a Notes, ma cadono nel ramo Chords (la cuiisChordLineaccetta già%).
| C7 | F7 | ← Chords
| a b c | … ← Notes (chiude la testa)
| % | % | ← Chords (TB1bis): ripete C7, F7 dal datapack sopra
| d e f | … ← Notes
Decisione 2026-05-26, supera il principio precedente «se vuoi una chord-row di soli
%devi dichiararla conC)». Motivazione: «accordi che si ripetono mentre la melodia cambia» è il pattern di lead-sheet più comune; forzareC)su ogni continuazione era attrito gratuito. Due guardie tengono il caso stretto:
- niente rest-token — una riga con
r/!resta sempre Notes (TB1): i silenzi sono inequivocabilmente note;!sawRealChordRow— se la testa ha già una chord-row con accordo reale, una riga%-only successiva resta Notes (è una notes-row di ripetizioni), perché la chord-row del datapack è già definita.Escape-hatch per la lettura opposta (un secondo rigo di note di soli
%): marcatore esplicitoN+/N). Limite noto: un datapack di soli%(senza alcuna notes-row) viene letto come chord-row e viola la grammatica(A?ND?L?)+(serve ≥1N); dichiararlo conN)se l'intento è una notes-row standalone di ripetizioni.
- TB2 — slash-only → Notes. Una riga di soli
/standalone (più barline,., spazi) è slash rhythm (neumaRk_notes_and_durations.md §10), mai una chord-row:/da solo è sintatticamente quasi-accordo ma semanticamente un evento di nota.
| / / | / / | ← Notes (TB2)
- TB3 —
^-only → Notes. Una riga di soli^(più|e spazi) è una riga di note con sole legature di valore (neumaRk_notes_and_durations.md §6), non Articulations.
| ^ | ← Notes (TB3)
- TB4 — notes-line valida → Notes. Una riga che è una notes-line valida
ha priorità sulle Articulations, anche se cade interamente nel charset del
vocabolario
A). Necessario perché alcune lettere del vocabolario sono pure note-name/durate: in particolareg(componeglglissato, §9) è anche la nota G, e le durate1–4stanno nel charset →g,g4,g g gmatchavanoarticulations_lineed erano rubati ad A).
A7 ← Chords
g ← Notes (TB4), non Articulations
Predicato: ogni token (split su spazi; le barline
|/:ai bordi sono spogliate) è un note-token valido secondo la grammatica canonicaparse_notes(fonte unica → niente divergenza), e almeno un token porta un pitch reale[a-g]/r. I token di sola articolazione (>,tr,-,o,gl,~…) non matchanoparse_notes→ la riga resta Articulations; una riga di soli./,/^(placeholder, nessun pitch reale) → resta Articulations. Realizzato 2026-05-26 (isNotesLineForTiebreakinmap_functions.cpp), gate anche sul rescue>/^/~(§3.bis.6). Principio: in caso di ambiguità A)↔N), vince la nota.
3.bis.6 Rescue > / ^¶
Una riga che il pre-filtro (§3.bis.3) avrebbe scartato come decorativa — perché
> è leggibile come anacrusi attaccata a una barline — ma che contiene >
oppure ^ ed è interamente charset-articolazioni, viene recuperata come
Articulations (qui > è un accento, non un'anacrusi):
| > | ← Articulations (rescue): accento sul primo evento della misura
Il rescue è un ramo fuori cascata e produce sempre Articulations (le
articolazioni possono aprire un gruppo in qualsiasi posizione); è soggetto allo
stesso vincolo lastType ≠ Articulations e all'esclusione ^-only (TB3).
Prima riga del datapack. Il rescue presuppone un contesto a monte. In prima posizione (
line_id == 0) una riga| > |è letta come Markers/anacrusi, non come accento: il pre-filtro Markers (cascata riga 1) ha precedenza e>è ambiguo fra accento e levare quando non c'è una riga di note sotto a disambiguarlo. È una scelta consapevole (decisione 2026-05-25): in assenza di contesto la lettura anacrusi prevale.
3.bis.7 Post-pass: promozione AlternateChords¶
La classificazione di base assegna Chords a tutte le chord-row implicite.
Una pass successiva rietichetta come AlternateChords (C+, accordi
alternativi sopra la base) le chord-row consecutive che precedono l'ultima,
solo se nessuna chord-row del datapack porta un marcatore esplicito (se
l'utente ha scelto i marcatori, la sua scelta è rispettata). Limite: max 2 righe
alternative per datapack (E127). Spec completa in
docs/feature-alternate-chords.md e neumaRk_chords.md §7.
3.bis.8 Derivazioni e vincolo¶
- Il charset di
articulations_line(riga 3) deriva dal vocabolario chiuso dineumaRk_articulations.md(fonte unica): la deduzione e la semantica del renderer non devono divergere. - Invariante: l'algoritmo può solo essere esteso verso quanto qui
scritto, mai cambiare in silenzio una mappatura riga→tipo esistente. Le
divergenze parser↔spec sulla classificazione (FU.3a testa chiusa, FU.3b
rest-only dopo
A), FU.3c rest-only dopo Chords) sono state chiuse il 2026-05-25, verificate per differenza sulla batteria "classification golden" (wasm/tests/fixtures/classify_*). Resta aperto FU.1 (charset articolazioni dal vocabolario chiuso), che non cambia la mappatura riga→tipo. - Cambio di mappatura 2026-05-26 (TB1bis): la riga
%-only senza rest-token in testa aperta e senza chord-row reale passa da Notes a Chords (§3.bis.5 TB1bis). È un cambio deliberato e documentato della mappatura, non silenzioso — ammesso perché il linguaggio non è ancora diffuso (nessun bump di versione). Coperto dai goldenclassify_pct_only_chords(promozione) eclassify_pct_after_real_chords(guardiasawRealChordRow). - Correzione 2026-05-26 (TB4): la riga che è una notes-line valida ma cade
nel charset
A)(tipicamente le righe di sola notag:g,g4,g g g) passa da Articulations a Notes (§3.bis.5 TB4). È un bug-fix verso il comportamento corretto («vince la nota»), non un'estensione controversa. Coperto dai goldenclassify_note_g_after_chordseclassify_note_g_vs_artic(con negativo> . . .→ resta Articulations).
4. Più righi per datapack (multi-stave)¶
Un datapack può rappresentare un sistema con più righi allineati
(es. melodia + basso). Il numero di righi è dato dal numero di gruppi
di note (A?ND?L?) presenti, fino a un massimo di 4.
Il numero di righi può variare da un datapack all’altro nello stesso brano: un datapack può contenere un solo rigo e quello successivo due o più, senza dichiarazioni preventive.
4.1 Elementi condivisi dal sistema¶
I seguenti elementi sono comuni a tutti i righi del datapack:
- riga di Markers
- riga(he) di Chords
- segni di battuta e decoratori di misura (volte, cambio di
metro/tonalità,
$,@,DC,FINE, ecc.) - tonalità e metro del sistema
Le stanghette di misura attraversano verticalmente tutti i righi.
4.2 Elementi indipendenti per rigo¶
Ogni gruppo (A?ND?L?) definisce un rigo indipendente con propri:
- Notes (obbligatorie)
- Articulations, Dynamics, Lyrics (opzionali)
- chiave dichiarata via direttiva inline
(@…)come primo token della riga di Notes — vedineumaRk_notes_and_durations.md§9. In assenza di direttiva, vale l’ultima chiave definita nel contesto (default: chiave di violino). - legature, travi e gruppi irregolari (tutti contenuti nel rigo)
4.3 Allineamento orizzontale¶
Tutti i righi del sistema devono contenere lo stesso numero di misure: l’allineamento verticale fra righi è temporale.
4.4 Esempio¶
C) | Gm6 |
N) | g | a | bb | a |
N) | (@F) g,4 bb8 d e4 d | g,4 bb8 d e4 d | g,4 bb8 d e4 d | g,4 bb8 d e4 d |
Sistema a 2 righi: il primo in chiave di violino (default), il secondo
in chiave di basso. L’accordo Gm6 è comune al sistema.
4.5 Continuità degli stave fra datapack (N+)¶
Quando un brano ha più datapack, ogni rigo (stave) ha una identità persistente: il "primo rigo" di un datapack è lo stesso "primo rigo" del precedente — eredita pitch context, chiave in vigore, durCtx, e viene reso nella stessa posizione verticale.
L'identità di base è posizionale: la prima N) del datapack
corrisponde alla prima N) del datapack precedente, la seconda alla
seconda, e così via.
Per aggiungere un nuovo rigo in un datapack senza romperne
l'identità con i precedenti, si usa il marker N+ al posto di N).
N+ <contenuto del rigo nuovo>
Il + sostituisce la ) (non la aggiunge): il prefisso resta a 2
caratteri come N), così l'allineamento verticale delle misure resta
identico fra righi adiacenti.
Regole¶
N)= continuazione del prossimo rigo del datapack precedente (FIFO, in source order). Ne eredita il context (pitch, chiave, durata).N+= nuovo rigo introdotto in questo datapack. Parte con context fresh (riferimento di orientamento dipende dalla chiave iniziale, vedineumaRk_notes_and_durations.md§2.2).- L'ordine in source = ordine visuale top→bottom. Il marker
N+determina solo l'identità (nuovo vs. continuazione), non la posizione. N+nel primo datapack del brano è ammesso ma ridondante (in assenza di precedenti tutti i righi sono per forza nuovi); viene trattato come un normaleN).- Limite invariato: max 4 righi totali per datapack (somma di
N) N+).
Errori¶
- E122 —
N) senza match: il datapack ha piùN)di quanti righi avesse il precedente. MancanoN+(o unN)di troppo).
Esempio¶
Datapack 1 (intro a 2 righi, treble + bass):
M) [intro]
C) G7
N) |: <d b>2 <e c>4 | <f d>2 <e c>4 :|
N) (@F) g,4. d'8 e d | f4. d8 e d
Datapack 2 (Theme): aggiunge un terzo rigo in alto (melodia di voce), mantenendo treble e bass dell'intro al centro e in basso.
M) [Theme]
C) > | G7
N+ > d8 | b'^ | b2 r8 d,
A) > | . ! | . !
N) > |: <d b>2 <e c>4 | <f d>2 <e c>4 :|
N) > | g,4. d'8 e d | f4. d8 e d
Mapping risultante (per l'engine, non visibile in source):
| source row | tipo | identità |
|---|---|---|
1 (N+) |
nuovo | nuovo stave (top) |
2 (N)) |
cont. | = primo rigo intro (treble) |
3 (N)) |
cont. | = secondo rigo intro (bass) |
Il context (last_pitch, chiave, durCtx) dei righi 2 e 3 del Theme viene dai righi 1 e 2 dell'intro; il rigo 1 del Theme parte fresh.
Casi non coperti¶
La sintassi N)/N+ esprime la situazione comune "aggiungo un
rigo in cima/in mezzo/in fondo", ma non copre:
- drop selettivo (datapack che mantiene il 2° rigo del precedente ma droppa il 1°);
- reorder (scambiare l'ordine visuale di righi esistenti, mantenendone l'identità).
Per questi casi una futura estensione potrebbe introdurre un riferimento
esplicito all'ID interno del rigo (es. N<n>)). Non spec'd in questa
versione.
4.6 Seconda voce per rigo (N2)¶
Ogni rigo può ospitare una seconda voce indipendente, introdotta
dalla riga N2. Stave e voce sono concetti distinti: il rigo è il
pentagramma, la voce è uno stream musicale all'interno del rigo.
La voce 2 condivide chiave, tonalità, metro, stanghette e riga degli accordi con la voce 1, ma mantiene contesto musicale persistente indipendente. Voce 1 ha gambi in alto, voce 2 in basso.
La specifica completa di sintassi, contesto, binding e diagnostica
è in neumaRk_voices.md.
5. Regole di validità del datapack¶
Un datapack è valido se:
- contiene almeno una riga di Notes o una riga di Chords
- rispetta l’ordine logico delle righe
- tutte le righe musicali sono temporalmente allineabili
Non è valido:
- un datapack con sole righe di testo
- un datapack con una riga di Format non finale
6. Segni di battuta e misure¶
Tutte le righe musicali (Markers, Chords, Articulations, Notes, Dynamics, Lyrics):
- contengono segni di battuta — semplici e composti — ed eventuali decoratori di misura (in assenza di barline tutto il contenuto apparterrà alla prima misura del rigo)
- definiscono implicitamente la suddivisione in misure
La riga di Format è l'unica eccezione: non ammette segni di battuta (né semplici né composti) e nessun decoratore di misura.
6.1 Segni di battuta supportati¶
I segni di battuta ammessi sono:
|battuta semplice||doppia barra|.o.|fine|:inizio ripetizione:|fine ripetizione
Il segno finale di battuta deve essere preceduto da uno spazio.
7. Decoratori di misura¶
I decoratori di misura sono elementi adiacenti a una barline e si dividono in:
- BEGIN decorators (a destra della barline)
- END decorators (a sinistra della barline)
7.1 BEGIN decorators¶
Posizionati immediatamente a destra della barline.
Possibili decoratori:
-
Cambio di metro e/o tonalità
-
fra parentesi tonde
- separati da virgola
- ordine arbitrario
Esempi:
|(3/4,Dm)
|([3+3+2]/8)
-
Volta endings
-
testo fra parentesi quadre
- opzionale
+nper la durata in misure
Esempio:
|[1.]+4
In assenza di +n, la volta si chiude automaticamente al primo :|
incontrato entro 4 battute (caso tipico dei finali [1.]).
Se nelle 4 battute successive non compare un :|, la volta indica
un'uscita — usare +n per i casi non standard.
$segno@coda
Se presenti, metro e tonalità devono precedere ogni altro decoratore BEGIN.
7.2 END decorators¶
Posizionati immediatamente a sinistra della barline.
Decoratori supportati:
DCDCal@DCalFINED$D$al@D$alFINEFINEal@- testo libero fra parentesi quadre (annotazione grafica)
I segni $ e @ sono BEGIN decorator (vedi §7.1): identificano il punto in cui il segno o la coda si trova, non un salto verso di essi.
8. Riga di Markers¶
La riga di Markers:
- contiene marcatori racchiusi fra parentesi quadre
- i marker si riferiscono all’inizio della battuta
Se un marker è preceduto da una barline:
- deve esserci uno spazio fra barline e marker
- per evitare ambiguità con i volta-decorators
È best practice collocare i decoratori di flusso (DC, D$, coda, ecc.) in questa riga.
9. Riga di Format¶
La riga di Format può essere dichiarata:
- in forma esplicita, tramite il marcatore
F); - in forma implicita, se il contenuto della riga è riconoscibile univocamente come riga di format.
La riga di Format, se presente, deve essere:
- unica per datapack;
- sempre l’ultima riga del datapack.
In caso di ambiguità con una riga musicale, prevale sempre l’interpretazione musicale e la riga non viene considerata Format.
Contiene indicazioni di allineamento:
| Simbolo | Allineamento |
|---|---|
\|* |
LEFT |
*\| |
RIGHT |
\|*\| |
CENTER |
\|**\| |
JUSTIFIED (default) |
10. Margini fra datapack¶
Una riga:
- che segue una riga vuota
- che inizia con
- - che contiene solo
-, spazi, tab o%
indica un margine verticale fra datapack.
La profondità del margine è data dal massimo numero di - consecutivi:
- - -→ margine 1- -- -→ margine 2--- -→ margine 3
Il simbolo % indica un possibile page break.
11. Commenti¶
Sono permessi commenti single-line nella forma // comment. Lo scope è la riga: tutto ciò che segue // fino al newline viene ignorato dal parser. I commenti possono stare su riga propria (sopra/sotto un datapack, o tra le righe di un datapack) oppure a fine riga di una riga di codice.
Il discriminante fra le due forme è posizionale: se prima di // c'è almeno un carattere non-whitespace, il commento è trailing (la parte di codice prima di // resta valida); altrimenti l'intera riga è commento.
I commenti multi-riga (/* … */) non sono supportati: NRK è un linguaggio column-sensitive (le | di battuta allineano verticalmente le righe del datapack) e i block comments romperebbero l'allineamento.
La sequenza %% ad inizio riga non è un commento: è riservata per i blocchi di versione del brano (vedi neumaRk_versions.md).
12. Blocchi di versione¶
Fra un datapack e l'altro possono comparire blocchi di versione, marcati %%NAME … %%end, che racchiudono uno o più datapack alternativi del brano. I blocchi vivono standalone fra datapack, non al loro interno. Vedi neumaRk_versions.md per la spec completa.