Aller au contenu

Diagrammes Mermaid

Le builder prend en charge les diagrammes Mermaid avec un traitement en deux phases : un plugin remark au moment du build prépare le balisage, et un moteur de rendu côté client produit le SVG.

Le plugin remark-mermaid (fourni par le package npm docs-theme) s’exécute pendant le build Astro. Il utilise unist-util-visit pour trouver les blocs de code délimités avec lang === 'mermaid' et les remplace par du HTML :

visit(tree, 'code', (node, index, parent) => {
if (node.lang !== 'mermaid' || index === undefined || !parent) return;
const escaped = node.value
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
parent.children[index] = {
type: 'html',
value: `<div class="mermaid-container" data-mermaid-src="${escaped}">
<pre class="mermaid">${node.value}</pre>
</div>`,
};
});

Détails clés :

AspectValeur
Type de nœud correspondantNœuds codelang === 'mermaid'
Échappement des entités HTML&, <, >, " — empêche l’injection d’attributs dans data-mermaid-src
Structure de sortie<div class="mermaid-container"> avec un attribut data-mermaid-src contenant la source échappée
Contenu de repli<pre class="mermaid"> avec la source brute (visible jusqu’au rendu JS)

La fonction renderMermaidDiagrams() dans src/scripts/placeholder-dom.ts gère la génération SVG dans le navigateur.

Mermaid est chargé à la demande depuis un CDN — il n’est pas inclus dans le bundle :

const mermaid = (await import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs')).default;
mermaid.initialize({
startOnLoad: false,
theme: 'default',
securityLevel: 'loose',
themeVariables: {
primaryColor: '#ffffff',
primaryBorderColor: '#cccccc',
background: '#ffffff',
mainBkg: '#ffffff',
secondBkg: '#ffffff',
tertiaryColor: '#ffffff',
},
});

startOnLoad: false empêche Mermaid de scanner automatiquement la page. securityLevel: 'loose' autorise les événements de clic et les liens dans les diagrammes.

Pour chaque élément .mermaid-container :

  1. Lire la source brute du diagramme depuis data-mermaid-src
  2. Exécuter la substitution de placeholders sur la source (voir ci-dessous)
  3. Vider le conteneur et supprimer tout attribut data-processed
  4. Appeler mermaid.render() avec un ID aléatoire pour produire le SVG
  5. Définir backgroundColor: 'white' sur l’élément <svg> généré

Avant le rendu, la source du diagramme passe par la même fonction substituteText() utilisée par le parcoureur DOM (voir Système de placeholders pour le mécanisme de parcours) :

const template = container.getAttribute('data-mermaid-src') || '';
const substituted = substituteText(template, values);

Cela signifie que les jetons de placeholder comme xCUSTOMER_ASNx fonctionnent à l’intérieur des définitions de diagrammes Mermaid. Lorsqu’un utilisateur modifie une valeur dans le formulaire, l’événement placeholder-change déclenche un nouveau rendu complet de tous les diagrammes avec les valeurs mises à jour.

Si mermaid.render() lève une exception (par exemple, en raison d’une erreur de syntaxe dans la source du diagramme), le bloc catch affiche l’erreur directement dans le conteneur :

} catch (e) {
container.textContent = `Diagram error: ${e}`;
}

Cela rend les erreurs de rédaction visibles sans casser le reste de la page.

Les diagrammes sont re-rendus dans deux situations :

DéclencheurÉvénementCe qui se passe
Changement de valeur de placeholderplaceholder-changehandleChange() appelle renderMermaidDiagrams() avec les nouvelles valeurs
Navigation de page Astroastro:page-loadinit() appelle renderMermaidDiagrams() pour la nouvelle page

Écrivez un bloc de code délimité standard avec le tag de langage mermaid :

```mermaid
flowchart LR
A[Customer ASN: xCUSTOMER_ASNx] --> B[F5 XC ASN: xF5_XC_ASNx]
```

Le plugin remark convertit cela en un div conteneur au moment du build. Le client le rend sous forme de SVG avec les valeurs de placeholders substituées.