@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 +12 -9
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +50 -27
- package/dist/index.d.mts +50 -27
- package/dist/index.d.ts +50 -27
- package/dist/index.mjs +1 -1
- package/package.json +3 -2
- package/dist/chunks/index.cjs +0 -1
- package/dist/chunks/index.mjs +0 -1
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
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
|
-
|
|
6668
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
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
|
-
|
|
6668
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
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
|
-
|
|
6668
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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.
|
|
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.
|
|
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"
|
package/dist/chunks/index.cjs
DELETED
|
@@ -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;
|
package/dist/chunks/index.mjs
DELETED
|
@@ -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";
|