@silurus/ooxml 0.68.0 → 0.70.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/README.md +115 -9
- package/dist/docx-DkL5ADAb.js +3894 -0
- package/dist/docx.mjs +3 -3
- package/dist/docx_parser_bg.wasm +0 -0
- package/dist/index.mjs +3 -3
- package/dist/{src-dTwJJJoi.js → line-metrics-DG9p1RvA.js} +3592 -6462
- package/dist/math.mjs +18 -18
- package/dist/mathjax-stix2.js +15 -0
- package/dist/pptx-BU8N1QPE.js +3324 -0
- package/dist/pptx.mjs +3 -3
- package/dist/pptx_parser_bg.wasm +0 -0
- package/dist/render-worker-host-2V2UCnvB.js +27 -0
- package/dist/render-worker-host-BcmXt3yA.js +27 -0
- package/dist/render-worker-host-UUYE6Oqt.js +27 -0
- package/dist/segments-BTivjRMw.js +7 -0
- package/dist/types/docx.d.ts +602 -2
- package/dist/types/index.d.ts +1396 -351
- package/dist/types/pptx.d.ts +616 -108
- package/dist/types/xlsx.d.ts +606 -206
- package/dist/virtual-scroll-CsikPntn.js +873 -0
- package/dist/visible-index-B4ljB_dg.js +1266 -0
- package/dist/xlsx-CCmtIDr_.js +4274 -0
- package/dist/xlsx.mjs +2 -2
- package/dist/xlsx_parser_bg.wasm +0 -0
- package/package.json +14 -6
- package/dist/docx-ax5d8q4F.js +0 -3166
- package/dist/pptx-10-ZMrrs.js +0 -2066
- package/dist/render-worker-host-CZjrumRh.js +0 -27
- package/dist/render-worker-host-ClhHaLeZ.js +0 -27
- package/dist/render-worker-host-DW2Upw5x.js +0 -27
- package/dist/xlsx-BAnsE-gd.js +0 -4233
- /package/dist/{mathjax-Q1s8_eMq.js → mathjax-BRfWlbSJ.js} +0 -0
package/README.md
CHANGED
|
@@ -27,9 +27,19 @@ npm install @silurus/ooxml
|
|
|
27
27
|
pnpm add @silurus/ooxml
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
> **Bundler note**:
|
|
31
|
-
|
|
32
|
-
>
|
|
30
|
+
> **Bundler note**: the Rust parsers ship as real `.wasm` asset files next to the
|
|
31
|
+
> JavaScript, referenced with the standard `new URL('…', import.meta.url)` form
|
|
32
|
+
> and fetched (streaming-compiled) at load time. Vite, webpack 5, Rollup,
|
|
33
|
+
> esbuild and Parcel detect that reference and copy the asset automatically — no
|
|
34
|
+
> extra WebAssembly plugin is required. If your bundler cannot emit the asset (or
|
|
35
|
+
> you want to serve the parser WASM from a CDN or a path you control), pass its
|
|
36
|
+
> URL via the `wasmUrl` load option:
|
|
37
|
+
>
|
|
38
|
+
> ```typescript
|
|
39
|
+
> new DocxViewer(canvas, { wasmUrl: 'https://cdn.example.com/docx_parser_bg.wasm' });
|
|
40
|
+
> ```
|
|
41
|
+
|
|
42
|
+
> **Bundle size note**: the package is ESM-only (`.mjs`). npm's *Unpacked Size* sums every entry bundle **and** the standalone MathJax + STIX Two Math asset (`mathjax-stix2.js`, ~3 MB) that ships in the tarball, so the reported figure is much larger than any single app build. What actually lands in your app is smaller on two counts: import only the format you need (e.g. `@silurus/ooxml/pptx`), and the math engine is a **separate entry** (`@silurus/ooxml/math`). Its main-thread chunk is a ~1 KB loader that references the ~3 MB engine asset as a **sibling file** (not an inline data URL): the engine is fetched **lazily, only when a document actually contains equations** — and only if you imported `@silurus/ooxml/math` and passed it to a viewer in the first place (see [Rendering equations](#rendering-equations)). Never import the `math` entry and the loader chunk never enters your graph at all.
|
|
33
43
|
|
|
34
44
|
---
|
|
35
45
|
|
|
@@ -62,11 +72,14 @@ pptx.nextSlide();
|
|
|
62
72
|
|
|
63
73
|
OMML equations (`m:oMath` / `m:oMathPara`) in `.docx`, `.pptx` and `.xlsx` are rendered with
|
|
64
74
|
[MathJax](https://www.mathjax.org/) + [STIX Two Math](https://github.com/stipub/stixfonts).
|
|
65
|
-
That engine is ~
|
|
75
|
+
That engine is ~3 MB, so it is **opt-in**: import the `math` engine from the separate
|
|
66
76
|
`@silurus/ooxml/math` entry and pass it to the viewer. Pass it and equations render;
|
|
67
|
-
omit it and the engine is referenced nowhere, so a bundler
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
omit it and the engine is referenced nowhere, so a bundler leaves it out of your build
|
|
78
|
+
entirely (equations are simply skipped). When you *do* pass it, the ~3 MB engine ships
|
|
79
|
+
as a **standalone asset file** next to the bundle rather than an inline data URL, and is
|
|
80
|
+
fetched **on demand — only the first time a document actually contains an equation**, so
|
|
81
|
+
equation-free documents never pay for it. It is fully self-contained: served from your own
|
|
82
|
+
origin, no cross-origin requests.
|
|
70
83
|
|
|
71
84
|
```typescript
|
|
72
85
|
import { DocxViewer } from '@silurus/ooxml/docx';
|
|
@@ -125,6 +138,97 @@ Notes:
|
|
|
125
138
|
transferred back as an `ImageBitmap`, so a single render can be marginally
|
|
126
139
|
slower than `mode: 'main'`. Choose it for non-blocking UI, not raw speed.
|
|
127
140
|
|
|
141
|
+
### Continuous scroll viewers
|
|
142
|
+
|
|
143
|
+
`DocxScrollViewer` and `PptxScrollViewer` render the whole document as one
|
|
144
|
+
vertically-scrolling, PDF-reader-style surface instead of a single page/slide at
|
|
145
|
+
a time. Unlike `DocxViewer` / `PptxViewer` (which take a `<canvas>`), the scroll
|
|
146
|
+
viewers take a **container** `<div>` — they own the scroll host, virtualize the
|
|
147
|
+
page/slide list (only the visible window plus a small overscan is mounted), and
|
|
148
|
+
recycle canvases as you scroll.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { DocxScrollViewer } from '@silurus/ooxml/docx';
|
|
152
|
+
|
|
153
|
+
const container = document.getElementById('docx-scroll') as HTMLElement;
|
|
154
|
+
const viewer = new DocxScrollViewer(container);
|
|
155
|
+
await viewer.load('/document.docx');
|
|
156
|
+
// viewer.scrollToPage(3);
|
|
157
|
+
// viewer.pageCount, viewer.topVisiblePage
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { PptxScrollViewer } from '@silurus/ooxml/pptx';
|
|
162
|
+
|
|
163
|
+
const container = document.getElementById('pptx-scroll') as HTMLElement;
|
|
164
|
+
const viewer = new PptxScrollViewer(container);
|
|
165
|
+
await viewer.load('/deck.pptx');
|
|
166
|
+
// viewer.scrollToSlide(2);
|
|
167
|
+
// viewer.slideCount, viewer.topVisibleSlide
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The container must have a bounded height (e.g. `height: 100vh` or a flex child)
|
|
171
|
+
so the viewer can size its scroll host to it. Base zoom fits the first page/slide
|
|
172
|
+
width to the container width and re-fits on resize; a `0`-width container defers
|
|
173
|
+
layout until it has width. Call `destroy()` to tear down (a self-loaded engine is
|
|
174
|
+
destroyed with it; an injected one is not — see below).
|
|
175
|
+
|
|
176
|
+
**Desk appearance.** The viewer paints each page/slide on its own white canvas
|
|
177
|
+
with a soft drop shadow, over a transparent "desk". Style the desk and the sheet
|
|
178
|
+
gaps without any wrapper CSS:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const viewer = new DocxScrollViewer(container, {
|
|
182
|
+
background: '#f3f4f6', // the desk behind / between pages
|
|
183
|
+
gap: 24, // vertical gap between pages
|
|
184
|
+
paddingTop: 32, // desk padding above the first page
|
|
185
|
+
pageShadow: '0 0 0 1px #c8ccd0', // crisp 1px "border" look (box-shadow never shifts layout)
|
|
186
|
+
// pageShadow: false, // flat pages, no shadow
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`paddingBottom`, `paddingLeft` and `paddingRight` each default to `gap`, so the
|
|
191
|
+
sheet sits inside a uniform desk margin; pass `0` for a flush edge.
|
|
192
|
+
|
|
193
|
+
**Zoom.** `Ctrl`/`⌘` + mouse-wheel (and trackpad pinch) zooms the surface;
|
|
194
|
+
bare-wheel still scrolls natively. Zoom is flicker-free — a rapid gesture shows a
|
|
195
|
+
CSS preview and settles into a crisp re-render when it pauses. Bounds are the
|
|
196
|
+
absolute scale factors `zoomMin` / `zoomMax` (default `0.1` / `4`), and
|
|
197
|
+
`setScale(scale)` sets it programmatically. Pass `enableZoom: false` to disable.
|
|
198
|
+
|
|
199
|
+
**Text selection** (main mode only). Pass `enableTextSelection: true` to overlay
|
|
200
|
+
a transparent, selectable text layer per page/slide for native copy. In
|
|
201
|
+
`mode: 'worker'` the overlay stays empty (the per-run geometry cannot cross the
|
|
202
|
+
worker boundary) and the viewer logs one warning — use the default `mode: 'main'`
|
|
203
|
+
for selectable text.
|
|
204
|
+
|
|
205
|
+
**Master–detail / shared engine.** Inject an already-loaded headless engine so a
|
|
206
|
+
paged viewer and a scroll viewer (or several panes) share **one** parse. When you
|
|
207
|
+
inject, `load()` is unsupported (the engine is already loaded), the engine's own
|
|
208
|
+
`mode` wins, and `destroy()` leaves the injected engine intact — the caller owns
|
|
209
|
+
its lifecycle:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { DocxDocument, DocxScrollViewer } from '@silurus/ooxml/docx';
|
|
213
|
+
|
|
214
|
+
const doc = await DocxDocument.load('/document.docx'); // parse once
|
|
215
|
+
const scroll = new DocxScrollViewer(container, { document: doc });
|
|
216
|
+
// ...also drive a thumbnail grid, a paged view, etc. from the same `doc`.
|
|
217
|
+
scroll.destroy(); // the injected `doc` is NOT destroyed — you own it
|
|
218
|
+
doc.destroy(); // release it yourself when every pane is gone
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
`PptxScrollViewer` takes the same shape with `{ presentation: pres }`
|
|
222
|
+
(`await PptxPresentation.load(...)`).
|
|
223
|
+
|
|
224
|
+
Both viewers also expose `relayout()` (force a re-fit when the container resizes
|
|
225
|
+
in a way a `ResizeObserver` cannot see — e.g. a late web-font load),
|
|
226
|
+
`onVisiblePageChange` / `onVisibleSlideChange` (fires when the top-most visible
|
|
227
|
+
page/slide changes), and `onError` (async per-page render failures are routed
|
|
228
|
+
here instead of crashing the scroll loop). The parse/render knobs from the
|
|
229
|
+
headless engines (`mode`, `useGoogleFonts`, `maxZipEntryBytes`, `math`, `dpr`)
|
|
230
|
+
are accepted too.
|
|
231
|
+
|
|
128
232
|
---
|
|
129
233
|
|
|
130
234
|
<details>
|
|
@@ -200,7 +304,7 @@ All three formats follow the same shape: the worker parses the `.docx` / `.xlsx`
|
|
|
200
304
|
<summary><strong>React 19</strong></summary>
|
|
201
305
|
|
|
202
306
|
```tsx
|
|
203
|
-
// React 19.1 —
|
|
307
|
+
// React 19.1 — Vite copies the parser .wasm asset automatically; no extra plugin needed.
|
|
204
308
|
import { useEffect, useRef, useState } from 'react';
|
|
205
309
|
import { PptxViewer } from '@silurus/ooxml/pptx';
|
|
206
310
|
|
|
@@ -459,7 +563,7 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
459
563
|
| | Math equations (OMML `m:oMath` / `m:oMathPara`, rendered via MathJax — opt-in `@silurus/ooxml/math`) | ✅ |
|
|
460
564
|
| | Images (inline and anchored, with text wrap) | ✅ |
|
|
461
565
|
| | SVG images (`asvg:svgBlip` MS-2016 extension — vector drawn from the embedded `.svg`, raster fallback) | ✅ |
|
|
462
|
-
| | Text boxes / drawing shapes (`wps:txbx`, `a:prstGeom` — 186 preset geometries via the shared engine; connector arrow heads `headEnd` / `tailEnd` (§20.1.8.3) and `prstDash` dash patterns (§20.1.8.48)) | ✅ |
|
|
566
|
+
| | Text boxes / drawing shapes (`wps:txbx`, `a:prstGeom` — 186 preset geometries via the shared engine; connector arrow heads `headEnd` / `tailEnd` (§20.1.8.3) and `prstDash` dash patterns (§20.1.8.48)). Text-box paragraphs run through the **same line-layout engine as body text**, so kinsoku 行頭/行末禁則 (§17.15.1.58–60), UAX#9 bidi (`w:bidi`, §17.3.1.6), justification (§17.18.44) and tab stops (§17.3.1.37) all apply inside a box | ✅ |
|
|
463
567
|
| | WMF metafile images (legacy vector, incl. inside text boxes) — rasterized via a built-in player (window mapping, pens/brushes, poly/rect); true EMF detected but not yet rendered | ✅ |
|
|
464
568
|
| **Advanced** | Footnotes — reference markers + bottom-of-page bodies with separator rule, numbered (`w:footnoteReference` / `w:footnoteRef`, §17.11) | ✅ |
|
|
465
569
|
| | Endnotes — reference markers + bodies at document end (`w:endnoteReference`, §17.11) | ✅ |
|
|
@@ -468,6 +572,7 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
468
572
|
| | Comments — author / date / text via the document model (`doc.comments`, §17.13.4; not drawn on the page) | ✅ |
|
|
469
573
|
| | Mail merge fields | ❌ Not planned |
|
|
470
574
|
| **Interaction** | Text selection (transparent overlay, native copy) | ✅ |
|
|
575
|
+
| | Continuous scroll viewer (`DocxScrollViewer` — virtualized page list, desk background / shadow, Ctrl/⌘+wheel zoom, engine injection) | ✅ |
|
|
471
576
|
|
|
472
577
|
---
|
|
473
578
|
|
|
@@ -612,6 +717,7 @@ export const PptxViewerComponent = component$<{ src: string }>(({ src }) => {
|
|
|
612
717
|
| | Font scheme (`+mj-lt`, `+mn-lt`) | ✅ |
|
|
613
718
|
| | lumMod / lumOff / alpha transforms | ✅ |
|
|
614
719
|
| **Interaction** | Text selection (transparent overlay, native copy) | ✅ |
|
|
720
|
+
| | Continuous scroll viewer (`PptxScrollViewer` — virtualized slide list, desk background / shadow, Ctrl/⌘+wheel zoom, engine injection) | ✅ |
|
|
615
721
|
|
|
616
722
|
---
|
|
617
723
|
|