@masumdev/markforge 0.4.1 → 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 +2 -2
- package/dist/App-JOOTPDJN.mjs +847 -0
- package/dist/{chunk-R6DT335C.mjs → chunk-H3ZUUSHP.mjs} +77 -23
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +44 -12
- package/dist/index.d.ts +44 -12
- package/dist/index.js +608 -67
- package/dist/index.mjs +595 -61
- package/dist/{previewServer-4EELOUAV.mjs → previewServer-U47WQ5FV.mjs} +1 -1
- package/package.json +1 -1
- package/dist/App-TPDCT2VL.mjs +0 -393
package/dist/index.js
CHANGED
|
@@ -38,6 +38,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
38
38
|
// src/index.ts
|
|
39
39
|
var src_exports = {};
|
|
40
40
|
__export(src_exports, {
|
|
41
|
+
BackCoverPreset: () => BackCoverPreset,
|
|
42
|
+
CoverPagePreset: () => CoverPagePreset,
|
|
41
43
|
DEFAULT_CONFIG: () => DEFAULT_CONFIG,
|
|
42
44
|
KATEX_INLINE_CSS: () => KATEX_INLINE_CSS,
|
|
43
45
|
MARKFORGE_VERSION: () => MARKFORGE_VERSION,
|
|
@@ -46,6 +48,8 @@ __export(src_exports, {
|
|
|
46
48
|
PAPER_DIMENSIONS_TWIP: () => PAPER_DIMENSIONS_TWIP,
|
|
47
49
|
PaperSizeEnum: () => PaperSizeEnum,
|
|
48
50
|
SYNTAX_COLORS: () => SYNTAX_COLORS,
|
|
51
|
+
SignatureAlign: () => SignatureAlign,
|
|
52
|
+
SignatureStyle: () => SignatureStyle,
|
|
49
53
|
SyntaxTheme: () => SyntaxTheme,
|
|
50
54
|
THEMES: () => THEMES,
|
|
51
55
|
THEME_CORPORATE: () => THEME_CORPORATE,
|
|
@@ -56,6 +60,9 @@ __export(src_exports, {
|
|
|
56
60
|
buildDocxDocument: () => buildDocxDocument,
|
|
57
61
|
buildHtmlDocument: () => buildHtmlDocument,
|
|
58
62
|
buildPdfDocument: () => buildPdfDocument,
|
|
63
|
+
buildPngDocument: () => buildPngDocument,
|
|
64
|
+
buildTextDocument: () => buildTextDocument,
|
|
65
|
+
buildTxtDocument: () => buildTextDocument,
|
|
59
66
|
compileMarkdown: () => compileMarkdown,
|
|
60
67
|
defineConfig: () => defineConfig,
|
|
61
68
|
escapeHtml: () => escapeHtml,
|
|
@@ -84,6 +91,7 @@ __export(src_exports, {
|
|
|
84
91
|
renderBackCoverHtml: () => renderBackCoverHtml,
|
|
85
92
|
renderCoverPageHtml: () => renderCoverPageHtml,
|
|
86
93
|
renderInlinesToHtml: () => renderInlinesToHtml,
|
|
94
|
+
renderInlinesToText: () => renderInlinesToText,
|
|
87
95
|
renderMathToHtml: () => renderMathToHtml,
|
|
88
96
|
renderMermaidToPng: () => renderMermaidToPng,
|
|
89
97
|
renderNodesToHtml: () => renderNodesToHtml,
|
|
@@ -97,8 +105,8 @@ __export(src_exports, {
|
|
|
97
105
|
module.exports = __toCommonJS(src_exports);
|
|
98
106
|
|
|
99
107
|
// src/core/engine.ts
|
|
100
|
-
var
|
|
101
|
-
var
|
|
108
|
+
var fs7 = __toESM(require("fs"));
|
|
109
|
+
var path7 = __toESM(require("path"));
|
|
102
110
|
|
|
103
111
|
// src/core/parser.ts
|
|
104
112
|
var import_gray_matter = __toESM(require("gray-matter"));
|
|
@@ -656,6 +664,7 @@ var import_docx = require("docx");
|
|
|
656
664
|
// src/core/imageResolver.ts
|
|
657
665
|
var fs = __toESM(require("fs"));
|
|
658
666
|
var path = __toESM(require("path"));
|
|
667
|
+
var import_node_url = require("url");
|
|
659
668
|
var memoryImageCache = /* @__PURE__ */ new Map();
|
|
660
669
|
function getMimeType(filePathOrUrl) {
|
|
661
670
|
const clean = filePathOrUrl.split("?")[0].toLowerCase();
|
|
@@ -712,9 +721,19 @@ async function resolveImage(src, baseDir = process.cwd()) {
|
|
|
712
721
|
memoryImageCache.set(cacheKey, resolved2);
|
|
713
722
|
return resolved2;
|
|
714
723
|
}
|
|
715
|
-
let localPath =
|
|
724
|
+
let localPath = src;
|
|
725
|
+
if (src.startsWith("file://")) {
|
|
726
|
+
try {
|
|
727
|
+
localPath = (0, import_node_url.fileURLToPath)(src);
|
|
728
|
+
} catch {
|
|
729
|
+
localPath = src;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
if (!path.isAbsolute(localPath)) {
|
|
733
|
+
localPath = path.resolve(baseDir, localPath);
|
|
734
|
+
}
|
|
716
735
|
if (!fs.existsSync(localPath)) {
|
|
717
|
-
const cwdPath = path.resolve(process.cwd(), src);
|
|
736
|
+
const cwdPath = path.resolve(process.cwd(), src.startsWith("file://") ? localPath : src);
|
|
718
737
|
if (fs.existsSync(cwdPath)) {
|
|
719
738
|
localPath = cwdPath;
|
|
720
739
|
} else {
|
|
@@ -1116,13 +1135,13 @@ var import_node_child_process2 = require("child_process");
|
|
|
1116
1135
|
var fs5 = __toESM(require("fs"));
|
|
1117
1136
|
var os2 = __toESM(require("os"));
|
|
1118
1137
|
var path5 = __toESM(require("path"));
|
|
1119
|
-
var
|
|
1138
|
+
var import_node_url4 = require("url");
|
|
1120
1139
|
|
|
1121
1140
|
// src/core/pdf/pdfBuilder.ts
|
|
1122
1141
|
var fs4 = __toESM(require("fs"));
|
|
1123
1142
|
var path4 = __toESM(require("path"));
|
|
1124
1143
|
var os = __toESM(require("os"));
|
|
1125
|
-
var
|
|
1144
|
+
var import_node_url3 = require("url");
|
|
1126
1145
|
var import_node_child_process = require("child_process");
|
|
1127
1146
|
var import_pdf_lib = require("pdf-lib");
|
|
1128
1147
|
var import_pdf_encrypt = require("@pdfsmaller/pdf-encrypt");
|
|
@@ -1137,6 +1156,7 @@ var OutputFormat = /* @__PURE__ */ ((OutputFormat2) => {
|
|
|
1137
1156
|
OutputFormat2["PDF"] = "pdf";
|
|
1138
1157
|
OutputFormat2["HTML"] = "html";
|
|
1139
1158
|
OutputFormat2["PNG"] = "png";
|
|
1159
|
+
OutputFormat2["TXT"] = "txt";
|
|
1140
1160
|
return OutputFormat2;
|
|
1141
1161
|
})(OutputFormat || {});
|
|
1142
1162
|
var Theme = /* @__PURE__ */ ((Theme2) => {
|
|
@@ -1171,6 +1191,33 @@ var WatermarkPosition = /* @__PURE__ */ ((WatermarkPosition2) => {
|
|
|
1171
1191
|
WatermarkPosition2["BOTTOM_RIGHT"] = "bottom-right";
|
|
1172
1192
|
return WatermarkPosition2;
|
|
1173
1193
|
})(WatermarkPosition || {});
|
|
1194
|
+
var CoverPagePreset = /* @__PURE__ */ ((CoverPagePreset2) => {
|
|
1195
|
+
CoverPagePreset2["MODERN"] = "modern";
|
|
1196
|
+
CoverPagePreset2["CORPORATE_SPLIT"] = "corporate-split";
|
|
1197
|
+
CoverPagePreset2["MINIMAL"] = "minimal";
|
|
1198
|
+
CoverPagePreset2["CARD"] = "card";
|
|
1199
|
+
return CoverPagePreset2;
|
|
1200
|
+
})(CoverPagePreset || {});
|
|
1201
|
+
var BackCoverPreset = /* @__PURE__ */ ((BackCoverPreset2) => {
|
|
1202
|
+
BackCoverPreset2["MODERN"] = "modern";
|
|
1203
|
+
BackCoverPreset2["CORPORATE"] = "corporate";
|
|
1204
|
+
BackCoverPreset2["MINIMAL"] = "minimal";
|
|
1205
|
+
BackCoverPreset2["CONTACT_CARD"] = "contact-card";
|
|
1206
|
+
return BackCoverPreset2;
|
|
1207
|
+
})(BackCoverPreset || {});
|
|
1208
|
+
var SignatureAlign = /* @__PURE__ */ ((SignatureAlign2) => {
|
|
1209
|
+
SignatureAlign2["LEFT"] = "left";
|
|
1210
|
+
SignatureAlign2["CENTER"] = "center";
|
|
1211
|
+
SignatureAlign2["RIGHT"] = "right";
|
|
1212
|
+
SignatureAlign2["SPACE_BETWEEN"] = "space-between";
|
|
1213
|
+
return SignatureAlign2;
|
|
1214
|
+
})(SignatureAlign || {});
|
|
1215
|
+
var SignatureStyle = /* @__PURE__ */ ((SignatureStyle2) => {
|
|
1216
|
+
SignatureStyle2["LINE"] = "line";
|
|
1217
|
+
SignatureStyle2["BOX"] = "box";
|
|
1218
|
+
SignatureStyle2["CLEAN"] = "clean";
|
|
1219
|
+
return SignatureStyle2;
|
|
1220
|
+
})(SignatureStyle || {});
|
|
1174
1221
|
|
|
1175
1222
|
// src/core/html/htmlThemes.ts
|
|
1176
1223
|
var THEME_COMPONENTS = `
|
|
@@ -1338,7 +1385,7 @@ ${theme.customCss || ""}
|
|
|
1338
1385
|
// src/config/loadConfig.ts
|
|
1339
1386
|
var fs2 = __toESM(require("fs"));
|
|
1340
1387
|
var path2 = __toESM(require("path"));
|
|
1341
|
-
var
|
|
1388
|
+
var import_node_url2 = require("url");
|
|
1342
1389
|
var YAML = __toESM(require("yaml"));
|
|
1343
1390
|
var DEFAULT_CONFIG_FILENAMES = [
|
|
1344
1391
|
"markforge.config.json",
|
|
@@ -1446,7 +1493,7 @@ async function loadConfig(customPath, startDir = process.cwd()) {
|
|
|
1446
1493
|
userConfig = YAML.parse(raw) || {};
|
|
1447
1494
|
} else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
|
|
1448
1495
|
try {
|
|
1449
|
-
const fileUrl = `${(0,
|
|
1496
|
+
const fileUrl = `${(0, import_node_url2.pathToFileURL)(resolvedPath).href}?t=${Date.now()}`;
|
|
1450
1497
|
const mod = await import(fileUrl);
|
|
1451
1498
|
const rawExport = mod.default ?? mod.config ?? mod;
|
|
1452
1499
|
userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
|
|
@@ -2485,7 +2532,7 @@ async function renderBackCoverHtml(backCover, baseDir = process.cwd()) {
|
|
|
2485
2532
|
`;
|
|
2486
2533
|
return { html, css };
|
|
2487
2534
|
}
|
|
2488
|
-
async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
2535
|
+
async function buildHtmlDocument(doc, config = {}, baseDir = process.cwd()) {
|
|
2489
2536
|
var _a, _b;
|
|
2490
2537
|
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
2491
2538
|
const baseThemeCss = generateThemeCss(resolved.theme);
|
|
@@ -2836,8 +2883,11 @@ function escapeXml(str) {
|
|
|
2836
2883
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2837
2884
|
}
|
|
2838
2885
|
function generateWatermarkPngBuffer(chromePath, wm) {
|
|
2839
|
-
const
|
|
2840
|
-
const
|
|
2886
|
+
const tmpId = Math.random().toString(36).substring(2, 9);
|
|
2887
|
+
const tmpDir = os.tmpdir();
|
|
2888
|
+
const tmpHtml = path4.join(tmpDir, `markforge-wm-${tmpId}.html`);
|
|
2889
|
+
const tmpPng = path4.join(tmpDir, `markforge-wm-${tmpId}.png`);
|
|
2890
|
+
const tmpProfile = path4.join(tmpDir, `markforge-wm-prof-${tmpId}`);
|
|
2841
2891
|
try {
|
|
2842
2892
|
const text = escapeXml(wm.text.toUpperCase());
|
|
2843
2893
|
const fontSize = (wm.fontSize || 52) * 1.5;
|
|
@@ -2882,12 +2932,15 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2882
2932
|
</body>
|
|
2883
2933
|
</html>`;
|
|
2884
2934
|
fs4.writeFileSync(tmpHtml, html, "utf8");
|
|
2885
|
-
const fileUrl = (0,
|
|
2935
|
+
const fileUrl = (0, import_node_url3.pathToFileURL)(tmpHtml).href;
|
|
2886
2936
|
const isWin = process.platform === "win32";
|
|
2887
2937
|
(0, import_node_child_process.spawnSync)(
|
|
2888
2938
|
chromePath,
|
|
2889
2939
|
[
|
|
2890
2940
|
"--headless=new",
|
|
2941
|
+
`--user-data-dir=${tmpProfile}`,
|
|
2942
|
+
"--no-first-run",
|
|
2943
|
+
"--no-default-browser-check",
|
|
2891
2944
|
"--disable-gpu",
|
|
2892
2945
|
"--disable-sync",
|
|
2893
2946
|
"--disable-extensions",
|
|
@@ -2909,6 +2962,7 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2909
2962
|
try {
|
|
2910
2963
|
if (fs4.existsSync(tmpHtml)) fs4.unlinkSync(tmpHtml);
|
|
2911
2964
|
if (fs4.existsSync(tmpPng)) fs4.unlinkSync(tmpPng);
|
|
2965
|
+
if (fs4.existsSync(tmpProfile)) fs4.rmSync(tmpProfile, { recursive: true, force: true });
|
|
2912
2966
|
} catch {
|
|
2913
2967
|
}
|
|
2914
2968
|
}
|
|
@@ -2924,6 +2978,8 @@ function findChromeExecutable() {
|
|
|
2924
2978
|
const winLocalAppData = process.env.LOCALAPPDATA ?? "";
|
|
2925
2979
|
const winProgramFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
2926
2980
|
const winProgramFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
2981
|
+
const winProgramW6432 = process.env.ProgramW6432 ?? "C:\\Program Files";
|
|
2982
|
+
const winUserProfile = process.env.USERPROFILE ?? "";
|
|
2927
2983
|
const candidates = [
|
|
2928
2984
|
// Linux
|
|
2929
2985
|
"/usr/bin/google-chrome",
|
|
@@ -2942,17 +2998,34 @@ function findChromeExecutable() {
|
|
|
2942
2998
|
// Windows — Microsoft Edge (Native Windows 10/11 browser, enterprise whitelist friendly)
|
|
2943
2999
|
`${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2944
3000
|
`${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
3001
|
+
`${winProgramW6432}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2945
3002
|
`${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2946
|
-
|
|
3003
|
+
`${winLocalAppData}\\Microsoft\\Edge Dev\\Application\\msedge.exe`,
|
|
3004
|
+
`${winLocalAppData}\\Microsoft\\Edge Beta\\Application\\msedge.exe`,
|
|
3005
|
+
// Windows — Google Chrome & Chrome SxS (Canary)
|
|
2947
3006
|
`${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2948
3007
|
`${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
3008
|
+
`${winProgramW6432}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2949
3009
|
`${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
3010
|
+
`${winLocalAppData}\\Google\\Chrome SxS\\Application\\chrome.exe`,
|
|
2950
3011
|
// Windows — Brave Browser
|
|
2951
3012
|
`${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2952
3013
|
`${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
3014
|
+
`${winProgramW6432}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2953
3015
|
`${winLocalAppData}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2954
3016
|
// Windows — Chromium
|
|
2955
|
-
`${winLocalAppData}\\Chromium\\Application\\chrome.exe
|
|
3017
|
+
`${winLocalAppData}\\Chromium\\Application\\chrome.exe`,
|
|
3018
|
+
// Windows — Scoop Package Manager
|
|
3019
|
+
`${winUserProfile}\\scoop\\apps\\googlechrome\\current\\chrome.exe`,
|
|
3020
|
+
`${winUserProfile}\\scoop\\apps\\chromium\\current\\chrome.exe`,
|
|
3021
|
+
`${winUserProfile}\\scoop\\apps\\brave\\current\\brave.exe`,
|
|
3022
|
+
`${winUserProfile}\\scoop\\apps\\msedge\\current\\msedge.exe`,
|
|
3023
|
+
`${winUserProfile}\\scoop\\shims\\chrome.exe`,
|
|
3024
|
+
`${winUserProfile}\\scoop\\shims\\msedge.exe`,
|
|
3025
|
+
// Windows — Chocolatey
|
|
3026
|
+
"C:\\ProgramData\\chocolatey\\bin\\chrome.exe",
|
|
3027
|
+
"C:\\ProgramData\\chocolatey\\bin\\msedge.exe",
|
|
3028
|
+
"C:\\ProgramData\\chocolatey\\bin\\brave.exe"
|
|
2956
3029
|
].filter(Boolean);
|
|
2957
3030
|
for (const candidate of candidates) {
|
|
2958
3031
|
try {
|
|
@@ -2963,13 +3036,15 @@ function findChromeExecutable() {
|
|
|
2963
3036
|
}
|
|
2964
3037
|
}
|
|
2965
3038
|
try {
|
|
2966
|
-
const cmd = isWin ? "where" : "which";
|
|
2967
|
-
const names = isWin ? ["chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
|
|
3039
|
+
const cmd = isWin ? "where.exe" : "which";
|
|
3040
|
+
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"];
|
|
2968
3041
|
for (const name of names) {
|
|
2969
|
-
const res = (0, import_node_child_process.spawnSync)(cmd, [name], { encoding: "utf-8" });
|
|
3042
|
+
const res = (0, import_node_child_process.spawnSync)(cmd, [name], { encoding: "utf-8", windowsHide: true });
|
|
2970
3043
|
if (res.status === 0 && res.stdout.trim()) {
|
|
2971
|
-
const
|
|
2972
|
-
|
|
3044
|
+
const lines = res.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
3045
|
+
for (const line of lines) {
|
|
3046
|
+
if (fs4.existsSync(line)) return line;
|
|
3047
|
+
}
|
|
2973
3048
|
}
|
|
2974
3049
|
}
|
|
2975
3050
|
} catch {
|
|
@@ -3184,7 +3259,7 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
|
|
|
3184
3259
|
];
|
|
3185
3260
|
try {
|
|
3186
3261
|
fs4.writeFileSync(tmpHtml, pagedHtml, "utf-8");
|
|
3187
|
-
const fileUrl = (0,
|
|
3262
|
+
const fileUrl = (0, import_node_url3.pathToFileURL)(tmpHtml).href;
|
|
3188
3263
|
let res = (0, import_node_child_process.spawnSync)(
|
|
3189
3264
|
chromePath,
|
|
3190
3265
|
[
|
|
@@ -3303,6 +3378,8 @@ async function renderMermaidToPng(mermaidCode, _baseDir = process.cwd()) {
|
|
|
3303
3378
|
const tmpDir = os2.tmpdir();
|
|
3304
3379
|
const tmpHtml = path5.join(tmpDir, `mermaid_${tmpId}.html`);
|
|
3305
3380
|
const tmpScreenshot = path5.join(tmpDir, `mermaid_${tmpId}.png`);
|
|
3381
|
+
const tmpProfile = path5.join(tmpDir, `mermaid_prof_${tmpId}`);
|
|
3382
|
+
const isWin = process.platform === "win32";
|
|
3306
3383
|
const htmlContent = `<!DOCTYPE html>
|
|
3307
3384
|
<html>
|
|
3308
3385
|
<head>
|
|
@@ -3342,14 +3419,18 @@ ${mermaidCode}
|
|
|
3342
3419
|
</html>`;
|
|
3343
3420
|
try {
|
|
3344
3421
|
fs5.writeFileSync(tmpHtml, htmlContent, "utf-8");
|
|
3345
|
-
const fileUrl = (0,
|
|
3422
|
+
const fileUrl = (0, import_node_url4.pathToFileURL)(tmpHtml).href;
|
|
3346
3423
|
const res = (0, import_node_child_process2.spawnSync)(
|
|
3347
3424
|
chromePath,
|
|
3348
3425
|
[
|
|
3349
|
-
"--headless",
|
|
3426
|
+
"--headless=new",
|
|
3427
|
+
`--user-data-dir=${tmpProfile}`,
|
|
3428
|
+
"--no-first-run",
|
|
3429
|
+
"--no-default-browser-check",
|
|
3350
3430
|
"--disable-gpu",
|
|
3351
|
-
"--
|
|
3352
|
-
"--disable-
|
|
3431
|
+
"--disable-sync",
|
|
3432
|
+
"--disable-extensions",
|
|
3433
|
+
...isWin ? [] : ["--no-sandbox", "--disable-setuid-sandbox"],
|
|
3353
3434
|
"--allow-file-access-from-files",
|
|
3354
3435
|
"--disable-web-security",
|
|
3355
3436
|
"--disable-software-rasterizer",
|
|
@@ -3358,7 +3439,7 @@ ${mermaidCode}
|
|
|
3358
3439
|
`--screenshot=${tmpScreenshot}`,
|
|
3359
3440
|
fileUrl
|
|
3360
3441
|
],
|
|
3361
|
-
{ timeout: 15e3 }
|
|
3442
|
+
{ timeout: 15e3, windowsHide: true }
|
|
3362
3443
|
);
|
|
3363
3444
|
if (res.status === 0 && fs5.existsSync(tmpScreenshot)) {
|
|
3364
3445
|
const buffer = fs5.readFileSync(tmpScreenshot);
|
|
@@ -3369,6 +3450,7 @@ ${mermaidCode}
|
|
|
3369
3450
|
try {
|
|
3370
3451
|
if (fs5.existsSync(tmpHtml)) fs5.unlinkSync(tmpHtml);
|
|
3371
3452
|
if (fs5.existsSync(tmpScreenshot)) fs5.unlinkSync(tmpScreenshot);
|
|
3453
|
+
if (fs5.existsSync(tmpProfile)) fs5.rmSync(tmpProfile, { recursive: true, force: true });
|
|
3372
3454
|
} catch {
|
|
3373
3455
|
}
|
|
3374
3456
|
}
|
|
@@ -4510,6 +4592,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4510
4592
|
);
|
|
4511
4593
|
docSections.push({
|
|
4512
4594
|
properties: {
|
|
4595
|
+
type: import_docx.SectionType.NEXT_PAGE,
|
|
4513
4596
|
page: {
|
|
4514
4597
|
size: {
|
|
4515
4598
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4524,13 +4607,14 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4524
4607
|
}
|
|
4525
4608
|
}
|
|
4526
4609
|
},
|
|
4527
|
-
headers:
|
|
4528
|
-
footers:
|
|
4610
|
+
headers: { default: new import_docx.Header({ children: [] }) },
|
|
4611
|
+
footers: { default: new import_docx.Footer({ children: [] }) },
|
|
4529
4612
|
children: coverElements
|
|
4530
4613
|
});
|
|
4531
4614
|
}
|
|
4532
4615
|
docSections.push({
|
|
4533
4616
|
properties: {
|
|
4617
|
+
type: import_docx.SectionType.NEXT_PAGE,
|
|
4534
4618
|
page: {
|
|
4535
4619
|
pageNumbers: {
|
|
4536
4620
|
start: 1,
|
|
@@ -4551,8 +4635,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4551
4635
|
}
|
|
4552
4636
|
}
|
|
4553
4637
|
},
|
|
4554
|
-
headers: docHeader ? { default: docHeader } :
|
|
4555
|
-
footers: docFooter ? { default: docFooter } :
|
|
4638
|
+
headers: docHeader ? { default: docHeader } : { default: new import_docx.Header({ children: [] }) },
|
|
4639
|
+
footers: docFooter ? { default: docFooter } : { default: new import_docx.Footer({ children: [] }) },
|
|
4556
4640
|
children: docElements
|
|
4557
4641
|
});
|
|
4558
4642
|
if (resolved.backCover && resolved.backCover.enabled) {
|
|
@@ -4567,6 +4651,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4567
4651
|
);
|
|
4568
4652
|
docSections.push({
|
|
4569
4653
|
properties: {
|
|
4654
|
+
type: import_docx.SectionType.NEXT_PAGE,
|
|
4570
4655
|
page: {
|
|
4571
4656
|
size: {
|
|
4572
4657
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4581,8 +4666,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4581
4666
|
}
|
|
4582
4667
|
}
|
|
4583
4668
|
},
|
|
4584
|
-
headers:
|
|
4585
|
-
footers:
|
|
4669
|
+
headers: { default: new import_docx.Header({ children: [] }) },
|
|
4670
|
+
footers: { default: new import_docx.Footer({ children: [] }) },
|
|
4586
4671
|
children: backElements
|
|
4587
4672
|
});
|
|
4588
4673
|
}
|
|
@@ -4985,6 +5070,432 @@ function createEmptyDocxCell(widthDxa) {
|
|
|
4985
5070
|
});
|
|
4986
5071
|
}
|
|
4987
5072
|
|
|
5073
|
+
// src/core/text/textBuilder.ts
|
|
5074
|
+
var LINE_WIDTH = 80;
|
|
5075
|
+
var HR_DOUBLE = "=".repeat(LINE_WIDTH);
|
|
5076
|
+
var HR_SINGLE = "-".repeat(LINE_WIDTH);
|
|
5077
|
+
function centerText(text, width = LINE_WIDTH) {
|
|
5078
|
+
if (text.length >= width) return text;
|
|
5079
|
+
const leftPad = Math.floor((width - text.length) / 2);
|
|
5080
|
+
return " ".repeat(leftPad) + text;
|
|
5081
|
+
}
|
|
5082
|
+
function renderInlinesToText(spans = [], meta = {}) {
|
|
5083
|
+
let result = "";
|
|
5084
|
+
for (const span of spans) {
|
|
5085
|
+
switch (span.type) {
|
|
5086
|
+
case "text": {
|
|
5087
|
+
const content = replaceDocumentTokens(span.content, meta);
|
|
5088
|
+
result += content;
|
|
5089
|
+
break;
|
|
5090
|
+
}
|
|
5091
|
+
case "bold": {
|
|
5092
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5093
|
+
result += `**${inner}**`;
|
|
5094
|
+
break;
|
|
5095
|
+
}
|
|
5096
|
+
case "italic": {
|
|
5097
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5098
|
+
result += `*${inner}*`;
|
|
5099
|
+
break;
|
|
5100
|
+
}
|
|
5101
|
+
case "code": {
|
|
5102
|
+
result += `\`${span.content}\``;
|
|
5103
|
+
break;
|
|
5104
|
+
}
|
|
5105
|
+
case "link": {
|
|
5106
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5107
|
+
result += span.url && span.url !== inner ? `${inner} (${span.url})` : inner;
|
|
5108
|
+
break;
|
|
5109
|
+
}
|
|
5110
|
+
case "image": {
|
|
5111
|
+
result += `[Image: ${span.alt || "image"} (${span.url || ""})]`;
|
|
5112
|
+
break;
|
|
5113
|
+
}
|
|
5114
|
+
case "strikethrough": {
|
|
5115
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5116
|
+
result += `~${inner}~`;
|
|
5117
|
+
break;
|
|
5118
|
+
}
|
|
5119
|
+
case "mathInline": {
|
|
5120
|
+
result += `$${span.content}$`;
|
|
5121
|
+
break;
|
|
5122
|
+
}
|
|
5123
|
+
case "footnoteRef": {
|
|
5124
|
+
const id = span.footnoteId || span.content;
|
|
5125
|
+
result += `[${id}]`;
|
|
5126
|
+
break;
|
|
5127
|
+
}
|
|
5128
|
+
case "htmlInline": {
|
|
5129
|
+
result += span.content.replace(/<[^>]+>/g, "");
|
|
5130
|
+
break;
|
|
5131
|
+
}
|
|
5132
|
+
default: {
|
|
5133
|
+
result += span.content || "";
|
|
5134
|
+
break;
|
|
5135
|
+
}
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
return result;
|
|
5139
|
+
}
|
|
5140
|
+
async function buildTextDocument(doc, config = {}, _baseDir = process.cwd()) {
|
|
5141
|
+
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
5142
|
+
const meta = {
|
|
5143
|
+
...doc.metadata,
|
|
5144
|
+
...config.metadata,
|
|
5145
|
+
title: resolved.title,
|
|
5146
|
+
subtitle: resolved.subtitle,
|
|
5147
|
+
author: resolved.author,
|
|
5148
|
+
company: resolved.company,
|
|
5149
|
+
version: resolved.version,
|
|
5150
|
+
date: resolved.date
|
|
5151
|
+
};
|
|
5152
|
+
const nodes = JSON.parse(JSON.stringify(doc.nodes));
|
|
5153
|
+
const tocEntries = JSON.parse(JSON.stringify(doc.tocEntries));
|
|
5154
|
+
if (resolved.numberHeadings && resolved.numberHeadings.enabled) {
|
|
5155
|
+
applyHeadingNumbering(nodes, tocEntries, resolved.numberHeadings);
|
|
5156
|
+
}
|
|
5157
|
+
const lines = [];
|
|
5158
|
+
if (resolved.coverPage && resolved.coverPage.enabled) {
|
|
5159
|
+
const cover = resolved.coverPage;
|
|
5160
|
+
const coverTitle = (cover.title || meta.title || "DOCUMENT").toUpperCase();
|
|
5161
|
+
const coverSubtitle = cover.subtitle || meta.subtitle || "";
|
|
5162
|
+
const coverAuthor = cover.author || meta.author || "";
|
|
5163
|
+
const coverCompany = cover.company || meta.company || "";
|
|
5164
|
+
const coverDate = cover.date || meta.date || "";
|
|
5165
|
+
const coverVersion = cover.version || meta.version || "";
|
|
5166
|
+
const coverBadge = cover.badge || "";
|
|
5167
|
+
const coverFooter = cover.footerText || "";
|
|
5168
|
+
lines.push(HR_DOUBLE);
|
|
5169
|
+
lines.push(centerText(coverTitle));
|
|
5170
|
+
if (coverSubtitle) {
|
|
5171
|
+
lines.push(centerText(coverSubtitle));
|
|
5172
|
+
}
|
|
5173
|
+
lines.push(HR_DOUBLE);
|
|
5174
|
+
if (coverBadge) {
|
|
5175
|
+
lines.push(`[${coverBadge}]`);
|
|
5176
|
+
lines.push("");
|
|
5177
|
+
}
|
|
5178
|
+
if (coverAuthor) lines.push(`Author: ${coverAuthor}`);
|
|
5179
|
+
if (coverCompany) lines.push(`Company: ${coverCompany}`);
|
|
5180
|
+
if (coverDate) lines.push(`Date: ${coverDate}`);
|
|
5181
|
+
if (coverVersion) lines.push(`Version: ${coverVersion}`);
|
|
5182
|
+
if (coverFooter) lines.push(`Notice: ${coverFooter}`);
|
|
5183
|
+
lines.push(HR_DOUBLE);
|
|
5184
|
+
lines.push("");
|
|
5185
|
+
lines.push("");
|
|
5186
|
+
}
|
|
5187
|
+
if (resolved.toc) {
|
|
5188
|
+
const headings = nodes.filter(
|
|
5189
|
+
(n) => n.type === "heading" && (n.level || 1) <= 3
|
|
5190
|
+
);
|
|
5191
|
+
if (headings.length > 0) {
|
|
5192
|
+
const tocTitle = "TABLE OF CONTENTS";
|
|
5193
|
+
lines.push(HR_DOUBLE);
|
|
5194
|
+
lines.push(centerText(tocTitle));
|
|
5195
|
+
lines.push(HR_DOUBLE);
|
|
5196
|
+
for (const h of headings) {
|
|
5197
|
+
const level = h.level || 1;
|
|
5198
|
+
const indent = " ".repeat(level - 1);
|
|
5199
|
+
const headingText = renderInlinesToText(h.inlines, meta);
|
|
5200
|
+
const prefix = level === 1 ? "* " : "- ";
|
|
5201
|
+
lines.push(`${indent}${prefix}${headingText}`);
|
|
5202
|
+
}
|
|
5203
|
+
lines.push(HR_DOUBLE);
|
|
5204
|
+
lines.push("");
|
|
5205
|
+
lines.push("");
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
function renderNode(node, listLevel = 0) {
|
|
5209
|
+
var _a;
|
|
5210
|
+
switch (node.type) {
|
|
5211
|
+
case "heading": {
|
|
5212
|
+
const level = node.level || 1;
|
|
5213
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5214
|
+
lines.push("");
|
|
5215
|
+
if (level === 1) {
|
|
5216
|
+
lines.push(HR_DOUBLE);
|
|
5217
|
+
lines.push(text.toUpperCase());
|
|
5218
|
+
lines.push(HR_DOUBLE);
|
|
5219
|
+
} else if (level === 2) {
|
|
5220
|
+
lines.push(HR_SINGLE);
|
|
5221
|
+
lines.push(text);
|
|
5222
|
+
lines.push(HR_SINGLE);
|
|
5223
|
+
} else {
|
|
5224
|
+
const hashes = "#".repeat(level);
|
|
5225
|
+
lines.push(`${hashes} ${text}`);
|
|
5226
|
+
}
|
|
5227
|
+
lines.push("");
|
|
5228
|
+
break;
|
|
5229
|
+
}
|
|
5230
|
+
case "paragraph": {
|
|
5231
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5232
|
+
if (text.trim()) {
|
|
5233
|
+
lines.push(text);
|
|
5234
|
+
lines.push("");
|
|
5235
|
+
}
|
|
5236
|
+
break;
|
|
5237
|
+
}
|
|
5238
|
+
case "callout": {
|
|
5239
|
+
const calloutType = (node.calloutType || "NOTE").toUpperCase();
|
|
5240
|
+
lines.push(`| [${calloutType}]`);
|
|
5241
|
+
if (node.inlines && node.inlines.length > 0) {
|
|
5242
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5243
|
+
text.split("\n").forEach((l) => lines.push(`| ${l}`));
|
|
5244
|
+
}
|
|
5245
|
+
lines.push("");
|
|
5246
|
+
break;
|
|
5247
|
+
}
|
|
5248
|
+
case "blockquote": {
|
|
5249
|
+
if (node.inlines && node.inlines.length > 0) {
|
|
5250
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5251
|
+
text.split("\n").forEach((l) => lines.push(`> ${l}`));
|
|
5252
|
+
lines.push("");
|
|
5253
|
+
}
|
|
5254
|
+
break;
|
|
5255
|
+
}
|
|
5256
|
+
case "codeBlock": {
|
|
5257
|
+
const lang = node.language ? `[Language: ${node.language}]` : "[Code]";
|
|
5258
|
+
lines.push(HR_SINGLE);
|
|
5259
|
+
lines.push(lang);
|
|
5260
|
+
lines.push(HR_SINGLE);
|
|
5261
|
+
const codeText = node.text || "";
|
|
5262
|
+
lines.push(codeText);
|
|
5263
|
+
lines.push(HR_SINGLE);
|
|
5264
|
+
lines.push("");
|
|
5265
|
+
break;
|
|
5266
|
+
}
|
|
5267
|
+
case "list": {
|
|
5268
|
+
if (node.children) {
|
|
5269
|
+
let itemIndex = 1;
|
|
5270
|
+
for (const item of node.children) {
|
|
5271
|
+
const indent = " ".repeat(listLevel);
|
|
5272
|
+
let prefix = node.ordered ? `${itemIndex}. ` : "* ";
|
|
5273
|
+
itemIndex++;
|
|
5274
|
+
if (item.checked !== void 0) {
|
|
5275
|
+
prefix = item.checked ? "[x] " : "[ ] ";
|
|
5276
|
+
}
|
|
5277
|
+
if (item.inlines && item.inlines.length > 0) {
|
|
5278
|
+
const text = renderInlinesToText(item.inlines, meta);
|
|
5279
|
+
lines.push(`${indent}${prefix}${text}`);
|
|
5280
|
+
}
|
|
5281
|
+
if (item.children && item.children.length > 0) {
|
|
5282
|
+
for (const subChild of item.children) {
|
|
5283
|
+
if (subChild.type === "list") {
|
|
5284
|
+
renderNode(subChild, listLevel + 1);
|
|
5285
|
+
} else if (subChild.type === "paragraph") {
|
|
5286
|
+
const text = renderInlinesToText(subChild.inlines, meta);
|
|
5287
|
+
lines.push(`${indent} ${text}`);
|
|
5288
|
+
} else {
|
|
5289
|
+
renderNode(subChild, listLevel + 1);
|
|
5290
|
+
}
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
lines.push("");
|
|
5295
|
+
}
|
|
5296
|
+
break;
|
|
5297
|
+
}
|
|
5298
|
+
case "table": {
|
|
5299
|
+
const rows = node.children || [];
|
|
5300
|
+
if (rows.length === 0) break;
|
|
5301
|
+
const rowCells = [];
|
|
5302
|
+
let maxCols = 0;
|
|
5303
|
+
for (const row of rows) {
|
|
5304
|
+
const cells = row.children || [];
|
|
5305
|
+
const texts = cells.map((c) => renderInlinesToText(c.inlines, meta));
|
|
5306
|
+
const isHeader = cells.some((c) => c.isHeader);
|
|
5307
|
+
maxCols = Math.max(maxCols, texts.length);
|
|
5308
|
+
rowCells.push({ isHeader, texts });
|
|
5309
|
+
}
|
|
5310
|
+
if (maxCols === 0) break;
|
|
5311
|
+
const colWidths = new Array(maxCols).fill(3);
|
|
5312
|
+
for (const r of rowCells) {
|
|
5313
|
+
for (let col = 0; col < maxCols; col++) {
|
|
5314
|
+
const cellText = r.texts[col] || "";
|
|
5315
|
+
colWidths[col] = Math.max(colWidths[col] ?? 3, cellText.length);
|
|
5316
|
+
}
|
|
5317
|
+
}
|
|
5318
|
+
const separatorLine = "+" + colWidths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
5319
|
+
const formatRow = (texts) => {
|
|
5320
|
+
const paddedCells = colWidths.map((width, colIdx) => {
|
|
5321
|
+
const text = texts[colIdx] || "";
|
|
5322
|
+
return " " + text.padEnd(width, " ") + " ";
|
|
5323
|
+
});
|
|
5324
|
+
return "|" + paddedCells.join("|") + "|";
|
|
5325
|
+
};
|
|
5326
|
+
lines.push(separatorLine);
|
|
5327
|
+
for (const r of rowCells) {
|
|
5328
|
+
lines.push(formatRow(r.texts));
|
|
5329
|
+
if (r.isHeader) {
|
|
5330
|
+
lines.push(separatorLine);
|
|
5331
|
+
}
|
|
5332
|
+
}
|
|
5333
|
+
if (!((_a = rowCells[rowCells.length - 1]) == null ? void 0 : _a.isHeader)) {
|
|
5334
|
+
lines.push(separatorLine);
|
|
5335
|
+
}
|
|
5336
|
+
lines.push("");
|
|
5337
|
+
break;
|
|
5338
|
+
}
|
|
5339
|
+
case "mathBlock": {
|
|
5340
|
+
lines.push("[Equation]");
|
|
5341
|
+
lines.push(` $$${node.text || ""} $$`);
|
|
5342
|
+
lines.push("");
|
|
5343
|
+
break;
|
|
5344
|
+
}
|
|
5345
|
+
case "mermaid": {
|
|
5346
|
+
lines.push("[Diagram: Mermaid]");
|
|
5347
|
+
lines.push(node.text || "");
|
|
5348
|
+
lines.push("");
|
|
5349
|
+
break;
|
|
5350
|
+
}
|
|
5351
|
+
case "thematicBreak": {
|
|
5352
|
+
lines.push(HR_SINGLE);
|
|
5353
|
+
lines.push("");
|
|
5354
|
+
break;
|
|
5355
|
+
}
|
|
5356
|
+
case "columns": {
|
|
5357
|
+
if (node.children) {
|
|
5358
|
+
for (const col of node.children) {
|
|
5359
|
+
if (col.children) {
|
|
5360
|
+
for (const child of col.children) {
|
|
5361
|
+
renderNode(child, listLevel);
|
|
5362
|
+
}
|
|
5363
|
+
}
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
break;
|
|
5367
|
+
}
|
|
5368
|
+
default: {
|
|
5369
|
+
if (node.children && node.children.length > 0) {
|
|
5370
|
+
for (const child of node.children) {
|
|
5371
|
+
renderNode(child, listLevel);
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
break;
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
}
|
|
5378
|
+
for (const node of nodes) {
|
|
5379
|
+
renderNode(node);
|
|
5380
|
+
}
|
|
5381
|
+
if (doc.footnoteDefs && doc.footnoteDefs.length > 0) {
|
|
5382
|
+
lines.push(HR_SINGLE);
|
|
5383
|
+
lines.push("FOOTNOTES");
|
|
5384
|
+
lines.push(HR_SINGLE);
|
|
5385
|
+
for (const fn of doc.footnoteDefs) {
|
|
5386
|
+
const text = renderInlinesToText(fn.inlines, meta);
|
|
5387
|
+
lines.push(`[${fn.id}] ${text}`);
|
|
5388
|
+
}
|
|
5389
|
+
lines.push("");
|
|
5390
|
+
}
|
|
5391
|
+
if (resolved.signatures && resolved.signatures.items && resolved.signatures.items.length > 0) {
|
|
5392
|
+
lines.push(HR_SINGLE);
|
|
5393
|
+
lines.push("SIGNATURES & APPROVALS");
|
|
5394
|
+
lines.push(HR_SINGLE);
|
|
5395
|
+
lines.push("");
|
|
5396
|
+
for (const item of resolved.signatures.items) {
|
|
5397
|
+
const title = item.title || "Signatory";
|
|
5398
|
+
const name = item.name ? replaceDocumentTokens(item.name, meta) : "";
|
|
5399
|
+
const role = item.role ? replaceDocumentTokens(item.role, meta) : "";
|
|
5400
|
+
const date = item.date ? replaceDocumentTokens(item.date, meta) : "";
|
|
5401
|
+
lines.push(`[${title}]`);
|
|
5402
|
+
lines.push("____________________________________");
|
|
5403
|
+
if (name) lines.push(`Name: ${name}`);
|
|
5404
|
+
if (role) lines.push(`Role: ${role}`);
|
|
5405
|
+
if (date) lines.push(`Date: ${date}`);
|
|
5406
|
+
lines.push("");
|
|
5407
|
+
}
|
|
5408
|
+
}
|
|
5409
|
+
if (resolved.backCover && resolved.backCover.enabled) {
|
|
5410
|
+
const back = resolved.backCover;
|
|
5411
|
+
const backTitle = (back.title || "THANK YOU").toUpperCase();
|
|
5412
|
+
const backSubtitle = back.subtitle || "";
|
|
5413
|
+
const backCompany = back.company ? replaceDocumentTokens(back.company, meta) : "";
|
|
5414
|
+
const backAddress = back.address ? replaceDocumentTokens(back.address, meta) : "";
|
|
5415
|
+
const backEmail = back.email ? replaceDocumentTokens(back.email, meta) : "";
|
|
5416
|
+
const backPhone = back.phone ? replaceDocumentTokens(back.phone, meta) : "";
|
|
5417
|
+
const backWebsite = back.website ? replaceDocumentTokens(back.website, meta) : "";
|
|
5418
|
+
const backCopyright = back.copyright ? replaceDocumentTokens(back.copyright, meta) : "";
|
|
5419
|
+
lines.push(HR_DOUBLE);
|
|
5420
|
+
lines.push(centerText(backTitle));
|
|
5421
|
+
if (backSubtitle) {
|
|
5422
|
+
lines.push(centerText(backSubtitle));
|
|
5423
|
+
}
|
|
5424
|
+
lines.push(HR_DOUBLE);
|
|
5425
|
+
if (backCompany) lines.push(`Company: ${backCompany}`);
|
|
5426
|
+
if (backAddress) lines.push(`Address: ${backAddress}`);
|
|
5427
|
+
if (backEmail) lines.push(`Email: ${backEmail}`);
|
|
5428
|
+
if (backPhone) lines.push(`Phone: ${backPhone}`);
|
|
5429
|
+
if (backWebsite) lines.push(`Website: ${backWebsite}`);
|
|
5430
|
+
if (back.social && back.social.github) {
|
|
5431
|
+
lines.push(`GitHub: ${back.social.github}`);
|
|
5432
|
+
}
|
|
5433
|
+
if (backCopyright) {
|
|
5434
|
+
lines.push("");
|
|
5435
|
+
lines.push(backCopyright);
|
|
5436
|
+
}
|
|
5437
|
+
lines.push(HR_DOUBLE);
|
|
5438
|
+
lines.push("");
|
|
5439
|
+
}
|
|
5440
|
+
return lines.join("\n").trim() + "\n";
|
|
5441
|
+
}
|
|
5442
|
+
|
|
5443
|
+
// src/core/png/pngBuilder.ts
|
|
5444
|
+
var fs6 = __toESM(require("fs"));
|
|
5445
|
+
var path6 = __toESM(require("path"));
|
|
5446
|
+
var os3 = __toESM(require("os"));
|
|
5447
|
+
var import_node_url5 = require("url");
|
|
5448
|
+
var import_node_child_process3 = require("child_process");
|
|
5449
|
+
async function buildPngDocument(doc, config, baseDir) {
|
|
5450
|
+
const htmlContent = await buildHtmlDocument(doc, config, baseDir);
|
|
5451
|
+
const chromePath = findChromeExecutable();
|
|
5452
|
+
if (!chromePath) {
|
|
5453
|
+
throw new Error(
|
|
5454
|
+
"Headless Chrome / Chromium / Edge executable not found for PNG document export. Please install Google Chrome, Chromium, or Microsoft Edge, or set CHROME_PATH environment variable."
|
|
5455
|
+
);
|
|
5456
|
+
}
|
|
5457
|
+
const tmpHtml = path6.join(
|
|
5458
|
+
os3.tmpdir(),
|
|
5459
|
+
`markforge-png-${Date.now()}-${Math.random().toString(36).slice(2)}.html`
|
|
5460
|
+
);
|
|
5461
|
+
const tmpPng = path6.join(
|
|
5462
|
+
os3.tmpdir(),
|
|
5463
|
+
`markforge-png-${Date.now()}-${Math.random().toString(36).slice(2)}.png`
|
|
5464
|
+
);
|
|
5465
|
+
try {
|
|
5466
|
+
fs6.writeFileSync(tmpHtml, htmlContent, "utf-8");
|
|
5467
|
+
const fileUrl = (0, import_node_url5.pathToFileURL)(tmpHtml).href;
|
|
5468
|
+
const spawnResult = (0, import_node_child_process3.spawnSync)(
|
|
5469
|
+
chromePath,
|
|
5470
|
+
[
|
|
5471
|
+
"--headless=new",
|
|
5472
|
+
"--disable-gpu",
|
|
5473
|
+
"--no-sandbox",
|
|
5474
|
+
"--disable-setuid-sandbox",
|
|
5475
|
+
"--hide-scrollbars",
|
|
5476
|
+
"--force-device-scale-factor=2",
|
|
5477
|
+
"--window-size=1200,1600",
|
|
5478
|
+
`--screenshot=${tmpPng}`,
|
|
5479
|
+
fileUrl
|
|
5480
|
+
],
|
|
5481
|
+
{ timeout: 3e4, windowsHide: true }
|
|
5482
|
+
);
|
|
5483
|
+
if (spawnResult.error) {
|
|
5484
|
+
throw new Error(`Failed to execute Chromium for PNG export: ${spawnResult.error.message}`);
|
|
5485
|
+
}
|
|
5486
|
+
if (!fs6.existsSync(tmpPng) || fs6.statSync(tmpPng).size === 0) {
|
|
5487
|
+
throw new Error("Chromium PNG export failed to generate output screenshot file.");
|
|
5488
|
+
}
|
|
5489
|
+
return fs6.readFileSync(tmpPng);
|
|
5490
|
+
} finally {
|
|
5491
|
+
try {
|
|
5492
|
+
if (fs6.existsSync(tmpHtml)) fs6.unlinkSync(tmpHtml);
|
|
5493
|
+
if (fs6.existsSync(tmpPng)) fs6.unlinkSync(tmpPng);
|
|
5494
|
+
} catch {
|
|
5495
|
+
}
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
|
|
4988
5499
|
// src/core/engine.ts
|
|
4989
5500
|
function formatServerTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
4990
5501
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -5008,20 +5519,20 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5008
5519
|
let baseDir = process.cwd();
|
|
5009
5520
|
let inputFileName = "document.md";
|
|
5010
5521
|
let isFilePath = false;
|
|
5011
|
-
if (
|
|
5522
|
+
if (fs7.existsSync(inputFilePathOrContent)) {
|
|
5012
5523
|
isFilePath = true;
|
|
5013
|
-
rawMarkdown =
|
|
5014
|
-
baseDir =
|
|
5015
|
-
inputFileName =
|
|
5524
|
+
rawMarkdown = fs7.readFileSync(inputFilePathOrContent, "utf-8");
|
|
5525
|
+
baseDir = path7.dirname(path7.resolve(inputFilePathOrContent));
|
|
5526
|
+
inputFileName = path7.basename(inputFilePathOrContent);
|
|
5016
5527
|
} else {
|
|
5017
5528
|
rawMarkdown = inputFilePathOrContent;
|
|
5018
5529
|
}
|
|
5019
5530
|
onProgress == null ? void 0 : onProgress(`Parsing markdown AST: ${inputFileName}...`);
|
|
5020
5531
|
const parsedDoc = parseMarkdownDocument(rawMarkdown);
|
|
5021
5532
|
const baseName = inputFileName.replace(/\.(md|mdx|markdown)$/i, "");
|
|
5022
|
-
const outputDir = config.outputDir ?
|
|
5023
|
-
if (!
|
|
5024
|
-
|
|
5533
|
+
const outputDir = config.outputDir ? path7.isAbsolute(config.outputDir) ? config.outputDir : path7.resolve(process.cwd(), config.outputDir) : baseDir;
|
|
5534
|
+
if (!fs7.existsSync(outputDir)) {
|
|
5535
|
+
fs7.mkdirSync(outputDir, { recursive: true });
|
|
5025
5536
|
}
|
|
5026
5537
|
const formats = Array.isArray(config.to) ? config.to : [config.to || "docx", "pdf"];
|
|
5027
5538
|
const generatedFiles = [];
|
|
@@ -5031,8 +5542,8 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5031
5542
|
if (fmt === "docx") {
|
|
5032
5543
|
onProgress == null ? void 0 : onProgress(`Generating DOCX document: ${baseName}.docx...`);
|
|
5033
5544
|
const docxBuffer = await buildDocxDocument(parsedDoc, config, baseDir);
|
|
5034
|
-
const docxPath =
|
|
5035
|
-
|
|
5545
|
+
const docxPath = path7.join(outputDir, `${baseName}.docx`);
|
|
5546
|
+
fs7.writeFileSync(docxPath, docxBuffer);
|
|
5036
5547
|
generatedFiles.push({
|
|
5037
5548
|
format: "docx",
|
|
5038
5549
|
filePath: docxPath,
|
|
@@ -5042,8 +5553,8 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5042
5553
|
} else if (fmt === "html") {
|
|
5043
5554
|
onProgress == null ? void 0 : onProgress(`Generating HTML document: ${baseName}.html...`);
|
|
5044
5555
|
const htmlString = await buildHtmlDocument(parsedDoc, config, baseDir);
|
|
5045
|
-
const htmlPath =
|
|
5046
|
-
|
|
5556
|
+
const htmlPath = path7.join(outputDir, `${baseName}.html`);
|
|
5557
|
+
fs7.writeFileSync(htmlPath, htmlString, "utf-8");
|
|
5047
5558
|
generatedFiles.push({
|
|
5048
5559
|
format: "html",
|
|
5049
5560
|
filePath: htmlPath,
|
|
@@ -5053,14 +5564,36 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5053
5564
|
} else if (fmt === "pdf") {
|
|
5054
5565
|
onProgress == null ? void 0 : onProgress(`Generating PDF document: ${baseName}.pdf...`);
|
|
5055
5566
|
const pdfBuffer = await buildPdfDocument(parsedDoc, config, baseDir);
|
|
5056
|
-
const pdfPath =
|
|
5057
|
-
|
|
5567
|
+
const pdfPath = path7.join(outputDir, `${baseName}.pdf`);
|
|
5568
|
+
fs7.writeFileSync(pdfPath, pdfBuffer);
|
|
5058
5569
|
generatedFiles.push({
|
|
5059
5570
|
format: "pdf",
|
|
5060
5571
|
filePath: pdfPath,
|
|
5061
5572
|
fileName: `${baseName}.pdf`,
|
|
5062
5573
|
sizeBytes: pdfBuffer.length
|
|
5063
5574
|
});
|
|
5575
|
+
} else if (fmt === "txt") {
|
|
5576
|
+
onProgress == null ? void 0 : onProgress(`Generating Plain Text document: ${baseName}.txt...`);
|
|
5577
|
+
const textContent = await buildTextDocument(parsedDoc, config, baseDir);
|
|
5578
|
+
const textPath = path7.join(outputDir, `${baseName}.txt`);
|
|
5579
|
+
fs7.writeFileSync(textPath, textContent, "utf-8");
|
|
5580
|
+
generatedFiles.push({
|
|
5581
|
+
format: "txt",
|
|
5582
|
+
filePath: textPath,
|
|
5583
|
+
fileName: `${baseName}.txt`,
|
|
5584
|
+
sizeBytes: Buffer.byteLength(textContent, "utf-8")
|
|
5585
|
+
});
|
|
5586
|
+
} else if (fmt === "png") {
|
|
5587
|
+
onProgress == null ? void 0 : onProgress(`Generating PNG document: ${baseName}.png...`);
|
|
5588
|
+
const pngBuffer = await buildPngDocument(parsedDoc, config, baseDir);
|
|
5589
|
+
const pngPath = path7.join(outputDir, `${baseName}.png`);
|
|
5590
|
+
fs7.writeFileSync(pngPath, pngBuffer);
|
|
5591
|
+
generatedFiles.push({
|
|
5592
|
+
format: "png",
|
|
5593
|
+
filePath: pngPath,
|
|
5594
|
+
fileName: `${baseName}.png`,
|
|
5595
|
+
sizeBytes: pngBuffer.length
|
|
5596
|
+
});
|
|
5064
5597
|
}
|
|
5065
5598
|
} catch (err) {
|
|
5066
5599
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -5079,14 +5612,14 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5079
5612
|
|
|
5080
5613
|
// src/server/previewServer.ts
|
|
5081
5614
|
var http = __toESM(require("http"));
|
|
5082
|
-
var
|
|
5083
|
-
var
|
|
5615
|
+
var fs8 = __toESM(require("fs"));
|
|
5616
|
+
var path8 = __toESM(require("path"));
|
|
5084
5617
|
async function startPreviewServer(options) {
|
|
5085
|
-
const absoluteFilePath =
|
|
5086
|
-
if (!
|
|
5618
|
+
const absoluteFilePath = path8.resolve(process.cwd(), options.filePath);
|
|
5619
|
+
if (!fs8.existsSync(absoluteFilePath)) {
|
|
5087
5620
|
throw new Error(`MarkForge preview error: File not found at "${absoluteFilePath}"`);
|
|
5088
5621
|
}
|
|
5089
|
-
const baseDir =
|
|
5622
|
+
const baseDir = path8.dirname(absoluteFilePath);
|
|
5090
5623
|
const { config: fileConfig } = await loadConfig(void 0, baseDir);
|
|
5091
5624
|
const baseConfig = options.config || fileConfig;
|
|
5092
5625
|
const port = options.port || 3e3;
|
|
@@ -5104,9 +5637,9 @@ data: ${Date.now()}
|
|
|
5104
5637
|
});
|
|
5105
5638
|
};
|
|
5106
5639
|
let debounceTimer = null;
|
|
5107
|
-
const watcher =
|
|
5640
|
+
const watcher = fs8.watch(baseDir, { recursive: false }, (_event, filename) => {
|
|
5108
5641
|
if (!filename) return;
|
|
5109
|
-
const changedPath =
|
|
5642
|
+
const changedPath = path8.resolve(baseDir, filename);
|
|
5110
5643
|
if (changedPath === absoluteFilePath || filename.includes("markforge") || filename.endsWith(".css")) {
|
|
5111
5644
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
5112
5645
|
debounceTimer = setTimeout(() => {
|
|
@@ -5133,12 +5666,12 @@ data: ${Date.now()}
|
|
|
5133
5666
|
}
|
|
5134
5667
|
if (url.pathname === "/api/file-content" && req.method === "GET") {
|
|
5135
5668
|
try {
|
|
5136
|
-
const content =
|
|
5669
|
+
const content = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5137
5670
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5138
5671
|
res.end(
|
|
5139
5672
|
JSON.stringify({
|
|
5140
5673
|
content,
|
|
5141
|
-
fileName:
|
|
5674
|
+
fileName: path8.basename(absoluteFilePath),
|
|
5142
5675
|
filePath: absoluteFilePath
|
|
5143
5676
|
})
|
|
5144
5677
|
);
|
|
@@ -5158,7 +5691,7 @@ data: ${Date.now()}
|
|
|
5158
5691
|
try {
|
|
5159
5692
|
const parsed = JSON.parse(body);
|
|
5160
5693
|
if (typeof parsed.content === "string") {
|
|
5161
|
-
|
|
5694
|
+
fs8.writeFileSync(absoluteFilePath, parsed.content, "utf-8");
|
|
5162
5695
|
broadcastReload();
|
|
5163
5696
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5164
5697
|
res.end(JSON.stringify({ success: true, savedAt: Date.now() }));
|
|
@@ -5177,11 +5710,11 @@ data: ${Date.now()}
|
|
|
5177
5710
|
if (url.pathname === "/api/export" && (req.method === "GET" || req.method === "POST")) {
|
|
5178
5711
|
const format = url.searchParams.get("format") || "docx";
|
|
5179
5712
|
try {
|
|
5180
|
-
const mdContent =
|
|
5713
|
+
const mdContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5181
5714
|
const doc = parseMarkdownDocument(mdContent);
|
|
5182
5715
|
const { config: resolvedConfig } = await loadConfig(void 0, baseDir);
|
|
5183
5716
|
const mergedConfig = { ...baseConfig, ...resolvedConfig };
|
|
5184
|
-
const fileBase =
|
|
5717
|
+
const fileBase = path8.basename(absoluteFilePath, path8.extname(absoluteFilePath));
|
|
5185
5718
|
if (format === "docx") {
|
|
5186
5719
|
const buffer = await buildDocxDocument(doc, mergedConfig, baseDir);
|
|
5187
5720
|
res.writeHead(200, {
|
|
@@ -5216,7 +5749,7 @@ data: ${Date.now()}
|
|
|
5216
5749
|
}
|
|
5217
5750
|
if (url.pathname === "/document-content") {
|
|
5218
5751
|
try {
|
|
5219
|
-
const mdContent =
|
|
5752
|
+
const mdContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5220
5753
|
const doc = parseMarkdownDocument(mdContent);
|
|
5221
5754
|
const { config: resolvedConfig } = await loadConfig(void 0, baseDir);
|
|
5222
5755
|
const html = await buildHtmlDocument(doc, { ...baseConfig, ...resolvedConfig }, baseDir);
|
|
@@ -5249,8 +5782,8 @@ data: ${Date.now()}
|
|
|
5249
5782
|
return;
|
|
5250
5783
|
}
|
|
5251
5784
|
if (url.pathname === "/" || url.pathname === "/index.html") {
|
|
5252
|
-
const fileName =
|
|
5253
|
-
const initialContent =
|
|
5785
|
+
const fileName = path8.basename(absoluteFilePath);
|
|
5786
|
+
const initialContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5254
5787
|
const appHtml = `<!DOCTYPE html>
|
|
5255
5788
|
<html lang="en">
|
|
5256
5789
|
<head>
|
|
@@ -5954,9 +6487,9 @@ function defineConfig(config) {
|
|
|
5954
6487
|
}
|
|
5955
6488
|
|
|
5956
6489
|
// src/version.ts
|
|
5957
|
-
var
|
|
5958
|
-
var
|
|
5959
|
-
var
|
|
6490
|
+
var fs9 = __toESM(require("fs"));
|
|
6491
|
+
var path9 = __toESM(require("path"));
|
|
6492
|
+
var import_node_url6 = require("url");
|
|
5960
6493
|
var import_meta = {};
|
|
5961
6494
|
try {
|
|
5962
6495
|
if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
|
|
@@ -5982,16 +6515,16 @@ function readVersionFromPackageJson(fromDir) {
|
|
|
5982
6515
|
let currentDir = fromDir;
|
|
5983
6516
|
for (let i = 0; i < 10; i++) {
|
|
5984
6517
|
try {
|
|
5985
|
-
const pkgJsonPath =
|
|
5986
|
-
if (
|
|
5987
|
-
const pkg = JSON.parse(
|
|
6518
|
+
const pkgJsonPath = path9.join(currentDir, "package.json");
|
|
6519
|
+
if (fs9.existsSync(pkgJsonPath)) {
|
|
6520
|
+
const pkg = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5988
6521
|
if (pkg.name === "@masumdev/markforge" && pkg.version) {
|
|
5989
6522
|
return pkg.version;
|
|
5990
6523
|
}
|
|
5991
6524
|
}
|
|
5992
6525
|
} catch {
|
|
5993
6526
|
}
|
|
5994
|
-
const parentDir =
|
|
6527
|
+
const parentDir = path9.dirname(currentDir);
|
|
5995
6528
|
if (parentDir === currentDir) break;
|
|
5996
6529
|
currentDir = parentDir;
|
|
5997
6530
|
}
|
|
@@ -6004,7 +6537,7 @@ function getPackageDir() {
|
|
|
6004
6537
|
return __dirname;
|
|
6005
6538
|
}
|
|
6006
6539
|
try {
|
|
6007
|
-
return
|
|
6540
|
+
return path9.dirname((0, import_node_url6.fileURLToPath)(import_meta.url));
|
|
6008
6541
|
} catch {
|
|
6009
6542
|
return process.cwd();
|
|
6010
6543
|
}
|
|
@@ -6015,6 +6548,8 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
6015
6548
|
}
|
|
6016
6549
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6017
6550
|
0 && (module.exports = {
|
|
6551
|
+
BackCoverPreset,
|
|
6552
|
+
CoverPagePreset,
|
|
6018
6553
|
DEFAULT_CONFIG,
|
|
6019
6554
|
KATEX_INLINE_CSS,
|
|
6020
6555
|
MARKFORGE_VERSION,
|
|
@@ -6023,6 +6558,8 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
6023
6558
|
PAPER_DIMENSIONS_TWIP,
|
|
6024
6559
|
PaperSizeEnum,
|
|
6025
6560
|
SYNTAX_COLORS,
|
|
6561
|
+
SignatureAlign,
|
|
6562
|
+
SignatureStyle,
|
|
6026
6563
|
SyntaxTheme,
|
|
6027
6564
|
THEMES,
|
|
6028
6565
|
THEME_CORPORATE,
|
|
@@ -6033,6 +6570,9 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
6033
6570
|
buildDocxDocument,
|
|
6034
6571
|
buildHtmlDocument,
|
|
6035
6572
|
buildPdfDocument,
|
|
6573
|
+
buildPngDocument,
|
|
6574
|
+
buildTextDocument,
|
|
6575
|
+
buildTxtDocument,
|
|
6036
6576
|
compileMarkdown,
|
|
6037
6577
|
defineConfig,
|
|
6038
6578
|
escapeHtml,
|
|
@@ -6061,6 +6601,7 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
6061
6601
|
renderBackCoverHtml,
|
|
6062
6602
|
renderCoverPageHtml,
|
|
6063
6603
|
renderInlinesToHtml,
|
|
6604
|
+
renderInlinesToText,
|
|
6064
6605
|
renderMathToHtml,
|
|
6065
6606
|
renderMermaidToPng,
|
|
6066
6607
|
renderNodesToHtml,
|