@brahim.ariani/md2pdf-cli 1.2.0 → 1.2.1

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.
Files changed (2) hide show
  1. package/lib/index.js +67 -3
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -140,6 +140,52 @@ function normalizeBlockMath(src) {
140
140
  return out.join('\n');
141
141
  }
142
142
 
143
+ // Page dimensions in millimetres (portrait) for the formats Puppeteer accepts.
144
+ const PAGE_SIZES_MM = {
145
+ a0: [841, 1189],
146
+ a1: [594, 841],
147
+ a2: [420, 594],
148
+ a3: [297, 420],
149
+ a4: [210, 297],
150
+ a5: [148, 210],
151
+ a6: [105, 148],
152
+ letter: [215.9, 279.4],
153
+ legal: [215.9, 355.6],
154
+ tabloid: [279.4, 431.8],
155
+ ledger: [431.8, 279.4],
156
+ };
157
+
158
+ const PX_PER_MM = 96 / 25.4;
159
+
160
+ function lengthToMm(value, fallbackMm) {
161
+ if (value == null) return fallbackMm;
162
+ const m = String(value).trim().match(/^([\d.]+)\s*(mm|cm|in|px|pt)?$/i);
163
+ if (!m) return fallbackMm;
164
+ const n = parseFloat(m[1]);
165
+ switch ((m[2] || 'mm').toLowerCase()) {
166
+ case 'cm': return n * 10;
167
+ case 'in': return n * 25.4;
168
+ case 'pt': return (n / 72) * 25.4;
169
+ case 'px': return n / PX_PER_MM;
170
+ default: return n;
171
+ }
172
+ }
173
+
174
+ // Computes the usable content area (inside the page margins) in CSS pixels, so
175
+ // oversized diagrams can be scaled down to fit a single page.
176
+ function printableAreaPx(format, margin = {}) {
177
+ const size = PAGE_SIZES_MM[String(format || 'A4').toLowerCase()] || PAGE_SIZES_MM.a4;
178
+ const [wMm, hMm] = size;
179
+ const left = lengthToMm(margin.left, 0);
180
+ const right = lengthToMm(margin.right, 0);
181
+ const top = lengthToMm(margin.top, 0);
182
+ const bottom = lengthToMm(margin.bottom, 0);
183
+ return {
184
+ width: Math.max(1, (wMm - left - right) * PX_PER_MM),
185
+ height: Math.max(1, (hMm - top - bottom) * PX_PER_MM),
186
+ };
187
+ }
188
+
143
189
  async function convert(options) {
144
190
  const {
145
191
  input,
@@ -243,7 +289,9 @@ async function convert(options) {
243
289
 
244
290
  if (mermaid && (await page.$('.mermaid'))) {
245
291
  await page.addScriptTag({ content: getMermaidScript() });
246
- await page.evaluate(async (themeName) => {
292
+ const area = printableAreaPx(format, margin);
293
+ await page.evaluate(async (opts) => {
294
+ const { themeName, maxW, maxH } = opts;
247
295
  window.mermaid.initialize({
248
296
  startOnLoad: false,
249
297
  securityLevel: 'strict',
@@ -253,7 +301,23 @@ async function convert(options) {
253
301
  querySelector: '.mermaid',
254
302
  suppressErrors: true,
255
303
  });
256
- }, mermaidTheme);
304
+ // Scale any diagram larger than one page down to fit, keeping ratio.
305
+ document.querySelectorAll('.mermaid svg').forEach((svg) => {
306
+ const vb = svg.viewBox && svg.viewBox.baseVal;
307
+ let w = vb && vb.width;
308
+ let h = vb && vb.height;
309
+ if (!w || !h) {
310
+ const rect = svg.getBoundingClientRect();
311
+ w = rect.width;
312
+ h = rect.height;
313
+ }
314
+ if (!w || !h) return;
315
+ const scale = Math.min((maxW * 0.99) / w, (maxH * 0.98) / h, 1);
316
+ svg.style.maxWidth = 'none';
317
+ svg.style.width = `${Math.floor(w * scale)}px`;
318
+ svg.style.height = `${Math.floor(h * scale)}px`;
319
+ });
320
+ }, { themeName: mermaidTheme, maxW: area.width, maxH: area.height });
257
321
  }
258
322
 
259
323
  const pdfOptions = {
@@ -283,4 +347,4 @@ async function convert(options) {
283
347
  }
284
348
  }
285
349
 
286
- module.exports = { convert, defaultCss, renderMarkdown };
350
+ module.exports = { convert, defaultCss, renderMarkdown, printableAreaPx };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brahim.ariani/md2pdf-cli",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Convert Markdown files to beautifully styled PDFs using marked and puppeteer.",
5
5
  "keywords": [
6
6
  "markdown",