docgen-utils 1.0.17 → 1.0.18
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/dist/bundle.js +441 -176
- package/dist/bundle.min.js +233 -233
- package/dist/cli.js +350 -151
- package/dist/packages/cli/commands/export-docs.d.ts +2 -3
- package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-docs.js +108 -101
- package/dist/packages/cli/commands/export-docs.js.map +1 -1
- package/dist/packages/cli/commands/export-slides.d.ts +10 -0
- package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-slides.js +41 -26
- package/dist/packages/cli/commands/export-slides.js.map +1 -1
- package/dist/packages/docs/convert.d.ts.map +1 -1
- package/dist/packages/docs/convert.js +14 -10
- package/dist/packages/docs/convert.js.map +1 -1
- package/dist/packages/docs/import-docx.d.ts.map +1 -1
- package/dist/packages/docs/import-docx.js +256 -11
- package/dist/packages/docs/import-docx.js.map +1 -1
- package/dist/packages/shared/fetch-with-proxy.d.ts +13 -0
- package/dist/packages/shared/fetch-with-proxy.d.ts.map +1 -0
- package/dist/packages/shared/fetch-with-proxy.js +33 -0
- package/dist/packages/shared/fetch-with-proxy.js.map +1 -0
- package/dist/packages/shared/fonts.d.ts +73 -0
- package/dist/packages/shared/fonts.d.ts.map +1 -0
- package/dist/packages/shared/fonts.js +251 -0
- package/dist/packages/shared/fonts.js.map +1 -0
- package/dist/packages/slides/common.d.ts +4 -0
- package/dist/packages/slides/common.d.ts.map +1 -1
- package/dist/packages/slides/convert.d.ts.map +1 -1
- package/dist/packages/slides/convert.js +34 -4
- package/dist/packages/slides/convert.js.map +1 -1
- package/dist/packages/slides/fonts.d.ts +4 -37
- package/dist/packages/slides/fonts.d.ts.map +1 -1
- package/dist/packages/slides/fonts.js +4 -205
- package/dist/packages/slides/fonts.js.map +1 -1
- package/dist/packages/slides/vendor/pptxgen.d.ts +2 -0
- package/dist/packages/slides/vendor/pptxgen.js +2 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -43686,7 +43686,25 @@ function getBorderStyleCss(style) {
|
|
|
43686
43686
|
triple: "double",
|
|
43687
43687
|
thick: "solid",
|
|
43688
43688
|
nil: "none",
|
|
43689
|
-
none: "none"
|
|
43689
|
+
none: "none",
|
|
43690
|
+
// Compound border types - rendered as double for visual distinction
|
|
43691
|
+
thinThickSmallGap: "double",
|
|
43692
|
+
thickThinSmallGap: "double",
|
|
43693
|
+
thinThickMedGap: "double",
|
|
43694
|
+
thickThinMedGap: "double",
|
|
43695
|
+
thinThickLargeGap: "double",
|
|
43696
|
+
thickThinLargeGap: "double",
|
|
43697
|
+
thinThickThinSmallGap: "double",
|
|
43698
|
+
thinThickThinMedGap: "double",
|
|
43699
|
+
thinThickThinLargeGap: "double",
|
|
43700
|
+
// Wave borders
|
|
43701
|
+
wave: "solid",
|
|
43702
|
+
doubleWave: "double",
|
|
43703
|
+
// 3D borders
|
|
43704
|
+
threeDEmboss: "ridge",
|
|
43705
|
+
threeDEngrave: "groove",
|
|
43706
|
+
outset: "outset",
|
|
43707
|
+
inset: "inset"
|
|
43690
43708
|
};
|
|
43691
43709
|
return styleMap[style] ?? "solid";
|
|
43692
43710
|
}
|
|
@@ -43986,6 +44004,41 @@ function parseStyles(stylesDoc, themeColors, themeFonts) {
|
|
|
43986
44004
|
}
|
|
43987
44005
|
}
|
|
43988
44006
|
const styleEls = stylesDoc.getElementsByTagName("w:style");
|
|
44007
|
+
for (let i = 0; i < styleEls.length; i++) {
|
|
44008
|
+
const styleEl = styleEls[i];
|
|
44009
|
+
const styleType = styleEl.getAttribute("w:type");
|
|
44010
|
+
const isDefault = styleEl.getAttribute("w:default");
|
|
44011
|
+
if (styleType === "table" && isDefault === "1") {
|
|
44012
|
+
const tblPr = findChild(styleEl, "tblPr");
|
|
44013
|
+
if (tblPr) {
|
|
44014
|
+
const tblCellMar = findChild(tblPr, "tblCellMar");
|
|
44015
|
+
if (tblCellMar) {
|
|
44016
|
+
defaults.tableCellMargins = {};
|
|
44017
|
+
const topEl = findChild(tblCellMar, "top");
|
|
44018
|
+
const bottomEl = findChild(tblCellMar, "bottom");
|
|
44019
|
+
const leftEl = findChild(tblCellMar, "left") || findChild(tblCellMar, "start");
|
|
44020
|
+
const rightEl = findChild(tblCellMar, "right") || findChild(tblCellMar, "end");
|
|
44021
|
+
if (topEl) {
|
|
44022
|
+
const w = topEl.getAttribute("w:w");
|
|
44023
|
+
if (w) defaults.tableCellMargins.top = parseInt(w, 10);
|
|
44024
|
+
}
|
|
44025
|
+
if (bottomEl) {
|
|
44026
|
+
const w = bottomEl.getAttribute("w:w");
|
|
44027
|
+
if (w) defaults.tableCellMargins.bottom = parseInt(w, 10);
|
|
44028
|
+
}
|
|
44029
|
+
if (leftEl) {
|
|
44030
|
+
const w = leftEl.getAttribute("w:w");
|
|
44031
|
+
if (w) defaults.tableCellMargins.left = parseInt(w, 10);
|
|
44032
|
+
}
|
|
44033
|
+
if (rightEl) {
|
|
44034
|
+
const w = rightEl.getAttribute("w:w");
|
|
44035
|
+
if (w) defaults.tableCellMargins.right = parseInt(w, 10);
|
|
44036
|
+
}
|
|
44037
|
+
}
|
|
44038
|
+
}
|
|
44039
|
+
break;
|
|
44040
|
+
}
|
|
44041
|
+
}
|
|
43989
44042
|
for (let i = 0; i < styleEls.length; i++) {
|
|
43990
44043
|
const styleEl = styleEls[i];
|
|
43991
44044
|
const styleId = styleEl.getAttribute("w:styleId");
|
|
@@ -44401,7 +44454,7 @@ function parseParagraphBorders(pBdr) {
|
|
|
44401
44454
|
borders.right = parseBorder(findChild(pBdr, "right"));
|
|
44402
44455
|
return borders;
|
|
44403
44456
|
}
|
|
44404
|
-
function parseParagraphProps(pPr) {
|
|
44457
|
+
function parseParagraphProps(pPr, themeColors, themeFonts) {
|
|
44405
44458
|
const props = {};
|
|
44406
44459
|
const pStyle = findChild(pPr, "pStyle");
|
|
44407
44460
|
if (pStyle) {
|
|
@@ -44455,6 +44508,10 @@ function parseParagraphProps(pPr) {
|
|
|
44455
44508
|
props.shading = "#" + fill;
|
|
44456
44509
|
}
|
|
44457
44510
|
}
|
|
44511
|
+
const rPr = findChild(pPr, "rPr");
|
|
44512
|
+
if (rPr && themeColors && themeFonts) {
|
|
44513
|
+
props.rPr = parseRunProps(rPr, themeColors, themeFonts);
|
|
44514
|
+
}
|
|
44458
44515
|
return props;
|
|
44459
44516
|
}
|
|
44460
44517
|
function parseRunProps(rPr, themeColors, themeFonts) {
|
|
@@ -44559,7 +44616,7 @@ function parseTextRun(r, themeColors, themeFonts) {
|
|
|
44559
44616
|
}
|
|
44560
44617
|
function parseParagraph(p, themeColors, themeFonts) {
|
|
44561
44618
|
const pPr = findChild(p, "pPr");
|
|
44562
|
-
const props = pPr ? parseParagraphProps(pPr) : {};
|
|
44619
|
+
const props = pPr ? parseParagraphProps(pPr, themeColors, themeFonts) : {};
|
|
44563
44620
|
const runs = [];
|
|
44564
44621
|
const processElement = (el) => {
|
|
44565
44622
|
for (let i = 0; i < el.children.length; i++) {
|
|
@@ -44617,6 +44674,10 @@ function parseTableCell(tc, themeColors, themeFonts) {
|
|
|
44617
44674
|
cell.vAlign = val;
|
|
44618
44675
|
}
|
|
44619
44676
|
}
|
|
44677
|
+
const noWrap = findChild(tcPr, "noWrap");
|
|
44678
|
+
if (noWrap) {
|
|
44679
|
+
cell.noWrap = true;
|
|
44680
|
+
}
|
|
44620
44681
|
}
|
|
44621
44682
|
const collectParagraphs = (parent) => {
|
|
44622
44683
|
const result = [];
|
|
@@ -44710,6 +44771,30 @@ function parseTable(tbl, themeColors, themeFonts) {
|
|
|
44710
44771
|
table.tableIndent = parseInt(w, 10);
|
|
44711
44772
|
}
|
|
44712
44773
|
}
|
|
44774
|
+
const tblCellMar = findChild(tblPr, "tblCellMar");
|
|
44775
|
+
if (tblCellMar) {
|
|
44776
|
+
table.cellMargins = {};
|
|
44777
|
+
const topMar = findChild(tblCellMar, "top");
|
|
44778
|
+
const bottomMar = findChild(tblCellMar, "bottom");
|
|
44779
|
+
const leftMar = findChild(tblCellMar, "left") || findChild(tblCellMar, "start");
|
|
44780
|
+
const rightMar = findChild(tblCellMar, "right") || findChild(tblCellMar, "end");
|
|
44781
|
+
if (topMar) {
|
|
44782
|
+
const w = topMar.getAttribute("w:w");
|
|
44783
|
+
if (w) table.cellMargins.top = parseInt(w, 10);
|
|
44784
|
+
}
|
|
44785
|
+
if (bottomMar) {
|
|
44786
|
+
const w = bottomMar.getAttribute("w:w");
|
|
44787
|
+
if (w) table.cellMargins.bottom = parseInt(w, 10);
|
|
44788
|
+
}
|
|
44789
|
+
if (leftMar) {
|
|
44790
|
+
const w = leftMar.getAttribute("w:w");
|
|
44791
|
+
if (w) table.cellMargins.left = parseInt(w, 10);
|
|
44792
|
+
}
|
|
44793
|
+
if (rightMar) {
|
|
44794
|
+
const w = rightMar.getAttribute("w:w");
|
|
44795
|
+
if (w) table.cellMargins.right = parseInt(w, 10);
|
|
44796
|
+
}
|
|
44797
|
+
}
|
|
44713
44798
|
}
|
|
44714
44799
|
const tblGrid = findChild(tbl, "tblGrid");
|
|
44715
44800
|
if (tblGrid) {
|
|
@@ -44728,6 +44813,14 @@ function parseTable(tbl, themeColors, themeFonts) {
|
|
|
44728
44813
|
if (trHeight) {
|
|
44729
44814
|
const val = trHeight.getAttribute("w:val");
|
|
44730
44815
|
if (val) row.height = parseInt(val, 10);
|
|
44816
|
+
const hRule = trHeight.getAttribute("w:hRule");
|
|
44817
|
+
if (hRule === "exact") {
|
|
44818
|
+
row.heightRule = "exact";
|
|
44819
|
+
} else if (hRule === "auto") {
|
|
44820
|
+
row.heightRule = "auto";
|
|
44821
|
+
} else {
|
|
44822
|
+
row.heightRule = "atLeast";
|
|
44823
|
+
}
|
|
44731
44824
|
}
|
|
44732
44825
|
}
|
|
44733
44826
|
const tcs = findChildren(tr, "tc");
|
|
@@ -45094,10 +45187,8 @@ function renderParagraphToHtml(para, styleMap, numberingMap, imageMap = /* @__PU
|
|
|
45094
45187
|
}
|
|
45095
45188
|
}
|
|
45096
45189
|
const styleAttr = styles.length > 0 ? ` style="${styles.join(";")}"` : "";
|
|
45097
|
-
|
|
45098
|
-
|
|
45099
|
-
}
|
|
45100
|
-
return `<${tag}${styleAttr}>${content}</${tag}>`;
|
|
45190
|
+
const finalContent = content || " ";
|
|
45191
|
+
return `<${tag}${styleAttr}>${finalContent}</${tag}>`;
|
|
45101
45192
|
}
|
|
45102
45193
|
function renderTableToHtml(table, styleMap, numberingMap, themeColors, imageMap, docDefaults = {}) {
|
|
45103
45194
|
const styles = [
|
|
@@ -45112,23 +45203,110 @@ function renderTableToHtml(table, styleMap, numberingMap, themeColors, imageMap,
|
|
|
45112
45203
|
styles.push(`margin-left:${twipsToPx(table.tableIndent)}px`);
|
|
45113
45204
|
}
|
|
45114
45205
|
let html = `<table style="${styles.join(";")}">`;
|
|
45206
|
+
const rowspanMap = /* @__PURE__ */ new Map();
|
|
45207
|
+
for (let rowIdx = 0; rowIdx < table.rows.length; rowIdx++) {
|
|
45208
|
+
let colIdx = 0;
|
|
45209
|
+
for (const cell of table.rows[rowIdx].cells) {
|
|
45210
|
+
if (cell.vMerge === "restart") {
|
|
45211
|
+
let span = 1;
|
|
45212
|
+
for (let nextRow = rowIdx + 1; nextRow < table.rows.length; nextRow++) {
|
|
45213
|
+
let nextColIdx = 0;
|
|
45214
|
+
let foundContinue = false;
|
|
45215
|
+
for (const nextCell of table.rows[nextRow].cells) {
|
|
45216
|
+
if (nextColIdx === colIdx) {
|
|
45217
|
+
if (nextCell.vMerge === "continue") {
|
|
45218
|
+
span++;
|
|
45219
|
+
foundContinue = true;
|
|
45220
|
+
}
|
|
45221
|
+
break;
|
|
45222
|
+
}
|
|
45223
|
+
nextColIdx += nextCell.gridSpan ?? 1;
|
|
45224
|
+
}
|
|
45225
|
+
if (!foundContinue) break;
|
|
45226
|
+
}
|
|
45227
|
+
if (span > 1) {
|
|
45228
|
+
rowspanMap.set(`${rowIdx}-${colIdx}`, span);
|
|
45229
|
+
}
|
|
45230
|
+
}
|
|
45231
|
+
colIdx += cell.gridSpan ?? 1;
|
|
45232
|
+
}
|
|
45233
|
+
}
|
|
45115
45234
|
let colIndex = 0;
|
|
45116
|
-
for (
|
|
45235
|
+
for (let rowIdx = 0; rowIdx < table.rows.length; rowIdx++) {
|
|
45236
|
+
const row = table.rows[rowIdx];
|
|
45117
45237
|
const rowStyles = [];
|
|
45118
45238
|
if (row.height) {
|
|
45119
45239
|
rowStyles.push(`height:${twipsToPx(row.height)}px`);
|
|
45120
45240
|
}
|
|
45121
45241
|
html += `<tr${rowStyles.length > 0 ? ` style="${rowStyles.join(";")}"` : ""}>`;
|
|
45242
|
+
let emptyParagraphsToDistribute = [];
|
|
45243
|
+
colIndex = 0;
|
|
45244
|
+
for (const cell of row.cells) {
|
|
45245
|
+
if (cell.vMerge === "continue") {
|
|
45246
|
+
colIndex += cell.gridSpan ?? 1;
|
|
45247
|
+
continue;
|
|
45248
|
+
}
|
|
45249
|
+
const rowspan = rowspanMap.get(`${rowIdx}-${colIndex}`);
|
|
45250
|
+
if (rowspan && rowspan > 1) {
|
|
45251
|
+
const emptyParas = [];
|
|
45252
|
+
for (const para of cell.paragraphs) {
|
|
45253
|
+
const isEmpty = !para.runs || para.runs.length === 0 || para.runs.every((run) => !run.text || run.text.trim() === "");
|
|
45254
|
+
if (isEmpty) {
|
|
45255
|
+
emptyParas.push(para);
|
|
45256
|
+
}
|
|
45257
|
+
}
|
|
45258
|
+
let linesInNextRows = 0;
|
|
45259
|
+
for (let r = rowIdx + 1; r < rowIdx + rowspan && r < table.rows.length; r++) {
|
|
45260
|
+
let colIdx = 0;
|
|
45261
|
+
for (const nextRowCell of table.rows[r].cells) {
|
|
45262
|
+
if (nextRowCell.vMerge !== "continue") {
|
|
45263
|
+
for (const para of nextRowCell.paragraphs) {
|
|
45264
|
+
const isEmpty = !para.runs || para.runs.length === 0 || para.runs.every((run) => !run.text || run.text.trim() === "");
|
|
45265
|
+
if (!isEmpty) {
|
|
45266
|
+
linesInNextRows++;
|
|
45267
|
+
}
|
|
45268
|
+
}
|
|
45269
|
+
break;
|
|
45270
|
+
}
|
|
45271
|
+
colIdx += nextRowCell.gridSpan ?? 1;
|
|
45272
|
+
}
|
|
45273
|
+
}
|
|
45274
|
+
const countToDistribute = Math.max(0, emptyParas.length - linesInNextRows);
|
|
45275
|
+
for (let i = 0; i < countToDistribute; i++) {
|
|
45276
|
+
emptyParagraphsToDistribute.push(emptyParas[i]);
|
|
45277
|
+
}
|
|
45278
|
+
}
|
|
45279
|
+
colIndex += cell.gridSpan ?? 1;
|
|
45280
|
+
}
|
|
45122
45281
|
colIndex = 0;
|
|
45123
45282
|
for (const cell of row.cells) {
|
|
45124
45283
|
if (cell.vMerge === "continue") {
|
|
45125
45284
|
colIndex += cell.gridSpan ?? 1;
|
|
45126
45285
|
continue;
|
|
45127
45286
|
}
|
|
45128
|
-
const cellStyles = [
|
|
45287
|
+
const cellStyles = [];
|
|
45129
45288
|
const cellAttrs = [];
|
|
45289
|
+
if (table.cellMargins) {
|
|
45290
|
+
const top = table.cellMargins.top !== void 0 ? twipsToPx(table.cellMargins.top) : 0;
|
|
45291
|
+
const right = table.cellMargins.right !== void 0 ? twipsToPx(table.cellMargins.right) : 0;
|
|
45292
|
+
const bottom = table.cellMargins.bottom !== void 0 ? twipsToPx(table.cellMargins.bottom) : 0;
|
|
45293
|
+
const left = table.cellMargins.left !== void 0 ? twipsToPx(table.cellMargins.left) : 0;
|
|
45294
|
+
cellStyles.push(`padding:${top}px ${right}px ${bottom}px ${left}px`);
|
|
45295
|
+
} else if (docDefaults.tableCellMargins) {
|
|
45296
|
+
const margins = docDefaults.tableCellMargins;
|
|
45297
|
+
const top = margins.top !== void 0 ? twipsToPx(margins.top) : 0;
|
|
45298
|
+
const right = margins.right !== void 0 ? twipsToPx(margins.right) : 7;
|
|
45299
|
+
const bottom = margins.bottom !== void 0 ? twipsToPx(margins.bottom) : 0;
|
|
45300
|
+
const left = margins.left !== void 0 ? twipsToPx(margins.left) : 7;
|
|
45301
|
+
cellStyles.push(`padding:${top}px ${right}px ${bottom}px ${left}px`);
|
|
45302
|
+
} else {
|
|
45303
|
+
cellStyles.push("padding:0 7px");
|
|
45304
|
+
}
|
|
45130
45305
|
const vAlign = cell.vAlign ?? "top";
|
|
45131
45306
|
cellStyles.push(`vertical-align:${vAlign}`);
|
|
45307
|
+
if (cell.noWrap) {
|
|
45308
|
+
cellStyles.push("white-space:nowrap");
|
|
45309
|
+
}
|
|
45132
45310
|
if (cell.width) {
|
|
45133
45311
|
cellStyles.push(`width:${twipsToPx(cell.width)}px`);
|
|
45134
45312
|
} else if (table.columnWidths && table.columnWidths[colIndex]) {
|
|
@@ -45144,6 +45322,10 @@ function renderTableToHtml(table, styleMap, numberingMap, themeColors, imageMap,
|
|
|
45144
45322
|
if (cell.gridSpan && cell.gridSpan > 1) {
|
|
45145
45323
|
cellAttrs.push(`colspan="${cell.gridSpan}"`);
|
|
45146
45324
|
}
|
|
45325
|
+
const rowspan = rowspanMap.get(`${rowIdx}-${colIndex}`);
|
|
45326
|
+
if (rowspan && rowspan > 1) {
|
|
45327
|
+
cellAttrs.push(`rowspan="${rowspan}"`);
|
|
45328
|
+
}
|
|
45147
45329
|
if (cell.shading) {
|
|
45148
45330
|
cellStyles.push(`background-color:${cell.shading}`);
|
|
45149
45331
|
}
|
|
@@ -45184,14 +45366,25 @@ function renderTableToHtml(table, styleMap, numberingMap, themeColors, imageMap,
|
|
|
45184
45366
|
}
|
|
45185
45367
|
const attrsStr = cellAttrs.length > 0 ? " " + cellAttrs.join(" ") : "";
|
|
45186
45368
|
html += `<td${attrsStr} style="${cellStyles.join(";")}">`;
|
|
45369
|
+
const isRowspanCell = rowspan && rowspan > 1;
|
|
45370
|
+
let cellContent = "";
|
|
45187
45371
|
for (const para of cell.paragraphs) {
|
|
45188
|
-
|
|
45372
|
+
cellContent += renderParagraphToHtml(para, styleMap, numberingMap, imageMap, docDefaults);
|
|
45373
|
+
}
|
|
45374
|
+
if (!isRowspanCell && emptyParagraphsToDistribute.length > 0) {
|
|
45375
|
+
for (const para of emptyParagraphsToDistribute) {
|
|
45376
|
+
cellContent += renderParagraphToHtml(para, styleMap, numberingMap, imageMap, docDefaults);
|
|
45377
|
+
}
|
|
45189
45378
|
}
|
|
45190
45379
|
if (cell.nestedTables) {
|
|
45191
45380
|
for (const nestedTable of cell.nestedTables) {
|
|
45192
|
-
|
|
45381
|
+
cellContent += renderTableToHtml(nestedTable, styleMap, numberingMap, themeColors, imageMap, docDefaults);
|
|
45193
45382
|
}
|
|
45194
45383
|
}
|
|
45384
|
+
if (!cellContent.trim()) {
|
|
45385
|
+
cellContent = " ";
|
|
45386
|
+
}
|
|
45387
|
+
html += cellContent;
|
|
45195
45388
|
html += "</td>";
|
|
45196
45389
|
colIndex += cell.gridSpan ?? 1;
|
|
45197
45390
|
}
|
|
@@ -45420,6 +45613,7 @@ function generateStylesCss(styleMap, themeFonts) {
|
|
|
45420
45613
|
const headingStyles = /* @__PURE__ */ new Map();
|
|
45421
45614
|
cssRules.push(`p { margin: 0 0 10pt 0; }`);
|
|
45422
45615
|
cssRules.push(`table { margin: 10pt 0; border-collapse: collapse; }`);
|
|
45616
|
+
cssRules.push(`td p { margin: 0; line-height: 1.15; }`);
|
|
45423
45617
|
cssRules.push(`img { max-width: 100%; }`);
|
|
45424
45618
|
cssRules.push(`ul, ol { margin: 0 0 10pt 0; padding-left: 24px; }`);
|
|
45425
45619
|
cssRules.push(`li { margin: 0 0 4pt 0; }`);
|
|
@@ -45750,7 +45944,7 @@ import * as path2 from "node:path";
|
|
|
45750
45944
|
// packages/slides/import-pptx.ts
|
|
45751
45945
|
var import_jszip2 = __toESM(require_lib4(), 1);
|
|
45752
45946
|
|
|
45753
|
-
// packages/
|
|
45947
|
+
// packages/shared/fonts.ts
|
|
45754
45948
|
var FONT_MAP = {
|
|
45755
45949
|
// ---- Microsoft Office fonts ----
|
|
45756
45950
|
"Calibri": { cssFallback: "'Calibri','Carlito','Helvetica Neue',Helvetica,Arial,sans-serif", officeFont: "Calibri", category: "sans-serif" },
|
|
@@ -45795,8 +45989,8 @@ var FONT_MAP = {
|
|
|
45795
45989
|
"Nirmala UI": { cssFallback: "'Nirmala UI','Helvetica Neue',Arial,sans-serif", officeFont: "Nirmala UI", category: "sans-serif" },
|
|
45796
45990
|
"Ebrima": { cssFallback: "'Ebrima','Helvetica Neue',Arial,sans-serif", officeFont: "Ebrima", category: "sans-serif" },
|
|
45797
45991
|
// ---- Google Fonts / web fonts (sans-serif) ----
|
|
45798
|
-
// Preserve original font names in
|
|
45799
|
-
//
|
|
45992
|
+
// Preserve original font names in Office export for maximum fidelity.
|
|
45993
|
+
// Office apps will render these correctly if the fonts are installed,
|
|
45800
45994
|
// and fall back gracefully if not. The cssFallback stack provides
|
|
45801
45995
|
// alternatives for HTML rendering (import side) only.
|
|
45802
45996
|
"Inter": { cssFallback: "'Inter','Helvetica Neue',Helvetica,Arial,sans-serif", officeFont: "Inter", category: "sans-serif" },
|
|
@@ -45877,6 +46071,11 @@ function cssFontFamily(fontName) {
|
|
|
45877
46071
|
}
|
|
45878
46072
|
return `'${fontName}',sans-serif`;
|
|
45879
46073
|
}
|
|
46074
|
+
function mapToOfficeFont(fontFamily) {
|
|
46075
|
+
const normalized = fontFamily.toLowerCase().trim();
|
|
46076
|
+
const entry = FONT_MAP_LOWER[normalized];
|
|
46077
|
+
return entry ? entry.officeFont : fontFamily;
|
|
46078
|
+
}
|
|
45880
46079
|
|
|
45881
46080
|
// packages/slides/import-pptx.ts
|
|
45882
46081
|
var TARGET_WIDTH = 1280;
|
|
@@ -72419,10 +72618,11 @@ var GradientTextRun = class extends XmlElement {
|
|
|
72419
72618
|
rPr.addChildElement(new XmlElement("w:szCs", { "w:val": options.size.toString() }));
|
|
72420
72619
|
}
|
|
72421
72620
|
if (options.font) {
|
|
72621
|
+
const officeFont = mapToOfficeFont(options.font);
|
|
72422
72622
|
rPr.addChildElement(new XmlElement("w:rFonts", {
|
|
72423
|
-
"w:ascii":
|
|
72424
|
-
"w:hAnsi":
|
|
72425
|
-
"w:cs":
|
|
72623
|
+
"w:ascii": officeFont,
|
|
72624
|
+
"w:hAnsi": officeFont,
|
|
72625
|
+
"w:cs": officeFont
|
|
72426
72626
|
}));
|
|
72427
72627
|
}
|
|
72428
72628
|
const fallbackColor = options.fallbackColor || options.gradient.stops[0]?.color;
|
|
@@ -72455,6 +72655,7 @@ function inlineRunsToTextRuns(runs, textTransform) {
|
|
|
72455
72655
|
const result = [];
|
|
72456
72656
|
for (const run of runs) {
|
|
72457
72657
|
const parts = run.text.split("\n");
|
|
72658
|
+
const font = run.fontFamily ? mapToOfficeFont(run.fontFamily) : void 0;
|
|
72458
72659
|
const underlineConfig = run.underline ? {
|
|
72459
72660
|
type: getUnderlineType(run.underline.type),
|
|
72460
72661
|
color: run.underline.color
|
|
@@ -72468,7 +72669,7 @@ function inlineRunsToTextRuns(runs, textTransform) {
|
|
|
72468
72669
|
italics: run.italic,
|
|
72469
72670
|
color: run.color,
|
|
72470
72671
|
size: run.size,
|
|
72471
|
-
font
|
|
72672
|
+
font,
|
|
72472
72673
|
superScript: run.superscript,
|
|
72473
72674
|
subScript: run.subscript,
|
|
72474
72675
|
strike: run.strike,
|
|
@@ -72489,7 +72690,7 @@ function inlineRunsToTextRuns(runs, textTransform) {
|
|
|
72489
72690
|
bold: run.bold,
|
|
72490
72691
|
italics: run.italic,
|
|
72491
72692
|
size: run.size,
|
|
72492
|
-
font
|
|
72693
|
+
font,
|
|
72493
72694
|
fallbackColor: run.color
|
|
72494
72695
|
// Solid color fallback for LibreOffice
|
|
72495
72696
|
}));
|
|
@@ -72500,7 +72701,7 @@ function inlineRunsToTextRuns(runs, textTransform) {
|
|
|
72500
72701
|
italics: run.italic,
|
|
72501
72702
|
color: run.color,
|
|
72502
72703
|
size: run.size,
|
|
72503
|
-
font
|
|
72704
|
+
font,
|
|
72504
72705
|
superScript: run.superscript,
|
|
72505
72706
|
subScript: run.subscript,
|
|
72506
72707
|
strike: run.strike,
|
|
@@ -72548,7 +72749,7 @@ function createTableRow(cells, isHeaderRow, columnCount, cellPadding, headerBack
|
|
|
72548
72749
|
// Use header text color for header rows, otherwise use run's color
|
|
72549
72750
|
color: isHeaderRow && headerTextColor ? headerTextColor : run.color,
|
|
72550
72751
|
size: run.size,
|
|
72551
|
-
font: run.fontFamily,
|
|
72752
|
+
font: run.fontFamily ? mapToOfficeFont(run.fontFamily) : void 0,
|
|
72552
72753
|
superScript: run.superscript,
|
|
72553
72754
|
subScript: run.subscript,
|
|
72554
72755
|
strike: run.strike,
|
|
@@ -72653,7 +72854,7 @@ function convertElementToDocx(element) {
|
|
|
72653
72854
|
textRunOptions.color = element.color;
|
|
72654
72855
|
}
|
|
72655
72856
|
if (element.fontFamily) {
|
|
72656
|
-
textRunOptions.font = element.fontFamily;
|
|
72857
|
+
textRunOptions.font = mapToOfficeFont(element.fontFamily);
|
|
72657
72858
|
}
|
|
72658
72859
|
if (element.fontSize) {
|
|
72659
72860
|
textRunOptions.size = element.fontSize;
|
|
@@ -72707,7 +72908,7 @@ function convertElementToDocx(element) {
|
|
|
72707
72908
|
bold: element.bold,
|
|
72708
72909
|
italics: element.italic,
|
|
72709
72910
|
color: element.color,
|
|
72710
|
-
font: element.fontFamily
|
|
72911
|
+
font: element.fontFamily ? mapToOfficeFont(element.fontFamily) : void 0
|
|
72711
72912
|
})
|
|
72712
72913
|
];
|
|
72713
72914
|
const alignment = textAlignmentToDocx(element.alignment);
|
|
@@ -72837,7 +73038,7 @@ function convertElementToDocx(element) {
|
|
|
72837
73038
|
bold: innerElement.bold,
|
|
72838
73039
|
italics: innerElement.italic,
|
|
72839
73040
|
color: paragraphColor,
|
|
72840
|
-
font: innerElement.fontFamily
|
|
73041
|
+
font: innerElement.fontFamily ? mapToOfficeFont(innerElement.fontFamily) : void 0
|
|
72841
73042
|
})
|
|
72842
73043
|
];
|
|
72843
73044
|
cellContent.push(
|
|
@@ -73512,96 +73713,119 @@ async function createDocxBuffer(html, options = {}) {
|
|
|
73512
73713
|
return Packer.toBuffer(doc);
|
|
73513
73714
|
}
|
|
73514
73715
|
|
|
73716
|
+
// packages/shared/fetch-with-proxy.ts
|
|
73717
|
+
var userAgent = "Mozilla/5.0 (compatible; Copilot/1.0)";
|
|
73718
|
+
async function fetchWithProxy(url) {
|
|
73719
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
|
|
73720
|
+
if (proxyUrl) {
|
|
73721
|
+
const undici = await import("undici");
|
|
73722
|
+
const agent = new undici.ProxyAgent(proxyUrl);
|
|
73723
|
+
const response = await undici.fetch(url, {
|
|
73724
|
+
dispatcher: agent,
|
|
73725
|
+
headers: {
|
|
73726
|
+
"User-Agent": userAgent
|
|
73727
|
+
}
|
|
73728
|
+
});
|
|
73729
|
+
return response;
|
|
73730
|
+
}
|
|
73731
|
+
return fetch(url, {
|
|
73732
|
+
headers: {
|
|
73733
|
+
"User-Agent": userAgent
|
|
73734
|
+
}
|
|
73735
|
+
});
|
|
73736
|
+
}
|
|
73737
|
+
|
|
73515
73738
|
// packages/cli/commands/export-docs.ts
|
|
73516
73739
|
var MAX_IMAGE_WIDTH = 624;
|
|
73517
|
-
|
|
73740
|
+
function parseImageDimensions(data) {
|
|
73741
|
+
if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
|
|
73742
|
+
const width = data[16] << 24 | data[17] << 16 | data[18] << 8 | data[19];
|
|
73743
|
+
const height = data[20] << 24 | data[21] << 16 | data[22] << 8 | data[23];
|
|
73744
|
+
return { width, height };
|
|
73745
|
+
}
|
|
73746
|
+
if (data[0] === 255 && data[1] === 216) {
|
|
73747
|
+
let offset = 2;
|
|
73748
|
+
while (offset < data.length - 8) {
|
|
73749
|
+
if (data[offset] !== 255) {
|
|
73750
|
+
offset++;
|
|
73751
|
+
continue;
|
|
73752
|
+
}
|
|
73753
|
+
const marker = data[offset + 1];
|
|
73754
|
+
if (marker === 192 || marker === 194) {
|
|
73755
|
+
const height = data[offset + 5] << 8 | data[offset + 6];
|
|
73756
|
+
const width = data[offset + 7] << 8 | data[offset + 8];
|
|
73757
|
+
return { width, height };
|
|
73758
|
+
}
|
|
73759
|
+
const length = data[offset + 2] << 8 | data[offset + 3];
|
|
73760
|
+
offset += 2 + length;
|
|
73761
|
+
}
|
|
73762
|
+
}
|
|
73763
|
+
if (data[0] === 71 && data[1] === 73 && data[2] === 70) {
|
|
73764
|
+
const width = data[6] | data[7] << 8;
|
|
73765
|
+
const height = data[8] | data[9] << 8;
|
|
73766
|
+
return { width, height };
|
|
73767
|
+
}
|
|
73768
|
+
if (data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70 && data[8] === 87 && data[9] === 69 && data[10] === 66 && data[11] === 80) {
|
|
73769
|
+
if (data[12] === 86 && data[13] === 80 && data[14] === 56 && data[15] === 88) {
|
|
73770
|
+
const width = (data[24] | data[25] << 8 | data[26] << 16) + 1;
|
|
73771
|
+
const height = (data[27] | data[28] << 8 | data[29] << 16) + 1;
|
|
73772
|
+
return { width, height };
|
|
73773
|
+
}
|
|
73774
|
+
if (data[12] === 86 && data[13] === 80 && data[14] === 56 && data[15] === 76) {
|
|
73775
|
+
const bits = data[21] | data[22] << 8 | data[23] << 16 | data[24] << 24;
|
|
73776
|
+
const width = (bits & 16383) + 1;
|
|
73777
|
+
const height = (bits >> 14 & 16383) + 1;
|
|
73778
|
+
return { width, height };
|
|
73779
|
+
}
|
|
73780
|
+
if (data[12] === 86 && data[13] === 80 && data[14] === 56 && data[15] === 32) {
|
|
73781
|
+
const width = (data[26] | data[27] << 8) & 16383;
|
|
73782
|
+
const height = (data[28] | data[29] << 8) & 16383;
|
|
73783
|
+
return { width, height };
|
|
73784
|
+
}
|
|
73785
|
+
}
|
|
73786
|
+
return null;
|
|
73787
|
+
}
|
|
73788
|
+
async function fetchExternalImages(htmlContent) {
|
|
73518
73789
|
const imageMap = /* @__PURE__ */ new Map();
|
|
73519
|
-
const
|
|
73520
|
-
|
|
73790
|
+
const imgRegex = /<img\s+[^>]*src="(https?:\/\/[^"]+)"[^>]*>/gi;
|
|
73791
|
+
const matches2 = [...htmlContent.matchAll(imgRegex)];
|
|
73792
|
+
if (matches2.length === 0) {
|
|
73521
73793
|
return imageMap;
|
|
73522
73794
|
}
|
|
73523
|
-
const
|
|
73524
|
-
|
|
73525
|
-
|
|
73526
|
-
await page.goto(`file://${absoluteHtmlPath}`, {
|
|
73527
|
-
waitUntil: "networkidle"
|
|
73528
|
-
});
|
|
73529
|
-
await page.waitForTimeout(1e3);
|
|
73530
|
-
const uniqueSrcs = await page.evaluate(() => {
|
|
73531
|
-
const images = Array.from(document.querySelectorAll("img"));
|
|
73532
|
-
const srcs = images.map((img) => img.src).filter((src) => src && !src.startsWith("data:"));
|
|
73533
|
-
return [...new Set(srcs)];
|
|
73534
|
-
});
|
|
73535
|
-
if (uniqueSrcs.length === 0) {
|
|
73536
|
-
await page.close();
|
|
73537
|
-
return imageMap;
|
|
73795
|
+
const urls = /* @__PURE__ */ new Set();
|
|
73796
|
+
for (const match of matches2) {
|
|
73797
|
+
urls.add(match[1]);
|
|
73538
73798
|
}
|
|
73539
|
-
console.log(`Fetching ${
|
|
73540
|
-
|
|
73541
|
-
|
|
73542
|
-
|
|
73543
|
-
|
|
73544
|
-
|
|
73545
|
-
|
|
73546
|
-
|
|
73547
|
-
|
|
73548
|
-
|
|
73549
|
-
|
|
73550
|
-
|
|
73551
|
-
|
|
73552
|
-
|
|
73553
|
-
|
|
73554
|
-
|
|
73555
|
-
|
|
73556
|
-
|
|
73557
|
-
|
|
73558
|
-
|
|
73559
|
-
|
|
73560
|
-
|
|
73561
|
-
|
|
73562
|
-
|
|
73563
|
-
|
|
73564
|
-
|
|
73565
|
-
|
|
73566
|
-
if (!base64) {
|
|
73567
|
-
resolve5(null);
|
|
73568
|
-
return;
|
|
73569
|
-
}
|
|
73570
|
-
const binaryString = atob(base64);
|
|
73571
|
-
const bytes = new Array(binaryString.length);
|
|
73572
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
73573
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
73574
|
-
}
|
|
73575
|
-
resolve5({ data: bytes, width, height });
|
|
73576
|
-
} catch (err) {
|
|
73577
|
-
console.warn("Error processing image:", err);
|
|
73578
|
-
resolve5(null);
|
|
73579
|
-
}
|
|
73580
|
-
};
|
|
73581
|
-
img.onerror = () => {
|
|
73582
|
-
console.warn("Failed to load image:", src2);
|
|
73583
|
-
resolve5(null);
|
|
73584
|
-
};
|
|
73585
|
-
setTimeout(() => {
|
|
73586
|
-
console.warn("Image load timeout:", src2);
|
|
73587
|
-
resolve5(null);
|
|
73588
|
-
}, 1e4);
|
|
73589
|
-
img.src = src2;
|
|
73590
|
-
});
|
|
73591
|
-
}, { src, maxWidth: MAX_IMAGE_WIDTH });
|
|
73592
|
-
if (imageData) {
|
|
73593
|
-
imageMap.set(src, {
|
|
73594
|
-
data: Buffer.from(imageData.data),
|
|
73595
|
-
width: imageData.width,
|
|
73596
|
-
height: imageData.height
|
|
73597
|
-
});
|
|
73799
|
+
console.log(`Fetching ${urls.size} external image(s)...`);
|
|
73800
|
+
await Promise.all(
|
|
73801
|
+
Array.from(urls).map(async (url) => {
|
|
73802
|
+
try {
|
|
73803
|
+
const response = await fetchWithProxy(url);
|
|
73804
|
+
if (response.ok) {
|
|
73805
|
+
const buffer2 = await response.arrayBuffer();
|
|
73806
|
+
const data = new Uint8Array(buffer2);
|
|
73807
|
+
const dimensions = parseImageDimensions(data);
|
|
73808
|
+
if (!dimensions) {
|
|
73809
|
+
console.warn(`Could not parse dimensions for image: ${url}`);
|
|
73810
|
+
return;
|
|
73811
|
+
}
|
|
73812
|
+
let { width, height } = dimensions;
|
|
73813
|
+
if (width > MAX_IMAGE_WIDTH) {
|
|
73814
|
+
const scale = MAX_IMAGE_WIDTH / width;
|
|
73815
|
+
width = MAX_IMAGE_WIDTH;
|
|
73816
|
+
height = Math.round(height * scale);
|
|
73817
|
+
}
|
|
73818
|
+
imageMap.set(url, {
|
|
73819
|
+
data: Buffer.from(buffer2),
|
|
73820
|
+
width,
|
|
73821
|
+
height
|
|
73822
|
+
});
|
|
73823
|
+
}
|
|
73824
|
+
} catch {
|
|
73825
|
+
console.warn(`Failed to fetch image: ${url}`);
|
|
73598
73826
|
}
|
|
73599
|
-
}
|
|
73600
|
-
|
|
73601
|
-
continue;
|
|
73602
|
-
}
|
|
73603
|
-
}
|
|
73604
|
-
await page.close();
|
|
73827
|
+
})
|
|
73828
|
+
);
|
|
73605
73829
|
return imageMap;
|
|
73606
73830
|
}
|
|
73607
73831
|
async function renderChartImages(browser2, htmlPath) {
|
|
@@ -73724,16 +73948,15 @@ async function exportDocs(filePath, outDir, options = {}) {
|
|
|
73724
73948
|
console.log(`Exporting to DOCX: ${filePath}`);
|
|
73725
73949
|
const html = fs3.readFileSync(absolutePath, "utf-8");
|
|
73726
73950
|
const baseName = outputName || path3.basename(filePath, ".html");
|
|
73951
|
+
const imageMap = await fetchExternalImages(html);
|
|
73727
73952
|
const launchOptions = { headless: true };
|
|
73728
73953
|
const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
73729
73954
|
if (proxyServer) {
|
|
73730
73955
|
launchOptions.proxy = { server: proxyServer };
|
|
73731
73956
|
}
|
|
73732
73957
|
const browser2 = await chromium.launch(launchOptions);
|
|
73733
|
-
let imageMap;
|
|
73734
73958
|
let chartImages;
|
|
73735
73959
|
try {
|
|
73736
|
-
imageMap = await fetchExternalImages(browser2, absolutePath);
|
|
73737
73960
|
chartImages = await renderChartImages(browser2, absolutePath);
|
|
73738
73961
|
} finally {
|
|
73739
73962
|
await browser2.close();
|
|
@@ -73756,30 +73979,6 @@ import * as fs4 from "node:fs";
|
|
|
73756
73979
|
import * as path4 from "node:path";
|
|
73757
73980
|
import { fileURLToPath } from "node:url";
|
|
73758
73981
|
import { chromium as chromium2 } from "playwright";
|
|
73759
|
-
|
|
73760
|
-
// packages/cli/commands/common.ts
|
|
73761
|
-
var userAgent = "Mozilla/5.0 (compatible; Copilot/1.0)";
|
|
73762
|
-
async function fetchWithProxy(url) {
|
|
73763
|
-
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
|
|
73764
|
-
if (proxyUrl) {
|
|
73765
|
-
const undici = await import("undici");
|
|
73766
|
-
const agent = new undici.ProxyAgent(proxyUrl);
|
|
73767
|
-
const response = await undici.fetch(url, {
|
|
73768
|
-
dispatcher: agent,
|
|
73769
|
-
headers: {
|
|
73770
|
-
"User-Agent": userAgent
|
|
73771
|
-
}
|
|
73772
|
-
});
|
|
73773
|
-
return response;
|
|
73774
|
-
}
|
|
73775
|
-
return fetch(url, {
|
|
73776
|
-
headers: {
|
|
73777
|
-
"User-Agent": userAgent
|
|
73778
|
-
}
|
|
73779
|
-
});
|
|
73780
|
-
}
|
|
73781
|
-
|
|
73782
|
-
// packages/cli/commands/export-slides.ts
|
|
73783
73982
|
var __filename = fileURLToPath(import.meta.url);
|
|
73784
73983
|
var __dirname = path4.dirname(__filename);
|
|
73785
73984
|
async function embedExternalImages(html) {
|
|
@@ -73835,7 +74034,16 @@ async function exportSlides(filePaths, outDir, outputName) {
|
|
|
73835
74034
|
throw new Error(`Bundle not found: ${bundlePath}. Run 'npm run build' first.`);
|
|
73836
74035
|
}
|
|
73837
74036
|
const bundleCode = fs4.readFileSync(bundlePath, "utf-8");
|
|
73838
|
-
const
|
|
74037
|
+
const htmlContents = [];
|
|
74038
|
+
for (const p of absolutePaths) {
|
|
74039
|
+
let html = fs4.readFileSync(p, "utf-8");
|
|
74040
|
+
html = await embedExternalImages(html);
|
|
74041
|
+
htmlContents.push(html);
|
|
74042
|
+
}
|
|
74043
|
+
const launchOptions = {
|
|
74044
|
+
headless: true,
|
|
74045
|
+
args: ["--disable-web-security"]
|
|
74046
|
+
};
|
|
73839
74047
|
const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
73840
74048
|
if (proxyServer) {
|
|
73841
74049
|
launchOptions.proxy = { server: proxyServer };
|
|
@@ -73848,26 +74056,17 @@ async function exportSlides(filePaths, outDir, outputName) {
|
|
|
73848
74056
|
ignoreHTTPSErrors: true
|
|
73849
74057
|
});
|
|
73850
74058
|
const page = await context.newPage();
|
|
73851
|
-
const
|
|
73852
|
-
|
|
73853
|
-
|
|
73854
|
-
|
|
73855
|
-
|
|
73856
|
-
|
|
73857
|
-
|
|
73858
|
-
|
|
73859
|
-
<head>
|
|
73860
|
-
<script>${bundleCode}</script>
|
|
73861
|
-
</head>
|
|
73862
|
-
<body></body>
|
|
73863
|
-
</html>`;
|
|
73864
|
-
await page.setContent(pageHtml, { waitUntil: "networkidle" });
|
|
74059
|
+
const htmlDir = path4.dirname(absolutePaths[0]);
|
|
74060
|
+
await page.goto(`file://${htmlDir}/`, { waitUntil: "networkidle" });
|
|
74061
|
+
await page.evaluate((code) => {
|
|
74062
|
+
const script = document.createElement("script");
|
|
74063
|
+
script.textContent = code;
|
|
74064
|
+
document.head.appendChild(script);
|
|
74065
|
+
}, bundleCode);
|
|
74066
|
+
await page.waitForFunction(() => !!window.docgen);
|
|
73865
74067
|
const pptxBuffer = await page.evaluate(
|
|
73866
74068
|
async ({ htmlContents: htmlContents2 }) => {
|
|
73867
74069
|
const docgen = window.docgen;
|
|
73868
|
-
if (!docgen) {
|
|
73869
|
-
throw new Error("docgen bundle not loaded");
|
|
73870
|
-
}
|
|
73871
74070
|
const pptx = new docgen.PptxGenJS();
|
|
73872
74071
|
pptx.layout = "LAYOUT_16x9";
|
|
73873
74072
|
pptx.author = "docgen";
|