Markup testuale¶
Questo documento definisce la sintassi e la semantica del markup testuale in neumaRk: regole comuni di formattazione applicabili a tutti i container testuali del linguaggio (marker, end-decorator, comment-label, annotation note, label di sezione, prosa di forma).
L'obiettivo è fornire un sistema unificato e ortogonale in cui un primo asse decide la cornice grafica (container), un secondo asse decide lo stile di default (costrutto ospitante), e un terzo asse — opzionale — consente all'utente di applicare markup esplicito.
1. Tre assi ortogonali¶
Il rendering del testo in neumaRk è funzione di tre assi indipendenti:
- Container — il testo sta fra virgolette; la cornice attorno è
facoltativa:
"…"(nessuna),["…"](riquadro, abbreviabile in[…]),("…")(tonda). Vedi §2.1. - Stile di default — determinato dal costrutto ospitante (marker, comment-label, annotation, prosa, ecc.).
- Markup utente — opzionale, definito tramite un sottoinsieme di Markdown applicato dentro il container.
Nessuno dei tre assi vincola gli altri. Lo stesso testo può essere espresso con qualunque cornice, qualunque default semantico, con o senza markup esplicito.
Eccezione: marker
M). Nei marker della rigaM)(sezioni e annotazioni, vedineumaRk_markers.md§3.1) le quadre e le virgolette portano semantica strutturale, non una cornice:[…]= sezione (target di PLAY/FORM, delimita scope collassabili),"…"= annotazione (testo descrittivo, non strutturale). Il modello a cornice di §2.1 non si applica inM). Una sezione scritta["NOME"]vale[NOME]: le virgolette delimitano il nome e non ne fanno parte.
2. Container testuali¶
2.1 Forme: il modello a cornice¶
Un container testuale è un testo fra virgolette "…" con una
cornice facoltativa attorno:
| Forma | Cornice | Note |
|---|---|---|
"testo" |
nessuna | |
["testo"] |
riquadro | forma di riferimento |
[testo] |
riquadro | abbreviazione di ["testo"]: stesso risultato |
("testo") |
tonda | una coppia di parentesi attorno al testo |
Le virgolette di ["…"] e ("…") delimitano il testo e non compaiono
mai nella resa: ["testo"] e [testo] producono lo stesso riquadro.
Il modello vale per tutti i container di §2.2 che lo indicano: label
d'accordo (di accordo, di gruppo, di riga), testi di A) (sulla nota, alla
stanghetta, sopra C)), testi di D) (sulla nota, alla stanghetta),
annotazioni di nota ed end-decorator testuali. Restano fuori, con la loro
sintassi: sezione e annotazione di M) (vedi l'eccezione in §1), label di
onda e di staffa d'analisi (~"…", {"…"), label dei box PLAY)/FORM).
Dentro la cornice il testo è un container normale: markup (§3), a-capo ;
(§3bis, una sola cornice attorno all'intera pila), link (§3quater),
escape \" (§4).
Riconoscimento della tonda. È una cornice solo la forma esatta
("…"): ( seguita subito da ", e la " di chiusura seguita subito da
). Ogni altra ( conserva il significato del suo contesto: legatura in
A) (("dolce" … ) è una legatura che parte con un testo), gruppo di
accordi opzionali o durata in C). In D) le parentesi non hanno altro
significato: una ( o ) fuori da ("…") è ignorata e segnalata con
W177.
2.2 Dove si applica il markup¶
Il markup definito in questo documento si applica a tutti i container testuali del linguaggio:
| Costrutto | Container ammessi | Riferimento |
|---|---|---|
Sezione M) |
[…] (strutturale) |
neumaRk_markers.md §3.1 |
Annotazione M) |
"…" |
neumaRk_markers.md §3.1 |
| End-decorator testuale | modello a cornice | neumaRk_flow_and_repeats.md §4.3 |
| Comment-label chord / group / row | modello a cornice | neumaRk_chords.md §8 |
| Annotation note | modello a cornice | neumaRk_notes_and_durations.md §8 |
Annotation dinamiche D) |
modello a cornice | neumaRk_dynamics.md §3.4 |
Testo A) (nota, stanghetta, sopra C)) |
modello a cornice | neumaRk_articulations.md §13.1 |
Label articolazione A) (onda, staffa) |
"…" |
neumaRk_articulations.md §10.2/§10.3 |
| Top/bottom label box di sezione | "…" |
neumaRk_play_and_form.md §3.3 |
Prosa libera in PLAY) / FORM) |
tutta la prosa | neumaRk_play_and_form.md §5 |
Prosa libera in TEXT) |
tutta la prosa | neumaRk_text_line.md §3 |
Il markup non si applica a:
- valori dell'header (titolo, credits, year, style, key, meter, BPM), che sono renderizzati in modo autonomo dal sistema;
- nomi tecnici dei marker quando referenziati in
PLAY)/FORM), dove il matching è per text-equality (il markup, se presente, è applicato in display ma stripped per il matching); - volta begin (
|[1.]), che è un container simil-box predeterminato e non ammette markup interno.
3. Sintassi del markup¶
Il markup neumaRk è un sottoinsieme di Markdown, scelto per essere deterministico e single-line.
3.1 Dimensione del testo¶
I 3 prefissi #/##/### selezionano una dimensione relativa che
dipende dal ruolo size del costrutto (vedi §5):
- role
reduced(default per: comment-label chord/group/row, annotation note, annotation D), label PLAY/FORM, annotation marker"…"): il default è la dimensione media;###scende al piccolo,#sale al grande. - role
body(default per: markerM)[NAME], prosa PLAY/FORM): il default è la dimensione media; i prefissi scalano SOPRA e SOTTO.
| Prefisso | role reduced |
role body |
|---|---|---|
# |
grande (1.33× default) | grande (1.5× default) |
## |
medio (= default, no prefix) | medio (1.0× default = body) |
### |
piccolo (0.67× default) | piccolo (0.7× default) |
Resa di riferimento (informativa): i fattori fra parentesi sono quelli dell'implementazione di riferimento. Normativi sono i tre gradi (grande, medio, piccolo) e il default medio.
Regole:
- lo spazio dopo
#/##/###è obbligatorio:#hashtagè letterale,# titleapre lo span; - il prefisso compare solo all'inizio del testo del container o
all'inizio di un run di prosa (in
PLAY)/FORM), dopo un token strutturale o all'inizio del body); - lo span aperto da
#/##/###si chiude al primo dei seguenti eventi: fine del container, prossimo token strutturale inPLAY)/FORM)([…],&kw,$,@); ####e oltre sono trattati come letterali;##è ammesso per esplicitare il livello size anche se ridondante col default (in entrambi i role il medio coincide col no-prefix).
3.2 Enfasi¶
Tre forme di emphasis, attivate da delimitatori in coppia:
| Sintassi | Effetto |
|---|---|
*foo* |
italic |
**foo** |
bold |
***foo*** |
bold + italic |
Regole:
- gli span sono delimitatori chiusi: un
*non chiuso è letterale (nessun render parziale); - l'asterisco chiudente deve essere preceduto da contenuto non vuoto;
- gli span possono comparire in qualunque posizione del testo;
- non è ammesso annidamento di emphasis (per esempio
**foo *bar* baz**non è valido): la forma***foo***è atomica.
3.3 Underline¶
Sintassi attivata dal doppio underscore:
| Sintassi | Effetto |
|---|---|
__foo__ |
underline |
Regole:
- come gli span di emphasis, lo span è delimitatore chiuso: un
__non chiuso è letterale; - il
__chiudente deve essere preceduto da contenuto non vuoto; - lo span può comparire in qualunque posizione del testo;
- underscore singolo
_è letterale:_x_non è italic alternativo (NRK non adotta la convenzione Markdown di_come alias di*); ___foo___(tre o più underscore di apertura/chiusura) è trattato come letterale, analogamente a####per i prefissi di dimensione.
Underline non è una forma di emphasis: è un asse ortogonale a bold/italic. La regola "non annidamento di emphasis" di §3.2 non si applica all'underline.
3.4 Combinazione¶
Più span di emphasis possono coesistere nello stesso testo, purché disgiunti:
*foo* and **bar** ✓ italic + bold disgiunti
*foo and **bar*** ✗ annidamento non ammesso
***foo*** plain ***bar*** ✓ due span bold-italic disgiunti
L'underline è un asse ortogonale: può coesistere con bold e italic nello stesso span:
**__foo__** ✓ bold + underline
*__foo__* ✓ italic + underline
***__foo__*** ✓ bold + italic + underline
__**foo**__ ✓ ordine delimitatori libero
__*foo* and **bar**__ ✓ underline su span con emphasis disgiunti interni
Uno span di emphasis o underline può coesistere con un prefisso di dimensione: il prefisso vale per l'intero span del testo, gli altri delimitatori modificano solo la porzione interna:
# Title with **bold** and __underline__ words
3bis. A-capo ; (testo multi-riga)¶
Dentro ogni container testuale (§2), in entrambe le forme "…" e
[…] e con qualunque cornice (["…"], ("…")), un ; non escapato è
un a-capo: il contenuto si compone di più righe. Per un ;
letterale si usa l'escape \; (§4).
c4"ten.;trp." → 2 righe: "ten." / "trp."
c4("in 3\;4") → 1 riga: "in 3;4" (';' letterale)
c4"r1;r2;r3" → 3 righe
M) | "poco;a poco" | → 2 righe: "poco" / "a poco"
C) | C7"alt;b9" | → 2 righe: "alt" / "b9"
La regola vale allo stesso modo per "…" e per […]: le due forme
differiscono solo per il riquadro (§2.1), quindi passare da C7"a;b" a
C7[a;b] non cambia l'a-capo.
Perché ;. Un container occupa una sola riga del sorgente (§6.2):
l'a-capo del file non è disponibile, e serve un separatore. Il ; è
inerte dentro il container (il parser ne conserva l'intero contenuto),
raro come carattere letterale in un'etichetta e senza significato
altrove in neumaRk. Un ; dentro l'indirizzo di un link [testo=>url] è
parte dell'indirizzo e non va a capo (§3quater).
Esclusioni. Non sono container d'a-capo, e il ; vi resta letterale:
- il nome di sezione
M) [NOME]: è il bersaglio diPLAY)/FORM)per uguaglianza di testo (stessa ragione per cui non ammette link); - l'etichetta di versione
%%NAME "…": è il nome della variante; - l'etichetta di
INFO): sta su una riga sola; - volta
|[1.], valori d'header e sillabeL), che non portano markup.
Nella prosa di TEXT) e di INFO) il ; è un carattere come gli altri.
La prosa di questi blocchi non è un container: occupa più righe del sorgente e
va a capo sull'a-capo del sorgente, quindi non le serve un separatore. Due
regole, ciascuna con la sua ragione: fra le righe del sorgente l'a-capo; dentro
un container, che deve stare su una riga sola, il ;.
In PLAY)/FORM) il ; va a capo anche nella prosa. Lì l'a-capo del
sorgente vale uno spazio (neumaRk_play_and_form.md §6), quindi l'unico modo di
andare a capo in un punto preciso è il ;, come nei container: ogni ; non
escapato chiude la riga di box e prosa (§6.3), e \; stampa un ;.
Resa multi-riga. Il primo segmento è sempre la riga in alto:
si legge dall'alto in basso. La riga più vicina al rigo resta dove sarebbe
la riga singola e la pila si allontana dal rigo: sopra il rigo
(annotazioni di nota, di M) e di A), label della banda accordi, label di
onda e staffa, end-decorator) cresce verso l'alto, e l'ultima riga resta ferma;
sotto il rigo (annotazione D)) cresce verso il basso, e la prima riga resta
ferma. Con una riga sola la resa non cambia. L'interlinea è
la stessa ovunque (nella resa di riferimento 1,18 × la dimensione più grande
fra le righe), e una riga
vuota (a;;b) resta vuota. Il markup di §3 si applica per riga:
("**ten.**;trp."). Con una cornice, una sola cornice avvolge l'intera
pila (non una per riga).
Ogni riga conserva l'allineamento del container: centrata dove il testo è
centrato (comment-label d'accordo e di gruppo, annotazione A) su una sigla),
a sinistra dove è ancorato a sinistra (annotazione M), annotazione A) sulla
nota, label di riga, label a lato di C-7"…"-, label di onda e staffa {…}),
a destra dove è appeso al bordo destro della misura (end-decorator, A) e D)
alla stanghetta di fine misura). Un testo
impilato sopra un altro (label di gruppo, annotazione A), label di riga)
scavalca la pila intera di quello sotto, non solo la sua ultima riga. Una
linea tratteggiata di prolungamento resta agganciata alla riga più vicina
al rigo, per quota e per partenza.
Copertura della resa. Ogni container disegna il ; su più righe:
annotazioni di nota e di M), D), A) (alla nota e alla stanghetta),
comment-label d'accordo, di gruppo e di riga, testi sugli accordi, label di onda
e staffa d'analisi, end-decorator testuali, label dei box PLAY)/FORM), voci
di FOOT). Le label dei box PLAY)/FORM) vanno anche a capo per larghezza,
riga per riga, e la label sotto il box cresce verso il basso (la sua riga
più vicina al box è la prima).
Sorgente vs contenuto — la riga sorgente resta single-line (nessun carattere di nuova riga nel file: vedi §6.2); è il contenuto del container a essere multi-riga, diviso sui
;.
3ter. Richiamo footnote [^etichetta]¶
Il markup ammette il richiamo a nota a piè di pagina [^etichetta]: un
piccolo segno reso in apice dentro il testo, che rimanda a una definizione
del blocco globale FOOT). La grammatica completa (etichette, blocco FOOT),
ripetizione multi-pagina, diagnostici W162–W166) è in
neumaRk_footnotes.md. In sintesi:
[^*][^†][^1]= etichetta esplicita (segno = simbolo/numero);[^]= auto-numerato.- Riconosciuto come richiamo solo dentro
"…"per i container note/accordi/ marker e i testi diA)/D)(dove[NAME]è strutturale), anche dentro una cornice (["…"],("…")), non nell'abbreviazione[…], dove la]del richiamo chiuderebbe il container:c4[a[^1]]non è valido (E001), si scrivec4["a[^1]"]; nella prosaPLAY)/FORM)/TEXT)(non quotata) vale sull'intero testo. L'escape\[resta parentesi letterale. - NON collide con il corsivo
*…*(per questo si usa la cornice[^…]).
c4("piano[^*]")
3quater. Link esterno [testo=>url]¶
Il markup ammette un link a materiale esterno: il video da cui è tratta una trascrizione, una voce d'enciclopedia, la pagina di un autore.
| Forma | Si vede | Porta a |
|---|---|---|
[testo=>url] |
testo |
url |
[=>url] |
il dominio (it.wikipedia.org, senza www.) |
url |
TEXT) Trascrizione dal [live a Montreux=>https://www.youtube.com/watch?v=abc123]
TEXT) Vedi [=>https://it.wikipedia.org/wiki/Bill_Evans]
C) | Cm7"cfr. [la fonte=>https://example.org/lp]" | F7 |
Regole:
- il testo si separa dall'indirizzo al primo
=>; - nel testo vale il markup di §3 (
[*Montreux* **1978**=>…]); nell'indirizzo no: è letterale fino alla]._,__,*,#,;e//nell'indirizzo sono caratteri dell'indirizzo — nessun sottolineato, nessun a-capo (§3bis), nessun commento; - una
]dentro l'indirizzo si scrive\]: è l'unico escape risolto nell'indirizzo; - schemi ammessi: solo
http://ehttps://, senza spazi (uno spazio si scrive%20). Un indirizzo con un altro schema (mailto:,ftp:…), relativo o con spazi non è un link: resta il testo, non attivabile (W175). Un link vuoto —[testo=>]o[=>]— lascia il testo, se c'è (W176); \[testo=>url]è testo letterale, reso com'è scritto (§4): serve a mostrare la sintassi. Anche qui il//dell'indirizzo non apre un commento;- il dominio della forma breve è ricavato alla resa: il documento conserva l'indirizzo intero.
Dove vale. Stessa regola di riconoscimento del richiamo [^…] (§3ter): dentro
"…" per note, accordi, testi di A)/D) e annotazioni di marker; sull'intero testo per la prosa
di TEXT), PLAY) e FORM), per etichetta e corpo di INFO) e per le voci di
FOOT). In PLAY)/FORM) un […] che contiene => è un link, mai un box di
sezione. Il link non vale nei nomi di sezione M) [NOME], che sono il
bersaglio di PLAY)/FORM) per uguaglianza di testo, né nelle sillabe L).
Resa. Il link è una proprietà del testo, non del contenuto musicale. A
schermo il testo è reso come link — distinto dal sottolineato __…__ — e può
essere attivato. In stampa e in PDF esce come testo normale, senza stile da link
e senza collegamento.
4. Escape¶
Il carattere \ (backslash) precede un meta-carattere per renderlo
letterale.
| Token | Forma escaped |
|---|---|
* |
\* |
_ |
\_ |
# |
\# |
[ |
\[ |
] |
\] |
" |
\" |
; |
\; |
\ |
\\ |
L'escape \_ serve quando si vuole inserire un __ letterale in un
testo che dovrebbe esserne consumato dal markup (raro: i singoli _
sono già letterali by default).
Esempi:
M) | [The \*Real\* Book] |
c4"track \#3"
Un \ non seguito da un meta-carattere è letterale.
Gli escape valgono in qualunque testo che ammette markup: nei container
e nella prosa. In particolare \; scrive un ; anche dove il ; è già
letterale (prosa, nomi di sezione), così la stessa scrittura funziona
ovunque. L'unica eccezione è l'indirizzo di un link, dove si risolve solo
\] (§3quater).
Dentro un container "…" (con qualunque cornice) \" non chiude il testo:
c4"il \"Re\"" → il "Re"
C) | C("a \"tempo\"") | → (a "tempo")
L'header (titolo, credits, style) non è testo con markup: lì " e \ sono
letterali e non si escapano (neumaRk_header.md §5).
5. Stile di default per costrutto¶
La cornice (nessuna, riquadro, tonda) decide solo la grafica attorno al testo. Lo stile di default (size, weight, italic) è proprietà del costrutto ospitante.
| Costrutto | Default style |
|---|---|
Marker M) [NAME] |
bold, size body (role body, vedi §3.1) |
Annotation marker M) "…" |
plain, size media (role reduced) |
| End-decorator testuale | plain, size body (role body) |
| Comment-label chord / group / row | plain, size media (role reduced) |
| Annotation note | plain, size media (role reduced) |
Annotation dinamiche D) |
plain, size media (role reduced) |
| Top/bottom label box PLAY/FORM | plain, size media (role reduced) |
| Prosa PLAY/FORM | plain, size body (role body) |
Prosa TEXT) |
plain, size body (role body) |
Il role size decide come i prefissi #/##/### scalano attorno al
default (vedi §3.1 tabella). In entrambi i role il default è la size media
e ### scende SOTTO (piccolo); il role reduced differisce solo per
quanto sale # (nella resa di riferimento 1.33× invece di 1.5×).
Il markup utente (§3) sovrascrive sempre il default. Per esempio un
comment-label parte plain: chord"sub" è reso tondo, mentre
chord"*sub*" accende l'italic via markup sopra quel default.
6. Regole di parsing¶
6.1 Disambiguazione […] e ( per ruolo¶
In neumaRk il delimitatore […] è condiviso fra più costrutti
(polychord, volta, end-decorator, comment-label, annotation note,
grace block, ecc.). La disambiguazione è posizionale e definita
nelle spec dei singoli costrutti. Una volta che il parser ha
identificato il ruolo del […], il contenuto è interpretato secondo
le regole di questo documento.
La ( è cornice tonda solo nella forma esatta ("…") (§2.1); altrove
mantiene il ruolo del suo costrutto (legatura, gruppo opzionale, durata,
oggetto di contesto, play directive).
6.2 Single-line nel sorgente, multi-riga nel contenuto¶
I container "…", […], ["…"], ("…") occupano una sola riga sorgente:
non ammettono caratteri di nuova riga nel file. Un container aperto e non
chiuso nella sua misura (una ", [ o (" senza chiusura prima della
stanghetta) legge come testo il resto della misura: nelle righe N), A),
D) e M) il parser lo segnala con W133 (in N) le note che seguono
nella misura si perdono: c4"abc d e f | conserva solo c4); nella riga
accordi il token non è riconosciuto (E102).
Il contenuto però può essere multi-riga: l'a-capo si esprime col
separatore ; (§3bis), non con un newline nel sorgente. Così una singola
riga N) resta allineata a colonne con le altre righe del datapack anche
quando l'annotazione si rende su più righe.
La prosa di PLAY) / FORM) ammette continuazione di riga (vedi
documenti correlati).
6.3 Container vuoti¶
[] e "" sono letterali: non vengono interpretati come container.
7. Casi limite¶
7.1 Markup nei nomi di reference¶
Dentro [NAME] di reference in PLAY) / FORM), il NAME è
interpretato come testo. Il markup interno è applicato in display
ma rimosso prima del matching con i marker definiti:
PLAY) [**Solo**] [A]
[**Solo**] cerca un marker chiamato "Solo" e lo rende in bold se
trovato. Se il NAME contiene markup non chiuso o malformato, il
fallback è il matching letterale comprensivo dei caratteri di markup.
7.2 Spazi attorno ai delimitatori di emphasis e underline¶
A differenza di Markdown standard, neumaRk non richiede che i
delimitatori (*, __) siano "tight" rispetto al contenuto: * foo *
è equivalente a *foo*, __ foo __ è equivalente a __foo__. La
scelta riduce errori comuni e mantiene il markup più tollerante.
7.3 Cornici diverse nello stesso documento¶
Nei costrutti col modello a cornice le forme si mescolano liberamente, anche sulla stessa riga. La scelta è guidata solo dalla grafica voluta.
C) | C"freely" | F[swing] | G["a tempo"] | C("rit.") |
8. Riassunto¶
| Asse | Valori | Decide |
|---|---|---|
| Container | "…" / ["…"] ([…]) / ("…") |
nessuna cornice / riquadro / tonda |
| Costrutto | marker, label, annotation, … | size + weight + italic di default |
| Markup utente | *…*, **…**, __…__, # …, […=>url], ecc. |
override esplicito |
I tre assi sono ortogonali. Nessuno dei tre vincola gli altri.
9. Diagnostici¶
| Codice | Condizione |
|---|---|
| E102 | Container non chiuso su una riga accordi (§6.2) |
| W133 | Container non chiuso nella misura su N), A), D), M): il resto della misura è testo (§6.2) |
| W175 | Link con indirizzo non http/https o malformato: resta il testo (§3quater) |
| W176 | Link vuoto [testo=>] / [=>] (§3quater) |
| W177 | In D), parentesi fuori da una cornice ("…"): ignorate (§2.1) |
I diagnostici dei richiami [^…] (W162–W166) sono in neumaRk_footnotes.md.
Questo documento definisce il sistema di formattazione testuale unificato di neumaRk, applicabile a tutti i container testuali del linguaggio.