¿Qué es mermaid.js?
mermaid.js es una biblioteca de JavaScript que permite describir diagramas mediante una sintaxis basada en texto (sintaxis de Mermaid) para representar gráficamente diagramas complejos como diagramas de flujo, diagramas de Gantt, etc.
También se utiliza en varios servicios como GitHub, Qiita y Notion. En esta ocasión, configuraremos hugo para poder usar mermaid.js.
Habilitar mermaid.js en hugo
Los pasos son los siguientes:
- Añadir lo siguiente a layouts/partials/extend_footer.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
| {{ if or .Params.mermaid .Site.Params.mermaid }}
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.3.0/dist/mermaid.min.js"></script>
{{- $loadmermaid := resources.Get "js/load-mermaid.js" }}
<script src="{{ $loadmermaid.RelPermalink }}"></script>
<script>
window.initMermaid();
if (isDarkTheme()) {
setPrefTheme('dark');
} else {
setPrefTheme('light');
}
</script>
{{ end }}
|
- Solo se carga
mermaid.min.js si se establece mermaid: true en la condición if. Esta biblioteca pesa aproximadamente 3MB, lo cual es sorprendentemente grande.
- Crear assets/js/load-mermaid.js. Este proceso se utiliza para inicializar y volver a dibujar cuando el tema cambia dinámicamente.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| (function(window){
'use strict'
const elementCode = '.mermaid'
const loadMermaid = function(theme) {
window.mermaid.initialize({theme})
window.mermaid.init({theme}, document.querySelectorAll(elementCode))
}
const saveOriginalData = function(){
return new Promise((resolve, reject) => {
try {
var els = document.querySelectorAll(elementCode),
count = els.length;
els.forEach(element => {
element.setAttribute('data-original-code', element.innerHTML)
count--
if(count == 0){
resolve()
}
});
} catch (error) {
reject(error)
}
})
}
const resetProcessed = function(){
return new Promise((resolve, reject) => {
try {
var els = document.querySelectorAll(elementCode),
count = els.length;
els.forEach(element => {
if(element.getAttribute('data-original-code') != null){
element.removeAttribute('data-processed')
element.innerHTML = element.getAttribute('data-original-code')
}
count--
if(count == 0){
resolve()
}
});
} catch (error) {
reject(error)
}
})
}
const init = ()=>{
saveOriginalData()
.catch( console.error )
document.body.addEventListener('dark-theme-set', ()=>{
resetProcessed()
.then(loadMermaid('dark'))
.catch(console.error)
})
document.body.addEventListener('light-theme-set', ()=>{
resetProcessed()
.then(loadMermaid('default'))
.catch(console.error)
})
}
window.initMermaid = init
})(window);
|
El código original en el que me basé fue tomado de la siguiente referencia:
- Modificar el procesamiento al cambiar de tema en header.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| function switchTheme(theme) {
switch (theme) {
case 'light':
{{ if or .Params.mermaid .Site.Params.mermaid }}
document.body.dispatchEvent(new CustomEvent('light-theme-set'));
{{ end }}
document.body.classList.remove('dark');
break;
case 'dark':
{{ if or .Params.mermaid .Site.Params.mermaid }}
document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
{{ end }}
document.body.classList.add('dark');
break;
// auto
default:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
{{ if or .Params.mermaid .Site.Params.mermaid }}
document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
{{ end }}
document.body.classList.add('dark');
}
}
}
|
- Crear layouts/shortcodes/mermaid.html
1
2
3
| <div class="mermaid" align="{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}">
{{ safeHTML .Inner }}
</div>
|
Con esto, la preparación para usar mermaid.js está completa.
Probando mermaid.js
- Añadir lo siguiente a la definición del artículo:
- Añadir lo siguiente al cuerpo del artículo:
Diagrama de flujo
1
2
3
4
5
6
| {{<mermaid align="center">}}
graph TD
A[Inicio] -->|Condición 1| B(Condición 2)
B --> C{Condición 3}
C -->|Condición 4| D[Fin]
{{</mermaid>}}
|
Resultado de salida
graph TD
A[Inicio] -->|Condición 1| B(Condición 2)
B --> C{Condición 3}
C -->|Condición 4| D[Fin]
Diagrama de Gantt
1
2
3
4
5
6
7
8
9
10
11
12
| {{<mermaid align="center">}}
gantt
section Project
Definición de requisitos :done, a, 2024-05-25, 5d
Diseño básico :done, b, after a, 5d
Diseño detallado :done, c, after b, 5d
Implementación :active, d, after c, 10d
Pruebas unitarias :crit, e, after d, 5d
Pruebas de integración : f, after e, 5d
Pruebas del sistema : g, after f, 5d
Lanzamiento :milestone, h, after g, 1d
{{</mermaid>}}
|
Resultado de salida
gantt
section Project
Definición de requisitos :done, a, 2024-05-25, 5d
Diseño básico :done, b, after a, 5d
Diseño detallado :done, c, after b, 5d
Implementación :active, d, after c, 10d
Pruebas unitarias :crit, e, after d, 5d
Pruebas de integración : f, after e, 5d
Pruebas del sistema : g, after f, 5d
Lanzamiento :milestone, h, after g, 1d
Diagrama de secuencia
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {{<mermaid align="center">}}
sequenceDiagram
participant user
participant view
participant controller
participant model
participant database
user->>view: Ingreso de ID/PW
view->>controller: Petición de autenticación
controller->>model: Petición de autenticación
model->>database: Petición de autenticación
database-->>model: Devolución de resultado de autenticación
model-->>controller: Devolución de resultado de autenticación
controller-->>view: Devolución de resultado de autenticación
view-->>user: Mostrar resultado de autenticación
{{</mermaid>}}
|
Resultado de salida
sequenceDiagram
participant user
participant view
participant controller
participant model
participant database
user->>view: Ingreso de ID/PW
view->>controller: Consulta ajax
controller->>model: Petición de autenticación
model->>database: Emisión de SQL
database-->>model: Devolución de resultado SQL
model-->>controller: Devolución de resultado de petición de autenticación
controller-->>view: Devolución de resultado de consulta ajax
view-->>user: Mostrar resultado de autenticación
Eso es todo.
Referencias