@masumdev/markforge 0.4.0 → 0.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/README.md +4 -4
- package/dist/App-JOOTPDJN.mjs +847 -0
- package/dist/{chunk-CRV7R2BG.mjs → chunk-H3ZUUSHP.mjs} +303 -98
- package/dist/{chunk-TNWZ4MFS.mjs → chunk-UNWAEVDU.mjs} +4 -3
- package/dist/cli.mjs +14 -6
- package/dist/index.d.mts +117 -50
- package/dist/index.d.ts +117 -50
- package/dist/index.js +838 -145
- package/dist/index.mjs +826 -139
- package/dist/{previewServer-XAUOBNBZ.mjs → previewServer-U47WQ5FV.mjs} +1 -1
- package/package.json +1 -1
- package/dist/App-3QDKBKHG.mjs +0 -328
|
@@ -183,7 +183,16 @@ function parseInlineSpans(text) {
|
|
|
183
183
|
remaining = remaining.slice(nextSpecial);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
-
|
|
186
|
+
const merged = [];
|
|
187
|
+
for (const s of spans) {
|
|
188
|
+
const prev = merged[merged.length - 1];
|
|
189
|
+
if (prev && prev.type === "text" && s.type === "text") {
|
|
190
|
+
prev.content += s.content;
|
|
191
|
+
} else {
|
|
192
|
+
merged.push(s);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return merged;
|
|
187
196
|
}
|
|
188
197
|
function slugify(text) {
|
|
189
198
|
return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -195,6 +204,7 @@ function applyHeadingNumbering(nodes, tocEntries, options) {
|
|
|
195
204
|
const counters = [0, 0, 0, 0, 0, 0];
|
|
196
205
|
for (const node of nodes) {
|
|
197
206
|
if (node.type === "heading" && node.level) {
|
|
207
|
+
if (node._numbered) continue;
|
|
198
208
|
const lvl = node.level;
|
|
199
209
|
if (lvl > depth) continue;
|
|
200
210
|
if (lvl === 1 && skipH1) continue;
|
|
@@ -210,6 +220,7 @@ function applyHeadingNumbering(nodes, tocEntries, options) {
|
|
|
210
220
|
const originalText = node.text || "";
|
|
211
221
|
node.text = fullPrefix + originalText;
|
|
212
222
|
node.inlines = parseInlineSpans(node.text);
|
|
223
|
+
node._numbered = true;
|
|
213
224
|
const toc = tocEntries.find((t) => t.id === node.id);
|
|
214
225
|
if (toc) {
|
|
215
226
|
toc.text = node.text;
|
|
@@ -557,6 +568,7 @@ import * as path2 from "path";
|
|
|
557
568
|
// src/core/imageResolver.ts
|
|
558
569
|
import * as fs from "fs";
|
|
559
570
|
import * as path from "path";
|
|
571
|
+
import { fileURLToPath } from "url";
|
|
560
572
|
var memoryImageCache = /* @__PURE__ */ new Map();
|
|
561
573
|
function getMimeType(filePathOrUrl) {
|
|
562
574
|
const clean = filePathOrUrl.split("?")[0].toLowerCase();
|
|
@@ -613,9 +625,19 @@ async function resolveImage(src, baseDir = process.cwd()) {
|
|
|
613
625
|
memoryImageCache.set(cacheKey, resolved2);
|
|
614
626
|
return resolved2;
|
|
615
627
|
}
|
|
616
|
-
let localPath =
|
|
628
|
+
let localPath = src;
|
|
629
|
+
if (src.startsWith("file://")) {
|
|
630
|
+
try {
|
|
631
|
+
localPath = fileURLToPath(src);
|
|
632
|
+
} catch {
|
|
633
|
+
localPath = src;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
if (!path.isAbsolute(localPath)) {
|
|
637
|
+
localPath = path.resolve(baseDir, localPath);
|
|
638
|
+
}
|
|
617
639
|
if (!fs.existsSync(localPath)) {
|
|
618
|
-
const cwdPath = path.resolve(process.cwd(), src);
|
|
640
|
+
const cwdPath = path.resolve(process.cwd(), src.startsWith("file://") ? localPath : src);
|
|
619
641
|
if (fs.existsSync(cwdPath)) {
|
|
620
642
|
localPath = cwdPath;
|
|
621
643
|
} else {
|
|
@@ -665,7 +687,7 @@ var THEME_COMPONENTS = `
|
|
|
665
687
|
.document-meta { font-size: 0.9rem; color: var(--mf-text-muted); display: flex; gap: 1.5rem; flex-wrap: wrap; }
|
|
666
688
|
|
|
667
689
|
/* Table of Contents */
|
|
668
|
-
.table-of-contents { background: var(--mf-card-bg); border: 1px solid var(--mf-border); border-radius: 8px; padding: 1.5rem 2rem; margin: 2rem 0; }
|
|
690
|
+
.table-of-contents { background: var(--mf-card-bg); border: 1px solid var(--mf-border); border-radius: 8px; padding: 1.5rem 2rem; margin: 2rem 0; page-break-after: always; break-after: page; }
|
|
669
691
|
.table-of-contents h2 { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--mf-text-muted); margin: 0 0 1rem 0; }
|
|
670
692
|
.table-of-contents ul { list-style: none; padding: 0; margin: 0; }
|
|
671
693
|
.table-of-contents li { padding: 0.25rem 0; }
|
|
@@ -738,11 +760,13 @@ var THEME_CORPORATE = `
|
|
|
738
760
|
}
|
|
739
761
|
body { background-color: var(--mf-bg); color: var(--mf-text); font-family: var(--mf-font-family); font-size: 15px; line-height: 1.65; margin: 0; padding: 2.5rem; }
|
|
740
762
|
.document-container { max-width: 860px; margin: 0 auto; position: relative; z-index: 1; }
|
|
741
|
-
h1, h2, h3, h4, h5, h6 { color: var(--mf-
|
|
742
|
-
h1 { font-size: 2.2rem; border-bottom:
|
|
763
|
+
h1, h2, h3, h4, h5, h6 { color: var(--mf-primary-dark); font-weight: 700; margin-top: 1.8rem; margin-bottom: 0.8rem; line-height: 1.25; }
|
|
764
|
+
h1 { font-size: 2.2rem; color: var(--mf-primary-dark); border-bottom: 2.5px solid var(--mf-primary); padding-bottom: 0.5rem; }
|
|
743
765
|
h2 { font-size: 1.6rem; color: var(--mf-primary-dark); border-bottom: 1px solid #CCFBF1; padding-bottom: 0.4rem; }
|
|
744
|
-
h3 { font-size: 1.3rem; }
|
|
745
|
-
h4 { font-size: 1.1rem; }
|
|
766
|
+
h3 { font-size: 1.3rem; color: var(--mf-primary-dark); }
|
|
767
|
+
h4 { font-size: 1.1rem; color: var(--mf-primary-dark); }
|
|
768
|
+
h5 { font-size: 1.0rem; color: var(--mf-primary-dark); }
|
|
769
|
+
h6 { font-size: 0.9rem; color: var(--mf-primary-dark); }
|
|
746
770
|
p { margin: 0.8rem 0; }
|
|
747
771
|
`;
|
|
748
772
|
var THEMES = {
|
|
@@ -783,11 +807,13 @@ function generateThemeCss(theme) {
|
|
|
783
807
|
}
|
|
784
808
|
body { background-color: var(--mf-bg); color: var(--mf-text); font-family: var(--mf-font-family); font-size: 15px; line-height: 1.65; margin: 0; padding: 2.5rem; }
|
|
785
809
|
.document-container { max-width: 860px; margin: 0 auto; position: relative; z-index: 1; }
|
|
786
|
-
h1, h2, h3, h4, h5, h6 { color: var(--mf-
|
|
787
|
-
h1 { font-size: 2.2rem; border-bottom:
|
|
810
|
+
h1, h2, h3, h4, h5, h6 { color: var(--mf-primary-dark); font-weight: 700; margin-top: 1.8rem; margin-bottom: 0.8rem; line-height: 1.25; }
|
|
811
|
+
h1 { font-size: 2.2rem; color: var(--mf-primary-dark); border-bottom: 2.5px solid var(--mf-primary); padding-bottom: 0.5rem; }
|
|
788
812
|
h2 { font-size: 1.6rem; color: var(--mf-primary-dark); border-bottom: 1px solid var(--mf-border); padding-bottom: 0.4rem; }
|
|
789
|
-
h3 { font-size: 1.3rem; }
|
|
790
|
-
h4 { font-size: 1.1rem; }
|
|
813
|
+
h3 { font-size: 1.3rem; color: var(--mf-primary-dark); }
|
|
814
|
+
h4 { font-size: 1.1rem; color: var(--mf-primary-dark); }
|
|
815
|
+
h5 { font-size: 1.0rem; color: var(--mf-primary-dark); }
|
|
816
|
+
h6 { font-size: 0.9rem; color: var(--mf-primary-dark); }
|
|
791
817
|
p { margin: 0.8rem 0; }
|
|
792
818
|
${theme.customCss || ""}
|
|
793
819
|
`;
|
|
@@ -1197,16 +1223,45 @@ function formatMarginCss(margin, defaultCss = "2.5cm") {
|
|
|
1197
1223
|
if (/^[0-9.]+$/.test(str)) return `${str}pt`;
|
|
1198
1224
|
return str;
|
|
1199
1225
|
}
|
|
1200
|
-
function replaceDocumentTokens(template = "", meta) {
|
|
1201
|
-
|
|
1202
|
-
|
|
1226
|
+
function replaceDocumentTokens(template = "", meta = {}) {
|
|
1227
|
+
if (!template) return "";
|
|
1228
|
+
const currentYear = meta.year ? String(meta.year) : (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
1229
|
+
const tokenMap = {
|
|
1230
|
+
title: meta.title ? String(meta.title) : "",
|
|
1231
|
+
subtitle: meta.subtitle ? String(meta.subtitle) : "",
|
|
1232
|
+
author: meta.author ? Array.isArray(meta.author) ? meta.author.join(", ") : String(meta.author) : "",
|
|
1233
|
+
version: meta.version ? String(meta.version) : "",
|
|
1234
|
+
date: meta.date ? String(meta.date) : "",
|
|
1235
|
+
company: meta.company ? String(meta.company) : "",
|
|
1236
|
+
year: currentYear
|
|
1237
|
+
};
|
|
1238
|
+
if (meta.metadata && typeof meta.metadata === "object") {
|
|
1239
|
+
for (const [key, val] of Object.entries(meta.metadata)) {
|
|
1240
|
+
if (val !== void 0 && val !== null) {
|
|
1241
|
+
tokenMap[key.toLowerCase()] = String(val);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
for (const [key, val] of Object.entries(meta)) {
|
|
1246
|
+
if (val !== void 0 && val !== null && typeof val !== "object") {
|
|
1247
|
+
tokenMap[key.toLowerCase()] = String(val);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
return template.replace(/\{([a-zA-Z0-9_\-]+)\}/gi, (match, tokenKey) => {
|
|
1251
|
+
const lowerKey = tokenKey.toLowerCase();
|
|
1252
|
+
if (lowerKey in tokenMap) {
|
|
1253
|
+
return tokenMap[lowerKey];
|
|
1254
|
+
}
|
|
1255
|
+
return match;
|
|
1256
|
+
});
|
|
1203
1257
|
}
|
|
1204
|
-
function normalizeWatermark(rawWatermark) {
|
|
1258
|
+
function normalizeWatermark(rawWatermark, tokens) {
|
|
1205
1259
|
if (!rawWatermark) {
|
|
1206
1260
|
return void 0;
|
|
1207
1261
|
}
|
|
1208
1262
|
if (typeof rawWatermark === "string") {
|
|
1209
|
-
|
|
1263
|
+
let text = rawWatermark.trim();
|
|
1264
|
+
if (tokens) text = replaceDocumentTokens(text, tokens);
|
|
1210
1265
|
if (!text) return void 0;
|
|
1211
1266
|
return {
|
|
1212
1267
|
text,
|
|
@@ -1219,8 +1274,10 @@ function normalizeWatermark(rawWatermark) {
|
|
|
1219
1274
|
}
|
|
1220
1275
|
if (typeof rawWatermark === "object") {
|
|
1221
1276
|
if (!rawWatermark.text || !rawWatermark.text.trim()) return void 0;
|
|
1277
|
+
let text = rawWatermark.text.trim();
|
|
1278
|
+
if (tokens) text = replaceDocumentTokens(text, tokens);
|
|
1222
1279
|
return {
|
|
1223
|
-
text
|
|
1280
|
+
text,
|
|
1224
1281
|
color: rawWatermark.color || "#94a3b8",
|
|
1225
1282
|
opacity: typeof rawWatermark.opacity === "number" ? rawWatermark.opacity : 0.08,
|
|
1226
1283
|
fontSize: rawWatermark.fontSize || 54,
|
|
@@ -1341,27 +1398,46 @@ function normalizeCoverPage(rawCover, tokenCtx = {}) {
|
|
|
1341
1398
|
const cfg = typeof rawCover === "object" ? rawCover : {};
|
|
1342
1399
|
if (cfg.enabled === false) return void 0;
|
|
1343
1400
|
const preset = cfg.preset || "modern";
|
|
1344
|
-
const title = cfg.title ? replaceDocumentTokens(String(cfg.title), tokenCtx) : tokenCtx.title
|
|
1345
|
-
const subtitle = cfg.subtitle ? replaceDocumentTokens(String(cfg.subtitle), tokenCtx) : tokenCtx.subtitle;
|
|
1346
|
-
const author = Array.isArray(cfg.author) ? cfg.author.join(", ") : cfg.author ? replaceDocumentTokens(String(cfg.author), tokenCtx) : tokenCtx.author;
|
|
1347
|
-
const company = cfg.company ? replaceDocumentTokens(String(cfg.company), tokenCtx) : tokenCtx.company;
|
|
1348
|
-
const version = cfg.version ? replaceDocumentTokens(String(cfg.version), tokenCtx) : tokenCtx.version;
|
|
1401
|
+
const title = cfg.title ? replaceDocumentTokens(String(cfg.title), tokenCtx) : tokenCtx.title ? String(tokenCtx.title) : "Document Title";
|
|
1402
|
+
const subtitle = cfg.subtitle ? replaceDocumentTokens(String(cfg.subtitle), tokenCtx) : tokenCtx.subtitle ? String(tokenCtx.subtitle) : void 0;
|
|
1403
|
+
const author = Array.isArray(cfg.author) ? cfg.author.join(", ") : cfg.author ? replaceDocumentTokens(String(cfg.author), tokenCtx) : tokenCtx.author ? String(tokenCtx.author) : void 0;
|
|
1404
|
+
const company = cfg.company ? replaceDocumentTokens(String(cfg.company), tokenCtx) : tokenCtx.company ? String(tokenCtx.company) : void 0;
|
|
1405
|
+
const version = cfg.version ? replaceDocumentTokens(String(cfg.version), tokenCtx) : tokenCtx.version ? String(tokenCtx.version) : void 0;
|
|
1349
1406
|
let dateStr;
|
|
1350
1407
|
if (typeof cfg.date === "string") {
|
|
1351
1408
|
dateStr = replaceDocumentTokens(cfg.date, tokenCtx);
|
|
1352
1409
|
} else if (cfg.date === true) {
|
|
1353
|
-
dateStr = tokenCtx.date
|
|
1410
|
+
dateStr = tokenCtx.date ? String(tokenCtx.date) : (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1354
1411
|
} else {
|
|
1355
|
-
dateStr = tokenCtx.date;
|
|
1412
|
+
dateStr = tokenCtx.date ? String(tokenCtx.date) : void 0;
|
|
1356
1413
|
}
|
|
1357
1414
|
const badge = cfg.badge ? replaceDocumentTokens(String(cfg.badge), tokenCtx) : void 0;
|
|
1358
1415
|
const badgeColor = typeof cfg.badgeColor === "string" ? cfg.badgeColor : void 0;
|
|
1359
1416
|
const badgeTextColor = typeof cfg.badgeTextColor === "string" ? cfg.badgeTextColor : void 0;
|
|
1360
1417
|
const logo = typeof cfg.logo === "string" ? cfg.logo : void 0;
|
|
1361
1418
|
const logoWidth = cfg.logoWidth;
|
|
1362
|
-
const bgGradient = typeof cfg.bgGradient === "string" ? cfg.bgGradient : void 0;
|
|
1419
|
+
const bgGradient = typeof cfg.bgGradient === "string" ? cfg.bgGradient : typeof cfg.backgroundColor === "string" ? cfg.backgroundColor : void 0;
|
|
1420
|
+
const backgroundColor = typeof cfg.backgroundColor === "string" ? cfg.backgroundColor : void 0;
|
|
1363
1421
|
const textColor = typeof cfg.textColor === "string" ? cfg.textColor : void 0;
|
|
1422
|
+
const titleColor = typeof cfg.titleColor === "string" ? cfg.titleColor : void 0;
|
|
1423
|
+
const subtitleColor = typeof cfg.subtitleColor === "string" ? cfg.subtitleColor : void 0;
|
|
1424
|
+
const accentColor = typeof cfg.accentColor === "string" ? cfg.accentColor : void 0;
|
|
1364
1425
|
const footerText = cfg.footerText ? replaceDocumentTokens(String(cfg.footerText), tokenCtx) : void 0;
|
|
1426
|
+
const address = cfg.address ? replaceDocumentTokens(String(cfg.address), tokenCtx) : void 0;
|
|
1427
|
+
const email = cfg.email ? replaceDocumentTokens(String(cfg.email), tokenCtx) : void 0;
|
|
1428
|
+
const phone = cfg.phone ? replaceDocumentTokens(String(cfg.phone), tokenCtx) : void 0;
|
|
1429
|
+
const website = cfg.website ? replaceDocumentTokens(String(cfg.website), tokenCtx) : void 0;
|
|
1430
|
+
let socialMap;
|
|
1431
|
+
if (cfg.social && typeof cfg.social === "object") {
|
|
1432
|
+
socialMap = {};
|
|
1433
|
+
for (const [k, v] of Object.entries(cfg.social)) {
|
|
1434
|
+
if (typeof v === "string") {
|
|
1435
|
+
socialMap[k] = replaceDocumentTokens(v, tokenCtx);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
1440
|
+
const copyright = cfg.copyright ? replaceDocumentTokens(String(cfg.copyright), { ...tokenCtx, year: currentYear }) : void 0;
|
|
1365
1441
|
return {
|
|
1366
1442
|
enabled: true,
|
|
1367
1443
|
preset,
|
|
@@ -1377,8 +1453,18 @@ function normalizeCoverPage(rawCover, tokenCtx = {}) {
|
|
|
1377
1453
|
logo,
|
|
1378
1454
|
logoWidth,
|
|
1379
1455
|
bgGradient,
|
|
1456
|
+
backgroundColor,
|
|
1380
1457
|
textColor,
|
|
1381
|
-
|
|
1458
|
+
titleColor,
|
|
1459
|
+
subtitleColor,
|
|
1460
|
+
accentColor,
|
|
1461
|
+
footerText,
|
|
1462
|
+
address,
|
|
1463
|
+
email,
|
|
1464
|
+
phone,
|
|
1465
|
+
website,
|
|
1466
|
+
social: socialMap,
|
|
1467
|
+
copyright
|
|
1382
1468
|
};
|
|
1383
1469
|
}
|
|
1384
1470
|
function normalizeBackCover(rawBack, tokenCtx = {}) {
|
|
@@ -1388,7 +1474,10 @@ function normalizeBackCover(rawBack, tokenCtx = {}) {
|
|
|
1388
1474
|
const preset = cfg.preset || "modern";
|
|
1389
1475
|
const title = cfg.title ? replaceDocumentTokens(String(cfg.title), tokenCtx) : "Thank You";
|
|
1390
1476
|
const subtitle = cfg.subtitle ? replaceDocumentTokens(String(cfg.subtitle), tokenCtx) : void 0;
|
|
1391
|
-
const
|
|
1477
|
+
const author = Array.isArray(cfg.author) ? cfg.author.join(", ") : cfg.author ? replaceDocumentTokens(String(cfg.author), tokenCtx) : tokenCtx.author ? String(tokenCtx.author) : void 0;
|
|
1478
|
+
const company = cfg.company ? replaceDocumentTokens(String(cfg.company), tokenCtx) : tokenCtx.company ? String(tokenCtx.company) : void 0;
|
|
1479
|
+
const version = cfg.version ? replaceDocumentTokens(String(cfg.version), tokenCtx) : tokenCtx.version ? String(tokenCtx.version) : void 0;
|
|
1480
|
+
const date = typeof cfg.date === "string" ? replaceDocumentTokens(cfg.date, tokenCtx) : tokenCtx.date ? String(tokenCtx.date) : void 0;
|
|
1392
1481
|
const address = cfg.address ? replaceDocumentTokens(String(cfg.address), tokenCtx) : void 0;
|
|
1393
1482
|
const email = cfg.email ? replaceDocumentTokens(String(cfg.email), tokenCtx) : void 0;
|
|
1394
1483
|
const phone = cfg.phone ? replaceDocumentTokens(String(cfg.phone), tokenCtx) : void 0;
|
|
@@ -1404,32 +1493,45 @@ function normalizeBackCover(rawBack, tokenCtx = {}) {
|
|
|
1404
1493
|
}
|
|
1405
1494
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
1406
1495
|
const copyright = cfg.copyright ? replaceDocumentTokens(String(cfg.copyright), { ...tokenCtx, year: currentYear }) : company ? `Copyright (c) ${currentYear} ${company}. All Rights Reserved.` : void 0;
|
|
1496
|
+
const footerText = cfg.footerText ? replaceDocumentTokens(String(cfg.footerText), tokenCtx) : void 0;
|
|
1407
1497
|
const badge = cfg.badge ? replaceDocumentTokens(String(cfg.badge), tokenCtx) : void 0;
|
|
1408
1498
|
const badgeColor = typeof cfg.badgeColor === "string" ? cfg.badgeColor : void 0;
|
|
1409
1499
|
const badgeTextColor = typeof cfg.badgeTextColor === "string" ? cfg.badgeTextColor : void 0;
|
|
1410
1500
|
const logo = typeof cfg.logo === "string" ? cfg.logo : void 0;
|
|
1411
1501
|
const logoWidth = cfg.logoWidth;
|
|
1412
|
-
const bgGradient = typeof cfg.bgGradient === "string" ? cfg.bgGradient : void 0;
|
|
1502
|
+
const bgGradient = typeof cfg.bgGradient === "string" ? cfg.bgGradient : typeof cfg.backgroundColor === "string" ? cfg.backgroundColor : void 0;
|
|
1503
|
+
const backgroundColor = typeof cfg.backgroundColor === "string" ? cfg.backgroundColor : void 0;
|
|
1413
1504
|
const textColor = typeof cfg.textColor === "string" ? cfg.textColor : void 0;
|
|
1505
|
+
const titleColor = typeof cfg.titleColor === "string" ? cfg.titleColor : void 0;
|
|
1506
|
+
const subtitleColor = typeof cfg.subtitleColor === "string" ? cfg.subtitleColor : void 0;
|
|
1507
|
+
const accentColor = typeof cfg.accentColor === "string" ? cfg.accentColor : void 0;
|
|
1414
1508
|
return {
|
|
1415
1509
|
enabled: true,
|
|
1416
1510
|
preset,
|
|
1417
1511
|
title,
|
|
1418
1512
|
subtitle,
|
|
1513
|
+
author,
|
|
1419
1514
|
company,
|
|
1515
|
+
version,
|
|
1516
|
+
date,
|
|
1420
1517
|
address,
|
|
1421
1518
|
email,
|
|
1422
1519
|
phone,
|
|
1423
1520
|
website,
|
|
1424
1521
|
social: socialMap,
|
|
1425
1522
|
copyright,
|
|
1523
|
+
footerText,
|
|
1426
1524
|
badge,
|
|
1427
1525
|
badgeColor,
|
|
1428
1526
|
badgeTextColor,
|
|
1429
1527
|
logo,
|
|
1430
1528
|
logoWidth,
|
|
1431
1529
|
bgGradient,
|
|
1432
|
-
|
|
1530
|
+
backgroundColor,
|
|
1531
|
+
textColor,
|
|
1532
|
+
titleColor,
|
|
1533
|
+
subtitleColor,
|
|
1534
|
+
accentColor
|
|
1433
1535
|
};
|
|
1434
1536
|
}
|
|
1435
1537
|
function normalizeNumberHeadings(raw) {
|
|
@@ -1469,7 +1571,15 @@ function resolveDocumentConfig(frontmatter = {}, userConfig = {}) {
|
|
|
1469
1571
|
const version = mergedMeta.version || void 0;
|
|
1470
1572
|
const company = mergedMeta.company || void 0;
|
|
1471
1573
|
const lang = mergedMeta.lang || "en";
|
|
1472
|
-
const tokenContext = {
|
|
1574
|
+
const tokenContext = {
|
|
1575
|
+
...mergedMeta,
|
|
1576
|
+
title,
|
|
1577
|
+
subtitle,
|
|
1578
|
+
author,
|
|
1579
|
+
version,
|
|
1580
|
+
date,
|
|
1581
|
+
company
|
|
1582
|
+
};
|
|
1473
1583
|
const theme = mergedMeta.theme || userConfig.theme || DEFAULT_CONFIG.theme;
|
|
1474
1584
|
const orientation = mergedMeta.orientation || userConfig.orientation || DEFAULT_CONFIG.orientation;
|
|
1475
1585
|
const paperSize = mergedMeta.paperSize || userConfig.paperSize || DEFAULT_CONFIG.paperSize;
|
|
@@ -1498,7 +1608,7 @@ function resolveDocumentConfig(frontmatter = {}, userConfig = {}) {
|
|
|
1498
1608
|
const footer = normalizeHeaderFooter(rawFooter, tokenContext);
|
|
1499
1609
|
const toc = typeof mergedMeta.toc === "boolean" ? mergedMeta.toc : typeof userConfig.toc === "boolean" ? userConfig.toc : DEFAULT_CONFIG.toc;
|
|
1500
1610
|
const rawWatermark = mergedMeta.watermark !== void 0 ? mergedMeta.watermark : userConfig.watermark !== void 0 ? userConfig.watermark : DEFAULT_CONFIG.watermark;
|
|
1501
|
-
const watermark = normalizeWatermark(rawWatermark);
|
|
1611
|
+
const watermark = normalizeWatermark(rawWatermark, tokenContext);
|
|
1502
1612
|
const rawSignatures = mergedMeta.signatures || userConfig.signatures;
|
|
1503
1613
|
const signatures = normalizeSignatures(rawSignatures, tokenContext);
|
|
1504
1614
|
const rawCover = mergedMeta.coverPage !== void 0 ? mergedMeta.coverPage : userConfig.coverPage;
|
|
@@ -1594,7 +1704,7 @@ var KATEX_INLINE_CSS = `
|
|
|
1594
1704
|
function escapeHtml(str) {
|
|
1595
1705
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1596
1706
|
}
|
|
1597
|
-
async function renderInlinesToHtml(spans = [], baseDir = process.cwd()) {
|
|
1707
|
+
async function renderInlinesToHtml(spans = [], baseDir = process.cwd(), tokens) {
|
|
1598
1708
|
let result = "";
|
|
1599
1709
|
for (const span of spans) {
|
|
1600
1710
|
if (span.type === "image" && span.url) {
|
|
@@ -1608,23 +1718,23 @@ async function renderInlinesToHtml(spans = [], baseDir = process.cwd()) {
|
|
|
1608
1718
|
continue;
|
|
1609
1719
|
}
|
|
1610
1720
|
if (span.type === "link" && span.url) {
|
|
1611
|
-
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir) : escapeHtml(span.content);
|
|
1721
|
+
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir, tokens) : escapeHtml(tokens ? replaceDocumentTokens(span.content, tokens) : span.content);
|
|
1612
1722
|
const title = span.title ? ` title="${escapeHtml(span.title)}"` : "";
|
|
1613
1723
|
result += `<a href="${escapeHtml(span.url)}"${title}>${inner}</a>`;
|
|
1614
1724
|
continue;
|
|
1615
1725
|
}
|
|
1616
1726
|
if (span.type === "bold") {
|
|
1617
|
-
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir) : escapeHtml(span.content);
|
|
1727
|
+
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir, tokens) : escapeHtml(tokens ? replaceDocumentTokens(span.content, tokens) : span.content);
|
|
1618
1728
|
result += `<strong>${inner}</strong>`;
|
|
1619
1729
|
continue;
|
|
1620
1730
|
}
|
|
1621
1731
|
if (span.type === "italic") {
|
|
1622
|
-
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir) : escapeHtml(span.content);
|
|
1732
|
+
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir, tokens) : escapeHtml(tokens ? replaceDocumentTokens(span.content, tokens) : span.content);
|
|
1623
1733
|
result += `<em>${inner}</em>`;
|
|
1624
1734
|
continue;
|
|
1625
1735
|
}
|
|
1626
1736
|
if (span.type === "strikethrough") {
|
|
1627
|
-
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir) : escapeHtml(span.content);
|
|
1737
|
+
const inner = span.children ? await renderInlinesToHtml(span.children, baseDir, tokens) : escapeHtml(tokens ? replaceDocumentTokens(span.content, tokens) : span.content);
|
|
1628
1738
|
result += `<del>${inner}</del>`;
|
|
1629
1739
|
continue;
|
|
1630
1740
|
}
|
|
@@ -1645,21 +1755,23 @@ async function renderInlinesToHtml(spans = [], baseDir = process.cwd()) {
|
|
|
1645
1755
|
result += span.content;
|
|
1646
1756
|
continue;
|
|
1647
1757
|
}
|
|
1648
|
-
|
|
1758
|
+
const content = tokens ? replaceDocumentTokens(span.content, tokens) : span.content;
|
|
1759
|
+
result += escapeHtml(content);
|
|
1649
1760
|
}
|
|
1650
1761
|
return result;
|
|
1651
1762
|
}
|
|
1652
|
-
async function renderNodesToHtml(nodes, resolved, baseDir = process.cwd()) {
|
|
1763
|
+
async function renderNodesToHtml(nodes, resolved, baseDir = process.cwd(), tokens) {
|
|
1653
1764
|
let bodyHtml = "";
|
|
1765
|
+
const tokenCtx = tokens || resolved;
|
|
1654
1766
|
for (const node of nodes) {
|
|
1655
1767
|
if (node.type === "heading") {
|
|
1656
|
-
const inner = await renderInlinesToHtml(node.inlines, baseDir);
|
|
1768
|
+
const inner = await renderInlinesToHtml(node.inlines, baseDir, tokenCtx);
|
|
1657
1769
|
bodyHtml += ` <h${node.level} id="${node.id}">${inner}</h${node.level}>
|
|
1658
1770
|
`;
|
|
1659
1771
|
continue;
|
|
1660
1772
|
}
|
|
1661
1773
|
if (node.type === "paragraph") {
|
|
1662
|
-
const inner = await renderInlinesToHtml(node.inlines, baseDir);
|
|
1774
|
+
const inner = await renderInlinesToHtml(node.inlines, baseDir, tokenCtx);
|
|
1663
1775
|
bodyHtml += ` <p>${inner}</p>
|
|
1664
1776
|
`;
|
|
1665
1777
|
continue;
|
|
@@ -1674,7 +1786,7 @@ async function renderNodesToHtml(nodes, resolved, baseDir = process.cwd()) {
|
|
|
1674
1786
|
const gap = node.columnGap || "1.5rem";
|
|
1675
1787
|
let colChildrenHtml = "";
|
|
1676
1788
|
for (const col of node.children || []) {
|
|
1677
|
-
const colInner = await renderNodesToHtml(col.children || [], resolved, baseDir);
|
|
1789
|
+
const colInner = await renderNodesToHtml(col.children || [], resolved, baseDir, tokenCtx);
|
|
1678
1790
|
colChildrenHtml += ` <div class="markforge-col">
|
|
1679
1791
|
${colInner} </div>
|
|
1680
1792
|
`;
|
|
@@ -1700,7 +1812,7 @@ ${escapeHtml(node.text || "")}
|
|
|
1700
1812
|
continue;
|
|
1701
1813
|
}
|
|
1702
1814
|
if (node.type === "callout") {
|
|
1703
|
-
const inner = await renderInlinesToHtml(node.inlines, baseDir);
|
|
1815
|
+
const inner = await renderInlinesToHtml(node.inlines, baseDir, tokenCtx);
|
|
1704
1816
|
const CALLOUT_STYLES = {
|
|
1705
1817
|
NOTE: { bg: "#ECFDFD", border: "#33CDCF", titleColor: "#009DA0" },
|
|
1706
1818
|
TIP: { bg: "#ecfdf5", border: "#10b981", titleColor: "#10b981" },
|
|
@@ -1720,7 +1832,7 @@ ${escapeHtml(node.text || "")}
|
|
|
1720
1832
|
continue;
|
|
1721
1833
|
}
|
|
1722
1834
|
if (node.type === "blockquote") {
|
|
1723
|
-
const inner = await renderInlinesToHtml(node.inlines, baseDir);
|
|
1835
|
+
const inner = await renderInlinesToHtml(node.inlines, baseDir, tokenCtx);
|
|
1724
1836
|
bodyHtml += ` <blockquote>${inner}</blockquote>
|
|
1725
1837
|
`;
|
|
1726
1838
|
continue;
|
|
@@ -1734,7 +1846,7 @@ ${escapeHtml(node.text || "")}
|
|
|
1734
1846
|
for (const cell of row.children || []) {
|
|
1735
1847
|
const tag = cell.isHeader ? "th" : "td";
|
|
1736
1848
|
const align = cell.align ? ` align="${cell.align}"` : "";
|
|
1737
|
-
const inner = await renderInlinesToHtml(cell.inlines, baseDir);
|
|
1849
|
+
const inner = await renderInlinesToHtml(cell.inlines, baseDir, tokenCtx);
|
|
1738
1850
|
bodyHtml += ` <${tag}${align}>${inner}</${tag}>
|
|
1739
1851
|
`;
|
|
1740
1852
|
}
|
|
@@ -1750,7 +1862,7 @@ ${escapeHtml(node.text || "")}
|
|
|
1750
1862
|
bodyHtml += ` <${tag}>
|
|
1751
1863
|
`;
|
|
1752
1864
|
for (const item of node.children) {
|
|
1753
|
-
const inner = await renderInlinesToHtml(item.inlines, baseDir);
|
|
1865
|
+
const inner = await renderInlinesToHtml(item.inlines, baseDir, tokenCtx);
|
|
1754
1866
|
bodyHtml += ` <li>${inner}</li>
|
|
1755
1867
|
`;
|
|
1756
1868
|
}
|
|
@@ -2063,8 +2175,8 @@ async function renderBackCoverHtml(backCover, baseDir = process.cwd()) {
|
|
|
2063
2175
|
`;
|
|
2064
2176
|
return { html, css };
|
|
2065
2177
|
}
|
|
2066
|
-
async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
2067
|
-
var _a;
|
|
2178
|
+
async function buildHtmlDocument(doc, config = {}, baseDir = process.cwd()) {
|
|
2179
|
+
var _a, _b;
|
|
2068
2180
|
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
2069
2181
|
const baseThemeCss = generateThemeCss(resolved.theme);
|
|
2070
2182
|
let customCss = "";
|
|
@@ -2160,6 +2272,9 @@ async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2160
2272
|
bodyHtml += ` </header>
|
|
2161
2273
|
`;
|
|
2162
2274
|
}
|
|
2275
|
+
if (((_b = resolved.numberHeadings) == null ? void 0 : _b.enabled) !== false && resolved.numberHeadings) {
|
|
2276
|
+
applyHeadingNumbering(doc.nodes, doc.tocEntries, resolved.numberHeadings);
|
|
2277
|
+
}
|
|
2163
2278
|
if (resolved.toc && doc.tocEntries.length > 0) {
|
|
2164
2279
|
bodyHtml += ` <nav class="table-of-contents">
|
|
2165
2280
|
`;
|
|
@@ -2175,12 +2290,26 @@ async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2175
2290
|
</nav>
|
|
2176
2291
|
`;
|
|
2177
2292
|
}
|
|
2178
|
-
|
|
2293
|
+
const mergedTokens = {
|
|
2294
|
+
...config.metadata,
|
|
2295
|
+
...doc.metadata,
|
|
2296
|
+
...resolved,
|
|
2297
|
+
title: resolved.title,
|
|
2298
|
+
subtitle: resolved.subtitle,
|
|
2299
|
+
author: resolved.author,
|
|
2300
|
+
version: resolved.version,
|
|
2301
|
+
date: resolved.date,
|
|
2302
|
+
company: resolved.company
|
|
2303
|
+
};
|
|
2304
|
+
const nodesHtml = await renderNodesToHtml(doc.nodes, resolved, baseDir, mergedTokens);
|
|
2305
|
+
bodyHtml += ` <main class="markforge-content-body">
|
|
2306
|
+
${nodesHtml} </main>
|
|
2307
|
+
`;
|
|
2179
2308
|
let footnotesHtml = "";
|
|
2180
2309
|
if (doc.footnoteDefs && doc.footnoteDefs.length > 0) {
|
|
2181
2310
|
let fnListHtml = "";
|
|
2182
2311
|
for (const def of doc.footnoteDefs) {
|
|
2183
|
-
const defInner = await renderInlinesToHtml(def.inlines, baseDir);
|
|
2312
|
+
const defInner = await renderInlinesToHtml(def.inlines, baseDir, mergedTokens);
|
|
2184
2313
|
fnListHtml += ` <li id="fn-${escapeHtml(def.id)}">${defInner} <a href="#fnref-${escapeHtml(def.id)}" class="markforge-fn-return">↩</a></li>
|
|
2185
2314
|
`;
|
|
2186
2315
|
}
|
|
@@ -2218,17 +2347,7 @@ ${fnListHtml} </ol>
|
|
|
2218
2347
|
}
|
|
2219
2348
|
@media print {
|
|
2220
2349
|
.document-watermark {
|
|
2221
|
-
|
|
2222
|
-
top: 0;
|
|
2223
|
-
left: 0;
|
|
2224
|
-
right: 0;
|
|
2225
|
-
bottom: 0;
|
|
2226
|
-
width: 100vw;
|
|
2227
|
-
height: 100vh;
|
|
2228
|
-
pointer-events: none;
|
|
2229
|
-
z-index: 0;
|
|
2230
|
-
-webkit-print-color-adjust: exact;
|
|
2231
|
-
print-color-adjust: exact;
|
|
2350
|
+
display: none !important;
|
|
2232
2351
|
}
|
|
2233
2352
|
}
|
|
2234
2353
|
`;
|
|
@@ -2414,8 +2533,11 @@ function escapeXml(str) {
|
|
|
2414
2533
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2415
2534
|
}
|
|
2416
2535
|
function generateWatermarkPngBuffer(chromePath, wm) {
|
|
2417
|
-
const
|
|
2418
|
-
const
|
|
2536
|
+
const tmpId = Math.random().toString(36).substring(2, 9);
|
|
2537
|
+
const tmpDir = os.tmpdir();
|
|
2538
|
+
const tmpHtml = path3.join(tmpDir, `markforge-wm-${tmpId}.html`);
|
|
2539
|
+
const tmpPng = path3.join(tmpDir, `markforge-wm-${tmpId}.png`);
|
|
2540
|
+
const tmpProfile = path3.join(tmpDir, `markforge-wm-prof-${tmpId}`);
|
|
2419
2541
|
try {
|
|
2420
2542
|
const text = escapeXml(wm.text.toUpperCase());
|
|
2421
2543
|
const fontSize = (wm.fontSize || 52) * 1.5;
|
|
@@ -2466,6 +2588,9 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2466
2588
|
chromePath,
|
|
2467
2589
|
[
|
|
2468
2590
|
"--headless=new",
|
|
2591
|
+
`--user-data-dir=${tmpProfile}`,
|
|
2592
|
+
"--no-first-run",
|
|
2593
|
+
"--no-default-browser-check",
|
|
2469
2594
|
"--disable-gpu",
|
|
2470
2595
|
"--disable-sync",
|
|
2471
2596
|
"--disable-extensions",
|
|
@@ -2487,6 +2612,7 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2487
2612
|
try {
|
|
2488
2613
|
if (fs3.existsSync(tmpHtml)) fs3.unlinkSync(tmpHtml);
|
|
2489
2614
|
if (fs3.existsSync(tmpPng)) fs3.unlinkSync(tmpPng);
|
|
2615
|
+
if (fs3.existsSync(tmpProfile)) fs3.rmSync(tmpProfile, { recursive: true, force: true });
|
|
2490
2616
|
} catch {
|
|
2491
2617
|
}
|
|
2492
2618
|
}
|
|
@@ -2502,6 +2628,8 @@ function findChromeExecutable() {
|
|
|
2502
2628
|
const winLocalAppData = process.env.LOCALAPPDATA ?? "";
|
|
2503
2629
|
const winProgramFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
2504
2630
|
const winProgramFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
2631
|
+
const winProgramW6432 = process.env.ProgramW6432 ?? "C:\\Program Files";
|
|
2632
|
+
const winUserProfile = process.env.USERPROFILE ?? "";
|
|
2505
2633
|
const candidates = [
|
|
2506
2634
|
// Linux
|
|
2507
2635
|
"/usr/bin/google-chrome",
|
|
@@ -2520,17 +2648,34 @@ function findChromeExecutable() {
|
|
|
2520
2648
|
// Windows — Microsoft Edge (Native Windows 10/11 browser, enterprise whitelist friendly)
|
|
2521
2649
|
`${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2522
2650
|
`${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2651
|
+
`${winProgramW6432}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2523
2652
|
`${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2524
|
-
|
|
2653
|
+
`${winLocalAppData}\\Microsoft\\Edge Dev\\Application\\msedge.exe`,
|
|
2654
|
+
`${winLocalAppData}\\Microsoft\\Edge Beta\\Application\\msedge.exe`,
|
|
2655
|
+
// Windows — Google Chrome & Chrome SxS (Canary)
|
|
2525
2656
|
`${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2526
2657
|
`${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2658
|
+
`${winProgramW6432}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2527
2659
|
`${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2660
|
+
`${winLocalAppData}\\Google\\Chrome SxS\\Application\\chrome.exe`,
|
|
2528
2661
|
// Windows — Brave Browser
|
|
2529
2662
|
`${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2530
2663
|
`${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2664
|
+
`${winProgramW6432}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2531
2665
|
`${winLocalAppData}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2532
2666
|
// Windows — Chromium
|
|
2533
|
-
`${winLocalAppData}\\Chromium\\Application\\chrome.exe
|
|
2667
|
+
`${winLocalAppData}\\Chromium\\Application\\chrome.exe`,
|
|
2668
|
+
// Windows — Scoop Package Manager
|
|
2669
|
+
`${winUserProfile}\\scoop\\apps\\googlechrome\\current\\chrome.exe`,
|
|
2670
|
+
`${winUserProfile}\\scoop\\apps\\chromium\\current\\chrome.exe`,
|
|
2671
|
+
`${winUserProfile}\\scoop\\apps\\brave\\current\\brave.exe`,
|
|
2672
|
+
`${winUserProfile}\\scoop\\apps\\msedge\\current\\msedge.exe`,
|
|
2673
|
+
`${winUserProfile}\\scoop\\shims\\chrome.exe`,
|
|
2674
|
+
`${winUserProfile}\\scoop\\shims\\msedge.exe`,
|
|
2675
|
+
// Windows — Chocolatey
|
|
2676
|
+
"C:\\ProgramData\\chocolatey\\bin\\chrome.exe",
|
|
2677
|
+
"C:\\ProgramData\\chocolatey\\bin\\msedge.exe",
|
|
2678
|
+
"C:\\ProgramData\\chocolatey\\bin\\brave.exe"
|
|
2534
2679
|
].filter(Boolean);
|
|
2535
2680
|
for (const candidate of candidates) {
|
|
2536
2681
|
try {
|
|
@@ -2541,13 +2686,15 @@ function findChromeExecutable() {
|
|
|
2541
2686
|
}
|
|
2542
2687
|
}
|
|
2543
2688
|
try {
|
|
2544
|
-
const cmd = isWin ? "where" : "which";
|
|
2545
|
-
const names = isWin ? ["chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
|
|
2689
|
+
const cmd = isWin ? "where.exe" : "which";
|
|
2690
|
+
const names = isWin ? ["chrome.exe", "msedge.exe", "brave.exe", "chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
|
|
2546
2691
|
for (const name of names) {
|
|
2547
|
-
const res = spawnSync(cmd, [name], { encoding: "utf-8" });
|
|
2692
|
+
const res = spawnSync(cmd, [name], { encoding: "utf-8", windowsHide: true });
|
|
2548
2693
|
if (res.status === 0 && res.stdout.trim()) {
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2694
|
+
const lines = res.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
2695
|
+
for (const line of lines) {
|
|
2696
|
+
if (fs3.existsSync(line)) return line;
|
|
2697
|
+
}
|
|
2551
2698
|
}
|
|
2552
2699
|
}
|
|
2553
2700
|
} catch {
|
|
@@ -2555,7 +2702,7 @@ function findChromeExecutable() {
|
|
|
2555
2702
|
return null;
|
|
2556
2703
|
}
|
|
2557
2704
|
function injectPagedMediaStyles(html, config, metadata) {
|
|
2558
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2705
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
2559
2706
|
const resolved = resolveDocumentConfig(metadata || {}, config);
|
|
2560
2707
|
const size = resolved.paperSize;
|
|
2561
2708
|
const orientation = resolved.orientation;
|
|
@@ -2630,9 +2777,11 @@ function injectPagedMediaStyles(html, config, metadata) {
|
|
|
2630
2777
|
min-height: 100vh;
|
|
2631
2778
|
height: 100vh;
|
|
2632
2779
|
box-sizing: border-box;
|
|
2780
|
+
break-before: page;
|
|
2781
|
+
break-after: avoid;
|
|
2633
2782
|
}` : "";
|
|
2634
|
-
const
|
|
2635
|
-
@page {
|
|
2783
|
+
const tocPageCss = resolved.toc ? `
|
|
2784
|
+
@page toc-page {
|
|
2636
2785
|
size: ${size} ${orientation};
|
|
2637
2786
|
margin-top: ${top};
|
|
2638
2787
|
margin-bottom: ${bottom};
|
|
@@ -2643,9 +2792,36 @@ function injectPagedMediaStyles(html, config, metadata) {
|
|
|
2643
2792
|
${buildZoneCss("top-right", (_e = resolved.header) == null ? void 0 : _e.right)}
|
|
2644
2793
|
${buildZoneCss("bottom-left", (_f = resolved.footer) == null ? void 0 : _f.left)}
|
|
2645
2794
|
${buildZoneCss("bottom-center", (_g = resolved.footer) == null ? void 0 : _g.center)}
|
|
2646
|
-
|
|
2795
|
+
@bottom-right {
|
|
2796
|
+
content: counter(page, lower-roman);
|
|
2797
|
+
font-size: 9pt;
|
|
2798
|
+
color: #94a3b8;
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
.table-of-contents {
|
|
2802
|
+
page: toc-page;
|
|
2803
|
+
page-break-after: always;
|
|
2804
|
+
break-after: page;
|
|
2805
|
+
}
|
|
2806
|
+
.markforge-content-body {
|
|
2807
|
+
counter-reset: page 1;
|
|
2808
|
+
}` : "";
|
|
2809
|
+
const pagedCss = `
|
|
2810
|
+
@page {
|
|
2811
|
+
size: ${size} ${orientation};
|
|
2812
|
+
margin-top: ${top};
|
|
2813
|
+
margin-bottom: ${bottom};
|
|
2814
|
+
margin-left: ${left};
|
|
2815
|
+
margin-right: ${right};
|
|
2816
|
+
${buildZoneCss("top-left", (_h = resolved.header) == null ? void 0 : _h.left)}
|
|
2817
|
+
${buildZoneCss("top-center", (_i = resolved.header) == null ? void 0 : _i.center)}
|
|
2818
|
+
${buildZoneCss("top-right", (_j = resolved.header) == null ? void 0 : _j.right)}
|
|
2819
|
+
${buildZoneCss("bottom-left", (_k = resolved.footer) == null ? void 0 : _k.left)}
|
|
2820
|
+
${buildZoneCss("bottom-center", (_l = resolved.footer) == null ? void 0 : _l.center)}
|
|
2821
|
+
${buildZoneCss("bottom-right", (_m = resolved.footer) == null ? void 0 : _m.right, true)}
|
|
2647
2822
|
}
|
|
2648
2823
|
${coverPageCss}
|
|
2824
|
+
${tocPageCss}
|
|
2649
2825
|
${backCoverCss}
|
|
2650
2826
|
@media print {
|
|
2651
2827
|
body { padding: 0; }
|
|
@@ -2776,9 +2952,10 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2776
2952
|
const wmPng = generateWatermarkPngBuffer(chromePath, resolved.watermark);
|
|
2777
2953
|
if (wmPng) {
|
|
2778
2954
|
const embeddedPng = await pdfDoc.embedPng(wmPng);
|
|
2955
|
+
const totalPages = pdfDoc.getPageCount();
|
|
2779
2956
|
const pages = pdfDoc.getPages();
|
|
2780
2957
|
const startPageIndex = ((_b = resolved.coverPage) == null ? void 0 : _b.enabled) ? 1 : 0;
|
|
2781
|
-
const endPageIndex = ((_c = resolved.backCover) == null ? void 0 : _c.enabled) ?
|
|
2958
|
+
const endPageIndex = ((_c = resolved.backCover) == null ? void 0 : _c.enabled) ? totalPages - 1 : totalPages;
|
|
2782
2959
|
for (let i = startPageIndex; i < endPageIndex; i++) {
|
|
2783
2960
|
const page = pages[i];
|
|
2784
2961
|
const { width, height } = page.getSize();
|
|
@@ -2863,7 +3040,10 @@ import {
|
|
|
2863
3040
|
convertMillimetersToTwip,
|
|
2864
3041
|
ShadingType,
|
|
2865
3042
|
ExternalHyperlink,
|
|
2866
|
-
TabStopType
|
|
3043
|
+
TabStopType,
|
|
3044
|
+
PageBreak,
|
|
3045
|
+
NumberFormat,
|
|
3046
|
+
SectionType
|
|
2867
3047
|
} from "docx";
|
|
2868
3048
|
|
|
2869
3049
|
// src/core/mermaid/mermaidRenderer.ts
|
|
@@ -2881,6 +3061,8 @@ async function renderMermaidToPng(mermaidCode, _baseDir = process.cwd()) {
|
|
|
2881
3061
|
const tmpDir = os2.tmpdir();
|
|
2882
3062
|
const tmpHtml = path4.join(tmpDir, `mermaid_${tmpId}.html`);
|
|
2883
3063
|
const tmpScreenshot = path4.join(tmpDir, `mermaid_${tmpId}.png`);
|
|
3064
|
+
const tmpProfile = path4.join(tmpDir, `mermaid_prof_${tmpId}`);
|
|
3065
|
+
const isWin = process.platform === "win32";
|
|
2884
3066
|
const htmlContent = `<!DOCTYPE html>
|
|
2885
3067
|
<html>
|
|
2886
3068
|
<head>
|
|
@@ -2924,10 +3106,14 @@ ${mermaidCode}
|
|
|
2924
3106
|
const res = spawnSync2(
|
|
2925
3107
|
chromePath,
|
|
2926
3108
|
[
|
|
2927
|
-
"--headless",
|
|
3109
|
+
"--headless=new",
|
|
3110
|
+
`--user-data-dir=${tmpProfile}`,
|
|
3111
|
+
"--no-first-run",
|
|
3112
|
+
"--no-default-browser-check",
|
|
2928
3113
|
"--disable-gpu",
|
|
2929
|
-
"--
|
|
2930
|
-
"--disable-
|
|
3114
|
+
"--disable-sync",
|
|
3115
|
+
"--disable-extensions",
|
|
3116
|
+
...isWin ? [] : ["--no-sandbox", "--disable-setuid-sandbox"],
|
|
2931
3117
|
"--allow-file-access-from-files",
|
|
2932
3118
|
"--disable-web-security",
|
|
2933
3119
|
"--disable-software-rasterizer",
|
|
@@ -2936,7 +3122,7 @@ ${mermaidCode}
|
|
|
2936
3122
|
`--screenshot=${tmpScreenshot}`,
|
|
2937
3123
|
fileUrl
|
|
2938
3124
|
],
|
|
2939
|
-
{ timeout: 15e3 }
|
|
3125
|
+
{ timeout: 15e3, windowsHide: true }
|
|
2940
3126
|
);
|
|
2941
3127
|
if (res.status === 0 && fs4.existsSync(tmpScreenshot)) {
|
|
2942
3128
|
const buffer = fs4.readFileSync(tmpScreenshot);
|
|
@@ -2947,6 +3133,7 @@ ${mermaidCode}
|
|
|
2947
3133
|
try {
|
|
2948
3134
|
if (fs4.existsSync(tmpHtml)) fs4.unlinkSync(tmpHtml);
|
|
2949
3135
|
if (fs4.existsSync(tmpScreenshot)) fs4.unlinkSync(tmpScreenshot);
|
|
3136
|
+
if (fs4.existsSync(tmpProfile)) fs4.rmSync(tmpProfile, { recursive: true, force: true });
|
|
2950
3137
|
} catch {
|
|
2951
3138
|
}
|
|
2952
3139
|
}
|
|
@@ -3125,7 +3312,7 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd(), opt
|
|
|
3125
3312
|
return runs;
|
|
3126
3313
|
}
|
|
3127
3314
|
async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
3128
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3315
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3129
3316
|
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
3130
3317
|
const docElements = [];
|
|
3131
3318
|
const themeProps = typeof resolved.theme === "object" ? resolved.theme : {};
|
|
@@ -3197,6 +3384,9 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3197
3384
|
);
|
|
3198
3385
|
}
|
|
3199
3386
|
}
|
|
3387
|
+
if (((_b = resolved.numberHeadings) == null ? void 0 : _b.enabled) !== false && resolved.numberHeadings) {
|
|
3388
|
+
applyHeadingNumbering(doc.nodes, doc.tocEntries, resolved.numberHeadings);
|
|
3389
|
+
}
|
|
3200
3390
|
if (resolved.toc) {
|
|
3201
3391
|
const headingNodes = doc.nodes.filter(
|
|
3202
3392
|
(n) => n.type === "heading" && typeof n.level === "number" && n.level >= 1 && n.level <= 3
|
|
@@ -3266,7 +3456,11 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3266
3456
|
]
|
|
3267
3457
|
});
|
|
3268
3458
|
docElements.push(tocCard);
|
|
3269
|
-
docElements.push(
|
|
3459
|
+
docElements.push(
|
|
3460
|
+
new Paragraph({
|
|
3461
|
+
children: [new PageBreak()]
|
|
3462
|
+
})
|
|
3463
|
+
);
|
|
3270
3464
|
}
|
|
3271
3465
|
}
|
|
3272
3466
|
for (const node of doc.nodes) {
|
|
@@ -3276,7 +3470,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3276
3470
|
font: defaultFont,
|
|
3277
3471
|
size: 34,
|
|
3278
3472
|
// 17pt
|
|
3279
|
-
color:
|
|
3473
|
+
color: primaryDarkHex,
|
|
3280
3474
|
bold: true
|
|
3281
3475
|
});
|
|
3282
3476
|
docElements.push(
|
|
@@ -3322,7 +3516,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3322
3516
|
font: defaultFont,
|
|
3323
3517
|
size: 22,
|
|
3324
3518
|
// 11pt
|
|
3325
|
-
color:
|
|
3519
|
+
color: primaryDarkHex,
|
|
3326
3520
|
bold: true
|
|
3327
3521
|
});
|
|
3328
3522
|
docElements.push(
|
|
@@ -3552,7 +3746,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3552
3746
|
}
|
|
3553
3747
|
if (node.type === "table" && node.children) {
|
|
3554
3748
|
const tableRows = [];
|
|
3555
|
-
const numCols = ((
|
|
3749
|
+
const numCols = ((_d = (_c = node.children[0]) == null ? void 0 : _c.children) == null ? void 0 : _d.length) || 1;
|
|
3556
3750
|
const colWidth = Math.floor(9e3 / numCols);
|
|
3557
3751
|
for (let rowIdx = 0; rowIdx < node.children.length; rowIdx++) {
|
|
3558
3752
|
const rowNode = node.children[rowIdx];
|
|
@@ -3562,7 +3756,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3562
3756
|
if (rowNode.children) {
|
|
3563
3757
|
for (let colIdx = 0; colIdx < rowNode.children.length; colIdx++) {
|
|
3564
3758
|
const cellNode = rowNode.children[colIdx];
|
|
3565
|
-
const align = (
|
|
3759
|
+
const align = (_e = node.align) == null ? void 0 : _e[colIdx];
|
|
3566
3760
|
let alignment = AlignmentType.LEFT;
|
|
3567
3761
|
if (align === "center") alignment = AlignmentType.CENTER;
|
|
3568
3762
|
if (align === "right") alignment = AlignmentType.RIGHT;
|
|
@@ -3869,7 +4063,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3869
4063
|
const centerPos = Math.round(contentWidthTwip / 2);
|
|
3870
4064
|
const rightPos = contentWidthTwip;
|
|
3871
4065
|
const headerRuns = [];
|
|
3872
|
-
if ((
|
|
4066
|
+
if ((_f = resolved.header) == null ? void 0 : _f.left) {
|
|
3873
4067
|
headerRuns.push(
|
|
3874
4068
|
new TextRun({
|
|
3875
4069
|
text: resolved.header.left.text,
|
|
@@ -3882,7 +4076,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3882
4076
|
);
|
|
3883
4077
|
}
|
|
3884
4078
|
headerRuns.push(new TextRun({ text: " " }));
|
|
3885
|
-
if ((
|
|
4079
|
+
if ((_g = resolved.header) == null ? void 0 : _g.center) {
|
|
3886
4080
|
headerRuns.push(
|
|
3887
4081
|
new TextRun({
|
|
3888
4082
|
text: resolved.header.center.text,
|
|
@@ -3895,7 +4089,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3895
4089
|
);
|
|
3896
4090
|
}
|
|
3897
4091
|
headerRuns.push(new TextRun({ text: " " }));
|
|
3898
|
-
if ((
|
|
4092
|
+
if ((_h = resolved.header) == null ? void 0 : _h.right) {
|
|
3899
4093
|
headerRuns.push(
|
|
3900
4094
|
new TextRun({
|
|
3901
4095
|
text: resolved.header.right.text,
|
|
@@ -3934,7 +4128,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3934
4128
|
]
|
|
3935
4129
|
}) : void 0;
|
|
3936
4130
|
const footerRuns = [];
|
|
3937
|
-
if ((
|
|
4131
|
+
if ((_i = resolved.footer) == null ? void 0 : _i.left) {
|
|
3938
4132
|
footerRuns.push(
|
|
3939
4133
|
new TextRun({
|
|
3940
4134
|
text: resolved.footer.left.text,
|
|
@@ -3947,7 +4141,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3947
4141
|
);
|
|
3948
4142
|
}
|
|
3949
4143
|
footerRuns.push(new TextRun({ text: " " }));
|
|
3950
|
-
if ((
|
|
4144
|
+
if ((_j = resolved.footer) == null ? void 0 : _j.center) {
|
|
3951
4145
|
footerRuns.push(
|
|
3952
4146
|
new TextRun({
|
|
3953
4147
|
text: resolved.footer.center.text,
|
|
@@ -3960,7 +4154,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3960
4154
|
);
|
|
3961
4155
|
}
|
|
3962
4156
|
footerRuns.push(new TextRun({ text: " " }));
|
|
3963
|
-
if ((
|
|
4157
|
+
if ((_k = resolved.footer) == null ? void 0 : _k.right) {
|
|
3964
4158
|
const rZone = resolved.footer.right;
|
|
3965
4159
|
const rColor = rZone.color.replace("#", "");
|
|
3966
4160
|
const rSize = (rZone.fontSize || 9) * 2;
|
|
@@ -4058,6 +4252,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4058
4252
|
);
|
|
4059
4253
|
docSections.push({
|
|
4060
4254
|
properties: {
|
|
4255
|
+
type: SectionType.NEXT_PAGE,
|
|
4061
4256
|
page: {
|
|
4062
4257
|
size: {
|
|
4063
4258
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4072,14 +4267,19 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4072
4267
|
}
|
|
4073
4268
|
}
|
|
4074
4269
|
},
|
|
4075
|
-
headers:
|
|
4076
|
-
footers:
|
|
4270
|
+
headers: { default: new Header({ children: [] }) },
|
|
4271
|
+
footers: { default: new Footer({ children: [] }) },
|
|
4077
4272
|
children: coverElements
|
|
4078
4273
|
});
|
|
4079
4274
|
}
|
|
4080
4275
|
docSections.push({
|
|
4081
4276
|
properties: {
|
|
4277
|
+
type: SectionType.NEXT_PAGE,
|
|
4082
4278
|
page: {
|
|
4279
|
+
pageNumbers: {
|
|
4280
|
+
start: 1,
|
|
4281
|
+
formatType: NumberFormat.DECIMAL
|
|
4282
|
+
},
|
|
4083
4283
|
size: {
|
|
4084
4284
|
width: resolved.paperDimensions.widthTwip,
|
|
4085
4285
|
height: resolved.paperDimensions.heightTwip,
|
|
@@ -4095,8 +4295,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4095
4295
|
}
|
|
4096
4296
|
}
|
|
4097
4297
|
},
|
|
4098
|
-
headers: docHeader ? { default: docHeader } :
|
|
4099
|
-
footers: docFooter ? { default: docFooter } :
|
|
4298
|
+
headers: docHeader ? { default: docHeader } : { default: new Header({ children: [] }) },
|
|
4299
|
+
footers: docFooter ? { default: docFooter } : { default: new Footer({ children: [] }) },
|
|
4100
4300
|
children: docElements
|
|
4101
4301
|
});
|
|
4102
4302
|
if (resolved.backCover && resolved.backCover.enabled) {
|
|
@@ -4111,6 +4311,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4111
4311
|
);
|
|
4112
4312
|
docSections.push({
|
|
4113
4313
|
properties: {
|
|
4314
|
+
type: SectionType.NEXT_PAGE,
|
|
4114
4315
|
page: {
|
|
4115
4316
|
size: {
|
|
4116
4317
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4125,8 +4326,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4125
4326
|
}
|
|
4126
4327
|
}
|
|
4127
4328
|
},
|
|
4128
|
-
headers:
|
|
4129
|
-
footers:
|
|
4329
|
+
headers: { default: new Header({ children: [] }) },
|
|
4330
|
+
footers: { default: new Footer({ children: [] }) },
|
|
4130
4331
|
children: backElements
|
|
4131
4332
|
});
|
|
4132
4333
|
}
|
|
@@ -4530,8 +4731,12 @@ function createEmptyDocxCell(widthDxa) {
|
|
|
4530
4731
|
}
|
|
4531
4732
|
|
|
4532
4733
|
export {
|
|
4734
|
+
applyHeadingNumbering,
|
|
4533
4735
|
parseMarkdownDocument,
|
|
4736
|
+
replaceDocumentTokens,
|
|
4737
|
+
resolveDocumentConfig,
|
|
4534
4738
|
buildHtmlDocument,
|
|
4739
|
+
findChromeExecutable,
|
|
4535
4740
|
buildPdfDocument,
|
|
4536
4741
|
buildDocxDocument
|
|
4537
4742
|
};
|