5.3.1 • Published 9 months ago

@deskeen/markdown v5.3.1

Weekly downloads
14
License
MIT
Repository
github
Last release
9 months ago

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

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 Docs
  • id: Attribut id de l'élément. MDN Docs
  • className: Attribut Class de l'élément. MDN Docs
  • attributes: Attributs de l'élément. MDN Docs
  • children: Liste des enfants de type Element. MDN Docs
  • childNodes: Liste des enfants de type Element et Text. MDN Docs
  • firstChild: Premier enfant. MDN Docs
  • lastChild: Dernier enfant. MDN Docs
  • parentNode: Parent de l'élément. MDN Docs
  • textContent: Texte de l'élément et de ses descendants. MDN Docs
  • hasAttribute(attrName): Retourne si l'élément à un attribut spécifique. MDN Docs
  • setAttribute(attrName, attrValue): Ajoute un attribut à l'élément. MDN Docs
  • getAttribute(attrName): Retourne un attribute de l'élément. MDN Docs
  • removeAttribute(attrName): Enlève un attribute de l'élément. MDN Docs
  • appendChild(child): Ajoute un élément à la fin de la liste des enfants. MDN Docs
  • prepend(...nodesToPreprend): Insère une liste d'éléments avant le premier enfant. MDN Docs
  • append(...nodesToAppend): Insère une liste d'éléments après le dernier enfant. MDN Docs
  • removeChild(child): Enlève un élément. MDN
  • remove(): Enlève un enfant de son parent. MDN
  • innerHTML: Retourne la représentation HTML des éléments contenus dans l'élément. MDN Docs
  • outerHTML: 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

TypeSyntaxe 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ée2 espaces
Liste numérotée+ Item de liste numérotée
Liste numérotée imbriquée3 espaces
Ligne horizontale---
Code`Code`
Code multilignes```\nCode text\n```
Citation> Citation
Note de bas de pageRé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.

SyntaxGitHubRedditGitLabCommonMark
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 \n2 espaces
Liste num.1.
Liste num.imb.3 espaces\n
List num. \n3 espaces
Ligne Horiz.\n---\n
Code`
Multi.Code```
Citation>
Echappement\ | ☑ | ☑ | ☑ | ☑
Exposant^⚠ HTML⚠ HTML⚠ N/A
IndiceN/A⚠ HTML☑ N/A⚠ HTML⚠ N/A
Note bas page[^1]⚠ N/A⚠ Diff.⚠ N/A
HTMLN/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

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

5.3.1

9 months ago

5.2.2

9 months ago

5.2.1

9 months ago

5.1.3

3 years ago

5.1.2

3 years ago

5.1.1

3 years ago

5.1.0

3 years ago

5.0.0

3 years ago

4.1.2

3 years ago

4.1.1

3 years ago

4.1.0

3 years ago

4.0.1

3 years ago

4.0.0

3 years ago

3.2.2

4 years ago

3.2.1

4 years ago

3.2.0

4 years ago

3.1.0

4 years ago

3.0.0

4 years ago

2.0.0

4 years ago

1.0.0

4 years ago