Les listes de tâches Markdown et ce qui s'affiche vraiment où
Publié le 02/07/2025 · 12 min de lecture · Outils texte & langage
Daniel Okonkwo — Développeur front-end et rédacteur Tech chez OneKitly
Performance web · Formats de fichiers
Vérifié à partir de 4 sources
Une liste de tâches Markdown — un élément de liste commençant par [ ] ou [x] — ne fait pas partie de CommonMark. Nous avons cherché dans la spécification CommonMark 0.31.2 du 28 janvier 2024 : les expressions « task list » et « checkbox » y apparaissent zéro fois. Les listes de tâches sont définies dans la spécification GitHub Flavored Markdown 0.29-gfm du 6 avril 2019, section 5.3, comme une extension. Voilà toute l'explication du fait que le même fichier affiche des cases à cocher sur GitHub et des crochets littéraux ailleurs. Nous avons passé une ligne, « - [ ] acheter du lait », dans quatre moteurs : seul celui à saveur GitHub a produit un élément input de type checkbox ; l'implémentation de référence CommonMark et deux autres configurations ont produit un élément de liste contenant le texte littéral [ ] acheter du lait. La règle du marqueur est exacte et sans indulgence : une suite facultative d'espaces, un crochet ouvrant, soit une espace soit la lettre x dans l'une ou l'autre casse, un crochet fermant, puis au moins une espace avant le contenu. « - [x]acheter » sans espace s'affiche en texte partout, « - [] » s'affiche en texte, et « - [ ] » avec deux espaces aussi. La même prudence vaut pour les tableaux, le texte barré et les liens automatiques, également des extensions, et pour les notes de bas de page, absentes des deux spécifications.
Les listes de tâches ne sont pas dans CommonMark. C'est une extension de GitHub Flavored Markdown, d'où des cases à cocher ici et des crochets littéraux là. La règle exacte du marqueur, l'effet de l'imbrication, et un tableau de ce qui est CommonMark, GFM ou ni l'un ni l'autre — vérifié sur les deux spécifications et quatre moteurs de rendu.
Une ligne, quatre moteurs, deux documents différents
Nous avons pris une seule ligne — un tiret, une espace, une paire de crochets vides, une espace, du texte — et l'avons rendue de quatre façons. Avec l'analyse à saveur GitHub activée, elle devient un élément de liste contenant un élément input de type checkbox, désactivé. Avec la même bibliothèque, saveur désactivée, avec l'implémentation de référence CommonMark, et avec une troisième bibliothèque dans sa configuration par défaut, elle devient un élément de liste contenant les caractères [ ] suivis du texte. Rien n'a échoué. Quatre moteurs corrects ont produit deux documents différents à partir d'un même fichier.
La raison est documentée, pas mystérieuse. Nous avons cherché « task list » et « checkbox » dans la spécification CommonMark 0.31.2 du 28 janvier 2024 : les deux apparaissent zéro fois. La spécification GitHub Flavored Markdown 0.29-gfm du 6 avril 2019 comporte une section 5.3 intitulée « Task list items (extension) ». Le mot extension fait tout le travail dans ce titre : GFM est CommonMark plus cinq ajouts nommés, et un moteur qui n'implémente que CommonMark n'est pas cassé quand il affiche tes cases à cocher en crochets. Il est correct.
La règle du marqueur, caractère par caractère
La section 5.3 de GFM définit un élément de liste de tâches comme un élément dont le premier bloc est un paragraphe commençant par un marqueur de liste de tâches suivi d'au moins une espace avant tout autre contenu. Le marqueur est un nombre facultatif d'espaces, un crochet ouvrant, soit une espace soit la lettre x en minuscule ou en majuscule, et un crochet fermant. Chaque mot de cette phrase porte, et les échecs sont silencieux : nous avons exécuté chaque violation, et toutes se sont affichées en texte ordinaire dans les quatre moteurs.
Omets l'espace après le crochet fermant et rien ne se passe : « - [x]acheter du lait » est du texte. Mets deux espaces entre les crochets et rien ne se passe : le marqueur tient exactement un caractère. Laisse les crochets vides et rien ne se passe. Utilise une lettre autre que x et rien ne se passe. Déplace le marqueur hors du début du paragraphe — « - acheter [ ] du lait » — et rien ne se passe. Supprime la liste et « [ ] acheter du lait » est un paragraphe. Ce qui marche est plus généreux qu'on ne croit : la lettre peut être un X majuscule, la puce peut être un tiret, un astérisque ou un plus, la liste peut être numérotée, et une tabulation compte comme l'espace après le crochet.
L'imbrication, et la règle du premier bloc
Les listes de tâches s'imbriquent librement, et la spécification le montre par un exemple traité. Nous avons exécuté un élément parent avec deux enfants indentés : case à cocher sur le parent, liste imbriquée à l'intérieur du même élément, case à cocher sur chaque enfant. Mélanger des éléments cochés, non cochés et de simples puces dans la même liste fonctionne aussi : l'élément simple reste simple et les éléments marqués deviennent des cases, ce qui rend une checklist lisible comme un ordre du jour mixte.
L'exigence que le premier bloc soit un paragraphe se rate facilement. Mets une citation en tête — « - > [ ] cité » — et aucun moteur ne produit de case à cocher, y compris celui à saveur GitHub, parce que le premier bloc est une citation et que le marqueur n'a jamais sa chance. Ajoute un second paragraphe après celui marqué et la case survit, placée avant le premier paragraphe, le second suivant dans le même élément. Ce ne sont pas des bizarreries de moteur : cela découle directement de la phrase de la section 5.3.
Les extensions voisines, et une qui n'est dans aucune spécification
Les tableaux sont la section 4.10 de la spécification GFM, également une extension. Notre tableau à barres verticales de trois lignes est sorti en vrai élément table sous l'analyse à saveur GitHub et sous les réglages par défaut d'une autre bibliothèque, et en un seul paragraphe de barres littérales sous l'implémentation de référence CommonMark. Le barré est la section 6.5, et il est plus étrange qu'il n'y paraît : la spécification autorise un ou deux tildes, donc ~ici~ est barré, mais trois ou plus ne le sont pas, donc ~~~non~~~ reste littéral. Une bibliothèque testée barrait avec deux tildes mais pas un seul, et émettait un élément de texte barré plutôt que l'élément de texte supprimé montré par la spéc. GFM. Deux moteurs peuvent tous deux prendre en charge le barré et diverger sur l'entrée comme sur la sortie.
Les liens automatiques existent en deux formes et une seule est native. Une adresse entre chevrons est du CommonMark et est devenue un lien dans tous les moteurs testés. Une adresse nue relève de la section 6.9 de GFM, une extension avec ses propres règles : le schéma http est inséré devant une adresse en www, et la ponctuation finale est exclue du lien, si bien que « Visite www.commonmark.org. » lie l'adresse et laisse le point dehors. Seule la configuration à saveur GitHub a produit ces liens ; les autres ont laissé le texte tel quel.
Les notes de bas de page sont le cas instructif, parce qu'elles ne sont dans aucune des deux spécifications. Le mot footnote apparaît exactement une fois dans la spéc. CommonMark et exactement une fois dans la spéc. GFM, dans la même phrase historique de l'introduction, à propos des implémentations qui ont ajouté des conventions pour les notes et les tableaux. Nos quatre moteurs ont laissé [^1] en texte littéral et transformé la ligne de définition en paragraphe orphelin. GitHub, lui, affiche les notes, et c'est exactement le piège : une fonction que tu as vue marcher n'est pas pour autant dans le format.
« Markdown » n'est pas un format
Deux spécifications avec des numéros de version différents et cinq ans d'écart, plus un jeu d'options par bibliothèque, cela ne fait pas un format unique. Les désaccords descendent bien en dessous du niveau des fonctions. Sur une coupure de ligne dure, deux de nos moteurs ont émis une balise de saut auto-fermante et deux la forme HTML5. Sur un élément script dans la source, deux l'ont laissé passer tel quel dans la sortie et un l'a échappé en texte ; la spéc. GFM consacre une extension entière, la section 6.11, au filtrage de neuf balises précises en remplaçant leur chevron ouvrant par une entité. Rien de tout cela n'est un bug.
La règle pratique qui s'ensuit est courte : écris pour le moteur que tu vises réellement, et sache lequel c'est. Un README sur une forge, un générateur de site de documentation, un client de discussion et un constructeur de site statique sont quatre cibles avec quatre jeux de fonctions, et un document qui s'affiche correctement chez l'une n'offre aucune garantie chez les autres. Si la destination est inconnue, reste dans CommonMark : titres, emphase, listes, code, liens, liens automatiques entre chevrons et citations sont identiques partout.
Teste l'aller-retour, et compte depuis la source
Le test le moins cher pour une checklist est arithmétique. Nous avons écrit une liste de sprint imbriquée de cinq éléments, dont deux marqués faits, comptés depuis la source markdown avec un motif reconnaissant le marqueur en tête d'élément : 2 sur 5. Le rendu du même document en analyse à saveur GitHub, avec comptage des éléments input cochés dans le HTML, donne aussi 2 sur 5. Le rendu par l'implémentation de référence CommonMark donne zéro élément input — le document est intact, les cases n'ont simplement jamais fait partie de ce dialecte.
Voilà l'habitude à garder : compte depuis la source, pas depuis le rendu. Le fichier markdown est l'enregistrement ; le HTML n'en est qu'une interprétation, et laquelle tu obtiens dépend d'une version de bibliothèque et d'un drapeau. Notre générateur de checklist écrit le marqueur GFM exactement comme la section 5.3 le spécifie — puce, espace, crochet, un caractère, crochet, espace — de sorte que le fichier fonctionne là où l'extension est prise en charge et se dégrade en liste à crochets lisible là où elle ne l'est pas. S'il faut que la case survive partout, l'alternative honnête est une liste simple contenant le mot « fait ».
| Fonction | Dans CommonMark 0.31.2 ? | Dans la spéc. GFM 0.29 ? | Sortie de l'implémentation de référence | Sortie de markdown-it par défaut |
|---|---|---|---|---|
| Liste de tâches - [ ] / - [x] | Non — 0 mention | Oui — section 5.3, extension | [ ] littéral dans l'élément de liste | [ ] littéral dans l'élément de liste |
| Tableau à barres verticales | Non | Oui — section 4.10, extension | Un paragraphe de barres littérales | Un vrai élément table |
| Barré à deux tildes | Non | Oui — section 6.5, extension | Tildes littéraux | Un élément barré, mais s au lieu de del |
| Barré à un seul tilde | Non | Oui — un ou deux tildes | Tildes littéraux | Tildes littéraux — il en exige deux |
| URL nue transformée en lien | Non | Oui — section 6.9, extension | Texte brut | Texte brut dans les configurations testées |
| Lien automatique entre chevrons | Oui — dans la spéc. de base | Oui, hérité | Un vrai lien | Un vrai lien |
| Note de bas de page [^1] | Non | Non — absente de la spéc. aussi | [^1] littéral et une ligne de définition orpheline | [^1] littéral et une ligne de définition orpheline |
| HTML brut laissé passer | Oui, par défaut | Oui, moins neuf balises filtrées | Laissé passer tel quel | Échappé en texte |
Questions fréquentes
- Pourquoi mes cases s'affichent-elles en [ ] au lieu de cases ?
- Parce que le moteur implémente CommonMark sans les extensions GitHub. Les listes de tâches sont la section 5.3 de la spéc. GFM et n'apparaissent nulle part dans CommonMark 0.31.2. La seconde possibilité est un marqueur mal formé : l'espace après le crochet fermant est obligatoire, il faut exactement un caractère entre les crochets, et le marqueur doit ouvrir le premier paragraphe de l'élément. Tous ces échecs s'affichent en texte littéral sans aucun avertissement.
- Le x doit-il être en minuscule ?
- Non. La spéc. GFM dit la lettre x en minuscule ou en majuscule, et nous avons confirmé que les deux donnent une case cochée. Aucune autre lettre ne fonctionne : un o entre les crochets s'affiche en texte littéral dans tous les moteurs essayés. Il ne peut pas non plus y avoir deux caractères — un marqueur avec deux espaces entre les crochets n'est pas un marqueur.
- Les listes de tâches peuvent-elles être imbriquées ou numérotées ?
- Les deux. La spéc. GFM montre des listes de tâches imbriquées librement dans un exemple traité, et notre exécution a produit une case sur le parent et sur chaque enfant indenté. Un élément de liste numérotée fonctionne pareil — le marqueur se place après le nombre et le point. Ce qui ne fonctionne pas, c'est un élément dont le premier bloc n'est pas un paragraphe : une citation avant le marqueur a supprimé la case dans tous les moteurs.
- Les tableaux et le barré sont-ils utilisables partout ?
- Non. Les deux sont des extensions GFM, sections 4.10 et 6.5, et aucune n'est dans CommonMark. Notre tableau est sorti en vrai tableau dans deux configurations et en paragraphe de barres littérales dans une autre. Le barré est pire : la spéc. GFM barre le texte entouré d'un ou deux tildes mais pas de trois, tandis qu'une autre bibliothèque très répandue en exigeait deux et produisait un autre élément HTML pour le résultat.
- Les notes de bas de page font-elles partie de GitHub Flavored Markdown ?
- Pas selon la spécification GFM publiée. Le mot footnote y apparaît exactement une fois, dans une phrase historique de l'introduction, et il n'existe aucune section sur les notes. Le site de GitHub les affiche pourtant, bonne illustration de l'écart entre une spécification et un produit. Les quatre moteurs testés ont laissé l'appel en texte littéral et la définition en paragraphe orphelin.
Articles qui pourraient t'intéresser
Tous les guides →Outils similaires
Sources
- 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
Tu as repéré une erreur dans cet article ?