docgen-utils 1.0.20 → 1.0.21

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/cli.js CHANGED
@@ -43617,11 +43617,18 @@ async function loadZipSafely(arrayBuffer) {
43617
43617
  }
43618
43618
 
43619
43619
  // node_modules/rtf.js/index.js
43620
+ var rtf_exports = {};
43621
+ __export(rtf_exports, {
43622
+ EMFJS: () => EMFJS,
43623
+ RTFJS: () => RTFJS,
43624
+ WMFJS: () => WMFJS
43625
+ });
43620
43626
  var RTFJS = __toESM(require_RTFJS_bundle());
43621
43627
  var EMFJS = __toESM(require_EMFJS_bundle());
43622
43628
  var WMFJS = __toESM(require_WMFJS_bundle());
43623
43629
 
43624
43630
  // packages/docs/import-docx.ts
43631
+ var { EMFJS: EMFJS2 } = rtf_exports;
43625
43632
  var TWIPS_PER_PX = 1440 / 96;
43626
43633
  var EMU_PER_PX = 914400 / 96;
43627
43634
  var HALF_POINTS_TO_PT = 0.5;
@@ -43872,7 +43879,7 @@ async function convertEmfToSvg(buffer2) {
43872
43879
  console.log = () => {
43873
43880
  };
43874
43881
  try {
43875
- const renderer = new EMFJS.Renderer(buffer2);
43882
+ const renderer = new EMFJS2.Renderer(buffer2);
43876
43883
  const svg = renderer.render({
43877
43884
  width: boundsWidth + "px",
43878
43885
  height: boundsHeight + "px",
@@ -46414,6 +46421,34 @@ function parseDecorativeShapes(spTree, scale, themeColors, imageMap, themeFonts)
46414
46421
  }
46415
46422
  function parseGroupShape(grpSp, scale, themeColors, imageMap, themeFonts) {
46416
46423
  const elements = [];
46424
+ const grpSpPr = findChild2(grpSp, "grpSpPr");
46425
+ const xfrm = grpSpPr ? findChild2(grpSpPr, "xfrm") : null;
46426
+ const grpOff = xfrm ? findChild2(xfrm, "off") : null;
46427
+ const grpExt = xfrm ? findChild2(xfrm, "ext") : null;
46428
+ const chOff = xfrm ? findChild2(xfrm, "chOff") : null;
46429
+ const chExt = xfrm ? findChild2(xfrm, "chExt") : null;
46430
+ const hasTransform = !!(grpOff && grpExt && chOff && chExt);
46431
+ const grpOffX = parseInt(grpOff?.getAttribute("x") ?? "0", 10);
46432
+ const grpOffY = parseInt(grpOff?.getAttribute("y") ?? "0", 10);
46433
+ const grpExtCx = parseInt(grpExt?.getAttribute("cx") ?? "0", 10);
46434
+ const grpExtCy = parseInt(grpExt?.getAttribute("cy") ?? "0", 10);
46435
+ const chOffX = parseInt(chOff?.getAttribute("x") ?? "0", 10);
46436
+ const chOffY = parseInt(chOff?.getAttribute("y") ?? "0", 10);
46437
+ const chExtCx = parseInt(chExt?.getAttribute("cx") ?? "1", 10);
46438
+ const chExtCy = parseInt(chExt?.getAttribute("cy") ?? "1", 10);
46439
+ const scaleX = grpExtCx / chExtCx;
46440
+ const scaleY = grpExtCy / chExtCy;
46441
+ function remapCoords(el) {
46442
+ if (!hasTransform) return;
46443
+ const childXEmu = el.x / scale * EMU_PER_PX2;
46444
+ const childYEmu = el.y / scale * EMU_PER_PX2;
46445
+ const childWEmu = el.w / scale * EMU_PER_PX2;
46446
+ const childHEmu = el.h / scale * EMU_PER_PX2;
46447
+ el.x = Math.round(emuToPx2(grpOffX + (childXEmu - chOffX) * scaleX) * scale);
46448
+ el.y = Math.round(emuToPx2(grpOffY + (childYEmu - chOffY) * scaleY) * scale);
46449
+ el.w = Math.round(emuToPx2(childWEmu * scaleX) * scale);
46450
+ el.h = Math.round(emuToPx2(childHEmu * scaleY) * scale);
46451
+ }
46417
46452
  for (let i = 0; i < grpSp.children.length; i++) {
46418
46453
  const child = grpSp.children[i];
46419
46454
  if (child.localName === "sp") {
@@ -46431,16 +46466,23 @@ function parseGroupShape(grpSp, scale, themeColors, imageMap, themeFonts) {
46431
46466
  const shape2 = parseShape(child, scale, themeColors, themeFonts);
46432
46467
  if (shape2) {
46433
46468
  shape2.clipPath = clipPath;
46469
+ remapCoords(shape2);
46434
46470
  elements.push({ kind: "shape", data: shape2 });
46435
46471
  }
46436
46472
  continue;
46437
46473
  }
46438
46474
  }
46439
46475
  const shape = parseShape(child, scale, themeColors, themeFonts);
46440
- if (shape) elements.push({ kind: "shape", data: shape });
46476
+ if (shape) {
46477
+ remapCoords(shape);
46478
+ elements.push({ kind: "shape", data: shape });
46479
+ }
46441
46480
  } else if (child.localName === "pic") {
46442
46481
  const img = parsePicture(child, scale, imageMap);
46443
- if (img) elements.push({ kind: "image", data: img });
46482
+ if (img) {
46483
+ remapCoords(img);
46484
+ elements.push({ kind: "image", data: img });
46485
+ }
46444
46486
  } else if (child.localName === "grpSp") {
46445
46487
  const nested = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
46446
46488
  elements.push(...nested);
@@ -46616,6 +46658,27 @@ function parseShape(sp, scale, themeColors, themeFonts) {
46616
46658
  }
46617
46659
  }
46618
46660
  }
46661
+ const effectLst = findChild2(spPr, "effectLst");
46662
+ if (effectLst) {
46663
+ const outerShdw = findChild2(effectLst, "outerShdw");
46664
+ if (outerShdw) {
46665
+ const blurRad = parseInt(outerShdw.getAttribute("blurRad") ?? "0", 10);
46666
+ const blurPx = Math.round(emuToPx2(blurRad) * scale);
46667
+ let shadowColor = "rgba(0,0,0,0.3)";
46668
+ const prstClr = findChild2(outerShdw, "prstClr");
46669
+ const srgbClr = findChild2(outerShdw, "srgbClr");
46670
+ if (prstClr || srgbClr) {
46671
+ const colorEl = prstClr ?? srgbClr;
46672
+ const alphaEl = colorEl ? findChild2(colorEl, "alpha") : null;
46673
+ const alphaVal = alphaEl ? parseInt(alphaEl.getAttribute("val") ?? "100000", 10) / 1e5 : 1;
46674
+ const baseColor = prstClr?.getAttribute("val") === "black" ? "0,0,0" : prstClr?.getAttribute("val") === "white" ? "255,255,255" : "0,0,0";
46675
+ shadowColor = `rgba(${baseColor},${alphaVal})`;
46676
+ }
46677
+ if (blurPx > 0) {
46678
+ shape.boxShadow = `0 0 ${blurPx}px ${shadowColor}`;
46679
+ }
46680
+ }
46681
+ }
46619
46682
  const txBody = findChild2(sp, "txBody");
46620
46683
  if (txBody) {
46621
46684
  const bodyPr = findChild2(txBody, "bodyPr");
@@ -47764,6 +47827,9 @@ function renderSlideHtml(elements, bgColor, contentOffsetX = 0) {
47764
47827
  styles.push(`border:${shape.borderWidth}px ${borderStyle} ${shape.borderColor}`);
47765
47828
  styles.push("box-sizing:border-box");
47766
47829
  }
47830
+ if (shape.boxShadow) {
47831
+ styles.push(`box-shadow:${shape.boxShadow}`);
47832
+ }
47767
47833
  if (shape.padding) {
47768
47834
  styles.push(
47769
47835
  `padding:${shape.padding.top}px ${shape.padding.right}px ${shape.padding.bottom}px ${shape.padding.left}px`
@@ -48153,6 +48219,9 @@ async function importPptx(arrayBuffer) {
48153
48219
  } else if (child.localName === "pic") {
48154
48220
  const img = parsePicture(child, scale, imageMap);
48155
48221
  if (img) elements.push({ kind: "image", data: img });
48222
+ } else if (child.localName === "grpSp") {
48223
+ const grpElements = parseGroupShape(child, scale, themeColors, imageMap, themeFonts);
48224
+ elements.push(...grpElements);
48156
48225
  } else if (child.localName === "graphicFrame") {
48157
48226
  const table = parseTable2(child, scale, themeColors, themeFonts, tableStyleMap);
48158
48227
  if (table) {
@@ -71545,7 +71614,33 @@ function detectTimeline(element, cssContext) {
71545
71614
  }
71546
71615
 
71547
71616
  // packages/docs/parse.ts
71548
- function parseContainerContent(element, cssContext, inheritedColor) {
71617
+ function createParsedImageElement(imageEl, imageKey) {
71618
+ const src = imageEl.getAttribute("src")?.trim();
71619
+ if (!src) {
71620
+ return null;
71621
+ }
71622
+ const alt = imageEl.getAttribute("alt") || void 0;
71623
+ let width;
71624
+ let height;
71625
+ const widthAttr = imageEl.getAttribute("width");
71626
+ const heightAttr = imageEl.getAttribute("height");
71627
+ if (widthAttr && !widthAttr.includes("%")) {
71628
+ width = parseInt(widthAttr, 10) || void 0;
71629
+ }
71630
+ if (heightAttr && !heightAttr.includes("%")) {
71631
+ height = parseInt(heightAttr, 10) || void 0;
71632
+ }
71633
+ let caption;
71634
+ const parentFigure = imageEl.closest("figure");
71635
+ if (parentFigure) {
71636
+ const figcaption = parentFigure.querySelector("figcaption");
71637
+ if (figcaption) {
71638
+ caption = getTextContent(figcaption).trim() || void 0;
71639
+ }
71640
+ }
71641
+ return { type: "image", imageKey, src, alt, width, height, caption };
71642
+ }
71643
+ function parseContainerContent(element, cssContext, nextImageKey, inheritedColor) {
71549
71644
  const innerElements = [];
71550
71645
  function processInnerNode(node, color) {
71551
71646
  if (node.nodeType === Node.TEXT_NODE) {
@@ -71728,7 +71823,7 @@ function parseContainerContent(element, cssContext, inheritedColor) {
71728
71823
  }
71729
71824
  return innerElements;
71730
71825
  }
71731
- function parseBlockquoteContent(element, cssContext) {
71826
+ function parseBlockquoteContent(element, cssContext, nextImageKey) {
71732
71827
  const innerElements = [];
71733
71828
  const blockquoteStyles = getElementStyles(element, cssContext);
71734
71829
  const blockquoteIsItalic = blockquoteStyles.fontStyle === "italic";
@@ -71842,7 +71937,7 @@ function parseBlockquoteContent(element, cssContext) {
71842
71937
  }
71843
71938
  const nestedBorderHex = extractBorderColorFromStyle(styles);
71844
71939
  if (nestedBgColor || nestedBorderHex) {
71845
- const nestedContent = parseBlockquoteContent(el, cssContext);
71940
+ const nestedContent = parseBlockquoteContent(el, cssContext, nextImageKey);
71846
71941
  if (nestedContent.length > 0) {
71847
71942
  let nestedBorderStyle;
71848
71943
  if (styles.borderLeft && !styles.border) {
@@ -71895,28 +71990,9 @@ function parseBlockquoteContent(element, cssContext) {
71895
71990
  }
71896
71991
  }
71897
71992
  if (tagName19 === "img") {
71898
- const src = el.getAttribute("src")?.trim();
71899
- if (src) {
71900
- const alt = el.getAttribute("alt") || void 0;
71901
- let width;
71902
- let height;
71903
- const widthAttr = el.getAttribute("width");
71904
- const heightAttr = el.getAttribute("height");
71905
- if (widthAttr && !widthAttr.includes("%")) {
71906
- width = parseInt(widthAttr, 10) || void 0;
71907
- }
71908
- if (heightAttr && !heightAttr.includes("%")) {
71909
- height = parseInt(heightAttr, 10) || void 0;
71910
- }
71911
- let caption;
71912
- const parentFigure = el.closest("figure");
71913
- if (parentFigure) {
71914
- const figcaption = parentFigure.querySelector("figcaption");
71915
- if (figcaption) {
71916
- caption = getTextContent(figcaption).trim() || void 0;
71917
- }
71918
- }
71919
- innerElements.push({ type: "image", src, alt, width, height, caption });
71993
+ const imageElement = createParsedImageElement(el, nextImageKey());
71994
+ if (imageElement) {
71995
+ innerElements.push(imageElement);
71920
71996
  }
71921
71997
  return;
71922
71998
  }
@@ -72087,6 +72163,8 @@ function parseHtmlContent(html) {
72087
72163
  const elements = [];
72088
72164
  const cssContext = parseCssContext(doc);
72089
72165
  const processedSvgs = /* @__PURE__ */ new Set();
72166
+ let imageIndex = 0;
72167
+ const nextImageKey = () => `image-${imageIndex++}`;
72090
72168
  const { body } = doc;
72091
72169
  function processNode(node, inheritedAlignment, inheritedColor) {
72092
72170
  if (node.nodeType === Node.TEXT_NODE) {
@@ -72223,7 +72301,7 @@ function parseHtmlContent(html) {
72223
72301
  return;
72224
72302
  }
72225
72303
  if (tagName19 === "p" && isBlockquoteOrCallout(element, cssContext)) {
72226
- const content = parseBlockquoteContent(element, cssContext);
72304
+ const content = parseBlockquoteContent(element, cssContext, nextImageKey);
72227
72305
  if (content.length > 0) {
72228
72306
  const elementStyles = getElementStyles(element, cssContext);
72229
72307
  let borderColor;
@@ -72600,8 +72678,8 @@ function parseHtmlContent(html) {
72600
72678
  const sidebarStyles = getElementStyles(sidebarEl, cssContext);
72601
72679
  const sidebarBgColor = sidebarStyles.backgroundColor ? extractHexColor(sidebarStyles.backgroundColor) : void 0;
72602
72680
  const sidebarTextColor = sidebarStyles.color ? extractHexColor(sidebarStyles.color) : void 0;
72603
- const sidebarContent = parseContainerContent(sidebarEl, cssContext, sidebarTextColor);
72604
- const mainContent = parseContainerContent(mainEl, cssContext);
72681
+ const sidebarContent = parseContainerContent(sidebarEl, cssContext, nextImageKey, sidebarTextColor);
72682
+ const mainContent = parseContainerContent(mainEl, cssContext, nextImageKey);
72605
72683
  if (sidebarContent.length > 0 || mainContent.length > 0) {
72606
72684
  elements.push({
72607
72685
  type: "two-column-layout",
@@ -72665,7 +72743,7 @@ function parseHtmlContent(html) {
72665
72743
  }
72666
72744
  const columnContents = [];
72667
72745
  for (const col of gridColumns) {
72668
- const colContent = parseContainerContent(col, cssContext);
72746
+ const colContent = parseContainerContent(col, cssContext, nextImageKey);
72669
72747
  columnContents.push(colContent);
72670
72748
  }
72671
72749
  const hasContent = columnContents.some((c) => c.length > 0);
@@ -73030,56 +73108,18 @@ function parseHtmlContent(html) {
73030
73108
  return;
73031
73109
  }
73032
73110
  if (tagName19 === "img") {
73033
- const src = element.getAttribute("src")?.trim();
73034
- if (src) {
73035
- const alt = element.getAttribute("alt") || void 0;
73036
- let width;
73037
- let height;
73038
- const widthAttr = element.getAttribute("width");
73039
- const heightAttr = element.getAttribute("height");
73040
- if (widthAttr && !widthAttr.includes("%")) {
73041
- width = parseInt(widthAttr, 10) || void 0;
73042
- }
73043
- if (heightAttr && !heightAttr.includes("%")) {
73044
- height = parseInt(heightAttr, 10) || void 0;
73045
- }
73046
- let caption;
73047
- const parentFigure = element.closest("figure");
73048
- if (parentFigure) {
73049
- const figcaption = parentFigure.querySelector("figcaption");
73050
- if (figcaption) {
73051
- caption = getTextContent(figcaption).trim() || void 0;
73052
- }
73053
- }
73054
- elements.push({ type: "image", src, alt, width, height, caption });
73111
+ const imageElement = createParsedImageElement(element, nextImageKey());
73112
+ if (imageElement) {
73113
+ elements.push(imageElement);
73055
73114
  }
73056
73115
  return;
73057
73116
  }
73058
73117
  if (tagName19 === "picture") {
73059
73118
  const imgEl = element.querySelector("img");
73060
73119
  if (imgEl) {
73061
- const src = imgEl.getAttribute("src")?.trim();
73062
- if (src) {
73063
- const alt = imgEl.getAttribute("alt") || void 0;
73064
- let width;
73065
- let height;
73066
- const widthAttr = imgEl.getAttribute("width");
73067
- const heightAttr = imgEl.getAttribute("height");
73068
- if (widthAttr && !widthAttr.includes("%")) {
73069
- width = parseInt(widthAttr, 10) || void 0;
73070
- }
73071
- if (heightAttr && !heightAttr.includes("%")) {
73072
- height = parseInt(heightAttr, 10) || void 0;
73073
- }
73074
- let caption;
73075
- const parentFigure = element.closest("figure");
73076
- if (parentFigure) {
73077
- const figcaption = parentFigure.querySelector("figcaption");
73078
- if (figcaption) {
73079
- caption = getTextContent(figcaption).trim() || void 0;
73080
- }
73081
- }
73082
- elements.push({ type: "image", src, alt, width, height, caption });
73120
+ const imageElement = createParsedImageElement(imgEl, nextImageKey());
73121
+ if (imageElement) {
73122
+ elements.push(imageElement);
73083
73123
  }
73084
73124
  }
73085
73125
  return;
@@ -73087,25 +73127,9 @@ function parseHtmlContent(html) {
73087
73127
  if (tagName19 === "figure") {
73088
73128
  const imgEl = element.querySelector("img") || element.querySelector("picture img");
73089
73129
  if (imgEl) {
73090
- const src = imgEl.getAttribute("src")?.trim();
73091
- if (src) {
73092
- const alt = imgEl.getAttribute("alt") || void 0;
73093
- let width;
73094
- let height;
73095
- const widthAttr = imgEl.getAttribute("width");
73096
- const heightAttr = imgEl.getAttribute("height");
73097
- if (widthAttr && !widthAttr.includes("%")) {
73098
- width = parseInt(widthAttr, 10) || void 0;
73099
- }
73100
- if (heightAttr && !heightAttr.includes("%")) {
73101
- height = parseInt(heightAttr, 10) || void 0;
73102
- }
73103
- let caption;
73104
- const figcaption = element.querySelector("figcaption");
73105
- if (figcaption) {
73106
- caption = getTextContent(figcaption).trim() || void 0;
73107
- }
73108
- elements.push({ type: "image", src, alt, width, height, caption });
73130
+ const imageElement = createParsedImageElement(imgEl, nextImageKey());
73131
+ if (imageElement) {
73132
+ elements.push(imageElement);
73109
73133
  return;
73110
73134
  }
73111
73135
  }
@@ -73117,7 +73141,7 @@ function parseHtmlContent(html) {
73117
73141
  return;
73118
73142
  }
73119
73143
  if (isBlockquoteOrCallout(element, cssContext)) {
73120
- const content = parseBlockquoteContent(element, cssContext);
73144
+ const content = parseBlockquoteContent(element, cssContext, nextImageKey);
73121
73145
  if (content.length > 0) {
73122
73146
  const elementStyles = getElementStyles(element, cssContext);
73123
73147
  let borderColor;
@@ -74520,8 +74544,14 @@ function createDocxDocument(html, options = {}) {
74520
74544
  if (imageMap && imageMap.size > 0) {
74521
74545
  let populateImageData2 = function(elements) {
74522
74546
  for (const element of elements) {
74523
- if (element.type === "image" && !element.imageData && imageMap.has(element.src)) {
74524
- element.imageData = imageMap.get(element.src);
74547
+ if (element.type === "image" && !element.imageData) {
74548
+ const lookupKeys = [element.imageKey, element.src].filter((key2) => Boolean(key2));
74549
+ for (const lookupKey of lookupKeys) {
74550
+ if (imageMap.has(lookupKey)) {
74551
+ element.imageData = imageMap.get(lookupKey);
74552
+ break;
74553
+ }
74554
+ }
74525
74555
  }
74526
74556
  if (element.type === "blockquote" && element.content) {
74527
74557
  populateImageData2(element.content);
@@ -74888,6 +74918,50 @@ function parseImageDimensions(data) {
74888
74918
  }
74889
74919
  return null;
74890
74920
  }
74921
+ function parseDataUriImages(htmlContent) {
74922
+ const imageMap = /* @__PURE__ */ new Map();
74923
+ const dataUriRegex = /<img\s+[^>]*src="\s*(data:image\/[^;]+;base64,[^"]+)\s*"[^>]*>/gi;
74924
+ const matches2 = [...htmlContent.matchAll(dataUriRegex)];
74925
+ if (matches2.length === 0) {
74926
+ return imageMap;
74927
+ }
74928
+ const dataUris = /* @__PURE__ */ new Set();
74929
+ for (const match of matches2) {
74930
+ dataUris.add(match[1]);
74931
+ }
74932
+ console.log(`Processing ${dataUris.size} inline base64 image(s)...`);
74933
+ for (const dataUri of dataUris) {
74934
+ try {
74935
+ const commaIndex = dataUri.indexOf(",");
74936
+ if (commaIndex === -1) {
74937
+ console.warn(`Invalid data URI format`);
74938
+ continue;
74939
+ }
74940
+ const base64Data = dataUri.slice(commaIndex + 1);
74941
+ const buffer2 = Buffer.from(base64Data, "base64");
74942
+ const data = new Uint8Array(buffer2);
74943
+ const dimensions = parseImageDimensions(data);
74944
+ if (!dimensions) {
74945
+ console.warn(`Could not parse dimensions for data URI image`);
74946
+ continue;
74947
+ }
74948
+ let { width, height } = dimensions;
74949
+ if (width > MAX_IMAGE_WIDTH) {
74950
+ const scale = MAX_IMAGE_WIDTH / width;
74951
+ width = MAX_IMAGE_WIDTH;
74952
+ height = Math.round(height * scale);
74953
+ }
74954
+ imageMap.set(dataUri, {
74955
+ data: buffer2,
74956
+ width,
74957
+ height
74958
+ });
74959
+ } catch {
74960
+ console.warn(`Failed to parse data URI image`);
74961
+ }
74962
+ }
74963
+ return imageMap;
74964
+ }
74891
74965
  async function fetchExternalImages(htmlContent) {
74892
74966
  const imageMap = /* @__PURE__ */ new Map();
74893
74967
  const imgRegex = /<img\s+[^>]*src="\s*(https?:\/\/[^"]+?)\s*"[^>]*>/gi;
@@ -74931,14 +75005,87 @@ async function fetchExternalImages(htmlContent) {
74931
75005
  );
74932
75006
  return imageMap;
74933
75007
  }
74934
- async function renderChartImages(browser2, htmlPath) {
75008
+ async function renderHtmlImages(browser2, htmlPath, elements) {
75009
+ const renderedImages = /* @__PURE__ */ new Map();
75010
+ const absoluteHtmlPath = path3.resolve(htmlPath);
75011
+ if (!fs3.existsSync(absoluteHtmlPath)) {
75012
+ return renderedImages;
75013
+ }
75014
+ const htmlImageElements = [];
75015
+ function collectImages(els) {
75016
+ for (const el of els) {
75017
+ if (el.type === "image") {
75018
+ htmlImageElements.push(el);
75019
+ } else if (el.type === "blockquote" && el.content) {
75020
+ collectImages(el.content);
75021
+ } else if (el.type === "two-column-layout") {
75022
+ collectImages(el.sidebar.content);
75023
+ collectImages(el.main.content);
75024
+ }
75025
+ }
75026
+ }
75027
+ collectImages(elements);
75028
+ if (htmlImageElements.length === 0) {
75029
+ return renderedImages;
75030
+ }
75031
+ console.log(`Rendering ${htmlImageElements.length} HTML image(s)...`);
75032
+ const page = await browser2.newPage({
75033
+ viewport: { width: 1200, height: 800 }
75034
+ });
75035
+ try {
75036
+ await page.goto(`file://${absoluteHtmlPath}`, {
75037
+ waitUntil: "networkidle"
75038
+ });
75039
+ await page.waitForTimeout(500);
75040
+ const domImageCount = await page.evaluate(() => {
75041
+ let imageIndex = 0;
75042
+ for (const img of Array.from(document.querySelectorAll("img"))) {
75043
+ const src = img.getAttribute("src")?.trim();
75044
+ if (!src) {
75045
+ continue;
75046
+ }
75047
+ img.setAttribute("data-docgen-image-index", String(imageIndex));
75048
+ imageIndex++;
75049
+ }
75050
+ return imageIndex;
75051
+ });
75052
+ if (domImageCount !== htmlImageElements.length) {
75053
+ console.warn(`HTML image count mismatch: parsed ${htmlImageElements.length}, DOM ${domImageCount}`);
75054
+ }
75055
+ for (let i = 0; i < htmlImageElements.length; i++) {
75056
+ const imageElement = htmlImageElements[i];
75057
+ if (!imageElement.imageKey) {
75058
+ continue;
75059
+ }
75060
+ const imgEl = await page.$(`img[data-docgen-image-index="${i}"]`);
75061
+ if (!imgEl) {
75062
+ continue;
75063
+ }
75064
+ const box = await imgEl.boundingBox();
75065
+ if (!box || box.width < 1 || box.height < 1) {
75066
+ continue;
75067
+ }
75068
+ const screenshot = await imgEl.screenshot({
75069
+ type: "png"
75070
+ });
75071
+ const scale = box.width > MAX_IMAGE_WIDTH ? MAX_IMAGE_WIDTH / box.width : 1;
75072
+ renderedImages.set(imageElement.imageKey, {
75073
+ data: screenshot,
75074
+ width: Math.round(box.width * scale),
75075
+ height: Math.round(box.height * scale)
75076
+ });
75077
+ }
75078
+ } finally {
75079
+ await page.close();
75080
+ }
75081
+ return renderedImages;
75082
+ }
75083
+ async function renderChartImages(browser2, htmlPath, elements) {
74935
75084
  const chartImages = /* @__PURE__ */ new Map();
74936
75085
  const absoluteHtmlPath = path3.resolve(htmlPath);
74937
75086
  if (!fs3.existsSync(absoluteHtmlPath)) {
74938
75087
  return chartImages;
74939
75088
  }
74940
- const htmlContent = fs3.readFileSync(absoluteHtmlPath, "utf-8");
74941
- const elements = parseHtmlContent(htmlContent);
74942
75089
  const svgChartElements = [];
74943
75090
  function collectSvgCharts(els) {
74944
75091
  for (const el of els) {
@@ -75050,21 +75197,32 @@ async function exportDocs(filePath, outDir, options = {}) {
75050
75197
  }
75051
75198
  console.log(`Exporting to DOCX: ${filePath}`);
75052
75199
  const html = fs3.readFileSync(absolutePath, "utf-8");
75200
+ const elements = parseHtmlContent(html);
75053
75201
  const baseName = outputName || path3.basename(filePath, ".html");
75054
75202
  const imageMap = await fetchExternalImages(html);
75203
+ const dataUriImages = parseDataUriImages(html);
75204
+ for (const [uri2, data] of dataUriImages) {
75205
+ imageMap.set(uri2, data);
75206
+ }
75055
75207
  const launchOptions = { headless: true };
75056
75208
  const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
75057
75209
  if (proxyServer) {
75058
75210
  launchOptions.proxy = { server: proxyServer };
75059
75211
  }
75060
75212
  const browser2 = await chromium.launch(launchOptions);
75213
+ let renderedImages;
75061
75214
  let chartImages;
75062
75215
  try {
75063
- chartImages = await renderChartImages(browser2, absolutePath);
75216
+ [renderedImages, chartImages] = await Promise.all([
75217
+ renderHtmlImages(browser2, absolutePath, elements),
75218
+ renderChartImages(browser2, absolutePath, elements)
75219
+ ]);
75064
75220
  } finally {
75065
75221
  await browser2.close();
75066
75222
  }
75067
- const elements = parseHtmlContent(html);
75223
+ for (const [imageKey, data] of renderedImages) {
75224
+ imageMap.set(imageKey, data);
75225
+ }
75068
75226
  const buffer2 = await createDocxBuffer(html, {
75069
75227
  title: baseName,
75070
75228
  elements,
@@ -1 +1 @@
1
- {"version":3,"file":"export-docs.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-docs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+TH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDjH"}
1
+ {"version":3,"file":"export-docs.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-docs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoeH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoEjH"}