Le liste di attività in Markdown e cosa viene reso davvero e dove
Pubblicato il 02/07/2025 · 12 min di lettura · Strumenti testo e lingua
Daniel Okonkwo — Sviluppatore front-end e redattore Tech presso Allin
Performance web · Formati di file
Verificato su 4 fonti
Una lista di attività in Markdown — un elemento di elenco che inizia con [ ] o [x] — non fa parte di CommonMark. Abbiamo cercato nella specifica CommonMark 0.31.2 del 28 gennaio 2024: le espressioni «task list» e «checkbox» vi compaiono zero volte. Le liste di attività sono definite nella specifica GitHub Flavored Markdown 0.29-gfm del 6 aprile 2019, sezione 5.3, come estensione. È tutta qui la spiegazione del fatto che lo stesso file mostri caselle su GitHub e parentesi quadre letterali altrove. Abbiamo passato una riga, «- [ ] comprare il latte», per quattro motori: solo quello di sapore GitHub ha prodotto un elemento input di tipo checkbox; l'implementazione di riferimento CommonMark e altre due configurazioni hanno prodotto un elemento di elenco con il testo letterale [ ] comprare il latte. La regola del marcatore è esatta e poco indulgente: una sequenza facoltativa di spazi, una parentesi quadra aperta, o uno spazio o la lettera x in qualunque cassa, una parentesi quadra chiusa, e poi almeno uno spazio prima del contenuto. «- [x]comprare» senza spazio esce come testo ovunque, «- []» esce come testo e «- [ ]» con due spazi pure. La stessa prudenza vale per tabelle, testo barrato e collegamenti automatici, anch'essi estensioni, e per le note a piè di pagina, che non stanno in nessuna delle due specifiche.
Le liste di attività non sono in CommonMark. Sono un'estensione di GitHub Flavored Markdown, ed è per questo che lo stesso file mostra caselle in un posto e parentesi quadre letterali in un altro. La regola esatta del marcatore, cosa fa l'annidamento e una tabella di cosa è CommonMark, cosa è GFM e cosa non è nessuno dei due — verificato su entrambe le specifiche e quattro motori di resa.
Una riga, quattro motori, due documenti diversi
Abbiamo preso una sola riga — un trattino, uno spazio, una coppia di parentesi quadre vuota, uno spazio e del testo — e l'abbiamo resa in quattro modi. Con l'analisi di sapore GitHub attiva diventa un elemento di elenco con un elemento input di tipo checkbox, disabilitato. Con la stessa libreria e il sapore spento, con l'implementazione di riferimento CommonMark e con una terza libreria nella sua configurazione predefinita, diventa un elemento di elenco con i caratteri [ ] seguiti dal testo. Nulla è fallito. Quattro motori corretti hanno prodotto due documenti diversi dallo stesso file.
La ragione è documentata, non misteriosa. Abbiamo cercato «task list» e «checkbox» nella specifica CommonMark 0.31.2 del 28 gennaio 2024: entrambe compaiono zero volte. La specifica GitHub Flavored Markdown 0.29-gfm del 6 aprile 2019 ha una sezione 5.3 intitolata «Task list items (extension)». La parola estensione fa tutto il lavoro in quel titolo: GFM è CommonMark più cinque aggiunte con nome, e un motore che implementa solo CommonMark non è rotto quando stampa le tue caselle come parentesi. È corretto.
La regola del marcatore, carattere per carattere
La sezione 5.3 di GFM definisce un elemento di lista di attività come un elemento il cui primo blocco è un paragrafo che inizia con un marcatore di lista di attività seguito da almeno uno spazio prima di qualsiasi altro contenuto. Il marcatore è un numero facoltativo di spazi, una parentesi quadra aperta, o uno spazio o la lettera x in minuscolo o maiuscolo, e una parentesi quadra chiusa. Ogni parola di quella frase porta peso, e i fallimenti sono silenziosi: abbiamo eseguito ogni violazione e tutte sono uscite come testo ordinario in tutti e quattro i motori.
Ometti lo spazio dopo la parentesi di chiusura e non succede nulla: «- [x]comprare il latte» è testo. Metti due spazi fra le parentesi e non succede nulla: il marcatore contiene esattamente un carattere. Lascia le parentesi vuote e non succede nulla. Usa una lettera diversa da x e non succede nulla. Sposta il marcatore dall'inizio del paragrafo — «- comprare [ ] il latte» — e non succede nulla. Togli l'elenco e «[ ] comprare il latte» è un paragrafo. Ciò che funziona è più generoso di quanto si creda: la lettera può essere una X maiuscola, il segno di elenco può essere un trattino, un asterisco o un più, l'elenco può essere numerato, e una tabulazione conta come lo spazio dopo la parentesi.
L'annidamento e la regola del primo blocco
Le liste di attività si annidano liberamente, e la specifica lo mostra con un esempio svolto. Abbiamo eseguito un elemento padre con due figli indentati: casella sul padre, elenco annidato dentro lo stesso elemento e casella su ogni figlio. Anche mescolare elementi spuntati, non spuntati e semplici punti elenco nella stessa lista funziona: l'elemento semplice resta semplice e quelli marcati diventano caselle, il che rende una checklist leggibile come un ordine del giorno misto.
Il requisito che il primo blocco sia un paragrafo si viola facilmente. Metti una citazione all'inizio — «- > [ ] citato» — e nessun motore produce una casella, incluso quello di sapore GitHub, perché il primo blocco è una citazione e il marcatore non ha mai la sua occasione. Aggiungi un secondo paragrafo dopo quello marcato e la casella sopravvive, collocata prima del primo paragrafo, con il secondo che segue nello stesso elemento. Non sono stranezze del motore: discendono direttamente dalla frase della sezione 5.3.
Le estensioni vicine, e una che non è in nessuna specifica
Le tabelle sono la sezione 4.10 della specifica GFM, anch'esse un'estensione. La nostra tabella a barre di tre righe è uscita come vero elemento table sotto l'analisi di sapore GitHub e sotto le impostazioni predefinite di un'altra libreria, e come un unico paragrafo di barre letterali sotto l'implementazione di riferimento CommonMark. Il barrato è la sezione 6.5, ed è più strano di quanto sembri: la specifica ammette una o due tilde, quindi ~qui~ è barrato, ma tre o più no, quindi ~~~no~~~ resta letterale. Una libreria testata barrava con due tilde ma non con una, ed emetteva un elemento di testo barrato invece dell'elemento di testo eliminato mostrato dalla spec. GFM. Due motori possono entrambi supportare il barrato e continuare a non essere d'accordo sull'input e sull'output.
I collegamenti automatici esistono in due forme e solo una è nativa. Un indirizzo fra parentesi angolari è CommonMark ed è diventato un collegamento in ogni motore provato. Un indirizzo nudo è la sezione 6.9 di GFM, un'estensione con regole proprie: lo schema http viene inserito davanti a un indirizzo www e la punteggiatura finale resta fuori dal collegamento, così «Visita www.commonmark.org.» collega l'indirizzo e lascia fuori il punto. Solo la configurazione di sapore GitHub ha prodotto quei collegamenti; le altre hanno lasciato il testo com'era.
Le note a piè di pagina sono il caso istruttivo, perché non stanno in nessuna delle due specifiche. La parola footnote compare esattamente una volta nella spec. CommonMark ed esattamente una volta in quella GFM, nella stessa frase storica dell'introduzione sulle implementazioni che aggiunsero convenzioni per note e tabelle. Tutti e quattro i nostri motori hanno lasciato [^1] come testo letterale e trasformato la riga di definizione in un paragrafo orfano. GitHub stesso rende le note a piè di pagina, ed è esattamente questa la trappola: una funzione che hai visto funzionare non è per questo nel formato.
«Markdown» non è un formato
Due specifiche con numeri di versione diversi e cinque anni di distanza, più un insieme di opzioni per libreria, non fanno un formato unico. I disaccordi scendono ben sotto il livello delle funzioni. Di fronte a un ritorno a capo duro, due dei nostri motori hanno emesso un tag di interruzione autochiudente e due la forma HTML5. Di fronte a un elemento script nel sorgente, due l'hanno passato tale e quale all'output e uno l'ha mascherato come testo; la spec. GFM dedica un'intera estensione, la sezione 6.11, a filtrare nove tag precisi sostituendo la loro parentesi angolare di apertura con un'entità. Niente di tutto ciò è un bug.
La regola pratica che ne segue è breve: scrivi per il motore che davvero prendi di mira, e sappi quale sia. Un README su una piattaforma di codice, un generatore di siti di documentazione, un client di chat e un costruttore di siti statici sono quattro destinazioni con quattro insiemi di funzioni, e un documento che appare bene in una non offre alcuna garanzia sulle altre. Se la destinazione è ignota, resta dentro CommonMark: titoli, enfasi, elenchi, codice, collegamenti, collegamenti automatici fra parentesi angolari e citazioni sono uguali ovunque.
Verifica l'andata e ritorno, e conta dalla sorgente
Il test più economico di una checklist è l'aritmetica. Abbiamo scritto un elenco di sprint annidato da cinque elementi, due marcati come fatti, li abbiamo contati dalla sorgente markdown con un modello che riconosce il marcatore a inizio elemento e abbiamo ottenuto 2 su 5. Rendendo lo stesso documento con analisi di sapore GitHub e contando gli elementi input spuntati nell'HTML si ottiene ancora 2 su 5. Rendendolo con l'implementazione di riferimento CommonMark si ottengono zero elementi input — il documento è intatto, le caselle semplicemente non sono mai state una funzione di quel dialetto.
È questa l'abitudine da tenere: conta dalla sorgente, non dalla resa. Il file markdown è il registro; l'HTML ne è un'interpretazione, e quale ne ottieni dipende da una versione di libreria e da un flag. Il nostro generatore di checklist scrive il marcatore GFM esattamente come lo specifica la sezione 5.3 — punto elenco, spazio, parentesi, un carattere, parentesi, spazio — così il file funziona dove l'estensione è supportata e degrada a un elenco con parentesi leggibile dove non lo è. Se hai bisogno che la casella sopravviva ovunque, l'alternativa onesta è un elenco semplice con la parola «fatto» dentro.
| Funzione | In CommonMark 0.31.2? | Nella spec. GFM 0.29? | Output dell'implementazione di riferimento | Output di markdown-it predefinito |
|---|---|---|---|---|
| Lista di attività - [ ] / - [x] | No — 0 menzioni | Sì — sezione 5.3, estensione | [ ] letterale nell'elemento di elenco | [ ] letterale nell'elemento di elenco |
| Tabella con barre | No | Sì — sezione 4.10, estensione | Un paragrafo di barre letterali | Un vero elemento table |
| Barrato con due tilde | No | Sì — sezione 6.5, estensione | Tilde letterali | Un elemento barrato, ma s invece di del |
| Barrato con una tilde | No | Sì — una o due tilde | Tilde letterali | Tilde letterali — ne richiede due |
| URL nudo trasformato in collegamento | No | Sì — sezione 6.9, estensione | Testo semplice | Testo semplice nelle configurazioni provate |
| Collegamento automatico fra parentesi angolari | Sì — parte della specifica di base | Sì, ereditato | Un vero collegamento | Un vero collegamento |
| Nota a piè di pagina [^1] | No | No — nemmeno nella specifica | [^1] letterale e una riga di definizione orfana | [^1] letterale e una riga di definizione orfana |
| HTML grezzo lasciato passare | Sì, per default | Sì, meno nove tag filtrati | Passato invariato | Mascherato come testo |
Domande frequenti
- Perché le mie caselle appaiono come [ ] invece che come caselle?
- Perché il motore implementa CommonMark senza le estensioni GitHub. Le liste di attività sono la sezione 5.3 della spec. GFM e non compaiono da nessuna parte in CommonMark 0.31.2. La seconda possibilità è un marcatore malformato: lo spazio dopo la parentesi di chiusura è obbligatorio, fra le parentesi va esattamente un carattere, e il marcatore deve aprire il primo paragrafo dell'elemento. Tutti questi errori escono come testo letterale senza alcun avviso.
- La x deve essere minuscola?
- No. La spec. GFM dice la lettera x in minuscolo o maiuscolo, e abbiamo confermato che entrambe producono una casella spuntata. Nessun'altra lettera funziona: una o fra le parentesi è uscita come testo letterale in ogni motore provato. Nemmeno due caratteri sono ammessi — un marcatore con due spazi fra le parentesi non è un marcatore.
- Le liste di attività si possono annidare o usare in un elenco numerato?
- Entrambe. La spec. GFM mostra liste di attività annidate liberamente in un esempio svolto, e la nostra esecuzione ha prodotto una casella sul padre e su ogni figlio indentato. Un elemento di elenco numerato funziona allo stesso modo — il marcatore sta dopo il numero e il punto. Ciò che non funziona è un elemento il cui primo blocco non sia un paragrafo: una citazione prima del marcatore ha soppresso la casella in ogni motore.
- Tabelle e barrato si possono usare ovunque?
- No. Entrambe sono estensioni GFM, sezioni 4.10 e 6.5, e nessuna è in CommonMark. La nostra tabella è uscita come vera tabella in due configurazioni e come paragrafo di barre letterali in un'altra. Il barrato è peggio: la spec. GFM barra il testo racchiuso fra una o due tilde ma non fra tre, mentre un'altra libreria molto usata ne richiedeva due e produceva un elemento HTML diverso per il risultato.
- Le note a piè di pagina fanno parte di GitHub Flavored Markdown?
- Secondo la specifica GFM pubblicata, no. La parola footnote vi compare esattamente una volta, in una frase storica dell'introduzione, e non esiste alcuna sezione sulle note. Il sito di GitHub le rende comunque, il che illustra bene la differenza fra una specifica e un prodotto. Tutti e quattro i motori provati hanno lasciato il richiamo come testo letterale e la definizione come paragrafo orfano.
Articoli che potrebbero interessarti
Tutte le guide →Strumenti correlati
Fonti
- CommonMark — CommonMark Spec, version 0.31.2 (2024-01-28) — the core grammar, which contains no task lists, tables, strikethrough or footnotes
- GitHub — GitHub Flavored Markdown Spec, version 0.29-gfm (2019-04-06) — sections 4.10 Tables, 5.3 Task list items, 6.5 Strikethrough, 6.9 Autolinks, 6.11 Disallowed Raw HTML
- CommonMark — The CommonMark project — reference implementations and the Dingus for testing a document against the core spec
- GitHub Docs — Basic writing and formatting syntax — the features GitHub renders beyond its own published specification, including footnotes
Hai notato un errore in questo articolo?