@docen/import-docx 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -89,10 +89,10 @@ interface DocxImportOptions {
89
89
 
90
90
  /**
91
91
  * Enable or disable image cropping during import
92
- * When true (default), images with crop information in DOCX will be cropped
93
- * When false, crop information is ignored and full image is used
92
+ * When true, images with crop information in DOCX will be cropped
93
+ * When false (default), crop information is ignored and full image is used
94
94
  *
95
- * @default true
95
+ * @default false
96
96
  */
97
97
  enableImageCrop?: boolean;
98
98
  }
@@ -220,7 +220,7 @@ async function importDocx(file: File) {
220
220
 
221
221
  ### Node.js Environment with Image Cropping
222
222
 
223
- In Node.js environment, you need to provide `@napi-rs/canvas` for image cropping:
223
+ To enable image cropping in Node.js environment, you need to provide `@napi-rs/canvas`:
224
224
 
225
225
  ```typescript
226
226
  import { parseDOCX } from "@docen/import-docx";
@@ -231,13 +231,15 @@ const buffer = readFileSync("document.docx");
231
231
 
232
232
  const content = await parseDOCX(buffer, {
233
233
  canvasImport: () => import("@napi-rs/canvas"),
234
- enableImageCrop: true, // default is true
234
+ enableImageCrop: true, // Enable cropping (default is false)
235
235
  });
236
236
  ```
237
237
 
238
+ **Note:** By default, image cropping is disabled. Images are imported in full size, ignoring crop information in DOCX.
239
+
238
240
  ### Disable Image Cropping
239
241
 
240
- If you want to ignore crop information in DOCX and use full images:
242
+ If you want to explicitly ignore crop information in DOCX and use full images (this is the default behavior):
241
243
 
242
244
  ```typescript
243
245
  const content = await parseDOCX(buffer, {
@@ -268,10 +270,11 @@ All colors are imported as hex values (e.g., "#FF0000", "#008000"). Color names
268
270
 
269
271
  - Only embedded images are supported (external image links are not fetched)
270
272
  - Image dimensions and title are extracted from DOCX metadata
271
- - **Image Cropping in Node.js**: Requires `@napi-rs/canvas` as an optional dependency
273
+ - **Image Cropping**: By default, images are imported in full size (crop information is ignored)
274
+ - To enable cropping, set `enableImageCrop: true` in options
272
275
  - In browser environments, cropping works natively with Canvas API
273
- - In Node.js, you must provide `canvasImport` option with dynamic import of `@napi-rs/canvas`
274
- - If `@napi-rs/canvas` is not available, images will be imported without cropping (graceful degradation)
276
+ - In Node.js, you must also provide `canvasImport` option with dynamic import of `@napi-rs/canvas`
277
+ - If `@napi-rs/canvas` is not available in Node.js, images will be imported without cropping (graceful degradation)
275
278
  - Some DOCX image features (like advanced positioning or text wrapping) have limited support
276
279
 
277
280
  ### Table Cell Types
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const xastUtilFromXml=require("xast-util-from-xml"),fflate=require("fflate"),undio=require("undio"),imageMeta=require("image-meta");function findChild(n,t){for(const e of n.children)if(e.type==="element"&&e.name===t)return e}function findDeepChild(n,t){for(const e of n.children){if(e.type==="element"&&e.name===t)return e;if(e.type==="element"){const r=findDeepChild(e,t);if(r)return r}}}function findDeepChildren(n,t){const e=[];for(const r of n.children)r.type==="element"&&r.name===t&&e.push(r),r.type==="element"&&e.push(...findDeepChildren(r,t));return e}const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function uint8ArrayToBase64(n){const t=n.length,e=Math.ceil(t/3)*4,r=Array.from({length:e});let i=0;for(let c=0;c<t;c+=3){const l=n[c],f=c+1<t?n[c+1]:0,b=c+2<t?n[c+2]:0,I=l>>2,k=(l&3)<<4|f>>4,R=(f&15)<<2|b>>6,P=b&63;r[i++]=s[I],r[i++]=s[k],r[i++]=c+1<t?s[R]:"=",r[i++]=c+2<t?s[P]:"="}return r.join("")}function base64ToUint8Array(n){const t=atob(n),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}const isNode=globalThis.process?.release?.name==="node",isBrowser=typeof window<"u";async function h$2(n){const t=await n;return t.default||t}let o,u$1=class{#t=!1;constructor({enableHWA:t=!1}={}){this.#t=t}create(t,e){const r=this._createCanvas(t,e);return{canvas:r,context:r.getContext("2d",{willReadFrequently:!this.#t})}}reset({canvas:t},e,r){if(!t)throw new Error("Canvas is not specified");t.width=e,t.height=r}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0,t.canvas.height=0,t.canvas=void 0,t.context=void 0}_createCanvas(t,e){throw new Error("Not implemented")}};class DOMCanvasFactory extends u$1{_document;constructor({ownerDocument:t=globalThis.document,enableHWA:e=!1}={}){super({enableHWA:e}),this._document=t}_createCanvas(t,e){const r=this._document.createElement("canvas");return r.width=t,r.height=e,r}}class NodeCanvasFactory extends u$1{constructor({enableHWA:t=!1}={}){super({enableHWA:t})}_createCanvas(t,e){if(!o)throw new Error("@napi-rs/canvas module is not resolved");return o.createCanvas(t,e)}}async function resolveCanvasModule(n){o??=await h$2(n())}async function createCanvasFactory(n){if(isBrowser)return DOMCanvasFactory;if(isNode){if(!n)throw new Error("In Node.js environment, @napi-rs/canvas is required for image cropping. Please provide canvasImport parameter or install it: pnpm add @napi-rs/canvas");return await resolveCanvasModule(n),NodeCanvasFactory}throw new Error("Unsupported environment for canvas operations")}async function cropImageIfNeeded(n,t,e={}){if(!t||!t.left&&!t.top&&!t.right&&!t.bottom||e.enabled===!1)return n;try{const r=await createCanvasFactory(e.canvasImport),i=await w$1(n,r),c=(t.left||0)/1e5*i.width,l=(t.top||0)/1e5*i.height,f=(t.right||0)/1e5*i.width,b=(t.bottom||0)/1e5*i.height,I=Math.round(i.width-c-f),k=Math.round(i.height-l-b);if(I<=0||k<=0)return console.warn("Invalid crop dimensions, returning original image"),n;const R=new r().create(I,k);if(!R.context)throw new Error("Failed to get 2D context from canvas");R.context.drawImage(i,c,l,I,k,0,0,I,k);const P=R.canvas.toDataURL(),F=await(await fetch(P)).arrayBuffer();return new Uint8Array(F)}catch(r){return console.warn("Image cropping failed, returning original image:",r),n}}async function w$1(n,t){if(isBrowser){const e=new Blob([n.buffer]),r=URL.createObjectURL(e);try{const i=new Image;return new Promise((c,l)=>{i.onload=()=>{URL.revokeObjectURL(r),c(i)},i.onerror=()=>{URL.revokeObjectURL(r),l(new Error("Failed to load image"))},i.src=r})}catch(i){throw URL.revokeObjectURL(r),i}}else{if(!o)throw new Error("@napi-rs/canvas module is not resolved");return await o.loadImage(Buffer.from(n))}}const j="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";function C$1(n){const t=parseInt(n,10);if(!isNaN(t))return Math.round(t/9525)}function B(n){const t=n.attributes.l,e=n.attributes.t,r=n.attributes.r,i=n.attributes.b;if(!(!t&&!e&&!r&&!i))return{left:t?parseInt(t,10):void 0,top:e?parseInt(e,10):void 0,right:r?parseInt(r,10):void 0,bottom:i?parseInt(i,10):void 0}}function N(n){const t=findChild(n,"wp:align"),e=findChild(n,"wp:posOffset"),r=t?.children[0]?.type==="text"?t.children[0].value:void 0,i=e?.children[0]?.type==="text"?parseInt(e.children[0].value,10):void 0;if(!(!r&&i===void 0))return{...r&&{align:r},...i!==void 0&&{offset:i}}}function findDrawingElement(n){let t=findChild(n,"w:drawing");if(t)return t;const e=findChild(n,"mc:AlternateContent"),r=e&&findChild(e,"mc:Choice");return r&&findChild(r,"w:drawing")}function O$1(n,t,e,r){const i=e/r,c=n/t;return Math.abs(i-c)>.1?i>c?{width:n,height:Math.round(n/i)}:{width:Math.round(t*i),height:t}:{width:n,height:t}}function extractImages(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=findChild(r,"Relationships");if(!i)return t;const c=findDeepChildren(i,"Relationship");for(const l of c)if(l.attributes.Type===j&&l.attributes.Id&&l.attributes.Target){const f="word/"+l.attributes.Target,b=n[f];if(!b)continue;let I,k,R="png";try{const $=imageMeta.imageMeta(b);I=$.width,k=$.height,$.type&&(R=$.type)}catch{}const P=uint8ArrayToBase64(b),F=`data:image/${R};base64,${P}`;t.set(l.attributes.Id,{src:F,width:I,height:k})}return t}async function extractImageFromDrawing(n,t){const{images:e,options:r}=t,i=findDeepChild(n,"a:blip");if(!i?.attributes["r:embed"])return null;const c=i.attributes["r:embed"],l=e.get(c);if(!l)return null;let f=l.src;const b=findDeepChild(n,"a:srcRect");if(b){const D=B(b);if(D&&f.startsWith("data:")){const[U,_]=f.split(",");if(_){const V=base64ToUint8Array(_);try{const q=await cropImageIfNeeded(V,D,{canvasImport:r?.canvasImport,enabled:r?.enableImageCrop!==!1}),G=uint8ArrayToBase64(q);f=`${U},${G}`}catch(q){console.warn("Image cropping failed, using original image:",q)}}}}const I=findDeepChild(n,"wp:extent");let k,R;if(I){const D=I.attributes.cx,U=I.attributes.cy;typeof D=="string"&&(k=C$1(D)),typeof U=="string"&&(R=C$1(U))}const P=findDeepChild(n,"a:xfrm");let F;if(P?.attributes.rot){const D=parseInt(P.attributes.rot,10);isNaN(D)||(F=D/6e4)}const $=findDeepChild(n,"wp:docPr")?.attributes.title,W=findDeepChild(n,"wp:positionH"),z=findDeepChild(n,"wp:positionV");let E;if(W||z){const D=W?N(W):void 0,U=z?N(z):void 0;E={horizontalPosition:{relative:W?.attributes.relativeFrom||"page",...D?.align&&{align:D.align},...D?.offset!==void 0&&{offset:D.offset}},verticalPosition:{relative:z?.attributes.relativeFrom||"page",...U?.align&&{align:U.align},...U?.offset!==void 0&&{offset:U.offset}}}}const H=findDeepChild(n,"pic:spPr");let X;if(H){const D=findDeepChild(H,"a:ln"),U=D&&findDeepChild(D,"a:solidFill"),_=U&&findDeepChild(U,"a:srgbClr");_?.attributes.val&&(X={type:"solidFill",solidFillType:"rgb",value:_.attributes.val})}return{type:"image",attrs:{src:f,alt:"",...k!==void 0&&{width:k},...R!==void 0&&{height:R},...F!==void 0&&{rotation:F},...$&&{title:$},...E&&{floating:E},...X&&{outline:X}}}}function S$2(n,t,e){if(t&&e&&n.width&&n.height){const r=O$1(t,e,n.width,n.height);return{type:"image",attrs:{src:n.src,alt:"",width:r.width,height:r.height}}}return{type:"image",attrs:{src:n.src,alt:"",...t!==void 0&&{width:t},...e!==void 0&&{height:e}}}}async function extractImagesFromDrawing(n,t){const e=[],r=findChild(n,"wp:inline")||findChild(n,"wp:anchor");if(!r)return e;const i=findChild(r,"wp:extent");let c,l;if(i){const k=i.attributes.cx,R=i.attributes.cy;typeof k=="string"&&(c=C$1(k)),typeof R=="string"&&(l=C$1(R))}const f=findChild(r,"a:graphic");if(!f)return e;const b=findChild(f,"a:graphicData");if(!b)return e;const I=findChild(b,"wpg:wgp");if(I){const k=findChild(I,"wpg:grpSp"),R=k?[...findDeepChildren(k,"pic:pic"),...findDeepChildren(k,"pic")]:[...findDeepChildren(I,"pic:pic"),...findDeepChildren(I,"pic")];for(const P of R){const F=findChild(P,"a:graphic");if(!F){const E=findChild(P,"pic:blipFill")||findDeepChild(P,"a:blipFill");if(!E)continue;const H=findChild(E,"a:blip")||findDeepChild(E,"a:blip");if(!H?.attributes["r:embed"])continue;const X=H.attributes["r:embed"],D=t.images.get(X);if(!D)continue;e.push(S$2(D,c,l));continue}const $={children:[F]},W=await extractImageFromDrawing($,t);if(!W)continue;const z=$.children[0]?.type==="element"?findDeepChild($.children[0],"a:blip")?.attributes["r:embed"]:void 0;if(c&&l&&z){const E=t.images.get(z);if(E?.width&&E?.height){const H=O$1(c,l,E.width,E.height);W.attrs.width=H.width,W.attrs.height=H.height}else W.attrs.width=c,W.attrs.height=l}e.push(W)}}else{const k=await extractImageFromDrawing(n,t);k&&e.push(k)}return e}const p="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";function extractHyperlinks(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=findChild(r,"Relationships");if(!i)return t;const c=findDeepChildren(i,"Relationship");for(const l of c)l.attributes.Type===p&&l.attributes.Id&&l.attributes.Target&&t.set(l.attributes.Id,l.attributes.Target);return t}function parseNumberingXml(n){const t=new Map,e=new Map,r=n["word/numbering.xml"];if(!r)return t;const i=xastUtilFromXml.fromXml(new TextDecoder().decode(r)),c=new Map,l=findChild(i,"w:numbering");if(!l)return t;const f=findDeepChildren(l,"w:abstractNum");for(const I of f){const k=I.attributes["w:abstractNumId"],R=findChild(I,"w:lvl");if(!R)continue;const P=findChild(R,"w:numFmt");P?.attributes["w:val"]&&c.set(k,P.attributes["w:val"]);const F=findChild(R,"w:start");F?.attributes["w:val"]&&e.set(k,parseInt(F.attributes["w:val"],10))}const b=findDeepChildren(l,"w:num");for(const I of b){const k=I.attributes["w:numId"],R=findChild(I,"w:abstractNumId");if(!R?.attributes["w:val"])continue;const P=R.attributes["w:val"],F=c.get(P);if(!F)continue;const $=e.get(P);F==="bullet"?t.set(k,{type:"bullet"}):t.set(k,{type:"ordered",...$!==void 0&&{start:$}})}return t}function parseStylesXml(n){const t=new Map,e=n["word/styles.xml"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=findChild(r,"w:styles");if(!i)return t;const c=findDeepChildren(i,"w:style").filter(l=>l.attributes["w:type"]==="paragraph");for(const l of c){const f=l.attributes["w:styleId"];if(!f)continue;const b={styleId:f},I=findChild(l,"w:name");I?.attributes["w:val"]&&(b.name=I.attributes["w:val"]);const k=findChild(l,"w:pPr");if(k){const P=findChild(k,"w:outlineLvl");P?.attributes["w:val"]!==void 0&&(b.outlineLvl=parseInt(P.attributes["w:val"],10))}const R=findChild(l,"w:rPr");if(R){const P={},F=findChild(R,"w:color");if(F?.attributes["w:val"]&&F.attributes["w:val"]!=="auto"){const z=F.attributes["w:val"];P.color=z.startsWith("#")?z:`#${z}`}findChild(R,"w:b")&&(P.bold=!0),findChild(R,"w:i")&&(P.italic=!0),findChild(R,"w:u")&&(P.underline=!0),findChild(R,"w:strike")&&(P.strike=!0);const $=findChild(R,"w:sz");if($?.attributes["w:val"]){const z=$.attributes["w:val"],E=parseInt(z,10);isNaN(E)||(P.fontSize=E)}const W=findChild(R,"w:rFonts");W?.attributes["w:ascii"]&&(P.fontFamily=W.attributes["w:ascii"]),Object.keys(P).length>0&&(b.charFormat=P)}t.set(f,b)}return t}function d(n,t){const e=findChild(n,"w:t");if(!e)return null;const r=e.children.find(c=>c.type==="text");if(!r?.value)return null;const i=extractMarks(n,t);return{type:"text",text:r.value,...i.length&&{marks:i}}}async function extractRuns(n,t){const e=[];for(const r of n.children)if(r.type==="element"){if(r.name==="w:hyperlink"){const i=r,c=i.attributes["r:id"],l=t.hyperlinks.get(c);if(!l)continue;for(const f of i.children){if(f.type!=="element"||f.name!=="w:r")continue;const b=f,I=findDrawingElement(b);if(I){const R=await extractImageFromDrawing(I,t);if(R){e.push(R);continue}const P=await extractImagesFromDrawing(I,t);if(P.length){e.push(...P);continue}}const k=d(b,t.styleInfo);k&&(k.marks=k.marks||[],k.marks.push({type:"link",attrs:{href:l}}),e.push(k))}}else if(r.name==="w:r"){const i=r,c=findDrawingElement(i);if(c){const f=await extractImagesFromDrawing(c,t);if(f.length){e.push(...f);continue}}if(findChild(i,"w:br")){const f=extractMarks(i,t.styleInfo);e.push({type:"hardBreak",...f.length&&{marks:f}})}const l=d(i,t.styleInfo);l&&e.push(l)}}return e}function extractMarks(n,t){const e=[],r=findChild(n,"w:rPr");let i={};if(t?.charFormat&&(i={...t.charFormat}),r){const c=findChild(r,"w:b");c&&(c.attributes["w:val"]==="false"?i.bold=!1:i.bold=!0);const l=findChild(r,"w:i");l&&(l.attributes["w:val"]==="false"?i.italic=!1:i.italic=!0),findChild(r,"w:u")&&(i.underline=!0),findChild(r,"w:strike")&&(i.strike=!0);const f=findChild(r,"w:color");if(f?.attributes["w:val"]&&f.attributes["w:val"]!=="auto"){const P=f.attributes["w:val"];i.color=P.startsWith("#")?P:`#${P}`}const b=findChild(r,"w:sz");if(b?.attributes["w:val"]){const P=b.attributes["w:val"],F=parseInt(P,10);isNaN(F)||(i.fontSize=F)}const I=findChild(r,"w:rFonts");I?.attributes["w:ascii"]&&(i.fontFamily=I.attributes["w:ascii"]);const k=findChild(r,"w:shd");if(k?.attributes["w:fill"]&&k.attributes["w:fill"]!=="auto"){const P=k.attributes["w:fill"];i.backgroundColor=P.startsWith("#")?P:`#${P}`}findChild(r,"w:highlight")&&e.push({type:"highlight"});const R=findChild(r,"w:vertAlign");if(R){const P=R.attributes["w:val"];P==="subscript"?e.push({type:"subscript"}):P==="superscript"&&e.push({type:"superscript"})}}if(i.bold&&e.push({type:"bold"}),i.italic&&e.push({type:"italic"}),i.underline&&e.push({type:"underline"}),i.strike&&e.push({type:"strike"}),i.color||i.backgroundColor||i.fontSize||i.fontFamily){const c={color:i.color||"",backgroundColor:i.backgroundColor||"",fontSize:"",fontFamily:"",lineHeight:""};if(i.fontSize){const l=Math.round(i.fontSize/1.5*10)/10;c.fontSize=`${l}px`}i.fontFamily&&(c.fontFamily=i.fontFamily),e.push({type:"textStyle",attrs:c})}return e}function extractAlignment(n){const t=findChild(n,"w:pPr");if(!t)return;const e=findChild(t,"w:jc");if(!e?.attributes["w:val"])return;const r=e.attributes["w:val"],i={left:"left",right:"right",center:"center",both:"justify"}[r];return i?{textAlign:i}:void 0}function y$2(n){return`${Math.round(n/15)}px`}function m$1(n){const t=findChild(n,"w:pPr");if(!t)return null;const e={},r=findChild(t,"w:ind");if(r){const c=I=>{const k=r.attributes[I];if(typeof k!="string")return null;const R=parseInt(k,10);return isNaN(R)?null:y$2(R)},l=c("w:left");l&&(e.indentLeft=l);const f=c("w:right");f&&(e.indentRight=f);const b=c("w:firstLine");if(b)e.indentFirstLine=b;else{const I=c("w:hanging");I&&(e.indentFirstLine=`-${I}`)}}const i=findChild(t,"w:spacing");if(i){const c=b=>{const I=i.attributes[b];if(typeof I!="string")return null;const k=parseInt(I,10);return isNaN(k)?null:y$2(k)},l=c("w:before");l&&(e.spacingBefore=l);const f=c("w:after");f&&(e.spacingAfter=f)}return Object.keys(e).length?e:null}async function convertParagraph(n,t){const e=findChild(n,"w:pPr"),r=(e&&findChild(e,"w:pStyle"))?.attributes["w:val"];if(r&&t.styleMap){const f=t.styleMap.get(r);if(f?.outlineLvl!==void 0&&f.outlineLvl>=0&&f.outlineLvl<=5){const I=f.outlineLvl+1;return h$1(n,t,f,I)}const b=r.match(/^Heading(\d+)$/);if(b){const I=parseInt(b[1],10);return h$1(n,t,f,I)}}const i=r&&t.styleMap?t.styleMap.get(r):void 0,c=await extractRuns(n,{...t,styleInfo:i}),l={...extractAlignment(n),...m$1(n)};if(w(n)){const f=c.filter(b=>b.type!=="hardBreak");return[{type:"paragraph",...Object.keys(l).length&&{attrs:l},content:f.length?f:void 0},{type:"horizontalRule"}]}if(c.length===1&&c[0].type==="hardBreak"){const f=findChild(n,"w:r");if((f&&findChild(f,"w:br"))?.attributes["w:type"]==="page")return{type:"horizontalRule"}}return c.length===1&&c[0].type==="image"?c[0]:{type:"paragraph",...Object.keys(l).length&&{attrs:l},content:c}}function w(n){const t=[],e=r=>{if(r.name==="w:r")t.push(r);else for(const i of r.children)i.type==="element"&&e(i)};return e(n),t.some(r=>findChild(r,"w:br")?.attributes["w:type"]==="page")}async function h$1(n,t,e,r){return{type:"heading",attrs:{level:r,...m$1(n)},content:await extractRuns(n,{...t,styleInfo:e})}}function parseBorder(n){if(!n)return null;const t=n.attributes["w:val"],e=n.attributes["w:sz"],r=n.attributes["w:color"],i={single:"solid",dashed:"dashed",dotted:"dotted",double:"double",none:"none",nil:"none"},c={};if(r&&r!=="auto"&&(c.color=`#${r}`),e){const l=parseInt(e);isNaN(l)||(c.width=Math.round(l/6))}return t&&i[t]&&(c.style=i[t]),Object.keys(c).length>0?c:null}function parseTableProperties(n){const t={marginTop:void 0,marginBottom:void 0,marginLeft:void 0,marginRight:void 0},e=findChild(n,"w:tblPr");if(!e)return null;const r=findChild(e,"w:tblCellMar");if(!r)return null;const i=findChild(r,"w:top");if(i?.attributes["w:w"]){const b=parseInt(i.attributes["w:w"]);isNaN(b)||(t.marginTop=b)}const c=findChild(r,"w:bottom");if(c?.attributes["w:w"]){const b=parseInt(c.attributes["w:w"]);isNaN(b)||(t.marginBottom=b)}const l=findChild(r,"w:left");if(l?.attributes["w:w"]){const b=parseInt(l.attributes["w:w"]);isNaN(b)||(t.marginLeft=b)}const f=findChild(r,"w:right");if(f?.attributes["w:w"]){const b=parseInt(f.attributes["w:w"]);isNaN(b)||(t.marginRight=b)}return t.marginTop===void 0&&t.marginBottom===void 0&&t.marginLeft===void 0&&t.marginRight===void 0?null:t}function parseRowProperties(n){const t={rowHeight:null},e=findChild(n,"w:trPr");if(!e)return t;const r=findChild(e,"w:trHeight");if(r?.attributes["w:val"]){const i=parseInt(r.attributes["w:val"]),c=Math.round(i/15);t.rowHeight=`${c}px`}return t}function parseCellProperties(n){const t={colSpan:1,rowSpan:1,colWidth:null},e=findChild(n,"w:tcPr");if(!e)return t;const r=findChild(e,"w:gridSpan");r?.attributes["w:val"]&&(t.colSpan=parseInt(r.attributes["w:val"])),findChild(e,"w:vMerge")?.attributes["w:val"]==="continue"&&(t.rowSpan=0);const i=findChild(e,"w:tcW");if(i?.attributes["w:w"]){const b=parseInt(i.attributes["w:w"]);t.colWidth=Math.round(b/15)}const c=findChild(e,"w:shd");c?.attributes["w:fill"]&&(t.backgroundColor=`#${c.attributes["w:fill"]}`);const l=findChild(e,"w:vAlign");l?.attributes["w:val"]&&(t.verticalAlign=l.attributes["w:val"]);const f=findChild(e,"w:tcBorders");if(f){const b=parseBorder(findChild(f,"w:top"));b&&(t.borderTop=b);const I=parseBorder(findChild(f,"w:bottom"));I&&(t.borderBottom=I);const k=parseBorder(findChild(f,"w:left"));k&&(t.borderLeft=k);const R=parseBorder(findChild(f,"w:right"));R&&(t.borderRight=R)}return t}function isTable(n){return n.name==="w:tbl"}async function convertTable(n,t){const e=[];for(const l of n.children)l.type==="element"&&l.name==="w:tr"&&e.push(l);const r=new Map,i=await Promise.all(e.map((l,f)=>u(l,{...t,activeRowspans:r,rows:e,rowIndex:f}))),c=parseTableProperties(n);return{type:"table",...c&&{attrs:c},content:i}}async function u(n,t){const e=[];let r=0;const i=parseRowProperties(n);for(const c of n.children){if(c.type!=="element"||c.name!=="w:tc")continue;const l=t.activeRowspans.get(r);if(l&&l>0){t.activeRowspans.set(r,l-1),r++;continue}let f=parseCellProperties(c);if(f?.rowSpan===1){const I=y$1({...t,colIndex:r});I>1&&(f={...f,rowSpan:I})}if(f?.rowSpan&&f.rowSpan>1&&t.activeRowspans.set(r,f.rowSpan-1),f?.rowSpan===0){r++;continue}const b=await g(c,t);e.push({type:"tableCell",...f&&{attrs:f},content:b}),r+=f?.colSpan||1}return{type:"tableRow",...i&&{attrs:i},content:e}}function y$1(n){let t=1,e=n.colIndex;for(let r=n.rowIndex+1;r<n.rows.length;r++){const i=n.rows[r];let c=!1;for(const l of i.children){if(l.type!=="element"||l.name!=="w:tc")continue;const f=parseCellProperties(l),b=f?.colSpan||1;if(e>=0&&e<b){if(f?.rowSpan===0)t++,c=!0;else return t;break}e-=b}if(!c)break}return t}async function g(n,t){const e=[];for(const r of n.children)if(r.type==="element"&&r.name==="w:p"){const i=await convertParagraph(r,t);Array.isArray(i)?e.push(...i):e.push(i)}return e.length?e:[{type:"paragraph",content:[]}]}function isListItem(n){const t=findChild(n,"w:pPr");return!!t&&findChild(t,"w:numPr")!==void 0}function getListInfo(n){const t=findChild(n,"w:pPr"),e=t&&findChild(t,"w:numPr");if(!e)return null;const r=findChild(e,"w:ilvl"),i=findChild(e,"w:numId");return!r||!i?null:{numId:i.attributes["w:val"],level:parseInt(r.attributes["w:val"]||"0",10)}}function isCodeBlock(n){const t=findChild(n,"w:pPr"),e=(t&&findChild(t,"w:pStyle"))?.attributes["w:val"];return e==="CodeBlock"||e?.startsWith("Code")||!1}function getCodeBlockLanguage(n){const t=findChild(n,"w:pPr"),e=(t&&findChild(t,"w:pStyle"))?.attributes["w:val"];return e?.startsWith("CodeBlock")&&e.replace("CodeBlock","").toLowerCase()||void 0}const x="\u2610",a="\u2611";function m(n){const t=findChild(n,"w:r");if(!t)return null;const e=findChild(t,"w:t");if(!e)return null;const r=e.children.find(i=>i.type==="text");return r?.value&&r||null}function isTaskItem(n){const t=m(n);if(!t)return!1;const e=t.value;return e.startsWith(x)||e.startsWith(a)}function getTaskItemChecked(n){return m(n)?.value.startsWith(a)||!1}function convertTaskItem(n){return{type:"taskItem",attrs:{checked:getTaskItemChecked(n)},content:[h(n)]}}function h(n){const t=[];let e=!1;for(const i of n.children){if(i.type!=="element"||i.name!=="w:r")continue;if(!e){const f=findChild(i,"w:t")?.children.find(b=>b.type==="text");if(f?.value){const b=f.value;if(b.startsWith(x)||b.startsWith(a)){e=!0;const I=b.substring(2).trimStart();I&&t.push({type:"text",text:I});continue}}}const c=y(i),l=findChild(i,"w:t")?.children.find(f=>f.type==="text");if(l?.value){const f={type:"text",text:l.value};c.length&&(f.marks=c),t.push(f)}}const r=extractAlignment(n);return{type:"paragraph",...r&&{attrs:r},content:t.length?t:void 0}}function y(n){const t=[],e=findChild(n,"w:rPr");return e&&(findChild(e,"w:b")&&t.push({type:"bold"}),findChild(e,"w:i")&&t.push({type:"italic"}),findChild(e,"w:u")&&t.push({type:"underline"}),findChild(e,"w:strike")&&t.push({type:"strike"})),t}function isHorizontalRule(n){const t=findChild(n,"w:r");if(!t)return!1;let e=!1,r=!1;for(const i of t.children)i.type==="element"&&(i.name==="w:br"&&i.attributes["w:type"]==="page"?e=!0:i.name==="w:t"?i.children.find(c=>c.type==="text")?.value?.trim().length&&(r=!0):i.name!=="w:rPr"&&(r=!0));return e&&!r}const O=n=>{const t=[],e=findDeepChildren(n,"w:r");for(const r of e){const i=findChild(r,"w:t");if(!i)continue;const c=i.children.find(l=>l.type==="text");c&&"value"in c&&c.value&&t.push({type:"text",text:c.value})}return t},S$1=async(n,t,e)=>{const r=await convertTable(n[t],{hyperlinks:e.hyperlinks,images:e.images,options:e.options,styleMap:e.styleMap});let i=1;return t+1<n.length&&n[t+1].name==="w:p"&&C(n[t+1])&&i++,{nodes:[r],consumed:i}},J=async(n,t)=>{const e=[];let r=t;for(;r<n.length;){const i=n[r];if(i.name!=="w:p"||!isCodeBlock(i))break;const c=getCodeBlockLanguage(i),l={type:"codeBlock",...c&&{attrs:{language:c}},content:O(i)};e.push(l),r++}return{nodes:e,consumed:r-t}},M=async(n,t,e)=>{const{listTypeMap:r}=e,i=[];let c=t;for(;c<n.length;){const l=n[c];if(l.name!=="w:p"||!isListItem(l))break;const f=getListInfo(l);if(!f)break;const b=r.get(f.numId),I=b?.type||"bullet",k=[];for(;c<n.length;){const P=n[c];if(P.name!=="w:p"||!isListItem(P))break;const F=getListInfo(P);if(!F||F.numId!==f.numId)break;const $=await convertParagraph(P,e),W=Array.isArray($)?$[0]:$;k.push({type:"listItem",content:[W]}),c++}const R={type:I==="bullet"?"bulletList":"orderedList",content:k};I==="ordered"&&(R.attrs={type:null,...b?.start!==void 0&&{start:b.start}}),i.push(R)}return{nodes:i,consumed:c-t}},T=async(n,t)=>{const e=[];let r=t;for(;r<n.length;){const i=n[r];if(i.name!=="w:p"||!isTaskItem(i))break;const{convertTaskItem:c}=await import("./chunks/index.cjs"),l=c(i);e.push(l),r++}return{nodes:[{type:"taskList",content:e}],consumed:r-t}},v=async()=>({nodes:[{type:"horizontalRule"}],consumed:1}),L=async(n,t,e)=>{const r=await convertParagraph(n[t],e);return Array.isArray(r)?{nodes:r,consumed:1}:{nodes:[r],consumed:1}},C=n=>{const t=findDeepChildren(n,"w:r");for(const e of t){const r=findChild(e,"w:t");if(r){const c=r.children.find(l=>l.type==="text");if(c&&"value"in c&&c.value&&c.value.trim().length>0)return!1}if(findChild(e,"w:drawing")||findChild(e,"mc:AlternateContent")||findChild(e,"w:pict"))return!1;const i=findChild(e,"w:br");if(i&&i.attributes["w:type"]==="page")return!1}return!0},A=n=>n.name==="w:tbl"?S$1:n.name==="w:p"?isCodeBlock(n)?J:isTaskItem(n)?T:isListItem(n)?M:isHorizontalRule(n)?v:L:null,processElements=async(n,t)=>{const e=[];let r=0;for(;r<n.length;){const i=n[r],c=A(i);if(!c){r++;continue}if(i.name==="w:p"&&t.ignoreEmptyParagraphs&&C(i)){r++;continue}const{nodes:l,consumed:f}=await c(n,r,t);e.push(...l),r+=f}return e};async function parseDOCX(n,t={}){const{ignoreEmptyParagraphs:e=!1}=t,r=await undio.toUint8Array(n),i=fflate.unzipSync(r),c=extractHyperlinks(i),l=extractImages(i),f=i["word/document.xml"];if(!f)throw new Error("Invalid DOCX file: missing word/document.xml");const b=xastUtilFromXml.fromXml(new TextDecoder().decode(f)),I=parseNumberingXml(i),k=parseStylesXml(i);return await S(b,l,c,I,k,e,t)}async function S(n,t,e,r,i,c,l){if(n.type!=="root")return{type:"doc",content:[]};const f=findChild(n,"w:document");if(!f)return{type:"doc",content:[]};const b=findChild(f,"w:body");if(!b)return{type:"doc",content:[]};const I={hyperlinks:e,images:t,listTypeMap:r,styleMap:i,ignoreEmptyParagraphs:c,options:l};return{type:"doc",content:await processElements(b.children.filter(k=>k.type==="element"),I)}}exports.convertParagraph=convertParagraph,exports.convertTable=convertTable,exports.convertTaskItem=convertTaskItem,exports.extractAlignment=extractAlignment,exports.extractMarks=extractMarks,exports.extractRuns=extractRuns,exports.getCodeBlockLanguage=getCodeBlockLanguage,exports.getListInfo=getListInfo,exports.getTaskItemChecked=getTaskItemChecked,exports.isCodeBlock=isCodeBlock,exports.isHorizontalRule=isHorizontalRule,exports.isListItem=isListItem,exports.isTable=isTable,exports.isTaskItem=isTaskItem,exports.parseDOCX=parseDOCX;
1
+ "use strict";const xastUtilFromXml=require("xast-util-from-xml"),fflate=require("fflate"),undio=require("undio"),imageMeta=require("image-meta");function a(n){return Math.round(n*96/1440)}function s$1(n){return Math.round(n/(914400/96))}function m$2(n){const t=parseInt(n,10);if(!isNaN(t))return s$1(t)}function B$1(n,t){if(!n.children)return null;for(const e of n.children)if(e.type==="element"&&e.name===t)return e;return null}function l$1(n,t){if(!n.children)return null;for(const e of n.children)if(e.type==="element"){if(e.name===t)return e;const r=l$1(e,t);if(r)return r}return null}function F(n,t){const e=[];if(!n.children)return e;for(const r of n.children)r.type==="element"&&(r.name===t&&e.push(r),e.push(...F(r,t)));return e}function D$1(n,t){const e=n[t];if(!e)return;const r=parseInt(e,10);if(!isNaN(r))return e}const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function uint8ArrayToBase64(n){const t=n.length,e=Math.ceil(t/3)*4,r=Array.from({length:e});let i=0;for(let c=0;c<t;c+=3){const f=n[c],g=c+1<t?n[c+1]:0,v=c+2<t?n[c+2]:0,I=f>>2,C=(f&3)<<4|g>>4,T=(g&15)<<2|v>>6,k=v&63;r[i++]=s[I],r[i++]=s[C],r[i++]=c+1<t?s[T]:"=",r[i++]=c+2<t?s[k]:"="}return r.join("")}function base64ToUint8Array(n){const t=atob(n),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}const isNode=globalThis.process?.release?.name==="node",isBrowser=typeof window<"u";async function h(n){const t=await n;return t.default||t}let o,u$1=class{#t=!1;constructor({enableHWA:t=!1}={}){this.#t=t}create(t,e){const r=this._createCanvas(t,e);return{canvas:r,context:r.getContext("2d",{willReadFrequently:!this.#t})}}reset({canvas:t},e,r){if(!t)throw new Error("Canvas is not specified");t.width=e,t.height=r}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0,t.canvas.height=0,t.canvas=void 0,t.context=void 0}_createCanvas(t,e){throw new Error("Not implemented")}};class DOMCanvasFactory extends u$1{_document;constructor({ownerDocument:t=globalThis.document,enableHWA:e=!1}={}){super({enableHWA:e}),this._document=t}_createCanvas(t,e){const r=this._document.createElement("canvas");return r.width=t,r.height=e,r}}class NodeCanvasFactory extends u$1{constructor({enableHWA:t=!1}={}){super({enableHWA:t})}_createCanvas(t,e){if(!o)throw new Error("@napi-rs/canvas module is not resolved");return o.createCanvas(t,e)}}async function resolveCanvasModule(n){o??=await h(n())}async function createCanvasFactory(n){if(isBrowser)return DOMCanvasFactory;if(isNode){if(!n)throw new Error("In Node.js environment, @napi-rs/canvas is required for image cropping. Please provide canvasImport parameter or install it: pnpm add @napi-rs/canvas");return await resolveCanvasModule(n),NodeCanvasFactory}throw new Error("Unsupported environment for canvas operations")}async function cropImageIfNeeded(n,t,e={}){if(!t||!t.left&&!t.top&&!t.right&&!t.bottom||e.enabled===!1)return n;try{const r=await createCanvasFactory(e.canvasImport),i=await w$2(n,r),c=(t.left||0)/1e5*i.width,f=(t.top||0)/1e5*i.height,g=(t.right||0)/1e5*i.width,v=(t.bottom||0)/1e5*i.height,I=Math.round(i.width-c-g),C=Math.round(i.height-f-v);if(I<=0||C<=0)return console.warn("Invalid crop dimensions, returning original image"),n;const T=new r().create(I,C);if(!T.context)throw new Error("Failed to get 2D context from canvas");T.context.drawImage(i,c,f,I,C,0,0,I,C);const k=T.canvas.toDataURL(),M=await(await fetch(k)).arrayBuffer();return new Uint8Array(M)}catch(r){return console.warn("Image cropping failed, returning original image:",r),n}}async function w$2(n,t){if(isBrowser){const e=new Blob([n.buffer]),r=URL.createObjectURL(e);try{const i=new Image;return new Promise((c,f)=>{i.onload=()=>{URL.revokeObjectURL(r),c(i)},i.onerror=()=>{URL.revokeObjectURL(r),f(new Error("Failed to load image"))},i.src=r})}catch(i){throw URL.revokeObjectURL(r),i}}else{if(!o)throw new Error("@napi-rs/canvas module is not resolved");return await o.loadImage(Buffer.from(n))}}const X$1="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";function _(n){const t=n.attributes.l,e=n.attributes.t,r=n.attributes.r,i=n.attributes.b;if(!(!t&&!e&&!r&&!i))return{left:t?parseInt(t,10):void 0,top:e?parseInt(e,10):void 0,right:r?parseInt(r,10):void 0,bottom:i?parseInt(i,10):void 0}}function N(n){const t=B$1(n,"wp:align"),e=B$1(n,"wp:posOffset"),r=t?.children[0]?.type==="text"?t.children[0].value:void 0,i=e?.children[0]?.type==="text"?parseInt(e.children[0].value,10):void 0;if(!(!r&&i===void 0))return{...r&&{align:r},...i!==void 0&&{offset:i}}}function findDrawingElement(n){let t=B$1(n,"w:drawing");if(t)return t;const e=B$1(n,"mc:AlternateContent"),r=e&&B$1(e,"mc:Choice");return r?B$1(r,"w:drawing"):null}function R$1(n,t,e,r){const i=e/r,c=n/t;return Math.abs(i-c)>.1?i>c?{width:n,height:Math.round(n/i)}:{width:Math.round(t*i),height:t}:{width:n,height:t}}function extractImages(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=B$1(r,"Relationships");if(!i)return t;const c=F(i,"Relationship");for(const f of c)if(f.attributes.Type===X$1&&f.attributes.Id&&f.attributes.Target){const g="word/"+f.attributes.Target,v=n[g];if(!v)continue;let I,C,T="png";try{const P=imageMeta.imageMeta(v);I=P.width,C=P.height,P.type&&(T=P.type)}catch{}const k=uint8ArrayToBase64(v),M=`data:image/${T};base64,${k}`;t.set(f.attributes.Id,{src:M,width:I,height:C})}return t}async function extractImageFromDrawing(n,t){const{context:e}=t,r=l$1(n,"a:blip");if(!r?.attributes["r:embed"])return null;const i=r.attributes["r:embed"],c=e.images.get(i);if(!c)return null;let f=c.src;const g=l$1(n,"a:srcRect");if(g){const $=_(g);if($&&f.startsWith("data:")){const[S,H]=f.split(",");if(H){const V=base64ToUint8Array(H);try{const q=await cropImageIfNeeded(V,$,{canvasImport:e.canvasImport,enabled:e.enableImageCrop}),G=uint8ArrayToBase64(q);f=`${S},${G}`}catch(q){console.warn("Image cropping failed, using original image:",q)}}}}const v=l$1(n,"wp:extent");let I,C;if(v){const $=v.attributes.cx,S=v.attributes.cy;typeof $=="string"&&(I=m$2($)),typeof S=="string"&&(C=m$2(S))}const T=l$1(n,"a:xfrm");let k;if(T?.attributes.rot){const $=parseInt(T.attributes.rot,10);isNaN($)||(k=$/6e4)}const M=l$1(n,"wp:docPr")?.attributes.title,P=l$1(n,"wp:positionH"),W=l$1(n,"wp:positionV");let O;if(P||W){const $=P?N(P):void 0,S=W?N(W):void 0;O={horizontalPosition:{relative:P?.attributes.relativeFrom||"page",...$?.align&&{align:$.align},...$?.offset!==void 0&&{offset:$.offset}},verticalPosition:{relative:W?.attributes.relativeFrom||"page",...S?.align&&{align:S.align},...S?.offset!==void 0&&{offset:S.offset}}}}const E=l$1(n,"pic:spPr");let U;if(E){const $=l$1(E,"a:ln"),S=$&&l$1($,"a:solidFill"),H=S&&l$1(S,"a:srgbClr");H?.attributes.val&&(U={type:"solidFill",solidFillType:"rgb",value:H.attributes.val})}return{type:"image",attrs:{src:f,alt:"",...I!==void 0&&{width:I},...C!==void 0&&{height:C},...k!==void 0&&{rotation:k},...M&&{title:M},...O&&{floating:O},...U&&{outline:U}}}}function j(n,t,e){if(t&&e&&n.width&&n.height){const r=R$1(t,e,n.width,n.height);return{type:"image",attrs:{src:n.src,alt:"",width:r.width,height:r.height}}}return{type:"image",attrs:{src:n.src,alt:"",...t!==void 0&&{width:t},...e!==void 0&&{height:e}}}}async function extractImagesFromDrawing(n,t){const e=[],r=B$1(n,"wp:inline")||B$1(n,"wp:anchor");if(!r)return e;const i=B$1(r,"wp:extent");let c,f;if(i){const C=i.attributes.cx,T=i.attributes.cy;typeof C=="string"&&(c=m$2(C)),typeof T=="string"&&(f=m$2(T))}const g=B$1(r,"a:graphic");if(!g)return e;const v=B$1(g,"a:graphicData");if(!v)return e;const I=B$1(v,"wpg:wgp");if(I){const C=B$1(I,"wpg:grpSp"),T=C?[...F(C,"pic:pic"),...F(C,"pic")]:[...F(I,"pic:pic"),...F(I,"pic")];for(const k of T){const M=B$1(k,"a:graphic");if(!M){const E=B$1(k,"pic:blipFill")||l$1(k,"a:blipFill");if(!E)continue;const U=B$1(E,"a:blip")||l$1(E,"a:blip");if(!U?.attributes["r:embed"])continue;const $=U.attributes["r:embed"],S=t.context.images.get($);if(!S)continue;e.push(j(S,c,f));continue}const P={children:[M]},W=await extractImageFromDrawing(P,t);if(!W)continue;const O=P.children[0]?.type==="element"?l$1(P.children[0],"a:blip")?.attributes["r:embed"]:void 0;if(c&&f&&O){const E=t.context.images.get(O);if(E?.width&&E?.height){const U=R$1(c,f,E.width,E.height);W.attrs.width=U.width,W.attrs.height=U.height}else W.attrs.width=c,W.attrs.height=f}e.push(W)}}else{const C=await extractImageFromDrawing(n,t);C&&e.push(C)}return e}const p="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";function extractHyperlinks(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=B$1(r,"Relationships");if(!i)return t;const c=F(i,"Relationship");for(const f of c)f.attributes.Type===p&&f.attributes.Id&&f.attributes.Target&&t.set(f.attributes.Id,f.attributes.Target);return t}function parseNumberingXml(n){const t=new Map,e=new Map,r=n["word/numbering.xml"];if(!r)return t;const i=xastUtilFromXml.fromXml(new TextDecoder().decode(r)),c=new Map,f=B$1(i,"w:numbering");if(!f)return t;const g=F(f,"w:abstractNum");for(const I of g){const C=I.attributes["w:abstractNumId"],T=B$1(I,"w:lvl");if(!T)continue;const k=B$1(T,"w:numFmt");k?.attributes["w:val"]&&c.set(C,k.attributes["w:val"]);const M=B$1(T,"w:start");M?.attributes["w:val"]&&e.set(C,parseInt(M.attributes["w:val"],10))}const v=F(f,"w:num");for(const I of v){const C=I.attributes["w:numId"],T=B$1(I,"w:abstractNumId");if(!T?.attributes["w:val"])continue;const k=T.attributes["w:val"],M=c.get(k);if(!M)continue;const P=e.get(k);M==="bullet"?t.set(C,{type:"bullet"}):t.set(C,{type:"ordered",...P!==void 0&&{start:P}})}return t}function parseStylesXml(n){const t=new Map,e=n["word/styles.xml"];if(!e)return t;const r=xastUtilFromXml.fromXml(new TextDecoder().decode(e)),i=B$1(r,"w:styles");if(!i)return t;const c=F(i,"w:style").filter(f=>f.attributes["w:type"]==="paragraph");for(const f of c){const g=f.attributes["w:styleId"];if(!g)continue;const v={styleId:g},I=B$1(f,"w:name");I?.attributes["w:val"]&&(v.name=I.attributes["w:val"]);const C=B$1(f,"w:pPr");if(C){const k=B$1(C,"w:outlineLvl");k?.attributes["w:val"]!==void 0&&(v.outlineLvl=parseInt(k.attributes["w:val"],10))}const T=B$1(f,"w:rPr");if(T){const k={},M=B$1(T,"w:color");if(M?.attributes["w:val"]&&M.attributes["w:val"]!=="auto"){const O=M.attributes["w:val"];k.color=O.startsWith("#")?O:`#${O}`}B$1(T,"w:b")&&(k.bold=!0),B$1(T,"w:i")&&(k.italic=!0),B$1(T,"w:u")&&(k.underline=!0),B$1(T,"w:strike")&&(k.strike=!0);const P=B$1(T,"w:sz");if(P?.attributes["w:val"]){const O=P.attributes["w:val"],E=parseInt(O,10);isNaN(E)||(k.fontSize=E)}const W=B$1(T,"w:rFonts");W?.attributes["w:ascii"]&&(k.fontFamily=W.attributes["w:ascii"]),Object.keys(k).length>0&&(v.charFormat=k)}t.set(g,v)}return t}function w$1(n,t){const e=B$1(n,"w:t");if(!e)return null;const r=e.children.find(c=>c.type==="text");if(!r?.value)return null;const i=extractMarks(n,t);return{type:"text",text:r.value,...i.length&&{marks:i}}}async function extractRuns(n,t){const{context:e,styleInfo:r}=t,i=[];for(const c of n.children)if(c.type==="element"){if(c.name==="w:hyperlink"){const f=c,g=f.attributes["r:id"],v=e.hyperlinks.get(g);if(!v)continue;for(const I of f.children){if(I.type!=="element"||I.name!=="w:r")continue;const C=I,T=findDrawingElement(C);if(T){const M=await extractImageFromDrawing(T,{context:e});if(M){i.push(M);continue}const P=await extractImagesFromDrawing(T,{context:e});if(P.length){i.push(...P);continue}}const k=w$1(C,r);k&&(k.marks=k.marks||[],k.marks.push({type:"link",attrs:{href:v}}),i.push(k))}}else if(c.name==="w:r"){const f=c,g=findDrawingElement(f);if(g){const I=await extractImagesFromDrawing(g,{context:e});if(I.length){i.push(...I);continue}}if(B$1(f,"w:br")){const I=extractMarks(f,r);i.push({type:"hardBreak",...I.length&&{marks:I}})}const v=w$1(f,r);v&&i.push(v)}}return i}function extractMarks(n,t){const e=[],r=B$1(n,"w:rPr");let i={};if(t?.charFormat&&(i={...t.charFormat}),r){const c=B$1(r,"w:b");c&&(c.attributes["w:val"]==="false"?i.bold=!1:i.bold=!0);const f=B$1(r,"w:i");f&&(f.attributes["w:val"]==="false"?i.italic=!1:i.italic=!0),B$1(r,"w:u")&&(i.underline=!0),B$1(r,"w:strike")&&(i.strike=!0);const g=B$1(r,"w:color");if(g?.attributes["w:val"]&&g.attributes["w:val"]!=="auto"){const k=g.attributes["w:val"];i.color=k.startsWith("#")?k:`#${k}`}const v=B$1(r,"w:sz");if(v?.attributes["w:val"]){const k=v.attributes["w:val"],M=parseInt(k,10);isNaN(M)||(i.fontSize=M)}const I=B$1(r,"w:rFonts");I?.attributes["w:ascii"]&&(i.fontFamily=I.attributes["w:ascii"]);const C=B$1(r,"w:shd");if(C?.attributes["w:fill"]&&C.attributes["w:fill"]!=="auto"){const k=C.attributes["w:fill"];i.backgroundColor=k.startsWith("#")?k:`#${k}`}B$1(r,"w:highlight")&&e.push({type:"highlight"});const T=B$1(r,"w:vertAlign");if(T){const k=T.attributes["w:val"];k==="subscript"?e.push({type:"subscript"}):k==="superscript"&&e.push({type:"superscript"})}}if(i.bold&&e.push({type:"bold"}),i.italic&&e.push({type:"italic"}),i.underline&&e.push({type:"underline"}),i.strike&&e.push({type:"strike"}),i.color||i.backgroundColor||i.fontSize||i.fontFamily){const c={color:i.color||"",backgroundColor:i.backgroundColor||"",fontSize:"",fontFamily:"",lineHeight:""};if(i.fontSize){const f=Math.round(i.fontSize/1.5*10)/10;c.fontSize=`${f}px`}i.fontFamily&&(c.fontFamily=i.fontFamily),e.push({type:"textStyle",attrs:c})}return e}function extractAlignment(n){const t=B$1(n,"w:pPr");if(!t)return;const e=B$1(t,"w:jc");if(!e?.attributes["w:val"])return;const r=e.attributes["w:val"],i={left:"left",right:"right",center:"center",both:"justify"}[r];return i?{textAlign:i}:void 0}function m$1(n){const t=B$1(n,"w:pPr");if(!t)return null;const e={},r=B$1(t,"w:ind");if(r){const c=D$1(r.attributes,"w:left");c&&(e.indentLeft=c);const f=D$1(r.attributes,"w:right");f&&(e.indentRight=f);const g=D$1(r.attributes,"w:firstLine");if(g)e.indentFirstLine=g;else{const v=D$1(r.attributes,"w:hanging");v&&(e.indentFirstLine=`-${v}`)}}const i=B$1(t,"w:spacing");if(i){const c=D$1(i.attributes,"w:before");c&&(e.spacingBefore=c);const f=D$1(i.attributes,"w:after");f&&(e.spacingAfter=f)}return Object.keys(e).length?e:null}async function convertParagraph(n,t){const{context:e,styleInfo:r}=t,i=B$1(n,"w:pPr"),c=(i&&B$1(i,"w:pStyle"))?.attributes["w:val"];if(c&&e.styleMap){const I=e.styleMap.get(c);if(I?.outlineLvl!==void 0&&I.outlineLvl>=0&&I.outlineLvl<=5){const T=I.outlineLvl+1;return d(n,t,I,T)}const C=c.match(/^Heading(\d+)$/);if(C){const T=parseInt(C[1],10);return d(n,t,I,T)}}const f=c&&e.styleMap?e.styleMap.get(c):void 0,g=await extractRuns(n,{context:e,styleInfo:r||f}),v={...extractAlignment(n),...m$1(n)};if(w(n)){const I=g.filter(C=>C.type!=="hardBreak");return[{type:"paragraph",...Object.keys(v).length&&{attrs:v},content:I.length?I:void 0},{type:"horizontalRule"}]}if(g.length===1&&g[0].type==="hardBreak"){const I=B$1(n,"w:r");if((I&&B$1(I,"w:br"))?.attributes["w:type"]==="page")return{type:"horizontalRule"}}return g.length===1&&g[0].type==="image"?g[0]:{type:"paragraph",...Object.keys(v).length&&{attrs:v},content:g}}function w(n){const t=[],e=r=>{if(r.name==="w:r")t.push(r);else for(const i of r.children)i.type==="element"&&e(i)};return e(n),t.some(r=>B$1(r,"w:br")?.attributes["w:type"]==="page")}async function d(n,t,e,r){return{type:"heading",attrs:{level:r,...m$1(n)},content:await extractRuns(n,{context:t.context,styleInfo:e})}}function parseBorder(n){if(!n)return null;const t=n.attributes["w:val"],e=n.attributes["w:sz"],r=n.attributes["w:color"],i={single:"solid",dashed:"dashed",dotted:"dotted",double:"double",none:"none",nil:"none"},c={};if(r&&r!=="auto"&&(c.color=`#${r}`),e){const f=parseInt(e);isNaN(f)||(c.width=Math.round(f/6))}return t&&i[t]&&(c.style=i[t]),Object.keys(c).length>0?c:null}function parseTableProperties(n){const t={marginTop:void 0,marginBottom:void 0,marginLeft:void 0,marginRight:void 0},e=B$1(n,"w:tblPr");if(!e)return null;const r=B$1(e,"w:tblCellMar");if(!r)return null;const i=B$1(r,"w:top");if(i?.attributes["w:w"]){const v=parseInt(i.attributes["w:w"]);isNaN(v)||(t.marginTop=v)}const c=B$1(r,"w:bottom");if(c?.attributes["w:w"]){const v=parseInt(c.attributes["w:w"]);isNaN(v)||(t.marginBottom=v)}const f=B$1(r,"w:left");if(f?.attributes["w:w"]){const v=parseInt(f.attributes["w:w"]);isNaN(v)||(t.marginLeft=v)}const g=B$1(r,"w:right");if(g?.attributes["w:w"]){const v=parseInt(g.attributes["w:w"]);isNaN(v)||(t.marginRight=v)}return t.marginTop===void 0&&t.marginBottom===void 0&&t.marginLeft===void 0&&t.marginRight===void 0?null:t}function parseRowProperties(n){const t={rowHeight:null},e=B$1(n,"w:trPr");if(!e)return t;const r=B$1(e,"w:trHeight");if(r?.attributes["w:val"]){const i=parseInt(r.attributes["w:val"]),c=a(i);t.rowHeight=`${c}px`}return t}function parseCellProperties(n){const t={colspan:1,rowspan:1,colwidth:null},e=B$1(n,"w:tcPr");if(!e)return t;const r=B$1(e,"w:gridSpan");r?.attributes["w:val"]&&(t.colspan=parseInt(r.attributes["w:val"])),B$1(e,"w:vMerge")?.attributes["w:val"]==="continue"&&(t.rowspan=0);const i=B$1(e,"w:tcW");if(i?.attributes["w:w"]){const v=parseInt(i.attributes["w:w"]),I=a(v);t.colwidth=[I]}const c=B$1(e,"w:shd");c?.attributes["w:fill"]&&(t.backgroundColor=`#${c.attributes["w:fill"]}`);const f=B$1(e,"w:vAlign");f?.attributes["w:val"]&&(t.verticalAlign=f.attributes["w:val"]);const g=B$1(e,"w:tcBorders");if(g){const v=parseBorder(B$1(g,"w:top"));v&&(t.borderTop=v);const I=parseBorder(B$1(g,"w:bottom"));I&&(t.borderBottom=I);const C=parseBorder(B$1(g,"w:left"));C&&(t.borderLeft=C);const T=parseBorder(B$1(g,"w:right"));T&&(t.borderRight=T)}return t}function isTable(n){return n.name==="w:tbl"}async function convertTable(n,t){const e=[];for(const f of n.children)f.type==="element"&&f.name==="w:tr"&&e.push(f);const r=new Map,i=await Promise.all(e.map((f,g)=>u(f,{context:t.context,activeRowspans:r,rows:e,rowIndex:g}))),c=parseTableProperties(n);return{type:"table",...c&&{attrs:c},content:i}}async function u(n,t){const e=[];let r=0;const i=parseRowProperties(n);for(const c of n.children){if(c.type!=="element"||c.name!=="w:tc")continue;const f=t.activeRowspans.get(r);if(f&&f>0){t.activeRowspans.set(r,f-1),r++;continue}let g=parseCellProperties(c);if(g?.rowspan===1){const I=x$1({rows:t.rows,rowIndex:t.rowIndex,colIndex:r});I>1&&(g={...g,rowspan:I})}if(g?.rowspan&&g.rowspan>1&&t.activeRowspans.set(r,g.rowspan-1),g?.rowspan===0){r++;continue}const v=await b(c,t);e.push({type:"tableCell",...g&&{attrs:g},content:v}),r+=g?.colspan||1}return{type:"tableRow",...i&&{attrs:i},content:e}}function x$1(n){let t=1,e=n.colIndex;for(let r=n.rowIndex+1;r<n.rows.length;r++){const i=n.rows[r];let c=!1;for(const f of i.children){if(f.type!=="element"||f.name!=="w:tc")continue;const g=parseCellProperties(f),v=g?.colspan||1;if(e>=0&&e<v){if(g?.rowspan===0)t++,c=!0;else return t;break}e-=v}if(!c)break}return t}async function b(n,t){const e=[];for(const r of n.children)if(r.type==="element"&&r.name==="w:p"){const i=await convertParagraph(r,t);Array.isArray(i)?e.push(...i):e.push(i)}return e.length?e:[{type:"paragraph",content:[]}]}const m="\u2610",l="\u2611";function x(n){const t=B$1(n,"w:r");if(!t)return null;const e=B$1(t,"w:t");if(!e)return null;const r=e.children.find(i=>i.type==="text");return r?.value&&r||null}function isTaskItem(n){const t=x(n);if(!t)return!1;const e=t.value;return e.startsWith(m)||e.startsWith(l)}function getTaskItemChecked(n){return x(n)?.value.startsWith(l)||!1}async function convertTaskItem(n,t){return{type:"taskItem",attrs:{checked:getTaskItemChecked(n)},content:[await y(n,t)]}}async function convertTaskList(n,t){const{siblings:e,index:r,processedIndices:i}=t,c=[];let f=r;for(;f<e.length;){const g=e[f];if(g.name!=="w:p"||!isTaskItem(g))break;i.add(f);const v=await convertTaskItem(g,{context:t.context,styleInfo:t.styleInfo});c.push(v),f++}return{type:"taskList",content:c}}async function y(n,t){const{context:e,styleInfo:r}=t,i=await extractRuns(n,{context:e,styleInfo:r});if(i.length>0&&i[0].type==="text"){const f=i[0],g=f.text;if(g.startsWith(m)||g.startsWith(l)){const v=g.substring(2).trimStart();v?f.text=v:i.shift()}}const c=extractAlignment(n);return{type:"paragraph",...c&&{attrs:c},content:i.length?i:void 0}}function isCodeBlock(n){const t=B$1(n,"w:pPr"),e=(t&&B$1(t,"w:pStyle"))?.attributes["w:val"];return e==="CodeBlock"||e?.startsWith("Code")||!1}function getCodeBlockLanguage(n){const t=B$1(n,"w:pPr"),e=(t&&B$1(t,"w:pStyle"))?.attributes["w:val"];return e?.startsWith("CodeBlock")&&e.replace("CodeBlock","").toLowerCase()||void 0}function isListItem(n){const t=B$1(n,"w:pPr");return!!t&&B$1(t,"w:numPr")!==void 0}function getListInfo(n){const t=B$1(n,"w:pPr"),e=t&&B$1(t,"w:numPr");if(!e)return null;const r=B$1(e,"w:ilvl"),i=B$1(e,"w:numId");return!r||!i?null:{numId:i.attributes["w:val"],level:parseInt(r.attributes["w:val"]||"0",10)}}function isHorizontalRule(n){const t=B$1(n,"w:r");if(!t)return!1;let e=!1,r=!1;for(const i of t.children)i.type==="element"&&(i.name==="w:br"&&i.attributes["w:type"]==="page"?e=!0:i.name==="w:t"?i.children.find(c=>c.type==="text")?.value?.trim().length&&(r=!0):i.name!=="w:rPr"&&(r=!0));return e&&!r}async function parseDOCX(n,t={}){const e=await undio.toUint8Array(n),r=fflate.unzipSync(e),i=extractHyperlinks(r),c=extractImages(r),f=r["word/document.xml"];if(!f)throw new Error("Invalid DOCX file: missing word/document.xml");const g=xastUtilFromXml.fromXml(new TextDecoder().decode(f)),v=parseNumberingXml(r),I=parseStylesXml(r),C={enableImageCrop:!1,ignoreEmptyParagraphs:!1,...t,hyperlinks:i,images:c,listTypeMap:v,styleMap:I};return await D(g,{context:C})}async function D(n,t){if(n.type!=="root")return{type:"doc",content:[]};const e=B$1(n,"w:document");if(!e)return{type:"doc",content:[]};const r=B$1(e,"w:body");return r?{type:"doc",content:await A(r.children.filter(i=>i.type==="element"),t)}:{type:"doc",content:[]}}async function A(n,t){const e=[],r=new Set;for(let i=0;i<n.length;i++){if(r.has(i))continue;const c=n[i];if(t.context.ignoreEmptyParagraphs&&c.name==="w:p"&&z(c))continue;const f=await L(c,n,i,t,r);Array.isArray(f)?e.push(...f):f&&e.push(f)}return e}async function L(n,t,e,r,i){switch(n.name){case"w:tbl":return await convertTable(n,r);case"w:p":return isCodeBlock(n)?await X(n):isTaskItem(n)?await convertTaskList(n,{...r,siblings:t,index:e,processedIndices:i}):isListItem(n)?await B(n,t,e,r,i):isHorizontalRule(n)?{type:"horizontalRule"}:await convertParagraph(n,r);default:return null}}async function X(n){const t=getCodeBlockLanguage(n),e=R(n);return{type:"codeBlock",...t&&{attrs:{language:t}},content:e}}async function B(n,t,e,r,i){const c=getListInfo(n);if(!c)return await convertParagraph(n,r);const f=r.context.listTypeMap.get(c.numId),g=f?.type||"bullet",v=[];let I=e;for(;I<t.length;){const T=t[I];if(T.name!=="w:p"||!isListItem(T))break;const k=getListInfo(T);if(!k||k.numId!==c.numId)break;i.add(I);const M=await convertParagraph(T,r),P=Array.isArray(M)?M[0]:M;v.push({type:"listItem",content:[P]}),I++}const C={type:g==="bullet"?"bulletList":"orderedList",content:v};return g==="ordered"&&(C.attrs={type:null,...f?.start!==void 0&&{start:f.start}}),C}function R(n){const t=[],e=F(n,"w:r");for(const r of e){const i=B$1(r,"w:t");if(!i)continue;const c=i.children.find(f=>f.type==="text");c&&"value"in c&&c.value&&t.push({type:"text",text:c.value})}return t}function z(n){const t=F(n,"w:r");for(const e of t){const r=B$1(e,"w:t");if(r){const c=r.children.find(f=>f.type==="text");if(c&&"value"in c&&c.value&&c.value.trim().length>0)return!1}if(B$1(e,"w:drawing")||B$1(e,"mc:AlternateContent")||B$1(e,"w:pict"))return!1;const i=B$1(e,"w:br");if(i&&i.attributes["w:type"]==="page")return!1}return!0}exports.convertParagraph=convertParagraph,exports.convertTable=convertTable,exports.convertTaskItem=convertTaskItem,exports.convertTaskList=convertTaskList,exports.extractAlignment=extractAlignment,exports.extractMarks=extractMarks,exports.extractRuns=extractRuns,exports.getCodeBlockLanguage=getCodeBlockLanguage,exports.getListInfo=getListInfo,exports.getTaskItemChecked=getTaskItemChecked,exports.isCodeBlock=isCodeBlock,exports.isHorizontalRule=isHorizontalRule,exports.isListItem=isListItem,exports.isTable=isTable,exports.isTaskItem=isTaskItem,exports.parseDOCX=parseDOCX;
package/dist/index.d.cts CHANGED
@@ -6591,6 +6591,25 @@ interface DocxImageResult {
6591
6591
  * Custom image converter function type
6592
6592
  */
6593
6593
  type DocxImageConverter = (image: DocxImageInfo) => Promise<DocxImageResult>;
6594
+ /**
6595
+ * List information extracted from numbering.xml
6596
+ */
6597
+ interface ListInfo {
6598
+ type: "bullet" | "ordered";
6599
+ start?: number;
6600
+ }
6601
+ /**
6602
+ * Map of numbering ID to list information
6603
+ */
6604
+ type ListTypeMap = Map<string, ListInfo>;
6605
+ /**
6606
+ * Image information with dimensions (for round-trip conversion)
6607
+ */
6608
+ interface ImageInfo {
6609
+ src: string;
6610
+ width?: number;
6611
+ height?: number;
6612
+ }
6594
6613
 
6595
6614
  /**
6596
6615
  * Options for importing DOCX files to TipTap content
@@ -6613,10 +6632,10 @@ interface DocxImportOptions {
6613
6632
  canvasImport?: () => Promise<typeof _napi_rs_canvas>;
6614
6633
  /**
6615
6634
  * Enable or disable image cropping during import
6616
- * When true (default), images with crop information in DOCX will be cropped
6617
- * When false, crop information is ignored and full image is used
6635
+ * When true, images with crop information in DOCX will be cropped
6636
+ * When false (default), crop information is ignored and full image is used
6618
6637
  *
6619
- * @default true
6638
+ * @default false
6620
6639
  */
6621
6640
  enableImageCrop?: boolean;
6622
6641
  }
@@ -6644,17 +6663,15 @@ interface StyleInfo {
6644
6663
  }
6645
6664
  type StyleMap = Map<string, StyleInfo>;
6646
6665
 
6647
- interface ListInfo {
6648
- type: "bullet" | "ordered";
6649
- start?: number;
6650
- }
6651
- type ListTypeMap = Map<string, ListInfo>;
6652
- interface ImageInfo {
6653
- src: string;
6654
- width?: number;
6655
- height?: number;
6666
+ /**
6667
+ * Parsing context containing all global resources from DOCX file
6668
+ */
6669
+ interface ParseContext extends DocxImportOptions {
6670
+ hyperlinks: Map<string, string>;
6671
+ images: Map<string, ImageInfo>;
6672
+ listTypeMap: ListTypeMap;
6673
+ styleMap: StyleMap;
6656
6674
  }
6657
-
6658
6675
  /**
6659
6676
  * Main entry point: Parse DOCX file and convert to TipTap JSON
6660
6677
  */
@@ -6664,19 +6681,15 @@ declare function parseDOCX(input: DataType, options?: DocxImportOptions): Promis
6664
6681
  * Convert DOCX paragraph node to TipTap paragraph
6665
6682
  */
6666
6683
  declare function convertParagraph(node: Element$1, params: {
6667
- hyperlinks: Map<string, string>;
6668
- images: Map<string, ImageInfo>;
6669
- options?: DocxImportOptions;
6670
- styleMap?: StyleMap;
6684
+ context: ParseContext;
6685
+ styleInfo?: StyleInfo;
6671
6686
  }): Promise<JSONContent>;
6672
6687
 
6673
6688
  /**
6674
6689
  * Extract all text runs from paragraph
6675
6690
  */
6676
6691
  declare function extractRuns(paragraph: Element$1, params: {
6677
- hyperlinks: Map<string, string>;
6678
- images: Map<string, ImageInfo>;
6679
- options?: DocxImportOptions;
6692
+ context: ParseContext;
6680
6693
  styleInfo?: StyleInfo;
6681
6694
  }): Promise<Array<{
6682
6695
  type: string;
@@ -6730,10 +6743,7 @@ declare function isTable(node: Element$1): boolean;
6730
6743
  * Convert a table element to TipTap JSON
6731
6744
  */
6732
6745
  declare function convertTable(node: Element$1, params: {
6733
- hyperlinks: Map<string, string>;
6734
- images: Map<string, ImageInfo>;
6735
- options?: DocxImportOptions;
6736
- styleMap?: StyleMap;
6746
+ context: ParseContext;
6737
6747
  }): Promise<JSONContent>;
6738
6748
 
6739
6749
  /**
@@ -6747,12 +6757,25 @@ declare function getTaskItemChecked(node: Element$1): boolean;
6747
6757
  /**
6748
6758
  * Convert a task item to TipTap JSON
6749
6759
  */
6750
- declare function convertTaskItem(node: Element$1): JSONContent;
6760
+ declare function convertTaskItem(node: Element$1, params: {
6761
+ context: ParseContext;
6762
+ styleInfo?: StyleInfo;
6763
+ }): Promise<JSONContent>;
6764
+ /**
6765
+ * Convert task list (handles consecutive task items)
6766
+ */
6767
+ declare function convertTaskList(_node: Element$1, params: {
6768
+ context: ParseContext;
6769
+ styleInfo?: StyleInfo;
6770
+ siblings: Element$1[];
6771
+ index: number;
6772
+ processedIndices: Set<number>;
6773
+ }): Promise<JSONContent>;
6751
6774
 
6752
6775
  /**
6753
6776
  * Check if a paragraph is a horizontal rule (page break)
6754
6777
  */
6755
6778
  declare function isHorizontalRule(node: Element$1): boolean;
6756
6779
 
6757
- export { convertParagraph, convertTable, convertTaskItem, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6758
- export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, StyleInfo, StyleMap };
6780
+ export { convertParagraph, convertTable, convertTaskItem, convertTaskList, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6781
+ export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, ParseContext };
package/dist/index.d.mts CHANGED
@@ -6591,6 +6591,25 @@ interface DocxImageResult {
6591
6591
  * Custom image converter function type
6592
6592
  */
6593
6593
  type DocxImageConverter = (image: DocxImageInfo) => Promise<DocxImageResult>;
6594
+ /**
6595
+ * List information extracted from numbering.xml
6596
+ */
6597
+ interface ListInfo {
6598
+ type: "bullet" | "ordered";
6599
+ start?: number;
6600
+ }
6601
+ /**
6602
+ * Map of numbering ID to list information
6603
+ */
6604
+ type ListTypeMap = Map<string, ListInfo>;
6605
+ /**
6606
+ * Image information with dimensions (for round-trip conversion)
6607
+ */
6608
+ interface ImageInfo {
6609
+ src: string;
6610
+ width?: number;
6611
+ height?: number;
6612
+ }
6594
6613
 
6595
6614
  /**
6596
6615
  * Options for importing DOCX files to TipTap content
@@ -6613,10 +6632,10 @@ interface DocxImportOptions {
6613
6632
  canvasImport?: () => Promise<typeof _napi_rs_canvas>;
6614
6633
  /**
6615
6634
  * Enable or disable image cropping during import
6616
- * When true (default), images with crop information in DOCX will be cropped
6617
- * When false, crop information is ignored and full image is used
6635
+ * When true, images with crop information in DOCX will be cropped
6636
+ * When false (default), crop information is ignored and full image is used
6618
6637
  *
6619
- * @default true
6638
+ * @default false
6620
6639
  */
6621
6640
  enableImageCrop?: boolean;
6622
6641
  }
@@ -6644,17 +6663,15 @@ interface StyleInfo {
6644
6663
  }
6645
6664
  type StyleMap = Map<string, StyleInfo>;
6646
6665
 
6647
- interface ListInfo {
6648
- type: "bullet" | "ordered";
6649
- start?: number;
6650
- }
6651
- type ListTypeMap = Map<string, ListInfo>;
6652
- interface ImageInfo {
6653
- src: string;
6654
- width?: number;
6655
- height?: number;
6666
+ /**
6667
+ * Parsing context containing all global resources from DOCX file
6668
+ */
6669
+ interface ParseContext extends DocxImportOptions {
6670
+ hyperlinks: Map<string, string>;
6671
+ images: Map<string, ImageInfo>;
6672
+ listTypeMap: ListTypeMap;
6673
+ styleMap: StyleMap;
6656
6674
  }
6657
-
6658
6675
  /**
6659
6676
  * Main entry point: Parse DOCX file and convert to TipTap JSON
6660
6677
  */
@@ -6664,19 +6681,15 @@ declare function parseDOCX(input: DataType, options?: DocxImportOptions): Promis
6664
6681
  * Convert DOCX paragraph node to TipTap paragraph
6665
6682
  */
6666
6683
  declare function convertParagraph(node: Element$1, params: {
6667
- hyperlinks: Map<string, string>;
6668
- images: Map<string, ImageInfo>;
6669
- options?: DocxImportOptions;
6670
- styleMap?: StyleMap;
6684
+ context: ParseContext;
6685
+ styleInfo?: StyleInfo;
6671
6686
  }): Promise<JSONContent>;
6672
6687
 
6673
6688
  /**
6674
6689
  * Extract all text runs from paragraph
6675
6690
  */
6676
6691
  declare function extractRuns(paragraph: Element$1, params: {
6677
- hyperlinks: Map<string, string>;
6678
- images: Map<string, ImageInfo>;
6679
- options?: DocxImportOptions;
6692
+ context: ParseContext;
6680
6693
  styleInfo?: StyleInfo;
6681
6694
  }): Promise<Array<{
6682
6695
  type: string;
@@ -6730,10 +6743,7 @@ declare function isTable(node: Element$1): boolean;
6730
6743
  * Convert a table element to TipTap JSON
6731
6744
  */
6732
6745
  declare function convertTable(node: Element$1, params: {
6733
- hyperlinks: Map<string, string>;
6734
- images: Map<string, ImageInfo>;
6735
- options?: DocxImportOptions;
6736
- styleMap?: StyleMap;
6746
+ context: ParseContext;
6737
6747
  }): Promise<JSONContent>;
6738
6748
 
6739
6749
  /**
@@ -6747,12 +6757,25 @@ declare function getTaskItemChecked(node: Element$1): boolean;
6747
6757
  /**
6748
6758
  * Convert a task item to TipTap JSON
6749
6759
  */
6750
- declare function convertTaskItem(node: Element$1): JSONContent;
6760
+ declare function convertTaskItem(node: Element$1, params: {
6761
+ context: ParseContext;
6762
+ styleInfo?: StyleInfo;
6763
+ }): Promise<JSONContent>;
6764
+ /**
6765
+ * Convert task list (handles consecutive task items)
6766
+ */
6767
+ declare function convertTaskList(_node: Element$1, params: {
6768
+ context: ParseContext;
6769
+ styleInfo?: StyleInfo;
6770
+ siblings: Element$1[];
6771
+ index: number;
6772
+ processedIndices: Set<number>;
6773
+ }): Promise<JSONContent>;
6751
6774
 
6752
6775
  /**
6753
6776
  * Check if a paragraph is a horizontal rule (page break)
6754
6777
  */
6755
6778
  declare function isHorizontalRule(node: Element$1): boolean;
6756
6779
 
6757
- export { convertParagraph, convertTable, convertTaskItem, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6758
- export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, StyleInfo, StyleMap };
6780
+ export { convertParagraph, convertTable, convertTaskItem, convertTaskList, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6781
+ export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, ParseContext };
package/dist/index.d.ts CHANGED
@@ -6591,6 +6591,25 @@ interface DocxImageResult {
6591
6591
  * Custom image converter function type
6592
6592
  */
6593
6593
  type DocxImageConverter = (image: DocxImageInfo) => Promise<DocxImageResult>;
6594
+ /**
6595
+ * List information extracted from numbering.xml
6596
+ */
6597
+ interface ListInfo {
6598
+ type: "bullet" | "ordered";
6599
+ start?: number;
6600
+ }
6601
+ /**
6602
+ * Map of numbering ID to list information
6603
+ */
6604
+ type ListTypeMap = Map<string, ListInfo>;
6605
+ /**
6606
+ * Image information with dimensions (for round-trip conversion)
6607
+ */
6608
+ interface ImageInfo {
6609
+ src: string;
6610
+ width?: number;
6611
+ height?: number;
6612
+ }
6594
6613
 
6595
6614
  /**
6596
6615
  * Options for importing DOCX files to TipTap content
@@ -6613,10 +6632,10 @@ interface DocxImportOptions {
6613
6632
  canvasImport?: () => Promise<typeof _napi_rs_canvas>;
6614
6633
  /**
6615
6634
  * Enable or disable image cropping during import
6616
- * When true (default), images with crop information in DOCX will be cropped
6617
- * When false, crop information is ignored and full image is used
6635
+ * When true, images with crop information in DOCX will be cropped
6636
+ * When false (default), crop information is ignored and full image is used
6618
6637
  *
6619
- * @default true
6638
+ * @default false
6620
6639
  */
6621
6640
  enableImageCrop?: boolean;
6622
6641
  }
@@ -6644,17 +6663,15 @@ interface StyleInfo {
6644
6663
  }
6645
6664
  type StyleMap = Map<string, StyleInfo>;
6646
6665
 
6647
- interface ListInfo {
6648
- type: "bullet" | "ordered";
6649
- start?: number;
6650
- }
6651
- type ListTypeMap = Map<string, ListInfo>;
6652
- interface ImageInfo {
6653
- src: string;
6654
- width?: number;
6655
- height?: number;
6666
+ /**
6667
+ * Parsing context containing all global resources from DOCX file
6668
+ */
6669
+ interface ParseContext extends DocxImportOptions {
6670
+ hyperlinks: Map<string, string>;
6671
+ images: Map<string, ImageInfo>;
6672
+ listTypeMap: ListTypeMap;
6673
+ styleMap: StyleMap;
6656
6674
  }
6657
-
6658
6675
  /**
6659
6676
  * Main entry point: Parse DOCX file and convert to TipTap JSON
6660
6677
  */
@@ -6664,19 +6681,15 @@ declare function parseDOCX(input: DataType, options?: DocxImportOptions): Promis
6664
6681
  * Convert DOCX paragraph node to TipTap paragraph
6665
6682
  */
6666
6683
  declare function convertParagraph(node: Element$1, params: {
6667
- hyperlinks: Map<string, string>;
6668
- images: Map<string, ImageInfo>;
6669
- options?: DocxImportOptions;
6670
- styleMap?: StyleMap;
6684
+ context: ParseContext;
6685
+ styleInfo?: StyleInfo;
6671
6686
  }): Promise<JSONContent>;
6672
6687
 
6673
6688
  /**
6674
6689
  * Extract all text runs from paragraph
6675
6690
  */
6676
6691
  declare function extractRuns(paragraph: Element$1, params: {
6677
- hyperlinks: Map<string, string>;
6678
- images: Map<string, ImageInfo>;
6679
- options?: DocxImportOptions;
6692
+ context: ParseContext;
6680
6693
  styleInfo?: StyleInfo;
6681
6694
  }): Promise<Array<{
6682
6695
  type: string;
@@ -6730,10 +6743,7 @@ declare function isTable(node: Element$1): boolean;
6730
6743
  * Convert a table element to TipTap JSON
6731
6744
  */
6732
6745
  declare function convertTable(node: Element$1, params: {
6733
- hyperlinks: Map<string, string>;
6734
- images: Map<string, ImageInfo>;
6735
- options?: DocxImportOptions;
6736
- styleMap?: StyleMap;
6746
+ context: ParseContext;
6737
6747
  }): Promise<JSONContent>;
6738
6748
 
6739
6749
  /**
@@ -6747,12 +6757,25 @@ declare function getTaskItemChecked(node: Element$1): boolean;
6747
6757
  /**
6748
6758
  * Convert a task item to TipTap JSON
6749
6759
  */
6750
- declare function convertTaskItem(node: Element$1): JSONContent;
6760
+ declare function convertTaskItem(node: Element$1, params: {
6761
+ context: ParseContext;
6762
+ styleInfo?: StyleInfo;
6763
+ }): Promise<JSONContent>;
6764
+ /**
6765
+ * Convert task list (handles consecutive task items)
6766
+ */
6767
+ declare function convertTaskList(_node: Element$1, params: {
6768
+ context: ParseContext;
6769
+ styleInfo?: StyleInfo;
6770
+ siblings: Element$1[];
6771
+ index: number;
6772
+ processedIndices: Set<number>;
6773
+ }): Promise<JSONContent>;
6751
6774
 
6752
6775
  /**
6753
6776
  * Check if a paragraph is a horizontal rule (page break)
6754
6777
  */
6755
6778
  declare function isHorizontalRule(node: Element$1): boolean;
6756
6779
 
6757
- export { convertParagraph, convertTable, convertTaskItem, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6758
- export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, StyleInfo, StyleMap };
6780
+ export { convertParagraph, convertTable, convertTaskItem, convertTaskList, extractAlignment, extractMarks, extractRuns, getCodeBlockLanguage, getListInfo, getTaskItemChecked, isCodeBlock, isHorizontalRule, isListItem, isTable, isTaskItem, parseDOCX };
6781
+ export type { DocxImageConverter, DocxImageInfo, DocxImageResult, DocxImportOptions, ImageInfo, ListInfo, ListTypeMap, ParseContext };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{fromXml as P}from"xast-util-from-xml";import{unzipSync as lt}from"fflate";import{toUint8Array as ut}from"undio";import{imageMeta as ft}from"image-meta";function a(n,t){for(const e of n.children)if(e.type==="element"&&e.name===t)return e}function y(n,t){for(const e of n.children){if(e.type==="element"&&e.name===t)return e;if(e.type==="element"){const r=y(e,t);if(r)return r}}}function x(n,t){const e=[];for(const r of n.children)r.type==="element"&&r.name===t&&e.push(r),r.type==="element"&&e.push(...x(r,t));return e}const N="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function U(n){const t=n.length,e=Math.ceil(t/3)*4,r=Array.from({length:e});let o=0;for(let i=0;i<t;i+=3){const s=n[i],c=i+1<t?n[i+1]:0,l=i+2<t?n[i+2]:0,u=s>>2,f=(s&3)<<4|c>>4,w=(c&15)<<2|l>>6,p=l&63;r[o++]=N[u],r[o++]=N[f],r[o++]=i+1<t?N[w]:"=",r[o++]=i+2<t?N[p]:"="}return r.join("")}function pt(n){const t=atob(n),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}const wt=globalThis.process?.release?.name==="node",H=typeof window<"u";async function dt(n){const t=await n;return t.default||t}let F,_=class{#t=!1;constructor({enableHWA:t=!1}={}){this.#t=t}create(t,e){const r=this._createCanvas(t,e);return{canvas:r,context:r.getContext("2d",{willReadFrequently:!this.#t})}}reset({canvas:t},e,r){if(!t)throw new Error("Canvas is not specified");t.width=e,t.height=r}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0,t.canvas.height=0,t.canvas=void 0,t.context=void 0}_createCanvas(t,e){throw new Error("Not implemented")}};class ht extends _{_document;constructor({ownerDocument:t=globalThis.document,enableHWA:e=!1}={}){super({enableHWA:e}),this._document=t}_createCanvas(t,e){const r=this._document.createElement("canvas");return r.width=t,r.height=e,r}}class gt extends _{constructor({enableHWA:t=!1}={}){super({enableHWA:t})}_createCanvas(t,e){if(!F)throw new Error("@napi-rs/canvas module is not resolved");return F.createCanvas(t,e)}}async function mt(n){F??=await dt(n())}async function bt(n){if(H)return ht;if(wt){if(!n)throw new Error("In Node.js environment, @napi-rs/canvas is required for image cropping. Please provide canvasImport parameter or install it: pnpm add @napi-rs/canvas");return await mt(n),gt}throw new Error("Unsupported environment for canvas operations")}async function yt(n,t,e={}){if(!t||!t.left&&!t.top&&!t.right&&!t.bottom||e.enabled===!1)return n;try{const r=await bt(e.canvasImport),o=await vt(n,r),i=(t.left||0)/1e5*o.width,s=(t.top||0)/1e5*o.height,c=(t.right||0)/1e5*o.width,l=(t.bottom||0)/1e5*o.height,u=Math.round(o.width-i-c),f=Math.round(o.height-s-l);if(u<=0||f<=0)return console.warn("Invalid crop dimensions, returning original image"),n;const w=new r().create(u,f);if(!w.context)throw new Error("Failed to get 2D context from canvas");w.context.drawImage(o,i,s,u,f,0,0,u,f);const p=w.canvas.toDataURL(),d=await(await fetch(p)).arrayBuffer();return new Uint8Array(d)}catch(r){return console.warn("Image cropping failed, returning original image:",r),n}}async function vt(n,t){if(H){const e=new Blob([n.buffer]),r=URL.createObjectURL(e);try{const o=new Image;return new Promise((i,s)=>{o.onload=()=>{URL.revokeObjectURL(r),i(o)},o.onerror=()=>{URL.revokeObjectURL(r),s(new Error("Failed to load image"))},o.src=r})}catch(o){throw URL.revokeObjectURL(r),o}}else{if(!F)throw new Error("@napi-rs/canvas module is not resolved");return await F.loadImage(Buffer.from(n))}}const It="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";function R(n){const t=parseInt(n,10);if(!isNaN(t))return Math.round(t/9525)}function xt(n){const t=n.attributes.l,e=n.attributes.t,r=n.attributes.r,o=n.attributes.b;if(!(!t&&!e&&!r&&!o))return{left:t?parseInt(t,10):void 0,top:e?parseInt(e,10):void 0,right:r?parseInt(r,10):void 0,bottom:o?parseInt(o,10):void 0}}function X(n){const t=a(n,"wp:align"),e=a(n,"wp:posOffset"),r=t?.children[0]?.type==="text"?t.children[0].value:void 0,o=e?.children[0]?.type==="text"?parseInt(e.children[0].value,10):void 0;if(!(!r&&o===void 0))return{...r&&{align:r},...o!==void 0&&{offset:o}}}function q(n){let t=a(n,"w:drawing");if(t)return t;const e=a(n,"mc:AlternateContent"),r=e&&a(e,"mc:Choice");return r&&a(r,"w:drawing")}function J(n,t,e,r){const o=e/r,i=n/t;return Math.abs(o-i)>.1?o>i?{width:n,height:Math.round(n/o)}:{width:Math.round(t*o),height:t}:{width:n,height:t}}function kt(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=P(new TextDecoder().decode(e)),o=a(r,"Relationships");if(!o)return t;const i=x(o,"Relationship");for(const s of i)if(s.attributes.Type===It&&s.attributes.Id&&s.attributes.Target){const c="word/"+s.attributes.Target,l=n[c];if(!l)continue;let u,f,w="png";try{const h=ft(l);u=h.width,f=h.height,h.type&&(w=h.type)}catch{}const p=U(l),d=`data:image/${w};base64,${p}`;t.set(s.attributes.Id,{src:d,width:u,height:f})}return t}async function $(n,t){const{images:e,options:r}=t,o=y(n,"a:blip");if(!o?.attributes["r:embed"])return null;const i=o.attributes["r:embed"],s=e.get(i);if(!s)return null;let c=s.src;const l=y(n,"a:srcRect");if(l){const g=xt(l);if(g&&c.startsWith("data:")){const[I,M]=c.split(",");if(M){const at=pt(M);try{const A=await yt(at,g,{canvasImport:r?.canvasImport,enabled:r?.enableImageCrop!==!1}),ct=U(A);c=`${I},${ct}`}catch(A){console.warn("Image cropping failed, using original image:",A)}}}}const u=y(n,"wp:extent");let f,w;if(u){const g=u.attributes.cx,I=u.attributes.cy;typeof g=="string"&&(f=R(g)),typeof I=="string"&&(w=R(I))}const p=y(n,"a:xfrm");let d;if(p?.attributes.rot){const g=parseInt(p.attributes.rot,10);isNaN(g)||(d=g/6e4)}const h=y(n,"wp:docPr")?.attributes.title,m=y(n,"wp:positionH"),v=y(n,"wp:positionV");let b;if(m||v){const g=m?X(m):void 0,I=v?X(v):void 0;b={horizontalPosition:{relative:m?.attributes.relativeFrom||"page",...g?.align&&{align:g.align},...g?.offset!==void 0&&{offset:g.offset}},verticalPosition:{relative:v?.attributes.relativeFrom||"page",...I?.align&&{align:I.align},...I?.offset!==void 0&&{offset:I.offset}}}}const k=y(n,"pic:spPr");let C;if(k){const g=y(k,"a:ln"),I=g&&y(g,"a:solidFill"),M=I&&y(I,"a:srgbClr");M?.attributes.val&&(C={type:"solidFill",solidFillType:"rgb",value:M.attributes.val})}return{type:"image",attrs:{src:c,alt:"",...f!==void 0&&{width:f},...w!==void 0&&{height:w},...d!==void 0&&{rotation:d},...h&&{title:h},...b&&{floating:b},...C&&{outline:C}}}}function Ct(n,t,e){if(t&&e&&n.width&&n.height){const r=J(t,e,n.width,n.height);return{type:"image",attrs:{src:n.src,alt:"",width:r.width,height:r.height}}}return{type:"image",attrs:{src:n.src,alt:"",...t!==void 0&&{width:t},...e!==void 0&&{height:e}}}}async function V(n,t){const e=[],r=a(n,"wp:inline")||a(n,"wp:anchor");if(!r)return e;const o=a(r,"wp:extent");let i,s;if(o){const f=o.attributes.cx,w=o.attributes.cy;typeof f=="string"&&(i=R(f)),typeof w=="string"&&(s=R(w))}const c=a(r,"a:graphic");if(!c)return e;const l=a(c,"a:graphicData");if(!l)return e;const u=a(l,"wpg:wgp");if(u){const f=a(u,"wpg:grpSp"),w=f?[...x(f,"pic:pic"),...x(f,"pic")]:[...x(u,"pic:pic"),...x(u,"pic")];for(const p of w){const d=a(p,"a:graphic");if(!d){const b=a(p,"pic:blipFill")||y(p,"a:blipFill");if(!b)continue;const k=a(b,"a:blip")||y(b,"a:blip");if(!k?.attributes["r:embed"])continue;const C=k.attributes["r:embed"],g=t.images.get(C);if(!g)continue;e.push(Ct(g,i,s));continue}const h={children:[d]},m=await $(h,t);if(!m)continue;const v=h.children[0]?.type==="element"?y(h.children[0],"a:blip")?.attributes["r:embed"]:void 0;if(i&&s&&v){const b=t.images.get(v);if(b?.width&&b?.height){const k=J(i,s,b.width,b.height);m.attrs.width=k.width,m.attrs.height=k.height}else m.attrs.width=i,m.attrs.height=s}e.push(m)}}else{const f=await $(n,t);f&&e.push(f)}return e}const Mt="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";function Pt(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=P(new TextDecoder().decode(e)),o=a(r,"Relationships");if(!o)return t;const i=x(o,"Relationship");for(const s of i)s.attributes.Type===Mt&&s.attributes.Id&&s.attributes.Target&&t.set(s.attributes.Id,s.attributes.Target);return t}function Ft(n){const t=new Map,e=new Map,r=n["word/numbering.xml"];if(!r)return t;const o=P(new TextDecoder().decode(r)),i=new Map,s=a(o,"w:numbering");if(!s)return t;const c=x(s,"w:abstractNum");for(const u of c){const f=u.attributes["w:abstractNumId"],w=a(u,"w:lvl");if(!w)continue;const p=a(w,"w:numFmt");p?.attributes["w:val"]&&i.set(f,p.attributes["w:val"]);const d=a(w,"w:start");d?.attributes["w:val"]&&e.set(f,parseInt(d.attributes["w:val"],10))}const l=x(s,"w:num");for(const u of l){const f=u.attributes["w:numId"],w=a(u,"w:abstractNumId");if(!w?.attributes["w:val"])continue;const p=w.attributes["w:val"],d=i.get(p);if(!d)continue;const h=e.get(p);d==="bullet"?t.set(f,{type:"bullet"}):t.set(f,{type:"ordered",...h!==void 0&&{start:h}})}return t}function Nt(n){const t=new Map,e=n["word/styles.xml"];if(!e)return t;const r=P(new TextDecoder().decode(e)),o=a(r,"w:styles");if(!o)return t;const i=x(o,"w:style").filter(s=>s.attributes["w:type"]==="paragraph");for(const s of i){const c=s.attributes["w:styleId"];if(!c)continue;const l={styleId:c},u=a(s,"w:name");u?.attributes["w:val"]&&(l.name=u.attributes["w:val"]);const f=a(s,"w:pPr");if(f){const p=a(f,"w:outlineLvl");p?.attributes["w:val"]!==void 0&&(l.outlineLvl=parseInt(p.attributes["w:val"],10))}const w=a(s,"w:rPr");if(w){const p={},d=a(w,"w:color");if(d?.attributes["w:val"]&&d.attributes["w:val"]!=="auto"){const v=d.attributes["w:val"];p.color=v.startsWith("#")?v:`#${v}`}a(w,"w:b")&&(p.bold=!0),a(w,"w:i")&&(p.italic=!0),a(w,"w:u")&&(p.underline=!0),a(w,"w:strike")&&(p.strike=!0);const h=a(w,"w:sz");if(h?.attributes["w:val"]){const v=h.attributes["w:val"],b=parseInt(v,10);isNaN(b)||(p.fontSize=b)}const m=a(w,"w:rFonts");m?.attributes["w:ascii"]&&(p.fontFamily=m.attributes["w:ascii"]),Object.keys(p).length>0&&(l.charFormat=p)}t.set(c,l)}return t}function G(n,t){const e=a(n,"w:t");if(!e)return null;const r=e.children.find(i=>i.type==="text");if(!r?.value)return null;const o=D(n,t);return{type:"text",text:r.value,...o.length&&{marks:o}}}async function B(n,t){const e=[];for(const r of n.children)if(r.type==="element"){if(r.name==="w:hyperlink"){const o=r,i=o.attributes["r:id"],s=t.hyperlinks.get(i);if(!s)continue;for(const c of o.children){if(c.type!=="element"||c.name!=="w:r")continue;const l=c,u=q(l);if(u){const w=await $(u,t);if(w){e.push(w);continue}const p=await V(u,t);if(p.length){e.push(...p);continue}}const f=G(l,t.styleInfo);f&&(f.marks=f.marks||[],f.marks.push({type:"link",attrs:{href:s}}),e.push(f))}}else if(r.name==="w:r"){const o=r,i=q(o);if(i){const c=await V(i,t);if(c.length){e.push(...c);continue}}if(a(o,"w:br")){const c=D(o,t.styleInfo);e.push({type:"hardBreak",...c.length&&{marks:c}})}const s=G(o,t.styleInfo);s&&e.push(s)}}return e}function D(n,t){const e=[],r=a(n,"w:rPr");let o={};if(t?.charFormat&&(o={...t.charFormat}),r){const i=a(r,"w:b");i&&(i.attributes["w:val"]==="false"?o.bold=!1:o.bold=!0);const s=a(r,"w:i");s&&(s.attributes["w:val"]==="false"?o.italic=!1:o.italic=!0),a(r,"w:u")&&(o.underline=!0),a(r,"w:strike")&&(o.strike=!0);const c=a(r,"w:color");if(c?.attributes["w:val"]&&c.attributes["w:val"]!=="auto"){const p=c.attributes["w:val"];o.color=p.startsWith("#")?p:`#${p}`}const l=a(r,"w:sz");if(l?.attributes["w:val"]){const p=l.attributes["w:val"],d=parseInt(p,10);isNaN(d)||(o.fontSize=d)}const u=a(r,"w:rFonts");u?.attributes["w:ascii"]&&(o.fontFamily=u.attributes["w:ascii"]);const f=a(r,"w:shd");if(f?.attributes["w:fill"]&&f.attributes["w:fill"]!=="auto"){const p=f.attributes["w:fill"];o.backgroundColor=p.startsWith("#")?p:`#${p}`}a(r,"w:highlight")&&e.push({type:"highlight"});const w=a(r,"w:vertAlign");if(w){const p=w.attributes["w:val"];p==="subscript"?e.push({type:"subscript"}):p==="superscript"&&e.push({type:"superscript"})}}if(o.bold&&e.push({type:"bold"}),o.italic&&e.push({type:"italic"}),o.underline&&e.push({type:"underline"}),o.strike&&e.push({type:"strike"}),o.color||o.backgroundColor||o.fontSize||o.fontFamily){const i={color:o.color||"",backgroundColor:o.backgroundColor||"",fontSize:"",fontFamily:"",lineHeight:""};if(o.fontSize){const s=Math.round(o.fontSize/1.5*10)/10;i.fontSize=`${s}px`}o.fontFamily&&(i.fontFamily=o.fontFamily),e.push({type:"textStyle",attrs:i})}return e}function W(n){const t=a(n,"w:pPr");if(!t)return;const e=a(t,"w:jc");if(!e?.attributes["w:val"])return;const r=e.attributes["w:val"],o={left:"left",right:"right",center:"center",both:"justify"}[r];return o?{textAlign:o}:void 0}function K(n){return`${Math.round(n/15)}px`}function Q(n){const t=a(n,"w:pPr");if(!t)return null;const e={},r=a(t,"w:ind");if(r){const i=u=>{const f=r.attributes[u];if(typeof f!="string")return null;const w=parseInt(f,10);return isNaN(w)?null:K(w)},s=i("w:left");s&&(e.indentLeft=s);const c=i("w:right");c&&(e.indentRight=c);const l=i("w:firstLine");if(l)e.indentFirstLine=l;else{const u=i("w:hanging");u&&(e.indentFirstLine=`-${u}`)}}const o=a(t,"w:spacing");if(o){const i=l=>{const u=o.attributes[l];if(typeof u!="string")return null;const f=parseInt(u,10);return isNaN(f)?null:K(f)},s=i("w:before");s&&(e.spacingBefore=s);const c=i("w:after");c&&(e.spacingAfter=c)}return Object.keys(e).length?e:null}async function S(n,t){const e=a(n,"w:pPr"),r=(e&&a(e,"w:pStyle"))?.attributes["w:val"];if(r&&t.styleMap){const c=t.styleMap.get(r);if(c?.outlineLvl!==void 0&&c.outlineLvl>=0&&c.outlineLvl<=5){const u=c.outlineLvl+1;return Y(n,t,c,u)}const l=r.match(/^Heading(\d+)$/);if(l){const u=parseInt(l[1],10);return Y(n,t,c,u)}}const o=r&&t.styleMap?t.styleMap.get(r):void 0,i=await B(n,{...t,styleInfo:o}),s={...W(n),...Q(n)};if(Rt(n)){const c=i.filter(l=>l.type!=="hardBreak");return[{type:"paragraph",...Object.keys(s).length&&{attrs:s},content:c.length?c:void 0},{type:"horizontalRule"}]}if(i.length===1&&i[0].type==="hardBreak"){const c=a(n,"w:r");if((c&&a(c,"w:br"))?.attributes["w:type"]==="page")return{type:"horizontalRule"}}return i.length===1&&i[0].type==="image"?i[0]:{type:"paragraph",...Object.keys(s).length&&{attrs:s},content:i}}function Rt(n){const t=[],e=r=>{if(r.name==="w:r")t.push(r);else for(const o of r.children)o.type==="element"&&e(o)};return e(n),t.some(r=>a(r,"w:br")?.attributes["w:type"]==="page")}async function Y(n,t,e,r){return{type:"heading",attrs:{level:r,...Q(n)},content:await B(n,{...t,styleInfo:e})}}function T(n){if(!n)return null;const t=n.attributes["w:val"],e=n.attributes["w:sz"],r=n.attributes["w:color"],o={single:"solid",dashed:"dashed",dotted:"dotted",double:"double",none:"none",nil:"none"},i={};if(r&&r!=="auto"&&(i.color=`#${r}`),e){const s=parseInt(e);isNaN(s)||(i.width=Math.round(s/6))}return t&&o[t]&&(i.style=o[t]),Object.keys(i).length>0?i:null}function St(n){const t={marginTop:void 0,marginBottom:void 0,marginLeft:void 0,marginRight:void 0},e=a(n,"w:tblPr");if(!e)return null;const r=a(e,"w:tblCellMar");if(!r)return null;const o=a(r,"w:top");if(o?.attributes["w:w"]){const l=parseInt(o.attributes["w:w"]);isNaN(l)||(t.marginTop=l)}const i=a(r,"w:bottom");if(i?.attributes["w:w"]){const l=parseInt(i.attributes["w:w"]);isNaN(l)||(t.marginBottom=l)}const s=a(r,"w:left");if(s?.attributes["w:w"]){const l=parseInt(s.attributes["w:w"]);isNaN(l)||(t.marginLeft=l)}const c=a(r,"w:right");if(c?.attributes["w:w"]){const l=parseInt(c.attributes["w:w"]);isNaN(l)||(t.marginRight=l)}return t.marginTop===void 0&&t.marginBottom===void 0&&t.marginLeft===void 0&&t.marginRight===void 0?null:t}function Tt(n){const t={rowHeight:null},e=a(n,"w:trPr");if(!e)return t;const r=a(e,"w:trHeight");if(r?.attributes["w:val"]){const o=parseInt(r.attributes["w:val"]),i=Math.round(o/15);t.rowHeight=`${i}px`}return t}function Z(n){const t={colSpan:1,rowSpan:1,colWidth:null},e=a(n,"w:tcPr");if(!e)return t;const r=a(e,"w:gridSpan");r?.attributes["w:val"]&&(t.colSpan=parseInt(r.attributes["w:val"])),a(e,"w:vMerge")?.attributes["w:val"]==="continue"&&(t.rowSpan=0);const o=a(e,"w:tcW");if(o?.attributes["w:w"]){const l=parseInt(o.attributes["w:w"]);t.colWidth=Math.round(l/15)}const i=a(e,"w:shd");i?.attributes["w:fill"]&&(t.backgroundColor=`#${i.attributes["w:fill"]}`);const s=a(e,"w:vAlign");s?.attributes["w:val"]&&(t.verticalAlign=s.attributes["w:val"]);const c=a(e,"w:tcBorders");if(c){const l=T(a(c,"w:top"));l&&(t.borderTop=l);const u=T(a(c,"w:bottom"));u&&(t.borderBottom=u);const f=T(a(c,"w:left"));f&&(t.borderLeft=f);const w=T(a(c,"w:right"));w&&(t.borderRight=w)}return t}function Lt(n){return n.name==="w:tbl"}async function tt(n,t){const e=[];for(const s of n.children)s.type==="element"&&s.name==="w:tr"&&e.push(s);const r=new Map,o=await Promise.all(e.map((s,c)=>At(s,{...t,activeRowspans:r,rows:e,rowIndex:c}))),i=St(n);return{type:"table",...i&&{attrs:i},content:o}}async function At(n,t){const e=[];let r=0;const o=Tt(n);for(const i of n.children){if(i.type!=="element"||i.name!=="w:tc")continue;const s=t.activeRowspans.get(r);if(s&&s>0){t.activeRowspans.set(r,s-1),r++;continue}let c=Z(i);if(c?.rowSpan===1){const u=$t({...t,colIndex:r});u>1&&(c={...c,rowSpan:u})}if(c?.rowSpan&&c.rowSpan>1&&t.activeRowspans.set(r,c.rowSpan-1),c?.rowSpan===0){r++;continue}const l=await Bt(i,t);e.push({type:"tableCell",...c&&{attrs:c},content:l}),r+=c?.colSpan||1}return{type:"tableRow",...o&&{attrs:o},content:e}}function $t(n){let t=1,e=n.colIndex;for(let r=n.rowIndex+1;r<n.rows.length;r++){const o=n.rows[r];let i=!1;for(const s of o.children){if(s.type!=="element"||s.name!=="w:tc")continue;const c=Z(s),l=c?.colSpan||1;if(e>=0&&e<l){if(c?.rowSpan===0)t++,i=!0;else return t;break}e-=l}if(!i)break}return t}async function Bt(n,t){const e=[];for(const r of n.children)if(r.type==="element"&&r.name==="w:p"){const o=await S(r,t);Array.isArray(o)?e.push(...o):e.push(o)}return e.length?e:[{type:"paragraph",content:[]}]}function L(n){const t=a(n,"w:pPr");return!!t&&a(t,"w:numPr")!==void 0}function E(n){const t=a(n,"w:pPr"),e=t&&a(t,"w:numPr");if(!e)return null;const r=a(e,"w:ilvl"),o=a(e,"w:numId");return!r||!o?null:{numId:o.attributes["w:val"],level:parseInt(r.attributes["w:val"]||"0",10)}}function z(n){const t=a(n,"w:pPr"),e=(t&&a(t,"w:pStyle"))?.attributes["w:val"];return e==="CodeBlock"||e?.startsWith("Code")||!1}function et(n){const t=a(n,"w:pPr"),e=(t&&a(t,"w:pStyle"))?.attributes["w:val"];return e?.startsWith("CodeBlock")&&e.replace("CodeBlock","").toLowerCase()||void 0}const nt="\u2610",O="\u2611";function rt(n){const t=a(n,"w:r");if(!t)return null;const e=a(t,"w:t");if(!e)return null;const r=e.children.find(o=>o.type==="text");return r?.value&&r||null}function j(n){const t=rt(n);if(!t)return!1;const e=t.value;return e.startsWith(nt)||e.startsWith(O)}function ot(n){return rt(n)?.value.startsWith(O)||!1}function Dt(n){return{type:"taskItem",attrs:{checked:ot(n)},content:[Wt(n)]}}function Wt(n){const t=[];let e=!1;for(const o of n.children){if(o.type!=="element"||o.name!=="w:r")continue;if(!e){const c=a(o,"w:t")?.children.find(l=>l.type==="text");if(c?.value){const l=c.value;if(l.startsWith(nt)||l.startsWith(O)){e=!0;const u=l.substring(2).trimStart();u&&t.push({type:"text",text:u});continue}}}const i=Et(o),s=a(o,"w:t")?.children.find(c=>c.type==="text");if(s?.value){const c={type:"text",text:s.value};i.length&&(c.marks=i),t.push(c)}}const r=W(n);return{type:"paragraph",...r&&{attrs:r},content:t.length?t:void 0}}function Et(n){const t=[],e=a(n,"w:rPr");return e&&(a(e,"w:b")&&t.push({type:"bold"}),a(e,"w:i")&&t.push({type:"italic"}),a(e,"w:u")&&t.push({type:"underline"}),a(e,"w:strike")&&t.push({type:"strike"})),t}function it(n){const t=a(n,"w:r");if(!t)return!1;let e=!1,r=!1;for(const o of t.children)o.type==="element"&&(o.name==="w:br"&&o.attributes["w:type"]==="page"?e=!0:o.name==="w:t"?o.children.find(i=>i.type==="text")?.value?.trim().length&&(r=!0):o.name!=="w:rPr"&&(r=!0));return e&&!r}const zt=n=>{const t=[],e=x(n,"w:r");for(const r of e){const o=a(r,"w:t");if(!o)continue;const i=o.children.find(s=>s.type==="text");i&&"value"in i&&i.value&&t.push({type:"text",text:i.value})}return t},Ot=async(n,t,e)=>{const r=await tt(n[t],{hyperlinks:e.hyperlinks,images:e.images,options:e.options,styleMap:e.styleMap});let o=1;return t+1<n.length&&n[t+1].name==="w:p"&&st(n[t+1])&&o++,{nodes:[r],consumed:o}},jt=async(n,t)=>{const e=[];let r=t;for(;r<n.length;){const o=n[r];if(o.name!=="w:p"||!z(o))break;const i=et(o),s={type:"codeBlock",...i&&{attrs:{language:i}},content:zt(o)};e.push(s),r++}return{nodes:e,consumed:r-t}},Ut=async(n,t,e)=>{const{listTypeMap:r}=e,o=[];let i=t;for(;i<n.length;){const s=n[i];if(s.name!=="w:p"||!L(s))break;const c=E(s);if(!c)break;const l=r.get(c.numId),u=l?.type||"bullet",f=[];for(;i<n.length;){const p=n[i];if(p.name!=="w:p"||!L(p))break;const d=E(p);if(!d||d.numId!==c.numId)break;const h=await S(p,e),m=Array.isArray(h)?h[0]:h;f.push({type:"listItem",content:[m]}),i++}const w={type:u==="bullet"?"bulletList":"orderedList",content:f};u==="ordered"&&(w.attrs={type:null,...l?.start!==void 0&&{start:l.start}}),o.push(w)}return{nodes:o,consumed:i-t}},Ht=async(n,t)=>{const e=[];let r=t;for(;r<n.length;){const o=n[r];if(o.name!=="w:p"||!j(o))break;const{convertTaskItem:i}=await import("./chunks/index.mjs"),s=i(o);e.push(s),r++}return{nodes:[{type:"taskList",content:e}],consumed:r-t}},_t=async()=>({nodes:[{type:"horizontalRule"}],consumed:1}),Xt=async(n,t,e)=>{const r=await S(n[t],e);return Array.isArray(r)?{nodes:r,consumed:1}:{nodes:[r],consumed:1}},st=n=>{const t=x(n,"w:r");for(const e of t){const r=a(e,"w:t");if(r){const i=r.children.find(s=>s.type==="text");if(i&&"value"in i&&i.value&&i.value.trim().length>0)return!1}if(a(e,"w:drawing")||a(e,"mc:AlternateContent")||a(e,"w:pict"))return!1;const o=a(e,"w:br");if(o&&o.attributes["w:type"]==="page")return!1}return!0},qt=n=>n.name==="w:tbl"?Ot:n.name==="w:p"?z(n)?jt:j(n)?Ht:L(n)?Ut:it(n)?_t:Xt:null,Jt=async(n,t)=>{const e=[];let r=0;for(;r<n.length;){const o=n[r],i=qt(o);if(!i){r++;continue}if(o.name==="w:p"&&t.ignoreEmptyParagraphs&&st(o)){r++;continue}const{nodes:s,consumed:c}=await i(n,r,t);e.push(...s),r+=c}return e};async function Vt(n,t={}){const{ignoreEmptyParagraphs:e=!1}=t,r=await ut(n),o=lt(r),i=Pt(o),s=kt(o),c=o["word/document.xml"];if(!c)throw new Error("Invalid DOCX file: missing word/document.xml");const l=P(new TextDecoder().decode(c)),u=Ft(o),f=Nt(o);return await Gt(l,s,i,u,f,e,t)}async function Gt(n,t,e,r,o,i,s){if(n.type!=="root")return{type:"doc",content:[]};const c=a(n,"w:document");if(!c)return{type:"doc",content:[]};const l=a(c,"w:body");if(!l)return{type:"doc",content:[]};const u={hyperlinks:e,images:t,listTypeMap:r,styleMap:o,ignoreEmptyParagraphs:i,options:s};return{type:"doc",content:await Jt(l.children.filter(f=>f.type==="element"),u)}}export{S as convertParagraph,tt as convertTable,Dt as convertTaskItem,W as extractAlignment,D as extractMarks,B as extractRuns,et as getCodeBlockLanguage,E as getListInfo,ot as getTaskItemChecked,z as isCodeBlock,it as isHorizontalRule,L as isListItem,Lt as isTable,j as isTaskItem,Vt as parseDOCX};
1
+ import{fromXml as R}from"xast-util-from-xml";import{unzipSync as ut}from"fflate";import{toUint8Array as ft}from"undio";import{imageMeta as wt}from"image-meta";function O(n){return Math.round(n*96/1440)}function pt(n){return Math.round(n/(914400/96))}function P(n){const t=parseInt(n,10);if(!isNaN(t))return pt(t)}function a(n,t){if(!n.children)return null;for(const e of n.children)if(e.type==="element"&&e.name===t)return e;return null}function m(n,t){if(!n.children)return null;for(const e of n.children)if(e.type==="element"){if(e.name===t)return e;const r=m(e,t);if(r)return r}return null}function I(n,t){const e=[];if(!n.children)return e;for(const r of n.children)r.type==="element"&&(r.name===t&&e.push(r),e.push(...I(r,t)));return e}function C(n,t){const e=n[t];if(!e)return;const r=parseInt(e,10);if(!isNaN(r))return e}const N="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function U(n){const t=n.length,e=Math.ceil(t/3)*4,r=Array.from({length:e});let i=0;for(let o=0;o<t;o+=3){const s=n[o],c=o+1<t?n[o+1]:0,l=o+2<t?n[o+2]:0,u=s>>2,w=(s&3)<<4|c>>4,p=(c&15)<<2|l>>6,f=l&63;r[i++]=N[u],r[i++]=N[w],r[i++]=o+1<t?N[p]:"=",r[i++]=o+2<t?N[f]:"="}return r.join("")}function dt(n){const t=atob(n),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}const ht=globalThis.process?.release?.name==="node",H=typeof window<"u";async function gt(n){const t=await n;return t.default||t}let L,_=class{#t=!1;constructor({enableHWA:t=!1}={}){this.#t=t}create(t,e){const r=this._createCanvas(t,e);return{canvas:r,context:r.getContext("2d",{willReadFrequently:!this.#t})}}reset({canvas:t},e,r){if(!t)throw new Error("Canvas is not specified");t.width=e,t.height=r}destroy(t){if(!t.canvas)throw new Error("Canvas is not specified");t.canvas.width=0,t.canvas.height=0,t.canvas=void 0,t.context=void 0}_createCanvas(t,e){throw new Error("Not implemented")}};class bt extends _{_document;constructor({ownerDocument:t=globalThis.document,enableHWA:e=!1}={}){super({enableHWA:e}),this._document=t}_createCanvas(t,e){const r=this._document.createElement("canvas");return r.width=t,r.height=e,r}}class mt extends _{constructor({enableHWA:t=!1}={}){super({enableHWA:t})}_createCanvas(t,e){if(!L)throw new Error("@napi-rs/canvas module is not resolved");return L.createCanvas(t,e)}}async function yt(n){L??=await gt(n())}async function vt(n){if(H)return bt;if(ht){if(!n)throw new Error("In Node.js environment, @napi-rs/canvas is required for image cropping. Please provide canvasImport parameter or install it: pnpm add @napi-rs/canvas");return await yt(n),mt}throw new Error("Unsupported environment for canvas operations")}async function xt(n,t,e={}){if(!t||!t.left&&!t.top&&!t.right&&!t.bottom||e.enabled===!1)return n;try{const r=await vt(e.canvasImport),i=await It(n,r),o=(t.left||0)/1e5*i.width,s=(t.top||0)/1e5*i.height,c=(t.right||0)/1e5*i.width,l=(t.bottom||0)/1e5*i.height,u=Math.round(i.width-o-c),w=Math.round(i.height-s-l);if(u<=0||w<=0)return console.warn("Invalid crop dimensions, returning original image"),n;const p=new r().create(u,w);if(!p.context)throw new Error("Failed to get 2D context from canvas");p.context.drawImage(i,o,s,u,w,0,0,u,w);const f=p.canvas.toDataURL(),d=await(await fetch(f)).arrayBuffer();return new Uint8Array(d)}catch(r){return console.warn("Image cropping failed, returning original image:",r),n}}async function It(n,t){if(H){const e=new Blob([n.buffer]),r=URL.createObjectURL(e);try{const i=new Image;return new Promise((o,s)=>{i.onload=()=>{URL.revokeObjectURL(r),o(i)},i.onerror=()=>{URL.revokeObjectURL(r),s(new Error("Failed to load image"))},i.src=r})}catch(i){throw URL.revokeObjectURL(r),i}}else{if(!L)throw new Error("@napi-rs/canvas module is not resolved");return await L.loadImage(Buffer.from(n))}}const kt="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";function Ct(n){const t=n.attributes.l,e=n.attributes.t,r=n.attributes.r,i=n.attributes.b;if(!(!t&&!e&&!r&&!i))return{left:t?parseInt(t,10):void 0,top:e?parseInt(e,10):void 0,right:r?parseInt(r,10):void 0,bottom:i?parseInt(i,10):void 0}}function X(n){const t=a(n,"wp:align"),e=a(n,"wp:posOffset"),r=t?.children[0]?.type==="text"?t.children[0].value:void 0,i=e?.children[0]?.type==="text"?parseInt(e.children[0].value,10):void 0;if(!(!r&&i===void 0))return{...r&&{align:r},...i!==void 0&&{offset:i}}}function q(n){let t=a(n,"w:drawing");if(t)return t;const e=a(n,"mc:AlternateContent"),r=e&&a(e,"mc:Choice");return r?a(r,"w:drawing"):null}function V(n,t,e,r){const i=e/r,o=n/t;return Math.abs(i-o)>.1?i>o?{width:n,height:Math.round(n/i)}:{width:Math.round(t*i),height:t}:{width:n,height:t}}function Ft(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=R(new TextDecoder().decode(e)),i=a(r,"Relationships");if(!i)return t;const o=I(i,"Relationship");for(const s of o)if(s.attributes.Type===kt&&s.attributes.Id&&s.attributes.Target){const c="word/"+s.attributes.Target,l=n[c];if(!l)continue;let u,w,p="png";try{const h=wt(l);u=h.width,w=h.height,h.type&&(p=h.type)}catch{}const f=U(l),d=`data:image/${p};base64,${f}`;t.set(s.attributes.Id,{src:d,width:u,height:w})}return t}async function B(n,t){const{context:e}=t,r=m(n,"a:blip");if(!r?.attributes["r:embed"])return null;const i=r.attributes["r:embed"],o=e.images.get(i);if(!o)return null;let s=o.src;const c=m(n,"a:srcRect");if(c){const g=Ct(c);if(g&&s.startsWith("data:")){const[b,F]=s.split(",");if(F){const ct=dt(F);try{const $=await xt(ct,g,{canvasImport:e.canvasImport,enabled:e.enableImageCrop}),lt=U($);s=`${b},${lt}`}catch($){console.warn("Image cropping failed, using original image:",$)}}}}const l=m(n,"wp:extent");let u,w;if(l){const g=l.attributes.cx,b=l.attributes.cy;typeof g=="string"&&(u=P(g)),typeof b=="string"&&(w=P(b))}const p=m(n,"a:xfrm");let f;if(p?.attributes.rot){const g=parseInt(p.attributes.rot,10);isNaN(g)||(f=g/6e4)}const d=m(n,"wp:docPr")?.attributes.title,h=m(n,"wp:positionH"),y=m(n,"wp:positionV");let x;if(h||y){const g=h?X(h):void 0,b=y?X(y):void 0;x={horizontalPosition:{relative:h?.attributes.relativeFrom||"page",...g?.align&&{align:g.align},...g?.offset!==void 0&&{offset:g.offset}},verticalPosition:{relative:y?.attributes.relativeFrom||"page",...b?.align&&{align:b.align},...b?.offset!==void 0&&{offset:b.offset}}}}const v=m(n,"pic:spPr");let k;if(v){const g=m(v,"a:ln"),b=g&&m(g,"a:solidFill"),F=b&&m(b,"a:srgbClr");F?.attributes.val&&(k={type:"solidFill",solidFillType:"rgb",value:F.attributes.val})}return{type:"image",attrs:{src:s,alt:"",...u!==void 0&&{width:u},...w!==void 0&&{height:w},...f!==void 0&&{rotation:f},...d&&{title:d},...x&&{floating:x},...k&&{outline:k}}}}function Rt(n,t,e){if(t&&e&&n.width&&n.height){const r=V(t,e,n.width,n.height);return{type:"image",attrs:{src:n.src,alt:"",width:r.width,height:r.height}}}return{type:"image",attrs:{src:n.src,alt:"",...t!==void 0&&{width:t},...e!==void 0&&{height:e}}}}async function G(n,t){const e=[],r=a(n,"wp:inline")||a(n,"wp:anchor");if(!r)return e;const i=a(r,"wp:extent");let o,s;if(i){const w=i.attributes.cx,p=i.attributes.cy;typeof w=="string"&&(o=P(w)),typeof p=="string"&&(s=P(p))}const c=a(r,"a:graphic");if(!c)return e;const l=a(c,"a:graphicData");if(!l)return e;const u=a(l,"wpg:wgp");if(u){const w=a(u,"wpg:grpSp"),p=w?[...I(w,"pic:pic"),...I(w,"pic")]:[...I(u,"pic:pic"),...I(u,"pic")];for(const f of p){const d=a(f,"a:graphic");if(!d){const v=a(f,"pic:blipFill")||m(f,"a:blipFill");if(!v)continue;const k=a(v,"a:blip")||m(v,"a:blip");if(!k?.attributes["r:embed"])continue;const g=k.attributes["r:embed"],b=t.context.images.get(g);if(!b)continue;e.push(Rt(b,o,s));continue}const h={children:[d]},y=await B(h,t);if(!y)continue;const x=h.children[0]?.type==="element"?m(h.children[0],"a:blip")?.attributes["r:embed"]:void 0;if(o&&s&&x){const v=t.context.images.get(x);if(v?.width&&v?.height){const k=V(o,s,v.width,v.height);y.attrs.width=k.width,y.attrs.height=k.height}else y.attrs.width=o,y.attrs.height=s}e.push(y)}}else{const w=await B(n,t);w&&e.push(w)}return e}const Lt="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";function Mt(n){const t=new Map,e=n["word/_rels/document.xml.rels"];if(!e)return t;const r=R(new TextDecoder().decode(e)),i=a(r,"Relationships");if(!i)return t;const o=I(i,"Relationship");for(const s of o)s.attributes.Type===Lt&&s.attributes.Id&&s.attributes.Target&&t.set(s.attributes.Id,s.attributes.Target);return t}function Pt(n){const t=new Map,e=new Map,r=n["word/numbering.xml"];if(!r)return t;const i=R(new TextDecoder().decode(r)),o=new Map,s=a(i,"w:numbering");if(!s)return t;const c=I(s,"w:abstractNum");for(const u of c){const w=u.attributes["w:abstractNumId"],p=a(u,"w:lvl");if(!p)continue;const f=a(p,"w:numFmt");f?.attributes["w:val"]&&o.set(w,f.attributes["w:val"]);const d=a(p,"w:start");d?.attributes["w:val"]&&e.set(w,parseInt(d.attributes["w:val"],10))}const l=I(s,"w:num");for(const u of l){const w=u.attributes["w:numId"],p=a(u,"w:abstractNumId");if(!p?.attributes["w:val"])continue;const f=p.attributes["w:val"],d=o.get(f);if(!d)continue;const h=e.get(f);d==="bullet"?t.set(w,{type:"bullet"}):t.set(w,{type:"ordered",...h!==void 0&&{start:h}})}return t}function Nt(n){const t=new Map,e=n["word/styles.xml"];if(!e)return t;const r=R(new TextDecoder().decode(e)),i=a(r,"w:styles");if(!i)return t;const o=I(i,"w:style").filter(s=>s.attributes["w:type"]==="paragraph");for(const s of o){const c=s.attributes["w:styleId"];if(!c)continue;const l={styleId:c},u=a(s,"w:name");u?.attributes["w:val"]&&(l.name=u.attributes["w:val"]);const w=a(s,"w:pPr");if(w){const f=a(w,"w:outlineLvl");f?.attributes["w:val"]!==void 0&&(l.outlineLvl=parseInt(f.attributes["w:val"],10))}const p=a(s,"w:rPr");if(p){const f={},d=a(p,"w:color");if(d?.attributes["w:val"]&&d.attributes["w:val"]!=="auto"){const x=d.attributes["w:val"];f.color=x.startsWith("#")?x:`#${x}`}a(p,"w:b")&&(f.bold=!0),a(p,"w:i")&&(f.italic=!0),a(p,"w:u")&&(f.underline=!0),a(p,"w:strike")&&(f.strike=!0);const h=a(p,"w:sz");if(h?.attributes["w:val"]){const x=h.attributes["w:val"],v=parseInt(x,10);isNaN(v)||(f.fontSize=v)}const y=a(p,"w:rFonts");y?.attributes["w:ascii"]&&(f.fontFamily=y.attributes["w:ascii"]),Object.keys(f).length>0&&(l.charFormat=f)}t.set(c,l)}return t}function J(n,t){const e=a(n,"w:t");if(!e)return null;const r=e.children.find(o=>o.type==="text");if(!r?.value)return null;const i=D(n,t);return{type:"text",text:r.value,...i.length&&{marks:i}}}async function T(n,t){const{context:e,styleInfo:r}=t,i=[];for(const o of n.children)if(o.type==="element"){if(o.name==="w:hyperlink"){const s=o,c=s.attributes["r:id"],l=e.hyperlinks.get(c);if(!l)continue;for(const u of s.children){if(u.type!=="element"||u.name!=="w:r")continue;const w=u,p=q(w);if(p){const d=await B(p,{context:e});if(d){i.push(d);continue}const h=await G(p,{context:e});if(h.length){i.push(...h);continue}}const f=J(w,r);f&&(f.marks=f.marks||[],f.marks.push({type:"link",attrs:{href:l}}),i.push(f))}}else if(o.name==="w:r"){const s=o,c=q(s);if(c){const u=await G(c,{context:e});if(u.length){i.push(...u);continue}}if(a(s,"w:br")){const u=D(s,r);i.push({type:"hardBreak",...u.length&&{marks:u}})}const l=J(s,r);l&&i.push(l)}}return i}function D(n,t){const e=[],r=a(n,"w:rPr");let i={};if(t?.charFormat&&(i={...t.charFormat}),r){const o=a(r,"w:b");o&&(o.attributes["w:val"]==="false"?i.bold=!1:i.bold=!0);const s=a(r,"w:i");s&&(s.attributes["w:val"]==="false"?i.italic=!1:i.italic=!0),a(r,"w:u")&&(i.underline=!0),a(r,"w:strike")&&(i.strike=!0);const c=a(r,"w:color");if(c?.attributes["w:val"]&&c.attributes["w:val"]!=="auto"){const f=c.attributes["w:val"];i.color=f.startsWith("#")?f:`#${f}`}const l=a(r,"w:sz");if(l?.attributes["w:val"]){const f=l.attributes["w:val"],d=parseInt(f,10);isNaN(d)||(i.fontSize=d)}const u=a(r,"w:rFonts");u?.attributes["w:ascii"]&&(i.fontFamily=u.attributes["w:ascii"]);const w=a(r,"w:shd");if(w?.attributes["w:fill"]&&w.attributes["w:fill"]!=="auto"){const f=w.attributes["w:fill"];i.backgroundColor=f.startsWith("#")?f:`#${f}`}a(r,"w:highlight")&&e.push({type:"highlight"});const p=a(r,"w:vertAlign");if(p){const f=p.attributes["w:val"];f==="subscript"?e.push({type:"subscript"}):f==="superscript"&&e.push({type:"superscript"})}}if(i.bold&&e.push({type:"bold"}),i.italic&&e.push({type:"italic"}),i.underline&&e.push({type:"underline"}),i.strike&&e.push({type:"strike"}),i.color||i.backgroundColor||i.fontSize||i.fontFamily){const o={color:i.color||"",backgroundColor:i.backgroundColor||"",fontSize:"",fontFamily:"",lineHeight:""};if(i.fontSize){const s=Math.round(i.fontSize/1.5*10)/10;o.fontSize=`${s}px`}i.fontFamily&&(o.fontFamily=i.fontFamily),e.push({type:"textStyle",attrs:o})}return e}function z(n){const t=a(n,"w:pPr");if(!t)return;const e=a(t,"w:jc");if(!e?.attributes["w:val"])return;const r=e.attributes["w:val"],i={left:"left",right:"right",center:"center",both:"justify"}[r];return i?{textAlign:i}:void 0}function K(n){const t=a(n,"w:pPr");if(!t)return null;const e={},r=a(t,"w:ind");if(r){const o=C(r.attributes,"w:left");o&&(e.indentLeft=o);const s=C(r.attributes,"w:right");s&&(e.indentRight=s);const c=C(r.attributes,"w:firstLine");if(c)e.indentFirstLine=c;else{const l=C(r.attributes,"w:hanging");l&&(e.indentFirstLine=`-${l}`)}}const i=a(t,"w:spacing");if(i){const o=C(i.attributes,"w:before");o&&(e.spacingBefore=o);const s=C(i.attributes,"w:after");s&&(e.spacingAfter=s)}return Object.keys(e).length?e:null}async function M(n,t){const{context:e,styleInfo:r}=t,i=a(n,"w:pPr"),o=(i&&a(i,"w:pStyle"))?.attributes["w:val"];if(o&&e.styleMap){const u=e.styleMap.get(o);if(u?.outlineLvl!==void 0&&u.outlineLvl>=0&&u.outlineLvl<=5){const p=u.outlineLvl+1;return Q(n,t,u,p)}const w=o.match(/^Heading(\d+)$/);if(w){const p=parseInt(w[1],10);return Q(n,t,u,p)}}const s=o&&e.styleMap?e.styleMap.get(o):void 0,c=await T(n,{context:e,styleInfo:r||s}),l={...z(n),...K(n)};if(Tt(n)){const u=c.filter(w=>w.type!=="hardBreak");return[{type:"paragraph",...Object.keys(l).length&&{attrs:l},content:u.length?u:void 0},{type:"horizontalRule"}]}if(c.length===1&&c[0].type==="hardBreak"){const u=a(n,"w:r");if((u&&a(u,"w:br"))?.attributes["w:type"]==="page")return{type:"horizontalRule"}}return c.length===1&&c[0].type==="image"?c[0]:{type:"paragraph",...Object.keys(l).length&&{attrs:l},content:c}}function Tt(n){const t=[],e=r=>{if(r.name==="w:r")t.push(r);else for(const i of r.children)i.type==="element"&&e(i)};return e(n),t.some(r=>a(r,"w:br")?.attributes["w:type"]==="page")}async function Q(n,t,e,r){return{type:"heading",attrs:{level:r,...K(n)},content:await T(n,{context:t.context,styleInfo:e})}}function A(n){if(!n)return null;const t=n.attributes["w:val"],e=n.attributes["w:sz"],r=n.attributes["w:color"],i={single:"solid",dashed:"dashed",dotted:"dotted",double:"double",none:"none",nil:"none"},o={};if(r&&r!=="auto"&&(o.color=`#${r}`),e){const s=parseInt(e);isNaN(s)||(o.width=Math.round(s/6))}return t&&i[t]&&(o.style=i[t]),Object.keys(o).length>0?o:null}function At(n){const t={marginTop:void 0,marginBottom:void 0,marginLeft:void 0,marginRight:void 0},e=a(n,"w:tblPr");if(!e)return null;const r=a(e,"w:tblCellMar");if(!r)return null;const i=a(r,"w:top");if(i?.attributes["w:w"]){const l=parseInt(i.attributes["w:w"]);isNaN(l)||(t.marginTop=l)}const o=a(r,"w:bottom");if(o?.attributes["w:w"]){const l=parseInt(o.attributes["w:w"]);isNaN(l)||(t.marginBottom=l)}const s=a(r,"w:left");if(s?.attributes["w:w"]){const l=parseInt(s.attributes["w:w"]);isNaN(l)||(t.marginLeft=l)}const c=a(r,"w:right");if(c?.attributes["w:w"]){const l=parseInt(c.attributes["w:w"]);isNaN(l)||(t.marginRight=l)}return t.marginTop===void 0&&t.marginBottom===void 0&&t.marginLeft===void 0&&t.marginRight===void 0?null:t}function $t(n){const t={rowHeight:null},e=a(n,"w:trPr");if(!e)return t;const r=a(e,"w:trHeight");if(r?.attributes["w:val"]){const i=parseInt(r.attributes["w:val"]),o=O(i);t.rowHeight=`${o}px`}return t}function Y(n){const t={colspan:1,rowspan:1,colwidth:null},e=a(n,"w:tcPr");if(!e)return t;const r=a(e,"w:gridSpan");r?.attributes["w:val"]&&(t.colspan=parseInt(r.attributes["w:val"])),a(e,"w:vMerge")?.attributes["w:val"]==="continue"&&(t.rowspan=0);const i=a(e,"w:tcW");if(i?.attributes["w:w"]){const l=parseInt(i.attributes["w:w"]),u=O(l);t.colwidth=[u]}const o=a(e,"w:shd");o?.attributes["w:fill"]&&(t.backgroundColor=`#${o.attributes["w:fill"]}`);const s=a(e,"w:vAlign");s?.attributes["w:val"]&&(t.verticalAlign=s.attributes["w:val"]);const c=a(e,"w:tcBorders");if(c){const l=A(a(c,"w:top"));l&&(t.borderTop=l);const u=A(a(c,"w:bottom"));u&&(t.borderBottom=u);const w=A(a(c,"w:left"));w&&(t.borderLeft=w);const p=A(a(c,"w:right"));p&&(t.borderRight=p)}return t}function Bt(n){return n.name==="w:tbl"}async function Z(n,t){const e=[];for(const s of n.children)s.type==="element"&&s.name==="w:tr"&&e.push(s);const r=new Map,i=await Promise.all(e.map((s,c)=>Dt(s,{context:t.context,activeRowspans:r,rows:e,rowIndex:c}))),o=At(n);return{type:"table",...o&&{attrs:o},content:i}}async function Dt(n,t){const e=[];let r=0;const i=$t(n);for(const o of n.children){if(o.type!=="element"||o.name!=="w:tc")continue;const s=t.activeRowspans.get(r);if(s&&s>0){t.activeRowspans.set(r,s-1),r++;continue}let c=Y(o);if(c?.rowspan===1){const u=zt({rows:t.rows,rowIndex:t.rowIndex,colIndex:r});u>1&&(c={...c,rowspan:u})}if(c?.rowspan&&c.rowspan>1&&t.activeRowspans.set(r,c.rowspan-1),c?.rowspan===0){r++;continue}const l=await St(o,t);e.push({type:"tableCell",...c&&{attrs:c},content:l}),r+=c?.colspan||1}return{type:"tableRow",...i&&{attrs:i},content:e}}function zt(n){let t=1,e=n.colIndex;for(let r=n.rowIndex+1;r<n.rows.length;r++){const i=n.rows[r];let o=!1;for(const s of i.children){if(s.type!=="element"||s.name!=="w:tc")continue;const c=Y(s),l=c?.colspan||1;if(e>=0&&e<l){if(c?.rowspan===0)t++,o=!0;else return t;break}e-=l}if(!o)break}return t}async function St(n,t){const e=[];for(const r of n.children)if(r.type==="element"&&r.name==="w:p"){const i=await M(r,t);Array.isArray(i)?e.push(...i):e.push(i)}return e.length?e:[{type:"paragraph",content:[]}]}const tt="\u2610",S="\u2611";function et(n){const t=a(n,"w:r");if(!t)return null;const e=a(t,"w:t");if(!e)return null;const r=e.children.find(i=>i.type==="text");return r?.value&&r||null}function W(n){const t=et(n);if(!t)return!1;const e=t.value;return e.startsWith(tt)||e.startsWith(S)}function nt(n){return et(n)?.value.startsWith(S)||!1}async function rt(n,t){return{type:"taskItem",attrs:{checked:nt(n)},content:[await Wt(n,t)]}}async function it(n,t){const{siblings:e,index:r,processedIndices:i}=t,o=[];let s=r;for(;s<e.length;){const c=e[s];if(c.name!=="w:p"||!W(c))break;i.add(s);const l=await rt(c,{context:t.context,styleInfo:t.styleInfo});o.push(l),s++}return{type:"taskList",content:o}}async function Wt(n,t){const{context:e,styleInfo:r}=t,i=await T(n,{context:e,styleInfo:r});if(i.length>0&&i[0].type==="text"){const s=i[0],c=s.text;if(c.startsWith(tt)||c.startsWith(S)){const l=c.substring(2).trimStart();l?s.text=l:i.shift()}}const o=z(n);return{type:"paragraph",...o&&{attrs:o},content:i.length?i:void 0}}function ot(n){const t=a(n,"w:pPr"),e=(t&&a(t,"w:pStyle"))?.attributes["w:val"];return e==="CodeBlock"||e?.startsWith("Code")||!1}function st(n){const t=a(n,"w:pPr"),e=(t&&a(t,"w:pStyle"))?.attributes["w:val"];return e?.startsWith("CodeBlock")&&e.replace("CodeBlock","").toLowerCase()||void 0}function E(n){const t=a(n,"w:pPr");return!!t&&a(t,"w:numPr")!==void 0}function j(n){const t=a(n,"w:pPr"),e=t&&a(t,"w:numPr");if(!e)return null;const r=a(e,"w:ilvl"),i=a(e,"w:numId");return!r||!i?null:{numId:i.attributes["w:val"],level:parseInt(r.attributes["w:val"]||"0",10)}}function at(n){const t=a(n,"w:r");if(!t)return!1;let e=!1,r=!1;for(const i of t.children)i.type==="element"&&(i.name==="w:br"&&i.attributes["w:type"]==="page"?e=!0:i.name==="w:t"?i.children.find(o=>o.type==="text")?.value?.trim().length&&(r=!0):i.name!=="w:rPr"&&(r=!0));return e&&!r}async function Et(n,t={}){const e=await ft(n),r=ut(e),i=Mt(r),o=Ft(r),s=r["word/document.xml"];if(!s)throw new Error("Invalid DOCX file: missing word/document.xml");const c=R(new TextDecoder().decode(s)),l=Pt(r),u=Nt(r),w={enableImageCrop:!1,ignoreEmptyParagraphs:!1,...t,hyperlinks:i,images:o,listTypeMap:l,styleMap:u};return await jt(c,{context:w})}async function jt(n,t){if(n.type!=="root")return{type:"doc",content:[]};const e=a(n,"w:document");if(!e)return{type:"doc",content:[]};const r=a(e,"w:body");return r?{type:"doc",content:await Ot(r.children.filter(i=>i.type==="element"),t)}:{type:"doc",content:[]}}async function Ot(n,t){const e=[],r=new Set;for(let i=0;i<n.length;i++){if(r.has(i))continue;const o=n[i];if(t.context.ignoreEmptyParagraphs&&o.name==="w:p"&&qt(o))continue;const s=await Ut(o,n,i,t,r);Array.isArray(s)?e.push(...s):s&&e.push(s)}return e}async function Ut(n,t,e,r,i){switch(n.name){case"w:tbl":return await Z(n,r);case"w:p":return ot(n)?await Ht(n):W(n)?await it(n,{...r,siblings:t,index:e,processedIndices:i}):E(n)?await _t(n,t,e,r,i):at(n)?{type:"horizontalRule"}:await M(n,r);default:return null}}async function Ht(n){const t=st(n),e=Xt(n);return{type:"codeBlock",...t&&{attrs:{language:t}},content:e}}async function _t(n,t,e,r,i){const o=j(n);if(!o)return await M(n,r);const s=r.context.listTypeMap.get(o.numId),c=s?.type||"bullet",l=[];let u=e;for(;u<t.length;){const p=t[u];if(p.name!=="w:p"||!E(p))break;const f=j(p);if(!f||f.numId!==o.numId)break;i.add(u);const d=await M(p,r),h=Array.isArray(d)?d[0]:d;l.push({type:"listItem",content:[h]}),u++}const w={type:c==="bullet"?"bulletList":"orderedList",content:l};return c==="ordered"&&(w.attrs={type:null,...s?.start!==void 0&&{start:s.start}}),w}function Xt(n){const t=[],e=I(n,"w:r");for(const r of e){const i=a(r,"w:t");if(!i)continue;const o=i.children.find(s=>s.type==="text");o&&"value"in o&&o.value&&t.push({type:"text",text:o.value})}return t}function qt(n){const t=I(n,"w:r");for(const e of t){const r=a(e,"w:t");if(r){const o=r.children.find(s=>s.type==="text");if(o&&"value"in o&&o.value&&o.value.trim().length>0)return!1}if(a(e,"w:drawing")||a(e,"mc:AlternateContent")||a(e,"w:pict"))return!1;const i=a(e,"w:br");if(i&&i.attributes["w:type"]==="page")return!1}return!0}export{M as convertParagraph,Z as convertTable,rt as convertTaskItem,it as convertTaskList,z as extractAlignment,D as extractMarks,T as extractRuns,st as getCodeBlockLanguage,j as getListInfo,nt as getTaskItemChecked,ot as isCodeBlock,at as isHorizontalRule,E as isListItem,Bt as isTable,W as isTaskItem,Et as parseDOCX};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docen/import-docx",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "A powerful TipTap/ProseMirror extension that imports Microsoft Word DOCX files to editor content",
5
5
  "keywords": [
6
6
  "converter",
@@ -52,7 +52,8 @@
52
52
  "devDependencies": {
53
53
  "@tiptap/core": "3.15.3",
54
54
  "@types/xast": "2.0.4",
55
- "@docen/extensions": "0.0.8"
55
+ "@docen/extensions": "0.0.9",
56
+ "@docen/utils": "0.0.9"
56
57
  },
57
58
  "peerDependencies": {
58
59
  "@napi-rs/canvas": "^0.1.88"
@@ -1 +0,0 @@
1
- "use strict";const index=require("../index.cjs");require("xast-util-from-xml"),require("fflate"),require("undio"),require("image-meta"),exports.convertParagraph=index.convertParagraph,exports.convertTable=index.convertTable,exports.convertTaskItem=index.convertTaskItem,exports.extractAlignment=index.extractAlignment,exports.extractMarks=index.extractMarks,exports.extractRuns=index.extractRuns,exports.getCodeBlockLanguage=index.getCodeBlockLanguage,exports.getListInfo=index.getListInfo,exports.getTaskItemChecked=index.getTaskItemChecked,exports.isCodeBlock=index.isCodeBlock,exports.isHorizontalRule=index.isHorizontalRule,exports.isListItem=index.isListItem,exports.isTable=index.isTable,exports.isTaskItem=index.isTaskItem;
@@ -1 +0,0 @@
1
- export{convertParagraph,convertTable,convertTaskItem,extractAlignment,extractMarks,extractRuns,getCodeBlockLanguage,getListInfo,getTaskItemChecked,isCodeBlock,isHorizontalRule,isListItem,isTable,isTaskItem}from"../index.mjs";import"xast-util-from-xml";import"fflate";import"undio";import"image-meta";