@silurus/ooxml 0.54.0 → 0.56.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.
@@ -102,6 +102,12 @@ export declare interface DocParagraph {
102
102
  /** Default font family resolved from the style chain. Used to size empty
103
103
  * paragraphs (no runs) with the intended font's line metrics. */
104
104
  defaultFontFamily?: string | null;
105
+ /**
106
+ * ECMA-376 §17.3.1.6 `<w:bidi>` — right-to-left paragraph. `true` = RTL,
107
+ * `false` = explicitly LTR, absent = unspecified (inherit). Phase 0 of RTL
108
+ * support: recorded only; alignment/column-order resolution is deferred.
109
+ */
110
+ bidi?: boolean;
105
111
  }
106
112
 
107
113
  export declare interface DocRevision {
@@ -131,6 +137,19 @@ export declare type DocRun = {
131
137
  fontSize: number;
132
138
  };
133
139
 
140
+ declare interface DocSettings {
141
+ /** §17.15.1.58 `w:kinsoku` — East-Asian line-breaking toggle. `undefined`
142
+ * means the element is absent; the spec default is ON (treated as `true`). */
143
+ kinsoku?: boolean;
144
+ /** §17.15.1.60 `w:noLineBreaksBefore@w:val` — custom set of characters that
145
+ * cannot begin a line (行頭禁則). When present it REPLACES the application
146
+ * default set. Word's per-`w:lang` sets are merged into one string. */
147
+ noLineBreaksBefore?: string;
148
+ /** §17.15.1.59 `w:noLineBreaksAfter@w:val` — custom set of characters that
149
+ * cannot end a line (行末禁則). Replaces the default when present. */
150
+ noLineBreaksAfter?: string;
151
+ }
152
+
134
153
  declare interface DocTable {
135
154
  colWidths: number[];
136
155
  rows: DocTableRow[];
@@ -141,6 +160,22 @@ declare interface DocTable {
141
160
  cellMarginRight: number;
142
161
  /** table horizontal alignment on the page: 'left' | 'center' | 'right'. */
143
162
  jc: string;
163
+ /** ECMA-376 §17.4.52 `<w:tblLayout w:type>` — 'fixed' | 'autofit'. Absent
164
+ * (undefined) ⇒ spec default 'autofit': columns are sized by the per-column
165
+ * max preferred width (cell `widthPt`), tblGrid only as fallback. 'fixed'
166
+ * uses tblGrid widths verbatim (scaled to fit). */
167
+ layout?: string;
168
+ /** ECMA-376 §17.4.63 `<w:tblW>` preferred table width (type="dxa"), pt. */
169
+ widthPt?: number;
170
+ /** `<w:tblW>` type="pct": 50ths of a percent of available content width. */
171
+ widthPct?: number;
172
+ /**
173
+ * ECMA-376 §17.4.1 `<w:bidiVisual>` — render columns in right-to-left
174
+ * (visual) order. `true` = RTL columns, `false` = explicitly LTR, absent =
175
+ * unspecified. Phase 0 of RTL support: recorded only; column-order
176
+ * resolution is deferred.
177
+ */
178
+ bidiVisual?: boolean;
144
179
  }
145
180
 
146
181
  declare interface DocTableCell {
@@ -150,7 +185,13 @@ declare interface DocTableCell {
150
185
  borders: CellBorders;
151
186
  background: string | null;
152
187
  vAlign: 'top' | 'center' | 'bottom';
188
+ /** ECMA-376 §17.4.71 `<w:tcW>` preferred cell width (type="dxa"), pt. Drives
189
+ * autofit column sizing: each grid column's width is the max `widthPt` over
190
+ * the cells anchored in it. */
153
191
  widthPt: number | null;
192
+ /** `<w:tcW>` type="pct": 50ths of a percent of available content width.
193
+ * Resolved against the available width at render time. */
194
+ widthPct?: number;
154
195
  /** Per-cell margins (pt) from `<w:tcPr><w:tcMar>` (ECMA-376 §17.4.42). Each
155
196
  * edge overrides the table-level `cellMargin*` default when set; null/absent
156
197
  * = inherit the table default. */
@@ -216,6 +257,11 @@ export declare interface DocxDocumentModel {
216
257
  /** ECMA-376 §17.11.4 — `word/endnotes.xml` (id + text). Same shape as
217
258
  * `footnotes`. */
218
259
  endnotes?: DocNote[];
260
+ /** ECMA-376 §17.15.1.* — document-wide compatibility / typography settings
261
+ * from `word/settings.xml`. Currently carries the Japanese line-breaking
262
+ * (kinsoku) configuration. Absent when settings.xml has no relevant
263
+ * elements (the renderer then uses spec defaults: kinsoku ON). */
264
+ settings?: DocSettings;
219
265
  }
220
266
 
221
267
  export declare interface DocxTextRun {
@@ -244,6 +290,27 @@ export declare interface DocxTextRun {
244
290
  * underline and deletions with an author-coloured strikethrough so
245
291
  * tracked changes appear inline. */
246
292
  revision?: RunRevision;
293
+ /** ECMA-376 §17.3.2.30 `<w:rtl>` — complex-script / right-to-left run.
294
+ * `true` = RTL, `false` = explicitly LTR, absent = unspecified.
295
+ * Phase 0: recorded only; glyph-order resolution is deferred. */
296
+ rtl?: boolean;
297
+ /** ECMA-376 §17.3.2.7 `<w:cs/>` — complex-script run toggle: cs formatting
298
+ * applies to ALL characters of the run (§17.3.2.26). Distinct from
299
+ * `rFonts@cs` (`fontFamilyCs`), which is only a font slot. */
300
+ cs?: boolean;
301
+ /** ECMA-376 §17.3.2.26 `<w:rFonts w:cs>` — complex-script typeface
302
+ * (theme references resolved to a literal family). */
303
+ fontFamilyCs?: string;
304
+ /** ECMA-376 §17.3.2.39 `<w:szCs>` — complex-script font size in pt
305
+ * (same units as `fontSize`). */
306
+ fontSizeCs?: number;
307
+ /** ECMA-376 §17.3.2.3 `<w:bCs>` — complex-script bold toggle. */
308
+ boldCs?: boolean;
309
+ /** ECMA-376 §17.3.2.17 `<w:iCs>` — complex-script italic toggle. */
310
+ italicCs?: boolean;
311
+ /** ECMA-376 §17.3.2.20 `<w:lang w:bidi>` — complex-script (RTL) language tag,
312
+ * lower-cased (e.g. "ar-sa", "ae-ar"). Drives Word's AN digit ordering. */
313
+ langBidi?: string;
247
314
  }
248
315
 
249
316
  /** Information about a rendered text segment for building a transparent selection overlay. */
@@ -436,6 +503,16 @@ declare interface LoadOptions_2 {
436
503
  * untrusted input. Zero / negative values fall back to the default.
437
504
  */
438
505
  maxZipEntryBytes?: number;
506
+ /**
507
+ * Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Inject it
508
+ * **once** here and every render of this document / presentation / workbook
509
+ * uses it — the same dependency-injection contract across all three formats
510
+ * and their viewers. Import it from the separate `@silurus/ooxml/math` entry
511
+ * (`import { math } from '@silurus/ooxml/math'`). Omit it and equations are
512
+ * skipped and the engine tree-shakes away entirely (no network, no bundle
513
+ * cost).
514
+ */
515
+ math?: MathRenderer;
439
516
  }
440
517
 
441
518
  /** Accent (`m:acc`), e.g. hat, bar, vector arrow over the base. */
@@ -705,6 +705,12 @@ declare interface DocParagraph {
705
705
  /** Default font family resolved from the style chain. Used to size empty
706
706
  * paragraphs (no runs) with the intended font's line metrics. */
707
707
  defaultFontFamily?: string | null;
708
+ /**
709
+ * ECMA-376 §17.3.1.6 `<w:bidi>` — right-to-left paragraph. `true` = RTL,
710
+ * `false` = explicitly LTR, absent = unspecified (inherit). Phase 0 of RTL
711
+ * support: recorded only; alignment/column-order resolution is deferred.
712
+ */
713
+ bidi?: boolean;
708
714
  }
709
715
 
710
716
  declare interface DocRevision {
@@ -734,6 +740,19 @@ declare type DocRun = {
734
740
  fontSize: number;
735
741
  };
736
742
 
743
+ declare interface DocSettings {
744
+ /** §17.15.1.58 `w:kinsoku` — East-Asian line-breaking toggle. `undefined`
745
+ * means the element is absent; the spec default is ON (treated as `true`). */
746
+ kinsoku?: boolean;
747
+ /** §17.15.1.60 `w:noLineBreaksBefore@w:val` — custom set of characters that
748
+ * cannot begin a line (行頭禁則). When present it REPLACES the application
749
+ * default set. Word's per-`w:lang` sets are merged into one string. */
750
+ noLineBreaksBefore?: string;
751
+ /** §17.15.1.59 `w:noLineBreaksAfter@w:val` — custom set of characters that
752
+ * cannot end a line (行末禁則). Replaces the default when present. */
753
+ noLineBreaksAfter?: string;
754
+ }
755
+
737
756
  declare interface DocTable {
738
757
  colWidths: number[];
739
758
  rows: DocTableRow[];
@@ -744,6 +763,22 @@ declare interface DocTable {
744
763
  cellMarginRight: number;
745
764
  /** table horizontal alignment on the page: 'left' | 'center' | 'right'. */
746
765
  jc: string;
766
+ /** ECMA-376 §17.4.52 `<w:tblLayout w:type>` — 'fixed' | 'autofit'. Absent
767
+ * (undefined) ⇒ spec default 'autofit': columns are sized by the per-column
768
+ * max preferred width (cell `widthPt`), tblGrid only as fallback. 'fixed'
769
+ * uses tblGrid widths verbatim (scaled to fit). */
770
+ layout?: string;
771
+ /** ECMA-376 §17.4.63 `<w:tblW>` preferred table width (type="dxa"), pt. */
772
+ widthPt?: number;
773
+ /** `<w:tblW>` type="pct": 50ths of a percent of available content width. */
774
+ widthPct?: number;
775
+ /**
776
+ * ECMA-376 §17.4.1 `<w:bidiVisual>` — render columns in right-to-left
777
+ * (visual) order. `true` = RTL columns, `false` = explicitly LTR, absent =
778
+ * unspecified. Phase 0 of RTL support: recorded only; column-order
779
+ * resolution is deferred.
780
+ */
781
+ bidiVisual?: boolean;
747
782
  }
748
783
 
749
784
  declare interface DocTableCell {
@@ -753,7 +788,13 @@ declare interface DocTableCell {
753
788
  borders: CellBorders;
754
789
  background: string | null;
755
790
  vAlign: 'top' | 'center' | 'bottom';
791
+ /** ECMA-376 §17.4.71 `<w:tcW>` preferred cell width (type="dxa"), pt. Drives
792
+ * autofit column sizing: each grid column's width is the max `widthPt` over
793
+ * the cells anchored in it. */
756
794
  widthPt: number | null;
795
+ /** `<w:tcW>` type="pct": 50ths of a percent of available content width.
796
+ * Resolved against the available width at render time. */
797
+ widthPct?: number;
757
798
  /** Per-cell margins (pt) from `<w:tcPr><w:tcMar>` (ECMA-376 §17.4.42). Each
758
799
  * edge overrides the table-level `cellMargin*` default when set; null/absent
759
800
  * = inherit the table default. */
@@ -843,6 +884,11 @@ declare interface DocxDocumentModel {
843
884
  /** ECMA-376 §17.11.4 — `word/endnotes.xml` (id + text). Same shape as
844
885
  * `footnotes`. */
845
886
  endnotes?: DocNote[];
887
+ /** ECMA-376 §17.15.1.* — document-wide compatibility / typography settings
888
+ * from `word/settings.xml`. Currently carries the Japanese line-breaking
889
+ * (kinsoku) configuration. Absent when settings.xml has no relevant
890
+ * elements (the renderer then uses spec defaults: kinsoku ON). */
891
+ settings?: DocSettings;
846
892
  }
847
893
 
848
894
  declare interface DocxTextRun {
@@ -871,6 +917,27 @@ declare interface DocxTextRun {
871
917
  * underline and deletions with an author-coloured strikethrough so
872
918
  * tracked changes appear inline. */
873
919
  revision?: RunRevision;
920
+ /** ECMA-376 §17.3.2.30 `<w:rtl>` — complex-script / right-to-left run.
921
+ * `true` = RTL, `false` = explicitly LTR, absent = unspecified.
922
+ * Phase 0: recorded only; glyph-order resolution is deferred. */
923
+ rtl?: boolean;
924
+ /** ECMA-376 §17.3.2.7 `<w:cs/>` — complex-script run toggle: cs formatting
925
+ * applies to ALL characters of the run (§17.3.2.26). Distinct from
926
+ * `rFonts@cs` (`fontFamilyCs`), which is only a font slot. */
927
+ cs?: boolean;
928
+ /** ECMA-376 §17.3.2.26 `<w:rFonts w:cs>` — complex-script typeface
929
+ * (theme references resolved to a literal family). */
930
+ fontFamilyCs?: string;
931
+ /** ECMA-376 §17.3.2.39 `<w:szCs>` — complex-script font size in pt
932
+ * (same units as `fontSize`). */
933
+ fontSizeCs?: number;
934
+ /** ECMA-376 §17.3.2.3 `<w:bCs>` — complex-script bold toggle. */
935
+ boldCs?: boolean;
936
+ /** ECMA-376 §17.3.2.17 `<w:iCs>` — complex-script italic toggle. */
937
+ italicCs?: boolean;
938
+ /** ECMA-376 §17.3.2.20 `<w:lang w:bidi>` — complex-script (RTL) language tag,
939
+ * lower-cased (e.g. "ar-sa", "ae-ar"). Drives Word's AN digit ordering. */
940
+ langBidi?: string;
874
941
  }
875
942
 
876
943
  /** Information about a rendered text segment for building a transparent selection overlay. */
@@ -1182,6 +1249,16 @@ declare interface LoadOptions_2 {
1182
1249
  * untrusted input. Zero / negative values fall back to the default.
1183
1250
  */
1184
1251
  maxZipEntryBytes?: number;
1252
+ /**
1253
+ * Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Inject it
1254
+ * **once** here and every render of this document / presentation / workbook
1255
+ * uses it — the same dependency-injection contract across all three formats
1256
+ * and their viewers. Import it from the separate `@silurus/ooxml/math` entry
1257
+ * (`import { math } from '@silurus/ooxml/math'`). Omit it and equations are
1258
+ * skipped and the engine tree-shakes away entirely (no network, no bundle
1259
+ * cost).
1260
+ */
1261
+ math?: MathRenderer;
1185
1262
  }
1186
1263
 
1187
1264
  /** Options for {@link XlsxWorkbook.load}. The shared load-options type from
@@ -1634,6 +1711,10 @@ declare class PptxPresentation {
1634
1711
  private _mediaCache;
1635
1712
  private _workerReady;
1636
1713
  private _workerReadyCallbacks;
1714
+ /** Opt-in OMML equation engine, injected once at {@link load}. Every
1715
+ * `renderSlide` / `presentSlide` reuses it — equations render when present,
1716
+ * and are skipped (engine tree-shaken) when omitted. */
1717
+ private _math;
1637
1718
  private constructor();
1638
1719
  /** Parse a PPTX from URL or ArrayBuffer. */
1639
1720
  static load(source: string | ArrayBuffer, opts?: LoadOptions): Promise<PptxPresentation>;
@@ -1737,23 +1818,11 @@ declare class PptxViewer {
1737
1818
  destroy(): void;
1738
1819
  }
1739
1820
 
1740
- declare interface PptxViewerOptions extends RenderOptions {
1821
+ declare interface PptxViewerOptions extends RenderOptions, LoadOptions {
1741
1822
  /** Called when a slide finishes rendering */
1742
1823
  onSlideChange?: (index: number, total: number) => void;
1743
1824
  /** Called on parse or render errors */
1744
1825
  onError?: (err: Error) => void;
1745
- /**
1746
- * Opt in to loading theme-declared webfonts from Google Fonts. Off by
1747
- * default — see {@link PptxPresentation.load} for privacy implications.
1748
- */
1749
- useGoogleFonts?: boolean;
1750
- /**
1751
- * Override the per-entry ZIP decompression cap (bytes) used by the zip-bomb
1752
- * guard in the Rust parser. Defaults to 512 MiB. Raise this to load decks
1753
- * with very large embedded media, or lower it to tighten the budget for
1754
- * untrusted input. Zero / negative values fall back to the default.
1755
- */
1756
- maxZipEntryBytes?: number;
1757
1826
  /**
1758
1827
  * Enable interactive audio/video playback. When true, slides are rendered
1759
1828
  * via {@link PptxPresentation.presentSlide} so media elements become
@@ -1834,13 +1903,6 @@ declare interface RenderOptions {
1834
1903
  * the static renderer drawing a duplicate play badge.
1835
1904
  */
1836
1905
  skipMediaControls?: boolean;
1837
- /**
1838
- * Opt-in OMML equation engine. Import it from the separate `@silurus/ooxml/math`
1839
- * entry and pass it in: `import { math } from '@silurus/ooxml/math'`. When
1840
- * omitted, equations are skipped and the ~3 MB engine tree-shakes out of the
1841
- * bundle entirely (it is referenced nowhere unless you import it).
1842
- */
1843
- math?: MathRenderer;
1844
1906
  }
1845
1907
 
1846
1908
  declare interface RenderPageOptions {
@@ -1868,7 +1930,7 @@ declare interface RenderPageOptions {
1868
1930
  * Render a single slide onto a <canvas> element.
1869
1931
  * Returns the canvas for convenience.
1870
1932
  */
1871
- declare function renderSlide(canvas: HTMLCanvasElement | OffscreenCanvas, slide: Slide, slideWidth: number, slideHeight: number, opts?: RenderOptions, onTextRun?: TextRunCallback): Promise<HTMLCanvasElement | OffscreenCanvas>;
1933
+ declare function renderSlide(canvas: HTMLCanvasElement | OffscreenCanvas, slide: Slide, slideWidth: number, slideHeight: number, opts?: SlideRenderOptions, onTextRun?: TextRunCallback): Promise<HTMLCanvasElement | OffscreenCanvas>;
1872
1934
 
1873
1935
  /** Options for rendering a single slide onto a canvas. */
1874
1936
  declare interface RenderSlideOptions {
@@ -1884,12 +1946,6 @@ declare interface RenderSlideOptions {
1884
1946
  * its own play/pause chrome without duplication.
1885
1947
  */
1886
1948
  skipMediaControls?: boolean;
1887
- /**
1888
- * Opt-in OMML equation engine. Import it from the separate `@silurus/ooxml/math`
1889
- * entry and pass it in: `import { math } from '@silurus/ooxml/math'`. When
1890
- * omitted, equations are skipped and the ~3 MB engine never enters the bundle.
1891
- */
1892
- math?: MathRenderer;
1893
1949
  }
1894
1950
 
1895
1951
  declare interface RenderViewportOptions {
@@ -1906,11 +1962,6 @@ declare interface RenderViewportOptions {
1906
1962
  cellScale?: number;
1907
1963
  /** Pre-loaded Image elements keyed by their dataUrl (for ImageAnchor rendering). */
1908
1964
  loadedImages?: Map<string, HTMLImageElement>;
1909
- /** Opt-in OMML equation engine. Import it from the separate `@silurus/ooxml/math`
1910
- * entry and pass it in (`import { math } from '@silurus/ooxml/math'`). When
1911
- * omitted, equations in shapes are skipped and the ~3 MB engine never enters
1912
- * the bundle. Same DI contract as docx/pptx. */
1913
- math?: MathRenderer;
1914
1965
  /** Called once per cell that contains text, with canvas-pixel position and cell address. */
1915
1966
  onTextRun?: (info: XlsxTextRunInfo) => void;
1916
1967
  /** Highlighted row range for selected row headers (1-indexed inclusive).
@@ -2136,6 +2187,9 @@ declare interface ShapeInfo {
2136
2187
  declare interface ShapeParagraph {
2137
2188
  /** `<a:pPr@algn>` — `l` (default) | `ctr` | `r` | `just` | `dist`. */
2138
2189
  align: string;
2190
+ /** `<a:pPr@rtl>` — whether the paragraph reads right-to-left
2191
+ * (ECMA-376 §21.1.2.2.7). Omitted (undefined) when false. */
2192
+ rtl?: boolean;
2139
2193
  runs: ShapeTextRun[];
2140
2194
  }
2141
2195
 
@@ -2295,6 +2349,16 @@ declare interface Slide {
2295
2349
 
2296
2350
  declare type SlideElement = ShapeElement | PictureElement | TableElement | ChartElement | MediaElement;
2297
2351
 
2352
+ /**
2353
+ * Internal render options: the shared {@link RenderOptions} plus the opt-in
2354
+ * `math` engine. `math` is internal plumbing — the headless {@link
2355
+ * PptxPresentation} injects it once at load and threads it here on each draw,
2356
+ * so the public `RenderSlideOptions` deliberately does not expose it.
2357
+ */
2358
+ declare type SlideRenderOptions = RenderOptions & {
2359
+ math?: MathRenderer;
2360
+ };
2361
+
2298
2362
  /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
2299
2363
  declare interface SoftEdge {
2300
2364
  radius: number;
@@ -2433,6 +2497,8 @@ declare interface TableElement {
2433
2497
  /** Column widths in EMU */
2434
2498
  cols: number[];
2435
2499
  rows: TableRow[];
2500
+ /** `<a:tblPr rtl="1">` (ECMA-376 §21.1.3.13): right-to-left table — column 0 at the right edge. */
2501
+ rtl?: boolean;
2436
2502
  }
2437
2503
 
2438
2504
  declare interface TableInfo {
@@ -2482,7 +2548,21 @@ declare interface TabStop_2 {
2482
2548
  leader: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
2483
2549
  }
2484
2550
 
2485
- declare interface TextBody {
2551
+ /**
2552
+ * PPTX text body. Extends the shared core `TextBody` with PPTX-only bodyPr
2553
+ * fields that the pptx parser surfaces but the shared core model does not yet
2554
+ * carry.
2555
+ */
2556
+ declare interface TextBody extends TextBody_2 {
2557
+ /**
2558
+ * `<a:bodyPr rtlCol>` (ECMA-376 §21.1.2.1.1) — when true the columns of a
2559
+ * multi-column text body are laid out right-to-left. Defaults to false;
2560
+ * omitted from JSON when false. Only meaningful when `numCol > 1`.
2561
+ */
2562
+ rtlCol?: boolean;
2563
+ }
2564
+
2565
+ declare interface TextBody_2 {
2486
2566
  /** Vertical anchor: "t" | "ctr" | "b" */
2487
2567
  verticalAnchor: string;
2488
2568
  paragraphs: Paragraph[];
@@ -2652,6 +2732,10 @@ declare interface Worksheet {
2652
2732
  * `<sheetView showGridLines>`). Mirrors the Excel "View → Gridlines"
2653
2733
  * checkbox. Defaults to true. */
2654
2734
  showGridlines?: boolean;
2735
+ /** Whether the sheet grid is laid out right-to-left, mirroring the entire
2736
+ * grid so column A sits on the right (ECMA-376 §18.3.1.87
2737
+ * `<sheetView rightToLeft>`). Defaults to false. */
2738
+ rightToLeft?: boolean;
2655
2739
  /** Sheet tab color (ECMA-376 §18.3.1.79). */
2656
2740
  tabColor?: string | null;
2657
2741
  /** AutoFilter header range (ECMA-376 §18.3.1.2). */
@@ -2819,6 +2903,40 @@ declare class XlsxViewer {
2819
2903
  /** The loaded workbook, or throws if {@link load} has not completed. */
2820
2904
  private get workbook();
2821
2905
  showSheet(index: number): Promise<void>;
2906
+ /** True when the current sheet's grid is laid out right-to-left. */
2907
+ private get isRtl();
2908
+ /** Maximum horizontal scroll offset the native scroll host allows (≥ 0). */
2909
+ private get maxScrollLeft();
2910
+ /**
2911
+ * The logical horizontal scroll position used to find the start-of-sheet
2912
+ * (col A) edge, in *scaled* CSS pixels — the same unit as
2913
+ * `scrollHost.scrollLeft`. The renderer always lays the grid out LTR and then
2914
+ * mirrors it (ECMA-376 §18.3.1.87), so the viewer must hand it a position
2915
+ * where 0 = the START of the sheet (col A) and increasing values reveal later
2916
+ * columns.
2917
+ *
2918
+ * For LTR that is exactly the native `scrollLeft`. For RTL the sheet starts at
2919
+ * the RIGHT, so the native scrollbar runs the opposite way: thumb fully right
2920
+ * (`scrollLeft = maxScrollLeft`) is the start, thumb left is the far columns.
2921
+ * Inverting here makes wheel/trackpad follow the finger and aligns the
2922
+ * thumb↔page mapping with Excel, without depending on browser-specific RTL
2923
+ * `scrollLeft` sign conventions.
2924
+ */
2925
+ private get effectiveScrollLeft();
2926
+ /**
2927
+ * Map between the logical-LTR x used by all the cell-geometry math and the
2928
+ * on-screen (canvasArea CSS-pixel) x, applying the RTL mirror (ECMA-376
2929
+ * §18.3.1.87) via the same {@link rtlMirrorX} the renderer uses. For LTR this
2930
+ * is the identity. The mirror is an involution, so this one method serves
2931
+ * both cell→px (overlay draw, `w` = cell width) and px→cell (pointer
2932
+ * hit-testing, `w` = 0 for a point) — guaranteeing the overlay sits exactly
2933
+ * where the cell is drawn and a click resolves to that same cell at every
2934
+ * scroll offset. `canvasArea.clientWidth` equals the renderer's `canvasW`.
2935
+ */
2936
+ private screenX;
2937
+ /** Park the scrollbar at the sheet's natural start: scrollLeft=0 for LTR,
2938
+ * the right end for RTL (so col A shows first). */
2939
+ private resetHorizontalScroll;
2822
2940
  /** 0-based index of the currently displayed sheet. */
2823
2941
  get sheetIndex(): number;
2824
2942
  /** Total number of sheets in the loaded workbook. */
@@ -2929,6 +3047,10 @@ declare class XlsxWorkbook {
2929
3047
  private imageCache;
2930
3048
  private rawData;
2931
3049
  private maxZipEntryBytes;
3050
+ /** Opt-in OMML equation engine, injected once at {@link load}. Every
3051
+ * `renderViewport` call reuses it — equations in shapes render when present,
3052
+ * and are skipped (engine tree-shaken) when omitted. */
3053
+ private math;
2932
3054
  private constructor();
2933
3055
  /** Parse an XLSX from a URL or ArrayBuffer. */
2934
3056
  static load(source: string | ArrayBuffer, opts?: LoadOptions_3): Promise<XlsxWorkbook>;
@@ -376,6 +376,16 @@ declare interface LoadOptions_2 {
376
376
  * untrusted input. Zero / negative values fall back to the default.
377
377
  */
378
378
  maxZipEntryBytes?: number;
379
+ /**
380
+ * Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Inject it
381
+ * **once** here and every render of this document / presentation / workbook
382
+ * uses it — the same dependency-injection contract across all three formats
383
+ * and their viewers. Import it from the separate `@silurus/ooxml/math` entry
384
+ * (`import { math } from '@silurus/ooxml/math'`). Omit it and equations are
385
+ * skipped and the engine tree-shakes away entirely (no network, no bundle
386
+ * cost).
387
+ */
388
+ math?: MathRenderer;
379
389
  }
380
390
 
381
391
  /** Accent (`m:acc`), e.g. hat, bar, vector arrow over the base. */
@@ -661,6 +671,10 @@ export declare class PptxPresentation {
661
671
  private _mediaCache;
662
672
  private _workerReady;
663
673
  private _workerReadyCallbacks;
674
+ /** Opt-in OMML equation engine, injected once at {@link load}. Every
675
+ * `renderSlide` / `presentSlide` reuses it — equations render when present,
676
+ * and are skipped (engine tree-shaken) when omitted. */
677
+ private _math;
664
678
  private constructor();
665
679
  /** Parse a PPTX from URL or ArrayBuffer. */
666
680
  static load(source: string | ArrayBuffer, opts?: LoadOptions): Promise<PptxPresentation>;
@@ -764,23 +778,11 @@ export declare class PptxViewer {
764
778
  destroy(): void;
765
779
  }
766
780
 
767
- export declare interface PptxViewerOptions extends RenderOptions {
781
+ export declare interface PptxViewerOptions extends RenderOptions, LoadOptions {
768
782
  /** Called when a slide finishes rendering */
769
783
  onSlideChange?: (index: number, total: number) => void;
770
784
  /** Called on parse or render errors */
771
785
  onError?: (err: Error) => void;
772
- /**
773
- * Opt in to loading theme-declared webfonts from Google Fonts. Off by
774
- * default — see {@link PptxPresentation.load} for privacy implications.
775
- */
776
- useGoogleFonts?: boolean;
777
- /**
778
- * Override the per-entry ZIP decompression cap (bytes) used by the zip-bomb
779
- * guard in the Rust parser. Defaults to 512 MiB. Raise this to load decks
780
- * with very large embedded media, or lower it to tighten the budget for
781
- * untrusted input. Zero / negative values fall back to the default.
782
- */
783
- maxZipEntryBytes?: number;
784
786
  /**
785
787
  * Enable interactive audio/video playback. When true, slides are rendered
786
788
  * via {@link PptxPresentation.presentSlide} so media elements become
@@ -861,20 +863,13 @@ export declare interface RenderOptions {
861
863
  * the static renderer drawing a duplicate play badge.
862
864
  */
863
865
  skipMediaControls?: boolean;
864
- /**
865
- * Opt-in OMML equation engine. Import it from the separate `@silurus/ooxml/math`
866
- * entry and pass it in: `import { math } from '@silurus/ooxml/math'`. When
867
- * omitted, equations are skipped and the ~3 MB engine tree-shakes out of the
868
- * bundle entirely (it is referenced nowhere unless you import it).
869
- */
870
- math?: MathRenderer;
871
866
  }
872
867
 
873
868
  /**
874
869
  * Render a single slide onto a <canvas> element.
875
870
  * Returns the canvas for convenience.
876
871
  */
877
- export declare function renderSlide(canvas: HTMLCanvasElement | OffscreenCanvas, slide: Slide, slideWidth: number, slideHeight: number, opts?: RenderOptions, onTextRun?: TextRunCallback): Promise<HTMLCanvasElement | OffscreenCanvas>;
872
+ export declare function renderSlide(canvas: HTMLCanvasElement | OffscreenCanvas, slide: Slide, slideWidth: number, slideHeight: number, opts?: SlideRenderOptions, onTextRun?: TextRunCallback): Promise<HTMLCanvasElement | OffscreenCanvas>;
878
873
 
879
874
  /** Options for rendering a single slide onto a canvas. */
880
875
  export declare interface RenderSlideOptions {
@@ -890,12 +885,6 @@ export declare interface RenderSlideOptions {
890
885
  * its own play/pause chrome without duplication.
891
886
  */
892
887
  skipMediaControls?: boolean;
893
- /**
894
- * Opt-in OMML equation engine. Import it from the separate `@silurus/ooxml/math`
895
- * entry and pass it in: `import { math } from '@silurus/ooxml/math'`. When
896
- * omitted, equations are skipped and the ~3 MB engine never enters the bundle.
897
- */
898
- math?: MathRenderer;
899
888
  }
900
889
 
901
890
  declare interface Shadow {
@@ -968,6 +957,16 @@ export declare interface Slide {
968
957
 
969
958
  export declare type SlideElement = ShapeElement | PictureElement | TableElement | ChartElement | MediaElement;
970
959
 
960
+ /**
961
+ * Internal render options: the shared {@link RenderOptions} plus the opt-in
962
+ * `math` engine. `math` is internal plumbing — the headless {@link
963
+ * PptxPresentation} injects it once at load and threads it here on each draw,
964
+ * so the public `RenderSlideOptions` deliberately does not expose it.
965
+ */
966
+ declare type SlideRenderOptions = RenderOptions & {
967
+ math?: MathRenderer;
968
+ };
969
+
971
970
  /** ECMA-376 §20.1.8.31 (CT_SoftEdgesEffect) — feather radius in EMU. */
972
971
  declare interface SoftEdge {
973
972
  radius: number;
@@ -1035,6 +1034,8 @@ declare interface TableElement {
1035
1034
  /** Column widths in EMU */
1036
1035
  cols: number[];
1037
1036
  rows: TableRow[];
1037
+ /** `<a:tblPr rtl="1">` (ECMA-376 §21.1.3.13): right-to-left table — column 0 at the right edge. */
1038
+ rtl?: boolean;
1038
1039
  }
1039
1040
 
1040
1041
  declare interface TableRow {
@@ -1050,7 +1051,21 @@ declare interface TabStop {
1050
1051
  algn: string;
1051
1052
  }
1052
1053
 
1053
- export declare interface TextBody {
1054
+ /**
1055
+ * PPTX text body. Extends the shared core `TextBody` with PPTX-only bodyPr
1056
+ * fields that the pptx parser surfaces but the shared core model does not yet
1057
+ * carry.
1058
+ */
1059
+ export declare interface TextBody extends TextBody_2 {
1060
+ /**
1061
+ * `<a:bodyPr rtlCol>` (ECMA-376 §21.1.2.1.1) — when true the columns of a
1062
+ * multi-column text body are laid out right-to-left. Defaults to false;
1063
+ * omitted from JSON when false. Only meaningful when `numCol > 1`.
1064
+ */
1065
+ rtlCol?: boolean;
1066
+ }
1067
+
1068
+ declare interface TextBody_2 {
1054
1069
  /** Vertical anchor: "t" | "ctr" | "b" */
1055
1070
  verticalAnchor: string;
1056
1071
  paragraphs: Paragraph[];