@silurus/ooxml 0.71.0 → 0.72.1

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.
@@ -1,4 +1,4 @@
1
- import { w as e } from "./find-cursor-DgyGlCIw.js";
1
+ import { V as e } from "./find-cursor-CABDFafh.js";
2
2
  //#region packages/core/src/text/bidi/segments.ts
3
3
  function t(t, n) {
4
4
  return t === !0 ? "rtl" : t === !1 ? "ltr" : e().computeLevels(n, "auto").paragraphLevel === 1 ? "rtl" : "ltr";
@@ -69,6 +69,14 @@ export declare type BodyElement = {
69
69
  * separately from `geom` because a section may inherit its geometry yet
70
70
  * still restart / re-format its page numbers. */
71
71
  pageNumType?: PageNumType | null;
72
+ /** ECMA-376 §17.6.20 `<w:textDirection w:val>` — this ENDING section's
73
+ * flow direction (TRANSITIONAL ST_TextDirection, same enum and semantics
74
+ * as {@link SectionProps.textDirection}), so a vertical (tbRl/btLr)
75
+ * non-final section can coexist with a horizontal final section (issue
76
+ * #1000). Absent ⇒ horizontal ("lrTb" is collapsed by the parser).
77
+ * Carried separately from `geom` (like `pageNumType`) because a section
78
+ * may inherit its page geometry yet still set its own flow direction. */
79
+ textDirection?: string | null;
72
80
  };
73
81
 
74
82
  export declare interface BorderSpec {
@@ -80,17 +88,23 @@ export declare interface BorderSpec {
80
88
  /**
81
89
  * Populate a highlight overlay layer with one box per matched run-slice.
82
90
  *
83
- * @param layer the overlay div (cleared and re-sized to the canvas here).
91
+ * Every box is positioned as a PERCENTAGE of `cssWidth`/`cssHeight`, and the
92
+ * container's own size is left untouched (`width:100%;height:100%` from the
93
+ * caller), so the highlights track the canvas's ACTUAL rendered box even when a
94
+ * consumer scales the canvas down with external CSS — mirroring
95
+ * {@link buildDocxTextLayer}.
96
+ *
97
+ * @param layer the overlay div (cleared here; sized `100%` by the caller).
84
98
  * @param runs the page's runs (same array the page was rendered/text-layered from).
85
99
  * @param matches the page's matches (run-slices + active flag).
86
- * @param canvasCssWidth the rendered canvas's CSS width (e.g. `"700px"`).
87
- * @param canvasCssHeight the rendered canvas's CSS height.
100
+ * @param cssWidth the page's intended CSS width (px, number) — the x-axis % denominator.
101
+ * @param cssHeight the page's intended CSS height (px, number) — the y-axis % denominator.
88
102
  * @param measureForFont returns a width-measurer primed with a run's `font`
89
103
  * (the viewer closes over a canvas 2d context). Kept as a
90
104
  * factory so the font is set once per run, not per glyph.
91
105
  * @param colors optional colour overrides.
92
106
  */
93
- export declare function buildDocxHighlightLayer(layer: HTMLDivElement, runs: DocxTextRunInfo[], matches: DocxHighlightMatch[], canvasCssWidth: string, canvasCssHeight: string, measureForFont: (font: string) => (s: string) => number, colors?: DocxHighlightColors): void;
107
+ export declare function buildDocxHighlightLayer(layer: HTMLDivElement, runs: DocxTextRunInfo[], matches: DocxHighlightMatch[], cssWidth: number, cssHeight: number, measureForFont: (font: string) => (s: string) => number, colors?: DocxHighlightColors): void;
94
108
 
95
109
  /**
96
110
  * Build the transparent text-selection overlay for a rendered docx page: one
@@ -103,11 +117,21 @@ export declare function buildDocxHighlightLayer(layer: HTMLDivElement, runs: Doc
103
117
  * the same `DocxTextRunInfo[]` off-thread and ships it back beside the bitmap, so
104
118
  * the overlay is built from identical geometry regardless of thread.
105
119
  *
106
- * @param layer the overlay div (position:relative parent expected).
120
+ * Every span is positioned as a PERCENTAGE of `cssWidth`/`cssHeight` (the page's
121
+ * intended CSS-px box), never literal px, and the container's own width/height are
122
+ * left untouched (the caller sizes it `width:100%;height:100%`). This lets the
123
+ * overlay track the canvas's ACTUAL rendered box even when a consumer scales the
124
+ * canvas down with external CSS (`width:100%!important; height:auto`): the
125
+ * `display:inline-block` wrapper shrinks with the canvas, the `100%` container
126
+ * follows, and every `%`-placed span scales with it, so nothing overflows the
127
+ * wrapper into an ancestor's scroll area.
128
+ *
129
+ * @param layer the overlay div (sized `width:100%;height:100%` by the caller).
107
130
  * @param runs per-run geometry from `renderPage({ onTextRun })`.
108
- * @param canvasCssWidth the rendered canvas's CSS width (e.g. `"700px"`), used
109
- * to size the overlay to match the canvas.
110
- * @param canvasCssHeight the rendered canvas's CSS height.
131
+ * @param cssWidth the page's intended CSS width (px, number) — the %
132
+ * denominator for the x axis.
133
+ * @param cssHeight the page's intended CSS height (px, number) — the %
134
+ * denominator for the y axis.
111
135
  * @param onHyperlinkClick IX1 — invoked when a run carrying a resolved
112
136
  * {@link HyperlinkTarget} is clicked. A hyperlink run's
113
137
  * span keeps its transparent glyphs (the visible link
@@ -127,7 +151,7 @@ export declare function buildDocxHighlightLayer(layer: HTMLDivElement, runs: Doc
127
151
  * a 縦中横 span keeps the bare rotate (no regression for
128
152
  * callers that do not thread a measurer).
129
153
  */
130
- export declare function buildDocxTextLayer(layer: HTMLDivElement, runs: DocxTextRunInfo[], canvasCssWidth: string, canvasCssHeight: string, onHyperlinkClick?: (target: HyperlinkTarget) => void, measureForFont?: (font: string) => (s: string) => number): void;
154
+ export declare function buildDocxTextLayer(layer: HTMLDivElement, runs: DocxTextRunInfo[], cssWidth: number, cssHeight: number, onHyperlinkClick?: (target: HyperlinkTarget) => void, measureForFont?: (font: string) => (s: string) => number): void;
131
155
 
132
156
  export declare interface CellBorders {
133
157
  top: BorderSpec | null;
@@ -312,6 +336,14 @@ declare interface ChartModel {
312
336
  title: string | null;
313
337
  categories: string[];
314
338
  series: ChartSeries[];
339
+ /**
340
+ * §21.2.2.227 `<c:varyColors val="1"/>` on a SINGLE-series bar/column chart:
341
+ * color each data point (bar) from the theme/palette sequence and list one
342
+ * legend entry per point, matching Office. Set by the shared parser ONLY for
343
+ * that non-pie, single-series case (pie/doughnut already vary by point via
344
+ * `chartType` + `dataPointColors`); absent/false otherwise.
345
+ */
346
+ varyColors?: boolean | null;
315
347
  /** Show data labels on bars / points / slices. */
316
348
  showDataLabels: boolean;
317
349
  /** Explicit Y-axis minimum (OOXML `<c:valAx><c:min>`). */
@@ -690,8 +722,9 @@ declare interface ChartModel {
690
722
  * core `renderChart` consumes (identical to what pptx/xlsx pass), so a docx
691
723
  * chart draws at the same quality through the same code path. `widthPt`/
692
724
  * `heightPt` are the `<wp:extent>` natural size. An inline chart flows as an
693
- * inline box of that size; an anchored chart (§20.4.2.3) is painted at its
694
- * absolute page box by `renderAnchorImages` — both via `renderChart`. */
725
+ * inline box of that size; an anchored chart (§20.4.2.3) is painted via
726
+ * `registerAnchorFloats` when it wraps text, or by `renderAnchorImages` for
727
+ * wrapNone/no-wrap anchors — all paths use `renderChart`. */
695
728
  export declare interface ChartRun {
696
729
  chart: ChartModel;
697
730
  widthPt: number;
@@ -703,6 +736,39 @@ export declare interface ChartRun {
703
736
  anchorYPt?: number;
704
737
  anchorXFromMargin?: boolean;
705
738
  anchorYFromPara?: boolean;
739
+ /**
740
+ * Wrap mode for anchored charts (ECMA-376 §20.4.2.16/.17):
741
+ * "square" | "topAndBottom" | "none" | "tight" | "through"
742
+ * Inline charts and undetermined cases leave this undefined. The renderer
743
+ * treats "tight" and "through" as "square", matching anchored images.
744
+ */
745
+ wrapMode?: string;
746
+ /** Padding top (pt). Anchor-only (ECMA-376 §20.4.2.16/.17). */
747
+ distTop?: number;
748
+ /** Padding bottom (pt). Anchor-only (ECMA-376 §20.4.2.16/.17). */
749
+ distBottom?: number;
750
+ /** Padding left (pt). Anchor-only (ECMA-376 §20.4.2.16/.17). */
751
+ distLeft?: number;
752
+ /** Padding right (pt). Anchor-only (ECMA-376 §20.4.2.16/.17). */
753
+ distRight?: number;
754
+ /** wrapText attribute: "bothSides" | "left" | "right" | "largest". */
755
+ wrapSide?: string;
756
+ /**
757
+ * ECMA-376 §20.4.2.3 `wp:anchor/@allowOverlap`. The parser omits this
758
+ * field when true, so renderers must read it as `allowOverlap ?? true`.
759
+ */
760
+ allowOverlap?: boolean;
761
+ /** ECMA-376 §20.4.3.1 wp:align horizontal: "left" | "center" | "right" |
762
+ * "inside" | "outside". */
763
+ anchorXAlign?: string | null;
764
+ /** Vertical equivalent of anchorXAlign: "top" | "center" | "bottom". */
765
+ anchorYAlign?: string | null;
766
+ /**
767
+ * ECMA-376 §20.4.3.2 `<wp:positionH/@relativeFrom>` / §20.4.3.5
768
+ * `<wp:positionV/@relativeFrom>` — the raw anchor placement containers.
769
+ */
770
+ anchorXRelativeFrom?: string | null;
771
+ anchorYRelativeFrom?: string | null;
706
772
  }
707
773
 
708
774
  declare interface ChartSeries {
@@ -975,12 +1041,20 @@ export declare interface DocParagraph {
975
1041
  shading?: string | null;
976
1042
  /** Force a page break before this paragraph (w:pageBreakBefore) */
977
1043
  pageBreakBefore?: boolean;
978
- /** Suppress spacing between adjacent same-style paragraphs (w:contextualSpacing) */
1044
+ /** ECMA-376 §17.3.1.9 `<w:contextualSpacing>` — between adjacent SAME-style
1045
+ * paragraphs, a toggling paragraph drops its OWN contribution to the
1046
+ * collapsed inter-paragraph gap (per-side, Word-adjudicated — issue #1015;
1047
+ * see the renderer's `contextualSpacingAdjust`). */
979
1048
  contextualSpacing?: boolean;
980
1049
  /** Keep paragraph on same page as the next paragraph (w:keepNext) */
981
1050
  keepNext?: boolean;
982
1051
  /** Keep all lines of this paragraph on the same page (w:keepLines) */
983
1052
  keepLines?: boolean;
1053
+ /** ECMA-376 §17.3.1.29 + §17.3.2.41 — the paragraph MARK's resolved `w:vanish`
1054
+ * (hidden text). An inkless paragraph whose mark is vanished collapses to zero
1055
+ * height in the normal/print view (hidden-text off), the same way the parser
1056
+ * strips hidden runs; the paginator drops it whole. Absent = mark is visible. */
1057
+ markVanish?: boolean;
984
1058
  /** Widow/orphan control (w:widowControl). ECMA-376 default is true. */
985
1059
  widowControl?: boolean;
986
1060
  /** Paragraph borders (w:pBdr) */
@@ -992,6 +1066,17 @@ export declare interface DocParagraph {
992
1066
  /** Default font family resolved from the style chain. Used to size empty
993
1067
  * paragraphs (no runs) with the intended font's line metrics. */
994
1068
  defaultFontFamily?: string | null;
1069
+ /** Default East Asian font family resolved from the style chain. Empty /
1070
+ * anchor-only paragraph marks in East Asian documents use this axis for line
1071
+ * metrics instead of the ASCII fallback. */
1072
+ defaultFontFamilyEastAsia?: string | null;
1073
+ /** ECMA-376 §17.3.1.29 — the paragraph MARK run's resolved `w:color` (direct
1074
+ * pPr/rPr → pStyle chain → docDefaults; hex 6 without `#`, lowercased; an
1075
+ * explicit `auto` surfaces as absent, §17.3.2.6). Word formats a numbering
1076
+ * marker with the level rPr (§17.9.24) layered over the mark's run
1077
+ * properties, so the renderer uses this as the marker-color fallback when
1078
+ * {@link NumberingInfo.color} is absent. */
1079
+ paragraphMarkColor?: string | null;
995
1080
  /**
996
1081
  * ECMA-376 §17.3.1.6 `<w:bidi>` — right-to-left paragraph. `true` = RTL,
997
1082
  * `false` = explicitly LTR, absent = unspecified (inherit). The renderer uses
@@ -1069,6 +1154,17 @@ export declare interface DocSettings {
1069
1154
  * tab stops generated after all custom stops. `undefined` ⇒ the renderer
1070
1155
  * uses the spec default of 720 twips (36pt). */
1071
1156
  defaultTabStop?: number;
1157
+ /** §17.15.1.18 `w:characterSpacingControl@w:val` — East Asian punctuation /
1158
+ * character-spacing control. */
1159
+ characterSpacingControl?: string;
1160
+ /** §17.15.3.1 `w:compat/w:useFELayout` — Far East layout compatibility. */
1161
+ useFeLayout?: boolean;
1162
+ /** §17.15.3.1 `w:compat/w:balanceSingleByteDoubleByteWidth` — balance
1163
+ * single-byte and double-byte widths for East Asian layout. */
1164
+ balanceSingleByteDoubleByteWidth?: boolean;
1165
+ /** §17.15.3.1 `w:compat/w:adjustLineHeightInTable` — apply the section
1166
+ * document-grid line pitch to text in table cells. */
1167
+ adjustLineHeightInTable?: boolean;
1072
1168
  }
1073
1169
 
1074
1170
  export declare interface DocTable {
@@ -1145,11 +1241,20 @@ export declare interface DocTableCell {
1145
1241
 
1146
1242
  export declare interface DocTableRow {
1147
1243
  cells: DocTableCell[];
1244
+ /** ECMA-376 §17.4.15 `<w:gridBefore>` — shared table-grid columns skipped
1245
+ * before placing this row's first real cell. Omitted/zero means none. */
1246
+ gridBefore?: number;
1247
+ /** ECMA-376 §17.4.14 `<w:gridAfter>` — shared table-grid columns skipped
1248
+ * after this row's last real cell. Omitted/zero means none. */
1249
+ gridAfter?: number;
1148
1250
  rowHeight: number | null;
1149
1251
  /** ECMA-376 §17.4.80 hRule. "auto" (default) = informational; "atLeast" =
1150
1252
  * lower bound; "exact" = fixed clip. */
1151
1253
  rowHeightRule: 'auto' | 'atLeast' | 'exact' | string;
1152
1254
  isHeader: boolean;
1255
+ /** ECMA-376 §17.4.6 `<w:cantSplit>` — when true, the row must not be split
1256
+ * across page boundaries. Omitted/false rows may split at page boundaries. */
1257
+ cantSplit?: boolean;
1153
1258
  }
1154
1259
 
1155
1260
  export declare class DocxDocument {
@@ -1333,6 +1438,16 @@ export declare interface DocxDocumentModel {
1333
1438
  * entry is absent or classified as "auto".
1334
1439
  */
1335
1440
  fontFamilyClasses?: Record<string, string>;
1441
+ /**
1442
+ * ECMA-376 §17.8.3.29 — per-font pitch from `word/fontTable.xml`
1443
+ * (`<w:pitch>`, ST_Pitch §17.18.66): font name → "fixed" | "variable" |
1444
+ * "default". Present only for fonts that declare `<w:pitch>`. The renderer
1445
+ * pairs this with {@link fontFamilyClasses}: a `family="modern"` face is
1446
+ * treated as monospace ONLY when its pitch is "fixed"; "variable" /
1447
+ * "default" / absent fall through to name-pattern / CJK-sans classification
1448
+ * (§17.8.3.10 `family` classifies the design, not the pitch — issue #855).
1449
+ */
1450
+ fontFamilyPitches?: Record<string, string>;
1336
1451
  /** ECMA-376 §17.8.3.3-.6 — embedded fonts from `word/fontTable.xml`, resolved
1337
1452
  * to their `.odttf` part paths + fontKey. The viewer de-obfuscates (§17.8.1)
1338
1453
  * and registers each as a FontFace before pagination so text measures/draws
@@ -1635,6 +1750,12 @@ export declare class DocxScrollViewer implements ZoomableViewer {
1635
1750
  * {@link DocxDocument.getBookmarkPage} (ECMA-376 §17.16.23) and scrolls there
1636
1751
  * with {@link scrollToPage}. An anchor naming no known bookmark is a safe no-op
1637
1752
  * rather than a scroll to a guessed page.
1753
+ *
1754
+ * IX1 — returns `undefined` when `enableHyperlinks` is `false`, the single gate
1755
+ * that disables hyperlink interactivity: {@link buildDocxTextLayer} treats a
1756
+ * missing handler as "render link runs like plain runs", so no hit region,
1757
+ * cursor, tooltip, listener, or navigation is wired (a custom
1758
+ * `onHyperlinkClick` is suppressed too).
1638
1759
  */
1639
1760
  private _hyperlinkHandler;
1640
1761
  /** A width-measurer primed with a run's `font` — used ONLY to clamp a §17.3.2.10
@@ -1643,6 +1764,10 @@ export declare class DocxScrollViewer implements ZoomableViewer {
1643
1764
  * unavailable so the caller still gets a callable (the overlay then sees scale
1644
1765
  * 1 and leaves the span un-clamped). */
1645
1766
  private _measureForFont;
1767
+ /** A canvas's intended CSS box in px (the % denominators the overlay builders
1768
+ * expect). Reads the inline `style.width`/`height` set by the render path,
1769
+ * falling back to the backing-store size when unset; tolerates the `px` suffix. */
1770
+ private _canvasCssPx;
1646
1771
  /** Route an async render failure to `onError`, or `console.error` when none is
1647
1772
  * set (so failures are never fully silent), and never after teardown. */
1648
1773
  private _reportRenderError;
@@ -1939,6 +2064,13 @@ export declare interface DocxScrollViewerOptions extends Omit<RenderPageOptions,
1939
2064
  * new tab via core `openExternalHyperlink` (sanitised, noopener,noreferrer);
1940
2065
  * internal → jump to the page whose text contains the bookmark (best-effort). */
1941
2066
  onHyperlinkClick?: (target: HyperlinkTarget) => void;
2067
+ /** IX1 — master switch for hyperlink interactivity. Default `true`. When
2068
+ * `false`, the hyperlink machinery is not wired at all: no overlay hit region
2069
+ * is installed for link runs, so there is no pointer cursor, no title tooltip,
2070
+ * no default navigation (external new-tab / internal bookmark jump), and
2071
+ * `onHyperlinkClick` is never called. Links still render exactly as authored
2072
+ * but are inert, like plain text. */
2073
+ enableHyperlinks?: boolean;
1942
2074
  /** Error callback. When set, `load()` invokes it and resolves (otherwise the
1943
2075
  * error is rethrown — shared viewer error contract). It ALSO fires for async
1944
2076
  * per-slot render failures (both main `renderPage` and worker
@@ -2037,12 +2169,22 @@ export declare interface DocxTextRun {
2037
2169
  /** ECMA-376 §17.3.2.20 `<w:lang w:bidi>` — complex-script (RTL) language tag,
2038
2170
  * lower-cased (e.g. "ar-sa", "ae-ar"). Drives Word's AN digit ordering. */
2039
2171
  langBidi?: string;
2172
+ /** ECMA-376 §17.3.2.34 `<w:snapToGrid>` — false opts this run out of the
2173
+ * section character grid; absent inherits participation. */
2174
+ snapToGrid?: boolean;
2040
2175
  /** ECMA-376 §17.3.2.35 `<w:spacing w:val>` — character-spacing adjustment in
2041
2176
  * POINTS (signed): the extra pitch added after each character before the next
2042
2177
  * is rendered. The renderer feeds it to `ctx.letterSpacing` on BOTH the
2043
2178
  * measure and paint passes so line breaking / pagination stay consistent.
2044
2179
  * Absent ⇒ no extra pitch. */
2045
2180
  charSpacing?: number;
2181
+ /** ECMA-376 §17.3.2.14 `<w:fitText>` — manual run-width target in TWIPS
2182
+ * (`w:val`, 1/20 pt) plus the optional `w:id` that links consecutive runs
2183
+ * into one region. The arbitrary-precision XSD integer id is serialized as a
2184
+ * string; numeric synthetic inputs remain supported for layout tests and
2185
+ * direct model construction. An id-less run is always standalone. */
2186
+ fitTextVal?: number;
2187
+ fitTextId?: string | number;
2046
2188
  /** ECMA-376 §17.3.2.43 `<w:w w:val>` — horizontal text scale as a FRACTION of
2047
2189
  * normal character width (0.67 = 67%, 2.0 = 200%). Stretches each glyph's
2048
2190
  * width, not the gap between glyphs. Absent ⇒ 100%. */
@@ -2096,6 +2238,9 @@ export declare interface DocxTextRunInfo {
2096
2238
  fontSize: number;
2097
2239
  /** CSS `font` shorthand used for canvas drawing (e.g. `"bold 16px Arial"`). */
2098
2240
  font: string;
2241
+ /** Uniform per-code-point pitch in CSS px used to draw a horizontal run.
2242
+ * Absent when the pitch is zero or the run uses vertical / 縦中横 paint. */
2243
+ letterSpacingPx?: number;
2099
2244
  /** ECMA-376 §17.6.20 (tbRl) — when the page is vertical the canvas is the
2100
2245
  * physical landscape page rotated +90° at paint, so this run's `x`/`y` are the
2101
2246
  * PHYSICAL top-left the overlay span must sit at, and `transform` is the CSS
@@ -2305,6 +2450,11 @@ export declare class DocxViewer implements ZoomableViewer {
2305
2450
  /** Draw the find-highlight boxes for the current page from its runs. Clears
2306
2451
  * the overlay when there is no active find. */
2307
2452
  private _buildHighlightLayer;
2453
+ /** The canvas's intended CSS box in px (the % denominators the overlay builders
2454
+ * expect). Reads the inline `style.width`/`height` set by the render path
2455
+ * (which mirror the render's logical size), falling back to the backing-store
2456
+ * dimensions when unset. Parsing tolerates the trailing `px`. */
2457
+ private _canvasCssPx;
2308
2458
  /** A width-measurer primed with `font`, backed by a private 1×1 canvas so it
2309
2459
  * never disturbs the visible canvas's context state. */
2310
2460
  private _measureForFont;
@@ -2323,6 +2473,12 @@ export declare class DocxViewer implements ZoomableViewer {
2323
2473
  * {@link DocxDocument.getBookmarkPage} (ECMA-376 §17.16.23) and jumps there
2324
2474
  * with {@link goToPage}. An anchor naming no known bookmark is a safe no-op
2325
2475
  * rather than a jump to a guessed page.
2476
+ *
2477
+ * IX1 — returns `undefined` when `enableHyperlinks` is `false`, the single gate
2478
+ * that disables hyperlink interactivity: {@link buildDocxTextLayer} treats a
2479
+ * missing handler as "render link runs like plain runs", so no hit region,
2480
+ * cursor, tooltip, listener, or navigation is wired (a custom
2481
+ * `onHyperlinkClick` is suppressed too).
2326
2482
  */
2327
2483
  private _hyperlinkHandler;
2328
2484
  }
@@ -2352,6 +2508,15 @@ export declare interface DocxViewerOptions extends RenderPageOptions, LoadOption
2352
2508
  * new tab via core `openExternalHyperlink` (sanitised, noopener,noreferrer);
2353
2509
  * internal → jump to the page whose text contains the bookmark (best-effort). */
2354
2510
  onHyperlinkClick?: (target: HyperlinkTarget) => void;
2511
+ /** IX1 — master switch for hyperlink interactivity. Default `true`. When
2512
+ * `false`, the hyperlink machinery is not wired at all: no overlay hit region
2513
+ * is installed for link runs, so there is no pointer cursor, no title tooltip,
2514
+ * no default navigation (external new-tab / internal bookmark jump), and
2515
+ * `onHyperlinkClick` is never called. Links still render exactly as authored
2516
+ * (their colour/underline are painted on the canvas) but are inert, like plain
2517
+ * text. Set it to disable clickable links entirely — e.g. in a preview where
2518
+ * navigation must not leave the current view. */
2519
+ enableHyperlinks?: boolean;
2355
2520
  /** Called on parse or render errors. */
2356
2521
  onError?: (err: Error) => void;
2357
2522
  }
@@ -2583,6 +2748,10 @@ export declare interface ImageRun {
2583
2748
  } | null;
2584
2749
  widthPt: number;
2585
2750
  heightPt: number;
2751
+ /** Effective DrawingML transform for grouped pictures. */
2752
+ rotation?: number;
2753
+ flipH?: boolean;
2754
+ flipV?: boolean;
2586
2755
  /** true = wp:anchor (absolute positioned), false/undefined = wp:inline (flows with text) */
2587
2756
  anchor?: boolean;
2588
2757
  /** X offset in pt (anchor only) */
@@ -3072,6 +3241,19 @@ export declare interface NumberingInfo {
3072
3241
  * this family. Absent ⇒ the renderer falls back to
3073
3242
  * {@link NumberingInfo.fontFamily}. */
3074
3243
  fontFamilyEastAsia?: string | null;
3244
+ /** ECMA-376 §17.9.24 — the numbering level rPr's `w:color` (hex 6 without
3245
+ * `#`, lowercased). Colors the marker glyph only, never the paragraph's
3246
+ * runs. Absent ⇒ the renderer falls back to
3247
+ * {@link DocParagraph.paragraphMarkColor} (§17.3.1.29 — Word layers the
3248
+ * level rPr over the paragraph mark's run properties) and finally to its
3249
+ * default ink. An explicit `w:val="auto"` is absent here + {@link colorAuto}. */
3250
+ color?: string | null;
3251
+ /** ECMA-376 §17.3.2.6 / ST_HexColorAuto (§17.18.39) — true when the level
3252
+ * rPr carries an EXPLICIT `w:color w:val="auto"`. Auto names no concrete
3253
+ * color but is not "unset": it breaks the paragraph-mark fallback, so the
3254
+ * marker draws the automatic (default) ink instead of
3255
+ * {@link DocParagraph.paragraphMarkColor}. */
3256
+ colorAuto?: boolean;
3075
3257
  /** ECMA-376 §17.9.9/§17.9.20 — when the level uses a `<w:lvlPicBulletId>`,
3076
3258
  * the marker is this image (zip path, e.g. `word/media/image1.gif`), drawn in
3077
3259
  * place of {@link NumberingInfo.text}. Absent ⇒ ordinary text/glyph marker. */
@@ -3298,6 +3480,10 @@ export declare interface RubyAnnotation {
3298
3480
  text: string;
3299
3481
  /** Annotation font size in pt. Word stores this as half-points in `<w:hps>`. */
3300
3482
  fontSizePt: number;
3483
+ /** Distance “between the phonetic guide base text and the phonetic guide
3484
+ * text” in pt. Word stores this as half-points in `<w:hpsRaise>`
3485
+ * (ECMA-376 §17.3.3.12). */
3486
+ hpsRaisePt?: number;
3301
3487
  }
3302
3488
 
3303
3489
  export declare interface RunRevision {
@@ -3497,7 +3683,7 @@ export declare interface ShapeRun {
3497
3683
  groupHeightPt?: number | null;
3498
3684
  /** Draw behind text when true (wp:anchor behindDoc="1"). */
3499
3685
  behindDoc?: boolean;
3500
- /** Document-order index within a group; lower values render first. */
3686
+ /** ECMA-376 §20.4.2.3 `wp:anchor/@relativeHeight`: lower values render first. */
3501
3687
  zOrder: number;
3502
3688
  /** Normalized [0,1] custom-geometry sub-paths. Empty when `presetGeometry`
3503
3689
  * is set; the renderer chooses between buildCustomPath and buildShapePath. */
@@ -3505,13 +3691,17 @@ export declare interface ShapeRun {
3505
3691
  /** OOXML <a:prstGeom prst> name (e.g. "rect", "ellipse", "rtTriangle").
3506
3692
  * When set the renderer calls core's buildShapePath with `adjValues`. */
3507
3693
  presetGeometry?: string | null;
3508
- /** Up to four <a:gd name="adj{n}"> values from prstGeom/avLst (0–100000). */
3509
- adjValues?: number[];
3694
+ /** <a:gd name="adj{n}"> values from prstGeom/avLst in adj1..adj8 order.
3695
+ * `null` preserves omitted named guides so the preset engine can use the
3696
+ * geometry's default for that index. */
3697
+ adjValues?: Array<number | null>;
3510
3698
  fill: ShapeFill | null;
3511
3699
  stroke: string | null;
3512
3700
  strokeWidth?: number;
3513
3701
  /** `<a:ln><a:prstDash val>` — ECMA-376 §20.1.8.48. Absent = solid. */
3514
3702
  strokeDash?: string | null;
3703
+ /** Normalized line cap: `butt` | `round` | `square`. */
3704
+ strokeCap?: CanvasLineCap | null;
3515
3705
  /** `<a:ln><a:headEnd>` line-start decoration (ECMA-376 §20.1.8.3). */
3516
3706
  headEnd?: LineEnd | null;
3517
3707
  /** `<a:ln><a:tailEnd>` line-end decoration (ECMA-376 §20.1.8.3). */
@@ -3556,6 +3746,14 @@ export declare interface ShapeRun {
3556
3746
  textInsetT?: number;
3557
3747
  textInsetR?: number;
3558
3748
  textInsetB?: number;
3749
+ /** ECMA-376 §20.1.10.83 ST_TextVerticalType — the text-body flow direction from
3750
+ * `<wps:bodyPr vert>` / `<a:bodyPr vert>`. Recognised vertical values:
3751
+ * "vert" (all glyphs 90° CW, chars T→B, lines R→L), "vert270" (all glyphs 270°
3752
+ * CW = 90° CCW, chars B→T, lines L→R), and "eaVert" (East-Asian upright: CJK
3753
+ * stands upright, non-EA rotated 90°, chars T→B, lines R→L). "horz"/absent ⇒
3754
+ * horizontal (unchanged). Unrecognised values ("mongolianVert", "wordArtVert",
3755
+ * …) fall back to horizontal until implemented. */
3756
+ textVert?: string | null;
3559
3757
  /** ECMA-376 Part 4 §19.1.2.23 `<v:textpath>` — WordArt text laid on the
3560
3758
  * shape path (a text watermark). When set the renderer draws this string,
3561
3759
  * scaled to fill the box (`fitshape`), rotated by {@link ShapeRun.rotation},
@@ -3581,6 +3779,8 @@ export declare interface ShapeText {
3581
3779
  * (image blocks / legacy single-format paragraphs). Absent for image-only
3582
3780
  * paragraphs. */
3583
3781
  runs?: ShapeTextRun[];
3782
+ /** ECMA-376 §17.9 paragraph numbering for text-box paragraphs. */
3783
+ numbering?: NumberingInfo | null;
3584
3784
  alignment: string;
3585
3785
  /** ECMA-376 §17.3.1.33 `<w:spacing w:before>` of this text-box paragraph, in
3586
3786
  * pt — reserved ABOVE the paragraph inside the box. Absent/0 ⇒ no offset. */
@@ -3618,6 +3818,19 @@ export declare interface ShapeText {
3618
3818
  * base direction for the UAX#9 reordering pass (the body renderer reads the
3619
3819
  * identical field). */
3620
3820
  bidi?: boolean;
3821
+ /** ECMA-376 §17.3.1.9 `<w:contextualSpacing>` — resolved through the style
3822
+ * chain in the parser. When set, this text-box paragraph drops its OWN
3823
+ * contribution to the collapsed gap against an ADJACENT paragraph that
3824
+ * shares its {@link ShapeText.styleId} (per-side, Word-adjudicated — issue
3825
+ * #1015; identical to {@link DocParagraph.contextualSpacing} via the
3826
+ * renderer's `contextualSpacingAdjust`). Absent ⇒ no suppression. */
3827
+ contextualSpacing?: boolean;
3828
+ /** Resolved paragraph style id of this text-box paragraph — the explicit
3829
+ * `<w:pStyle>`, else the document default paragraph style, else "Normal" (the
3830
+ * same stable id {@link DocParagraph.styleId} carries). Paired with
3831
+ * {@link ShapeText.contextualSpacing} to group adjacent same-style paragraphs
3832
+ * for §17.3.1.9. */
3833
+ styleId?: string | null;
3621
3834
  /** Zip path of an inline image inside this text-box paragraph
3622
3835
  * (`<w:drawing><wp:inline><a:blip r:embed>`), e.g. `word/media/image1.emf`.
3623
3836
  * Absent for a text-only paragraph. */
@@ -3650,6 +3863,8 @@ export declare interface ShapeTextRun {
3650
3863
  fontFamilyEastAsia?: string | null;
3651
3864
  bold?: boolean;
3652
3865
  italic?: boolean;
3866
+ /** ECMA-376 §17.3.3.25 ruby annotation (furigana) for text-box runs. */
3867
+ ruby?: RubyAnnotation | null;
3653
3868
  }
3654
3869
 
3655
3870
  export declare interface TableBorders {