@masumdev/markforge 0.2.4 → 0.3.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 +229 -298
- package/dist/{App-IJVCGBJM.mjs → App-AM2CWXHJ.mjs} +1413 -378
- package/dist/{chunk-NGC2ZAWZ.mjs → chunk-HKB4CSPZ.mjs} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/index.d.mts +409 -59
- package/dist/index.d.ts +409 -59
- package/dist/index.js +1533 -479
- package/dist/index.mjs +1520 -480
- package/package.json +1 -1
- package/schema.json +198 -36
package/dist/index.js
CHANGED
|
@@ -40,10 +40,17 @@ var src_exports = {};
|
|
|
40
40
|
__export(src_exports, {
|
|
41
41
|
DEFAULT_CONFIG: () => DEFAULT_CONFIG,
|
|
42
42
|
MARKFORGE_VERSION: () => MARKFORGE_VERSION,
|
|
43
|
+
Orientation: () => Orientation,
|
|
44
|
+
OutputFormat: () => OutputFormat,
|
|
45
|
+
PAPER_DIMENSIONS_TWIP: () => PAPER_DIMENSIONS_TWIP,
|
|
46
|
+
PaperSizeEnum: () => PaperSizeEnum,
|
|
43
47
|
SYNTAX_COLORS: () => SYNTAX_COLORS,
|
|
48
|
+
SyntaxTheme: () => SyntaxTheme,
|
|
44
49
|
THEMES: () => THEMES,
|
|
45
|
-
|
|
50
|
+
THEME_CORPORATE: () => THEME_CORPORATE,
|
|
46
51
|
THEME_DEFAULT: () => THEME_DEFAULT,
|
|
52
|
+
Theme: () => Theme,
|
|
53
|
+
WatermarkPosition: () => WatermarkPosition,
|
|
47
54
|
buildDocxDocument: () => buildDocxDocument,
|
|
48
55
|
buildHtmlDocument: () => buildHtmlDocument,
|
|
49
56
|
buildPdfDocument: () => buildPdfDocument,
|
|
@@ -52,6 +59,7 @@ __export(src_exports, {
|
|
|
52
59
|
escapeHtml: () => escapeHtml,
|
|
53
60
|
findChromeExecutable: () => findChromeExecutable,
|
|
54
61
|
formatServerTimestamp: () => formatServerTimestamp,
|
|
62
|
+
generateThemeCss: () => generateThemeCss,
|
|
55
63
|
getMarkforgeVersion: () => getMarkforgeVersion,
|
|
56
64
|
getMimeType: () => getMimeType,
|
|
57
65
|
highlightCodeToHtml: () => highlightCodeToHtml,
|
|
@@ -59,11 +67,17 @@ __export(src_exports, {
|
|
|
59
67
|
inlineHtmlImages: () => inlineHtmlImages,
|
|
60
68
|
loadConfig: () => loadConfig,
|
|
61
69
|
markforge: () => compileMarkdown,
|
|
70
|
+
normalizeHeaderFooter: () => normalizeHeaderFooter,
|
|
71
|
+
normalizeHeaderFooterSlot: () => normalizeHeaderFooterSlot,
|
|
72
|
+
normalizeSignatures: () => normalizeSignatures,
|
|
73
|
+
normalizeWatermark: () => normalizeWatermark,
|
|
62
74
|
parseInlineSpans: () => parseInlineSpans,
|
|
63
|
-
parseMarginToTwip: () =>
|
|
75
|
+
parseMarginToTwip: () => parseMarginToTwip2,
|
|
64
76
|
parseMarkdownDocument: () => parseMarkdownDocument,
|
|
65
77
|
renderInlinesToHtml: () => renderInlinesToHtml,
|
|
66
78
|
renderMermaidToPng: () => renderMermaidToPng,
|
|
79
|
+
replaceDocumentTokens: () => replaceDocumentTokens,
|
|
80
|
+
resolveDocumentConfig: () => resolveDocumentConfig,
|
|
67
81
|
resolveImage: () => resolveImage,
|
|
68
82
|
slugify: () => slugify,
|
|
69
83
|
tokenizeCodeLine: () => tokenizeCodeLine
|
|
@@ -585,6 +599,51 @@ var SYNTAX_COLORS_LIGHT = {
|
|
|
585
599
|
plain: "24292E"
|
|
586
600
|
// Near-black — identifiers
|
|
587
601
|
};
|
|
602
|
+
var SYNTAX_THEMES = {
|
|
603
|
+
"github-dark": SYNTAX_COLORS,
|
|
604
|
+
"dark": SYNTAX_COLORS,
|
|
605
|
+
"github-light": SYNTAX_COLORS_LIGHT,
|
|
606
|
+
"light": SYNTAX_COLORS_LIGHT,
|
|
607
|
+
"dracula": {
|
|
608
|
+
keyword: "FF79C6",
|
|
609
|
+
string: "F1FA8C",
|
|
610
|
+
comment: "6272A4",
|
|
611
|
+
number: "BD93F9",
|
|
612
|
+
boolean: "BD93F9",
|
|
613
|
+
function: "50FA7B",
|
|
614
|
+
type: "8BE9FD",
|
|
615
|
+
operator: "FF79C6",
|
|
616
|
+
punctuation: "F8F8F2",
|
|
617
|
+
plain: "F8F8F2"
|
|
618
|
+
},
|
|
619
|
+
"monokai": {
|
|
620
|
+
keyword: "F92672",
|
|
621
|
+
string: "E6DB74",
|
|
622
|
+
comment: "75715E",
|
|
623
|
+
number: "AE81FF",
|
|
624
|
+
boolean: "AE81FF",
|
|
625
|
+
function: "A6E22E",
|
|
626
|
+
type: "66D9EF",
|
|
627
|
+
operator: "F92672",
|
|
628
|
+
punctuation: "F8F8F2",
|
|
629
|
+
plain: "F8F8F2"
|
|
630
|
+
},
|
|
631
|
+
"nord": {
|
|
632
|
+
keyword: "81A1C1",
|
|
633
|
+
string: "A3BE8C",
|
|
634
|
+
comment: "616E88",
|
|
635
|
+
number: "B48EAD",
|
|
636
|
+
boolean: "81A1C1",
|
|
637
|
+
function: "88C0D0",
|
|
638
|
+
type: "8FBCBB",
|
|
639
|
+
operator: "81A1C1",
|
|
640
|
+
punctuation: "ECEFF4",
|
|
641
|
+
plain: "D8DEE9"
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
function getSyntaxPalette(themeName = "github-dark") {
|
|
645
|
+
return SYNTAX_THEMES[themeName.toLowerCase()] || SYNTAX_THEMES["github-dark"];
|
|
646
|
+
}
|
|
588
647
|
var JS_KEYWORDS = /* @__PURE__ */ new Set([
|
|
589
648
|
"import",
|
|
590
649
|
"from",
|
|
@@ -728,9 +787,9 @@ var SQL_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
728
787
|
"foreign",
|
|
729
788
|
"references"
|
|
730
789
|
]);
|
|
731
|
-
function tokenizeCodeLine(line, lang = "", theme = "dark") {
|
|
790
|
+
function tokenizeCodeLine(line, lang = "", theme = "github-dark") {
|
|
732
791
|
var _a;
|
|
733
|
-
const COLORS = theme
|
|
792
|
+
const COLORS = getSyntaxPalette(theme);
|
|
734
793
|
if (!line) {
|
|
735
794
|
return [{ text: " ", type: "plain", colorHex: COLORS.plain }];
|
|
736
795
|
}
|
|
@@ -813,6 +872,10 @@ function tokenizeCodeLine(line, lang = "", theme = "dark") {
|
|
|
813
872
|
tokens.push({ text: word, type: "keyword", colorHex: COLORS.keyword, bold: true });
|
|
814
873
|
continue;
|
|
815
874
|
}
|
|
875
|
+
if (/^[A-Z][a-zA-Z0-9_$]*$/.test(word)) {
|
|
876
|
+
tokens.push({ text: word, type: "type", colorHex: COLORS.type });
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
816
879
|
let nextNonWs = pos;
|
|
817
880
|
while (nextNonWs < line.length && /\s/.test(line[nextNonWs])) {
|
|
818
881
|
nextNonWs++;
|
|
@@ -821,10 +884,6 @@ function tokenizeCodeLine(line, lang = "", theme = "dark") {
|
|
|
821
884
|
tokens.push({ text: word, type: "function", colorHex: COLORS.function });
|
|
822
885
|
continue;
|
|
823
886
|
}
|
|
824
|
-
if (/^[A-Z][a-zA-Z0-9_$]*$/.test(word)) {
|
|
825
|
-
tokens.push({ text: word, type: "type", colorHex: COLORS.type });
|
|
826
|
-
continue;
|
|
827
|
-
}
|
|
828
887
|
tokens.push({ text: word, type: "plain", colorHex: COLORS.plain });
|
|
829
888
|
continue;
|
|
830
889
|
}
|
|
@@ -837,10 +896,10 @@ function tokenizeCodeLine(line, lang = "", theme = "dark") {
|
|
|
837
896
|
}
|
|
838
897
|
return tokens;
|
|
839
898
|
}
|
|
840
|
-
function highlightCodeToHtml(code, lang = "") {
|
|
899
|
+
function highlightCodeToHtml(code, lang = "", theme = "github-dark") {
|
|
841
900
|
const lines = (code || "").split("\n");
|
|
842
901
|
const htmlLines = lines.map((line) => {
|
|
843
|
-
const tokens = tokenizeCodeLine(line, lang);
|
|
902
|
+
const tokens = tokenizeCodeLine(line, lang, theme);
|
|
844
903
|
return tokens.map((t) => {
|
|
845
904
|
const escaped = t.text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
846
905
|
if (t.type === "plain") return escaped;
|
|
@@ -852,21 +911,62 @@ function highlightCodeToHtml(code, lang = "") {
|
|
|
852
911
|
|
|
853
912
|
// src/core/mermaid/mermaidRenderer.ts
|
|
854
913
|
var import_node_child_process2 = require("child_process");
|
|
855
|
-
var
|
|
914
|
+
var fs5 = __toESM(require("fs"));
|
|
856
915
|
var os2 = __toESM(require("os"));
|
|
857
|
-
var
|
|
858
|
-
var
|
|
916
|
+
var path5 = __toESM(require("path"));
|
|
917
|
+
var import_node_url3 = require("url");
|
|
859
918
|
|
|
860
919
|
// src/core/pdf/pdfBuilder.ts
|
|
861
|
-
var
|
|
862
|
-
var
|
|
920
|
+
var fs4 = __toESM(require("fs"));
|
|
921
|
+
var path4 = __toESM(require("path"));
|
|
863
922
|
var os = __toESM(require("os"));
|
|
864
|
-
var
|
|
923
|
+
var import_node_url2 = require("url");
|
|
865
924
|
var import_node_child_process = require("child_process");
|
|
866
925
|
|
|
867
926
|
// src/core/html/htmlBuilder.ts
|
|
868
|
-
var
|
|
869
|
-
var
|
|
927
|
+
var fs3 = __toESM(require("fs"));
|
|
928
|
+
var path3 = __toESM(require("path"));
|
|
929
|
+
|
|
930
|
+
// src/config/types.ts
|
|
931
|
+
var OutputFormat = /* @__PURE__ */ ((OutputFormat2) => {
|
|
932
|
+
OutputFormat2["DOCX"] = "docx";
|
|
933
|
+
OutputFormat2["PDF"] = "pdf";
|
|
934
|
+
OutputFormat2["HTML"] = "html";
|
|
935
|
+
OutputFormat2["PNG"] = "png";
|
|
936
|
+
return OutputFormat2;
|
|
937
|
+
})(OutputFormat || {});
|
|
938
|
+
var Theme = /* @__PURE__ */ ((Theme2) => {
|
|
939
|
+
Theme2["CORPORATE"] = "corporate";
|
|
940
|
+
return Theme2;
|
|
941
|
+
})(Theme || {});
|
|
942
|
+
var Orientation = /* @__PURE__ */ ((Orientation2) => {
|
|
943
|
+
Orientation2["PORTRAIT"] = "portrait";
|
|
944
|
+
Orientation2["LANDSCAPE"] = "landscape";
|
|
945
|
+
return Orientation2;
|
|
946
|
+
})(Orientation || {});
|
|
947
|
+
var PaperSizeEnum = /* @__PURE__ */ ((PaperSizeEnum2) => {
|
|
948
|
+
PaperSizeEnum2["A4"] = "A4";
|
|
949
|
+
PaperSizeEnum2["LETTER"] = "Letter";
|
|
950
|
+
PaperSizeEnum2["LEGAL"] = "Legal";
|
|
951
|
+
PaperSizeEnum2["A3"] = "A3";
|
|
952
|
+
PaperSizeEnum2["A5"] = "A5";
|
|
953
|
+
return PaperSizeEnum2;
|
|
954
|
+
})(PaperSizeEnum || {});
|
|
955
|
+
var SyntaxTheme = /* @__PURE__ */ ((SyntaxTheme2) => {
|
|
956
|
+
SyntaxTheme2["GITHUB_DARK"] = "github-dark";
|
|
957
|
+
SyntaxTheme2["GITHUB_LIGHT"] = "github-light";
|
|
958
|
+
SyntaxTheme2["DRACULA"] = "dracula";
|
|
959
|
+
SyntaxTheme2["MONOKAI"] = "monokai";
|
|
960
|
+
SyntaxTheme2["NORD"] = "nord";
|
|
961
|
+
return SyntaxTheme2;
|
|
962
|
+
})(SyntaxTheme || {});
|
|
963
|
+
var WatermarkPosition = /* @__PURE__ */ ((WatermarkPosition2) => {
|
|
964
|
+
WatermarkPosition2["DIAGONAL"] = "diagonal";
|
|
965
|
+
WatermarkPosition2["CENTER"] = "center";
|
|
966
|
+
WatermarkPosition2["TOP_RIGHT"] = "top-right";
|
|
967
|
+
WatermarkPosition2["BOTTOM_RIGHT"] = "bottom-right";
|
|
968
|
+
return WatermarkPosition2;
|
|
969
|
+
})(WatermarkPosition || {});
|
|
870
970
|
|
|
871
971
|
// src/core/html/htmlThemes.ts
|
|
872
972
|
var THEME_COMPONENTS = `
|
|
@@ -949,7 +1049,7 @@ hr { border: none; border-top: 1px solid var(--mf-border); margin: 2rem 0; }
|
|
|
949
1049
|
pre { overflow: visible; white-space: pre-wrap; word-break: break-all; }
|
|
950
1050
|
}
|
|
951
1051
|
`;
|
|
952
|
-
var
|
|
1052
|
+
var THEME_CORPORATE = `
|
|
953
1053
|
:root {
|
|
954
1054
|
--mf-bg: #ffffff;
|
|
955
1055
|
--mf-text: #0f172a;
|
|
@@ -961,49 +1061,479 @@ var THEME_DEFAULT = `
|
|
|
961
1061
|
--mf-card-bg: #f8fafc;
|
|
962
1062
|
--mf-code-bg: #0f172a;
|
|
963
1063
|
--mf-code-text: #f8fafc;
|
|
964
|
-
--mf-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
1064
|
+
--mf-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
965
1065
|
--mf-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
966
1066
|
}
|
|
967
1067
|
body { background-color: var(--mf-bg); color: var(--mf-text); font-family: var(--mf-font-family); font-size: 15px; line-height: 1.65; margin: 0; padding: 2.5rem; }
|
|
968
|
-
.document-container { max-width: 860px; margin: 0 auto; }
|
|
1068
|
+
.document-container { max-width: 860px; margin: 0 auto; position: relative; z-index: 1; }
|
|
969
1069
|
h1, h2, h3, h4, h5, h6 { color: var(--mf-text); font-weight: 700; margin-top: 1.8rem; margin-bottom: 0.8rem; line-height: 1.25; }
|
|
970
|
-
h1 { font-size: 2.2rem; border-bottom: 2px solid
|
|
971
|
-
h2 { font-size: 1.6rem; color:
|
|
1070
|
+
h1 { font-size: 2.2rem; border-bottom: 2px solid var(--mf-primary); padding-bottom: 0.5rem; }
|
|
1071
|
+
h2 { font-size: 1.6rem; color: var(--mf-primary-dark); border-bottom: 1px solid #CCFBF1; padding-bottom: 0.4rem; }
|
|
972
1072
|
h3 { font-size: 1.3rem; }
|
|
973
1073
|
h4 { font-size: 1.1rem; }
|
|
974
1074
|
p { margin: 0.8rem 0; }
|
|
975
1075
|
`;
|
|
976
|
-
var
|
|
1076
|
+
var THEME_DEFAULT = THEME_CORPORATE;
|
|
1077
|
+
var THEMES = {
|
|
1078
|
+
corporate: THEME_CORPORATE,
|
|
1079
|
+
default: THEME_CORPORATE
|
|
1080
|
+
};
|
|
1081
|
+
function generateThemeCss(theme) {
|
|
1082
|
+
if (!theme || theme === "corporate" || theme === "default" || theme === "corporate" /* CORPORATE */) {
|
|
1083
|
+
return THEME_CORPORATE;
|
|
1084
|
+
}
|
|
1085
|
+
if (typeof theme === "object") {
|
|
1086
|
+
const bg = theme.backgroundColor || "#ffffff";
|
|
1087
|
+
const text = theme.textColor || "#0f172a";
|
|
1088
|
+
const textMuted = theme.textMuted || "#64748b";
|
|
1089
|
+
const primary = theme.primaryColor || "#33CDCF";
|
|
1090
|
+
const primaryDark = theme.primaryDark || primary;
|
|
1091
|
+
const primaryLight = theme.primaryLight || "#ECFDFD";
|
|
1092
|
+
const border = theme.borderColor || "#e2e8f0";
|
|
1093
|
+
const cardBg = theme.cardBackground || "#f8fafc";
|
|
1094
|
+
const codeBg = theme.codeBackground || "#0f172a";
|
|
1095
|
+
const codeText = theme.codeText || "#f8fafc";
|
|
1096
|
+
const font = theme.fontFamily || "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
1097
|
+
const fontMono = theme.fontMono || "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
|
|
1098
|
+
return `
|
|
977
1099
|
:root {
|
|
978
|
-
--mf-bg:
|
|
979
|
-
--mf-text:
|
|
980
|
-
--mf-text-muted:
|
|
981
|
-
--mf-primary:
|
|
982
|
-
--mf-primary-dark:
|
|
983
|
-
--mf-primary-light:
|
|
984
|
-
--mf-border:
|
|
985
|
-
--mf-card-bg:
|
|
986
|
-
--mf-code-bg:
|
|
987
|
-
--mf-code-text:
|
|
988
|
-
--mf-font-family:
|
|
989
|
-
--mf-font-mono:
|
|
1100
|
+
--mf-bg: ${bg};
|
|
1101
|
+
--mf-text: ${text};
|
|
1102
|
+
--mf-text-muted: ${textMuted};
|
|
1103
|
+
--mf-primary: ${primary};
|
|
1104
|
+
--mf-primary-dark: ${primaryDark};
|
|
1105
|
+
--mf-primary-light: ${primaryLight};
|
|
1106
|
+
--mf-border: ${border};
|
|
1107
|
+
--mf-card-bg: ${cardBg};
|
|
1108
|
+
--mf-code-bg: ${codeBg};
|
|
1109
|
+
--mf-code-text: ${codeText};
|
|
1110
|
+
--mf-font-family: ${font};
|
|
1111
|
+
--mf-font-mono: ${fontMono};
|
|
990
1112
|
}
|
|
991
|
-
body { font-family: var(--mf-font-family); font-size:
|
|
992
|
-
.document-container { max-width:
|
|
993
|
-
h1, h2, h3 { font-
|
|
994
|
-
h1 { font-size: 2rem; border-bottom:
|
|
995
|
-
h2 { font-size: 1.
|
|
996
|
-
h3 { font-size: 1.
|
|
997
|
-
|
|
1113
|
+
body { background-color: var(--mf-bg); color: var(--mf-text); font-family: var(--mf-font-family); font-size: 15px; line-height: 1.65; margin: 0; padding: 2.5rem; }
|
|
1114
|
+
.document-container { max-width: 860px; margin: 0 auto; position: relative; z-index: 1; }
|
|
1115
|
+
h1, h2, h3, h4, h5, h6 { color: var(--mf-text); font-weight: 700; margin-top: 1.8rem; margin-bottom: 0.8rem; line-height: 1.25; }
|
|
1116
|
+
h1 { font-size: 2.2rem; border-bottom: 2px solid var(--mf-primary); padding-bottom: 0.5rem; }
|
|
1117
|
+
h2 { font-size: 1.6rem; color: var(--mf-primary-dark); border-bottom: 1px solid var(--mf-border); padding-bottom: 0.4rem; }
|
|
1118
|
+
h3 { font-size: 1.3rem; }
|
|
1119
|
+
h4 { font-size: 1.1rem; }
|
|
1120
|
+
p { margin: 0.8rem 0; }
|
|
1121
|
+
${theme.customCss || ""}
|
|
998
1122
|
`;
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1123
|
+
}
|
|
1124
|
+
if (typeof theme === "string" && THEMES[theme]) {
|
|
1125
|
+
return THEMES[theme];
|
|
1126
|
+
}
|
|
1127
|
+
return THEME_CORPORATE;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
// src/config/loadConfig.ts
|
|
1131
|
+
var fs2 = __toESM(require("fs"));
|
|
1132
|
+
var path2 = __toESM(require("path"));
|
|
1133
|
+
var import_node_url = require("url");
|
|
1134
|
+
var YAML = __toESM(require("yaml"));
|
|
1135
|
+
var DEFAULT_CONFIG_FILENAMES = [
|
|
1136
|
+
"markforge.config.json",
|
|
1137
|
+
".markforgerc.json",
|
|
1138
|
+
"markforge.config.yaml",
|
|
1139
|
+
"markforge.config.yml",
|
|
1140
|
+
".markforgerc.yaml",
|
|
1141
|
+
".markforgerc.yml",
|
|
1142
|
+
".markforgerc",
|
|
1143
|
+
"markforge.config.ts",
|
|
1144
|
+
"markforge.config.js",
|
|
1145
|
+
"markforge.config.mjs",
|
|
1146
|
+
"markforge.config.cjs"
|
|
1147
|
+
];
|
|
1148
|
+
var DEFAULT_CONFIG = {
|
|
1149
|
+
to: ["docx", "pdf"],
|
|
1150
|
+
outputDir: void 0,
|
|
1151
|
+
theme: "default",
|
|
1152
|
+
css: void 0,
|
|
1153
|
+
orientation: "portrait",
|
|
1154
|
+
paperSize: "A4",
|
|
1155
|
+
margins: {
|
|
1156
|
+
top: "2.5cm",
|
|
1157
|
+
bottom: "2.5cm",
|
|
1158
|
+
left: "2.5cm",
|
|
1159
|
+
right: "2.5cm"
|
|
1160
|
+
},
|
|
1161
|
+
header: void 0,
|
|
1162
|
+
footer: {
|
|
1163
|
+
right: "Page {page} of {pages}"
|
|
1164
|
+
},
|
|
1165
|
+
toc: false,
|
|
1166
|
+
watermark: void 0,
|
|
1167
|
+
embedImages: true,
|
|
1168
|
+
metadata: void 0,
|
|
1169
|
+
watch: false,
|
|
1170
|
+
serve: false,
|
|
1171
|
+
port: 4e3,
|
|
1172
|
+
open: false,
|
|
1173
|
+
bundleHtml: true,
|
|
1174
|
+
syntaxTheme: "github-dark"
|
|
1175
|
+
};
|
|
1176
|
+
function discoverConfigFile(startDir) {
|
|
1177
|
+
const dirsToCheck = [];
|
|
1178
|
+
let curr = path2.resolve(startDir);
|
|
1179
|
+
while (curr) {
|
|
1180
|
+
dirsToCheck.push(curr);
|
|
1181
|
+
const parent = path2.dirname(curr);
|
|
1182
|
+
if (parent === curr) break;
|
|
1183
|
+
curr = parent;
|
|
1184
|
+
}
|
|
1185
|
+
const cwd = path2.resolve(process.cwd());
|
|
1186
|
+
if (!dirsToCheck.includes(cwd)) {
|
|
1187
|
+
dirsToCheck.push(cwd);
|
|
1188
|
+
}
|
|
1189
|
+
for (const dir of dirsToCheck) {
|
|
1190
|
+
for (const filename of DEFAULT_CONFIG_FILENAMES) {
|
|
1191
|
+
const candidate = path2.join(dir, filename);
|
|
1192
|
+
if (fs2.existsSync(candidate) && fs2.statSync(candidate).isFile()) {
|
|
1193
|
+
return candidate;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return null;
|
|
1198
|
+
}
|
|
1199
|
+
async function loadConfig(customPath, startDir = process.cwd()) {
|
|
1200
|
+
let resolvedPath = null;
|
|
1201
|
+
if (customPath) {
|
|
1202
|
+
resolvedPath = path2.isAbsolute(customPath) ? customPath : path2.resolve(process.cwd(), customPath);
|
|
1203
|
+
if (!fs2.existsSync(resolvedPath)) {
|
|
1204
|
+
const altPath = path2.resolve(startDir, customPath);
|
|
1205
|
+
if (fs2.existsSync(altPath)) {
|
|
1206
|
+
resolvedPath = altPath;
|
|
1207
|
+
} else {
|
|
1208
|
+
throw new Error(`Configuration file not found: ${resolvedPath}`);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
} else {
|
|
1212
|
+
resolvedPath = discoverConfigFile(startDir);
|
|
1213
|
+
}
|
|
1214
|
+
if (!resolvedPath) {
|
|
1215
|
+
return {
|
|
1216
|
+
config: { ...DEFAULT_CONFIG },
|
|
1217
|
+
configPath: null
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
const ext = path2.extname(resolvedPath).toLowerCase();
|
|
1221
|
+
let userConfig = {};
|
|
1222
|
+
try {
|
|
1223
|
+
if (ext === ".json" || ext === "" || resolvedPath.endsWith(".markforgerc")) {
|
|
1224
|
+
const raw = fs2.readFileSync(resolvedPath, "utf-8").trim();
|
|
1225
|
+
try {
|
|
1226
|
+
userConfig = JSON.parse(raw);
|
|
1227
|
+
} catch {
|
|
1228
|
+
userConfig = YAML.parse(raw) || {};
|
|
1229
|
+
}
|
|
1230
|
+
} else if (ext === ".yaml" || ext === ".yml") {
|
|
1231
|
+
const raw = fs2.readFileSync(resolvedPath, "utf-8");
|
|
1232
|
+
userConfig = YAML.parse(raw) || {};
|
|
1233
|
+
} else if (ext === ".ts" || ext === ".js" || ext === ".mjs" || ext === ".cjs") {
|
|
1234
|
+
try {
|
|
1235
|
+
const fileUrl = `${(0, import_node_url.pathToFileURL)(resolvedPath).href}?t=${Date.now()}`;
|
|
1236
|
+
const mod = await import(fileUrl);
|
|
1237
|
+
const rawExport = mod.default ?? mod.config ?? mod;
|
|
1238
|
+
userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
|
|
1239
|
+
} catch (importErr) {
|
|
1240
|
+
try {
|
|
1241
|
+
const mod = require(resolvedPath);
|
|
1242
|
+
const rawExport = mod.default ?? mod.config ?? mod;
|
|
1243
|
+
userConfig = (typeof rawExport === "function" ? await rawExport() : rawExport) || {};
|
|
1244
|
+
} catch {
|
|
1245
|
+
throw importErr;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
} catch (err) {
|
|
1250
|
+
throw new Error(
|
|
1251
|
+
`Failed to parse configuration file at ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
if (userConfig && typeof userConfig === "object" && "$schema" in userConfig) {
|
|
1255
|
+
delete userConfig.$schema;
|
|
1256
|
+
}
|
|
1257
|
+
const parsedConfig = userConfig;
|
|
1258
|
+
const mergedConfig = {
|
|
1259
|
+
...DEFAULT_CONFIG,
|
|
1260
|
+
...parsedConfig,
|
|
1261
|
+
margins: {
|
|
1262
|
+
...DEFAULT_CONFIG.margins,
|
|
1263
|
+
...parsedConfig.margins || {}
|
|
1264
|
+
},
|
|
1265
|
+
header: parsedConfig.header !== void 0 ? parsedConfig.header : DEFAULT_CONFIG.header,
|
|
1266
|
+
footer: parsedConfig.footer !== void 0 ? parsedConfig.footer : DEFAULT_CONFIG.footer,
|
|
1267
|
+
metadata: {
|
|
1268
|
+
...DEFAULT_CONFIG.metadata || {},
|
|
1269
|
+
...parsedConfig.metadata || {}
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
return {
|
|
1273
|
+
config: mergedConfig,
|
|
1274
|
+
configPath: resolvedPath
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// src/config/resolveConfig.ts
|
|
1279
|
+
var PAPER_DIMENSIONS_TWIP = {
|
|
1280
|
+
A4: { width: 11906, height: 16838 },
|
|
1281
|
+
// 210mm x 297mm
|
|
1282
|
+
Letter: { width: 12240, height: 15840 },
|
|
1283
|
+
// 8.5in x 11in
|
|
1284
|
+
Legal: { width: 12240, height: 20160 },
|
|
1285
|
+
// 8.5in x 14in
|
|
1286
|
+
A3: { width: 16838, height: 23811 },
|
|
1287
|
+
// 297mm x 420mm
|
|
1288
|
+
A5: { width: 8390, height: 11906 }
|
|
1289
|
+
// 148mm x 210mm
|
|
1006
1290
|
};
|
|
1291
|
+
function parseMarginToTwip(margin, defaultTwip = 1440) {
|
|
1292
|
+
if (typeof margin === "number") return margin;
|
|
1293
|
+
if (!margin) return defaultTwip;
|
|
1294
|
+
const str = margin.trim().toLowerCase();
|
|
1295
|
+
if (str.endsWith("cm")) {
|
|
1296
|
+
const cm = parseFloat(str);
|
|
1297
|
+
return isNaN(cm) ? defaultTwip : Math.round(cm * 566.929);
|
|
1298
|
+
}
|
|
1299
|
+
if (str.endsWith("mm")) {
|
|
1300
|
+
const mm = parseFloat(str);
|
|
1301
|
+
return isNaN(mm) ? defaultTwip : Math.round(mm * 56.6929);
|
|
1302
|
+
}
|
|
1303
|
+
if (str.endsWith("in") || str.endsWith("inch")) {
|
|
1304
|
+
const inch = parseFloat(str);
|
|
1305
|
+
return isNaN(inch) ? defaultTwip : Math.round(inch * 1440);
|
|
1306
|
+
}
|
|
1307
|
+
if (str.endsWith("pt")) {
|
|
1308
|
+
const pt = parseFloat(str);
|
|
1309
|
+
return isNaN(pt) ? defaultTwip : Math.round(pt * 20);
|
|
1310
|
+
}
|
|
1311
|
+
const val = parseFloat(str);
|
|
1312
|
+
return isNaN(val) ? defaultTwip : Math.round(val);
|
|
1313
|
+
}
|
|
1314
|
+
function formatMarginCss(margin, defaultCss = "2.5cm") {
|
|
1315
|
+
if (margin === void 0 || margin === null) return defaultCss;
|
|
1316
|
+
if (typeof margin === "number") return `${margin}pt`;
|
|
1317
|
+
const str = margin.trim();
|
|
1318
|
+
if (!str) return defaultCss;
|
|
1319
|
+
if (/^[0-9.]+$/.test(str)) return `${str}pt`;
|
|
1320
|
+
return str;
|
|
1321
|
+
}
|
|
1322
|
+
function replaceDocumentTokens(template = "", meta) {
|
|
1323
|
+
return template.replace(/\{title\}/gi, meta.title || "").replace(/\{subtitle\}/gi, meta.subtitle || "").replace(/\{author\}/gi, meta.author || "").replace(/\{version\}/gi, meta.version || "").replace(/\{date\}/gi, meta.date || "").replace(/\{company\}/gi, meta.company || "");
|
|
1324
|
+
}
|
|
1325
|
+
function normalizeWatermark(rawWatermark) {
|
|
1326
|
+
if (!rawWatermark) {
|
|
1327
|
+
return void 0;
|
|
1328
|
+
}
|
|
1329
|
+
if (typeof rawWatermark === "string") {
|
|
1330
|
+
const text = rawWatermark.trim();
|
|
1331
|
+
if (!text) return void 0;
|
|
1332
|
+
return {
|
|
1333
|
+
text,
|
|
1334
|
+
color: "#94a3b8",
|
|
1335
|
+
opacity: 0.08,
|
|
1336
|
+
fontSize: 54,
|
|
1337
|
+
rotate: -45,
|
|
1338
|
+
position: "diagonal"
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
if (typeof rawWatermark === "object") {
|
|
1342
|
+
if (!rawWatermark.text || !rawWatermark.text.trim()) return void 0;
|
|
1343
|
+
return {
|
|
1344
|
+
text: rawWatermark.text.trim(),
|
|
1345
|
+
color: rawWatermark.color || "#94a3b8",
|
|
1346
|
+
opacity: typeof rawWatermark.opacity === "number" ? rawWatermark.opacity : 0.08,
|
|
1347
|
+
fontSize: rawWatermark.fontSize || 54,
|
|
1348
|
+
rotate: typeof rawWatermark.rotate === "number" ? rawWatermark.rotate : -45,
|
|
1349
|
+
position: rawWatermark.position || "diagonal"
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
return void 0;
|
|
1353
|
+
}
|
|
1354
|
+
function normalizeHeaderFooterSlot(rawSlot, parent, meta) {
|
|
1355
|
+
if (!rawSlot) return void 0;
|
|
1356
|
+
if (typeof rawSlot === "string") {
|
|
1357
|
+
const text = replaceDocumentTokens(rawSlot, meta).trim();
|
|
1358
|
+
if (!text) return void 0;
|
|
1359
|
+
return {
|
|
1360
|
+
text,
|
|
1361
|
+
color: (parent == null ? void 0 : parent.color) || "#94A3B8",
|
|
1362
|
+
fontSize: (parent == null ? void 0 : parent.size) || 9,
|
|
1363
|
+
fontFamily: (parent == null ? void 0 : parent.font) || "Segoe UI",
|
|
1364
|
+
bold: false,
|
|
1365
|
+
italic: false
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof rawSlot === "object") {
|
|
1369
|
+
const text = replaceDocumentTokens(rawSlot.text || "", meta).trim();
|
|
1370
|
+
if (!text) return void 0;
|
|
1371
|
+
return {
|
|
1372
|
+
text,
|
|
1373
|
+
color: rawSlot.color || (parent == null ? void 0 : parent.color) || "#94A3B8",
|
|
1374
|
+
fontSize: rawSlot.fontSize || (parent == null ? void 0 : parent.size) || 9,
|
|
1375
|
+
fontFamily: rawSlot.fontFamily || (parent == null ? void 0 : parent.font) || "Segoe UI",
|
|
1376
|
+
bold: Boolean(rawSlot.bold),
|
|
1377
|
+
italic: Boolean(rawSlot.italic)
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
return void 0;
|
|
1381
|
+
}
|
|
1382
|
+
function normalizeHeaderFooter(raw, meta) {
|
|
1383
|
+
if (!raw) return void 0;
|
|
1384
|
+
const left = normalizeHeaderFooterSlot(raw.left, raw, meta);
|
|
1385
|
+
const center = normalizeHeaderFooterSlot(raw.center, raw, meta);
|
|
1386
|
+
const right = normalizeHeaderFooterSlot(raw.right, raw, meta);
|
|
1387
|
+
if (!left && !center && !right) return void 0;
|
|
1388
|
+
return {
|
|
1389
|
+
left,
|
|
1390
|
+
center,
|
|
1391
|
+
right,
|
|
1392
|
+
font: raw.font || "Segoe UI",
|
|
1393
|
+
size: raw.size || 9,
|
|
1394
|
+
color: raw.color || "#94A3B8",
|
|
1395
|
+
divider: Boolean(raw.divider),
|
|
1396
|
+
dividerColor: raw.dividerColor || "#E2E8F0"
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
function normalizeSignatures(raw, meta = {}) {
|
|
1400
|
+
if (!raw) return void 0;
|
|
1401
|
+
let rawItems = [];
|
|
1402
|
+
let rawConfig = {};
|
|
1403
|
+
if (Array.isArray(raw)) {
|
|
1404
|
+
rawItems = raw;
|
|
1405
|
+
} else if (typeof raw === "object" && Array.isArray(raw.items)) {
|
|
1406
|
+
rawItems = raw.items;
|
|
1407
|
+
rawConfig = raw;
|
|
1408
|
+
}
|
|
1409
|
+
if (rawItems.length === 0) return void 0;
|
|
1410
|
+
const cappedItems = rawItems.slice(0, 4);
|
|
1411
|
+
const items = cappedItems.map((item) => {
|
|
1412
|
+
const tokenCtx = meta;
|
|
1413
|
+
const rawName = typeof item.name === "string" ? item.name : "";
|
|
1414
|
+
const name = replaceDocumentTokens(rawName, tokenCtx).trim();
|
|
1415
|
+
const title = item.title ? replaceDocumentTokens(item.title, tokenCtx).trim() : void 0;
|
|
1416
|
+
const role = item.role ? replaceDocumentTokens(item.role, tokenCtx).trim() : void 0;
|
|
1417
|
+
let dateStr;
|
|
1418
|
+
if (typeof item.date === "string") {
|
|
1419
|
+
dateStr = replaceDocumentTokens(item.date, tokenCtx).trim();
|
|
1420
|
+
} else if (item.date === true) {
|
|
1421
|
+
dateStr = meta.date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1422
|
+
}
|
|
1423
|
+
let signatureHeight = 60;
|
|
1424
|
+
if (typeof item.signatureHeight === "number") {
|
|
1425
|
+
signatureHeight = item.signatureHeight;
|
|
1426
|
+
} else if (typeof item.signatureHeight === "string") {
|
|
1427
|
+
const parsed = parseFloat(item.signatureHeight);
|
|
1428
|
+
if (!isNaN(parsed)) signatureHeight = parsed;
|
|
1429
|
+
}
|
|
1430
|
+
return {
|
|
1431
|
+
title,
|
|
1432
|
+
name: name || "Authorized Signatory",
|
|
1433
|
+
role,
|
|
1434
|
+
date: dateStr,
|
|
1435
|
+
image: item.image,
|
|
1436
|
+
signatureHeight
|
|
1437
|
+
};
|
|
1438
|
+
});
|
|
1439
|
+
const align = rawConfig.align || (items.length === 1 ? "right" : "space-between");
|
|
1440
|
+
const style = rawConfig.style || "line";
|
|
1441
|
+
const borderColor = rawConfig.borderColor || "#CBD5E1";
|
|
1442
|
+
const titleColor = rawConfig.titleColor || "#64748B";
|
|
1443
|
+
const nameColor = rawConfig.nameColor || "#0F172A";
|
|
1444
|
+
const roleColor = rawConfig.roleColor || "#64748B";
|
|
1445
|
+
const spacingBeforeRaw = rawConfig.spacingBefore ?? "2.5rem";
|
|
1446
|
+
const spacingBefore = formatMarginCss(spacingBeforeRaw, "2.5rem");
|
|
1447
|
+
const spacingBeforeTwip = parseMarginToTwip(spacingBeforeRaw, 600);
|
|
1448
|
+
return {
|
|
1449
|
+
items,
|
|
1450
|
+
align,
|
|
1451
|
+
style,
|
|
1452
|
+
borderColor,
|
|
1453
|
+
titleColor,
|
|
1454
|
+
nameColor,
|
|
1455
|
+
roleColor,
|
|
1456
|
+
spacingBefore,
|
|
1457
|
+
spacingBeforeTwip
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
function resolveDocumentConfig(frontmatter = {}, userConfig = {}) {
|
|
1461
|
+
const configMeta = userConfig.metadata || {};
|
|
1462
|
+
const mergedMeta = { ...configMeta, ...frontmatter };
|
|
1463
|
+
const title = mergedMeta.title || "MarkForge Document";
|
|
1464
|
+
const subtitle = mergedMeta.subtitle || void 0;
|
|
1465
|
+
const author = Array.isArray(mergedMeta.author) ? mergedMeta.author.join(", ") : mergedMeta.author || void 0;
|
|
1466
|
+
const date = mergedMeta.date || void 0;
|
|
1467
|
+
const version = mergedMeta.version || void 0;
|
|
1468
|
+
const company = mergedMeta.company || void 0;
|
|
1469
|
+
const lang = mergedMeta.lang || "en";
|
|
1470
|
+
const tokenContext = { title, subtitle, author, version, date, company };
|
|
1471
|
+
const theme = mergedMeta.theme || userConfig.theme || DEFAULT_CONFIG.theme;
|
|
1472
|
+
const orientation = mergedMeta.orientation || userConfig.orientation || DEFAULT_CONFIG.orientation;
|
|
1473
|
+
const paperSize = mergedMeta.paperSize || userConfig.paperSize || DEFAULT_CONFIG.paperSize;
|
|
1474
|
+
const baseDim = PAPER_DIMENSIONS_TWIP[paperSize] || PAPER_DIMENSIONS_TWIP.A4;
|
|
1475
|
+
const paperDimensions = orientation === "landscape" ? { widthTwip: baseDim.height, heightTwip: baseDim.width } : { widthTwip: baseDim.width, heightTwip: baseDim.height };
|
|
1476
|
+
const fmMargin = mergedMeta.margins || {};
|
|
1477
|
+
const cfgMargin = userConfig.margins || {};
|
|
1478
|
+
const defMargin = DEFAULT_CONFIG.margins || {};
|
|
1479
|
+
const topRaw = fmMargin.top ?? cfgMargin.top ?? defMargin.top ?? "2.5cm";
|
|
1480
|
+
const bottomRaw = fmMargin.bottom ?? cfgMargin.bottom ?? defMargin.bottom ?? "2.5cm";
|
|
1481
|
+
const leftRaw = fmMargin.left ?? cfgMargin.left ?? defMargin.left ?? "2.5cm";
|
|
1482
|
+
const rightRaw = fmMargin.right ?? cfgMargin.right ?? defMargin.right ?? "2.5cm";
|
|
1483
|
+
const margins = {
|
|
1484
|
+
top: formatMarginCss(topRaw),
|
|
1485
|
+
bottom: formatMarginCss(bottomRaw),
|
|
1486
|
+
left: formatMarginCss(leftRaw),
|
|
1487
|
+
right: formatMarginCss(rightRaw),
|
|
1488
|
+
topTwip: parseMarginToTwip(topRaw),
|
|
1489
|
+
bottomTwip: parseMarginToTwip(bottomRaw),
|
|
1490
|
+
leftTwip: parseMarginToTwip(leftRaw),
|
|
1491
|
+
rightTwip: parseMarginToTwip(rightRaw)
|
|
1492
|
+
};
|
|
1493
|
+
const rawHeader = mergedMeta.header || userConfig.header || DEFAULT_CONFIG.header;
|
|
1494
|
+
const rawFooter = mergedMeta.footer || userConfig.footer || DEFAULT_CONFIG.footer;
|
|
1495
|
+
const header = normalizeHeaderFooter(rawHeader, tokenContext);
|
|
1496
|
+
const footer = normalizeHeaderFooter(rawFooter, tokenContext);
|
|
1497
|
+
const toc = typeof mergedMeta.toc === "boolean" ? mergedMeta.toc : typeof userConfig.toc === "boolean" ? userConfig.toc : DEFAULT_CONFIG.toc;
|
|
1498
|
+
const rawWatermark = mergedMeta.watermark !== void 0 ? mergedMeta.watermark : userConfig.watermark !== void 0 ? userConfig.watermark : DEFAULT_CONFIG.watermark;
|
|
1499
|
+
const watermark = normalizeWatermark(rawWatermark);
|
|
1500
|
+
const rawSignatures = mergedMeta.signatures || userConfig.signatures;
|
|
1501
|
+
const signatures = normalizeSignatures(rawSignatures, tokenContext);
|
|
1502
|
+
const cssList = [];
|
|
1503
|
+
const addCss = (item) => {
|
|
1504
|
+
if (!item) return;
|
|
1505
|
+
if (Array.isArray(item)) cssList.push(...item);
|
|
1506
|
+
else cssList.push(item);
|
|
1507
|
+
};
|
|
1508
|
+
addCss(userConfig.css);
|
|
1509
|
+
addCss(mergedMeta.css);
|
|
1510
|
+
const embedImages = typeof userConfig.embedImages === "boolean" ? userConfig.embedImages : DEFAULT_CONFIG.embedImages;
|
|
1511
|
+
const bundleHtml = typeof userConfig.bundleHtml === "boolean" ? userConfig.bundleHtml : DEFAULT_CONFIG.bundleHtml;
|
|
1512
|
+
const syntaxTheme = userConfig.syntaxTheme || DEFAULT_CONFIG.syntaxTheme || "github-dark";
|
|
1513
|
+
return {
|
|
1514
|
+
title,
|
|
1515
|
+
subtitle,
|
|
1516
|
+
author,
|
|
1517
|
+
date,
|
|
1518
|
+
version,
|
|
1519
|
+
company,
|
|
1520
|
+
lang,
|
|
1521
|
+
theme,
|
|
1522
|
+
orientation,
|
|
1523
|
+
paperSize,
|
|
1524
|
+
paperDimensions,
|
|
1525
|
+
margins,
|
|
1526
|
+
header,
|
|
1527
|
+
footer,
|
|
1528
|
+
toc,
|
|
1529
|
+
signatures,
|
|
1530
|
+
watermark,
|
|
1531
|
+
css: cssList,
|
|
1532
|
+
embedImages,
|
|
1533
|
+
bundleHtml,
|
|
1534
|
+
syntaxTheme
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1007
1537
|
|
|
1008
1538
|
// src/core/html/htmlBuilder.ts
|
|
1009
1539
|
function escapeHtml(str) {
|
|
@@ -1056,43 +1586,41 @@ async function renderInlinesToHtml(spans = [], baseDir = process.cwd()) {
|
|
|
1056
1586
|
return result;
|
|
1057
1587
|
}
|
|
1058
1588
|
async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
1059
|
-
|
|
1060
|
-
const
|
|
1061
|
-
const themeName = metadata.theme || config.theme || "default";
|
|
1062
|
-
const baseThemeCss = THEMES[themeName] || THEMES.default;
|
|
1589
|
+
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
1590
|
+
const baseThemeCss = generateThemeCss(resolved.theme);
|
|
1063
1591
|
let customCss = "";
|
|
1064
|
-
|
|
1065
|
-
const
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
if (fs2.existsSync(fullCssPath)) {
|
|
1069
|
-
customCss += `
|
|
1592
|
+
for (const cssPath of resolved.css) {
|
|
1593
|
+
const fullCssPath = path3.isAbsolute(cssPath) ? cssPath : path3.resolve(baseDir, cssPath);
|
|
1594
|
+
if (fs3.existsSync(fullCssPath)) {
|
|
1595
|
+
customCss += `
|
|
1070
1596
|
/* Custom CSS: ${cssPath} */
|
|
1071
|
-
` +
|
|
1072
|
-
}
|
|
1597
|
+
` + fs3.readFileSync(fullCssPath, "utf-8");
|
|
1073
1598
|
}
|
|
1074
1599
|
}
|
|
1075
1600
|
const inlinedCss = doc.inlinedStyles.join("\n");
|
|
1076
1601
|
let bodyHtml = "";
|
|
1077
|
-
if (
|
|
1602
|
+
if (resolved.title) {
|
|
1078
1603
|
bodyHtml += ` <header class="document-header">
|
|
1079
1604
|
`;
|
|
1080
|
-
bodyHtml += ` <h1 class="document-title">${escapeHtml(
|
|
1605
|
+
bodyHtml += ` <h1 class="document-title">${escapeHtml(resolved.title)}</h1>
|
|
1081
1606
|
`;
|
|
1082
|
-
if (
|
|
1083
|
-
bodyHtml += ` <div class="document-subtitle">${escapeHtml(
|
|
1607
|
+
if (resolved.subtitle) {
|
|
1608
|
+
bodyHtml += ` <div class="document-subtitle">${escapeHtml(resolved.subtitle)}</div>
|
|
1084
1609
|
`;
|
|
1085
1610
|
}
|
|
1086
|
-
if (
|
|
1611
|
+
if (resolved.author || resolved.date || resolved.version) {
|
|
1087
1612
|
bodyHtml += ` <div class="document-meta">
|
|
1088
1613
|
`;
|
|
1089
|
-
if (
|
|
1090
|
-
|
|
1091
|
-
|
|
1614
|
+
if (resolved.author) {
|
|
1615
|
+
bodyHtml += ` <span>Author: ${escapeHtml(resolved.author)}</span>
|
|
1616
|
+
`;
|
|
1617
|
+
}
|
|
1618
|
+
if (resolved.version) {
|
|
1619
|
+
bodyHtml += ` <span>Version: ${escapeHtml(resolved.version)}</span>
|
|
1092
1620
|
`;
|
|
1093
1621
|
}
|
|
1094
|
-
if (
|
|
1095
|
-
bodyHtml += ` <span>Date: ${escapeHtml(
|
|
1622
|
+
if (resolved.date) {
|
|
1623
|
+
bodyHtml += ` <span>Date: ${escapeHtml(resolved.date)}</span>
|
|
1096
1624
|
`;
|
|
1097
1625
|
}
|
|
1098
1626
|
bodyHtml += ` </div>
|
|
@@ -1101,22 +1629,20 @@ async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1101
1629
|
bodyHtml += ` </header>
|
|
1102
1630
|
`;
|
|
1103
1631
|
}
|
|
1104
|
-
if (
|
|
1105
|
-
|
|
1106
|
-
bodyHtml += ` <nav class="table-of-contents">
|
|
1632
|
+
if (resolved.toc && doc.tocEntries.length > 0) {
|
|
1633
|
+
bodyHtml += ` <nav class="table-of-contents">
|
|
1107
1634
|
`;
|
|
1108
|
-
|
|
1635
|
+
bodyHtml += ` <h2>Table of Contents</h2>
|
|
1109
1636
|
<ul>
|
|
1110
1637
|
`;
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1638
|
+
for (const entry of doc.tocEntries) {
|
|
1639
|
+
const indent = " ".repeat(entry.level);
|
|
1640
|
+
bodyHtml += ` ${indent}<li><a href="#${entry.id}">${escapeHtml(entry.text)}</a></li>
|
|
1114
1641
|
`;
|
|
1115
|
-
|
|
1116
|
-
|
|
1642
|
+
}
|
|
1643
|
+
bodyHtml += ` </ul>
|
|
1117
1644
|
</nav>
|
|
1118
1645
|
`;
|
|
1119
|
-
}
|
|
1120
1646
|
}
|
|
1121
1647
|
for (const node of doc.nodes) {
|
|
1122
1648
|
if (node.type === "heading") {
|
|
@@ -1134,7 +1660,7 @@ async function buildHtmlDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1134
1660
|
if (node.type === "codeBlock") {
|
|
1135
1661
|
const lang = node.language || "";
|
|
1136
1662
|
const langClass = lang ? ` class="language-${escapeHtml(lang)}"` : "";
|
|
1137
|
-
const highlighted = highlightCodeToHtml(node.text || "", lang);
|
|
1663
|
+
const highlighted = highlightCodeToHtml(node.text || "", lang, resolved.syntaxTheme);
|
|
1138
1664
|
bodyHtml += ` <pre><code${langClass}>${highlighted}</code></pre>
|
|
1139
1665
|
`;
|
|
1140
1666
|
continue;
|
|
@@ -1178,15 +1704,12 @@ ${escapeHtml(node.text || "")}
|
|
|
1178
1704
|
for (const row of node.children) {
|
|
1179
1705
|
bodyHtml += ` <tr>
|
|
1180
1706
|
`;
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
const cellInner = await renderInlinesToHtml(cell.inlines, baseDir);
|
|
1187
|
-
bodyHtml += ` <${tag}${align}>${cellInner}</${tag}>
|
|
1707
|
+
for (const cell of row.children || []) {
|
|
1708
|
+
const tag = cell.isHeader ? "th" : "td";
|
|
1709
|
+
const align = cell.align ? ` align="${cell.align}"` : "";
|
|
1710
|
+
const inner = await renderInlinesToHtml(cell.inlines, baseDir);
|
|
1711
|
+
bodyHtml += ` <${tag}${align}>${inner}</${tag}>
|
|
1188
1712
|
`;
|
|
1189
|
-
}
|
|
1190
1713
|
}
|
|
1191
1714
|
bodyHtml += ` </tr>
|
|
1192
1715
|
`;
|
|
@@ -1200,58 +1723,187 @@ ${escapeHtml(node.text || "")}
|
|
|
1200
1723
|
bodyHtml += ` <${tag}>
|
|
1201
1724
|
`;
|
|
1202
1725
|
for (const item of node.children) {
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
if (item.checked !== void 0) {
|
|
1206
|
-
prefix = `<input type="checkbox" disabled ${item.checked ? "checked" : ""}/> `;
|
|
1207
|
-
}
|
|
1208
|
-
bodyHtml += ` <li>${prefix}${itemInner}</li>
|
|
1726
|
+
const inner = await renderInlinesToHtml(item.inlines, baseDir);
|
|
1727
|
+
bodyHtml += ` <li>${inner}</li>
|
|
1209
1728
|
`;
|
|
1210
1729
|
}
|
|
1211
1730
|
bodyHtml += ` </${tag}>
|
|
1212
1731
|
`;
|
|
1213
1732
|
continue;
|
|
1214
1733
|
}
|
|
1215
|
-
if (node.type === "
|
|
1216
|
-
bodyHtml += `
|
|
1734
|
+
if (node.type === "thematicBreak") {
|
|
1735
|
+
bodyHtml += ` <hr />
|
|
1217
1736
|
`;
|
|
1218
1737
|
continue;
|
|
1219
1738
|
}
|
|
1220
|
-
if (node.type === "
|
|
1221
|
-
bodyHtml += `
|
|
1739
|
+
if (node.type === "htmlBlock") {
|
|
1740
|
+
bodyHtml += ` ${node.text}
|
|
1222
1741
|
`;
|
|
1223
1742
|
continue;
|
|
1224
1743
|
}
|
|
1225
1744
|
}
|
|
1226
|
-
const wmConfig = config.watermark ?? metadata.watermark;
|
|
1227
|
-
let watermarkHtml = "";
|
|
1228
1745
|
let watermarkCss = "";
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
const
|
|
1232
|
-
const rotate = typeof wmConfig === "object" && wmConfig.rotate !== void 0 ? wmConfig.rotate : -45;
|
|
1233
|
-
const color = typeof wmConfig === "object" && wmConfig.color ? wmConfig.color : "#94A3B8";
|
|
1234
|
-
const fontSize = typeof wmConfig === "object" && wmConfig.fontSize ? `${wmConfig.fontSize}pt` : "52pt";
|
|
1746
|
+
let watermarkHtml = "";
|
|
1747
|
+
if (resolved.watermark) {
|
|
1748
|
+
const wm = resolved.watermark;
|
|
1235
1749
|
watermarkCss = `
|
|
1236
1750
|
.document-watermark {
|
|
1237
1751
|
position: fixed;
|
|
1238
|
-
top:
|
|
1239
|
-
left:
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
font-weight: 800;
|
|
1243
|
-
color: ${color};
|
|
1244
|
-
opacity: ${opacity};
|
|
1752
|
+
top: 0;
|
|
1753
|
+
left: 0;
|
|
1754
|
+
width: 100vw;
|
|
1755
|
+
height: 100vh;
|
|
1245
1756
|
pointer-events: none;
|
|
1757
|
+
z-index: 0;
|
|
1246
1758
|
user-select: none;
|
|
1247
|
-
|
|
1248
|
-
text-transform: uppercase;
|
|
1249
|
-
letter-spacing: 0.15em;
|
|
1250
|
-
white-space: nowrap;
|
|
1759
|
+
-webkit-user-select: none;
|
|
1251
1760
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1761
|
+
.document-container {
|
|
1762
|
+
position: relative;
|
|
1763
|
+
z-index: 1;
|
|
1764
|
+
}
|
|
1765
|
+
@media print {
|
|
1766
|
+
.document-watermark {
|
|
1767
|
+
position: fixed;
|
|
1768
|
+
top: 0;
|
|
1769
|
+
left: 0;
|
|
1770
|
+
width: 100vw;
|
|
1771
|
+
height: 100vh;
|
|
1772
|
+
-webkit-print-color-adjust: exact;
|
|
1773
|
+
print-color-adjust: exact;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
`;
|
|
1777
|
+
watermarkHtml = ` <div id="markforge-watermark" class="document-watermark" aria-hidden="true"></div>
|
|
1778
|
+
<script>
|
|
1779
|
+
(function() {
|
|
1780
|
+
try {
|
|
1781
|
+
var canvas = document.createElement('canvas');
|
|
1782
|
+
var dpr = 3;
|
|
1783
|
+
var width = 800;
|
|
1784
|
+
var height = 1100;
|
|
1785
|
+
canvas.width = Math.round(width * dpr);
|
|
1786
|
+
canvas.height = Math.round(height * dpr);
|
|
1787
|
+
var ctx = canvas.getContext('2d');
|
|
1788
|
+
if (ctx) {
|
|
1789
|
+
ctx.scale(dpr, dpr);
|
|
1790
|
+
ctx.translate(width / 2, height / 2);
|
|
1791
|
+
ctx.rotate((${wm.rotate} * Math.PI) / 180);
|
|
1792
|
+
ctx.textAlign = 'center';
|
|
1793
|
+
ctx.textBaseline = 'middle';
|
|
1794
|
+
ctx.font = '900 ${wm.fontSize * 1.5}px system-ui, -apple-system, sans-serif';
|
|
1795
|
+
ctx.fillStyle = '${wm.color}';
|
|
1796
|
+
ctx.globalAlpha = ${wm.opacity};
|
|
1797
|
+
try { ctx.letterSpacing = '0.15em'; } catch(e) {}
|
|
1798
|
+
ctx.fillText(${JSON.stringify(wm.text.toUpperCase())}, 0, 0);
|
|
1799
|
+
var dataUrl = canvas.toDataURL('image/png');
|
|
1800
|
+
var wmEl = document.getElementById('markforge-watermark');
|
|
1801
|
+
if (wmEl) {
|
|
1802
|
+
wmEl.style.backgroundImage = 'url("' + dataUrl + '")';
|
|
1803
|
+
wmEl.style.backgroundRepeat = 'no-repeat';
|
|
1804
|
+
wmEl.style.backgroundPosition = 'center center';
|
|
1805
|
+
wmEl.style.backgroundSize = 'contain';
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
} catch(err) {}
|
|
1809
|
+
})();
|
|
1810
|
+
</script>
|
|
1811
|
+
`;
|
|
1812
|
+
}
|
|
1813
|
+
let signaturesHtml = "";
|
|
1814
|
+
let signaturesCss = "";
|
|
1815
|
+
if (resolved.signatures && resolved.signatures.items.length > 0) {
|
|
1816
|
+
const sig = resolved.signatures;
|
|
1817
|
+
const numItems = sig.items.length;
|
|
1818
|
+
let justifyCss = "flex-end";
|
|
1819
|
+
if (sig.align === "left") justifyCss = "flex-start";
|
|
1820
|
+
else if (sig.align === "center") justifyCss = "center";
|
|
1821
|
+
else if (sig.align === "space-between") justifyCss = "space-between";
|
|
1822
|
+
signaturesCss = `
|
|
1823
|
+
.markforge-signatures {
|
|
1824
|
+
margin-top: ${sig.spacingBefore};
|
|
1825
|
+
display: grid;
|
|
1826
|
+
grid-template-columns: ${numItems === 1 ? sig.align === "left" ? "minmax(200px, 280px) 1fr" : sig.align === "center" ? "1fr minmax(200px, 280px) 1fr" : "1fr minmax(200px, 280px)" : `repeat(${numItems}, minmax(0, 1fr))`};
|
|
1827
|
+
gap: 2rem;
|
|
1828
|
+
page-break-inside: avoid;
|
|
1829
|
+
break-inside: avoid;
|
|
1830
|
+
}
|
|
1831
|
+
.markforge-signature-card {
|
|
1832
|
+
${numItems === 1 && sig.align === "center" ? "grid-column: 2;" : ""}
|
|
1833
|
+
${numItems === 1 && sig.align === "right" ? "grid-column: 2;" : ""}
|
|
1834
|
+
display: flex;
|
|
1835
|
+
flex-direction: column;
|
|
1836
|
+
${sig.style === "box" ? `border: 1px solid ${sig.borderColor}; border-radius: 6px; padding: 14px 18px; background-color: var(--mf-card-bg, #F8FAFC);` : ""}
|
|
1837
|
+
}
|
|
1838
|
+
.markforge-sig-title {
|
|
1839
|
+
font-size: 0.85rem;
|
|
1840
|
+
color: ${sig.titleColor};
|
|
1841
|
+
font-weight: 600;
|
|
1842
|
+
margin-bottom: 6px;
|
|
1843
|
+
}
|
|
1844
|
+
.markforge-sig-space {
|
|
1845
|
+
height: var(--sig-height, 60px);
|
|
1846
|
+
display: flex;
|
|
1847
|
+
align-items: center;
|
|
1848
|
+
justify-content: center;
|
|
1849
|
+
margin-bottom: 6px;
|
|
1850
|
+
}
|
|
1851
|
+
.markforge-sig-space img {
|
|
1852
|
+
max-height: 100%;
|
|
1853
|
+
max-width: 100%;
|
|
1854
|
+
object-fit: contain;
|
|
1855
|
+
}
|
|
1856
|
+
.markforge-sig-line {
|
|
1857
|
+
${sig.style === "line" ? `border-bottom: 1.5px solid ${sig.borderColor}; margin-bottom: 8px;` : ""}
|
|
1858
|
+
}
|
|
1859
|
+
.markforge-sig-name {
|
|
1860
|
+
font-size: 0.95rem;
|
|
1861
|
+
font-weight: 700;
|
|
1862
|
+
color: ${sig.nameColor};
|
|
1863
|
+
}
|
|
1864
|
+
.markforge-sig-role {
|
|
1865
|
+
font-size: 0.82rem;
|
|
1866
|
+
color: ${sig.roleColor};
|
|
1867
|
+
margin-top: 2px;
|
|
1868
|
+
}
|
|
1869
|
+
.markforge-sig-date {
|
|
1870
|
+
font-size: 0.78rem;
|
|
1871
|
+
color: ${sig.roleColor};
|
|
1872
|
+
margin-top: 2px;
|
|
1873
|
+
}
|
|
1874
|
+
@media print {
|
|
1875
|
+
.markforge-signatures {
|
|
1876
|
+
page-break-inside: avoid;
|
|
1877
|
+
break-inside: avoid;
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
`;
|
|
1881
|
+
const itemCards = sig.items.map((item) => {
|
|
1882
|
+
const titleHtml = item.title ? `<div class="markforge-sig-title">${escapeHtml(item.title)}</div>` : "";
|
|
1883
|
+
let signSpaceHtml = "";
|
|
1884
|
+
if (item.image) {
|
|
1885
|
+
signSpaceHtml = `<div class="markforge-sig-space" style="--sig-height: ${item.signatureHeight}px;"><img src="${escapeHtml(item.image)}" alt="Signature" /></div>`;
|
|
1886
|
+
} else {
|
|
1887
|
+
signSpaceHtml = `<div class="markforge-sig-space" style="--sig-height: ${item.signatureHeight}px;"></div>`;
|
|
1888
|
+
}
|
|
1889
|
+
const lineHtml = sig.style === "line" ? `<div class="markforge-sig-line"></div>` : "";
|
|
1890
|
+
const nameHtml = `<div class="markforge-sig-name">${escapeHtml(item.name)}</div>`;
|
|
1891
|
+
const roleHtml = item.role ? `<div class="markforge-sig-role">${escapeHtml(item.role)}</div>` : "";
|
|
1892
|
+
const dateHtml = item.date ? `<div class="markforge-sig-date">Date: ${escapeHtml(item.date)}</div>` : "";
|
|
1893
|
+
return ` <div class="markforge-signature-card">
|
|
1894
|
+
${titleHtml}
|
|
1895
|
+
${signSpaceHtml}
|
|
1896
|
+
${lineHtml}
|
|
1897
|
+
${nameHtml}
|
|
1898
|
+
${roleHtml}
|
|
1899
|
+
${dateHtml}
|
|
1900
|
+
</div>`;
|
|
1901
|
+
}).join("\n");
|
|
1902
|
+
signaturesHtml = `
|
|
1903
|
+
<div class="markforge-signatures">
|
|
1904
|
+
${itemCards}
|
|
1905
|
+
</div>
|
|
1906
|
+
`;
|
|
1255
1907
|
}
|
|
1256
1908
|
const hasMermaid = doc.nodes.some((n) => n.type === "mermaid");
|
|
1257
1909
|
const mermaidScript = hasMermaid ? `<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
|
@@ -1269,24 +1921,24 @@ ${escapeHtml(node.text || "")}
|
|
|
1269
1921
|
}
|
|
1270
1922
|
});
|
|
1271
1923
|
</script>` : "";
|
|
1272
|
-
const documentTitle = metadata.title || "MarkForge Document";
|
|
1273
1924
|
return `<!DOCTYPE html>
|
|
1274
|
-
<html lang="${
|
|
1925
|
+
<html lang="${resolved.lang}">
|
|
1275
1926
|
<head>
|
|
1276
1927
|
<meta charset="UTF-8">
|
|
1277
1928
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1278
|
-
<title>${escapeHtml(
|
|
1929
|
+
<title>${escapeHtml(resolved.title)}</title>
|
|
1279
1930
|
<style>
|
|
1280
1931
|
${THEME_COMPONENTS}
|
|
1281
1932
|
${baseThemeCss}
|
|
1282
1933
|
${customCss}
|
|
1283
1934
|
${inlinedCss}
|
|
1284
1935
|
${watermarkCss}
|
|
1936
|
+
${signaturesCss}
|
|
1285
1937
|
</style>
|
|
1286
1938
|
</head>
|
|
1287
1939
|
<body>
|
|
1288
1940
|
${watermarkHtml} <div class="document-container">
|
|
1289
|
-
${bodyHtml} </div>
|
|
1941
|
+
${bodyHtml}${signaturesHtml} </div>
|
|
1290
1942
|
${mermaidScript}
|
|
1291
1943
|
</body>
|
|
1292
1944
|
</html>`;
|
|
@@ -1294,10 +1946,10 @@ ${bodyHtml} </div>
|
|
|
1294
1946
|
|
|
1295
1947
|
// src/core/pdf/pdfBuilder.ts
|
|
1296
1948
|
function findChromeExecutable() {
|
|
1297
|
-
if (process.env.CHROME_PATH &&
|
|
1949
|
+
if (process.env.CHROME_PATH && fs4.existsSync(process.env.CHROME_PATH)) {
|
|
1298
1950
|
return process.env.CHROME_PATH;
|
|
1299
1951
|
}
|
|
1300
|
-
if (process.env.PUPPETEER_EXECUTABLE_PATH &&
|
|
1952
|
+
if (process.env.PUPPETEER_EXECUTABLE_PATH && fs4.existsSync(process.env.PUPPETEER_EXECUTABLE_PATH)) {
|
|
1301
1953
|
return process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
1302
1954
|
}
|
|
1303
1955
|
const isWin = process.platform === "win32";
|
|
@@ -1319,14 +1971,14 @@ function findChromeExecutable() {
|
|
|
1319
1971
|
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
1320
1972
|
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
1321
1973
|
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
|
|
1974
|
+
// Windows — Microsoft Edge (Native Windows 10/11 browser, enterprise whitelist friendly)
|
|
1975
|
+
`${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1976
|
+
`${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1977
|
+
`${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1322
1978
|
// Windows — Google Chrome
|
|
1323
1979
|
`${winProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
1324
1980
|
`${winProgramFilesX86}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
1325
1981
|
`${winLocalAppData}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
1326
|
-
// Windows — Microsoft Edge (ships with Windows 10/11)
|
|
1327
|
-
`${winProgramFiles}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1328
|
-
`${winProgramFilesX86}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1329
|
-
`${winLocalAppData}\\Microsoft\\Edge\\Application\\msedge.exe`,
|
|
1330
1982
|
// Windows — Brave Browser
|
|
1331
1983
|
`${winProgramFiles}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
1332
1984
|
`${winProgramFilesX86}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe`,
|
|
@@ -1336,7 +1988,7 @@ function findChromeExecutable() {
|
|
|
1336
1988
|
].filter(Boolean);
|
|
1337
1989
|
for (const candidate of candidates) {
|
|
1338
1990
|
try {
|
|
1339
|
-
if (
|
|
1991
|
+
if (fs4.existsSync(candidate)) {
|
|
1340
1992
|
return candidate;
|
|
1341
1993
|
}
|
|
1342
1994
|
} catch {
|
|
@@ -1349,7 +2001,7 @@ function findChromeExecutable() {
|
|
|
1349
2001
|
const res = (0, import_node_child_process.spawnSync)(cmd, [name], { encoding: "utf-8" });
|
|
1350
2002
|
if (res.status === 0 && res.stdout.trim()) {
|
|
1351
2003
|
const binPath = res.stdout.split(/\r?\n/)[0].trim();
|
|
1352
|
-
if (
|
|
2004
|
+
if (fs4.existsSync(binPath)) return binPath;
|
|
1353
2005
|
}
|
|
1354
2006
|
}
|
|
1355
2007
|
} catch {
|
|
@@ -1357,22 +2009,50 @@ function findChromeExecutable() {
|
|
|
1357
2009
|
return null;
|
|
1358
2010
|
}
|
|
1359
2011
|
function injectPagedMediaStyles(html, config, metadata) {
|
|
1360
|
-
var _a, _b, _c, _d;
|
|
1361
|
-
const
|
|
1362
|
-
const
|
|
1363
|
-
const
|
|
1364
|
-
const
|
|
1365
|
-
const
|
|
1366
|
-
const
|
|
1367
|
-
const
|
|
1368
|
-
const
|
|
1369
|
-
const
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
2012
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2013
|
+
const resolved = resolveDocumentConfig(metadata || {}, config);
|
|
2014
|
+
const size = resolved.paperSize;
|
|
2015
|
+
const orientation = resolved.orientation;
|
|
2016
|
+
const top = resolved.margins.top;
|
|
2017
|
+
const bottom = resolved.margins.bottom;
|
|
2018
|
+
const left = resolved.margins.left;
|
|
2019
|
+
const right = resolved.margins.right;
|
|
2020
|
+
const esc = (s) => s.replace(/"/g, '\\"').replace(/\\/g, "\\\\");
|
|
2021
|
+
const buildZoneCss = (pos, zone, isPageCounter = false) => {
|
|
2022
|
+
if (!zone && !isPageCounter) return "";
|
|
2023
|
+
const color = (zone == null ? void 0 : zone.color) || "#94a3b8";
|
|
2024
|
+
const fontSize = (zone == null ? void 0 : zone.fontSize) ? `${zone.fontSize}pt` : "9pt";
|
|
2025
|
+
const fontFamily = (zone == null ? void 0 : zone.fontFamily) ? `font-family: ${zone.fontFamily};` : "";
|
|
2026
|
+
const fontWeight = (zone == null ? void 0 : zone.bold) ? "font-weight: bold;" : "";
|
|
2027
|
+
const fontStyle = (zone == null ? void 0 : zone.italic) ? "font-style: italic;" : "";
|
|
2028
|
+
let content = "";
|
|
2029
|
+
if (isPageCounter) {
|
|
2030
|
+
if ((zone == null ? void 0 : zone.text) && (zone.text.includes("{page}") || zone.text.includes("{pages}"))) {
|
|
2031
|
+
const parts = zone.text.split(/(\{page\}|\{pages\})/gi);
|
|
2032
|
+
const cssParts = parts.map((part) => {
|
|
2033
|
+
if (part.toLowerCase() === "{page}") return "counter(page)";
|
|
2034
|
+
if (part.toLowerCase() === "{pages}") return "counter(pages)";
|
|
2035
|
+
return `"${esc(part)}"`;
|
|
2036
|
+
});
|
|
2037
|
+
content = cssParts.join(" ");
|
|
2038
|
+
} else if (zone == null ? void 0 : zone.text) {
|
|
2039
|
+
content = `"${esc(zone.text)}"`;
|
|
2040
|
+
} else {
|
|
2041
|
+
content = `"Page " counter(page) " of " counter(pages)`;
|
|
2042
|
+
}
|
|
2043
|
+
} else if (zone == null ? void 0 : zone.text) {
|
|
2044
|
+
content = `"${esc(zone.text)}"`;
|
|
2045
|
+
}
|
|
2046
|
+
if (!content) return "";
|
|
2047
|
+
return `@${pos} {
|
|
2048
|
+
content: ${content};
|
|
2049
|
+
font-size: ${fontSize};
|
|
2050
|
+
color: ${color};
|
|
2051
|
+
${fontFamily}
|
|
2052
|
+
${fontWeight}
|
|
2053
|
+
${fontStyle}
|
|
2054
|
+
}`;
|
|
2055
|
+
};
|
|
1376
2056
|
const pagedCss = `
|
|
1377
2057
|
@page {
|
|
1378
2058
|
size: ${size} ${orientation};
|
|
@@ -1380,15 +2060,12 @@ function injectPagedMediaStyles(html, config, metadata) {
|
|
|
1380
2060
|
margin-bottom: ${bottom};
|
|
1381
2061
|
margin-left: ${left};
|
|
1382
2062
|
margin-right: ${right};
|
|
1383
|
-
${
|
|
1384
|
-
${
|
|
1385
|
-
${
|
|
1386
|
-
${
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
font-size: 9pt;
|
|
1390
|
-
color: #94a3b8;
|
|
1391
|
-
}
|
|
2063
|
+
${buildZoneCss("top-left", (_a = resolved.header) == null ? void 0 : _a.left)}
|
|
2064
|
+
${buildZoneCss("top-center", (_b = resolved.header) == null ? void 0 : _b.center)}
|
|
2065
|
+
${buildZoneCss("top-right", (_c = resolved.header) == null ? void 0 : _c.right)}
|
|
2066
|
+
${buildZoneCss("bottom-left", (_d = resolved.footer) == null ? void 0 : _d.left)}
|
|
2067
|
+
${buildZoneCss("bottom-center", (_e = resolved.footer) == null ? void 0 : _e.center)}
|
|
2068
|
+
${buildZoneCss("bottom-right", (_f = resolved.footer) == null ? void 0 : _f.right, true)}
|
|
1392
2069
|
}
|
|
1393
2070
|
@media print {
|
|
1394
2071
|
body { padding: 0; }
|
|
@@ -1445,56 +2122,72 @@ async function buildPdfDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1445
2122
|
if (chromePath) {
|
|
1446
2123
|
const tmpId = Math.random().toString(36).substring(2, 9);
|
|
1447
2124
|
const tmpDir = os.tmpdir();
|
|
1448
|
-
const tmpHtml =
|
|
1449
|
-
const tmpPdf =
|
|
2125
|
+
const tmpHtml = path4.join(tmpDir, `markforge_${tmpId}.html`);
|
|
2126
|
+
const tmpPdf = path4.join(tmpDir, `markforge_${tmpId}.pdf`);
|
|
2127
|
+
const tmpProfile = path4.join(tmpDir, `markforge_prof_${tmpId}`);
|
|
2128
|
+
const isolatedFlags = [
|
|
2129
|
+
`--user-data-dir=${tmpProfile}`,
|
|
2130
|
+
"--no-first-run",
|
|
2131
|
+
"--no-default-browser-check",
|
|
2132
|
+
"--disable-sync",
|
|
2133
|
+
"--disable-background-networking",
|
|
2134
|
+
"--disable-component-update",
|
|
2135
|
+
"--disable-default-apps",
|
|
2136
|
+
"--disable-extensions",
|
|
2137
|
+
"--disable-domain-reliability",
|
|
2138
|
+
"--disable-client-side-phishing-detection",
|
|
2139
|
+
"--disable-breakpad",
|
|
2140
|
+
"--disable-component-extensions-with-background-pages",
|
|
2141
|
+
"--disable-features=Translate,OptimizationHints,MediaRouter,DialMediaRouteProvider,CalculatedNewTabPage,ChromeWhatsNewUI,PrivacySandboxSettings4",
|
|
2142
|
+
"--password-store=basic",
|
|
2143
|
+
"--use-mock-keychain",
|
|
2144
|
+
"--mute-audio",
|
|
2145
|
+
"--no-service-autorun",
|
|
2146
|
+
"--disable-gpu",
|
|
2147
|
+
"--no-sandbox",
|
|
2148
|
+
"--disable-setuid-sandbox",
|
|
2149
|
+
"--allow-file-access-from-files",
|
|
2150
|
+
"--disable-web-security",
|
|
2151
|
+
"--force-color-profile=srgb",
|
|
2152
|
+
"--no-pdf-header-footer"
|
|
2153
|
+
];
|
|
1450
2154
|
try {
|
|
1451
|
-
|
|
1452
|
-
const fileUrl = (0,
|
|
2155
|
+
fs4.writeFileSync(tmpHtml, pagedHtml, "utf-8");
|
|
2156
|
+
const fileUrl = (0, import_node_url2.pathToFileURL)(tmpHtml).href;
|
|
1453
2157
|
let res = (0, import_node_child_process.spawnSync)(
|
|
1454
2158
|
chromePath,
|
|
1455
2159
|
[
|
|
1456
2160
|
"--headless=new",
|
|
1457
|
-
|
|
1458
|
-
"--no-sandbox",
|
|
1459
|
-
"--disable-setuid-sandbox",
|
|
1460
|
-
"--allow-file-access-from-files",
|
|
1461
|
-
"--disable-web-security",
|
|
1462
|
-
"--force-color-profile=srgb",
|
|
2161
|
+
...isolatedFlags,
|
|
1463
2162
|
"--run-all-compositor-stages-before-draw",
|
|
1464
2163
|
"--virtual-time-budget=8000",
|
|
1465
|
-
"--no-pdf-header-footer",
|
|
1466
2164
|
`--print-to-pdf=${tmpPdf}`,
|
|
1467
2165
|
fileUrl
|
|
1468
2166
|
],
|
|
1469
2167
|
{ timeout: 3e4 }
|
|
1470
2168
|
);
|
|
1471
|
-
if ((res.status !== 0 || !
|
|
2169
|
+
if ((res.status !== 0 || !fs4.existsSync(tmpPdf)) && chromePath) {
|
|
1472
2170
|
res = (0, import_node_child_process.spawnSync)(
|
|
1473
2171
|
chromePath,
|
|
1474
2172
|
[
|
|
1475
2173
|
"--headless",
|
|
1476
|
-
|
|
1477
|
-
"--no-sandbox",
|
|
1478
|
-
"--disable-setuid-sandbox",
|
|
1479
|
-
"--allow-file-access-from-files",
|
|
1480
|
-
"--disable-web-security",
|
|
1481
|
-
"--force-color-profile=srgb",
|
|
1482
|
-
"--no-pdf-header-footer",
|
|
2174
|
+
...isolatedFlags,
|
|
1483
2175
|
`--print-to-pdf=${tmpPdf}`,
|
|
1484
2176
|
fileUrl
|
|
1485
2177
|
],
|
|
1486
2178
|
{ timeout: 3e4 }
|
|
1487
2179
|
);
|
|
1488
2180
|
}
|
|
1489
|
-
if (
|
|
1490
|
-
const pdfBuffer =
|
|
2181
|
+
if (fs4.existsSync(tmpPdf) && fs4.statSync(tmpPdf).size > 0) {
|
|
2182
|
+
const pdfBuffer = fs4.readFileSync(tmpPdf);
|
|
1491
2183
|
return pdfBuffer;
|
|
1492
2184
|
}
|
|
1493
2185
|
} catch {
|
|
1494
2186
|
} finally {
|
|
1495
2187
|
try {
|
|
1496
|
-
if (
|
|
1497
|
-
if (
|
|
2188
|
+
if (fs4.existsSync(tmpHtml)) fs4.unlinkSync(tmpHtml);
|
|
2189
|
+
if (fs4.existsSync(tmpPdf)) fs4.unlinkSync(tmpPdf);
|
|
2190
|
+
if (fs4.existsSync(tmpProfile)) fs4.rmSync(tmpProfile, { recursive: true, force: true });
|
|
1498
2191
|
} catch {
|
|
1499
2192
|
}
|
|
1500
2193
|
}
|
|
@@ -1510,8 +2203,8 @@ async function renderMermaidToPng(mermaidCode, _baseDir = process.cwd()) {
|
|
|
1510
2203
|
}
|
|
1511
2204
|
const tmpId = Math.random().toString(36).substring(2, 9);
|
|
1512
2205
|
const tmpDir = os2.tmpdir();
|
|
1513
|
-
const tmpHtml =
|
|
1514
|
-
const tmpScreenshot =
|
|
2206
|
+
const tmpHtml = path5.join(tmpDir, `mermaid_${tmpId}.html`);
|
|
2207
|
+
const tmpScreenshot = path5.join(tmpDir, `mermaid_${tmpId}.png`);
|
|
1515
2208
|
const htmlContent = `<!DOCTYPE html>
|
|
1516
2209
|
<html>
|
|
1517
2210
|
<head>
|
|
@@ -1550,8 +2243,8 @@ ${mermaidCode}
|
|
|
1550
2243
|
</body>
|
|
1551
2244
|
</html>`;
|
|
1552
2245
|
try {
|
|
1553
|
-
|
|
1554
|
-
const fileUrl = (0,
|
|
2246
|
+
fs5.writeFileSync(tmpHtml, htmlContent, "utf-8");
|
|
2247
|
+
const fileUrl = (0, import_node_url3.pathToFileURL)(tmpHtml).href;
|
|
1555
2248
|
const res = (0, import_node_child_process2.spawnSync)(
|
|
1556
2249
|
chromePath,
|
|
1557
2250
|
[
|
|
@@ -1569,15 +2262,15 @@ ${mermaidCode}
|
|
|
1569
2262
|
],
|
|
1570
2263
|
{ timeout: 15e3 }
|
|
1571
2264
|
);
|
|
1572
|
-
if (res.status === 0 &&
|
|
1573
|
-
const buffer =
|
|
2265
|
+
if (res.status === 0 && fs5.existsSync(tmpScreenshot)) {
|
|
2266
|
+
const buffer = fs5.readFileSync(tmpScreenshot);
|
|
1574
2267
|
return buffer;
|
|
1575
2268
|
}
|
|
1576
2269
|
} catch {
|
|
1577
2270
|
} finally {
|
|
1578
2271
|
try {
|
|
1579
|
-
if (
|
|
1580
|
-
if (
|
|
2272
|
+
if (fs5.existsSync(tmpHtml)) fs5.unlinkSync(tmpHtml);
|
|
2273
|
+
if (fs5.existsSync(tmpScreenshot)) fs5.unlinkSync(tmpScreenshot);
|
|
1581
2274
|
} catch {
|
|
1582
2275
|
}
|
|
1583
2276
|
}
|
|
@@ -1585,7 +2278,7 @@ ${mermaidCode}
|
|
|
1585
2278
|
}
|
|
1586
2279
|
|
|
1587
2280
|
// src/core/docx/docxBuilder.ts
|
|
1588
|
-
function
|
|
2281
|
+
function parseMarginToTwip2(margin, defaultTwip = 1440) {
|
|
1589
2282
|
if (typeof margin === "number") return margin;
|
|
1590
2283
|
if (!margin) return defaultTwip;
|
|
1591
2284
|
const str = margin.trim().toLowerCase();
|
|
@@ -1608,7 +2301,7 @@ function parseMarginToTwip(margin, defaultTwip = 1440) {
|
|
|
1608
2301
|
const val = parseFloat(str);
|
|
1609
2302
|
return isNaN(val) ? defaultTwip : Math.round(val);
|
|
1610
2303
|
}
|
|
1611
|
-
async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
2304
|
+
async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd(), options = {}) {
|
|
1612
2305
|
const runs = [];
|
|
1613
2306
|
for (const span of spans) {
|
|
1614
2307
|
if (span.type === "image" && span.url) {
|
|
@@ -1638,7 +2331,10 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1638
2331
|
new import_docx.TextRun({
|
|
1639
2332
|
text: span.content,
|
|
1640
2333
|
style: "Hyperlink",
|
|
1641
|
-
color: "
|
|
2334
|
+
color: "009DA0",
|
|
2335
|
+
font: options.font,
|
|
2336
|
+
size: options.size,
|
|
2337
|
+
bold: options.bold,
|
|
1642
2338
|
underline: {}
|
|
1643
2339
|
})
|
|
1644
2340
|
],
|
|
@@ -1651,7 +2347,11 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1651
2347
|
runs.push(
|
|
1652
2348
|
new import_docx.TextRun({
|
|
1653
2349
|
text: span.content,
|
|
1654
|
-
bold: true
|
|
2350
|
+
bold: true,
|
|
2351
|
+
font: options.font,
|
|
2352
|
+
size: options.size,
|
|
2353
|
+
color: options.color,
|
|
2354
|
+
italics: options.italics
|
|
1655
2355
|
})
|
|
1656
2356
|
);
|
|
1657
2357
|
continue;
|
|
@@ -1660,7 +2360,11 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1660
2360
|
runs.push(
|
|
1661
2361
|
new import_docx.TextRun({
|
|
1662
2362
|
text: span.content,
|
|
1663
|
-
italics: true
|
|
2363
|
+
italics: true,
|
|
2364
|
+
font: options.font,
|
|
2365
|
+
size: options.size,
|
|
2366
|
+
color: options.color,
|
|
2367
|
+
bold: options.bold
|
|
1664
2368
|
})
|
|
1665
2369
|
);
|
|
1666
2370
|
continue;
|
|
@@ -1669,7 +2373,10 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1669
2373
|
runs.push(
|
|
1670
2374
|
new import_docx.TextRun({
|
|
1671
2375
|
text: span.content,
|
|
1672
|
-
strike: true
|
|
2376
|
+
strike: true,
|
|
2377
|
+
font: options.font,
|
|
2378
|
+
size: options.size,
|
|
2379
|
+
color: options.color
|
|
1673
2380
|
})
|
|
1674
2381
|
);
|
|
1675
2382
|
continue;
|
|
@@ -1677,22 +2384,23 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1677
2384
|
if (span.type === "code") {
|
|
1678
2385
|
runs.push(
|
|
1679
2386
|
new import_docx.TextRun({
|
|
1680
|
-
text:
|
|
2387
|
+
text: span.content,
|
|
1681
2388
|
font: "Consolas",
|
|
2389
|
+
size: options.size ? options.size - 2 : 19,
|
|
2390
|
+
color: "0F172A",
|
|
1682
2391
|
shading: {
|
|
1683
2392
|
type: import_docx.ShadingType.CLEAR,
|
|
1684
|
-
fill: "F1F5F9"
|
|
1685
|
-
color: "0F172A"
|
|
2393
|
+
fill: "F1F5F9"
|
|
1686
2394
|
}
|
|
1687
2395
|
})
|
|
1688
2396
|
);
|
|
1689
2397
|
continue;
|
|
1690
2398
|
}
|
|
1691
2399
|
if (span.type === "htmlInline") {
|
|
1692
|
-
let colorHex;
|
|
2400
|
+
let colorHex = options.color;
|
|
1693
2401
|
let bgHex;
|
|
1694
|
-
let isBold =
|
|
1695
|
-
let isItalic =
|
|
2402
|
+
let isBold = !!options.bold;
|
|
2403
|
+
let isItalic = !!options.italics;
|
|
1696
2404
|
if (span.style) {
|
|
1697
2405
|
if (span.style.color) {
|
|
1698
2406
|
colorHex = span.style.color.replace("#", "").trim();
|
|
@@ -1708,13 +2416,9 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1708
2416
|
}
|
|
1709
2417
|
}
|
|
1710
2418
|
if (span.children && span.children.length > 0) {
|
|
1711
|
-
const childRuns = await convertInlinesToTextRuns(span.children, baseDir);
|
|
2419
|
+
const childRuns = await convertInlinesToTextRuns(span.children, baseDir, options);
|
|
1712
2420
|
for (const child of childRuns) {
|
|
1713
|
-
|
|
1714
|
-
runs.push(child);
|
|
1715
|
-
} else {
|
|
1716
|
-
runs.push(child);
|
|
1717
|
-
}
|
|
2421
|
+
runs.push(child);
|
|
1718
2422
|
}
|
|
1719
2423
|
continue;
|
|
1720
2424
|
}
|
|
@@ -1724,6 +2428,8 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1724
2428
|
color: colorHex,
|
|
1725
2429
|
bold: isBold,
|
|
1726
2430
|
italics: isItalic,
|
|
2431
|
+
font: options.font,
|
|
2432
|
+
size: options.size,
|
|
1727
2433
|
shading: bgHex ? { type: import_docx.ShadingType.CLEAR, fill: bgHex } : void 0
|
|
1728
2434
|
})
|
|
1729
2435
|
);
|
|
@@ -1731,91 +2437,239 @@ async function convertInlinesToTextRuns(spans = [], baseDir = process.cwd()) {
|
|
|
1731
2437
|
}
|
|
1732
2438
|
runs.push(
|
|
1733
2439
|
new import_docx.TextRun({
|
|
1734
|
-
text: span.content
|
|
2440
|
+
text: span.content,
|
|
2441
|
+
font: options.font,
|
|
2442
|
+
size: options.size,
|
|
2443
|
+
color: options.color,
|
|
2444
|
+
bold: options.bold,
|
|
2445
|
+
italics: options.italics
|
|
1735
2446
|
})
|
|
1736
2447
|
);
|
|
1737
2448
|
}
|
|
1738
2449
|
return runs;
|
|
1739
2450
|
}
|
|
1740
2451
|
async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
1741
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
1742
|
-
const
|
|
2452
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2453
|
+
const resolved = resolveDocumentConfig(doc.metadata, config);
|
|
1743
2454
|
const docElements = [];
|
|
1744
|
-
|
|
2455
|
+
const themeProps = typeof resolved.theme === "object" ? resolved.theme : {};
|
|
2456
|
+
const primaryHex = (themeProps.primaryColor || "#33CDCF").replace("#", "");
|
|
2457
|
+
const primaryDarkHex = (themeProps.primaryDark || "#009DA0").replace("#", "");
|
|
2458
|
+
const textHex = (themeProps.textColor || "#0F172A").replace("#", "");
|
|
2459
|
+
const textMutedHex = (themeProps.textMuted || "#64748B").replace("#", "");
|
|
2460
|
+
const borderHex = (themeProps.borderColor || "#E2E8F0").replace("#", "");
|
|
2461
|
+
const cardBgHex = (themeProps.cardBackground || "#F8FAFC").replace("#", "");
|
|
2462
|
+
const defaultFont = themeProps.fontFamily ? themeProps.fontFamily.split(",")[0].replace(/['"]/g, "").trim() : "Segoe UI";
|
|
2463
|
+
if (resolved.title) {
|
|
1745
2464
|
docElements.push(
|
|
1746
2465
|
new import_docx.Paragraph({
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
2466
|
+
children: [
|
|
2467
|
+
new import_docx.TextRun({
|
|
2468
|
+
text: resolved.title,
|
|
2469
|
+
bold: true,
|
|
2470
|
+
size: 44,
|
|
2471
|
+
// 22pt
|
|
2472
|
+
color: textHex,
|
|
2473
|
+
font: defaultFont
|
|
2474
|
+
})
|
|
2475
|
+
],
|
|
2476
|
+
spacing: { before: 120, after: 80 }
|
|
1750
2477
|
})
|
|
1751
2478
|
);
|
|
1752
|
-
if (
|
|
2479
|
+
if (resolved.subtitle) {
|
|
1753
2480
|
docElements.push(
|
|
1754
2481
|
new import_docx.Paragraph({
|
|
1755
2482
|
children: [
|
|
1756
2483
|
new import_docx.TextRun({
|
|
1757
|
-
text:
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
size: 24
|
|
2484
|
+
text: resolved.subtitle,
|
|
2485
|
+
color: textMutedHex,
|
|
2486
|
+
size: 24,
|
|
1761
2487
|
// 12pt
|
|
2488
|
+
font: defaultFont
|
|
1762
2489
|
})
|
|
1763
2490
|
],
|
|
1764
|
-
spacing: { after:
|
|
2491
|
+
spacing: { before: 60, after: 120 }
|
|
1765
2492
|
})
|
|
1766
2493
|
);
|
|
1767
2494
|
}
|
|
1768
|
-
if (
|
|
2495
|
+
if (resolved.author || resolved.date || resolved.version || resolved.company) {
|
|
1769
2496
|
const metaParts = [];
|
|
1770
|
-
if (
|
|
1771
|
-
if (
|
|
2497
|
+
if (resolved.author) metaParts.push(`Author: ${resolved.author}`);
|
|
2498
|
+
if (resolved.version) metaParts.push(`Version: ${resolved.version}`);
|
|
2499
|
+
if (resolved.date) metaParts.push(`Date: ${resolved.date}`);
|
|
1772
2500
|
docElements.push(
|
|
1773
2501
|
new import_docx.Paragraph({
|
|
1774
2502
|
children: [
|
|
1775
2503
|
new import_docx.TextRun({
|
|
1776
|
-
text: metaParts.join("
|
|
1777
|
-
color:
|
|
1778
|
-
size:
|
|
1779
|
-
//
|
|
2504
|
+
text: metaParts.join(" "),
|
|
2505
|
+
color: textMutedHex,
|
|
2506
|
+
size: 18,
|
|
2507
|
+
// 9pt
|
|
2508
|
+
font: defaultFont
|
|
1780
2509
|
})
|
|
1781
2510
|
],
|
|
1782
|
-
spacing: { after:
|
|
2511
|
+
spacing: { before: 40, after: 240 },
|
|
1783
2512
|
border: {
|
|
1784
2513
|
bottom: {
|
|
1785
|
-
color:
|
|
1786
|
-
space:
|
|
2514
|
+
color: borderHex,
|
|
2515
|
+
space: 12,
|
|
1787
2516
|
style: import_docx.BorderStyle.SINGLE,
|
|
1788
|
-
size:
|
|
2517
|
+
size: 4
|
|
1789
2518
|
}
|
|
1790
2519
|
}
|
|
1791
2520
|
})
|
|
1792
2521
|
);
|
|
1793
2522
|
}
|
|
1794
2523
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
if (node.level === 5) headingLevel = import_docx.HeadingLevel.HEADING_5;
|
|
1802
|
-
if (node.level === 6) headingLevel = import_docx.HeadingLevel.HEADING_6;
|
|
1803
|
-
const runs = await convertInlinesToTextRuns(node.inlines, baseDir);
|
|
1804
|
-
docElements.push(
|
|
2524
|
+
if (resolved.toc) {
|
|
2525
|
+
const headingNodes = doc.nodes.filter(
|
|
2526
|
+
(n) => n.type === "heading" && typeof n.level === "number" && n.level >= 1 && n.level <= 3
|
|
2527
|
+
);
|
|
2528
|
+
if (headingNodes.length > 0) {
|
|
2529
|
+
const tocParagraphs = [
|
|
1805
2530
|
new import_docx.Paragraph({
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
2531
|
+
children: [
|
|
2532
|
+
new import_docx.TextRun({
|
|
2533
|
+
text: "TABLE OF CONTENTS",
|
|
2534
|
+
bold: true,
|
|
2535
|
+
size: 18,
|
|
2536
|
+
// 9pt
|
|
2537
|
+
color: textMutedHex,
|
|
2538
|
+
font: defaultFont
|
|
2539
|
+
})
|
|
2540
|
+
],
|
|
2541
|
+
spacing: { after: 120 },
|
|
2542
|
+
border: {
|
|
2543
|
+
bottom: {
|
|
2544
|
+
color: borderHex,
|
|
2545
|
+
space: 6,
|
|
2546
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
2547
|
+
size: 4
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
1809
2550
|
})
|
|
1810
|
-
|
|
2551
|
+
];
|
|
2552
|
+
for (const h of headingNodes) {
|
|
2553
|
+
const indentLeft = (h.level - 1) * 240;
|
|
2554
|
+
tocParagraphs.push(
|
|
2555
|
+
new import_docx.Paragraph({
|
|
2556
|
+
indent: { left: indentLeft },
|
|
2557
|
+
children: [
|
|
2558
|
+
new import_docx.TextRun({
|
|
2559
|
+
text: h.text,
|
|
2560
|
+
bold: h.level === 1,
|
|
2561
|
+
color: primaryDarkHex,
|
|
2562
|
+
size: h.level === 1 ? 21 : 20,
|
|
2563
|
+
font: defaultFont
|
|
2564
|
+
})
|
|
2565
|
+
],
|
|
2566
|
+
spacing: { before: 20, after: 20 }
|
|
2567
|
+
})
|
|
2568
|
+
);
|
|
2569
|
+
}
|
|
2570
|
+
const tocCard = new import_docx.Table({
|
|
2571
|
+
width: { size: 100, type: import_docx.WidthType.PERCENTAGE },
|
|
2572
|
+
columnWidths: [9e3],
|
|
2573
|
+
rows: [
|
|
2574
|
+
new import_docx.TableRow({
|
|
2575
|
+
children: [
|
|
2576
|
+
new import_docx.TableCell({
|
|
2577
|
+
width: { size: 9e3, type: import_docx.WidthType.DXA },
|
|
2578
|
+
shading: { fill: cardBgHex, type: import_docx.ShadingType.CLEAR },
|
|
2579
|
+
margins: { top: 140, bottom: 140, left: 180, right: 180 },
|
|
2580
|
+
borders: {
|
|
2581
|
+
top: { style: import_docx.BorderStyle.SINGLE, size: 4, color: borderHex },
|
|
2582
|
+
bottom: { style: import_docx.BorderStyle.SINGLE, size: 4, color: borderHex },
|
|
2583
|
+
left: { style: import_docx.BorderStyle.SINGLE, size: 4, color: borderHex },
|
|
2584
|
+
right: { style: import_docx.BorderStyle.SINGLE, size: 4, color: borderHex }
|
|
2585
|
+
},
|
|
2586
|
+
children: tocParagraphs
|
|
2587
|
+
})
|
|
2588
|
+
]
|
|
2589
|
+
})
|
|
2590
|
+
]
|
|
2591
|
+
});
|
|
2592
|
+
docElements.push(tocCard);
|
|
2593
|
+
docElements.push(new import_docx.Paragraph({ spacing: { after: 200 } }));
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
for (const node of doc.nodes) {
|
|
2597
|
+
if (node.type === "heading") {
|
|
2598
|
+
if (node.level === 1) {
|
|
2599
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2600
|
+
font: defaultFont,
|
|
2601
|
+
size: 34,
|
|
2602
|
+
// 17pt
|
|
2603
|
+
color: textHex,
|
|
2604
|
+
bold: true
|
|
2605
|
+
});
|
|
2606
|
+
docElements.push(
|
|
2607
|
+
new import_docx.Paragraph({
|
|
2608
|
+
heading: import_docx.HeadingLevel.HEADING_1,
|
|
2609
|
+
children: runs,
|
|
2610
|
+
spacing: { before: 360, after: 140 },
|
|
2611
|
+
border: {
|
|
2612
|
+
bottom: {
|
|
2613
|
+
color: primaryHex,
|
|
2614
|
+
space: 6,
|
|
2615
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
2616
|
+
size: 16
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
})
|
|
2620
|
+
);
|
|
2621
|
+
} else if (node.level === 2) {
|
|
2622
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2623
|
+
font: defaultFont,
|
|
2624
|
+
size: 26,
|
|
2625
|
+
// 13pt
|
|
2626
|
+
color: primaryDarkHex,
|
|
2627
|
+
bold: true
|
|
2628
|
+
});
|
|
2629
|
+
docElements.push(
|
|
2630
|
+
new import_docx.Paragraph({
|
|
2631
|
+
heading: import_docx.HeadingLevel.HEADING_2,
|
|
2632
|
+
children: runs,
|
|
2633
|
+
spacing: { before: 280, after: 100 },
|
|
2634
|
+
border: {
|
|
2635
|
+
bottom: {
|
|
2636
|
+
color: borderHex,
|
|
2637
|
+
space: 4,
|
|
2638
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
2639
|
+
size: 4
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
})
|
|
2643
|
+
);
|
|
2644
|
+
} else {
|
|
2645
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2646
|
+
font: defaultFont,
|
|
2647
|
+
size: 22,
|
|
2648
|
+
// 11pt
|
|
2649
|
+
color: textHex,
|
|
2650
|
+
bold: true
|
|
2651
|
+
});
|
|
2652
|
+
docElements.push(
|
|
2653
|
+
new import_docx.Paragraph({
|
|
2654
|
+
heading: node.level === 3 ? import_docx.HeadingLevel.HEADING_3 : import_docx.HeadingLevel.HEADING_4,
|
|
2655
|
+
children: runs,
|
|
2656
|
+
spacing: { before: 200, after: 80 }
|
|
2657
|
+
})
|
|
2658
|
+
);
|
|
2659
|
+
}
|
|
1811
2660
|
continue;
|
|
1812
2661
|
}
|
|
1813
2662
|
if (node.type === "paragraph") {
|
|
1814
|
-
const runs = await convertInlinesToTextRuns(node.inlines, baseDir
|
|
2663
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2664
|
+
font: defaultFont,
|
|
2665
|
+
size: 22,
|
|
2666
|
+
// 11pt
|
|
2667
|
+
color: "334155"
|
|
2668
|
+
});
|
|
1815
2669
|
docElements.push(
|
|
1816
2670
|
new import_docx.Paragraph({
|
|
1817
2671
|
children: runs,
|
|
1818
|
-
spacing: { before:
|
|
2672
|
+
spacing: { before: 40, after: 140, line: 280 }
|
|
1819
2673
|
})
|
|
1820
2674
|
);
|
|
1821
2675
|
continue;
|
|
@@ -1887,7 +2741,11 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1887
2741
|
bgFill = "F5F3FF";
|
|
1888
2742
|
title = "IMPORTANT";
|
|
1889
2743
|
}
|
|
1890
|
-
const runs = await convertInlinesToTextRuns(node.inlines, baseDir
|
|
2744
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2745
|
+
font: defaultFont,
|
|
2746
|
+
size: 21,
|
|
2747
|
+
color: "334155"
|
|
2748
|
+
});
|
|
1891
2749
|
const calloutTable = new import_docx.Table({
|
|
1892
2750
|
width: { size: 100, type: import_docx.WidthType.PERCENTAGE },
|
|
1893
2751
|
columnWidths: [9e3],
|
|
@@ -1902,7 +2760,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1902
2760
|
top: { style: import_docx.BorderStyle.NONE },
|
|
1903
2761
|
bottom: { style: import_docx.BorderStyle.NONE },
|
|
1904
2762
|
right: { style: import_docx.BorderStyle.NONE },
|
|
1905
|
-
left: { style: import_docx.BorderStyle.SINGLE, size:
|
|
2763
|
+
left: { style: import_docx.BorderStyle.SINGLE, size: 20, color: borderColor }
|
|
1906
2764
|
},
|
|
1907
2765
|
children: [
|
|
1908
2766
|
new import_docx.Paragraph({
|
|
@@ -1911,13 +2769,15 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1911
2769
|
text: `[${title}]`,
|
|
1912
2770
|
bold: true,
|
|
1913
2771
|
color: borderColor,
|
|
2772
|
+
font: defaultFont,
|
|
1914
2773
|
size: 20
|
|
1915
2774
|
})
|
|
1916
2775
|
],
|
|
1917
|
-
spacing: { after:
|
|
2776
|
+
spacing: { after: 40 }
|
|
1918
2777
|
}),
|
|
1919
2778
|
new import_docx.Paragraph({
|
|
1920
|
-
children: runs
|
|
2779
|
+
children: runs,
|
|
2780
|
+
spacing: { line: 270 }
|
|
1921
2781
|
})
|
|
1922
2782
|
]
|
|
1923
2783
|
})
|
|
@@ -1935,17 +2795,27 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1935
2795
|
if (lines.length > 0) {
|
|
1936
2796
|
for (const lineText of lines) {
|
|
1937
2797
|
const spans = parseInlineSpans(lineText.replace(/^>\s?/, "").trim());
|
|
1938
|
-
const lineRuns = await convertInlinesToTextRuns(spans, baseDir
|
|
2798
|
+
const lineRuns = await convertInlinesToTextRuns(spans, baseDir, {
|
|
2799
|
+
font: defaultFont,
|
|
2800
|
+
size: 21,
|
|
2801
|
+
color: "475569",
|
|
2802
|
+
italics: true
|
|
2803
|
+
});
|
|
1939
2804
|
quoteParagraphs.push(
|
|
1940
2805
|
new import_docx.Paragraph({
|
|
1941
2806
|
children: lineRuns,
|
|
1942
|
-
spacing: { before:
|
|
2807
|
+
spacing: { before: 20, after: 20, line: 260 }
|
|
1943
2808
|
})
|
|
1944
2809
|
);
|
|
1945
2810
|
}
|
|
1946
2811
|
} else {
|
|
1947
|
-
const runs = await convertInlinesToTextRuns(node.inlines, baseDir
|
|
1948
|
-
|
|
2812
|
+
const runs = await convertInlinesToTextRuns(node.inlines, baseDir, {
|
|
2813
|
+
font: defaultFont,
|
|
2814
|
+
size: 21,
|
|
2815
|
+
color: "475569",
|
|
2816
|
+
italics: true
|
|
2817
|
+
});
|
|
2818
|
+
quoteParagraphs.push(new import_docx.Paragraph({ children: runs, spacing: { line: 260 } }));
|
|
1949
2819
|
}
|
|
1950
2820
|
const quoteTable = new import_docx.Table({
|
|
1951
2821
|
width: { size: 100, type: import_docx.WidthType.PERCENTAGE },
|
|
@@ -1961,7 +2831,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1961
2831
|
top: { style: import_docx.BorderStyle.NONE },
|
|
1962
2832
|
bottom: { style: import_docx.BorderStyle.NONE },
|
|
1963
2833
|
right: { style: import_docx.BorderStyle.NONE },
|
|
1964
|
-
left: { style: import_docx.BorderStyle.SINGLE, size:
|
|
2834
|
+
left: { style: import_docx.BorderStyle.SINGLE, size: 16, color: primaryHex }
|
|
1965
2835
|
},
|
|
1966
2836
|
children: quoteParagraphs
|
|
1967
2837
|
})
|
|
@@ -1996,7 +2866,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
1996
2866
|
docElements.push(
|
|
1997
2867
|
new import_docx.Paragraph({
|
|
1998
2868
|
children: [
|
|
1999
|
-
new import_docx.TextRun({ text: "[Mermaid Diagram: " + (node.text || "").slice(0, 40) + "...]", bold: true, color:
|
|
2869
|
+
new import_docx.TextRun({ text: "[Mermaid Diagram: " + (node.text || "").slice(0, 40) + "...]", bold: true, color: primaryHex })
|
|
2000
2870
|
],
|
|
2001
2871
|
spacing: { before: 60, after: 60 }
|
|
2002
2872
|
})
|
|
@@ -2008,8 +2878,11 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2008
2878
|
const tableRows = [];
|
|
2009
2879
|
const numCols = ((_b = (_a = node.children[0]) == null ? void 0 : _a.children) == null ? void 0 : _b.length) || 1;
|
|
2010
2880
|
const colWidth = Math.floor(9e3 / numCols);
|
|
2011
|
-
for (
|
|
2881
|
+
for (let rowIdx = 0; rowIdx < node.children.length; rowIdx++) {
|
|
2882
|
+
const rowNode = node.children[rowIdx];
|
|
2012
2883
|
const cells = [];
|
|
2884
|
+
const isHeader = rowNode.isHeader;
|
|
2885
|
+
const rowBg = isHeader ? "F1F5F9" : rowIdx % 2 === 0 ? "FFFFFF" : "F8FAFC";
|
|
2013
2886
|
if (rowNode.children) {
|
|
2014
2887
|
for (let colIdx = 0; colIdx < rowNode.children.length; colIdx++) {
|
|
2015
2888
|
const cellNode = rowNode.children[colIdx];
|
|
@@ -2017,22 +2890,27 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2017
2890
|
let alignment = import_docx.AlignmentType.LEFT;
|
|
2018
2891
|
if (align === "center") alignment = import_docx.AlignmentType.CENTER;
|
|
2019
2892
|
if (align === "right") alignment = import_docx.AlignmentType.RIGHT;
|
|
2020
|
-
const runs = await convertInlinesToTextRuns(cellNode.inlines, baseDir
|
|
2893
|
+
const runs = await convertInlinesToTextRuns(cellNode.inlines, baseDir, {
|
|
2894
|
+
font: defaultFont,
|
|
2895
|
+
size: 20,
|
|
2896
|
+
color: isHeader ? "0F172A" : "334155",
|
|
2897
|
+
bold: isHeader
|
|
2898
|
+
});
|
|
2021
2899
|
cells.push(
|
|
2022
2900
|
new import_docx.TableCell({
|
|
2023
2901
|
width: { size: colWidth, type: import_docx.WidthType.DXA },
|
|
2024
|
-
shading:
|
|
2025
|
-
margins: { top: 100, bottom: 100, left:
|
|
2902
|
+
shading: { fill: rowBg, type: import_docx.ShadingType.CLEAR },
|
|
2903
|
+
margins: { top: 100, bottom: 100, left: 140, right: 140 },
|
|
2026
2904
|
borders: {
|
|
2027
|
-
top: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "
|
|
2028
|
-
bottom: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "CBD5E1" },
|
|
2029
|
-
left: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "
|
|
2030
|
-
right: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "
|
|
2905
|
+
top: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "E2E8F0" },
|
|
2906
|
+
bottom: { style: import_docx.BorderStyle.SINGLE, size: isHeader ? 8 : 4, color: isHeader ? "CBD5E1" : "E2E8F0" },
|
|
2907
|
+
left: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "E2E8F0" },
|
|
2908
|
+
right: { style: import_docx.BorderStyle.SINGLE, size: 4, color: "E2E8F0" }
|
|
2031
2909
|
},
|
|
2032
2910
|
children: [
|
|
2033
2911
|
new import_docx.Paragraph({
|
|
2034
2912
|
alignment,
|
|
2035
|
-
children:
|
|
2913
|
+
children: runs
|
|
2036
2914
|
})
|
|
2037
2915
|
]
|
|
2038
2916
|
})
|
|
@@ -2041,7 +2919,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2041
2919
|
}
|
|
2042
2920
|
tableRows.push(
|
|
2043
2921
|
new import_docx.TableRow({
|
|
2044
|
-
tableHeader:
|
|
2922
|
+
tableHeader: isHeader,
|
|
2045
2923
|
children: cells
|
|
2046
2924
|
})
|
|
2047
2925
|
);
|
|
@@ -2057,7 +2935,11 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2057
2935
|
}
|
|
2058
2936
|
if (node.type === "list" && node.children) {
|
|
2059
2937
|
for (const item of node.children) {
|
|
2060
|
-
const runs = await convertInlinesToTextRuns(item.inlines, baseDir
|
|
2938
|
+
const runs = await convertInlinesToTextRuns(item.inlines, baseDir, {
|
|
2939
|
+
font: defaultFont,
|
|
2940
|
+
size: 21,
|
|
2941
|
+
color: "334155"
|
|
2942
|
+
});
|
|
2061
2943
|
let prefix = "";
|
|
2062
2944
|
if (item.checked !== void 0) {
|
|
2063
2945
|
prefix = item.checked ? "[X] " : "[ ] ";
|
|
@@ -2069,7 +2951,7 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2069
2951
|
...prefix ? [new import_docx.TextRun({ text: prefix, bold: true, font: "Consolas" })] : [],
|
|
2070
2952
|
...runs
|
|
2071
2953
|
],
|
|
2072
|
-
spacing: { before:
|
|
2954
|
+
spacing: { before: 20, after: 20, line: 260 }
|
|
2073
2955
|
})
|
|
2074
2956
|
);
|
|
2075
2957
|
}
|
|
@@ -2144,88 +3026,258 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2144
3026
|
continue;
|
|
2145
3027
|
}
|
|
2146
3028
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
3029
|
+
if (resolved.signatures && resolved.signatures.items.length > 0) {
|
|
3030
|
+
const sig = resolved.signatures;
|
|
3031
|
+
const numItems = sig.items.length;
|
|
3032
|
+
const contentWidth = Math.max(
|
|
3033
|
+
1e3,
|
|
3034
|
+
resolved.paperDimensions.widthTwip - resolved.margins.leftTwip - resolved.margins.rightTwip
|
|
3035
|
+
);
|
|
3036
|
+
docElements.push(new import_docx.Paragraph({ spacing: { before: sig.spacingBeforeTwip } }));
|
|
3037
|
+
const sigCells = [];
|
|
3038
|
+
const colWidths = [];
|
|
3039
|
+
if (numItems === 1) {
|
|
3040
|
+
const cardWidth = Math.min(3400, Math.floor(contentWidth * 0.42));
|
|
3041
|
+
const spacerWidth = contentWidth - cardWidth;
|
|
3042
|
+
const cardCell = await buildDocxSignatureCell(sig.items[0], sig, cardWidth, defaultFont, baseDir);
|
|
3043
|
+
if (sig.align === "left") {
|
|
3044
|
+
colWidths.push(cardWidth, spacerWidth);
|
|
3045
|
+
sigCells.push(cardCell, createEmptyDocxCell(spacerWidth));
|
|
3046
|
+
} else if (sig.align === "center") {
|
|
3047
|
+
const sideWidth = Math.floor(spacerWidth / 2);
|
|
3048
|
+
colWidths.push(sideWidth, cardWidth, sideWidth);
|
|
3049
|
+
sigCells.push(createEmptyDocxCell(sideWidth), cardCell, createEmptyDocxCell(sideWidth));
|
|
3050
|
+
} else {
|
|
3051
|
+
colWidths.push(spacerWidth, cardWidth);
|
|
3052
|
+
sigCells.push(createEmptyDocxCell(spacerWidth), cardCell);
|
|
3053
|
+
}
|
|
3054
|
+
} else {
|
|
3055
|
+
const colWidth = Math.floor(contentWidth / numItems);
|
|
3056
|
+
for (let i = 0; i < numItems; i++) {
|
|
3057
|
+
colWidths.push(colWidth);
|
|
3058
|
+
const cell = await buildDocxSignatureCell(sig.items[i], sig, colWidth, defaultFont, baseDir);
|
|
3059
|
+
sigCells.push(cell);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
const sigTable = new import_docx.Table({
|
|
3063
|
+
width: { size: 100, type: import_docx.WidthType.PERCENTAGE },
|
|
3064
|
+
columnWidths: colWidths,
|
|
3065
|
+
borders: {
|
|
3066
|
+
top: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" },
|
|
3067
|
+
bottom: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" },
|
|
3068
|
+
left: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" },
|
|
3069
|
+
right: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" },
|
|
3070
|
+
insideHorizontal: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" },
|
|
3071
|
+
insideVertical: { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" }
|
|
3072
|
+
},
|
|
3073
|
+
rows: [
|
|
3074
|
+
new import_docx.TableRow({
|
|
3075
|
+
cantSplit: true,
|
|
3076
|
+
children: sigCells
|
|
3077
|
+
})
|
|
3078
|
+
]
|
|
3079
|
+
});
|
|
3080
|
+
docElements.push(sigTable);
|
|
3081
|
+
}
|
|
3082
|
+
const contentWidthTwip = Math.max(
|
|
3083
|
+
1e3,
|
|
3084
|
+
resolved.paperDimensions.widthTwip - resolved.margins.leftTwip - resolved.margins.rightTwip
|
|
3085
|
+
);
|
|
3086
|
+
const centerPos = Math.round(contentWidthTwip / 2);
|
|
3087
|
+
const rightPos = contentWidthTwip;
|
|
3088
|
+
const headerRuns = [];
|
|
3089
|
+
if ((_d = resolved.header) == null ? void 0 : _d.left) {
|
|
3090
|
+
headerRuns.push(
|
|
3091
|
+
new import_docx.TextRun({
|
|
3092
|
+
text: resolved.header.left.text,
|
|
3093
|
+
color: resolved.header.left.color.replace("#", ""),
|
|
3094
|
+
size: (resolved.header.left.fontSize || 9) * 2,
|
|
3095
|
+
font: resolved.header.left.fontFamily || defaultFont,
|
|
3096
|
+
bold: resolved.header.left.bold,
|
|
3097
|
+
italics: resolved.header.left.italic
|
|
3098
|
+
})
|
|
3099
|
+
);
|
|
3100
|
+
}
|
|
3101
|
+
headerRuns.push(new import_docx.TextRun({ text: " " }));
|
|
3102
|
+
if ((_e = resolved.header) == null ? void 0 : _e.center) {
|
|
3103
|
+
headerRuns.push(
|
|
3104
|
+
new import_docx.TextRun({
|
|
3105
|
+
text: resolved.header.center.text,
|
|
3106
|
+
color: resolved.header.center.color.replace("#", ""),
|
|
3107
|
+
size: (resolved.header.center.fontSize || 9) * 2,
|
|
3108
|
+
font: resolved.header.center.fontFamily || defaultFont,
|
|
3109
|
+
bold: resolved.header.center.bold,
|
|
3110
|
+
italics: resolved.header.center.italic
|
|
3111
|
+
})
|
|
3112
|
+
);
|
|
3113
|
+
}
|
|
3114
|
+
headerRuns.push(new import_docx.TextRun({ text: " " }));
|
|
3115
|
+
if ((_f = resolved.header) == null ? void 0 : _f.right) {
|
|
3116
|
+
headerRuns.push(
|
|
3117
|
+
new import_docx.TextRun({
|
|
3118
|
+
text: resolved.header.right.text,
|
|
3119
|
+
color: resolved.header.right.color.replace("#", ""),
|
|
3120
|
+
size: (resolved.header.right.fontSize || 9) * 2,
|
|
3121
|
+
font: resolved.header.right.fontFamily || defaultFont,
|
|
3122
|
+
bold: resolved.header.right.bold,
|
|
3123
|
+
italics: resolved.header.right.italic
|
|
3124
|
+
})
|
|
3125
|
+
);
|
|
3126
|
+
}
|
|
3127
|
+
const docHeader = resolved.header ? new import_docx.Header({
|
|
2154
3128
|
children: [
|
|
2155
3129
|
new import_docx.Paragraph({
|
|
2156
|
-
tabStops:
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
3130
|
+
tabStops: [
|
|
3131
|
+
{
|
|
3132
|
+
type: import_docx.TabStopType.CENTER,
|
|
3133
|
+
position: centerPos
|
|
3134
|
+
},
|
|
3135
|
+
{
|
|
3136
|
+
type: import_docx.TabStopType.RIGHT,
|
|
3137
|
+
position: rightPos
|
|
3138
|
+
}
|
|
3139
|
+
],
|
|
3140
|
+
border: resolved.header.divider ? {
|
|
3141
|
+
bottom: {
|
|
3142
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
3143
|
+
size: 4,
|
|
3144
|
+
space: 6,
|
|
3145
|
+
color: (resolved.header.dividerColor || "#CBD5E1").replace("#", "")
|
|
3146
|
+
}
|
|
3147
|
+
} : void 0,
|
|
3148
|
+
children: headerRuns,
|
|
3149
|
+
spacing: { after: 120 }
|
|
3150
|
+
})
|
|
3151
|
+
]
|
|
3152
|
+
}) : void 0;
|
|
3153
|
+
const footerRuns = [];
|
|
3154
|
+
if ((_g = resolved.footer) == null ? void 0 : _g.left) {
|
|
3155
|
+
footerRuns.push(
|
|
3156
|
+
new import_docx.TextRun({
|
|
3157
|
+
text: resolved.footer.left.text,
|
|
3158
|
+
color: resolved.footer.left.color.replace("#", ""),
|
|
3159
|
+
size: (resolved.footer.left.fontSize || 9) * 2,
|
|
3160
|
+
font: resolved.footer.left.fontFamily || defaultFont,
|
|
3161
|
+
bold: resolved.footer.left.bold,
|
|
3162
|
+
italics: resolved.footer.left.italic
|
|
3163
|
+
})
|
|
3164
|
+
);
|
|
3165
|
+
}
|
|
3166
|
+
footerRuns.push(new import_docx.TextRun({ text: " " }));
|
|
3167
|
+
if ((_h = resolved.footer) == null ? void 0 : _h.center) {
|
|
3168
|
+
footerRuns.push(
|
|
3169
|
+
new import_docx.TextRun({
|
|
3170
|
+
text: resolved.footer.center.text,
|
|
3171
|
+
color: resolved.footer.center.color.replace("#", ""),
|
|
3172
|
+
size: (resolved.footer.center.fontSize || 9) * 2,
|
|
3173
|
+
font: resolved.footer.center.fontFamily || defaultFont,
|
|
3174
|
+
bold: resolved.footer.center.bold,
|
|
3175
|
+
italics: resolved.footer.center.italic
|
|
3176
|
+
})
|
|
3177
|
+
);
|
|
3178
|
+
}
|
|
3179
|
+
footerRuns.push(new import_docx.TextRun({ text: " " }));
|
|
3180
|
+
if ((_i = resolved.footer) == null ? void 0 : _i.right) {
|
|
3181
|
+
const rZone = resolved.footer.right;
|
|
3182
|
+
const rColor = rZone.color.replace("#", "");
|
|
3183
|
+
const rSize = (rZone.fontSize || 9) * 2;
|
|
3184
|
+
const rFont = rZone.fontFamily || defaultFont;
|
|
3185
|
+
const rBold = rZone.bold;
|
|
3186
|
+
const rItalics = rZone.italic;
|
|
3187
|
+
if (rZone.text.includes("{page}") || rZone.text.includes("{pages}")) {
|
|
3188
|
+
const parts = rZone.text.split(/(\{page\}|\{pages\})/gi);
|
|
3189
|
+
for (const part of parts) {
|
|
3190
|
+
if (part.toLowerCase() === "{page}") {
|
|
3191
|
+
footerRuns.push(
|
|
2160
3192
|
new import_docx.TextRun({
|
|
2161
|
-
|
|
2162
|
-
color:
|
|
2163
|
-
size:
|
|
3193
|
+
children: [import_docx.PageNumber.CURRENT],
|
|
3194
|
+
color: rColor,
|
|
3195
|
+
size: rSize,
|
|
3196
|
+
font: rFont,
|
|
3197
|
+
bold: rBold,
|
|
3198
|
+
italics: rItalics
|
|
2164
3199
|
})
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
new import_docx.TextRun({ text: " ", color: "94A3B8", size: 18 }),
|
|
3200
|
+
);
|
|
3201
|
+
} else if (part.toLowerCase() === "{pages}") {
|
|
3202
|
+
footerRuns.push(
|
|
2169
3203
|
new import_docx.TextRun({
|
|
2170
|
-
|
|
2171
|
-
color:
|
|
2172
|
-
size:
|
|
3204
|
+
children: [import_docx.PageNumber.TOTAL_PAGES],
|
|
3205
|
+
color: rColor,
|
|
3206
|
+
size: rSize,
|
|
3207
|
+
font: rFont,
|
|
3208
|
+
bold: rBold,
|
|
3209
|
+
italics: rItalics
|
|
2173
3210
|
})
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
new import_docx.TextRun({
|
|
2178
|
-
text: headerObj.left || headerObj.center ? " " : "",
|
|
2179
|
-
color: "94A3B8",
|
|
2180
|
-
size: 18
|
|
2181
|
-
}),
|
|
3211
|
+
);
|
|
3212
|
+
} else if (part) {
|
|
3213
|
+
footerRuns.push(
|
|
2182
3214
|
new import_docx.TextRun({
|
|
2183
|
-
text:
|
|
2184
|
-
color:
|
|
2185
|
-
size:
|
|
3215
|
+
text: part,
|
|
3216
|
+
color: rColor,
|
|
3217
|
+
size: rSize,
|
|
3218
|
+
font: rFont,
|
|
3219
|
+
bold: rBold,
|
|
3220
|
+
italics: rItalics
|
|
2186
3221
|
})
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
3222
|
+
);
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
} else {
|
|
3226
|
+
footerRuns.push(
|
|
3227
|
+
new import_docx.TextRun({
|
|
3228
|
+
text: rZone.text,
|
|
3229
|
+
color: rColor,
|
|
3230
|
+
size: rSize,
|
|
3231
|
+
font: rFont,
|
|
3232
|
+
bold: rBold,
|
|
3233
|
+
italics: rItalics
|
|
3234
|
+
})
|
|
3235
|
+
);
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
const docFooter = resolved.footer ? new import_docx.Footer({
|
|
2193
3239
|
children: [
|
|
2194
3240
|
new import_docx.Paragraph({
|
|
2195
|
-
tabStops:
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
3241
|
+
tabStops: [
|
|
3242
|
+
{
|
|
3243
|
+
type: import_docx.TabStopType.CENTER,
|
|
3244
|
+
position: centerPos
|
|
3245
|
+
},
|
|
3246
|
+
{
|
|
3247
|
+
type: import_docx.TabStopType.RIGHT,
|
|
3248
|
+
position: rightPos
|
|
3249
|
+
}
|
|
3250
|
+
],
|
|
3251
|
+
border: resolved.footer.divider ? {
|
|
3252
|
+
top: {
|
|
3253
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
3254
|
+
size: 4,
|
|
3255
|
+
space: 6,
|
|
3256
|
+
color: (resolved.footer.dividerColor || "#CBD5E1").replace("#", "")
|
|
3257
|
+
}
|
|
3258
|
+
} : void 0,
|
|
3259
|
+
children: footerRuns,
|
|
3260
|
+
spacing: { before: 120 }
|
|
2212
3261
|
})
|
|
2213
3262
|
]
|
|
2214
3263
|
}) : void 0;
|
|
2215
|
-
const
|
|
2216
|
-
const bottomMargin = parseMarginToTwip(((_f = metadata.margins) == null ? void 0 : _f.bottom) || ((_g = config.margins) == null ? void 0 : _g.bottom), 1440);
|
|
2217
|
-
const leftMargin = parseMarginToTwip(((_h = metadata.margins) == null ? void 0 : _h.left) || ((_i = config.margins) == null ? void 0 : _i.left), 1440);
|
|
2218
|
-
const rightMargin = parseMarginToTwip(((_j = metadata.margins) == null ? void 0 : _j.right) || ((_k = config.margins) == null ? void 0 : _k.right), 1440);
|
|
2219
|
-
const isLandscape = (metadata.orientation || config.orientation) === "landscape";
|
|
3264
|
+
const isLandscape = resolved.orientation === "landscape";
|
|
2220
3265
|
const document = new import_docx.Document({
|
|
2221
3266
|
styles: {
|
|
2222
3267
|
default: {
|
|
2223
3268
|
document: {
|
|
2224
3269
|
run: {
|
|
2225
|
-
font:
|
|
2226
|
-
size:
|
|
2227
|
-
//
|
|
2228
|
-
color:
|
|
3270
|
+
font: defaultFont,
|
|
3271
|
+
size: 21,
|
|
3272
|
+
// 10.5pt
|
|
3273
|
+
color: textHex
|
|
3274
|
+
},
|
|
3275
|
+
paragraph: {
|
|
3276
|
+
spacing: {
|
|
3277
|
+
line: 276,
|
|
3278
|
+
// 1.15 line spacing
|
|
3279
|
+
after: 140
|
|
3280
|
+
}
|
|
2229
3281
|
}
|
|
2230
3282
|
}
|
|
2231
3283
|
}
|
|
@@ -2235,13 +3287,15 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2235
3287
|
properties: {
|
|
2236
3288
|
page: {
|
|
2237
3289
|
size: {
|
|
3290
|
+
width: resolved.paperDimensions.widthTwip,
|
|
3291
|
+
height: resolved.paperDimensions.heightTwip,
|
|
2238
3292
|
orientation: isLandscape ? import_docx.PageOrientation.LANDSCAPE : import_docx.PageOrientation.PORTRAIT
|
|
2239
3293
|
},
|
|
2240
3294
|
margin: {
|
|
2241
|
-
top:
|
|
2242
|
-
bottom:
|
|
2243
|
-
left:
|
|
2244
|
-
right:
|
|
3295
|
+
top: resolved.margins.topTwip,
|
|
3296
|
+
bottom: resolved.margins.bottomTwip,
|
|
3297
|
+
left: resolved.margins.leftTwip,
|
|
3298
|
+
right: resolved.margins.rightTwip,
|
|
2245
3299
|
header: 720,
|
|
2246
3300
|
footer: 720
|
|
2247
3301
|
}
|
|
@@ -2255,153 +3309,139 @@ async function buildDocxDocument(doc, config, baseDir = process.cwd()) {
|
|
|
2255
3309
|
});
|
|
2256
3310
|
return await import_docx.Packer.toBuffer(document);
|
|
2257
3311
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
];
|
|
2277
|
-
var DEFAULT_CONFIG = {
|
|
2278
|
-
to: ["docx", "pdf"],
|
|
2279
|
-
outputDir: void 0,
|
|
2280
|
-
theme: "default",
|
|
2281
|
-
css: void 0,
|
|
2282
|
-
orientation: "portrait",
|
|
2283
|
-
paperSize: "A4",
|
|
2284
|
-
margins: {
|
|
2285
|
-
top: "2.5cm",
|
|
2286
|
-
bottom: "2.5cm",
|
|
2287
|
-
left: "2.5cm",
|
|
2288
|
-
right: "2.5cm"
|
|
2289
|
-
},
|
|
2290
|
-
header: void 0,
|
|
2291
|
-
footer: {
|
|
2292
|
-
right: "Page {page} of {pages}"
|
|
2293
|
-
},
|
|
2294
|
-
toc: false,
|
|
2295
|
-
watermark: void 0,
|
|
2296
|
-
embedImages: true,
|
|
2297
|
-
metadata: void 0,
|
|
2298
|
-
watch: false,
|
|
2299
|
-
serve: false,
|
|
2300
|
-
port: 4e3,
|
|
2301
|
-
open: false,
|
|
2302
|
-
bundleHtml: true,
|
|
2303
|
-
syntaxTheme: "github-dark"
|
|
2304
|
-
};
|
|
2305
|
-
function discoverConfigFile(startDir) {
|
|
2306
|
-
const dirsToCheck = [];
|
|
2307
|
-
let curr = path5.resolve(startDir);
|
|
2308
|
-
while (curr) {
|
|
2309
|
-
dirsToCheck.push(curr);
|
|
2310
|
-
const parent = path5.dirname(curr);
|
|
2311
|
-
if (parent === curr) break;
|
|
2312
|
-
curr = parent;
|
|
2313
|
-
}
|
|
2314
|
-
const cwd = path5.resolve(process.cwd());
|
|
2315
|
-
if (!dirsToCheck.includes(cwd)) {
|
|
2316
|
-
dirsToCheck.push(cwd);
|
|
2317
|
-
}
|
|
2318
|
-
for (const dir of dirsToCheck) {
|
|
2319
|
-
for (const filename of DEFAULT_CONFIG_FILENAMES) {
|
|
2320
|
-
const candidate = path5.join(dir, filename);
|
|
2321
|
-
if (fs5.existsSync(candidate) && fs5.statSync(candidate).isFile()) {
|
|
2322
|
-
return candidate;
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
3312
|
+
async function buildDocxSignatureCell(item, sig, widthDxa, defaultFont, baseDir) {
|
|
3313
|
+
const cellParagraphs = [];
|
|
3314
|
+
if (item.title) {
|
|
3315
|
+
cellParagraphs.push(
|
|
3316
|
+
new import_docx.Paragraph({
|
|
3317
|
+
children: [
|
|
3318
|
+
new import_docx.TextRun({
|
|
3319
|
+
text: item.title,
|
|
3320
|
+
font: defaultFont,
|
|
3321
|
+
size: 18,
|
|
3322
|
+
// 9pt
|
|
3323
|
+
color: sig.titleColor.replace("#", ""),
|
|
3324
|
+
bold: true
|
|
3325
|
+
})
|
|
3326
|
+
],
|
|
3327
|
+
spacing: { after: 60 }
|
|
3328
|
+
})
|
|
3329
|
+
);
|
|
2325
3330
|
}
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
3331
|
+
if (item.image) {
|
|
3332
|
+
const resolvedImg = await resolveImage(item.image, baseDir);
|
|
3333
|
+
if (resolvedImg) {
|
|
3334
|
+
cellParagraphs.push(
|
|
3335
|
+
new import_docx.Paragraph({
|
|
3336
|
+
children: [
|
|
3337
|
+
new import_docx.ImageRun({
|
|
3338
|
+
data: resolvedImg.buffer,
|
|
3339
|
+
transformation: {
|
|
3340
|
+
width: 140,
|
|
3341
|
+
height: 60
|
|
3342
|
+
},
|
|
3343
|
+
type: "png"
|
|
3344
|
+
})
|
|
3345
|
+
],
|
|
3346
|
+
spacing: { before: 40, after: 40 }
|
|
3347
|
+
})
|
|
3348
|
+
);
|
|
3349
|
+
} else {
|
|
3350
|
+
cellParagraphs.push(new import_docx.Paragraph({ spacing: { before: 240, after: 240 } }));
|
|
2339
3351
|
}
|
|
2340
3352
|
} else {
|
|
2341
|
-
|
|
3353
|
+
cellParagraphs.push(new import_docx.Paragraph({ spacing: { before: 240, after: 240 } }));
|
|
2342
3354
|
}
|
|
2343
|
-
if (
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
3355
|
+
if (sig.style === "line") {
|
|
3356
|
+
cellParagraphs.push(
|
|
3357
|
+
new import_docx.Paragraph({
|
|
3358
|
+
border: {
|
|
3359
|
+
bottom: {
|
|
3360
|
+
style: import_docx.BorderStyle.SINGLE,
|
|
3361
|
+
size: 6,
|
|
3362
|
+
space: 2,
|
|
3363
|
+
color: sig.borderColor.replace("#", "")
|
|
3364
|
+
}
|
|
3365
|
+
},
|
|
3366
|
+
spacing: { after: 60 }
|
|
3367
|
+
})
|
|
3368
|
+
);
|
|
2348
3369
|
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
}
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
} catch (err) {
|
|
2379
|
-
throw new Error(
|
|
2380
|
-
`Failed to parse configuration file at ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
3370
|
+
cellParagraphs.push(
|
|
3371
|
+
new import_docx.Paragraph({
|
|
3372
|
+
children: [
|
|
3373
|
+
new import_docx.TextRun({
|
|
3374
|
+
text: item.name,
|
|
3375
|
+
font: defaultFont,
|
|
3376
|
+
size: 21,
|
|
3377
|
+
// 10.5pt
|
|
3378
|
+
bold: true,
|
|
3379
|
+
color: sig.nameColor.replace("#", "")
|
|
3380
|
+
})
|
|
3381
|
+
],
|
|
3382
|
+
spacing: { before: sig.style === "line" ? 40 : 20, after: 20 }
|
|
3383
|
+
})
|
|
3384
|
+
);
|
|
3385
|
+
if (item.role) {
|
|
3386
|
+
cellParagraphs.push(
|
|
3387
|
+
new import_docx.Paragraph({
|
|
3388
|
+
children: [
|
|
3389
|
+
new import_docx.TextRun({
|
|
3390
|
+
text: item.role,
|
|
3391
|
+
font: defaultFont,
|
|
3392
|
+
size: 18,
|
|
3393
|
+
// 9pt
|
|
3394
|
+
color: sig.roleColor.replace("#", "")
|
|
3395
|
+
})
|
|
3396
|
+
],
|
|
3397
|
+
spacing: { after: 20 }
|
|
3398
|
+
})
|
|
2381
3399
|
);
|
|
2382
3400
|
}
|
|
2383
|
-
if (
|
|
2384
|
-
|
|
3401
|
+
if (item.date) {
|
|
3402
|
+
cellParagraphs.push(
|
|
3403
|
+
new import_docx.Paragraph({
|
|
3404
|
+
children: [
|
|
3405
|
+
new import_docx.TextRun({
|
|
3406
|
+
text: `Date: ${item.date}`,
|
|
3407
|
+
font: defaultFont,
|
|
3408
|
+
size: 17,
|
|
3409
|
+
// 8.5pt
|
|
3410
|
+
color: sig.roleColor.replace("#", "")
|
|
3411
|
+
})
|
|
3412
|
+
],
|
|
3413
|
+
spacing: { after: 20 }
|
|
3414
|
+
})
|
|
3415
|
+
);
|
|
2385
3416
|
}
|
|
2386
|
-
const
|
|
2387
|
-
const
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
3417
|
+
const isBox = sig.style === "box";
|
|
3418
|
+
const boxBorder = { style: import_docx.BorderStyle.SINGLE, size: 4, color: sig.borderColor.replace("#", "") };
|
|
3419
|
+
const noneBorder = { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" };
|
|
3420
|
+
return new import_docx.TableCell({
|
|
3421
|
+
width: { size: widthDxa, type: import_docx.WidthType.DXA },
|
|
3422
|
+
shading: isBox ? { fill: "F8FAFC", type: import_docx.ShadingType.CLEAR } : void 0,
|
|
3423
|
+
margins: isBox ? { top: 140, bottom: 140, left: 160, right: 160 } : { top: 60, bottom: 60, left: 60, right: 60 },
|
|
3424
|
+
borders: {
|
|
3425
|
+
top: isBox ? boxBorder : noneBorder,
|
|
3426
|
+
bottom: isBox ? boxBorder : noneBorder,
|
|
3427
|
+
left: isBox ? boxBorder : noneBorder,
|
|
3428
|
+
right: isBox ? boxBorder : noneBorder
|
|
2393
3429
|
},
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
3430
|
+
children: cellParagraphs
|
|
3431
|
+
});
|
|
3432
|
+
}
|
|
3433
|
+
function createEmptyDocxCell(widthDxa) {
|
|
3434
|
+
const noneBorder = { style: import_docx.BorderStyle.NONE, size: 0, color: "auto" };
|
|
3435
|
+
return new import_docx.TableCell({
|
|
3436
|
+
width: { size: widthDxa, type: import_docx.WidthType.DXA },
|
|
3437
|
+
borders: {
|
|
3438
|
+
top: noneBorder,
|
|
3439
|
+
bottom: noneBorder,
|
|
3440
|
+
left: noneBorder,
|
|
3441
|
+
right: noneBorder
|
|
3442
|
+
},
|
|
3443
|
+
children: [new import_docx.Paragraph({})]
|
|
3444
|
+
});
|
|
2405
3445
|
}
|
|
2406
3446
|
|
|
2407
3447
|
// src/core/engine.ts
|
|
@@ -2526,7 +3566,7 @@ try {
|
|
|
2526
3566
|
}
|
|
2527
3567
|
} catch {
|
|
2528
3568
|
}
|
|
2529
|
-
var FALLBACK_VERSION = "0.
|
|
3569
|
+
var FALLBACK_VERSION = "0.3.0";
|
|
2530
3570
|
function readVersionFromPackageJson(fromDir) {
|
|
2531
3571
|
let currentDir = fromDir;
|
|
2532
3572
|
for (let i = 0; i < 6; i++) {
|
|
@@ -2564,10 +3604,17 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
2564
3604
|
0 && (module.exports = {
|
|
2565
3605
|
DEFAULT_CONFIG,
|
|
2566
3606
|
MARKFORGE_VERSION,
|
|
3607
|
+
Orientation,
|
|
3608
|
+
OutputFormat,
|
|
3609
|
+
PAPER_DIMENSIONS_TWIP,
|
|
3610
|
+
PaperSizeEnum,
|
|
2567
3611
|
SYNTAX_COLORS,
|
|
3612
|
+
SyntaxTheme,
|
|
2568
3613
|
THEMES,
|
|
2569
|
-
|
|
3614
|
+
THEME_CORPORATE,
|
|
2570
3615
|
THEME_DEFAULT,
|
|
3616
|
+
Theme,
|
|
3617
|
+
WatermarkPosition,
|
|
2571
3618
|
buildDocxDocument,
|
|
2572
3619
|
buildHtmlDocument,
|
|
2573
3620
|
buildPdfDocument,
|
|
@@ -2576,6 +3623,7 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
2576
3623
|
escapeHtml,
|
|
2577
3624
|
findChromeExecutable,
|
|
2578
3625
|
formatServerTimestamp,
|
|
3626
|
+
generateThemeCss,
|
|
2579
3627
|
getMarkforgeVersion,
|
|
2580
3628
|
getMimeType,
|
|
2581
3629
|
highlightCodeToHtml,
|
|
@@ -2583,11 +3631,17 @@ function getMarkforgeVersion(fromDir = getPackageDir()) {
|
|
|
2583
3631
|
inlineHtmlImages,
|
|
2584
3632
|
loadConfig,
|
|
2585
3633
|
markforge,
|
|
3634
|
+
normalizeHeaderFooter,
|
|
3635
|
+
normalizeHeaderFooterSlot,
|
|
3636
|
+
normalizeSignatures,
|
|
3637
|
+
normalizeWatermark,
|
|
2586
3638
|
parseInlineSpans,
|
|
2587
3639
|
parseMarginToTwip,
|
|
2588
3640
|
parseMarkdownDocument,
|
|
2589
3641
|
renderInlinesToHtml,
|
|
2590
3642
|
renderMermaidToPng,
|
|
3643
|
+
replaceDocumentTokens,
|
|
3644
|
+
resolveDocumentConfig,
|
|
2591
3645
|
resolveImage,
|
|
2592
3646
|
slugify,
|
|
2593
3647
|
tokenizeCodeLine
|