L’objectif de cet article est de découvrir la syntaxe du Markdown et de commencer à réfléchir à la manière dont nous pourrions transformer cette spécification en code.
Essayons de réduire son contenu à l’essentiel.
Note : C’est le premier article qui contient du code et des blocs de code. J’ai fait au plus simple pour l’instant, mais je prévois d’ajouter de la colorisation syntaxique et d’autres ajustements aux blocs de code.
Modification : 15 avril 2020 – Bon, je viens juste d’ajouter la colorisation syntaxique et la numérotation des lignes comme effet de bord de la migration du site vers Hugo. Youpi !
Types d’éléments
En première lecture, on remarque déjà que le Markdown supporte deux types d’éléments :
- Des éléments de type bloc qui peuvent, sans que ce soit nécessaire, s’étendre sur plusieurs lignes et qui sont propriétaires de leur ligne (ce qui veut dire que deux éléments de type bloc ne peuvent pas partager la même ligne).
- Des éléments en ligne, que vous pouvez ajouter n’importe où dans un élément de type bloc, et qui sera rendu en ligne avec le contenu, d’où leur nom.
Si ces types d’éléments vous disent quelque chose, c’est parce que ce sont les mêmes que pour l’HTML.
Élements de type bloc
Paragraphes
D’après la spécification rédigée par John Gruber :
Un paragraphe se compose simplement d’une ou plusieurs lignes consécutives, séparées par une ou plusieurs lignes vides. (Une ligne vide est une ligne qui apparait vide à la lecture — une ligne qui ne comporte que des espaces ou des tabulations est considérée comme vide). Un paragraphe standard ne devrait pas être indenté avec des espaces ou des tabulations.
Et juste là, nous avons la définition de deux de ce qui deviendra nos symboles ou nos nœuds une fois qu’ils auront été identifiés par notre parseur :
- Une ligne vide ou une ligne qui ne contient que des espaces ou des tabulations.
- Un paragraphe qui contient des lignes de texte non indenté.
Avec ces informations, et pour simplifier notre travail, nous pouvons déjà prendre deux décisions au sujet de notre parseur :
- Nous considèrerons les lignes vides comme des séparateurs. Elles diviseront le document en morceaux que le parseur analysera séparément.
- Par défaut, le parseur supposera qu’un bloc est un paragraphe, sauf si un autre type de bloc est détecté par une règle plus précise.
On peut écrire l’expression régulière qui représente une ligne vide comme suit :
/^[\t ]*$/;
Afin de s’assurer que notre expression régulière est correcte, on va utiliser une page HTML toute simple, avec le code ci-dessous. Si vous avez la flemme de le faire de votre côté (et un bon programmeur est un programmeur paresseux), je vous ai fait une page toute prête.
|
|
Si tout se passe bien, on devrait avoir le résultat suivant :
6 lignes trouvées!
0 : Cette ligne est vide!
1 : Cette ligne est vide!
2 : Cette ligne contient du texte!
3 : Cette ligne est vide!
4 : Cette ligne est vide!
5 : Cette ligne contient du texte!
Génial ! On sait maintenant détecter les lignes vides, les limites de chaque paragraphe. Passons à notre tâche suivante : extraire les paragraphes.
Il suffit de mettre à jour le code javascript avec les lignes ci-dessous :
|
|
Exécutons le code ci-dessus (vous pouvez le voir en action sur cette page), et vérifions que tout fonctionne comme on veut. Notre code devrait afficher les lignes suivantes :
Paragraphe 1 : Un peu de contenu
Paragraphe 2 : Du contenu en plus
Parfait ! Mais ne nous emballons pas. Étendons notre contenu de test afin de
s’assurer que la détection des paragraphes fonctionne correctement. Il suffit
d’ajouter quelques lignes de contenu à notre variable content
comme
ci-dessous :
|
|
À nouveau, si tout se passe bien lors de l’exécution du code, nous aurons réussi à extraire quatre paragraphes de notre contenu de test. Mais vous avez peut-être déjà remarqué un problème potentiel avec notre code. Et vous avez raison. Exécutons le code. Voici ce qu’on obtient :
Paragraphe 1 : Un peu de contenu
Paragraphe 2 : Du contenu en plus
Paragraphe 3 : Un paragraphe sur plusieurs
Paragraphe 4 : lignes avec un peu de contenu
Paragraphe 5 : Un paragraphe avec un
Paragraphe 6 : saut de ligne
Comme indiqué plus tôt, d’après la spécification Markdown, les lignes vides
séparent les paragraphes. Mais pour l’instant, on utilise le caractère de retour
chariot (\n
) comme séparateur. Ajustons ce comportement.
Il va tout d’abord falloir stocker les lignes du paragraphe en cours dans une variable (une zone tampon, aussi appelé buffer), et traiter les lignes du buffer une fois que l’on rencontre une ligne vide. Il nous faudra également implémenter la fonctionnalité de retour à la ligne forcé :
Quand vous souhaitez insérer une balise
<br/>
en Markdown, il suffit de terminer la ligne avec deux espaces ou plus, puis de faire un retour à la ligne.
Pour implémenter cette fonctionnalité, il suffit d’utiliser le code javascript suivant (ou afficher cette page) :
|
|
On obtient un résultat prometteur :
Paragraphe 1 : Un peu de contenu
Paragraphe 2 : Du contenu en plus
Paragraphe 3 : Un paragraphe sur plusieurs lignes avec un peu de contenu
Paragraphe 4 : Un paragraphe avec un saut de ligne
Cet article est plutôt long, mais si vous êtes arrivé jusqu’ici, voici votre récompense : nous sommes maintenant capable de faire le rendu des paragraphes !
Vous venez de créer votre tout premier, mais incomplet, parseur et moteur de rendu Markdown.
Pour faire le rendu de vos paragraphes, ajoutez le code suivant à votre page lien pour les paresseux :
|
|
|
|
Et on a fini ! Vous pouvez accéder à la page au dernier lien, télécharger le code (avec l’option “Enregistrer la page” dans le menu de votre navigateur) et vous aurez l’intégralité du code que nous avons écrit ensemble dans cet article.
Jouez avec, modifiez-le ou cassez-le. Puis montrez moi vos résultats sur Twitter.
Dans le prochain article de cette série, nous découvrirons comment gérer les titres.