@agilehub/docx-converter 0.0.0-stage → 0.2.0
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/CONTRIBUTING.md +47 -0
- package/LICENSE +201 -0
- package/README.md +594 -3
- package/dist/adapters/browser/metafile-preview.d.ts +5 -0
- package/dist/adapters/browser/node-pdf-unavailable.d.ts +1 -0
- package/dist/adapters/browser/pdf-renderer.d.ts +3 -0
- package/dist/adapters/node/convert-file.d.ts +6 -0
- package/dist/adapters/node/imagemagick-preview.d.ts +3 -0
- package/dist/adapters/node/pdf-renderer.d.ts +2 -0
- package/dist/application/conversion-session.d.ts +12 -0
- package/dist/application/convert-docx.d.ts +18 -0
- package/dist/application/convert-pdf.d.ts +2 -0
- package/dist/application/limits.d.ts +3 -0
- package/dist/application/read-input.d.ts +2 -0
- package/dist/browser-7rsR6MAK.js +32188 -0
- package/dist/browser-metafile.cjs +1 -0
- package/dist/browser-metafile.d.ts +1 -0
- package/dist/browser-metafile.js +9 -0
- package/dist/contracts/conversion.d.ts +92 -0
- package/dist/contracts/errors.d.ts +4 -0
- package/dist/contracts/ports.d.ts +16 -0
- package/dist/docx-converter.browser.js +61157 -0
- package/dist/docx-converter.umd.cjs +109 -0
- package/dist/domain/document.d.ts +93 -0
- package/dist/errors-MXQpFjKY.js +8 -0
- package/dist/html2canvas-BdBs_TOY.js +4005 -0
- package/dist/html2pdf-CoDoV4ti.js +28943 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1 -0
- package/dist/infrastructure/archive/zip-reader.d.ts +3 -0
- package/dist/infrastructure/opc/docx-package.d.ts +20 -0
- package/dist/infrastructure/opc/part-reader.d.ts +15 -0
- package/dist/infrastructure/xml/dom.d.ts +11 -0
- package/dist/infrastructure/xml/namespaces.d.ts +10 -0
- package/dist/infrastructure/xml/safe-xml.d.ts +2 -0
- package/dist/metafile-rasterizer-B07sBlcp.js +43 -0
- package/dist/metafile-rasterizer-C9QNCFz9.cjs +1 -0
- package/dist/modules/document/block-reader.d.ts +3 -0
- package/dist/modules/document/chart-parser.d.ts +6 -0
- package/dist/modules/document/document-parser.d.ts +13 -0
- package/dist/modules/document/drawing-parser.d.ts +9 -0
- package/dist/modules/document/group-drawing-parser.d.ts +5 -0
- package/dist/modules/document/inline-parser.d.ts +11 -0
- package/dist/modules/document/paragraph-parser.d.ts +4 -0
- package/dist/modules/document/parse-context.d.ts +20 -0
- package/dist/modules/document/table-parser.d.ts +9 -0
- package/dist/modules/images/drawing-rasterizer.d.ts +4 -0
- package/dist/modules/images/image-resolver.d.ts +11 -0
- package/dist/modules/images/metafile-rasterizer.d.ts +3 -0
- package/dist/modules/images/node-canvas-unavailable.d.ts +2 -0
- package/dist/modules/images/raster-codec.d.ts +2 -0
- package/dist/modules/math/mtef-latex.d.ts +2 -0
- package/dist/modules/math/ole-equation.d.ts +2 -0
- package/dist/modules/math/ole-native-stream.d.ts +2 -0
- package/dist/modules/math/omml-converter.d.ts +4 -0
- package/dist/modules/math/preview-consistency.d.ts +2 -0
- package/dist/modules/numbering/numbering-reader.d.ts +11 -0
- package/dist/modules/styles/ooxml-values.d.ts +2 -0
- package/dist/modules/styles/style-resolver.d.ts +34 -0
- package/dist/node-canvas-unavailable-CvBCngan.js +5 -0
- package/dist/node-pdf-unavailable-C8y2PrZN.js +6 -0
- package/dist/node.cjs +1 -0
- package/dist/node.d.ts +4 -0
- package/dist/node.js +52 -0
- package/dist/pdf-renderer-BXTmJHRv.js +69 -0
- package/dist/pdf-renderer-C7Ls8Wll.cjs +1 -0
- package/dist/pdf-renderer-D5aBQswF.js +68 -0
- package/dist/pdf-renderer-DG-eDzRb.js +40 -0
- package/dist/pdf-renderer-D_uNzxa8.cjs +1 -0
- package/dist/rendering/html/caption-policy.d.ts +13 -0
- package/dist/rendering/html/document-shell.d.ts +2 -0
- package/dist/rendering/html/html-renderer.d.ts +16 -0
- package/dist/rendering/html/image-renderer.d.ts +8 -0
- package/dist/rendering/html/math-image-renderer.d.ts +4 -0
- package/dist/rendering/html/styles.d.ts +4 -0
- package/dist/rendering/json/json-renderer.d.ts +13 -0
- package/dist/rendering/math-image-source.d.ts +24 -0
- package/dist/rolldown-runtime-DfEuXgQw.js +15 -0
- package/dist/shared/markup.d.ts +3 -0
- package/dist/shared/units.d.ts +2 -0
- package/dist/src-CGXH7X67.cjs +15 -0
- package/dist/src-DypdJEH8.js +56775 -0
- package/docs/architecture.md +159 -0
- package/package.json +82 -6
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src-CGXH7X67.cjs");exports.DocxError=e.a,exports.convertToHtml=e.n,exports.convertToJson=e.r,exports.convertToPdf=e.t;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Stable package facade. Internal modules are not public deep imports. */
|
|
2
|
+
export { convertToHtml, convertToJson } from './application/convert-docx.js';
|
|
3
|
+
export { convertToPdf } from './application/convert-pdf.js';
|
|
4
|
+
export type { JsonConversionResult, DocumentModel, Block, Inline, Paragraph, Table, Cell, Row, TextNode, ImageNode, MathNode, LinkNode, RunStyle, ParaStyle, Css } from './application/convert-docx.js';
|
|
5
|
+
export * from './contracts/conversion.js';
|
|
6
|
+
export { DocxError } from './contracts/errors.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { a as DocxError, n as convertToHtml, r as convertToJson, t as convertToPdf } from "./src-DypdJEH8.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Document } from '@xmldom/xmldom';
|
|
2
|
+
import type { ConversionLimits } from '../../contracts/conversion.js';
|
|
3
|
+
import type { PartReader, Relationship } from './part-reader.js';
|
|
4
|
+
export declare class DocxPackage implements PartReader {
|
|
5
|
+
private readonly limits;
|
|
6
|
+
private files;
|
|
7
|
+
private xmlCache;
|
|
8
|
+
private relCache;
|
|
9
|
+
private mimeDefaults;
|
|
10
|
+
private mimeOverrides;
|
|
11
|
+
readonly main: string;
|
|
12
|
+
constructor(bytes: Uint8Array, limits: ConversionLimits);
|
|
13
|
+
bytes(path: string): Uint8Array | undefined;
|
|
14
|
+
paths(): string[];
|
|
15
|
+
mime(path: string): string;
|
|
16
|
+
xml(path: string, required?: boolean): Document | undefined;
|
|
17
|
+
resolve(source: string, target: string): string;
|
|
18
|
+
relationships(source: string): Map<string, Relationship>;
|
|
19
|
+
related(source: string, kind: string): string | undefined;
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Document } from '@xmldom/xmldom';
|
|
2
|
+
import type { ResourceReader } from '../../contracts/ports.js';
|
|
3
|
+
export interface Relationship {
|
|
4
|
+
target: string;
|
|
5
|
+
type: string;
|
|
6
|
+
external: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Read-only OPC access for OOXML modules; the backing archive is replaceable. */
|
|
9
|
+
export interface PartReader extends ResourceReader {
|
|
10
|
+
readonly main: string;
|
|
11
|
+
xml(path: string, required?: boolean): Document | undefined;
|
|
12
|
+
resolve(source: string, target: string): string;
|
|
13
|
+
relationships(source: string): Map<string, Relationship>;
|
|
14
|
+
related(source: string, kind: string): string | undefined;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Element } from '@xmldom/xmldom';
|
|
2
|
+
export { NS } from './namespaces.js';
|
|
3
|
+
export type X = Element;
|
|
4
|
+
export declare function is(el: X, name: string, ns?: string): boolean;
|
|
5
|
+
export declare function children(el?: X | null): X[];
|
|
6
|
+
export declare function child(el: X | undefined | null, name: string, ns?: string): X | undefined;
|
|
7
|
+
export declare function descendants(el: X | undefined | null, name: string, ns?: string): X[];
|
|
8
|
+
export declare function attr(el: X | undefined | null, name: string, ns?: string): string | undefined;
|
|
9
|
+
export declare const val: (el?: X | null) => string | undefined;
|
|
10
|
+
export declare function bool(el?: X | null): boolean | undefined;
|
|
11
|
+
export declare function number(value: string | undefined, fallback?: number): number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/modules/images/raster-codec.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
if ([
|
|
4
|
+
137,
|
|
5
|
+
80,
|
|
6
|
+
78,
|
|
7
|
+
71,
|
|
8
|
+
13,
|
|
9
|
+
10,
|
|
10
|
+
26,
|
|
11
|
+
10
|
|
12
|
+
].every((t, n) => e[n] === t)) return "image/png";
|
|
13
|
+
if (e[0] === 255 && e[1] === 216 && e[2] === 255) return "image/jpeg";
|
|
14
|
+
let t = String.fromCharCode(...e.subarray(0, 12));
|
|
15
|
+
if (/^GIF8[79]a/.test(t)) return "image/gif";
|
|
16
|
+
if (t.startsWith("RIFF") && t.slice(8, 12) === "WEBP") return "image/webp";
|
|
17
|
+
}
|
|
18
|
+
function t(e) {
|
|
19
|
+
let t = "";
|
|
20
|
+
for (let n = 0; n < e.length; n += 24576) t += btoa(String.fromCharCode(...e.subarray(n, n + 24576)));
|
|
21
|
+
return t;
|
|
22
|
+
}
|
|
23
|
+
// src/modules/images/metafile-rasterizer.ts
|
|
24
|
+
async function n(t) {
|
|
25
|
+
if (!(!/\.(emf|wmf)$/i.test(t.path) || t.bytes.byteLength > 8388608)) try {
|
|
26
|
+
let { convertMetafileToDataUrl: n } = await import("emf-converter"), r = await n(Uint8Array.from(t.bytes).buffer, {
|
|
27
|
+
dpiScale: 2,
|
|
28
|
+
maxWidth: 1600,
|
|
29
|
+
maxHeight: 1600
|
|
30
|
+
});
|
|
31
|
+
if (!r?.startsWith("data:image/png;base64,")) return;
|
|
32
|
+
let i = r.slice(22);
|
|
33
|
+
if (i.length > 16777216) return;
|
|
34
|
+
let a = Uint8Array.from(atob(i), (e) => e.charCodeAt(0));
|
|
35
|
+
return e(a) === "image/png" ? {
|
|
36
|
+
bytes: a,
|
|
37
|
+
mimeType: "image/png"
|
|
38
|
+
} : void 0;
|
|
39
|
+
} catch {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export { t as n, e as r, n as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){if([137,80,78,71,13,10,26,10].every((t,n)=>e[n]===t))return`image/png`;if(e[0]===255&&e[1]===216&&e[2]===255)return`image/jpeg`;let t=String.fromCharCode(...e.subarray(0,12));if(/^GIF8[79]a/.test(t))return`image/gif`;if(t.startsWith(`RIFF`)&&t.slice(8,12)===`WEBP`)return`image/webp`}function t(e){let t=``;for(let n=0;n<e.length;n+=24576)t+=btoa(String.fromCharCode(...e.subarray(n,n+24576)));return t}async function n(t){if(!(!/\.(emf|wmf)$/i.test(t.path)||t.bytes.byteLength>8388608))try{let{convertMetafileToDataUrl:n}=await import(`emf-converter`),r=await n(Uint8Array.from(t.bytes).buffer,{dpiScale:2,maxWidth:1600,maxHeight:1600});if(!r?.startsWith(`data:image/png;base64,`))return;let i=r.slice(22);if(i.length>16777216)return;let a=Uint8Array.from(atob(i),e=>e.charCodeAt(0));return e(a)===`image/png`?{bytes:a,mimeType:`image/png`}:void 0}catch{return}}Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return n}});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type X } from '../../infrastructure/xml/dom.js';
|
|
2
|
+
import type { ImageNode } from '../../domain/document.js';
|
|
3
|
+
import type { ParseContext } from './parse-context.js';
|
|
4
|
+
export declare const CHART_NS = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
5
|
+
/** Render cached standard line charts. Unsupported chart families remain explicit placeholders. */
|
|
6
|
+
export declare function parseChart(ref: X, context: ParseContext, width?: number, height?: number): ImageNode | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConversionContext } from '../../contracts/ports.js';
|
|
2
|
+
import type { PartReader } from '../../infrastructure/opc/part-reader.js';
|
|
3
|
+
import type { ParsedDocument } from './parse-context.js';
|
|
4
|
+
/** Coordinates document flow; feature parsers own their own algorithms. */
|
|
5
|
+
export declare class DocumentParser {
|
|
6
|
+
private readonly context;
|
|
7
|
+
private readonly inlines;
|
|
8
|
+
private readonly tables;
|
|
9
|
+
constructor(source: PartReader, operations: ConversionContext);
|
|
10
|
+
parse(): ParsedDocument;
|
|
11
|
+
private blocks;
|
|
12
|
+
private paragraph;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Inline, Paragraph } from '../../domain/document.js';
|
|
2
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
3
|
+
import type { ParseContext } from './parse-context.js';
|
|
4
|
+
export declare class DrawingParser {
|
|
5
|
+
private readonly context;
|
|
6
|
+
private readonly parseParagraphs;
|
|
7
|
+
constructor(context: ParseContext, parseParagraphs: (parent: X) => Paragraph[]);
|
|
8
|
+
parse(el: X, formula: boolean): Inline[];
|
|
9
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type X } from '../../infrastructure/xml/dom.js';
|
|
2
|
+
import type { ImageNode } from '../../domain/document.js';
|
|
3
|
+
export declare const GROUP_NS = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
|
|
4
|
+
/** Conservative vector renderer for grouped Word shapes and straight connectors. */
|
|
5
|
+
export declare function parseGroupDrawing(root: X, width: number, height: number): ImageNode | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Inline, RunStyle } from '../../domain/document.js';
|
|
2
|
+
import type { DrawingParser } from './drawing-parser.js';
|
|
3
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
4
|
+
import type { ParseContext } from './parse-context.js';
|
|
5
|
+
export declare class InlineParser {
|
|
6
|
+
private readonly context;
|
|
7
|
+
private readonly drawings;
|
|
8
|
+
constructor(context: ParseContext, drawings: DrawingParser);
|
|
9
|
+
parse(el: X, inherited: RunStyle): Inline[];
|
|
10
|
+
private inline;
|
|
11
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Paragraph, Inline, RunStyle } from '../../domain/document.js';
|
|
2
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
3
|
+
import type { ParseContext } from './parse-context.js';
|
|
4
|
+
export declare function parseParagraph(el: X, context: ParseContext, parseInlines: (el: X, style: RunStyle) => Inline[]): Paragraph;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ConversionResult } from '../../contracts/conversion.js';
|
|
2
|
+
import type { ConversionContext } from '../../contracts/ports.js';
|
|
3
|
+
import type { DocumentModel } from '../../domain/document.js';
|
|
4
|
+
import type { PartReader } from '../../infrastructure/opc/part-reader.js';
|
|
5
|
+
import type { Styles } from '../styles/style-resolver.js';
|
|
6
|
+
import type { Numbering } from '../numbering/numbering-reader.js';
|
|
7
|
+
/** Shared only inside the parsing subsystem, never exposed to the renderer. */
|
|
8
|
+
export interface ParseContext {
|
|
9
|
+
source: PartReader;
|
|
10
|
+
operations: ConversionContext;
|
|
11
|
+
styles: Styles;
|
|
12
|
+
numbering: Numbering;
|
|
13
|
+
stats: ConversionResult['stats'];
|
|
14
|
+
resources: Set<string>;
|
|
15
|
+
}
|
|
16
|
+
export interface ParsedDocument {
|
|
17
|
+
document: DocumentModel;
|
|
18
|
+
stats: ConversionResult['stats'];
|
|
19
|
+
resourcePaths: string[];
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Block, Table } from '../../domain/document.js';
|
|
2
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
3
|
+
import type { ParseContext } from './parse-context.js';
|
|
4
|
+
export declare class TableParser {
|
|
5
|
+
private readonly context;
|
|
6
|
+
private readonly parseBlocks;
|
|
7
|
+
constructor(context: ParseContext, parseBlocks: (parent: X) => Block[]);
|
|
8
|
+
parse(el: X): Table;
|
|
9
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Rasterize trusted internal SVG without allowing external resources. */
|
|
2
|
+
export declare function svgToPng(svg: string, displayWidth: number, displayHeight: number, background?: string | null): Promise<Uint8Array>;
|
|
3
|
+
/** Grouped drawings use a white page background. */
|
|
4
|
+
export declare function drawingToPng(svg: string, displayWidth: number, displayHeight: number): Promise<Uint8Array>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ImageNode } from '../../domain/document.js';
|
|
2
|
+
import type { ConversionOptions } from '../../contracts/conversion.js';
|
|
3
|
+
import type { RenderContext, ResourceReader } from '../../contracts/ports.js';
|
|
4
|
+
/** Strategy boundary: recover image bytes, optionally convert, then resolve a safe URI. */
|
|
5
|
+
export declare class ImageResolver {
|
|
6
|
+
private readonly resources;
|
|
7
|
+
private readonly context;
|
|
8
|
+
private readonly options;
|
|
9
|
+
constructor(resources: ResourceReader, context: RenderContext, options: ConversionOptions);
|
|
10
|
+
resolve(n: ImageNode): Promise<string | undefined>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
2
|
+
import type { MathNode, RunStyle } from '../../domain/document.js';
|
|
3
|
+
import type { DiagnosticSink } from '../../contracts/ports.js';
|
|
4
|
+
export declare function convertMath(root: X, diagnostics: DiagnosticSink, display?: boolean, inherited?: RunStyle): MathNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PartReader } from '../../infrastructure/opc/part-reader.js';
|
|
2
|
+
export interface ListLevel {
|
|
3
|
+
format: string;
|
|
4
|
+
start: number;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class Numbering {
|
|
8
|
+
private nums;
|
|
9
|
+
constructor(pkg: PartReader);
|
|
10
|
+
get(id: string, level: number): ListLevel | undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Css, ParaStyle, RunStyle } from '../../domain/document.js';
|
|
2
|
+
import type { DiagnosticSink } from '../../contracts/ports.js';
|
|
3
|
+
import type { PartReader } from '../../infrastructure/opc/part-reader.js';
|
|
4
|
+
import type { X } from '../../infrastructure/xml/dom.js';
|
|
5
|
+
interface Style {
|
|
6
|
+
id: string;
|
|
7
|
+
parent?: string;
|
|
8
|
+
type?: string;
|
|
9
|
+
run: RunStyle;
|
|
10
|
+
para: ParaStyle;
|
|
11
|
+
table?: X;
|
|
12
|
+
}
|
|
13
|
+
export declare class Styles {
|
|
14
|
+
private readonly diagnostics;
|
|
15
|
+
private raw;
|
|
16
|
+
private cache;
|
|
17
|
+
private themeColors;
|
|
18
|
+
private themeFonts;
|
|
19
|
+
defaultRun: RunStyle;
|
|
20
|
+
defaultPara: ParaStyle;
|
|
21
|
+
defaultParaId?: string;
|
|
22
|
+
constructor(pkg: PartReader, diagnostics: DiagnosticSink);
|
|
23
|
+
resolve(id?: string, trail?: Set<string>): Style;
|
|
24
|
+
resolveColor(el?: X, key?: string): string | undefined;
|
|
25
|
+
readRun(pr?: X): RunStyle;
|
|
26
|
+
readPara(pr?: X): ParaStyle;
|
|
27
|
+
paragraph(pr?: X): {
|
|
28
|
+
run: RunStyle;
|
|
29
|
+
para: ParaStyle;
|
|
30
|
+
};
|
|
31
|
+
run(pr: X | undefined, paragraph: RunStyle): RunStyle;
|
|
32
|
+
borders(el?: X): Css;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
package/dist/node.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src-CGXH7X67.cjs");let t=require("node:fs/promises"),n=require("node:child_process"),r=require("node:os"),i=require("node:path"),a=require("node:util");async function o(n,r){if((await(0,t.stat)(n)).size>(r.limits?.inputBytes??e.i.inputBytes))throw new e.a(`INPUT_LIMIT`,`输入文件超过大小限制`);return(0,t.readFile)(n)}async function s(t,n={}){return e.n(await o(t,n),n)}async function c(t,n={}){return e.r(await o(t,n),n)}async function l(t,n={}){return e.t(await o(t,n),n)}var u=(0,a.promisify)(n.execFile);function d(e=`magick`){return async n=>{if(!n.formula||!/\.(wmf|emf)$/i.test(n.path)||n.bytes.length>8388608)return;let a=n.path.toLowerCase().endsWith(`.emf`)?`emf`:`wmf`,o=await(0,t.mkdtemp)((0,i.join)((0,r.tmpdir)(),`docx-converter-preview-`)),s=(0,i.join)(o,`preview.${a}`),c=(0,i.join)(o,`preview.png`);try{await(0,t.writeFile)(s,n.bytes),await u(e,[`-background`,`none`,s,`-resize`,`1600x1600>`,`PNG32:${c}`],{timeout:15e3,maxBuffer:1048576,windowsHide:!0});let r=await(0,t.readFile)(c);return r.length>16777216?void 0:{bytes:new Uint8Array(r),mimeType:`image/png`}}catch{return}finally{await(0,t.unlink)(s).catch(()=>{}),await(0,t.unlink)(c).catch(()=>{}),await(0,t.rmdir)(o)}}}exports.DocxError=e.a,exports.convertToHtml=e.n,exports.convertToHtmlFile=s,exports.convertToJson=e.r,exports.convertToJsonFile=c,exports.convertToPdf=e.t,exports.convertToPdfFile=l,exports.createImageMagickPreviewConverter=d;
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Node-specific facade; the browser bundle never imports this module. */
|
|
2
|
+
export * from './index.js';
|
|
3
|
+
export { convertToHtmlFile, convertToJsonFile, convertToPdfFile } from './adapters/node/convert-file.js';
|
|
4
|
+
export { createImageMagickPreviewConverter } from './adapters/node/imagemagick-preview.js';
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./src-DypdJEH8.js";
|
|
2
|
+
import { mkdtemp as a, readFile as o, rmdir as s, stat as c, unlink as l, writeFile as u } from "node:fs/promises";
|
|
3
|
+
import { execFile as d } from "node:child_process";
|
|
4
|
+
import { tmpdir as f } from "node:os";
|
|
5
|
+
import { join as p } from "node:path";
|
|
6
|
+
import { promisify as m } from "node:util";
|
|
7
|
+
// src/adapters/node/convert-file.ts
|
|
8
|
+
async function h(n, r) {
|
|
9
|
+
if ((await c(n)).size > (r.limits?.inputBytes ?? t.inputBytes)) throw new e("INPUT_LIMIT", "输入文件超过大小限制");
|
|
10
|
+
return o(n);
|
|
11
|
+
}
|
|
12
|
+
async function g(e, t = {}) {
|
|
13
|
+
return n(await h(e, t), t);
|
|
14
|
+
}
|
|
15
|
+
async function _(e, t = {}) {
|
|
16
|
+
return r(await h(e, t), t);
|
|
17
|
+
}
|
|
18
|
+
async function v(e, t = {}) {
|
|
19
|
+
return i(await h(e, t), t);
|
|
20
|
+
}
|
|
21
|
+
// src/adapters/node/imagemagick-preview.ts
|
|
22
|
+
var y = m(d);
|
|
23
|
+
function b(e = "magick") {
|
|
24
|
+
return async (t) => {
|
|
25
|
+
if (!t.formula || !/\.(wmf|emf)$/i.test(t.path) || t.bytes.length > 8388608) return;
|
|
26
|
+
let n = t.path.toLowerCase().endsWith(".emf") ? "emf" : "wmf", r = await a(p(f(), "docx-converter-preview-")), i = p(r, `preview.${n}`), c = p(r, "preview.png");
|
|
27
|
+
try {
|
|
28
|
+
await u(i, t.bytes), await y(e, [
|
|
29
|
+
"-background",
|
|
30
|
+
"none",
|
|
31
|
+
i,
|
|
32
|
+
"-resize",
|
|
33
|
+
"1600x1600>",
|
|
34
|
+
`PNG32:${c}`
|
|
35
|
+
], {
|
|
36
|
+
timeout: 15e3,
|
|
37
|
+
maxBuffer: 1048576,
|
|
38
|
+
windowsHide: !0
|
|
39
|
+
});
|
|
40
|
+
let n = await o(c);
|
|
41
|
+
return n.length > 16777216 ? void 0 : {
|
|
42
|
+
bytes: new Uint8Array(n),
|
|
43
|
+
mimeType: "image/png"
|
|
44
|
+
};
|
|
45
|
+
} catch {
|
|
46
|
+
return;
|
|
47
|
+
} finally {
|
|
48
|
+
await l(i).catch(() => {}), await l(c).catch(() => {}), await s(r);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export { e as DocxError, n as convertToHtml, g as convertToHtmlFile, r as convertToJson, _ as convertToJsonFile, i as convertToPdf, v as convertToPdfFile, b as createImageMagickPreviewConverter };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { r as e } from "./rolldown-runtime-DfEuXgQw.js";
|
|
2
|
+
import { t } from "./errors-MXQpFjKY.js";
|
|
3
|
+
// src/adapters/browser/pdf-renderer.ts
|
|
4
|
+
var n = 32767;
|
|
5
|
+
function r() {
|
|
6
|
+
let e = globalThis.navigator, t = e?.userAgent ?? "";
|
|
7
|
+
return /iPhone|iPad|iPod/.test(t) || /Macintosh/.test(t) && (e?.maxTouchPoints ?? 0) > 1 ? 16e6 : 12e7;
|
|
8
|
+
}
|
|
9
|
+
async function i(i, a) {
|
|
10
|
+
let [{ default: o }, { default: s }] = await Promise.all([import("./html2pdf-CoDoV4ti.js").then((t) => /* @__PURE__ */ e(t.default, 1)), import("./html2canvas-BdBs_TOY.js").then((t) => /* @__PURE__ */ e(t.default, 1))]), c = o(), l = globalThis.document, u = l.createElement("iframe");
|
|
11
|
+
u.setAttribute("sandbox", "allow-same-origin allow-scripts"), u.style.cssText = "position:fixed;left:-20000px;top:0;width:900px;height:1000px;border:0";
|
|
12
|
+
let d = () => {
|
|
13
|
+
if (a.signal?.aborted) throw new t("ABORTED", "转换已取消");
|
|
14
|
+
}, f;
|
|
15
|
+
try {
|
|
16
|
+
await new Promise((e, n) => {
|
|
17
|
+
let r = setTimeout(() => n(new t("PDF_TIMEOUT", "PDF 预览加载超时")), 3e4);
|
|
18
|
+
u.onload = () => {
|
|
19
|
+
clearTimeout(r), e();
|
|
20
|
+
}, u.srcdoc = i, l.body.append(u);
|
|
21
|
+
}), d();
|
|
22
|
+
let e = u.contentDocument;
|
|
23
|
+
await e.fonts.ready, await Promise.all(Array.from(e.images).map((e) => e.decode())), d();
|
|
24
|
+
let o = a.pdf ?? {}, p = o.scale ?? 2, m = {
|
|
25
|
+
scale: p,
|
|
26
|
+
useCORS: !0,
|
|
27
|
+
backgroundColor: "#ffffff",
|
|
28
|
+
logging: !1
|
|
29
|
+
}, h = c.set({
|
|
30
|
+
margin: o.margin ?? 15,
|
|
31
|
+
html2canvas: m,
|
|
32
|
+
jsPDF: {
|
|
33
|
+
unit: "mm",
|
|
34
|
+
format: o.format ?? "a4",
|
|
35
|
+
orientation: o.landscape ? "landscape" : "portrait"
|
|
36
|
+
},
|
|
37
|
+
pagebreak: {
|
|
38
|
+
mode: ["css", "legacy"],
|
|
39
|
+
avoid: ["tr", "img"]
|
|
40
|
+
}
|
|
41
|
+
}).from(e.querySelector(".docx-document"));
|
|
42
|
+
await h.toContainer();
|
|
43
|
+
let g = (e) => h.get(e), _ = await g("container");
|
|
44
|
+
f = await g("overlay");
|
|
45
|
+
let v = await g("pageSize");
|
|
46
|
+
d();
|
|
47
|
+
let y = Math.ceil(_.getBoundingClientRect().width), b = Math.max(1, Math.ceil(Math.max(_.scrollHeight, _.getBoundingClientRect().height))), x = Math.floor(y * p), S = Math.floor(x * v.inner.ratio), C = S / p, w = Math.max(1, Math.ceil(b / C - 1e-6)), T = Math.max(1, Math.min(Math.floor(n / S), Math.floor(r() / (x * S))));
|
|
48
|
+
for (let e = 0; e < w; e += T) {
|
|
49
|
+
d();
|
|
50
|
+
let t = e + T >= w, n = e * C, r = t ? b - n : T * C, i = await s(_, {
|
|
51
|
+
...m,
|
|
52
|
+
x: 0,
|
|
53
|
+
y: n,
|
|
54
|
+
width: y,
|
|
55
|
+
height: r
|
|
56
|
+
});
|
|
57
|
+
d(), e > 0 && await h.get("pdf", (e) => e.addPage()), await h.set({
|
|
58
|
+
canvas: i,
|
|
59
|
+
enableLinks: t
|
|
60
|
+
}).toPdf(), i.width = i.height = 0;
|
|
61
|
+
}
|
|
62
|
+
d();
|
|
63
|
+
let E = await h.outputPdf("arraybuffer");
|
|
64
|
+
return d(), new Uint8Array(E);
|
|
65
|
+
} finally {
|
|
66
|
+
f?.remove(), u.remove();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export { i as renderPdf };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("./src-CGXH7X67.cjs");let t=require("playwright-core");async function n(n,r){let i=r.pdf??{},a=await t.chromium.launch(i.executablePath?{executablePath:i.executablePath,headless:!0}:{channel:`chrome`,headless:!0}),o=()=>{a.close().catch(()=>{})};r.signal?.addEventListener(`abort`,o,{once:!0});try{if(r.signal?.aborted)throw new e.a(`ABORTED`,`转换已取消`);let t=await a.newPage();await t.setContent(n,{waitUntil:`load`,timeout:3e4}),await t.evaluate(`Promise.race([Promise.all([document.fonts.ready, ...Array.from(document.images).map(image => image.decode())]), new Promise((_, reject) => setTimeout(() => reject(new Error("PDF image/font load timed out")), 15000))])`),await t.addStyleTag({content:`table{width:auto;max-width:100%}tr,img{break-inside:avoid}body{padding:0!important}`});let o=`${i.margin??15}mm`;return new Uint8Array(await t.pdf({format:i.format===`letter`?`Letter`:`A4`,landscape:i.landscape,margin:{top:o,right:o,bottom:o,left:o},printBackground:!0}))}catch(t){throw r.signal?.aborted?new e.a(`ABORTED`,`转换已取消`):t}finally{r.signal?.removeEventListener(`abort`,o),await a.close()}}exports.renderPdf=n;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { a as e } from "./src-DypdJEH8.js";
|
|
2
|
+
// src/adapters/browser/pdf-renderer.ts
|
|
3
|
+
var t = 32767;
|
|
4
|
+
function n() {
|
|
5
|
+
let e = globalThis.navigator, t = e?.userAgent ?? "";
|
|
6
|
+
return /iPhone|iPad|iPod/.test(t) || /Macintosh/.test(t) && (e?.maxTouchPoints ?? 0) > 1 ? 16e6 : 12e7;
|
|
7
|
+
}
|
|
8
|
+
async function r(r, i) {
|
|
9
|
+
let [{ default: a }, { default: o }] = await Promise.all([import("html2pdf.js"), import("html2canvas")]), s = a(), c = globalThis.document, l = c.createElement("iframe");
|
|
10
|
+
l.setAttribute("sandbox", "allow-same-origin allow-scripts"), l.style.cssText = "position:fixed;left:-20000px;top:0;width:900px;height:1000px;border:0";
|
|
11
|
+
let u = () => {
|
|
12
|
+
if (i.signal?.aborted) throw new e("ABORTED", "转换已取消");
|
|
13
|
+
}, d;
|
|
14
|
+
try {
|
|
15
|
+
await new Promise((t, n) => {
|
|
16
|
+
let i = setTimeout(() => n(new e("PDF_TIMEOUT", "PDF 预览加载超时")), 3e4);
|
|
17
|
+
l.onload = () => {
|
|
18
|
+
clearTimeout(i), t();
|
|
19
|
+
}, l.srcdoc = r, c.body.append(l);
|
|
20
|
+
}), u();
|
|
21
|
+
let a = l.contentDocument;
|
|
22
|
+
await a.fonts.ready, await Promise.all(Array.from(a.images).map((e) => e.decode())), u();
|
|
23
|
+
let f = i.pdf ?? {}, p = f.scale ?? 2, m = {
|
|
24
|
+
scale: p,
|
|
25
|
+
useCORS: !0,
|
|
26
|
+
backgroundColor: "#ffffff",
|
|
27
|
+
logging: !1
|
|
28
|
+
}, h = s.set({
|
|
29
|
+
margin: f.margin ?? 15,
|
|
30
|
+
html2canvas: m,
|
|
31
|
+
jsPDF: {
|
|
32
|
+
unit: "mm",
|
|
33
|
+
format: f.format ?? "a4",
|
|
34
|
+
orientation: f.landscape ? "landscape" : "portrait"
|
|
35
|
+
},
|
|
36
|
+
pagebreak: {
|
|
37
|
+
mode: ["css", "legacy"],
|
|
38
|
+
avoid: ["tr", "img"]
|
|
39
|
+
}
|
|
40
|
+
}).from(a.querySelector(".docx-document"));
|
|
41
|
+
await h.toContainer();
|
|
42
|
+
let g = (e) => h.get(e), _ = await g("container");
|
|
43
|
+
d = await g("overlay");
|
|
44
|
+
let v = await g("pageSize");
|
|
45
|
+
u();
|
|
46
|
+
let y = Math.ceil(_.getBoundingClientRect().width), b = Math.max(1, Math.ceil(Math.max(_.scrollHeight, _.getBoundingClientRect().height))), x = Math.floor(y * p), S = Math.floor(x * v.inner.ratio), C = S / p, w = Math.max(1, Math.ceil(b / C - 1e-6)), T = Math.max(1, Math.min(Math.floor(t / S), Math.floor(n() / (x * S))));
|
|
47
|
+
for (let e = 0; e < w; e += T) {
|
|
48
|
+
u();
|
|
49
|
+
let t = e + T >= w, n = e * C, r = t ? b - n : T * C, i = await o(_, {
|
|
50
|
+
...m,
|
|
51
|
+
x: 0,
|
|
52
|
+
y: n,
|
|
53
|
+
width: y,
|
|
54
|
+
height: r
|
|
55
|
+
});
|
|
56
|
+
u(), e > 0 && await h.get("pdf", (e) => e.addPage()), await h.set({
|
|
57
|
+
canvas: i,
|
|
58
|
+
enableLinks: t
|
|
59
|
+
}).toPdf(), i.width = i.height = 0;
|
|
60
|
+
}
|
|
61
|
+
u();
|
|
62
|
+
let E = await h.outputPdf("arraybuffer");
|
|
63
|
+
return u(), new Uint8Array(E);
|
|
64
|
+
} finally {
|
|
65
|
+
d?.remove(), l.remove();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export { r as renderPdf };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { a as e } from "./src-DypdJEH8.js";
|
|
2
|
+
import { chromium as t } from "playwright-core";
|
|
3
|
+
// src/adapters/node/pdf-renderer.ts
|
|
4
|
+
async function n(n, r) {
|
|
5
|
+
let i = r.pdf ?? {}, a = await t.launch(i.executablePath ? {
|
|
6
|
+
executablePath: i.executablePath,
|
|
7
|
+
headless: !0
|
|
8
|
+
} : {
|
|
9
|
+
channel: "chrome",
|
|
10
|
+
headless: !0
|
|
11
|
+
}), o = () => {
|
|
12
|
+
a.close().catch(() => {});
|
|
13
|
+
};
|
|
14
|
+
r.signal?.addEventListener("abort", o, { once: !0 });
|
|
15
|
+
try {
|
|
16
|
+
if (r.signal?.aborted) throw new e("ABORTED", "转换已取消");
|
|
17
|
+
let t = await a.newPage();
|
|
18
|
+
await t.setContent(n, {
|
|
19
|
+
waitUntil: "load",
|
|
20
|
+
timeout: 3e4
|
|
21
|
+
}), await t.evaluate("Promise.race([Promise.all([document.fonts.ready, ...Array.from(document.images).map(image => image.decode())]), new Promise((_, reject) => setTimeout(() => reject(new Error(\"PDF image/font load timed out\")), 15000))])"), await t.addStyleTag({ content: "table{width:auto;max-width:100%}tr,img{break-inside:avoid}body{padding:0!important}" });
|
|
22
|
+
let o = `${i.margin ?? 15}mm`;
|
|
23
|
+
return new Uint8Array(await t.pdf({
|
|
24
|
+
format: i.format === "letter" ? "Letter" : "A4",
|
|
25
|
+
landscape: i.landscape,
|
|
26
|
+
margin: {
|
|
27
|
+
top: o,
|
|
28
|
+
right: o,
|
|
29
|
+
bottom: o,
|
|
30
|
+
left: o
|
|
31
|
+
},
|
|
32
|
+
printBackground: !0
|
|
33
|
+
}));
|
|
34
|
+
} catch (t) {
|
|
35
|
+
throw r.signal?.aborted ? new e("ABORTED", "转换已取消") : t;
|
|
36
|
+
} finally {
|
|
37
|
+
r.signal?.removeEventListener("abort", o), await a.close();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export { n as renderPdf };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("./src-CGXH7X67.cjs");var t=32767;function n(){let e=globalThis.navigator,t=e?.userAgent??``;return/iPhone|iPad|iPod/.test(t)||/Macintosh/.test(t)&&(e?.maxTouchPoints??0)>1?16e6:12e7}async function r(r,i){let[{default:a},{default:o}]=await Promise.all([import(`html2pdf.js`),import(`html2canvas`)]),s=a(),c=globalThis.document,l=c.createElement(`iframe`);l.setAttribute(`sandbox`,`allow-same-origin allow-scripts`),l.style.cssText=`position:fixed;left:-20000px;top:0;width:900px;height:1000px;border:0`;let u=()=>{if(i.signal?.aborted)throw new e.a(`ABORTED`,`转换已取消`)},d;try{await new Promise((t,n)=>{let i=setTimeout(()=>n(new e.a(`PDF_TIMEOUT`,`PDF 预览加载超时`)),3e4);l.onload=()=>{clearTimeout(i),t()},l.srcdoc=r,c.body.append(l)}),u();let a=l.contentDocument;await a.fonts.ready,await Promise.all(Array.from(a.images).map(e=>e.decode())),u();let f=i.pdf??{},p=f.scale??2,m={scale:p,useCORS:!0,backgroundColor:`#ffffff`,logging:!1},h=s.set({margin:f.margin??15,html2canvas:m,jsPDF:{unit:`mm`,format:f.format??`a4`,orientation:f.landscape?`landscape`:`portrait`},pagebreak:{mode:[`css`,`legacy`],avoid:[`tr`,`img`]}}).from(a.querySelector(`.docx-document`));await h.toContainer();let g=e=>h.get(e),_=await g(`container`);d=await g(`overlay`);let v=await g(`pageSize`);u();let y=Math.ceil(_.getBoundingClientRect().width),b=Math.max(1,Math.ceil(Math.max(_.scrollHeight,_.getBoundingClientRect().height))),x=Math.floor(y*p),S=Math.floor(x*v.inner.ratio),C=S/p,w=Math.max(1,Math.ceil(b/C-1e-6)),T=Math.max(1,Math.min(Math.floor(t/S),Math.floor(n()/(x*S))));for(let e=0;e<w;e+=T){u();let t=e+T>=w,n=e*C,r=t?b-n:T*C,i=await o(_,{...m,x:0,y:n,width:y,height:r});u(),e>0&&await h.get(`pdf`,e=>e.addPage()),await h.set({canvas:i,enableLinks:t}).toPdf(),i.width=i.height=0}u();let E=await h.outputPdf(`arraybuffer`);return u(),new Uint8Array(E)}finally{d?.remove(),l.remove()}}exports.renderPdf=r;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Block, ImageNode, Paragraph, Table } from '../../domain/document.js';
|
|
2
|
+
type CaptionMatch = {
|
|
3
|
+
kind: 'table';
|
|
4
|
+
table: Table;
|
|
5
|
+
caption: Paragraph;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'figure';
|
|
8
|
+
paragraph: Paragraph;
|
|
9
|
+
image: ImageNode;
|
|
10
|
+
};
|
|
11
|
+
/** Pure adjacent-block policy: keep caption recognition separate from HTML construction. */
|
|
12
|
+
export declare function matchCaption(block: Block, next?: Block): CaptionMatch | undefined;
|
|
13
|
+
export {};
|