docgen-utils 1.0.16 → 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.
Files changed (37) hide show
  1. package/dist/bundle.js +441 -176
  2. package/dist/bundle.min.js +233 -233
  3. package/dist/cli.js +350 -151
  4. package/dist/packages/cli/commands/export-docs.d.ts +2 -3
  5. package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
  6. package/dist/packages/cli/commands/export-docs.js +108 -101
  7. package/dist/packages/cli/commands/export-docs.js.map +1 -1
  8. package/dist/packages/cli/commands/export-slides.d.ts +10 -0
  9. package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
  10. package/dist/packages/cli/commands/export-slides.js +41 -26
  11. package/dist/packages/cli/commands/export-slides.js.map +1 -1
  12. package/dist/packages/docs/convert.d.ts.map +1 -1
  13. package/dist/packages/docs/convert.js +14 -10
  14. package/dist/packages/docs/convert.js.map +1 -1
  15. package/dist/packages/docs/import-docx.d.ts.map +1 -1
  16. package/dist/packages/docs/import-docx.js +256 -11
  17. package/dist/packages/docs/import-docx.js.map +1 -1
  18. package/dist/packages/shared/fetch-with-proxy.d.ts +13 -0
  19. package/dist/packages/shared/fetch-with-proxy.d.ts.map +1 -0
  20. package/dist/packages/shared/fetch-with-proxy.js +33 -0
  21. package/dist/packages/shared/fetch-with-proxy.js.map +1 -0
  22. package/dist/packages/shared/fonts.d.ts +73 -0
  23. package/dist/packages/shared/fonts.d.ts.map +1 -0
  24. package/dist/packages/shared/fonts.js +251 -0
  25. package/dist/packages/shared/fonts.js.map +1 -0
  26. package/dist/packages/slides/common.d.ts +4 -0
  27. package/dist/packages/slides/common.d.ts.map +1 -1
  28. package/dist/packages/slides/convert.d.ts.map +1 -1
  29. package/dist/packages/slides/convert.js +34 -4
  30. package/dist/packages/slides/convert.js.map +1 -1
  31. package/dist/packages/slides/fonts.d.ts +4 -37
  32. package/dist/packages/slides/fonts.d.ts.map +1 -1
  33. package/dist/packages/slides/fonts.js +4 -205
  34. package/dist/packages/slides/fonts.js.map +1 -1
  35. package/dist/packages/slides/vendor/pptxgen.d.ts +2 -0
  36. package/dist/packages/slides/vendor/pptxgen.js +2 -1
  37. 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
- if (!content) {
45098
- return `<${tag}${styleAttr}>&nbsp;</${tag}>`;
45099
- }
45100
- return `<${tag}${styleAttr}>${content}</${tag}>`;
45190
+ const finalContent = content || "&nbsp;";
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 (const row of table.rows) {
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 = ["padding:4px 8px"];
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
- html += renderParagraphToHtml(para, styleMap, numberingMap, imageMap, docDefaults);
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
- html += renderTableToHtml(nestedTable, styleMap, numberingMap, themeColors, imageMap, docDefaults);
45381
+ cellContent += renderTableToHtml(nestedTable, styleMap, numberingMap, themeColors, imageMap, docDefaults);
45193
45382
  }
45194
45383
  }
45384
+ if (!cellContent.trim()) {
45385
+ cellContent = "&nbsp;";
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/slides/fonts.ts
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 PPTX export for maximum fidelity.
45799
- // PowerPoint will render these correctly if the fonts are installed,
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": options.font,
72424
- "w:hAnsi": options.font,
72425
- "w:cs": options.font
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: run.fontFamily,
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: run.fontFamily,
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: run.fontFamily,
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
- async function fetchExternalImages(browser2, htmlPath) {
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 absoluteHtmlPath = path3.resolve(htmlPath);
73520
- if (!fs3.existsSync(absoluteHtmlPath)) {
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 page = await browser2.newPage({
73524
- viewport: { width: 1200, height: 800 }
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 ${uniqueSrcs.length} external image(s)...`);
73540
- for (const src of uniqueSrcs) {
73541
- try {
73542
- const imageData = await page.evaluate(async ({ src: src2, maxWidth }) => {
73543
- return new Promise((resolve5) => {
73544
- const img = new Image();
73545
- img.crossOrigin = "anonymous";
73546
- img.onload = () => {
73547
- try {
73548
- let width = img.naturalWidth;
73549
- let height = img.naturalHeight;
73550
- if (width > maxWidth) {
73551
- const scale = maxWidth / width;
73552
- width = maxWidth;
73553
- height = Math.round(height * scale);
73554
- }
73555
- const canvas = document.createElement("canvas");
73556
- canvas.width = width;
73557
- canvas.height = height;
73558
- const ctx = canvas.getContext("2d");
73559
- if (!ctx) {
73560
- resolve5(null);
73561
- return;
73562
- }
73563
- ctx.drawImage(img, 0, 0, width, height);
73564
- const dataUrl = canvas.toDataURL("image/png");
73565
- const base64 = dataUrl.split(",")[1];
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
- } catch (err) {
73600
- console.warn(`Failed to fetch image ${src}:`, err);
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 launchOptions = { headless: true };
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 htmlContents = [];
73852
- for (const p of absolutePaths) {
73853
- let html = fs4.readFileSync(p, "utf-8");
73854
- html = await embedExternalImages(html);
73855
- htmlContents.push(html);
73856
- }
73857
- const pageHtml = `<!DOCTYPE html>
73858
- <html>
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";