/** * DocxIR → `@office-open/docx` options. * * The backend takes a plain JSON document rather than an object graph, so this * layer is a pure function from IR nodes to option bags. Its vocabulary is * close to the docx.js adapter's — both mirror OOXML — but the two are kept * separate on purpose: they disagree about enough (tagged section children, * `simpleField` instead of a field class, `verticalMerge` instead of a merge * enum) that sharing the code would mean a conditional in every function. * * Backend gaps are handled by *not declaring the capability* in `index.ts`, so * anything this module cannot express has already been rejected before it is * called. Reaching a `throw` here is a bug, not a user error. */ /// /// import type { DocxIrBlock, DocxIrChartRun, DocxIrFloating, DocxIrInline, DocxIrNumbering, DocxIrParagraph, DocxIrParagraphFormatting, DocxIrRunFormatting, DocxIrSection, DocxIrTable } from '../../ir/types'; import { emuToPixels } from '../../ir/units'; type Opts = Record; /** * One prepared image per placement size. * * A vector image needs a rasterised fallback sized to the placement, and * producing it is asynchronous while this layer is not — so the renderer builds * the media first and this only places it. * * Media rather than a whole picture because the same bytes are placed two * different ways: a run-level `picture` states its size as a plain * `MediaTransformation`, while a group child states an already-resolved * `MediaDataTransformation` with an offset inside the group. Sharing the * factory is what keeps a resource embedded once however it is drawn. */ export interface PreparedImage { /** `png`, `jpg`, `svg`, … — the backend's media type tag. */ type: string; data: Buffer; /** The raster Word draws when it cannot draw the vector. */ fallback?: { type: string; data: Buffer; }; /** * The media part name these bytes are stored under. * * A run-level picture lets the backend allocate one. A *group child* cannot: * the backend registers grouped media with a factory that ignores the name * it is offered, so an unnamed child ends up referencing `{undefined}` and * the package ships a part called `media/undefined`. Deriving the name from * the resource and its drawn size keeps it deterministic and keeps two * identical placements sharing one part. */ fileName: string; fallbackFileName?: string; } export type ImageMediaFactory = (placement: { widthEmu: number; heightEmu: number; }) => PreparedImage; /** * What emitting a document needs beyond the IR itself. * * `nextDrawingId` exists because the backend numbers `wp:docPr` from a * module-level counter whenever a drawing does not state an id. That counter is * process-global: the same document rendered twice comes out with different * ids, and two rendered at once interleave. Every drawing this adapter emits * therefore states its own id, allocated per render in document order — which * is deterministic and cannot leak between documents. */ export interface EmitContext { /** Prepared image media, keyed by IR resource id. */ pictures: ReadonlyMap; /** Allocate the next `wp:docPr` id for this document. */ nextDrawingId: () => number; /** * Charts, in the order they were emitted. * * The backend numbers `word/charts/chartN.xml` by the order it stringifies * chart runs, which is document order — the same order this array fills. The * post-generation splice reads it to match each part with the data the * backend dropped. */ charts?: DocxIrChartRun[]; } /** A context for content that holds no drawings, and for tests. */ export declare function emptyContext(): EmitContext; export declare function runProperties(formatting: DocxIrRunFormatting | undefined): Opts; /** * Turn inline nodes into paragraph children. * * `pendingBreaks` carries a run of `lineBreak` nodes forward onto whichever run * comes next, which is where the backend puts them — `` is run-inner * content, so it has to ride on a run either way. */ export declare function inlineChildren(children: readonly DocxIrInline[], ctx?: EmitContext): Opts[]; /** An IR anchor as the backend's floating options. */ export declare function floatingOptions(floating: DocxIrFloating): Opts; export declare function paragraphProperties(formatting: DocxIrParagraphFormatting | undefined): Opts; export declare function paragraph(block: DocxIrParagraph, ctx?: EmitContext): Opts; /** One IR block as a tagged section child, which is how the backend takes it. */ export declare function block(value: DocxIrBlock, ctx?: EmitContext): Opts; export declare function table(value: DocxIrTable, ctx: EmitContext): Opts; export declare function section(value: DocxIrSection, ctx: EmitContext, closesDocument?: boolean): Opts; export declare function numberingConfig(numbering: DocxIrNumbering): Opts; export { emuToPixels }; //# sourceMappingURL=emit.d.ts.map