@deskeen/markdown
v5.3.1
Published
Node.js Markdown to HTML Parser
Downloads
1,288
Readme
Parseur Markdown vers HTML pour Node.js
Ce parseur Markdown-vers-HTML utilise une syntaxe personnalisée et allégée du language Markdown.
Il permet de créer: des textes en italique, textes en gras et textes barrés, des exposants, des liens, des titres et sous-titres, des images, des vidéos, des éléments audios, du code mono et multi lignes, des listes numérotées et non-numérotées, des listes imbriquées, des lignes horizontales, des citations et des notes de bas de page.
Un module pour le navigateur est aussi disponible ici: @deskeen/markdown-browser
Utilisation
const parser = require('@deskeen/markdown')
const html = parser.parse('mon texte markdown').innerHTML
// html === '<p>mon texte markdown</p>'
En savoir plus
- Installation
- Options du parseur
- L'objet Element
- Résumé des syntaxes Markdown
- Syntaxes Markdown
- Compatibilité avec d'autres Markdown populaires
- Syntaxes incompatibles
- Exemples
- Autres ressources
- Contact
- Licence
Installation
Ce paquet peut être ajouté à la liste des dépendances de votre projet Node.js en exécutant la commande:
npm install @deskeen/markdown
Pour importer le parseur à votre coe JavaScript:
const parseur = require('@deskeen/markdown')
Pour parser du texte et le transformer en HTML, utilisez:
const codeHtml = parseur.parse('du texte markdown').innerHTML
Le parseur a été testé avec les versions 10+ de Node.js mais il se peut qu'il fonctionne aussi sur des versions précédentes.
Options du parseur
parse(markdownText[, options])
Un objet avec les options peut être passé au parseur.
Les options disponibles sont:
allowHeader
: Si les titres sont autorisés.true
par défaut.allowHeaderFormat
: Si du texte formaté est aurotisé dans les titres.false
par défaut.allowLink
: Si les liens sont autorisés.true
par défaut.allowImage
: Si les images sont autorisées.true
par défaut.allowCode
: Si du code est autorisé.true
par défaut.allowMultilineCode
: Si du code multi lignes est autorisé.true
par défaut.allowUnorderedList
: Si les listes non-numérotées sont autorisées.true
par défaut.allowOrderedNestedList
: Si les listes numérotées imbriquées sont autorisées.true
par défaut.allowOrderedList
: Si les listes numérotées sont autorisées.true
par défaut.allowOrderedList
: Si les listes numérotées imbriquées sont autorisées.true
par défaut.allowHorizontalLine
: Si les lignes horizontales sont autorisées.true
par défaut.allowQuote
: Si les citations sont autorisées.true
par défaut.allowFootnote
: Si les notes de bas de page sont autorisées.false
par défaut.allowHTMLAttributes
: Si des attributes HTML peuvent sont autorisés.false
par défaut (beta).maxHeader
: Niveau maximal des titres. Nombre de 1 à 6 inclus. e.g. 2 signifie que les balises autorisées sont<h1>
et<h2>
. 3 par défaut.
Des fonctions Callback peuvent aussi être ajoutées aux options du parseur. Ces fonctions permettent de modifier l'élément de sortie (e.g. ajouter des attributs personnalisés)
Les Callbacks disponibles sont:
onHeader
: Fonction appelée lorsqu'un titre est parsé.onLink
: Fonction appelée lorsqu'un lien est parsé.onImage
: Fonction appelée lorsqu'une image est parsée.onAudio
: Fonction appelée lorsqu'un élément audio est parsé.onVidéo
: Fonction appelée lorsqu'une video est parsée.onCode
: Fonction appelée lorsque du code est parsé.onMultilineCode
: Fonction appelée lorsque du code multi lignes est parsé. Le deuxième argument est le nom (optionnel) du langage.onUnorderedList
: Fonction appelée lorsqu'une liste non numérotée est parsée.onOrderedList
: Fonction appelée lorsqu'une liste numérotée est parsée.onHorizontalLine
: Fonction appelée lorsqu'une ligne horizontale est parsée.onQuote
: Fonction appelée lorsqu'une citation est parsée.onReference
: Fonction appelée lorsqu'une référence est parsée. Le deuxième argument contient l'identifiant.
Le premier argument des Callbacks est toujours l'élément parsé.
function onXXX(element) {
// Votre code ici
// e.g.: element.className = 'css-class'
}
L'objet Element
Le parseur retourne un objet de type Element
qui est similaire à un objet DOM Element dans le navigateur.
Les propriétés disponibles sont:
tagName
: Nom de la balise. MDN Docsid
: Attribut id de l'élément. MDN DocsclassName
: Attribut Class de l'élément. MDN Docsattributes
: Attributs de l'élément. MDN Docschildren
: Liste des enfants de typeElement
. MDN DocschildNodes
: Liste des enfants de typeElement
etText
. MDN DocsfirstChild
: Premier enfant. MDN DocslastChild
: Dernier enfant. MDN DocsparentNode
: Parent de l'élément. MDN DocstextContent
: Texte de l'élément et de ses descendants. MDN DocshasAttribute(attrName)
: Retourne si l'élément à un attribut spécifique. MDN DocssetAttribute(attrName, attrValue)
: Ajoute un attribut à l'élément. MDN DocsgetAttribute(attrName)
: Retourne un attribute de l'élément. MDN DocsremoveAttribute(attrName)
: Enlève un attribute de l'élément. MDN DocsappendChild(child)
: Ajoute un élément à la fin de la liste des enfants. MDN Docsprepend(...nodesToPreprend)
: Insère une liste d'éléments avant le premier enfant. MDN Docsappend(...nodesToAppend)
: Insère une liste d'éléments après le dernier enfant. MDN DocsremoveChild(child)
: Enlève un élément. MDNremove()
: Enlève un enfant de son parent. MDNinnerHTML
: Retourne la représentation HTML des éléments contenus dans l'élément. MDN DocsouterHTML
: Retourne la représentation HTML de l'élément et de ses descendants. MDN Docs
De nouveaux éléments peuvent être créés en utilisant la classe Element
et du texte peut être créé en utilisant la class Text
:
const { Element, Text } = require('@deskeen/markdown')
const monElementDiv = new Element('div')
const monTexte = new Text('du text')
Résumé des syntaxes Markdown
| Type | Syntaxe Markdown |
| ----------------------------------------- | ---------------------------- |
| Texte en italique | *Texte en italique*
|
| Texte en gras | **Texte en gras**
|
| Texte en gras-italique| ***Texte en gras-italique***
|
| Texte barré | ~~Texte barré~~
|
| Exposant | ^Exposant
|
| Titre | # Titre
|
| Lien | [Texte affiche](lien)
|
| Image,VidéoAudio| ![Texte alt.](lien)
|
| Liste non-numérotée| - Item de la liste
|
| Liste non-numérotée imbriquée| 2 espaces |
| Liste numérotée | + Item de liste numérotée
|
| Liste numérotée imbriquée| 3 espaces |
| Ligne horizontale | ---
|
| Code | `Code`
|
| Code multilignes | ```\nCode text\n```
|
| Citation | > Citation
|
| Note de bas de page| Référence[^1]
|
| Caractère d'échappement| \# Titre non parsé
|
Syntaxes Markdown
Texte en italique
Un texte en italique est entouré d'une étoile (*
).
Exemple
Ceci est un *texte en italique*
<p>Ceci est un <em>texte en italique</em></p>
Texte en gras
Un texte en gras est entouré de deux étoiles (**
).
Exemple
Ceci est un **texte en gras**
<p>Ceci est un <strong>texte en gras</strong></p>
Texte en gras-italique
Un texte en gras-italique est entouré de trois étoiles (***
).
Exemple
Ceci est un ***texte en gras-italique***
<p>Ceci est un <strong><em>texte en gras-italique</em></strong></p>
Texte barré
Un texte barré est entouré de deux caractères tilde (~~
).
Exemple
Ceci est un ~~texte barré~~
<p>Ceci est un <s>texte barré</s></p>
Exposant
Un texte en exposant commence par un caractère circonflexe (^
) et termine avec un espace ou un saut de ligne. Un texte en exposant qui contient des espaces peut être entouré de parenthèses.
Exemple
Ceci est un ^texte en exposant
<p>Ceci est un <sup>texte</sup> en exposant</p>
Exemple avec parenthèses
Ceci est un ^(texte en exposant)
<p>Ceci est un <sup>texte en exposant</sup></p>
Paragraphe
Un seul saut de ligne ajoute le text au dernier paragraphe. Deux sauts de ligne à la suite créé un nouveau paragraphe.
Exemple avec un seul saut de ligne
Première ligne de texte
Seconde ligne de texte
<p>Première ligne de texte<br>Seconde ligne de texte</p>
Example with two newlines
Première ligne de texte
Seconde ligne de texte
<p>Première ligne de texte</p>
<p>Seconde ligne de texte</p>
Titre
Un titre commence par un à six caractères dièse (#
), suivi d'un espace.
Exemple
# Titre niveau 1
## Titre niveau 2
### Titre niveau 3
#### Titre niveau 4
##### Titre niveau 5
###### Titre niveau 6
<h1>Titre niveau 1</h1>
<h2>Titre niveau 2</h2>
<h3>Titre niveau 3</h3>
<h4>Titre niveau 4</h4>
<h5>Titre niveau 5</h5>
<h6>Titre niveau 6</h6>
Lien
Un lien est composé de deux parties. Le texte, entouré de crochets ([]
) suivi du lien, entouré de parenthèses (( )
), i.e. [Link](url)
. Les crochets fermants dans le texte doivent être précédés du caractère d'échappement.
Exemple
Ceci est un [lien](https://exemple.com)
<p>Ceci est un <a href="https://exemple.com">lien</a></p>
Exemple avec un crochet fermant
Selon [[1\]](#ref1), ce module est le meilleur !
<p>Selon <a href="#ref1">[1]</a>, ce module est le meilleur !</p>
Image
Une image commence par un point d'exclamation (!
) suivie d'un texte alternatif entouré de de crochets ([]
), suivi de l'adresse (URL) entouré de parenthèses (( )
). i.e. ![text alt.](lien_de_l_image)
Les images mises sur une ligne séparée et les images contenues dans une ligne de texte génèrent un code HTML différent.
Exemple d'une image sur une ligne de texte
Cette ![image](https://exemple.com/une_image.png) fait partie d'une ligne de texte
<p>Cette <img src="https://exemple.com/une_image.png" alt="image"> fait partie d'une ligne de texte</p>
Exemple d'une image seule sur une ligne
![Image seule sur la ligne](https://exemple.com/une_image.png)
<figure>
<img src="https://exemple.com/some_image.png" alt="Image seule sur la ligne">
</figure>
Exemple d'une image avec une légende
![Image avec une légende](https://exemple.com/une_image.png "Légende")
<figure style="height: 100px; width: 100px">
<img src="https://exemple.com/une_image.png" alt="Image avec une légende">
<figcaption>Légende</figcaption>
</figure>
Exemple d'une image avec du CSS
![Image avec style](https://exemple.com/une_image.png){style="height: 100px; width: 100px"}
<figure style="height: 100px; width: 100px">
<img src="https://exemple.com/une_image.png" alt="Image avec style">
</figure>
Vidéo
Les vidéos fonctionnent de la même manière que les images, i.e. ![][adresse_de_la_video]
.
Exemple d'une vidéo
![][https://exemple.com/une_video.mp4]
<figure>
<video controls="">
<source src="https://exemple.com/une_video.mp4" type="video/mp4">
</video>
</figure>
Exemple d'une vidéo avec légende
![][https://exemple.com/une_video.mp4 "ma légende"]
<figure>
<video controls="">
<source src="https://exemple.com/une_video.mp4" type="video/mp4">
</video>
<figcaption>ma légende</figcaption>
</figure>
Audio
Les éléments audios fonctionnent de la même manière que les images, i.e. ![][adresse_du_son]
.
Exemple d'un son
![][https://example.com/some_audio.mp3]
<figure>
<audio controls="">
<source src="https://example.com/some_audio.mp3" type="audio/mpeg">
</audio>
</figure>
Exemple d'un son avec légende
![][https://example.com/some_audio.mp3 "ma légende"]
<figure>
<audio controls="">
<source src="https://example.com/some_audio.mp3" type="audio/mpeg">
</audio>
<figcaption>ma légende</figcaption>
</figure>
Liste non numérotée
Les éléments d'une liste non numérotée commencent avec un tiret (-
) suivi par un espace.
Des sauts de lignes peuvent être insérées à l'intérieur d'un élément de la liste en commençant la ligne avec deux espaces.
Une liste peut être imbriquée dans une autre liste en commençant avec au moins deux espaces, suivi d'un tiret, et d'un autre espace. Seulement une liste de même type peut être imbriquée.
Exemple
- Item 1
- Item 2
- Item 3
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Exemple avec un saut de ligne à l'intérieur d'un élément
1. Item 1
Suite Item 1
2. Item 2
<ol>
<li>Item 1<br>Suite Item 1</li>
<li>Item 2</li>
</ol>
Exemple avec une liste imbriquée
- Item 1
- Item 1.1
- Item 1.2
- Item 2
<ul>
<li>
Item 1
<ul>
<li>Item 1.1</li>
<li>Item 1.2</li>
</ul>
</li>
<li>Item 2</li>
</ul>
Liste numérotée
Les éléments d'une liste numérotée commencent avec un nombre suivi par un point (.
) et un espace.
Des sauts de lignes peuvent être insérées à l'intérieur d'un élément de la liste en commençant la ligne avec trois espaces.
Une liste peut être imbriquée dans une autre liste en commençant avec au moins trois espaces, suivi d'un nombre, et d'un espace. Seulement une liste de même type peut être imbriquée.
Exemple
1. Item 1
2. Item 2
3. Item 3
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>
Exemple avec un saut de ligne à l'intérieur d'un élément
1. Item 1
Suite Item 1
2. Item 2
<ol>
<li>Item 1<br>Suite Item 1</li>
<li>Item 2</li>
</ol>
Les nombres des éléments des listes numérotées ne sont pas pris en compte. La liste est exportée de la même façon si les nombres se suivent ou pas.
Exemple avec des nombres qui ne se suivent pas
5. Item 1
1. Item 2
8. Item 3
3. Item 4
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ol>
Exemple avec une liste imbriquée
1. Item 1
1. Item 1.1
2. Item 1.2
2. Item 2
<ol>
<li>
Item 1
<ol>
<li>Item 1.1</li>
<li>Item 1.2</li>
</ol>
</li>
<li>Item 2</li>
</ol>
Ligne horizontale
Une ligne horizontale débute avec une ligne vide, suivi de trois tirets (---
), suivi d'une autre ligne vide.
Exemple
Au dessus de la ligne horizontale
---
En dessous de la ligne horizontale
<p>Au dessus de la ligne horizontale</p>
<hr>
<p>En dessous de la ligne horizontale</p>
Code
Le code est entouré du accent aigu (```).
Exemple
Ceci est du `code technique`
<p>Ceci est du <code>code technique</code></p>
Code multi lignes
Du code multi lignes est entouré par trois accents aigus (```), mis sur des lignes séparées.
Le langage du code peut être ajouté à côté des trois accents aigus d'ouverture. Il n'est pas affiché dans le code HTML de sorti mais il est passé en deuxième argument du Callback onMultilineCode
. Voir l'exemple plus bas.
Exemple
\`\`\`
Du code ligne 1
Du code ligne 2
Du code ligne 3
\`\`\`
<pre><code>Du code ligne 1
Du code ligne 2
Du code ligne 3</code></pre>
Exemple avec un nom de language
\`\`\`javascript
console.log('Hello World!')
\`\`\`
<pre><code>console.log('Hello World!')</code></pre>
Citation
Une citation débute avec un signe supérieur (>
).
Exemple
> Citation ligne 1
> Citation ligne 2
> Citation ligne 3
<blockquote>
<p>
Citation ligne 1
<br>
Citation ligne 2
<br>
Citation ligne 3
</p>
</blockquote>
Note de bas de page
Une note de bas de page est composée de deux parties: une référence et une note.
La référence commence avec un crochet ouvrant ([
), suivi d'un accent circonflexe (^
), un identifiant (un nombre ou un texte mais pas d'espaces), et un crochet fermant (]
). e.g. [^1]
La note doit être sur sa propre ligne n'importe où dans le document et doit correspondre avec la référence. Un double point (:
) est ajouté à côté de la référence suivi du texte de la note.
L'identifiant de la référence est seulement utilisé pour faire le lien entre la référence et la note de bas de page. Le code HTML de sortie sera numéroté de façon séquentielle.
Exemple
Ma première référence[^1].
Ma seconde[^two].
[^1]: 1ere note de bas de page.
[^two]: 2eme note de bas de page.
<p>Ma première référence<a href="#reference1"><sup>1</sup></a>.</p>
<p>Ma seconde<a href="#reference2"><sup>2</sup></a>.</p>
<section>
<ol>
<li id="reference1">First footnote.</li>
<li id="reference2">Second footnote.</li>
</ol>
</section>
Caractère d'échappement
Le caractère d'échappement est le caractères antislash (\
).
Il peut être utilisé pour indiquer au parseur de ne pas interpréter les caractères utilisés dans les syntaxes Markdown, i.e. *
, [
, `
, !
, #
, ~
, ^
et \
.
Exemple
Ce \*texte en gras\* n'est pas converti en HTML.
<p>Ce *texte en gras* n'est pas converti en HTML.</p>
Exemple 2
Cet antislash \ n'est pas enlevé car il n'est pas suivi d'un caractère spécial.
<p>Cet antislash \ n'est pas enlevé car il n'est pas suivi d'un caractère spécial.</p>
Compatibilité avec d'autres Markdown populaires
Une marque (☑) signifie que la syntaxe devrait fonctionner sur la plateforme.
| | Syntax | GitHub | Reddit | GitLab | CommonMark|
| ------------ |:---------|:----------|:-------|:--------|:----------|
| Italique | *
| ☑ | ☑ | ☑ | ☑ |
| Gras | **
| ☑ | ☑ | ☑ | ☑ |
| Gras-italique| ***
| ☑ | ☑ | ☑ | ⚠ N/A |
| Barré | ~~
| ☑ | ☑ | ☑ | ⚠ N/A |
| Saut de ligne| \n
| ☑ | ☑ | ⚠ Espace| ⚠ Espace |
| Paragraphe | \n\n
| ☑ | ☑ | ☑ | ☑ |
| Titre | #
| ☑ | ☑ | ☑ | ☑ |
| Lien | []()
| ☑ | ☑ | ☑ | ☑ |
| Image | ![]()
| ☑ | ☑ | ☑ | ☑ |
| Liste | -
| ☑ | ☑ | ☑ | ☑ |
| Liste imb. | 2 espaces| ☑ | ☑ | ☑ | ⚠ \n
|
| List \n | 2 espaces| ☑ | ☑ | ☑ | ☑ |
| Liste num. | 1.
| ☑ | ☑ | ☑ | ☑ |
| Liste num.imb.|3 espaces| ☑ | ☑ | ☑ | ⚠ \n
|
| List num. \n| 3 espaces| ☑ | ☑ | ☑ | ☑ |
| Ligne Horiz. | \n---\n
| ☑ | ☑ | ☑ | ☑ |
| Code | `
| ☑ | ☑ | ☑ | ☑ |
| Multi.Code|```
| ☑ | ☑ | ☑ | ☑ |
| Citation | >
| ☑ | ☑ | ☑ | ☑ |
| Echappement | \
| ☑ | ☑ | ☑ | ☑ |
| Exposant | ^
| ⚠ HTML | ☑ | ⚠ HTML | ⚠ N/A |
| Indice | N/A | ⚠ HTML | ☑ N/A | ⚠ HTML | ⚠ N/A |
| Note bas page| [^1]
| ☑ | ⚠ N/A | ⚠ Diff. | ⚠ N/A |
| HTML | N/A | ⚠ Av. | ☑ N/A | ⚠ Av. | ⚠ Av. |
Source: GitHub Markdown, Reddit Markdown, GitLab Markdown, CommonMark
Syntaxes incompatibles
Les syntaxes suivantes ne sont PAS supportées:
- Les textes en italiques et en gras avec un, deux et trois underscores.
- Les titres avec des tirets ou des signes égal en dessous.
- Les listes non-numérotées avec un signe plus ou une étoile.
- Plus d'une liste imbriquée.
- Les lignes horizontales avec des étoiles ou des underscores.
- Les liens entre inférieur et supérieur.
- Le code HTML.
Exemples
Ajouter un identifiant aux titres
parseMarkdown('# Title 1', {
onHeader: element => {
// node.textContent === 'Title 1'
element.id = element.textContent.replace(/ /g, '-').toLowerCase()
}
}).innerHTML
<h1 id="title-1">Title 1</h1>
Ouvrir les liens externes dans un nouvel onglet
parseMarkdown('See [this page](https:/example.com)!', {
onLink: element => {
// element.getAttribute('href') === 'http:/example.com'
const href = element.getAttribute('href')
if (href.startsWith('https://MY_SITE.com') === false) {
element.setAttribute('target', '_blank')
}
}
}).innerHTML
<p>See <a href="https:/example.com" target="_blank">this page</a>!</p>
Ajouter un préfixe aux liens relatifs des images
parseMarkdown('![Beautiful image](beautiful_image.png)', {
onImage: element => {
// element.tagName === 'IMG'
// element.getAttribute('src') === 'beautiful_image.png'
// element.getAttribute('alt') === 'Beautiful image'
if (element.hasAttribute('src')) {
const src = element.getAttribute('src')
if (src.startsWith('http') === false) {
element.setAttribute('src', 'https://example.com/' + src)
}
}
}
}).innerHTML
<figure>
<img src="https://example.com/beautiful_image.png" alt="" />
<figcaption>Beautiful image</figcaption>
</figure>
Ajouter une classe CSS au code
parseMarkdown('This is body html tag: `<body>`', {
onCode: element => {
element.className = 'some-class'
}
}).innerHTML
<p>This is body html tag: <code class="some-class"><body></code></p>
Afficher joliment les objets JSON
const markdownText = '```json\n{"some_property":"foo","some_other_property":"bar"}\n```'
parseMarkdown(markdownText, {
onMultilineCode: (element, language) => {
if (language === 'json') {
// element is a <pre> tag that includes the <code> tag
const codeElement = element.firstChild
const codeText = codeElement.textContent
const jsonObject = JSON.parse(codeText)
codeElement.textContent = JSON.stringify(jsonObject, null, 2)
}
}
}).innerHTML
<pre><code>{
"some_property": "foo",
"some_other_property": "bar"
}</code></pre>
Autres ressources
- Original Markdown: https://daringfireball.net/projects/markdown/
- CommonMark: https://commonmark.org/
FAQ
Que faire si j'ai un problème?
Vous pouvez reporter un problème et demander de l'aide.
Que puis-je faire pour aider?
Vous pouvez:
- Jeter un coup d'oeil aux problèmes et voir si vous pouvez aider quelqu'un.
- Jeter un coup d'oeil au code et voir si vous pouvez l'améliorer.
- Traduire cette page dans votre langue.
- Mettre une étoile à ce dépôt.
Contact
Vous pouvez me contacter à l'adresse {mon_prenom}@{mon_nom}.fr
Licence
Licence MIT - Copyright (c) Morgan Schmiedt