@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.mjs
CHANGED
|
@@ -14,8 +14,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
// src/core/engine.ts
|
|
17
|
-
import * as
|
|
18
|
-
import * as
|
|
17
|
+
import * as fs7 from "fs";
|
|
18
|
+
import * as path7 from "path";
|
|
19
19
|
|
|
20
20
|
// src/core/parser.ts
|
|
21
21
|
import matter from "gray-matter";
|
|
@@ -591,12 +591,14 @@ import {
|
|
|
591
591
|
ExternalHyperlink,
|
|
592
592
|
TabStopType,
|
|
593
593
|
PageBreak,
|
|
594
|
-
NumberFormat
|
|
594
|
+
NumberFormat,
|
|
595
|
+
SectionType
|
|
595
596
|
} from "docx";
|
|
596
597
|
|
|
597
598
|
// src/core/imageResolver.ts
|
|
598
599
|
import * as fs from "fs";
|
|
599
600
|
import * as path from "path";
|
|
601
|
+
import { fileURLToPath } from "url";
|
|
600
602
|
var memoryImageCache = /* @__PURE__ */ new Map();
|
|
601
603
|
function getMimeType(filePathOrUrl) {
|
|
602
604
|
const clean = filePathOrUrl.split("?")[0].toLowerCase();
|
|
@@ -653,9 +655,19 @@ async function resolveImage(src, baseDir = process.cwd()) {
|
|
|
653
655
|
memoryImageCache.set(cacheKey, resolved2);
|
|
654
656
|
return resolved2;
|
|
655
657
|
}
|
|
656
|
-
let localPath =
|
|
658
|
+
let localPath = src;
|
|
659
|
+
if (src.startsWith("file://")) {
|
|
660
|
+
try {
|
|
661
|
+
localPath = fileURLToPath(src);
|
|
662
|
+
} catch {
|
|
663
|
+
localPath = src;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (!path.isAbsolute(localPath)) {
|
|
667
|
+
localPath = path.resolve(baseDir, localPath);
|
|
668
|
+
}
|
|
657
669
|
if (!fs.existsSync(localPath)) {
|
|
658
|
-
const cwdPath = path.resolve(process.cwd(), src);
|
|
670
|
+
const cwdPath = path.resolve(process.cwd(), src.startsWith("file://") ? localPath : src);
|
|
659
671
|
if (fs.existsSync(cwdPath)) {
|
|
660
672
|
localPath = cwdPath;
|
|
661
673
|
} else {
|
|
@@ -1078,6 +1090,7 @@ var OutputFormat = /* @__PURE__ */ ((OutputFormat2) => {
|
|
|
1078
1090
|
OutputFormat2["PDF"] = "pdf";
|
|
1079
1091
|
OutputFormat2["HTML"] = "html";
|
|
1080
1092
|
OutputFormat2["PNG"] = "png";
|
|
1093
|
+
OutputFormat2["TXT"] = "txt";
|
|
1081
1094
|
return OutputFormat2;
|
|
1082
1095
|
})(OutputFormat || {});
|
|
1083
1096
|
var Theme = /* @__PURE__ */ ((Theme2) => {
|
|
@@ -1112,6 +1125,33 @@ var WatermarkPosition = /* @__PURE__ */ ((WatermarkPosition2) => {
|
|
|
1112
1125
|
WatermarkPosition2["BOTTOM_RIGHT"] = "bottom-right";
|
|
1113
1126
|
return WatermarkPosition2;
|
|
1114
1127
|
})(WatermarkPosition || {});
|
|
1128
|
+
var CoverPagePreset = /* @__PURE__ */ ((CoverPagePreset2) => {
|
|
1129
|
+
CoverPagePreset2["MODERN"] = "modern";
|
|
1130
|
+
CoverPagePreset2["CORPORATE_SPLIT"] = "corporate-split";
|
|
1131
|
+
CoverPagePreset2["MINIMAL"] = "minimal";
|
|
1132
|
+
CoverPagePreset2["CARD"] = "card";
|
|
1133
|
+
return CoverPagePreset2;
|
|
1134
|
+
})(CoverPagePreset || {});
|
|
1135
|
+
var BackCoverPreset = /* @__PURE__ */ ((BackCoverPreset2) => {
|
|
1136
|
+
BackCoverPreset2["MODERN"] = "modern";
|
|
1137
|
+
BackCoverPreset2["CORPORATE"] = "corporate";
|
|
1138
|
+
BackCoverPreset2["MINIMAL"] = "minimal";
|
|
1139
|
+
BackCoverPreset2["CONTACT_CARD"] = "contact-card";
|
|
1140
|
+
return BackCoverPreset2;
|
|
1141
|
+
})(BackCoverPreset || {});
|
|
1142
|
+
var SignatureAlign = /* @__PURE__ */ ((SignatureAlign2) => {
|
|
1143
|
+
SignatureAlign2["LEFT"] = "left";
|
|
1144
|
+
SignatureAlign2["CENTER"] = "center";
|
|
1145
|
+
SignatureAlign2["RIGHT"] = "right";
|
|
1146
|
+
SignatureAlign2["SPACE_BETWEEN"] = "space-between";
|
|
1147
|
+
return SignatureAlign2;
|
|
1148
|
+
})(SignatureAlign || {});
|
|
1149
|
+
var SignatureStyle = /* @__PURE__ */ ((SignatureStyle2) => {
|
|
1150
|
+
SignatureStyle2["LINE"] = "line";
|
|
1151
|
+
SignatureStyle2["BOX"] = "box";
|
|
1152
|
+
SignatureStyle2["CLEAN"] = "clean";
|
|
1153
|
+
return SignatureStyle2;
|
|
1154
|
+
})(SignatureStyle || {});
|
|
1115
1155
|
|
|
1116
1156
|
// src/core/html/htmlThemes.ts
|
|
1117
1157
|
var THEME_COMPONENTS = `
|
|
@@ -2426,7 +2466,7 @@ async function renderBackCoverHtml(backCover, baseDir = process.cwd()) {
|
|
|
2426
2466
|
`;
|
|
2427
2467
|
return { html, css };
|
|
2428
2468
|
}
|
|
2429
|
-
async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
2469
|
+
async function buildHtmlDocument(doc, config = {}, baseDir = process.cwd()) {
|
|
2430
2470
|
var _a, _b;
|
|
2431
2471
|
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
2432
2472
|
const baseThemeCss = generateThemeCss(resolved.theme);
|
|
@@ -2777,8 +2817,11 @@ function escapeXml(str) {
|
|
|
2777
2817
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2778
2818
|
}
|
|
2779
2819
|
function generateWatermarkPngBuffer(chromePath, wm) {
|
|
2780
|
-
const
|
|
2781
|
-
const
|
|
2820
|
+
const tmpId = Math.random().toString(36).substring(2, 9);
|
|
2821
|
+
const tmpDir = os.tmpdir();
|
|
2822
|
+
const tmpHtml = path4.join(tmpDir, `markforge-wm-${tmpId}.html`);
|
|
2823
|
+
const tmpPng = path4.join(tmpDir, `markforge-wm-${tmpId}.png`);
|
|
2824
|
+
const tmpProfile = path4.join(tmpDir, `markforge-wm-prof-${tmpId}`);
|
|
2782
2825
|
try {
|
|
2783
2826
|
const text = escapeXml(wm.text.toUpperCase());
|
|
2784
2827
|
const fontSize = (wm.fontSize || 52) * 1.5;
|
|
@@ -2829,6 +2872,9 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2829
2872
|
chromePath,
|
|
2830
2873
|
[
|
|
2831
2874
|
"--headless=new",
|
|
2875
|
+
`--user-data-dir=${tmpProfile}`,
|
|
2876
|
+
"--no-first-run",
|
|
2877
|
+
"--no-default-browser-check",
|
|
2832
2878
|
"--disable-gpu",
|
|
2833
2879
|
"--disable-sync",
|
|
2834
2880
|
"--disable-extensions",
|
|
@@ -2850,6 +2896,7 @@ function generateWatermarkPngBuffer(chromePath, wm) {
|
|
|
2850
2896
|
try {
|
|
2851
2897
|
if (fs4.existsSync(tmpHtml)) fs4.unlinkSync(tmpHtml);
|
|
2852
2898
|
if (fs4.existsSync(tmpPng)) fs4.unlinkSync(tmpPng);
|
|
2899
|
+
if (fs4.existsSync(tmpProfile)) fs4.rmSync(tmpProfile, { recursive: true, force: true });
|
|
2853
2900
|
} catch {
|
|
2854
2901
|
}
|
|
2855
2902
|
}
|
|
@@ -2865,6 +2912,8 @@ function findChromeExecutable() {
|
|
|
2865
2912
|
const winLocalAppData = process.env.LOCALAPPDATA ?? "";
|
|
2866
2913
|
const winProgramFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
2867
2914
|
const winProgramFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
2915
|
+
const winProgramW6432 = process.env.ProgramW6432 ?? "C:\\Program Files";
|
|
2916
|
+
const winUserProfile = process.env.USERPROFILE ?? "";
|
|
2868
2917
|
const candidates = [
|
|
2869
2918
|
// Linux
|
|
2870
2919
|
"/usr/bin/google-chrome",
|
|
@@ -2883,17 +2932,34 @@ function findChromeExecutable() {
|
|
|
2883
2932
|
// Windows — Microsoft Edge (Native Windows 10/11 browser, enterprise whitelist friendly)
|
|
2884
2933
|
`${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2885
2934
|
`${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2935
|
+
`${winProgramW6432}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2886
2936
|
`${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
2887
|
-
|
|
2937
|
+
`${winLocalAppData}\\Microsoft\\Edge Dev\\Application\\msedge.exe`,
|
|
2938
|
+
`${winLocalAppData}\\Microsoft\\Edge Beta\\Application\\msedge.exe`,
|
|
2939
|
+
// Windows — Google Chrome & Chrome SxS (Canary)
|
|
2888
2940
|
`${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2889
2941
|
`${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2942
|
+
`${winProgramW6432}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2890
2943
|
`${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
2944
|
+
`${winLocalAppData}\\Google\\Chrome SxS\\Application\\chrome.exe`,
|
|
2891
2945
|
// Windows — Brave Browser
|
|
2892
2946
|
`${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2893
2947
|
`${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2948
|
+
`${winProgramW6432}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2894
2949
|
`${winLocalAppData}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
2895
2950
|
// Windows — Chromium
|
|
2896
|
-
`${winLocalAppData}\\Chromium\\Application\\chrome.exe
|
|
2951
|
+
`${winLocalAppData}\\Chromium\\Application\\chrome.exe`,
|
|
2952
|
+
// Windows — Scoop Package Manager
|
|
2953
|
+
`${winUserProfile}\\scoop\\apps\\googlechrome\\current\\chrome.exe`,
|
|
2954
|
+
`${winUserProfile}\\scoop\\apps\\chromium\\current\\chrome.exe`,
|
|
2955
|
+
`${winUserProfile}\\scoop\\apps\\brave\\current\\brave.exe`,
|
|
2956
|
+
`${winUserProfile}\\scoop\\apps\\msedge\\current\\msedge.exe`,
|
|
2957
|
+
`${winUserProfile}\\scoop\\shims\\chrome.exe`,
|
|
2958
|
+
`${winUserProfile}\\scoop\\shims\\msedge.exe`,
|
|
2959
|
+
// Windows — Chocolatey
|
|
2960
|
+
"C:\\ProgramData\\chocolatey\\bin\\chrome.exe",
|
|
2961
|
+
"C:\\ProgramData\\chocolatey\\bin\\msedge.exe",
|
|
2962
|
+
"C:\\ProgramData\\chocolatey\\bin\\brave.exe"
|
|
2897
2963
|
].filter(Boolean);
|
|
2898
2964
|
for (const candidate of candidates) {
|
|
2899
2965
|
try {
|
|
@@ -2904,13 +2970,15 @@ function findChromeExecutable() {
|
|
|
2904
2970
|
}
|
|
2905
2971
|
}
|
|
2906
2972
|
try {
|
|
2907
|
-
const cmd = isWin ? "where" : "which";
|
|
2908
|
-
const names = isWin ? ["chrome", "msedge", "brave", "google-chrome", "chromium", "chromium-browser"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "microsoft-edge", "brave-browser"];
|
|
2973
|
+
const cmd = isWin ? "where.exe" : "which";
|
|
2974
|
+
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"];
|
|
2909
2975
|
for (const name of names) {
|
|
2910
|
-
const res = spawnSync(cmd, [name], { encoding: "utf-8" });
|
|
2976
|
+
const res = spawnSync(cmd, [name], { encoding: "utf-8", windowsHide: true });
|
|
2911
2977
|
if (res.status === 0 && res.stdout.trim()) {
|
|
2912
|
-
const
|
|
2913
|
-
|
|
2978
|
+
const lines = res.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
2979
|
+
for (const line of lines) {
|
|
2980
|
+
if (fs4.existsSync(line)) return line;
|
|
2981
|
+
}
|
|
2914
2982
|
}
|
|
2915
2983
|
}
|
|
2916
2984
|
} catch {
|
|
@@ -3244,6 +3312,8 @@ async function renderMermaidToPng(mermaidCode, _baseDir = process.cwd()) {
|
|
|
3244
3312
|
const tmpDir = os2.tmpdir();
|
|
3245
3313
|
const tmpHtml = path5.join(tmpDir, `mermaid_${tmpId}.html`);
|
|
3246
3314
|
const tmpScreenshot = path5.join(tmpDir, `mermaid_${tmpId}.png`);
|
|
3315
|
+
const tmpProfile = path5.join(tmpDir, `mermaid_prof_${tmpId}`);
|
|
3316
|
+
const isWin = process.platform === "win32";
|
|
3247
3317
|
const htmlContent = `<!DOCTYPE html>
|
|
3248
3318
|
<html>
|
|
3249
3319
|
<head>
|
|
@@ -3287,10 +3357,14 @@ ${mermaidCode}
|
|
|
3287
3357
|
const res = spawnSync2(
|
|
3288
3358
|
chromePath,
|
|
3289
3359
|
[
|
|
3290
|
-
"--headless",
|
|
3360
|
+
"--headless=new",
|
|
3361
|
+
`--user-data-dir=${tmpProfile}`,
|
|
3362
|
+
"--no-first-run",
|
|
3363
|
+
"--no-default-browser-check",
|
|
3291
3364
|
"--disable-gpu",
|
|
3292
|
-
"--
|
|
3293
|
-
"--disable-
|
|
3365
|
+
"--disable-sync",
|
|
3366
|
+
"--disable-extensions",
|
|
3367
|
+
...isWin ? [] : ["--no-sandbox", "--disable-setuid-sandbox"],
|
|
3294
3368
|
"--allow-file-access-from-files",
|
|
3295
3369
|
"--disable-web-security",
|
|
3296
3370
|
"--disable-software-rasterizer",
|
|
@@ -3299,7 +3373,7 @@ ${mermaidCode}
|
|
|
3299
3373
|
`--screenshot=${tmpScreenshot}`,
|
|
3300
3374
|
fileUrl
|
|
3301
3375
|
],
|
|
3302
|
-
{ timeout: 15e3 }
|
|
3376
|
+
{ timeout: 15e3, windowsHide: true }
|
|
3303
3377
|
);
|
|
3304
3378
|
if (res.status === 0 && fs5.existsSync(tmpScreenshot)) {
|
|
3305
3379
|
const buffer = fs5.readFileSync(tmpScreenshot);
|
|
@@ -3310,6 +3384,7 @@ ${mermaidCode}
|
|
|
3310
3384
|
try {
|
|
3311
3385
|
if (fs5.existsSync(tmpHtml)) fs5.unlinkSync(tmpHtml);
|
|
3312
3386
|
if (fs5.existsSync(tmpScreenshot)) fs5.unlinkSync(tmpScreenshot);
|
|
3387
|
+
if (fs5.existsSync(tmpProfile)) fs5.rmSync(tmpProfile, { recursive: true, force: true });
|
|
3313
3388
|
} catch {
|
|
3314
3389
|
}
|
|
3315
3390
|
}
|
|
@@ -4451,6 +4526,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4451
4526
|
);
|
|
4452
4527
|
docSections.push({
|
|
4453
4528
|
properties: {
|
|
4529
|
+
type: SectionType.NEXT_PAGE,
|
|
4454
4530
|
page: {
|
|
4455
4531
|
size: {
|
|
4456
4532
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4465,13 +4541,14 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4465
4541
|
}
|
|
4466
4542
|
}
|
|
4467
4543
|
},
|
|
4468
|
-
headers:
|
|
4469
|
-
footers:
|
|
4544
|
+
headers: { default: new Header({ children: [] }) },
|
|
4545
|
+
footers: { default: new Footer({ children: [] }) },
|
|
4470
4546
|
children: coverElements
|
|
4471
4547
|
});
|
|
4472
4548
|
}
|
|
4473
4549
|
docSections.push({
|
|
4474
4550
|
properties: {
|
|
4551
|
+
type: SectionType.NEXT_PAGE,
|
|
4475
4552
|
page: {
|
|
4476
4553
|
pageNumbers: {
|
|
4477
4554
|
start: 1,
|
|
@@ -4492,8 +4569,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4492
4569
|
}
|
|
4493
4570
|
}
|
|
4494
4571
|
},
|
|
4495
|
-
headers: docHeader ? { default: docHeader } :
|
|
4496
|
-
footers: docFooter ? { default: docFooter } :
|
|
4572
|
+
headers: docHeader ? { default: docHeader } : { default: new Header({ children: [] }) },
|
|
4573
|
+
footers: docFooter ? { default: docFooter } : { default: new Footer({ children: [] }) },
|
|
4497
4574
|
children: docElements
|
|
4498
4575
|
});
|
|
4499
4576
|
if (resolved.backCover && resolved.backCover.enabled) {
|
|
@@ -4508,6 +4585,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4508
4585
|
);
|
|
4509
4586
|
docSections.push({
|
|
4510
4587
|
properties: {
|
|
4588
|
+
type: SectionType.NEXT_PAGE,
|
|
4511
4589
|
page: {
|
|
4512
4590
|
size: {
|
|
4513
4591
|
width: resolved.paperDimensions.widthTwip,
|
|
@@ -4522,8 +4600,8 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
4522
4600
|
}
|
|
4523
4601
|
}
|
|
4524
4602
|
},
|
|
4525
|
-
headers:
|
|
4526
|
-
footers:
|
|
4603
|
+
headers: { default: new Header({ children: [] }) },
|
|
4604
|
+
footers: { default: new Footer({ children: [] }) },
|
|
4527
4605
|
children: backElements
|
|
4528
4606
|
});
|
|
4529
4607
|
}
|
|
@@ -4926,6 +5004,432 @@ function createEmptyDocxCell(widthDxa) {
|
|
|
4926
5004
|
});
|
|
4927
5005
|
}
|
|
4928
5006
|
|
|
5007
|
+
// src/core/text/textBuilder.ts
|
|
5008
|
+
var LINE_WIDTH = 80;
|
|
5009
|
+
var HR_DOUBLE = "=".repeat(LINE_WIDTH);
|
|
5010
|
+
var HR_SINGLE = "-".repeat(LINE_WIDTH);
|
|
5011
|
+
function centerText(text, width = LINE_WIDTH) {
|
|
5012
|
+
if (text.length >= width) return text;
|
|
5013
|
+
const leftPad = Math.floor((width - text.length) / 2);
|
|
5014
|
+
return " ".repeat(leftPad) + text;
|
|
5015
|
+
}
|
|
5016
|
+
function renderInlinesToText(spans = [], meta = {}) {
|
|
5017
|
+
let result = "";
|
|
5018
|
+
for (const span of spans) {
|
|
5019
|
+
switch (span.type) {
|
|
5020
|
+
case "text": {
|
|
5021
|
+
const content = replaceDocumentTokens(span.content, meta);
|
|
5022
|
+
result += content;
|
|
5023
|
+
break;
|
|
5024
|
+
}
|
|
5025
|
+
case "bold": {
|
|
5026
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5027
|
+
result += `**${inner}**`;
|
|
5028
|
+
break;
|
|
5029
|
+
}
|
|
5030
|
+
case "italic": {
|
|
5031
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5032
|
+
result += `*${inner}*`;
|
|
5033
|
+
break;
|
|
5034
|
+
}
|
|
5035
|
+
case "code": {
|
|
5036
|
+
result += `\`${span.content}\``;
|
|
5037
|
+
break;
|
|
5038
|
+
}
|
|
5039
|
+
case "link": {
|
|
5040
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5041
|
+
result += span.url && span.url !== inner ? `${inner} (${span.url})` : inner;
|
|
5042
|
+
break;
|
|
5043
|
+
}
|
|
5044
|
+
case "image": {
|
|
5045
|
+
result += `[Image: ${span.alt || "image"} (${span.url || ""})]`;
|
|
5046
|
+
break;
|
|
5047
|
+
}
|
|
5048
|
+
case "strikethrough": {
|
|
5049
|
+
const inner = span.children ? renderInlinesToText(span.children, meta) : replaceDocumentTokens(span.content, meta);
|
|
5050
|
+
result += `~${inner}~`;
|
|
5051
|
+
break;
|
|
5052
|
+
}
|
|
5053
|
+
case "mathInline": {
|
|
5054
|
+
result += `$${span.content}$`;
|
|
5055
|
+
break;
|
|
5056
|
+
}
|
|
5057
|
+
case "footnoteRef": {
|
|
5058
|
+
const id = span.footnoteId || span.content;
|
|
5059
|
+
result += `[${id}]`;
|
|
5060
|
+
break;
|
|
5061
|
+
}
|
|
5062
|
+
case "htmlInline": {
|
|
5063
|
+
result += span.content.replace(/<[^>]+>/g, "");
|
|
5064
|
+
break;
|
|
5065
|
+
}
|
|
5066
|
+
default: {
|
|
5067
|
+
result += span.content || "";
|
|
5068
|
+
break;
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
5071
|
+
}
|
|
5072
|
+
return result;
|
|
5073
|
+
}
|
|
5074
|
+
async function buildTextDocument(doc, config = {}, _baseDir = process.cwd()) {
|
|
5075
|
+
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
5076
|
+
const meta = {
|
|
5077
|
+
...doc.metadata,
|
|
5078
|
+
...config.metadata,
|
|
5079
|
+
title: resolved.title,
|
|
5080
|
+
subtitle: resolved.subtitle,
|
|
5081
|
+
author: resolved.author,
|
|
5082
|
+
company: resolved.company,
|
|
5083
|
+
version: resolved.version,
|
|
5084
|
+
date: resolved.date
|
|
5085
|
+
};
|
|
5086
|
+
const nodes = JSON.parse(JSON.stringify(doc.nodes));
|
|
5087
|
+
const tocEntries = JSON.parse(JSON.stringify(doc.tocEntries));
|
|
5088
|
+
if (resolved.numberHeadings && resolved.numberHeadings.enabled) {
|
|
5089
|
+
applyHeadingNumbering(nodes, tocEntries, resolved.numberHeadings);
|
|
5090
|
+
}
|
|
5091
|
+
const lines = [];
|
|
5092
|
+
if (resolved.coverPage && resolved.coverPage.enabled) {
|
|
5093
|
+
const cover = resolved.coverPage;
|
|
5094
|
+
const coverTitle = (cover.title || meta.title || "DOCUMENT").toUpperCase();
|
|
5095
|
+
const coverSubtitle = cover.subtitle || meta.subtitle || "";
|
|
5096
|
+
const coverAuthor = cover.author || meta.author || "";
|
|
5097
|
+
const coverCompany = cover.company || meta.company || "";
|
|
5098
|
+
const coverDate = cover.date || meta.date || "";
|
|
5099
|
+
const coverVersion = cover.version || meta.version || "";
|
|
5100
|
+
const coverBadge = cover.badge || "";
|
|
5101
|
+
const coverFooter = cover.footerText || "";
|
|
5102
|
+
lines.push(HR_DOUBLE);
|
|
5103
|
+
lines.push(centerText(coverTitle));
|
|
5104
|
+
if (coverSubtitle) {
|
|
5105
|
+
lines.push(centerText(coverSubtitle));
|
|
5106
|
+
}
|
|
5107
|
+
lines.push(HR_DOUBLE);
|
|
5108
|
+
if (coverBadge) {
|
|
5109
|
+
lines.push(`[${coverBadge}]`);
|
|
5110
|
+
lines.push("");
|
|
5111
|
+
}
|
|
5112
|
+
if (coverAuthor) lines.push(`Author: ${coverAuthor}`);
|
|
5113
|
+
if (coverCompany) lines.push(`Company: ${coverCompany}`);
|
|
5114
|
+
if (coverDate) lines.push(`Date: ${coverDate}`);
|
|
5115
|
+
if (coverVersion) lines.push(`Version: ${coverVersion}`);
|
|
5116
|
+
if (coverFooter) lines.push(`Notice: ${coverFooter}`);
|
|
5117
|
+
lines.push(HR_DOUBLE);
|
|
5118
|
+
lines.push("");
|
|
5119
|
+
lines.push("");
|
|
5120
|
+
}
|
|
5121
|
+
if (resolved.toc) {
|
|
5122
|
+
const headings = nodes.filter(
|
|
5123
|
+
(n) => n.type === "heading" && (n.level || 1) <= 3
|
|
5124
|
+
);
|
|
5125
|
+
if (headings.length > 0) {
|
|
5126
|
+
const tocTitle = "TABLE OF CONTENTS";
|
|
5127
|
+
lines.push(HR_DOUBLE);
|
|
5128
|
+
lines.push(centerText(tocTitle));
|
|
5129
|
+
lines.push(HR_DOUBLE);
|
|
5130
|
+
for (const h of headings) {
|
|
5131
|
+
const level = h.level || 1;
|
|
5132
|
+
const indent = " ".repeat(level - 1);
|
|
5133
|
+
const headingText = renderInlinesToText(h.inlines, meta);
|
|
5134
|
+
const prefix = level === 1 ? "* " : "- ";
|
|
5135
|
+
lines.push(`${indent}${prefix}${headingText}`);
|
|
5136
|
+
}
|
|
5137
|
+
lines.push(HR_DOUBLE);
|
|
5138
|
+
lines.push("");
|
|
5139
|
+
lines.push("");
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
function renderNode(node, listLevel = 0) {
|
|
5143
|
+
var _a;
|
|
5144
|
+
switch (node.type) {
|
|
5145
|
+
case "heading": {
|
|
5146
|
+
const level = node.level || 1;
|
|
5147
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5148
|
+
lines.push("");
|
|
5149
|
+
if (level === 1) {
|
|
5150
|
+
lines.push(HR_DOUBLE);
|
|
5151
|
+
lines.push(text.toUpperCase());
|
|
5152
|
+
lines.push(HR_DOUBLE);
|
|
5153
|
+
} else if (level === 2) {
|
|
5154
|
+
lines.push(HR_SINGLE);
|
|
5155
|
+
lines.push(text);
|
|
5156
|
+
lines.push(HR_SINGLE);
|
|
5157
|
+
} else {
|
|
5158
|
+
const hashes = "#".repeat(level);
|
|
5159
|
+
lines.push(`${hashes} ${text}`);
|
|
5160
|
+
}
|
|
5161
|
+
lines.push("");
|
|
5162
|
+
break;
|
|
5163
|
+
}
|
|
5164
|
+
case "paragraph": {
|
|
5165
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5166
|
+
if (text.trim()) {
|
|
5167
|
+
lines.push(text);
|
|
5168
|
+
lines.push("");
|
|
5169
|
+
}
|
|
5170
|
+
break;
|
|
5171
|
+
}
|
|
5172
|
+
case "callout": {
|
|
5173
|
+
const calloutType = (node.calloutType || "NOTE").toUpperCase();
|
|
5174
|
+
lines.push(`| [${calloutType}]`);
|
|
5175
|
+
if (node.inlines && node.inlines.length > 0) {
|
|
5176
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5177
|
+
text.split("\n").forEach((l) => lines.push(`| ${l}`));
|
|
5178
|
+
}
|
|
5179
|
+
lines.push("");
|
|
5180
|
+
break;
|
|
5181
|
+
}
|
|
5182
|
+
case "blockquote": {
|
|
5183
|
+
if (node.inlines && node.inlines.length > 0) {
|
|
5184
|
+
const text = renderInlinesToText(node.inlines, meta);
|
|
5185
|
+
text.split("\n").forEach((l) => lines.push(`> ${l}`));
|
|
5186
|
+
lines.push("");
|
|
5187
|
+
}
|
|
5188
|
+
break;
|
|
5189
|
+
}
|
|
5190
|
+
case "codeBlock": {
|
|
5191
|
+
const lang = node.language ? `[Language: ${node.language}]` : "[Code]";
|
|
5192
|
+
lines.push(HR_SINGLE);
|
|
5193
|
+
lines.push(lang);
|
|
5194
|
+
lines.push(HR_SINGLE);
|
|
5195
|
+
const codeText = node.text || "";
|
|
5196
|
+
lines.push(codeText);
|
|
5197
|
+
lines.push(HR_SINGLE);
|
|
5198
|
+
lines.push("");
|
|
5199
|
+
break;
|
|
5200
|
+
}
|
|
5201
|
+
case "list": {
|
|
5202
|
+
if (node.children) {
|
|
5203
|
+
let itemIndex = 1;
|
|
5204
|
+
for (const item of node.children) {
|
|
5205
|
+
const indent = " ".repeat(listLevel);
|
|
5206
|
+
let prefix = node.ordered ? `${itemIndex}. ` : "* ";
|
|
5207
|
+
itemIndex++;
|
|
5208
|
+
if (item.checked !== void 0) {
|
|
5209
|
+
prefix = item.checked ? "[x] " : "[ ] ";
|
|
5210
|
+
}
|
|
5211
|
+
if (item.inlines && item.inlines.length > 0) {
|
|
5212
|
+
const text = renderInlinesToText(item.inlines, meta);
|
|
5213
|
+
lines.push(`${indent}${prefix}${text}`);
|
|
5214
|
+
}
|
|
5215
|
+
if (item.children && item.children.length > 0) {
|
|
5216
|
+
for (const subChild of item.children) {
|
|
5217
|
+
if (subChild.type === "list") {
|
|
5218
|
+
renderNode(subChild, listLevel + 1);
|
|
5219
|
+
} else if (subChild.type === "paragraph") {
|
|
5220
|
+
const text = renderInlinesToText(subChild.inlines, meta);
|
|
5221
|
+
lines.push(`${indent} ${text}`);
|
|
5222
|
+
} else {
|
|
5223
|
+
renderNode(subChild, listLevel + 1);
|
|
5224
|
+
}
|
|
5225
|
+
}
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
lines.push("");
|
|
5229
|
+
}
|
|
5230
|
+
break;
|
|
5231
|
+
}
|
|
5232
|
+
case "table": {
|
|
5233
|
+
const rows = node.children || [];
|
|
5234
|
+
if (rows.length === 0) break;
|
|
5235
|
+
const rowCells = [];
|
|
5236
|
+
let maxCols = 0;
|
|
5237
|
+
for (const row of rows) {
|
|
5238
|
+
const cells = row.children || [];
|
|
5239
|
+
const texts = cells.map((c) => renderInlinesToText(c.inlines, meta));
|
|
5240
|
+
const isHeader = cells.some((c) => c.isHeader);
|
|
5241
|
+
maxCols = Math.max(maxCols, texts.length);
|
|
5242
|
+
rowCells.push({ isHeader, texts });
|
|
5243
|
+
}
|
|
5244
|
+
if (maxCols === 0) break;
|
|
5245
|
+
const colWidths = new Array(maxCols).fill(3);
|
|
5246
|
+
for (const r of rowCells) {
|
|
5247
|
+
for (let col = 0; col < maxCols; col++) {
|
|
5248
|
+
const cellText = r.texts[col] || "";
|
|
5249
|
+
colWidths[col] = Math.max(colWidths[col] ?? 3, cellText.length);
|
|
5250
|
+
}
|
|
5251
|
+
}
|
|
5252
|
+
const separatorLine = "+" + colWidths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
5253
|
+
const formatRow = (texts) => {
|
|
5254
|
+
const paddedCells = colWidths.map((width, colIdx) => {
|
|
5255
|
+
const text = texts[colIdx] || "";
|
|
5256
|
+
return " " + text.padEnd(width, " ") + " ";
|
|
5257
|
+
});
|
|
5258
|
+
return "|" + paddedCells.join("|") + "|";
|
|
5259
|
+
};
|
|
5260
|
+
lines.push(separatorLine);
|
|
5261
|
+
for (const r of rowCells) {
|
|
5262
|
+
lines.push(formatRow(r.texts));
|
|
5263
|
+
if (r.isHeader) {
|
|
5264
|
+
lines.push(separatorLine);
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
if (!((_a = rowCells[rowCells.length - 1]) == null ? void 0 : _a.isHeader)) {
|
|
5268
|
+
lines.push(separatorLine);
|
|
5269
|
+
}
|
|
5270
|
+
lines.push("");
|
|
5271
|
+
break;
|
|
5272
|
+
}
|
|
5273
|
+
case "mathBlock": {
|
|
5274
|
+
lines.push("[Equation]");
|
|
5275
|
+
lines.push(` $$${node.text || ""} $$`);
|
|
5276
|
+
lines.push("");
|
|
5277
|
+
break;
|
|
5278
|
+
}
|
|
5279
|
+
case "mermaid": {
|
|
5280
|
+
lines.push("[Diagram: Mermaid]");
|
|
5281
|
+
lines.push(node.text || "");
|
|
5282
|
+
lines.push("");
|
|
5283
|
+
break;
|
|
5284
|
+
}
|
|
5285
|
+
case "thematicBreak": {
|
|
5286
|
+
lines.push(HR_SINGLE);
|
|
5287
|
+
lines.push("");
|
|
5288
|
+
break;
|
|
5289
|
+
}
|
|
5290
|
+
case "columns": {
|
|
5291
|
+
if (node.children) {
|
|
5292
|
+
for (const col of node.children) {
|
|
5293
|
+
if (col.children) {
|
|
5294
|
+
for (const child of col.children) {
|
|
5295
|
+
renderNode(child, listLevel);
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
break;
|
|
5301
|
+
}
|
|
5302
|
+
default: {
|
|
5303
|
+
if (node.children && node.children.length > 0) {
|
|
5304
|
+
for (const child of node.children) {
|
|
5305
|
+
renderNode(child, listLevel);
|
|
5306
|
+
}
|
|
5307
|
+
}
|
|
5308
|
+
break;
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
for (const node of nodes) {
|
|
5313
|
+
renderNode(node);
|
|
5314
|
+
}
|
|
5315
|
+
if (doc.footnoteDefs && doc.footnoteDefs.length > 0) {
|
|
5316
|
+
lines.push(HR_SINGLE);
|
|
5317
|
+
lines.push("FOOTNOTES");
|
|
5318
|
+
lines.push(HR_SINGLE);
|
|
5319
|
+
for (const fn of doc.footnoteDefs) {
|
|
5320
|
+
const text = renderInlinesToText(fn.inlines, meta);
|
|
5321
|
+
lines.push(`[${fn.id}] ${text}`);
|
|
5322
|
+
}
|
|
5323
|
+
lines.push("");
|
|
5324
|
+
}
|
|
5325
|
+
if (resolved.signatures && resolved.signatures.items && resolved.signatures.items.length > 0) {
|
|
5326
|
+
lines.push(HR_SINGLE);
|
|
5327
|
+
lines.push("SIGNATURES & APPROVALS");
|
|
5328
|
+
lines.push(HR_SINGLE);
|
|
5329
|
+
lines.push("");
|
|
5330
|
+
for (const item of resolved.signatures.items) {
|
|
5331
|
+
const title = item.title || "Signatory";
|
|
5332
|
+
const name = item.name ? replaceDocumentTokens(item.name, meta) : "";
|
|
5333
|
+
const role = item.role ? replaceDocumentTokens(item.role, meta) : "";
|
|
5334
|
+
const date = item.date ? replaceDocumentTokens(item.date, meta) : "";
|
|
5335
|
+
lines.push(`[${title}]`);
|
|
5336
|
+
lines.push("____________________________________");
|
|
5337
|
+
if (name) lines.push(`Name: ${name}`);
|
|
5338
|
+
if (role) lines.push(`Role: ${role}`);
|
|
5339
|
+
if (date) lines.push(`Date: ${date}`);
|
|
5340
|
+
lines.push("");
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
if (resolved.backCover && resolved.backCover.enabled) {
|
|
5344
|
+
const back = resolved.backCover;
|
|
5345
|
+
const backTitle = (back.title || "THANK YOU").toUpperCase();
|
|
5346
|
+
const backSubtitle = back.subtitle || "";
|
|
5347
|
+
const backCompany = back.company ? replaceDocumentTokens(back.company, meta) : "";
|
|
5348
|
+
const backAddress = back.address ? replaceDocumentTokens(back.address, meta) : "";
|
|
5349
|
+
const backEmail = back.email ? replaceDocumentTokens(back.email, meta) : "";
|
|
5350
|
+
const backPhone = back.phone ? replaceDocumentTokens(back.phone, meta) : "";
|
|
5351
|
+
const backWebsite = back.website ? replaceDocumentTokens(back.website, meta) : "";
|
|
5352
|
+
const backCopyright = back.copyright ? replaceDocumentTokens(back.copyright, meta) : "";
|
|
5353
|
+
lines.push(HR_DOUBLE);
|
|
5354
|
+
lines.push(centerText(backTitle));
|
|
5355
|
+
if (backSubtitle) {
|
|
5356
|
+
lines.push(centerText(backSubtitle));
|
|
5357
|
+
}
|
|
5358
|
+
lines.push(HR_DOUBLE);
|
|
5359
|
+
if (backCompany) lines.push(`Company: ${backCompany}`);
|
|
5360
|
+
if (backAddress) lines.push(`Address: ${backAddress}`);
|
|
5361
|
+
if (backEmail) lines.push(`Email: ${backEmail}`);
|
|
5362
|
+
if (backPhone) lines.push(`Phone: ${backPhone}`);
|
|
5363
|
+
if (backWebsite) lines.push(`Website: ${backWebsite}`);
|
|
5364
|
+
if (back.social && back.social.github) {
|
|
5365
|
+
lines.push(`GitHub: ${back.social.github}`);
|
|
5366
|
+
}
|
|
5367
|
+
if (backCopyright) {
|
|
5368
|
+
lines.push("");
|
|
5369
|
+
lines.push(backCopyright);
|
|
5370
|
+
}
|
|
5371
|
+
lines.push(HR_DOUBLE);
|
|
5372
|
+
lines.push("");
|
|
5373
|
+
}
|
|
5374
|
+
return lines.join("\n").trim() + "\n";
|
|
5375
|
+
}
|
|
5376
|
+
|
|
5377
|
+
// src/core/png/pngBuilder.ts
|
|
5378
|
+
import * as fs6 from "fs";
|
|
5379
|
+
import * as path6 from "path";
|
|
5380
|
+
import * as os3 from "os";
|
|
5381
|
+
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
5382
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
5383
|
+
async function buildPngDocument(doc, config, baseDir) {
|
|
5384
|
+
const htmlContent = await buildHtmlDocument(doc, config, baseDir);
|
|
5385
|
+
const chromePath = findChromeExecutable();
|
|
5386
|
+
if (!chromePath) {
|
|
5387
|
+
throw new Error(
|
|
5388
|
+
"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."
|
|
5389
|
+
);
|
|
5390
|
+
}
|
|
5391
|
+
const tmpHtml = path6.join(
|
|
5392
|
+
os3.tmpdir(),
|
|
5393
|
+
`markforge-png-${Date.now()}-${Math.random().toString(36).slice(2)}.html`
|
|
5394
|
+
);
|
|
5395
|
+
const tmpPng = path6.join(
|
|
5396
|
+
os3.tmpdir(),
|
|
5397
|
+
`markforge-png-${Date.now()}-${Math.random().toString(36).slice(2)}.png`
|
|
5398
|
+
);
|
|
5399
|
+
try {
|
|
5400
|
+
fs6.writeFileSync(tmpHtml, htmlContent, "utf-8");
|
|
5401
|
+
const fileUrl = pathToFileURL4(tmpHtml).href;
|
|
5402
|
+
const spawnResult = spawnSync3(
|
|
5403
|
+
chromePath,
|
|
5404
|
+
[
|
|
5405
|
+
"--headless=new",
|
|
5406
|
+
"--disable-gpu",
|
|
5407
|
+
"--no-sandbox",
|
|
5408
|
+
"--disable-setuid-sandbox",
|
|
5409
|
+
"--hide-scrollbars",
|
|
5410
|
+
"--force-device-scale-factor=2",
|
|
5411
|
+
"--window-size=1200,1600",
|
|
5412
|
+
`--screenshot=${tmpPng}`,
|
|
5413
|
+
fileUrl
|
|
5414
|
+
],
|
|
5415
|
+
{ timeout: 3e4, windowsHide: true }
|
|
5416
|
+
);
|
|
5417
|
+
if (spawnResult.error) {
|
|
5418
|
+
throw new Error(`Failed to execute Chromium for PNG export: ${spawnResult.error.message}`);
|
|
5419
|
+
}
|
|
5420
|
+
if (!fs6.existsSync(tmpPng) || fs6.statSync(tmpPng).size === 0) {
|
|
5421
|
+
throw new Error("Chromium PNG export failed to generate output screenshot file.");
|
|
5422
|
+
}
|
|
5423
|
+
return fs6.readFileSync(tmpPng);
|
|
5424
|
+
} finally {
|
|
5425
|
+
try {
|
|
5426
|
+
if (fs6.existsSync(tmpHtml)) fs6.unlinkSync(tmpHtml);
|
|
5427
|
+
if (fs6.existsSync(tmpPng)) fs6.unlinkSync(tmpPng);
|
|
5428
|
+
} catch {
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
|
|
4929
5433
|
// src/core/engine.ts
|
|
4930
5434
|
function formatServerTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
4931
5435
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -4949,20 +5453,20 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
4949
5453
|
let baseDir = process.cwd();
|
|
4950
5454
|
let inputFileName = "document.md";
|
|
4951
5455
|
let isFilePath = false;
|
|
4952
|
-
if (
|
|
5456
|
+
if (fs7.existsSync(inputFilePathOrContent)) {
|
|
4953
5457
|
isFilePath = true;
|
|
4954
|
-
rawMarkdown =
|
|
4955
|
-
baseDir =
|
|
4956
|
-
inputFileName =
|
|
5458
|
+
rawMarkdown = fs7.readFileSync(inputFilePathOrContent, "utf-8");
|
|
5459
|
+
baseDir = path7.dirname(path7.resolve(inputFilePathOrContent));
|
|
5460
|
+
inputFileName = path7.basename(inputFilePathOrContent);
|
|
4957
5461
|
} else {
|
|
4958
5462
|
rawMarkdown = inputFilePathOrContent;
|
|
4959
5463
|
}
|
|
4960
5464
|
onProgress == null ? void 0 : onProgress(`Parsing markdown AST: ${inputFileName}...`);
|
|
4961
5465
|
const parsedDoc = parseMarkdownDocument(rawMarkdown);
|
|
4962
5466
|
const baseName = inputFileName.replace(/\.(md|mdx|markdown)$/i, "");
|
|
4963
|
-
const outputDir = config.outputDir ?
|
|
4964
|
-
if (!
|
|
4965
|
-
|
|
5467
|
+
const outputDir = config.outputDir ? path7.isAbsolute(config.outputDir) ? config.outputDir : path7.resolve(process.cwd(), config.outputDir) : baseDir;
|
|
5468
|
+
if (!fs7.existsSync(outputDir)) {
|
|
5469
|
+
fs7.mkdirSync(outputDir, { recursive: true });
|
|
4966
5470
|
}
|
|
4967
5471
|
const formats = Array.isArray(config.to) ? config.to : [config.to || "docx", "pdf"];
|
|
4968
5472
|
const generatedFiles = [];
|
|
@@ -4972,8 +5476,8 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
4972
5476
|
if (fmt === "docx") {
|
|
4973
5477
|
onProgress == null ? void 0 : onProgress(`Generating DOCX document: ${baseName}.docx...`);
|
|
4974
5478
|
const docxBuffer = await buildDocxDocument(parsedDoc, config, baseDir);
|
|
4975
|
-
const docxPath =
|
|
4976
|
-
|
|
5479
|
+
const docxPath = path7.join(outputDir, `${baseName}.docx`);
|
|
5480
|
+
fs7.writeFileSync(docxPath, docxBuffer);
|
|
4977
5481
|
generatedFiles.push({
|
|
4978
5482
|
format: "docx",
|
|
4979
5483
|
filePath: docxPath,
|
|
@@ -4983,8 +5487,8 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
4983
5487
|
} else if (fmt === "html") {
|
|
4984
5488
|
onProgress == null ? void 0 : onProgress(`Generating HTML document: ${baseName}.html...`);
|
|
4985
5489
|
const htmlString = await buildHtmlDocument(parsedDoc, config, baseDir);
|
|
4986
|
-
const htmlPath =
|
|
4987
|
-
|
|
5490
|
+
const htmlPath = path7.join(outputDir, `${baseName}.html`);
|
|
5491
|
+
fs7.writeFileSync(htmlPath, htmlString, "utf-8");
|
|
4988
5492
|
generatedFiles.push({
|
|
4989
5493
|
format: "html",
|
|
4990
5494
|
filePath: htmlPath,
|
|
@@ -4994,14 +5498,36 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
4994
5498
|
} else if (fmt === "pdf") {
|
|
4995
5499
|
onProgress == null ? void 0 : onProgress(`Generating PDF document: ${baseName}.pdf...`);
|
|
4996
5500
|
const pdfBuffer = await buildPdfDocument(parsedDoc, config, baseDir);
|
|
4997
|
-
const pdfPath =
|
|
4998
|
-
|
|
5501
|
+
const pdfPath = path7.join(outputDir, `${baseName}.pdf`);
|
|
5502
|
+
fs7.writeFileSync(pdfPath, pdfBuffer);
|
|
4999
5503
|
generatedFiles.push({
|
|
5000
5504
|
format: "pdf",
|
|
5001
5505
|
filePath: pdfPath,
|
|
5002
5506
|
fileName: `${baseName}.pdf`,
|
|
5003
5507
|
sizeBytes: pdfBuffer.length
|
|
5004
5508
|
});
|
|
5509
|
+
} else if (fmt === "txt") {
|
|
5510
|
+
onProgress == null ? void 0 : onProgress(`Generating Plain Text document: ${baseName}.txt...`);
|
|
5511
|
+
const textContent = await buildTextDocument(parsedDoc, config, baseDir);
|
|
5512
|
+
const textPath = path7.join(outputDir, `${baseName}.txt`);
|
|
5513
|
+
fs7.writeFileSync(textPath, textContent, "utf-8");
|
|
5514
|
+
generatedFiles.push({
|
|
5515
|
+
format: "txt",
|
|
5516
|
+
filePath: textPath,
|
|
5517
|
+
fileName: `${baseName}.txt`,
|
|
5518
|
+
sizeBytes: Buffer.byteLength(textContent, "utf-8")
|
|
5519
|
+
});
|
|
5520
|
+
} else if (fmt === "png") {
|
|
5521
|
+
onProgress == null ? void 0 : onProgress(`Generating PNG document: ${baseName}.png...`);
|
|
5522
|
+
const pngBuffer = await buildPngDocument(parsedDoc, config, baseDir);
|
|
5523
|
+
const pngPath = path7.join(outputDir, `${baseName}.png`);
|
|
5524
|
+
fs7.writeFileSync(pngPath, pngBuffer);
|
|
5525
|
+
generatedFiles.push({
|
|
5526
|
+
format: "png",
|
|
5527
|
+
filePath: pngPath,
|
|
5528
|
+
fileName: `${baseName}.png`,
|
|
5529
|
+
sizeBytes: pngBuffer.length
|
|
5530
|
+
});
|
|
5005
5531
|
}
|
|
5006
5532
|
} catch (err) {
|
|
5007
5533
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -5020,14 +5546,14 @@ async function compileMarkdown(inputFilePathOrContent, userConfig = {}, onProgre
|
|
|
5020
5546
|
|
|
5021
5547
|
// src/server/previewServer.ts
|
|
5022
5548
|
import * as http from "http";
|
|
5023
|
-
import * as
|
|
5024
|
-
import * as
|
|
5549
|
+
import * as fs8 from "fs";
|
|
5550
|
+
import * as path8 from "path";
|
|
5025
5551
|
async function startPreviewServer(options) {
|
|
5026
|
-
const absoluteFilePath =
|
|
5027
|
-
if (!
|
|
5552
|
+
const absoluteFilePath = path8.resolve(process.cwd(), options.filePath);
|
|
5553
|
+
if (!fs8.existsSync(absoluteFilePath)) {
|
|
5028
5554
|
throw new Error(`MarkForge preview error: File not found at "${absoluteFilePath}"`);
|
|
5029
5555
|
}
|
|
5030
|
-
const baseDir =
|
|
5556
|
+
const baseDir = path8.dirname(absoluteFilePath);
|
|
5031
5557
|
const { config: fileConfig } = await loadConfig(void 0, baseDir);
|
|
5032
5558
|
const baseConfig = options.config || fileConfig;
|
|
5033
5559
|
const port = options.port || 3e3;
|
|
@@ -5045,9 +5571,9 @@ data: ${Date.now()}
|
|
|
5045
5571
|
});
|
|
5046
5572
|
};
|
|
5047
5573
|
let debounceTimer = null;
|
|
5048
|
-
const watcher =
|
|
5574
|
+
const watcher = fs8.watch(baseDir, { recursive: false }, (_event, filename) => {
|
|
5049
5575
|
if (!filename) return;
|
|
5050
|
-
const changedPath =
|
|
5576
|
+
const changedPath = path8.resolve(baseDir, filename);
|
|
5051
5577
|
if (changedPath === absoluteFilePath || filename.includes("markforge") || filename.endsWith(".css")) {
|
|
5052
5578
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
5053
5579
|
debounceTimer = setTimeout(() => {
|
|
@@ -5074,12 +5600,12 @@ data: ${Date.now()}
|
|
|
5074
5600
|
}
|
|
5075
5601
|
if (url.pathname === "/api/file-content" && req.method === "GET") {
|
|
5076
5602
|
try {
|
|
5077
|
-
const content =
|
|
5603
|
+
const content = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5078
5604
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5079
5605
|
res.end(
|
|
5080
5606
|
JSON.stringify({
|
|
5081
5607
|
content,
|
|
5082
|
-
fileName:
|
|
5608
|
+
fileName: path8.basename(absoluteFilePath),
|
|
5083
5609
|
filePath: absoluteFilePath
|
|
5084
5610
|
})
|
|
5085
5611
|
);
|
|
@@ -5099,7 +5625,7 @@ data: ${Date.now()}
|
|
|
5099
5625
|
try {
|
|
5100
5626
|
const parsed = JSON.parse(body);
|
|
5101
5627
|
if (typeof parsed.content === "string") {
|
|
5102
|
-
|
|
5628
|
+
fs8.writeFileSync(absoluteFilePath, parsed.content, "utf-8");
|
|
5103
5629
|
broadcastReload();
|
|
5104
5630
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5105
5631
|
res.end(JSON.stringify({ success: true, savedAt: Date.now() }));
|
|
@@ -5118,11 +5644,11 @@ data: ${Date.now()}
|
|
|
5118
5644
|
if (url.pathname === "/api/export" && (req.method === "GET" || req.method === "POST")) {
|
|
5119
5645
|
const format = url.searchParams.get("format") || "docx";
|
|
5120
5646
|
try {
|
|
5121
|
-
const mdContent =
|
|
5647
|
+
const mdContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5122
5648
|
const doc = parseMarkdownDocument(mdContent);
|
|
5123
5649
|
const { config: resolvedConfig } = await loadConfig(void 0, baseDir);
|
|
5124
5650
|
const mergedConfig = { ...baseConfig, ...resolvedConfig };
|
|
5125
|
-
const fileBase =
|
|
5651
|
+
const fileBase = path8.basename(absoluteFilePath, path8.extname(absoluteFilePath));
|
|
5126
5652
|
if (format === "docx") {
|
|
5127
5653
|
const buffer = await buildDocxDocument(doc, mergedConfig, baseDir);
|
|
5128
5654
|
res.writeHead(200, {
|
|
@@ -5157,7 +5683,7 @@ data: ${Date.now()}
|
|
|
5157
5683
|
}
|
|
5158
5684
|
if (url.pathname === "/document-content") {
|
|
5159
5685
|
try {
|
|
5160
|
-
const mdContent =
|
|
5686
|
+
const mdContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5161
5687
|
const doc = parseMarkdownDocument(mdContent);
|
|
5162
5688
|
const { config: resolvedConfig } = await loadConfig(void 0, baseDir);
|
|
5163
5689
|
const html = await buildHtmlDocument(doc, { ...baseConfig, ...resolvedConfig }, baseDir);
|
|
@@ -5190,8 +5716,8 @@ data: ${Date.now()}
|
|
|
5190
5716
|
return;
|
|
5191
5717
|
}
|
|
5192
5718
|
if (url.pathname === "/" || url.pathname === "/index.html") {
|
|
5193
|
-
const fileName =
|
|
5194
|
-
const initialContent =
|
|
5719
|
+
const fileName = path8.basename(absoluteFilePath);
|
|
5720
|
+
const initialContent = fs8.readFileSync(absoluteFilePath, "utf-8");
|
|
5195
5721
|
const appHtml = `<!DOCTYPE html>
|
|
5196
5722
|
<html lang="en">
|
|
5197
5723
|
<head>
|
|
@@ -5895,9 +6421,9 @@ function defineConfig(config) {
|
|
|
5895
6421
|
}
|
|
5896
6422
|
|
|
5897
6423
|
// src/version.ts
|
|
5898
|
-
import * as
|
|
5899
|
-
import * as
|
|
5900
|
-
import { fileURLToPath } from "url";
|
|
6424
|
+
import * as fs9 from "fs";
|
|
6425
|
+
import * as path9 from "path";
|
|
6426
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5901
6427
|
try {
|
|
5902
6428
|
if (typeof globalThis !== "undefined" && (!globalThis.localStorage || typeof globalThis.localStorage.getItem !== "function")) {
|
|
5903
6429
|
Object.defineProperty(globalThis, "localStorage", {
|
|
@@ -5922,16 +6448,16 @@ function readVersionFromPackageJson(fromDir) {
|
|
|
5922
6448
|
let currentDir = fromDir;
|
|
5923
6449
|
for (let i = 0; i < 10; i++) {
|
|
5924
6450
|
try {
|
|
5925
|
-
const pkgJsonPath =
|
|
5926
|
-
if (
|
|
5927
|
-
const pkg = JSON.parse(
|
|
6451
|
+
const pkgJsonPath = path9.join(currentDir, "package.json");
|
|
6452
|
+
if (fs9.existsSync(pkgJsonPath)) {
|
|
6453
|
+
const pkg = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5928
6454
|
if (pkg.name === "@masumdev/markforge" && pkg.version) {
|
|
5929
6455
|
return pkg.version;
|
|
5930
6456
|
}
|
|
5931
6457
|
}
|
|
5932
6458
|
} catch {
|
|
5933
6459
|
}
|
|
5934
|
-
const parentDir =
|
|
6460
|
+
const parentDir = path9.dirname(currentDir);
|
|
5935
6461
|
if (parentDir === currentDir) break;
|
|
5936
6462
|
currentDir = parentDir;
|
|
5937
6463
|
}
|
|
@@ -5944,7 +6470,7 @@ function getPackageDir() {
|
|
|
5944
6470
|
return __dirname;
|
|
5945
6471
|
}
|
|
5946
6472
|
try {
|
|
5947
|
-
return
|
|
6473
|
+
return path9.dirname(fileURLToPath2(import.meta.url));
|
|
5948
6474
|
} catch {
|
|
5949
6475
|
return process.cwd();
|
|
5950
6476
|
}
|
|
@@ -5954,6 +6480,8 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
5954
6480
|
return readVersionFromPackageJson(fromDir);
|
|
5955
6481
|
}
|
|
5956
6482
|
export {
|
|
6483
|
+
BackCoverPreset,
|
|
6484
|
+
CoverPagePreset,
|
|
5957
6485
|
DEFAULT_CONFIG,
|
|
5958
6486
|
KATEX_INLINE_CSS,
|
|
5959
6487
|
MARKFORGE_VERSION,
|
|
@@ -5962,6 +6490,8 @@ export {
|
|
|
5962
6490
|
PAPER_DIMENSIONS_TWIP,
|
|
5963
6491
|
PaperSizeEnum,
|
|
5964
6492
|
SYNTAX_COLORS,
|
|
6493
|
+
SignatureAlign,
|
|
6494
|
+
SignatureStyle,
|
|
5965
6495
|
SyntaxTheme,
|
|
5966
6496
|
THEMES,
|
|
5967
6497
|
THEME_CORPORATE,
|
|
@@ -5972,6 +6502,9 @@ export {
|
|
|
5972
6502
|
buildDocxDocument,
|
|
5973
6503
|
buildHtmlDocument,
|
|
5974
6504
|
buildPdfDocument,
|
|
6505
|
+
buildPngDocument,
|
|
6506
|
+
buildTextDocument,
|
|
6507
|
+
buildTextDocument as buildTxtDocument,
|
|
5975
6508
|
compileMarkdown,
|
|
5976
6509
|
defineConfig,
|
|
5977
6510
|
escapeHtml,
|
|
@@ -6000,6 +6533,7 @@ export {
|
|
|
6000
6533
|
renderBackCoverHtml,
|
|
6001
6534
|
renderCoverPageHtml,
|
|
6002
6535
|
renderInlinesToHtml,
|
|
6536
|
+
renderInlinesToText,
|
|
6003
6537
|
renderMathToHtml,
|
|
6004
6538
|
renderMermaidToPng,
|
|
6005
6539
|
renderNodesToHtml,
|