@imontene/mdrender 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +55 -38
- package/dist/assets/theme-antigravity-dark.css +37 -0
- package/dist/assets/theme-antigravity.css +239 -0
- package/dist/assets.js +2 -0
- package/dist/cli.js +4 -2
- package/dist/convert.js +13 -5
- package/dist/options.d.ts +9 -3
- package/dist/options.js +5 -3
- package/dist/render/antigravity.d.ts +13 -0
- package/dist/render/antigravity.js +82 -0
- package/dist/render/fonts.d.ts +2 -0
- package/dist/render/fonts.js +6 -0
- package/dist/render/header-footer.d.ts +2 -1
- package/dist/render/header-footer.js +9 -4
- package/dist/render/mermaid.d.ts +2 -0
- package/dist/render/mermaid.js +3 -3
- package/dist/render/template.d.ts +3 -3
- package/dist/render/template.js +9 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Cambios
|
|
2
2
|
|
|
3
|
+
## 2.5.0 — 2026-10-22
|
|
4
|
+
|
|
5
|
+
- **Nuevo estilo por defecto: Anti-Gravity**, tomado del design system del mismo nombre y
|
|
6
|
+
llevado a páginas. Incluye:
|
|
7
|
+
- colores del sistema y títulos en Manrope 600 con interletrado negativo;
|
|
8
|
+
- etiquetas en JetBrains Mono, en mayúsculas: autor y fecha sobre el título, índice,
|
|
9
|
+
encabezado y pie;
|
|
10
|
+
- código, tablas, citas y alertas como superficies suaves;
|
|
11
|
+
- diagramas Mermaid con los mismos colores;
|
|
12
|
+
- un campo de luz tenue junto al título de la primera página.
|
|
13
|
+
- `--theme antigravity-dark` es su versión oscura. **Para conservar el aspecto anterior:**
|
|
14
|
+
`--theme light` (o `theme: light` en `mdrender.config.json`); `--theme dark` sigue
|
|
15
|
+
disponible.
|
|
16
|
+
|
|
3
17
|
## 2.4.0 — 2026-10-22
|
|
4
18
|
|
|
5
19
|
- **Párrafos justificados en el PDF**: los del texto, las citas y las alertas, con partición de
|
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@ Ejemplo: [`examples/ejemplo.md`](examples/ejemplo.md) → [`examples/ejemplo.pdf
|
|
|
23
23
|
tabla de contenidos y marcadores del PDF.
|
|
24
24
|
- 🗂️ **Lotes**: varios archivos, carpetas completas o patrones `docs/**/*.md`.
|
|
25
25
|
- 🔁 **`--watch`** y **vista previa en vivo** en el navegador.
|
|
26
|
-
- 🎨
|
|
26
|
+
- 🎨 Estilo **Anti-Gravity** por defecto (con variante oscura), los temas clásicos **claro** y
|
|
27
|
+
**oscuro**, o tu propio CSS.
|
|
27
28
|
- 🔌 **Sin conexión**: todo va empaquetado; por defecto no descarga nada de internet.
|
|
28
29
|
- 💻 **Windows 10/11 y Linux** (x64; arm64 en Linux), probado en ambos en cada cambio.
|
|
29
30
|
|
|
@@ -93,8 +94,9 @@ mdrender preview documento.md
|
|
|
93
94
|
# Más contenido por página
|
|
94
95
|
mdrender documento.md --density compact --font-size 10pt
|
|
95
96
|
|
|
96
|
-
#
|
|
97
|
-
mdrender documento.md --theme dark
|
|
97
|
+
# Variante oscura de Anti-Gravity, el estilo clásico, o un CSS propio que reemplaza el tema
|
|
98
|
+
mdrender documento.md --theme antigravity-dark
|
|
99
|
+
mdrender documento.md --theme light
|
|
98
100
|
mdrender documento.md --theme mi-tema.css
|
|
99
101
|
|
|
100
102
|
# Descargar un navegador si no tienes Chrome, Edge ni Chromium
|
|
@@ -135,41 +137,41 @@ equipo); `--port` fija el puerto y `--no-open` no abre el navegador.
|
|
|
135
137
|
|
|
136
138
|
### Opciones
|
|
137
139
|
|
|
138
|
-
| Opción | Descripción
|
|
139
|
-
| ------------------------------ |
|
|
140
|
-
| `-o, --output <ruta>` | Archivo de salida, o carpeta con varios archivos
|
|
141
|
-
| `-f, --format <pdf\|html>` | Formato de salida
|
|
142
|
-
| `--page-size <tamaño>` | `Letter`, `A4`, `Legal` (también `A3`, `A5`, `Tabloid`)
|
|
143
|
-
| `--margin <valor>` | Las cuatro márgenes como en CSS: `10mm`, `15mm 20mm`…
|
|
144
|
-
| `--margin-top <medida>` | Margen superior, p. ej. `15mm` (prevalece sobre `--margin`)
|
|
145
|
-
| `--margin-right <medida>` | Margen derecho
|
|
146
|
-
| `--margin-bottom <medida>` | Margen inferior
|
|
147
|
-
| `--margin-left <medida>` | Margen izquierdo
|
|
148
|
-
| `--orientation <orientación>` | `portrait` (vertical) o `landscape` (horizontal)
|
|
149
|
-
| `--landscape` | Atajo de `--orientation landscape`
|
|
150
|
-
| `--toc` | Tabla de contenidos al inicio (o donde pongas `[[toc]]`)
|
|
151
|
-
| `--toc-depth <n>` | Nivel de título más profundo en la tabla de contenidos
|
|
152
|
-
| `--header <texto>` | Encabezado de página (ver abajo)
|
|
153
|
-
| `--footer <texto>` | Pie de página (ver abajo)
|
|
154
|
-
| `--no-page-numbers` | Sin el pie con números de página
|
|
155
|
-
| `--font <manrope\|inter>` | Tipografía del texto (ver abajo)
|
|
156
|
-
| `--no-justify` | Párrafos alineados a la izquierda en el PDF (ver abajo)
|
|
157
|
-
| `--density <densidad>` | `normal` o `compact` (menos espacio entre líneas y bloques)
|
|
158
|
-
| `--font-size <tamaño>` | Tamaño del texto en `pt` o `px`, de 6 a 24 pt; p. ej. `10pt`
|
|
159
|
-
| `--theme <
|
|
160
|
-
| `--css <archivo.css>` | CSS adicional (se puede repetir)
|
|
161
|
-
| `--mermaid-theme <tema>` | `default`, `neutral`, `dark`, `forest`, `base`
|
|
162
|
-
| `--mermaid-flip <auto\|never>` | Si el autoajuste puede girar un diagrama de flujo de eje (ver abajo)
|
|
163
|
-
| `--no-mermaid-autofit` | Dibujar los diagramas de flujo tal como están escritos
|
|
164
|
-
| `--lang <código>` | Idioma del documento; `en` para inglés (`pt`, `fr`, `de`…)
|
|
165
|
-
| `--title <texto>` | Título del documento (muestra un bloque de título)
|
|
166
|
-
| `--config <archivo>` | Archivo de configuración
|
|
167
|
-
| `--no-config` | Ignorar `mdrender.config.json`
|
|
168
|
-
| `--browser <ruta>` | Ruta a Chrome/Edge/Chromium (o variable `MDRENDER_BROWSER`)
|
|
169
|
-
| `--allow-remote` | Permitir que el PDF descargue imágenes/CSS de internet
|
|
170
|
-
| `-w, --watch` | Regenerar al guardar
|
|
171
|
-
| `-q, --quiet` | Mostrar solo advertencias y errores
|
|
172
|
-
| `-v, --verbose` | Mostrar también configuración, navegador y tiempos
|
|
140
|
+
| Opción | Descripción | Por defecto |
|
|
141
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------ | --------------------- |
|
|
142
|
+
| `-o, --output <ruta>` | Archivo de salida, o carpeta con varios archivos | junto al `.md` |
|
|
143
|
+
| `-f, --format <pdf\|html>` | Formato de salida | `pdf` |
|
|
144
|
+
| `--page-size <tamaño>` | `Letter`, `A4`, `Legal` (también `A3`, `A5`, `Tabloid`) | `Letter` |
|
|
145
|
+
| `--margin <valor>` | Las cuatro márgenes como en CSS: `10mm`, `15mm 20mm`… | `10mm` |
|
|
146
|
+
| `--margin-top <medida>` | Margen superior, p. ej. `15mm` (prevalece sobre `--margin`) | `10mm` |
|
|
147
|
+
| `--margin-right <medida>` | Margen derecho | `10mm` |
|
|
148
|
+
| `--margin-bottom <medida>` | Margen inferior | `10mm` |
|
|
149
|
+
| `--margin-left <medida>` | Margen izquierdo | `10mm` |
|
|
150
|
+
| `--orientation <orientación>` | `portrait` (vertical) o `landscape` (horizontal) | `portrait` |
|
|
151
|
+
| `--landscape` | Atajo de `--orientation landscape` | — |
|
|
152
|
+
| `--toc` | Tabla de contenidos al inicio (o donde pongas `[[toc]]`) | — |
|
|
153
|
+
| `--toc-depth <n>` | Nivel de título más profundo en la tabla de contenidos | `3` |
|
|
154
|
+
| `--header <texto>` | Encabezado de página (ver abajo) | — |
|
|
155
|
+
| `--footer <texto>` | Pie de página (ver abajo) | `{page} / {pages}` |
|
|
156
|
+
| `--no-page-numbers` | Sin el pie con números de página | — |
|
|
157
|
+
| `--font <manrope\|inter>` | Tipografía del texto (ver abajo) | `manrope` |
|
|
158
|
+
| `--no-justify` | Párrafos alineados a la izquierda en el PDF (ver abajo) | justificado |
|
|
159
|
+
| `--density <densidad>` | `normal` o `compact` (menos espacio entre líneas y bloques) | `normal` |
|
|
160
|
+
| `--font-size <tamaño>` | Tamaño del texto en `pt` o `px`, de 6 a 24 pt; p. ej. `10pt` | `10.5pt` |
|
|
161
|
+
| `--theme <tema\|css>` | `antigravity`, `antigravity-dark`, `light`, `dark` o un `.css` que reemplaza el tema (ver abajo) | `antigravity` |
|
|
162
|
+
| `--css <archivo.css>` | CSS adicional (se puede repetir) | — |
|
|
163
|
+
| `--mermaid-theme <tema>` | `default`, `neutral`, `dark`, `forest`, `base` | el del tema de página |
|
|
164
|
+
| `--mermaid-flip <auto\|never>` | Si el autoajuste puede girar un diagrama de flujo de eje (ver abajo) | `auto` |
|
|
165
|
+
| `--no-mermaid-autofit` | Dibujar los diagramas de flujo tal como están escritos | — |
|
|
166
|
+
| `--lang <código>` | Idioma del documento; `en` para inglés (`pt`, `fr`, `de`…) | `es` |
|
|
167
|
+
| `--title <texto>` | Título del documento (muestra un bloque de título) | primer `# título` |
|
|
168
|
+
| `--config <archivo>` | Archivo de configuración | el más cercano |
|
|
169
|
+
| `--no-config` | Ignorar `mdrender.config.json` | — |
|
|
170
|
+
| `--browser <ruta>` | Ruta a Chrome/Edge/Chromium (o variable `MDRENDER_BROWSER`) | autodetección |
|
|
171
|
+
| `--allow-remote` | Permitir que el PDF descargue imágenes/CSS de internet | bloqueado |
|
|
172
|
+
| `-w, --watch` | Regenerar al guardar | — |
|
|
173
|
+
| `-q, --quiet` | Mostrar solo advertencias y errores | — |
|
|
174
|
+
| `-v, --verbose` | Mostrar también configuración, navegador y tiempos | — |
|
|
173
175
|
|
|
174
176
|
**Página**: por defecto hoja **Letter vertical con márgenes de 10 mm**. Las medidas aceptan
|
|
175
177
|
`mm`, `cm`, `in` o `px`. `--margin` fija las cuatro márgenes a la vez y `--margin-top`,
|
|
@@ -178,6 +180,21 @@ equipo); `--port` fija el puerto y `--no-open` no abre el navegador.
|
|
|
178
180
|
El encabezado y el pie se dibujan dentro de las márgenes superior e inferior: con menos de
|
|
179
181
|
10 mm pueden tocar el texto y mdrender lo advierte.
|
|
180
182
|
|
|
183
|
+
**Temas**: por defecto los documentos usan el estilo **Anti-Gravity**, tomado del design system
|
|
184
|
+
del mismo nombre y llevado de diapositivas a páginas:
|
|
185
|
+
|
|
186
|
+
- Manrope 600 en títulos con interletrado negativo, Manrope 400 en el texto.
|
|
187
|
+
- Etiquetas en JetBrains Mono, en mayúsculas: autor y fecha sobre el título, el índice, el
|
|
188
|
+
encabezado y el pie.
|
|
189
|
+
- Un único azul de acento para enlaces y etiquetas, superficies suaves sin bordes gruesos, y
|
|
190
|
+
alertas como tarjetas.
|
|
191
|
+
- Los diagramas Mermaid llevan los mismos colores.
|
|
192
|
+
- En la primera página, junto al título, un campo de luz muy tenue en azul, cian y violeta.
|
|
193
|
+
|
|
194
|
+
`--theme antigravity-dark` es su versión oscura. `--theme light` conserva el estilo de las
|
|
195
|
+
versiones anteriores y `--theme dark` su variante oscura. El design system pide texto alineado
|
|
196
|
+
a la izquierda: con este tema, usa `--no-justify` si quieres seguirlo al pie de la letra.
|
|
197
|
+
|
|
181
198
|
**Tipografía**: el texto usa [Manrope](https://fonts.google.com/specimen/Manrope);
|
|
182
199
|
`--font inter` (o `font: inter` en el front matter o en `mdrender.config.json`) vuelve a
|
|
183
200
|
[Inter](https://fonts.google.com/specimen/Inter), la tipografía de las versiones anteriores.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* mdrender Anti-Gravity dark stage: loaded after theme-antigravity.css, swaps its colours. */
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--ag-canvas: #0b0e13;
|
|
5
|
+
--ag-surface-subtle: #10141b;
|
|
6
|
+
--ag-surface-raised: #141922;
|
|
7
|
+
--ag-ink: #eef1f6;
|
|
8
|
+
--ag-ink-secondary: #b6bdc9;
|
|
9
|
+
--ag-ink-muted: #8f98a7;
|
|
10
|
+
--ag-hairline: #232a35;
|
|
11
|
+
--ag-hairline-strong: #3a4352;
|
|
12
|
+
--ag-accent: #7ea4ff;
|
|
13
|
+
--ag-accent-soft: #16213b;
|
|
14
|
+
--ag-opacity-field: 0.22;
|
|
15
|
+
--ag-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.35);
|
|
16
|
+
|
|
17
|
+
--alert-warning: #e3b341;
|
|
18
|
+
--alert-caution: #ff8a8a;
|
|
19
|
+
--color-error: #ffa198;
|
|
20
|
+
--color-error-bg: #2d1416;
|
|
21
|
+
--color-error-border: #8e1519;
|
|
22
|
+
|
|
23
|
+
--code-title: #b9a6ff;
|
|
24
|
+
--code-constant: #b9a6ff;
|
|
25
|
+
--code-string: #6fd3ec;
|
|
26
|
+
--code-builtin: #6fd3ec;
|
|
27
|
+
--code-added: #aff5b4;
|
|
28
|
+
--code-added-bg: #0d2e19;
|
|
29
|
+
--code-removed: #ffdcd7;
|
|
30
|
+
--code-removed-bg: #4a0f16;
|
|
31
|
+
color-scheme: dark;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Paint the whole sheet, margins included (the root background stops at the margins). */
|
|
35
|
+
@page {
|
|
36
|
+
background: #0b0e13;
|
|
37
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* mdrender Anti-Gravity theme (the default): loaded after theme.css. Colours, type and surfaces
|
|
3
|
+
* follow the Anti-Gravity design system (tokens.json), drawn for 1920 × 1080 slides and scaled
|
|
4
|
+
* here to a printed page. theme-antigravity-dark.css swaps the colours for its dark stage.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
/* Design system tokens */
|
|
9
|
+
--ag-canvas: #ffffff;
|
|
10
|
+
--ag-surface-subtle: #f6f8fb;
|
|
11
|
+
--ag-surface-raised: #ffffff;
|
|
12
|
+
--ag-ink: #0f1419;
|
|
13
|
+
--ag-ink-secondary: #454e5c;
|
|
14
|
+
--ag-ink-muted: #636c7a;
|
|
15
|
+
--ag-hairline: #e6e9ef;
|
|
16
|
+
--ag-hairline-strong: #c9d0db;
|
|
17
|
+
--ag-accent: #2456d3;
|
|
18
|
+
--ag-accent-soft: #ecf1fd;
|
|
19
|
+
--ag-field-blue: #4f7cff;
|
|
20
|
+
--ag-field-cyan: #22c3e6;
|
|
21
|
+
--ag-field-violet: #8c6cf0;
|
|
22
|
+
--ag-opacity-field: 0.16;
|
|
23
|
+
--ag-shadow-card: 0 1px 2px rgba(15, 20, 25, 0.04), 0 12px 32px rgba(15, 20, 25, 0.06);
|
|
24
|
+
|
|
25
|
+
/* The variables theme.css is written with */
|
|
26
|
+
--color-text: var(--ag-ink);
|
|
27
|
+
--color-muted: var(--ag-ink-muted);
|
|
28
|
+
--color-heading: var(--ag-ink);
|
|
29
|
+
--color-link: var(--ag-accent);
|
|
30
|
+
--color-border: var(--ag-hairline);
|
|
31
|
+
--color-subtle-bg: var(--ag-surface-subtle);
|
|
32
|
+
--color-accent: var(--ag-accent);
|
|
33
|
+
--color-bg: var(--ag-canvas);
|
|
34
|
+
--color-stripe: var(--ag-canvas);
|
|
35
|
+
/* Notes, tips and important points in the one accent. Warnings and cautions keep amber and
|
|
36
|
+
red: they carry risk, a deliberate exception to the system's single blue. */
|
|
37
|
+
--alert-note: var(--ag-accent);
|
|
38
|
+
--alert-tip: var(--ag-accent);
|
|
39
|
+
--alert-important: var(--ag-accent);
|
|
40
|
+
--alert-warning: #8a5d00;
|
|
41
|
+
--alert-caution: #c0262d;
|
|
42
|
+
|
|
43
|
+
/* Syntax highlighting: restrained, from the accent and the field hues (4.5:1 or better on
|
|
44
|
+
surface-subtle). */
|
|
45
|
+
--code-keyword: var(--ag-accent);
|
|
46
|
+
--code-title: #5b3fc4;
|
|
47
|
+
--code-constant: #5b3fc4;
|
|
48
|
+
--code-string: #0a6580;
|
|
49
|
+
--code-builtin: #0a6580;
|
|
50
|
+
--code-comment: var(--ag-ink-muted);
|
|
51
|
+
--code-tag: var(--ag-accent);
|
|
52
|
+
--code-text: var(--ag-ink);
|
|
53
|
+
--code-added: #116329;
|
|
54
|
+
--code-added-bg: #e6f6ea;
|
|
55
|
+
--code-removed: #a40e26;
|
|
56
|
+
--code-removed-bg: #fdecee;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Headings: Manrope 600, negative tracking, separated by white space rather than rules. */
|
|
60
|
+
h1,
|
|
61
|
+
h2,
|
|
62
|
+
h3,
|
|
63
|
+
h4,
|
|
64
|
+
h5,
|
|
65
|
+
h6 {
|
|
66
|
+
font-weight: 600;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
h1 {
|
|
70
|
+
font-size: 2.1em;
|
|
71
|
+
letter-spacing: -0.025em;
|
|
72
|
+
padding-bottom: 0;
|
|
73
|
+
border-bottom: 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
h2 {
|
|
77
|
+
font-size: 1.55em;
|
|
78
|
+
letter-spacing: -0.02em;
|
|
79
|
+
padding-bottom: 0;
|
|
80
|
+
border-bottom: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
h3 {
|
|
84
|
+
font-size: 1.15em;
|
|
85
|
+
letter-spacing: -0.01em;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
h4,
|
|
89
|
+
h5,
|
|
90
|
+
h6 {
|
|
91
|
+
font-size: 1em;
|
|
92
|
+
letter-spacing: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
h6 {
|
|
96
|
+
color: var(--ag-ink-secondary);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Title block as the system's TitleBlock: eyebrow (author · date), display title, lead. */
|
|
100
|
+
.doc-header {
|
|
101
|
+
display: flex;
|
|
102
|
+
flex-direction: column;
|
|
103
|
+
margin-bottom: 2.4em;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.doc-header .doc-meta {
|
|
107
|
+
order: -1;
|
|
108
|
+
margin: 0 0 1em;
|
|
109
|
+
padding-bottom: 0;
|
|
110
|
+
border-bottom: 0;
|
|
111
|
+
font-family: var(--font-code);
|
|
112
|
+
font-size: 0.78em;
|
|
113
|
+
font-weight: 500;
|
|
114
|
+
letter-spacing: 0.14em;
|
|
115
|
+
text-transform: uppercase;
|
|
116
|
+
color: var(--ag-accent);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.doc-header .doc-title {
|
|
120
|
+
margin: 0 0 0.35em;
|
|
121
|
+
font-size: 2.6em;
|
|
122
|
+
letter-spacing: -0.03em;
|
|
123
|
+
line-height: 1.12;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.doc-subtitle {
|
|
127
|
+
margin: 0;
|
|
128
|
+
font-size: 1.23em;
|
|
129
|
+
line-height: 1.4;
|
|
130
|
+
color: var(--ag-ink-secondary);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* The gradient field: soft light in the top-right corner of the title block (so only on the
|
|
135
|
+
* first page, and only when there is one), never under text: the title block's text keeps to
|
|
136
|
+
* the left 64%, the system's text measure. Each light fades out inside the box, so no edge shows.
|
|
137
|
+
*/
|
|
138
|
+
.doc-header {
|
|
139
|
+
position: relative;
|
|
140
|
+
z-index: 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.doc-header > * {
|
|
144
|
+
max-width: 64%;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.doc-header::before {
|
|
148
|
+
content: "";
|
|
149
|
+
position: absolute;
|
|
150
|
+
z-index: -1;
|
|
151
|
+
top: 0;
|
|
152
|
+
right: 0;
|
|
153
|
+
bottom: 0;
|
|
154
|
+
width: 36%;
|
|
155
|
+
opacity: var(--ag-opacity-field);
|
|
156
|
+
pointer-events: none;
|
|
157
|
+
background:
|
|
158
|
+
radial-gradient(28% 38% at 58% 45%, var(--ag-field-blue), transparent),
|
|
159
|
+
radial-gradient(16% 26% at 78% 58%, var(--ag-field-cyan), transparent),
|
|
160
|
+
radial-gradient(25% 30% at 40% 32%, var(--ag-field-violet), transparent);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Text */
|
|
164
|
+
li::marker {
|
|
165
|
+
color: var(--ag-ink-muted);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
blockquote {
|
|
169
|
+
padding: 0.8em 1.1em;
|
|
170
|
+
color: var(--ag-ink-secondary);
|
|
171
|
+
border-left: 0;
|
|
172
|
+
border-radius: 8px;
|
|
173
|
+
background: var(--ag-surface-subtle);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
hr {
|
|
177
|
+
background: var(--ag-hairline);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Code */
|
|
181
|
+
code {
|
|
182
|
+
border-radius: 4px;
|
|
183
|
+
background: var(--ag-accent-soft);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
pre {
|
|
187
|
+
border: 1px solid var(--ag-hairline);
|
|
188
|
+
border-radius: 8px;
|
|
189
|
+
background: var(--ag-surface-subtle);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* Tables: header on surface-subtle, hairline rules, no stripes. */
|
|
193
|
+
th,
|
|
194
|
+
td {
|
|
195
|
+
border-color: var(--ag-hairline);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
th {
|
|
199
|
+
background: var(--ag-surface-subtle);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Alerts as raised cards with a mono label; no left-border accents. */
|
|
203
|
+
.markdown-alert {
|
|
204
|
+
padding: 0.8em 1.1em;
|
|
205
|
+
color: var(--ag-ink);
|
|
206
|
+
border: 1px solid var(--ag-hairline);
|
|
207
|
+
border-radius: 12px;
|
|
208
|
+
background: var(--ag-surface-raised);
|
|
209
|
+
box-shadow: var(--ag-shadow-card);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.markdown-alert-title {
|
|
213
|
+
font-family: var(--font-code);
|
|
214
|
+
font-size: 0.78em;
|
|
215
|
+
font-weight: 500;
|
|
216
|
+
letter-spacing: 0.14em;
|
|
217
|
+
text-transform: uppercase;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Table of contents as a quiet panel with a mono label. */
|
|
221
|
+
.toc {
|
|
222
|
+
border-color: var(--ag-hairline);
|
|
223
|
+
border-radius: 12px;
|
|
224
|
+
background: var(--ag-surface-subtle);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.toc-title {
|
|
228
|
+
font-family: var(--font-code);
|
|
229
|
+
font-size: 0.78em;
|
|
230
|
+
font-weight: 500;
|
|
231
|
+
letter-spacing: 0.14em;
|
|
232
|
+
text-transform: uppercase;
|
|
233
|
+
color: var(--ag-accent);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Footnotes */
|
|
237
|
+
.footnotes {
|
|
238
|
+
color: var(--ag-ink-muted);
|
|
239
|
+
}
|
package/dist/assets.js
CHANGED
|
@@ -94,6 +94,8 @@ export const MERMAID_JS = "mermaid/dist/mermaid.min.js";
|
|
|
94
94
|
export const THEMES = [
|
|
95
95
|
"mdrender/assets/theme.css",
|
|
96
96
|
"mdrender/assets/theme-dark.css",
|
|
97
|
+
"mdrender/assets/theme-antigravity.css",
|
|
98
|
+
"mdrender/assets/theme-antigravity-dark.css",
|
|
97
99
|
"mdrender/assets/density-compact.css",
|
|
98
100
|
];
|
|
99
101
|
export const PACKAGE_JSON = "mdrender/package.json";
|
package/dist/cli.js
CHANGED
|
@@ -65,9 +65,11 @@ function addDocumentOptions(command) {
|
|
|
65
65
|
.option("--no-justify", "align paragraphs left in the PDF instead of justifying them")
|
|
66
66
|
.option("--density <density>", "normal or compact (tighter spacing) (default: normal)")
|
|
67
67
|
.option("--font-size <size>", "text size, e.g. 10pt or 11pt (default: 10.5pt)")
|
|
68
|
-
.option("--theme <theme>", "light, dark, or a .css file replacing the theme
|
|
68
|
+
.option("--theme <theme>", "antigravity, antigravity-dark, light, dark, or a .css file replacing the theme " +
|
|
69
|
+
"(default: antigravity)")
|
|
69
70
|
.option("--css <file>", "extra stylesheet (repeatable)", collect)
|
|
70
|
-
.option("--mermaid-theme <theme>", `Mermaid theme: ${MERMAID_THEMES.join(", ")}
|
|
71
|
+
.option("--mermaid-theme <theme>", `Mermaid theme: ${MERMAID_THEMES.join(", ")} ` +
|
|
72
|
+
"(default: the page theme's — base in Anti-Gravity colours, neutral for light, dark for dark)")
|
|
71
73
|
.option("--no-mermaid-autofit", "draw flowcharts exactly as written (no layout search)")
|
|
72
74
|
.option("--mermaid-flip <mode>", "auto: turn a flowchart to the other axis if its text prints too small; never (default: auto)")
|
|
73
75
|
.option("--lang <tag>", "document language, e.g. es or en (default: es)")
|
package/dist/convert.js
CHANGED
|
@@ -7,11 +7,12 @@ import { extractFrontMatter } from "./frontmatter.js";
|
|
|
7
7
|
import { strings } from "./i18n.js";
|
|
8
8
|
import { renderMarkdown } from "./markdown/index.js";
|
|
9
9
|
import { buildToc, tocPlaceholder } from "./markdown/toc.js";
|
|
10
|
-
import { DEFAULT_FONT_SIZE, fontSizePx, mergeOptions, normalizeOptions, OptionsError, resolveMargins, } from "./options.js";
|
|
10
|
+
import { BUILTIN_THEMES, DEFAULT_FONT_SIZE, fontSizePx, isDarkTheme, mergeOptions, normalizeOptions, OptionsError, resolveMargins, } from "./options.js";
|
|
11
11
|
import { BrowserSession } from "./render/browser.js";
|
|
12
12
|
import { DEFAULT_FOOTER, headerFooterTemplate } from "./render/header-footer.js";
|
|
13
13
|
import { fillMermaid, renderMermaid } from "./render/mermaid.js";
|
|
14
14
|
import { SMALL_SCALE } from "./render/mermaid-fit.js";
|
|
15
|
+
import { headerFooterStyle, mermaidThemeVariables } from "./render/antigravity.js";
|
|
15
16
|
import { FONT_FAMILIES, fontStack } from "./render/fonts.js";
|
|
16
17
|
import { contentHeightPx, contentWidthPx, lengthToPx, textWidthPx } from "./render/page.js";
|
|
17
18
|
import { buildHtmlDocument, builtinThemeCss, densityCss } from "./render/template.js";
|
|
@@ -52,7 +53,8 @@ function readStylesheet(file) {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
function themeStylesheets(theme) {
|
|
55
|
-
|
|
56
|
+
const builtin = BUILTIN_THEMES.find((name) => name === theme);
|
|
57
|
+
return builtin ? builtinThemeCss(builtin) : [readStylesheet(theme)];
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
60
|
* Chrome draws the header and footer inside the top and bottom margins. Measured: below about
|
|
@@ -126,7 +128,11 @@ export function describeLayout(layout) {
|
|
|
126
128
|
}
|
|
127
129
|
/** Mermaid theme: explicit choice, else dark diagrams for the dark page theme. */
|
|
128
130
|
export function effectiveMermaidTheme(options) {
|
|
129
|
-
|
|
131
|
+
if (options.mermaidTheme)
|
|
132
|
+
return options.mermaidTheme;
|
|
133
|
+
if (options.theme.startsWith("antigravity"))
|
|
134
|
+
return "base";
|
|
135
|
+
return isDarkTheme(options.theme) ? "dark" : "neutral";
|
|
130
136
|
}
|
|
131
137
|
/**
|
|
132
138
|
* Render a Markdown file to a complete HTML document. A browser is only started (through
|
|
@@ -188,6 +194,7 @@ paged = false) {
|
|
|
188
194
|
autofit: options.mermaidAutofit,
|
|
189
195
|
flip: options.mermaidFlip,
|
|
190
196
|
font: options.font,
|
|
197
|
+
themeVariables: theme === "base" ? mermaidThemeVariables(options.theme) : undefined,
|
|
191
198
|
});
|
|
192
199
|
const filled = fillMermaid(body, md.nonce, md.mermaid, results);
|
|
193
200
|
body = filled.html;
|
|
@@ -243,16 +250,17 @@ export async function convertFile(convert) {
|
|
|
243
250
|
const footer = options.footer ?? (options.pageNumbers ? DEFAULT_FOOTER : undefined);
|
|
244
251
|
const hasHeaderFooter = options.header !== undefined || footer !== undefined;
|
|
245
252
|
doc.diagnostics.push(...headerFooterSpaceWarnings(margin, options.header !== undefined, footer !== undefined));
|
|
253
|
+
const pageLook = headerFooterStyle(options.theme);
|
|
246
254
|
const session = await browsers.get();
|
|
247
255
|
const { pdf, blocked } = await session.printPdf(doc.html, {
|
|
248
256
|
format: options.pageSize,
|
|
249
257
|
landscape: options.orientation === "landscape",
|
|
250
258
|
margin,
|
|
251
259
|
headerTemplate: hasHeaderFooter
|
|
252
|
-
? headerFooterTemplate(options.header, values, margin, options.font)
|
|
260
|
+
? headerFooterTemplate(options.header, values, margin, options.font, pageLook)
|
|
253
261
|
: undefined,
|
|
254
262
|
footerTemplate: hasHeaderFooter
|
|
255
|
-
? headerFooterTemplate(footer, values, margin, options.font)
|
|
263
|
+
? headerFooterTemplate(footer, values, margin, options.font, pageLook)
|
|
256
264
|
: undefined,
|
|
257
265
|
allowRemote: convert.allowRemote,
|
|
258
266
|
softHyphensWidthPx: options.justify
|
package/dist/options.d.ts
CHANGED
|
@@ -13,7 +13,10 @@ export declare const MERMAID_THEMES: readonly ["default", "neutral", "dark", "fo
|
|
|
13
13
|
export type MermaidTheme = (typeof MERMAID_THEMES)[number];
|
|
14
14
|
export declare const MERMAID_FLIPS: readonly ["auto", "never"];
|
|
15
15
|
export type MermaidFlip = (typeof MERMAID_FLIPS)[number];
|
|
16
|
-
export declare const BUILTIN_THEMES: readonly ["light", "dark"];
|
|
16
|
+
export declare const BUILTIN_THEMES: readonly ["antigravity", "antigravity-dark", "light", "dark"];
|
|
17
|
+
export type BuiltinTheme = (typeof BUILTIN_THEMES)[number];
|
|
18
|
+
/** Built-in themes with a dark page. */
|
|
19
|
+
export declare const isDarkTheme: (theme: string) => boolean;
|
|
17
20
|
export declare const TEXT_FONTS: readonly ["manrope", "inter"];
|
|
18
21
|
export type TextFont = (typeof TEXT_FONTS)[number];
|
|
19
22
|
export declare const DENSITIES: readonly ["normal", "compact"];
|
|
@@ -37,7 +40,10 @@ export interface DocumentOptions {
|
|
|
37
40
|
/** Header/footer text; see render/header-footer.ts for placeholders and `|` columns. */
|
|
38
41
|
header?: string;
|
|
39
42
|
footer?: string;
|
|
40
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Mermaid theme; when unset, the page theme's: "base" coloured from the Anti-Gravity tokens,
|
|
45
|
+
* else "neutral" for light pages and "dark" for dark ones.
|
|
46
|
+
*/
|
|
41
47
|
mermaidTheme?: MermaidTheme;
|
|
42
48
|
/** Try several layouts of each flowchart and keep the one whose text prints largest. */
|
|
43
49
|
mermaidAutofit: boolean;
|
|
@@ -51,7 +57,7 @@ export interface DocumentOptions {
|
|
|
51
57
|
density: Density;
|
|
52
58
|
/** Base font size of the text, e.g. "10pt"; when unset, the theme's (10.5pt). */
|
|
53
59
|
fontSize?: string;
|
|
54
|
-
/**
|
|
60
|
+
/** A built-in theme (BUILTIN_THEMES), or the absolute path of a stylesheet replacing it. */
|
|
55
61
|
theme: string;
|
|
56
62
|
/** Extra stylesheets (absolute paths), applied after the built-in theme. */
|
|
57
63
|
css: string[];
|
package/dist/options.js
CHANGED
|
@@ -6,7 +6,9 @@ export const PAGE_SIZES = ["A3", "A4", "A5", "Letter", "Legal", "Tabloid"];
|
|
|
6
6
|
export const ORIENTATIONS = ["portrait", "landscape"];
|
|
7
7
|
export const MERMAID_THEMES = ["default", "neutral", "dark", "forest", "base"];
|
|
8
8
|
export const MERMAID_FLIPS = ["auto", "never"];
|
|
9
|
-
export const BUILTIN_THEMES = ["light", "dark"];
|
|
9
|
+
export const BUILTIN_THEMES = ["antigravity", "antigravity-dark", "light", "dark"];
|
|
10
|
+
/** Built-in themes with a dark page. */
|
|
11
|
+
export const isDarkTheme = (theme) => theme === "dark" || theme === "antigravity-dark";
|
|
10
12
|
export const TEXT_FONTS = ["manrope", "inter"];
|
|
11
13
|
export const DENSITIES = ["normal", "compact"];
|
|
12
14
|
export const DEFAULT_OPTIONS = {
|
|
@@ -21,7 +23,7 @@ export const DEFAULT_OPTIONS = {
|
|
|
21
23
|
font: "manrope",
|
|
22
24
|
justify: true,
|
|
23
25
|
density: "normal",
|
|
24
|
-
theme: "
|
|
26
|
+
theme: "antigravity",
|
|
25
27
|
css: [],
|
|
26
28
|
lang: DEFAULT_LANG,
|
|
27
29
|
};
|
|
@@ -129,7 +131,7 @@ const VALIDATORS = {
|
|
|
129
131
|
return builtin;
|
|
130
132
|
if (/\.css$/i.test(theme))
|
|
131
133
|
return path.resolve(baseDir, theme);
|
|
132
|
-
throw new OptionsError(`${describe} must be
|
|
134
|
+
throw new OptionsError(`${describe} must be ${BUILTIN_THEMES.join(", ")} or a .css file`);
|
|
133
135
|
},
|
|
134
136
|
css: (value, describe, baseDir) => {
|
|
135
137
|
const list = Array.isArray(value) ? value : [value];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const isAntigravityTheme: (theme: string) => boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Mermaid "base" theme variables for an Anti-Gravity page: nodes on accent-soft outlined in
|
|
4
|
+
* accent, edges and arrows in ink-muted, groups on surface-subtle. Undefined for other themes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function mermaidThemeVariables(theme: string): Record<string, string | boolean> | undefined;
|
|
7
|
+
export interface HeaderFooterStyle {
|
|
8
|
+
color: string;
|
|
9
|
+
/** Set in the mono family, uppercase and tracked, like the system's slide footers. */
|
|
10
|
+
mono: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** How page headers and footers look for a page theme. */
|
|
13
|
+
export declare function headerFooterStyle(theme: string): HeaderFooterStyle;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isDarkTheme } from "../options.js";
|
|
2
|
+
/**
|
|
3
|
+
* Anti-Gravity design system tokens needed outside the stylesheets (theme-antigravity.css):
|
|
4
|
+
* Mermaid draws its diagrams in a page of its own, and Chrome renders page headers and footers
|
|
5
|
+
* apart from the document, so neither sees the CSS variables.
|
|
6
|
+
*/
|
|
7
|
+
const TOKENS = {
|
|
8
|
+
light: {
|
|
9
|
+
canvas: "#ffffff",
|
|
10
|
+
surfaceSubtle: "#f6f8fb",
|
|
11
|
+
ink: "#0f1419",
|
|
12
|
+
inkSecondary: "#454e5c",
|
|
13
|
+
inkMuted: "#636c7a",
|
|
14
|
+
hairline: "#e6e9ef",
|
|
15
|
+
hairlineStrong: "#c9d0db",
|
|
16
|
+
accent: "#2456d3",
|
|
17
|
+
accentSoft: "#ecf1fd",
|
|
18
|
+
},
|
|
19
|
+
dark: {
|
|
20
|
+
canvas: "#0b0e13",
|
|
21
|
+
surfaceSubtle: "#10141b",
|
|
22
|
+
ink: "#eef1f6",
|
|
23
|
+
inkSecondary: "#b6bdc9",
|
|
24
|
+
inkMuted: "#8f98a7",
|
|
25
|
+
hairline: "#232a35",
|
|
26
|
+
hairlineStrong: "#3a4352",
|
|
27
|
+
accent: "#7ea4ff",
|
|
28
|
+
accentSoft: "#16213b",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const isAntigravityTheme = (theme) => theme.startsWith("antigravity");
|
|
32
|
+
const tokensFor = (theme) => (isDarkTheme(theme) ? TOKENS.dark : TOKENS.light);
|
|
33
|
+
/**
|
|
34
|
+
* Mermaid "base" theme variables for an Anti-Gravity page: nodes on accent-soft outlined in
|
|
35
|
+
* accent, edges and arrows in ink-muted, groups on surface-subtle. Undefined for other themes.
|
|
36
|
+
*/
|
|
37
|
+
export function mermaidThemeVariables(theme) {
|
|
38
|
+
if (!isAntigravityTheme(theme))
|
|
39
|
+
return undefined;
|
|
40
|
+
const t = tokensFor(theme);
|
|
41
|
+
return {
|
|
42
|
+
darkMode: isDarkTheme(theme),
|
|
43
|
+
background: t.canvas,
|
|
44
|
+
primaryColor: t.accentSoft,
|
|
45
|
+
primaryBorderColor: t.accent,
|
|
46
|
+
primaryTextColor: t.ink,
|
|
47
|
+
secondaryColor: t.surfaceSubtle,
|
|
48
|
+
secondaryBorderColor: t.hairlineStrong,
|
|
49
|
+
secondaryTextColor: t.ink,
|
|
50
|
+
tertiaryColor: t.canvas,
|
|
51
|
+
tertiaryBorderColor: t.hairlineStrong,
|
|
52
|
+
tertiaryTextColor: t.ink,
|
|
53
|
+
mainBkg: t.accentSoft,
|
|
54
|
+
nodeBorder: t.accent,
|
|
55
|
+
nodeTextColor: t.ink,
|
|
56
|
+
lineColor: t.inkMuted,
|
|
57
|
+
textColor: t.ink,
|
|
58
|
+
titleColor: t.ink,
|
|
59
|
+
clusterBkg: t.surfaceSubtle,
|
|
60
|
+
clusterBorder: t.hairlineStrong,
|
|
61
|
+
edgeLabelBackground: t.canvas,
|
|
62
|
+
noteBkgColor: t.surfaceSubtle,
|
|
63
|
+
noteBorderColor: t.hairlineStrong,
|
|
64
|
+
noteTextColor: t.ink,
|
|
65
|
+
actorBkg: t.accentSoft,
|
|
66
|
+
actorBorder: t.accent,
|
|
67
|
+
actorTextColor: t.ink,
|
|
68
|
+
actorLineColor: t.hairlineStrong,
|
|
69
|
+
signalColor: t.inkMuted,
|
|
70
|
+
signalTextColor: t.ink,
|
|
71
|
+
labelBoxBkgColor: t.surfaceSubtle,
|
|
72
|
+
labelBoxBorderColor: t.hairlineStrong,
|
|
73
|
+
labelTextColor: t.ink,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** How page headers and footers look for a page theme. */
|
|
77
|
+
export function headerFooterStyle(theme) {
|
|
78
|
+
if (isAntigravityTheme(theme))
|
|
79
|
+
return { color: tokensFor(theme).inkMuted, mono: true };
|
|
80
|
+
return { color: "#59636e", mono: false };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=antigravity.js.map
|
package/dist/render/fonts.d.ts
CHANGED
|
@@ -20,5 +20,7 @@ export declare function fontStack(font: TextFont): string;
|
|
|
20
20
|
export declare function inlineFontStylesheet(cssKey: string): string;
|
|
21
21
|
/** @font-face rules for every font a document uses, with the font files embedded. */
|
|
22
22
|
export declare function fontFaceCss(font?: TextFont): string;
|
|
23
|
+
/** JetBrains Mono Regular alone, for page headers/footers set in the mono family. */
|
|
24
|
+
export declare function monoRegularFontFace(): string;
|
|
23
25
|
/** The text font's regular weight alone, for page headers/footers (rendered apart from the page). */
|
|
24
26
|
export declare function regularFontFace(font?: TextFont): string;
|
package/dist/render/fonts.js
CHANGED
|
@@ -64,6 +64,12 @@ export function fontFaceCss(font = "manrope") {
|
|
|
64
64
|
}
|
|
65
65
|
return css;
|
|
66
66
|
}
|
|
67
|
+
let monoRegular;
|
|
68
|
+
/** JetBrains Mono Regular alone, for page headers/footers set in the mono family. */
|
|
69
|
+
export function monoRegularFontFace() {
|
|
70
|
+
monoRegular ??= inlineFontStylesheet(MONO_STYLESHEETS[0]);
|
|
71
|
+
return monoRegular;
|
|
72
|
+
}
|
|
67
73
|
const regularFaces = new Map();
|
|
68
74
|
/** The text font's regular weight alone, for page headers/footers (rendered apart from the page). */
|
|
69
75
|
export function regularFontFace(font = "manrope") {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TextFont } from "../options.js";
|
|
2
|
+
import type { HeaderFooterStyle } from "./antigravity.js";
|
|
2
3
|
/**
|
|
3
4
|
* Header/footer text with placeholders, in up to three columns separated by `|`:
|
|
4
5
|
*
|
|
@@ -19,5 +20,5 @@ export interface HeaderFooterValues {
|
|
|
19
20
|
export declare function headerFooterTemplate(spec: string | undefined, values: HeaderFooterValues, horizontalMargin: {
|
|
20
21
|
left: string;
|
|
21
22
|
right: string;
|
|
22
|
-
}, font?: TextFont): string;
|
|
23
|
+
}, font?: TextFont, style?: HeaderFooterStyle): string;
|
|
23
24
|
export declare const DEFAULT_FOOTER = "{page} / {pages}";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { escapeHtml } from "../html.js";
|
|
2
|
-
import { fontStack, regularFontFace } from "./fonts.js";
|
|
2
|
+
import { fontStack, monoRegularFontFace, regularFontFace } from "./fonts.js";
|
|
3
3
|
const CHROME_CLASSES = { page: "pageNumber", pages: "totalPages" };
|
|
4
4
|
function renderText(text, values) {
|
|
5
5
|
return escapeHtml(text.trim()).replace(/\{(\w+)\}/g, (match, name) => {
|
|
@@ -23,13 +23,18 @@ function columns(spec) {
|
|
|
23
23
|
* Chrome header/footer template. Chrome renders it apart from the page, so it carries its own
|
|
24
24
|
* styles and its own copy of the text font.
|
|
25
25
|
*/
|
|
26
|
-
export function headerFooterTemplate(spec, values, horizontalMargin, font = "manrope") {
|
|
26
|
+
export function headerFooterTemplate(spec, values, horizontalMargin, font = "manrope", style = { color: "#59636e", mono: false }) {
|
|
27
27
|
if (!spec)
|
|
28
28
|
return "<span></span>";
|
|
29
29
|
const [left, center, right] = columns(spec).map((c) => renderText(c, values));
|
|
30
|
-
|
|
30
|
+
// The font list sits in a style="…" attribute: single quotes only.
|
|
31
|
+
const look = style.mono
|
|
32
|
+
? `font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 7pt; ` +
|
|
33
|
+
`letter-spacing: 0.14em; text-transform: uppercase;`
|
|
34
|
+
: `font-family: ${fontStack(font).replaceAll('"', "'")}; font-size: 8pt;`;
|
|
35
|
+
return `<style>${style.mono ? monoRegularFontFace() : regularFontFace(font)}</style>
|
|
31
36
|
<div style="box-sizing: border-box; width: 100%; display: flex; padding: 0 ${horizontalMargin.right} 0 ${horizontalMargin.left};
|
|
32
|
-
|
|
37
|
+
${look} color: ${style.color};">
|
|
33
38
|
<span style="flex: 1; text-align: left;">${left}</span>
|
|
34
39
|
<span style="flex: 1; text-align: center;">${center}</span>
|
|
35
40
|
<span style="flex: 1; text-align: right;">${right}</span>
|
package/dist/render/mermaid.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface MermaidRenderOptions {
|
|
|
39
39
|
flip?: MermaidFlip;
|
|
40
40
|
/** Text font of the document, used for diagram labels too. */
|
|
41
41
|
font?: TextFont;
|
|
42
|
+
/** Extra Mermaid theme variables (the Anti-Gravity colours for the "base" theme). */
|
|
43
|
+
themeVariables?: Record<string, string | boolean>;
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Room kept for a heading printed together with the diagram below it (see keep-with-heading in
|
package/dist/render/mermaid.js
CHANGED
|
@@ -14,7 +14,7 @@ const DEFAULT_FONT_PX = 14;
|
|
|
14
14
|
*/
|
|
15
15
|
export const HEADING_ALLOWANCE_EM = 5;
|
|
16
16
|
let mermaidJs;
|
|
17
|
-
function mermaidConfig(theme, font, fontPx, wrap) {
|
|
17
|
+
function mermaidConfig(theme, font, fontPx, wrap, themeVariables = {}) {
|
|
18
18
|
const fontFamily = fontStack(font);
|
|
19
19
|
return {
|
|
20
20
|
startOnLoad: false,
|
|
@@ -23,7 +23,7 @@ function mermaidConfig(theme, font, fontPx, wrap) {
|
|
|
23
23
|
fontFamily,
|
|
24
24
|
// Sequence diagrams take their text sizes from here, the others from themeVariables.
|
|
25
25
|
fontSize: fontPx,
|
|
26
|
-
themeVariables: { fontFamily, fontSize: `${fontPx}px` },
|
|
26
|
+
themeVariables: { ...themeVariables, fontFamily, fontSize: `${fontPx}px` },
|
|
27
27
|
htmlLabels: true,
|
|
28
28
|
// Actors only at the top of sequence diagrams: repeating them below costs height.
|
|
29
29
|
sequence: { mirrorActors: false },
|
|
@@ -61,7 +61,7 @@ body { margin: 0; width: ${widthPx}px; font-family: ${fontStack(font)}; }</style
|
|
|
61
61
|
catch (error) {
|
|
62
62
|
return { error: String(error?.message ?? error) };
|
|
63
63
|
}
|
|
64
|
-
}, source, id, mermaidConfig(theme, font, fontPx, wrap));
|
|
64
|
+
}, source, id, mermaidConfig(theme, font, fontPx, wrap, options.themeVariables));
|
|
65
65
|
const results = [];
|
|
66
66
|
for (const [i, block] of blocks.entries()) {
|
|
67
67
|
const id = `mermaid-${i + 1}`;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { escapeHtml } from "../html.js";
|
|
2
|
-
import type { TextFont } from "../options.js";
|
|
2
|
+
import type { BuiltinTheme, TextFont } from "../options.js";
|
|
3
3
|
export { escapeHtml };
|
|
4
|
-
/** Stylesheets of a built-in theme
|
|
5
|
-
export declare function builtinThemeCss(theme:
|
|
4
|
+
/** Stylesheets of a built-in theme. */
|
|
5
|
+
export declare function builtinThemeCss(theme: BuiltinTheme): string[];
|
|
6
6
|
/** Stylesheet for a density other than "normal", applied after the theme. */
|
|
7
7
|
export declare function densityCss(density: "normal" | "compact"): string[];
|
|
8
8
|
export interface DocumentParts {
|
package/dist/render/template.js
CHANGED
|
@@ -13,9 +13,16 @@ function asset(name) {
|
|
|
13
13
|
}
|
|
14
14
|
return css;
|
|
15
15
|
}
|
|
16
|
-
/** Stylesheets of
|
|
16
|
+
/** Stylesheets of each built-in theme, applied in order. */
|
|
17
|
+
const THEME_FILES = {
|
|
18
|
+
antigravity: ["theme.css", "theme-antigravity.css"],
|
|
19
|
+
"antigravity-dark": ["theme.css", "theme-antigravity.css", "theme-antigravity-dark.css"],
|
|
20
|
+
light: ["theme.css"],
|
|
21
|
+
dark: ["theme.css", "theme-dark.css"],
|
|
22
|
+
};
|
|
23
|
+
/** Stylesheets of a built-in theme. */
|
|
17
24
|
export function builtinThemeCss(theme) {
|
|
18
|
-
return
|
|
25
|
+
return THEME_FILES[theme].map(asset);
|
|
19
26
|
}
|
|
20
27
|
/** Stylesheet for a density other than "normal", applied after the theme. */
|
|
21
28
|
export function densityCss(density) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imontene/mdrender",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Command-line app for Windows and Linux that renders Markdown — with LaTeX equations and Mermaid diagrams — to PDF and HTML set in Manrope or Inter",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|