xls-codec 4.7.6 → 4.9.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 +11 -5
- package/dist/biff/cursor.cjs +12 -1
- package/dist/biff/cursor.d.cts +1 -1
- package/dist/biff/cursor.d.ts +1 -1
- package/dist/biff/cursor.js +12 -1
- package/dist/biff/ptg.cjs +16 -2
- package/dist/biff/ptg.d.cts +2 -2
- package/dist/biff/ptg.d.ts +2 -2
- package/dist/biff/ptg.js +16 -3
- package/dist/biff/record-types.cjs +25 -1
- package/dist/biff/record-types.d.cts +18 -2
- package/dist/biff/record-types.d.ts +18 -2
- package/dist/biff/record-types.js +18 -2
- package/dist/biff/strings.d.cts +1 -1
- package/dist/biff/strings.d.ts +1 -1
- package/dist/biff/substreams.cjs +7 -8
- package/dist/biff/substreams.d.cts +1 -1
- package/dist/biff/substreams.d.ts +1 -1
- package/dist/biff/substreams.js +7 -8
- package/dist/biff/xf-colors.d.cts +1 -1
- package/dist/biff/xf-colors.d.ts +1 -1
- package/dist/biff/xf-writer.d.cts +1 -1
- package/dist/biff/xf-writer.d.ts +1 -1
- package/dist/{conditional-format-12-D-X5g_O3.d.ts → conditional-format-12-C3nwy1f8.d.ts} +10 -5
- package/dist/{conditional-format-12-DBhe7Zo6.d.cts → conditional-format-12-D65-ruTq.d.cts} +10 -5
- package/dist/conditional-format-BRMUTRP1.d.ts +41 -0
- package/dist/conditional-format-Cth_afMy.d.cts +41 -0
- package/dist/content.cjs +50 -18
- package/dist/content.js +50 -18
- package/dist/{cursor-VMtw9uVP.d.cts → cursor-CnEuX5qE.d.cts} +3 -1
- package/dist/{cursor-VMtw9uVP.d.ts → cursor-CnEuX5qE.d.ts} +3 -1
- package/dist/{data-validation-DfpjUN-N.d.cts → data-validation-BgUt8CbE.d.cts} +2 -2
- package/dist/{data-validation-BXvIVU0e.d.ts → data-validation-Cq6iD8lB.d.ts} +2 -2
- package/dist/drawing/blips.cjs +83 -0
- package/dist/drawing/blips.d.cts +10 -0
- package/dist/drawing/blips.d.ts +10 -0
- package/dist/drawing/blips.js +82 -0
- package/dist/drawing/bytes.cjs +15 -0
- package/dist/drawing/bytes.d.cts +5 -0
- package/dist/drawing/bytes.d.ts +5 -0
- package/dist/drawing/bytes.js +14 -0
- package/dist/drawing/escher-constants.cjs +52 -0
- package/dist/drawing/escher-constants.d.cts +34 -0
- package/dist/drawing/escher-constants.d.ts +34 -0
- package/dist/drawing/escher-constants.js +34 -0
- package/dist/drawing/escher.cjs +84 -0
- package/dist/drawing/escher.d.cts +30 -0
- package/dist/drawing/escher.d.ts +30 -0
- package/dist/drawing/escher.js +80 -0
- package/dist/drawing/shapes.cjs +80 -0
- package/dist/drawing/shapes.d.cts +24 -0
- package/dist/drawing/shapes.d.ts +24 -0
- package/dist/drawing/shapes.js +79 -0
- package/dist/index.cjs +11 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/{print-names-CCwUHAoL.d.cts → print-names-B2OR0fvs.d.cts} +1 -1
- package/dist/{print-names-CxAbgcjB.d.ts → print-names-BXcmmwVi.d.ts} +1 -1
- package/dist/{ptg-CCBbJLZJ.d.cts → ptg-75v7MhaA.d.cts} +7 -1
- package/dist/{ptg-CCBbJLZJ.d.ts → ptg-75v7MhaA.d.ts} +7 -1
- package/dist/{substreams-Dp5cZoUo.d.ts → substreams-CgTHx5kX.d.ts} +1 -1
- package/dist/{substreams-CHv3oWmn.d.cts → substreams-XDNgDvRJ.d.cts} +1 -1
- package/dist/units.cjs +7 -0
- package/dist/units.d.cts +6 -1
- package/dist/units.d.ts +6 -1
- package/dist/units.js +6 -1
- package/dist/workbook/chart.cjs +230 -0
- package/dist/workbook/chart.d.cts +19 -0
- package/dist/workbook/chart.d.ts +19 -0
- package/dist/workbook/chart.js +229 -0
- package/dist/workbook/comments.cjs +2 -1
- package/dist/workbook/comments.d.cts +7 -2
- package/dist/workbook/comments.d.ts +7 -2
- package/dist/workbook/comments.js +2 -2
- package/dist/workbook/conditional-format-12.cjs +32 -1
- package/dist/workbook/conditional-format-12.d.cts +2 -2
- package/dist/workbook/conditional-format-12.d.ts +2 -2
- package/dist/workbook/conditional-format-12.js +33 -3
- package/dist/workbook/conditional-format-ex.cjs +53 -0
- package/dist/workbook/conditional-format-ex.d.cts +13 -0
- package/dist/workbook/conditional-format-ex.d.ts +13 -0
- package/dist/workbook/conditional-format-ex.js +52 -0
- package/dist/workbook/conditional-format.cjs +46 -23
- package/dist/workbook/conditional-format.d.cts +2 -2
- package/dist/workbook/conditional-format.d.ts +2 -2
- package/dist/workbook/conditional-format.js +46 -23
- package/dist/workbook/data-validation.d.cts +1 -1
- package/dist/workbook/data-validation.d.ts +1 -1
- package/dist/workbook/drawing.cjs +270 -0
- package/dist/workbook/drawing.d.cts +31 -0
- package/dist/workbook/drawing.d.ts +31 -0
- package/dist/workbook/drawing.js +268 -0
- package/dist/workbook/globals-writer.d.cts +2 -2
- package/dist/workbook/globals-writer.d.ts +2 -2
- package/dist/workbook/globals.d.cts +4 -4
- package/dist/workbook/globals.d.ts +4 -4
- package/dist/workbook/print-names.d.cts +1 -1
- package/dist/workbook/print-names.d.ts +1 -1
- package/dist/workbook/sheet-writer.cjs +1 -1
- package/dist/workbook/sheet-writer.js +1 -1
- package/dist/workbook/sheet.cjs +11 -0
- package/dist/workbook/sheet.d.cts +5 -5
- package/dist/workbook/sheet.d.ts +5 -5
- package/dist/workbook/sheet.js +12 -1
- package/dist/{xf-colors-mqerVt2O.d.cts → xf-colors-aeH9Ax3Q.d.cts} +1 -1
- package/dist/{xf-colors-d3OvRw76.d.ts → xf-colors-kdNsiNYt.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/conditional-format-Czh2oTzQ.d.cts +0 -29
- package/dist/conditional-format-DOdazxWe.d.ts +0 -29
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ Under active development, with real, tested **read and write** support. Built an
|
|
|
22
22
|
- **Print settings** — every field of `ContentSheetPrintSettings`: page size and orientation, all four margins, gridline and row/column-header printing, page order, print scale or fit-to-page counts, manual page breaks, the print range, and the repeated header rows and columns — read from and written to the nine worksheet-substream records and the two built-in defined names that carry them, in both directions and verified against real LibreOffice-produced BIFF8 (see [Print settings](#print-settings)).
|
|
23
23
|
- **Cell alignment** — a cell's own horizontal (`left`/`center`/`right`/`justify`) and vertical (`top`/`middle`) alignment, read from and written to `XF`'s trailing `CellXF`/`StyleXF` payload's own leading word, in both directions and verified against real LibreOffice-produced BIFF8 (see [Cell alignment](#cell-alignment)).
|
|
24
24
|
- **Data validation, read-only (ExaDev/documents.js#1098)** — a sheet's own `Dv` records (`src/workbook/data-validation.ts`) into `ContentSheet.dataValidations`: type, comparison operator, one or two formulas (via the same `Ptg` reader `Formula` records already use), allow-blank/show-input/show-error flags, error style, and prompt/error titles and messages, resolved directly against [MS-XLS]'s own published `Dv`/`DVal`/`DVParsedFormula`/`SqRefU` field layouts rather than a producer-specific convention.
|
|
25
|
+
- **Charts, drawings, and images, read-only (ExaDev/documents.js#924)** — a worksheet's own MS-ODRAW (Escher) drawing layer (`src/drawing/escher.ts`, `src/drawing/shapes.ts`, `src/drawing/blips.ts`), the workbook-wide Blip Store every picture shape's own `pib` property indexes into, and an embedded chart's own nested substream (`src/workbook/chart.ts`), joined into `ContentSheet.images` and `ContentSheet.embeddedObjects` by `src/workbook/drawing.ts` — see "Charts, drawings, and images, resolved for real" under Read-side gaps below.
|
|
25
26
|
|
|
26
27
|
Verified primarily by round trip (`src/write.test.ts`, plus a dedicated `test/workers/write.test.ts` proving the whole write path inside a real `workerd` isolate, not just Node): build a `ContentDocument`, write it, read it back through this package's own independently-pinned reader, and check the result. Every record's own byte layout is additionally cited to its [MS-XLS] section in the writer's source, matching the reader's own convention.
|
|
27
28
|
|
|
@@ -35,9 +36,10 @@ What `writeXlsContent`/`writeXls` cover: every `ContentCellValue` kind a real `.
|
|
|
35
36
|
| Per-cell font | The reader does not read one back: `ContentSheetCell` has no cell-level font field at all (`ooxml.js`'s xlsx reader makes the identical font-scope choice), so writing a real value here would be unverifiable by round trip. Every `XF` this writer emits still references the same single font. |
|
|
36
37
|
| `MulBlank`/`RK`/`MulRk` | Pure compaction optimisations over information a plain `Blank`/`Number`/`LabelSst`/`BoolErr` record already carries losslessly. (`Blank` itself _is_ written, for a formatted empty cell — see the `empty` row below.) |
|
|
37
38
|
| An `empty`-kind cell carrying no formatting | Written as nothing at all, which is what round-trips: `content.ts`'s reader drops an unformatted blank cell it reads, and a merged range's empty anchor is independently reconstructed from `MergeCells` alone. A formatted one (a fill, a border, or a non-default alignment) is the opposite case — its formatting exists only in the `XF` a cell record names, so it gets a real `Blank` record ([MS-XLS] 2.4.20) and round-trips with that formatting intact. |
|
|
38
|
-
| Images, embedded objects
|
|
39
|
+
| Images, embedded objects (charts/drawings) | The reader now recovers a sheet's own pictures, charts, and generic drawing shapes (see Read-side gaps below), but writing them back out is its own separate mechanism — a shape's own MS-ODRAW (Escher) container tree, a workbook-wide Blip Store, and (for a chart) a whole nested `BOF`/`EOF` substream, none of which this writer's existing per-record emission has any machinery for — scoped as its own piece of work rather than folded into recovering the read side, the same split this table already draws for `Formula` records. `ContentSheet.images` and `ContentSheet.embeddedObjects` are silently ignored on write. |
|
|
40
|
+
| Defined names (`Lbl`) | Read only for the two built-in ones a sheet's print range and repeated header bands live in ([Print settings](#print-settings)); a user-defined name has nowhere to land in `document-schema.js`'s spreadsheet model, so there is no round trip to verify a writer for it against. |
|
|
39
41
|
| Data validation (`Dv`/`DVal`) | The reader now recovers a sheet's own validation rules (see Read-side gaps below), but writing them back out is its own separate mechanism -- re-encoding a formula's own text back into `Ptg` tokens for `Dv`'s two `DVParsedFormula` fields, the same "not folded into recovering the read side" split this table already draws for `Formula` records. A `ContentSheet.dataValidations` is silently ignored on write. |
|
|
40
|
-
| Conditional formatting (`CondFmt`/`CF`, `CondFmt12`/`CF12`)
|
|
42
|
+
| Conditional formatting (`CondFmt`/`CF`, `CondFmt12`/`CF12`, `CFEx`) | The reader now recovers a sheet's own base `cellIs` rules and every `CF12`/`CFEx` rule this package's schema models (see Read-side gaps below), but writing them back out is its own separate mechanism, the same "not folded into recovering the read side" split this table already draws for `Formula` records and `Dv`. A `ContentSheet.conditionalFormats` is silently ignored on write. |
|
|
41
43
|
| Cell comments (`Note`/`Txo`) | The reader now recovers a cell's comment (see Read-side gaps below), but writing one back out is its own separate mechanism -- a `Note`/`Obj`/`Txo` triple with its own object-id bookkeeping, distinct from every other cell record this writer already emits -- scoped as its own piece of work rather than folded into recovering the read side, the same split this table already draws for `Formula` records. A `ContentSheetCell.comment` is silently ignored on write. |
|
|
42
44
|
| A page size no `iPaperSize` code names | Written as [MS-XLS] 2.4.257's own custom-paper value rather than as a named paper it is not — the dimensions themselves are unwritable, since `Setup` addresses paper only by code. See [Print settings](#print-settings). |
|
|
43
45
|
| `Window1`/`Window2`, `CodePage`, `Index`/`DBCell`, the legacy interface records (`InterfaceHdr`, `WriteAccess`, …) | UI and interoperability bookkeeping [MS-XLS]'s own grammar names in the globals/worksheet substreams alongside the content-carrying records above, not data. `Index`/`DBCell` specifically is a pure cell-lookup performance optimisation (see [MS-XLS]'s own "Retrieval of Last-Calculated Cell Values Without Loading Cell Table") that this reader — and Excel's own reader — does not require to find a cell; real, well-established minimal BIFF8 writers (e.g. Python's `xlwt`) omit the same set and produce files Excel opens correctly. The calculation-state records (`CalcCount`, `CalcRefMode`, `CalcIter`, `CalcDelta`, `CalcSaveRecalc`) sat in this row until print settings needed them — see [Print settings](#print-settings) for why the writer emits them now. |
|
|
@@ -54,10 +56,12 @@ Each deliberate rather than overlooked:
|
|
|
54
56
|
- **Print settings, resolved for real.** Every field of `ContentSheetPrintSettings` is read from the records that carry it, with Excel's own "Normal" preset standing in per field for whatever the file leaves unstated — see [Print settings](#print-settings) for the record map, the two of BIFF8's own conditional rules that decide how to read `Setup`, and the three things that genuinely do not come through.
|
|
55
57
|
- **Cell comments, resolved for real (ExaDev/documents.js#949).** A legacy BIFF8 comment is split across three record kinds a single self-contained xlsx `<comment>` element never needs: a `Note` record ([MS-XLS] 2.4.179, wrapping a `NoteSh` structure) anchors the comment to a cell and names its author, but carries no text of its own; the text lives in a `Txo` record ([MS-XLS] 2.4.329), its characters carried across trailing `Continue` records; the two are joined through an `Obj` record ([MS-XLS] 2.4.181) whose `FtCmo` names an object id and type, the `Note`'s own `idObj` field naming that same id, and a `Txo` always immediately following the `Obj` record whose shape it belongs to (`src/workbook/comments.ts`). Read in one independent pass over the whole worksheet substream rather than assuming stream order between a `Note` and the `Obj`+`Txo` pair it names -- both are resolved regardless of which comes first. Legacy BIFF8 has no threading and no per-comment timestamp at all (unlike xlsx's own `[MS-XLSX]` threaded-comments extension), so `ContentSheetCellComment.replies` and `.createdAt` are never populated from an `.xls` source; rich per-character formatting within a comment (`TxORuns`) is skipped rather than modelled, the same scope limit this reader already applies to the shared string table's own rich runs, since `ContentSheetCellComment.text` is a plain string with nowhere to carry them.
|
|
56
58
|
- **Data validation, resolved for real (ExaDev/documents.js#1098).** `Dv` ([MS-XLS] 2.4.95) is a fixed, published binary structure -- a bit-packed flags `DWORD` (`valType`/`errStyle`/`fAllowBlank`/`fShowInputMsg`/`fShowErrorMsg`/`typOperator`), four `XLUnicodeString`s (prompt/error titles and messages), one or two `DVParsedFormula` structures, and a trailing `SqRefU` range list -- read directly against that spec (`src/workbook/data-validation.ts`), unlike `calcext:condition`'s own LibreOffice-source-transcribed mini-language odf.js's equivalent reader needed. A `DVParsedFormula`'s own `rgce` is the identical `Ptg` token grammar a cell's `Formula` record carries, so its formula text is recovered with the same `parseFormulaText` this reader already uses for ordinary cell formulas. `DVal` ([MS-XLS] 2.4.96), the record that precedes a sheet's own `Dv` collection, carries only input-window UI state (position, drop-down `Obj` reference) with no counterpart in `ContentSheetDataValidationSchema` and is not read for its own fields.
|
|
57
|
-
- **
|
|
59
|
+
- **Charts, drawings, and images, resolved for real (ExaDev/documents.js#924).** A worksheet's own `MsoDrawing` records ([MS-XLS] 2.1.7.20.3-adjacent, `RECORD_MSODRAWING`) carry MS-ODRAW (Escher) bytes that split across as many records as the drawing needs and simply concatenate, in stream order, into one continuous Escher record tree (`src/drawing/escher.ts`, reading [MS-ODRAW]'s own `OfficeArtRecordHeader`/container-vs-atom framing directly against its spec rather than from memory). Within that tree, `src/drawing/shapes.ts` walks the `DgContainer`/`SpgrContainer`/`SpContainer` hierarchy for each real top-level shape's own type, id, and cell anchor (`ClientAnchorSheet`, [MS-XLS] 2.5.163 — one `Sp` atom's `recInstance` and `ClientAnchor`'s corner-cell-plus-fractional-offset pair, 1/1024ths of a cell's width and 1/256ths of its height), skipping the invisible "patriarch" group root every drawing wraps its real shapes in. A picture shape's own `Opt` property table names a `pib` — a 1-based index into the **workbook-wide** Blip Store (`OfficeArtBstoreContainer`, read once from the globals substream's own `MsoDrawingGroup` stream, `src/drawing/blips.ts`) — resolved to real image bytes for a PNG or JPEG blip (`OfficeArtBlipPNG`/`OfficeArtBlipJPEG`'s own literal file bytes, past their `rgbUid` header); a DIB/EMF/WMF/PICT/TIFF blip is recognised but produces no image, since `ContentImageBlockSchema.format` has no lossless slot for any of them. Since neither an Escher shape nor a `MsoDrawing` record names what kind of object it actually holds, each shape is paired 1:1, in document order, with the worksheet substream's own `Obj` records (skipping any Note-type `Obj` `src/workbook/comments.ts` already accounts for) — the same positional correlation every other real BIFF8 reader relies on. An `Obj` naming a **chart** locates the chart's own nested `BOF`(dt=`0x0020`)/`EOF` substream — which sits INSIDE the worksheet substream, immediately after the shape that anchors it ([MS-XLS] "Chart Area") — via `src/biff/substreams.ts`'s own stack-based substream nesting (a genuinely new capability this issue needed: `splitSubstreams` previously treated any BOF met mid-substream as ending it outright, which would have silently dropped every worksheet record written after an embedded chart). `src/workbook/chart.ts` reads that substream's `Series`/`AI` (`BRAI`)/`SeriesText` records — a series' own name and its category/value data links — resolving each link's value either from the chart's own on-disk `SERIESDATA` cache (`Dimensions`/`SIIndex`/`Number`/`BoolErr`/`Blank`/`Label`, present when the chart's data lives on another sheet or is genuinely external) or, for the common case of a chart plotting its own sheet's cells, by resolving the `AI`'s `PtgArea3d`/`PtgRef3d` reference token directly against that sheet's own already-mapped cells — and lands as a `ContentEmbeddedObject` with `objectKind: 'chart'`, its cached series/category table flattened into a small one-sheet spreadsheet `ContentDocument`, the identical shape `ooxml.js`'s own xlsx/pptx chart reading already produces (ExaDev/documents.js#719): `document-schema.js` has no richer, chart-type-aware object model yet, so this reader targets the fallback that exists rather than inventing one. Every other recognised shape (an autoshape, a text box, a line, a group) lands as `objectKind: 'drawing'`, a single-page `ContentDocument` holding one sized-and-positioned `ContentShape` with no text content modelled. Not modelled at all: a shape's own rotation, fill/line formatting, or text runs; a group's own nested transform (a nested nested group's shapes are still recovered, cell-anchored, but a group's own rotation/scale is not composed into its children's positions); and a chart's own type, axes, and legend, which `document-schema.js`'s flattened-table representation has no field for regardless of what this reader could recover.
|
|
60
|
+
- **Conditional formatting, base rules resolved for real (ExaDev/documents.js#1102).** A `CondFmt` record ([MS-XLS] 2.4.56) marks the start of one to three `CF` records ([MS-XLS] 2.4.42) sharing one cell-range list, read together as a group (`src/workbook/conditional-format.ts`) since a `CF`'s own ranges live on its parent `CondFmt`, not on itself. Base BIFF8 (Excel 97) conditional formatting has exactly two rule shapes: a comparison ("Cell Value Is") condition, promoted to `ContentSheetConditionalFormat`'s `cellIs` variant with its formula(s) recovered through the same `parseFormulaText` this reader already uses for cell formulas and `Dv`; and a formula condition, left unpromoted for the same "no closed-form structure without a general formula engine" reason `data-validation.ts` and `ooxml.js`'s own xlsx `cfRule` reading already draw. A rule's resulting style -- font colour and fill background -- comes from its `CF`'s own `DXFN` structure, resolved through the identical `icv`/`Palette` colour machinery a regular cell's fill and border already use ([Cell decoration](#cell-decoration)); a `DXFN` naming a user-defined number format (`DXFNumUsr`) degrades that one rule's style to absent rather than risk misreading the font/fill fields that follow it, since [MS-XLS]'s own prose for `DXFNumUsr`'s length field does not settle whether it counts itself. Every richer rule type Excel 2007+ added has no representation in the base `CF` record at all; it rides a `CF12` record instead, or, for a rule Excel keeps expressible as a legacy formula condition for pre-2007 readers, a `CFEx` extension record that attaches richer metadata to an ordinary `CondFmt`-owned `CF` without promoting it into a `CF12` record at all.
|
|
58
61
|
- **Conditional formatting, CF12's colour scale/data bar/icon set rules resolved for real (ExaDev/documents.js#1104).** `CF12`'s own `ct` field picks one of six rule shapes ([MS-XLS] 2.4.43); this reader promotes the three that share a genuine array-of-thresholds building block already modelled in `document-schema.js` -- colour scale, data bar, and icon set (`src/workbook/conditional-format-12.ts`) -- each reading an array of `CFVO` threshold objects (the identical `num`/`percent`/`max`/`min`/`formula`/`percentile` vocabulary `ContentSheetConditionalFormatValueSchema` already carries for `ooxml.js`'s xlsx reader and `odf.js`'s ods reader) paired with `CFColor` values. A `CFColor` naming an indexed colour resolves through the same `icv`/`Palette` machinery as base `CF`'s own `DXFN`, then Excel's own TintAndShade model applies the colour's own tint/shade Xnum (`xf-colors.ts`'s `applyTint`); one naming a plain RGB triple resolves directly, tint included; one naming an automatic or theme colour degrades the whole rule to absent, since this package has no BIFF8 `Theme` reader to resolve a theme reference against. Icon set's own `iIconSet` byte maps to the identical ECMA-376 `ST_IconSetType` vocabulary (`3Arrows`, `3TrafficLights1`, `5Quarters`, and the rest of the seventeen built-in sets) `ooxml.js`'s xlsx `cfRule` reading already carries as a plain string. A record longer than the 8224-byte single-record ceiling continues onto `ContinueFrt12` rather than the plain `Continue` every other record in this package joins against; `groupRecords` (`src/biff/substreams.ts`) strips its own restated `FrtRefHeader` before joining it.
|
|
59
|
-
- **Conditional formatting, CF12's filter-dispatched template rules resolved for real (ExaDev/documents.js#1106).** `ct` 0x05 ("filter") dispatches further through `icfTemplate`, alongside a 16-byte `CFExTemplateParams` block always present regardless of `ct`. Of that block's five variants, only two need real parsing -- `CFExFilterParams` (top10's own `fTop`/`fPercent`/`iParam`) and `CFExAveragesTemplateParams` (the aboveAverage family's own standard-deviation count) -- since `CFExDefaultTemplateParams` (duplicateValues/uniqueValues/the four blank/error conditions) is 16 reserved bytes and `CFExDateTemplateParams`'s own `dateOp` field is a fixed restatement of `icfTemplate` for all ten date/time periods, so both dispatch directly off `icfTemplate` with no further byte reading. Unlike colour scale/data bar/icon set, [MS-XLS] does not force a `ct` 0x05 rule's own `cbDxf` to zero, so its `DXFN12` can carry a genuine font/fill override; that structure resolves through the identical `parseDxfStyle` base `CF`'s own `DXFN` already uses. A malformed `iParam` of zero degrades a top10 rule to absent rather than promoting a `rank` `ContentSheetConditionalFormatSchema` itself requires to be positive.
|
|
60
|
-
- **
|
|
62
|
+
- **Conditional formatting, CF12's filter-dispatched template rules resolved for real (ExaDev/documents.js#1106).** `ct` 0x05 ("filter") dispatches further through `icfTemplate`, alongside a 16-byte `CFExTemplateParams` block always present regardless of `ct`. Of that block's five variants, only two need real parsing -- `CFExFilterParams` (top10's own `fTop`/`fPercent`/`iParam`) and `CFExAveragesTemplateParams` (the aboveAverage family's own standard-deviation count) -- since `CFExDefaultTemplateParams` (duplicateValues/uniqueValues/the four blank/error conditions) is 16 reserved bytes and `CFExDateTemplateParams`'s own `dateOp` field is a fixed restatement of `icfTemplate` for all ten date/time periods, so both dispatch directly off `icfTemplate` with no further byte reading. Unlike colour scale/data bar/icon set, [MS-XLS] does not force a `ct` 0x05 rule's own `cbDxf` to zero, so its `DXFN12` can carry a genuine font/fill override; that structure resolves through the identical `parseDxfStyle` base `CF`'s own `DXFN` already uses. A malformed `iParam` of zero degrades a top10 rule to absent rather than promoting a `rank` `ContentSheetConditionalFormatSchema` itself requires to be positive.
|
|
63
|
+
- **Conditional formatting, `containsText`/`notContainsText`/`beginsWith`/`endsWith` and `CFEx`'s own legacy-`CF` extension resolved for real (ExaDev/documents.js#1100).** `icfTemplate` 0x0008 ("Contains text") is the one filter-dispatched template that is NOT actually a `ct` 0x05 rule: `CFExTextTemplateParams` carries only `ctp`, naming which of the four text sub-types a rule is, and neither it nor `ct` 0x05's own `CFFilter` `rgbCT` has anywhere to carry the literal search text (confirmed against a second, independent transcription of both structures -- [kinkou/unxls](https://github.com/kinkou/unxls)'s own `cfextexttemplateparams`/`cffilter` readers, which read `CFFilter` as an unconditional fixed six bytes with no variable trailer). Excel instead expresses these four rule kinds as a genuine `ct` 0x02 formula condition -- either directly on a `CF12` record, or (to stay evaluable by pre-2007 Excel, which silently skips an unrecognised `CF12`/`CondFmt12` "future record" wholesale) via a `CFEx` record ([MS-XLS] 2.4.63) extending an ordinary legacy `CF` -- with the literal text present as a string-constant (`PtgStr`) operand somewhere in the formula's own token stream, matching Excel's real, independently-confirmed generated formula for each sub-type (`NOT(ISERROR(SEARCH("text",cell)))` for `containsText`, and the `ISERROR`/`LEFT`+`LEN`/`RIGHT`+`LEN` equivalents for the other three -- LibreOffice's own `xecontent.cxx` `GetFixedFormula` emits exactly these shapes for its xlsx compatibility formula). `readCfTextFilterRule` (`src/workbook/conditional-format-12.ts`) extracts that operand via `ptg.ts`'s `extractFirstStringLiteral`, reached from both `readCf12`'s own `ct` 0x02 branch and `readCfEx` (`src/workbook/conditional-format-ex.ts`). A `CFEx` record with `fIsCF12` set (extending a genuine `CF12` record rather than a legacy `CF`) stays unread: that `CF12` carries no ranges of its own -- a `CondFmt12` normally supplies them -- and this reader has no established link back to one for it. `CFEx`'s own `nID` cross-references the `nID` field [MS-XLS] 2.1.7.20.6's own worksheet-substream grammar places on every `CondFmt` record (every `CFEx` on a sheet follows every `CondFmt`/`CondFmt12` group, per that same grammar), so `workbook/sheet.ts` keeps a per-`nID` map of each group's own resolved ranges and raw `CF` operands as it walks the substream, for a later `CFEx` to resolve its own `icf` index against.
|
|
64
|
+
- **Not read at all:** a `CFEx` record that extends a genuine `CF12` record rather than a legacy `CF` (see above). Defined names (`Lbl`) are read only for the two built-in ones a sheet's print range and repeated header bands live in ([Print settings](#print-settings)); a user-defined name has nowhere to land in `document-schema.js`'s spreadsheet model, so it is skipped.
|
|
61
65
|
- **RC4-encrypted workbooks, decrypted for real (ExaDev/documents.js#1108).** A `FilePass` record ([MS-XLS] 2.4.117) means every record after it is ciphertext under one of three schemes; this reader implements exactly one, the [MS-OFFCRYPTO] 2.3.6.1 "RC4 encryption header" -- `readXlsContent`/`readXls` take an optional `password`, verify it against the header's own `EncryptedVerifier`/`EncryptedVerifierHash` pair, then decrypt every subsequent record's data (`src/workbook/encryption.ts`) using the RC4/MD5 primitives [`archive-codec`](../archive-codec/README.md#legacy-office-encryption) shares with `doc-codec`/`ppt-codec`'s own eventual integration. [MS-XLS] 2.2.10's own exclusion list -- `BOF`, `FilePass`, and four shared-workbook revision-tracking records this package otherwise never reads, plus `BoundSheet8`'s own `lbPlyPos` field specifically -- is honoured exactly, re-derived independently in this package's own tests rather than trusted by construction. A missing or incorrect password throws rather than returning a garbled document; the newer "RC4 CryptoAPI encryption header" scheme and XOR obfuscation are explicitly out of scope, tracked separately on [#922](https://github.com/ExaDev/documents.js/issues/922).
|
|
62
66
|
|
|
63
67
|
This package is wired into `documents.js`'s conversion registry (`xlsToPdf`/`pdfToXls`, `convertDocument("xls", ...)`, and every same-variant spreadsheet bridge) — see that package's own README Fidelity table for exactly which pairs route and which don't. Remaining read+write scope gaps (formula writing and per-cell font) are tracked on [#815](https://github.com/ExaDev/documents.js/issues/815).
|
|
@@ -201,6 +205,8 @@ Layered bottom-up, each layer testable against hand-built byte sequences taken f
|
|
|
201
205
|
- **`src/biff/xf-colors.ts`** — the `Icv` colour table (both the eight fixed colours and the 56-entry default palette), the `BorderStyle`/`FillPattern` vocabularies, and the `CellXF`/`StyleXF` trailing payload's own border/fill bit-layout packing and unpacking, shared by `globals.ts`'s read side and `biff/xf-writer.ts`'s write side — see [Cell decoration](#cell-decoration).
|
|
202
206
|
- **`src/biff/print-setup.ts`**, **`src/workbook/print-names.ts`** — the two halves of [Print settings](#print-settings). The first is the `Setup` record's own flag bit layout and `iPaperSize` code table, packed and unpacked in one place exactly as `xf-colors.ts` does for the `XF` payload; the second is both directions of the built-in `Print_Area`/`Print_Titles` defined names, which live in the globals substream rather than the sheet's own and so are read by `globals.ts` and written by `globals-writer.ts`.
|
|
203
207
|
- **[`excel-number-format`](../excel-number-format/README.md)**, **`src/serial.ts`** — number-format classification and date-serial conversion, the two pieces of xlsx semantics BIFF8 shares because ECMA-376 inherited them from BIFF. The classifier itself is a dependency shared with `ooxml.js`, not a module in this package (ExaDev/documents.js#848) — `classifyNumberFormat` and `BUILTIN_NUMBER_FORMATS` still ride this package's own barrel (`export * from "excel-number-format"` in `src/index.ts`), so `import { classifyNumberFormat } from "xls-codec"` is unchanged.
|
|
208
|
+
- **`src/drawing/escher.ts`**, **`src/drawing/shapes.ts`**, **`src/drawing/blips.ts`** — MS-ODRAW (Escher), read as its own record tree independent of BIFF8's own record framing: the shared `OfficeArtRecordHeader` container/atom reader, the per-sheet shape walk (type, id, cell anchor, a picture's own `pib` blip reference), and the workbook-wide Blip Store a `pib` resolves against.
|
|
209
|
+
- **`src/workbook/chart.ts`**, **`src/workbook/drawing.ts`** — an embedded chart's own nested substream, read into a flattened series/category table; and the orchestration that pairs each Escher shape with the `Obj` record naming what it holds (a picture, a chart, or a generic shape) and produces `ContentSheet.images`/`ContentSheet.embeddedObjects` — see "Charts, drawings, and images, resolved for real" under [Read-side gaps](#read-side-gaps).
|
|
204
210
|
- **`src/content.ts`** — the mapping onto `document-schema.js`.
|
|
205
211
|
- **`src/metadata.ts`** — wraps `archive-codec`'s own `SummaryInformationProperties` <-> `LayoutMetadata` mapping with this package's `createdIso`/`modifiedIso` date validation, throwing `BiffWriteError` for a malformed one rather than letting an opaque `RangeError` escape the FILETIME conversion (see [Metadata](#metadata)).
|
|
206
212
|
|
package/dist/biff/cursor.cjs
CHANGED
|
@@ -62,8 +62,19 @@ var BlockCursor = class {
|
|
|
62
62
|
const raw = this.take(8);
|
|
63
63
|
return new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getFloat64(0, true);
|
|
64
64
|
}
|
|
65
|
-
/**
|
|
65
|
+
/** Total unread bytes across the current block and every block after it -- what a length-prefixed field's own prefix must be checked against before that many bytes are allocated, so a record cannot claim a length far larger than the data actually behind it. */
|
|
66
|
+
remainingTotal() {
|
|
67
|
+
this.settle();
|
|
68
|
+
let total = 0;
|
|
69
|
+
for (let index = this.blockIndex; index < this.blocks.length; index += 1) {
|
|
70
|
+
const block = this.blocks[index];
|
|
71
|
+
total += (index === this.blockIndex ? this.remainingInBlock() : block?.length) ?? 0;
|
|
72
|
+
}
|
|
73
|
+
return total;
|
|
74
|
+
}
|
|
75
|
+
/** The next `count` bytes, copied out. Spans block boundaries. Rejects a `count` larger than the data actually remaining before allocating, so a length-prefixed field taken from untrusted input (e.g. CFEx's own `cbDxf`) cannot force a multi-gigabyte allocation from a tiny record. */
|
|
66
76
|
take(count) {
|
|
77
|
+
if (count > this.remainingTotal()) throw new require_biff_records.BiffFormatError(`${count}-byte run requests more data than remains in the record`);
|
|
67
78
|
const out = new Uint8Array(count);
|
|
68
79
|
for (let index = 0; index < count; index += 1) out[index] = this.nextByte(`${count}-byte run`);
|
|
69
80
|
return out;
|
package/dist/biff/cursor.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as BlockCursor } from "../cursor-
|
|
1
|
+
import { t as BlockCursor } from "../cursor-CnEuX5qE.cjs";
|
|
2
2
|
export { BlockCursor };
|
package/dist/biff/cursor.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as BlockCursor } from "../cursor-
|
|
1
|
+
import { t as BlockCursor } from "../cursor-CnEuX5qE.js";
|
|
2
2
|
export { BlockCursor };
|
package/dist/biff/cursor.js
CHANGED
|
@@ -61,8 +61,19 @@ var BlockCursor = class {
|
|
|
61
61
|
const raw = this.take(8);
|
|
62
62
|
return new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getFloat64(0, true);
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
64
|
+
/** Total unread bytes across the current block and every block after it -- what a length-prefixed field's own prefix must be checked against before that many bytes are allocated, so a record cannot claim a length far larger than the data actually behind it. */
|
|
65
|
+
remainingTotal() {
|
|
66
|
+
this.settle();
|
|
67
|
+
let total = 0;
|
|
68
|
+
for (let index = this.blockIndex; index < this.blocks.length; index += 1) {
|
|
69
|
+
const block = this.blocks[index];
|
|
70
|
+
total += (index === this.blockIndex ? this.remainingInBlock() : block?.length) ?? 0;
|
|
71
|
+
}
|
|
72
|
+
return total;
|
|
73
|
+
}
|
|
74
|
+
/** The next `count` bytes, copied out. Spans block boundaries. Rejects a `count` larger than the data actually remaining before allocating, so a length-prefixed field taken from untrusted input (e.g. CFEx's own `cbDxf`) cannot force a multi-gigabyte allocation from a tiny record. */
|
|
65
75
|
take(count) {
|
|
76
|
+
if (count > this.remainingTotal()) throw new BiffFormatError(`${count}-byte run requests more data than remains in the record`);
|
|
66
77
|
const out = new Uint8Array(count);
|
|
67
78
|
for (let index = 0; index < count; index += 1) out[index] = this.nextByte(`${count}-byte run`);
|
|
68
79
|
return out;
|
package/dist/biff/ptg.cjs
CHANGED
|
@@ -336,9 +336,12 @@ function parseFormulaText(rgce, context, options = {}) {
|
|
|
336
336
|
case PTG_MISSARG:
|
|
337
337
|
pushAtomic(stack, "");
|
|
338
338
|
break;
|
|
339
|
-
case PTG_STR:
|
|
340
|
-
|
|
339
|
+
case PTG_STR: {
|
|
340
|
+
const value = require_biff_strings.readShortXLUnicodeString(cursor);
|
|
341
|
+
options.onStringLiteral?.(value);
|
|
342
|
+
pushAtomic(stack, quoteStringLiteral(value));
|
|
341
343
|
break;
|
|
344
|
+
}
|
|
342
345
|
case PTG_ERR: {
|
|
343
346
|
const text = require_biff_errors.errorTextOf(cursor.u8());
|
|
344
347
|
if (text === void 0) return void 0;
|
|
@@ -449,6 +452,16 @@ function parseFormulaText(rgce, context, options = {}) {
|
|
|
449
452
|
}
|
|
450
453
|
return stack.length === 1 ? stack[0]?.text : void 0;
|
|
451
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Returns the raw text of the first PtgStr operand `rgce` contains, or undefined if it contains none -- a narrower question than parseFormulaText's own "render the whole formula", answerable even when the formula wraps that operand in functions this reader has no other reason to understand. Exists for conditional-format-12.ts's own readCfTextFilterRule: a CF12/CFExNonCF12 containsText-family rule states which of the four text-comparison sub-types it is via CFExTextTemplateParams.ctp, but carries the literal search text nowhere else but as this operand in its own formula (Excel's real generated shape being e.g. NOT(ISERROR(SEARCH("text",A1))) for containsText -- see conditional-format-ex.ts's own top comment for the full citation). Walks the whole token stream via parseFormulaText's own onStringLiteral hook rather than scanning for the PtgStr opcode directly, since a raw byte scan cannot tell an opcode byte from a length or count belonging to some other token's own payload.
|
|
457
|
+
*/
|
|
458
|
+
function extractFirstStringLiteral(rgce, context) {
|
|
459
|
+
let literal;
|
|
460
|
+
parseFormulaText(rgce, context, { onStringLiteral: (value) => {
|
|
461
|
+
literal ??= value;
|
|
462
|
+
} });
|
|
463
|
+
return literal;
|
|
464
|
+
}
|
|
452
465
|
/** PtgExp's own opcode ([MS-XLS] f9aa266f): 0x01, a reserved bit, then the row/col of the Formula record that carries the shared or array formula's real expression -- see readPtgExpBase. */
|
|
453
466
|
const PTG_EXP_OPCODE = 1;
|
|
454
467
|
/** PtgExp's own fixed size: the opcode byte plus a Rw (2 bytes) and a Col (2 bytes), [MS-XLS] f9aa266f. */
|
|
@@ -468,5 +481,6 @@ function readPtgExpBase(rgce) {
|
|
|
468
481
|
};
|
|
469
482
|
}
|
|
470
483
|
//#endregion
|
|
484
|
+
exports.extractFirstStringLiteral = extractFirstStringLiteral;
|
|
471
485
|
exports.parseFormulaText = parseFormulaText;
|
|
472
486
|
exports.readPtgExpBase = readPtgExpBase;
|
package/dist/biff/ptg.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as SheetRange, i as ParseFormulaOptions, n as FormulaOrigin, o as
|
|
2
|
-
export { ExternalSheetLabel, FormulaOrigin, FormulaSheetContext, ParseFormulaOptions, SheetRange, parseFormulaText, readPtgExpBase };
|
|
1
|
+
import { a as SheetRange, c as readPtgExpBase, i as ParseFormulaOptions, n as FormulaOrigin, o as extractFirstStringLiteral, r as FormulaSheetContext, s as parseFormulaText, t as ExternalSheetLabel } from "../ptg-75v7MhaA.cjs";
|
|
2
|
+
export { ExternalSheetLabel, FormulaOrigin, FormulaSheetContext, ParseFormulaOptions, SheetRange, extractFirstStringLiteral, parseFormulaText, readPtgExpBase };
|
package/dist/biff/ptg.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as SheetRange, i as ParseFormulaOptions, n as FormulaOrigin, o as
|
|
2
|
-
export { ExternalSheetLabel, FormulaOrigin, FormulaSheetContext, ParseFormulaOptions, SheetRange, parseFormulaText, readPtgExpBase };
|
|
1
|
+
import { a as SheetRange, c as readPtgExpBase, i as ParseFormulaOptions, n as FormulaOrigin, o as extractFirstStringLiteral, r as FormulaSheetContext, s as parseFormulaText, t as ExternalSheetLabel } from "../ptg-75v7MhaA.js";
|
|
2
|
+
export { ExternalSheetLabel, FormulaOrigin, FormulaSheetContext, ParseFormulaOptions, SheetRange, extractFirstStringLiteral, parseFormulaText, readPtgExpBase };
|
package/dist/biff/ptg.js
CHANGED
|
@@ -335,9 +335,12 @@ function parseFormulaText(rgce, context, options = {}) {
|
|
|
335
335
|
case PTG_MISSARG:
|
|
336
336
|
pushAtomic(stack, "");
|
|
337
337
|
break;
|
|
338
|
-
case PTG_STR:
|
|
339
|
-
|
|
338
|
+
case PTG_STR: {
|
|
339
|
+
const value = readShortXLUnicodeString(cursor);
|
|
340
|
+
options.onStringLiteral?.(value);
|
|
341
|
+
pushAtomic(stack, quoteStringLiteral(value));
|
|
340
342
|
break;
|
|
343
|
+
}
|
|
341
344
|
case PTG_ERR: {
|
|
342
345
|
const text = errorTextOf(cursor.u8());
|
|
343
346
|
if (text === void 0) return void 0;
|
|
@@ -448,6 +451,16 @@ function parseFormulaText(rgce, context, options = {}) {
|
|
|
448
451
|
}
|
|
449
452
|
return stack.length === 1 ? stack[0]?.text : void 0;
|
|
450
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Returns the raw text of the first PtgStr operand `rgce` contains, or undefined if it contains none -- a narrower question than parseFormulaText's own "render the whole formula", answerable even when the formula wraps that operand in functions this reader has no other reason to understand. Exists for conditional-format-12.ts's own readCfTextFilterRule: a CF12/CFExNonCF12 containsText-family rule states which of the four text-comparison sub-types it is via CFExTextTemplateParams.ctp, but carries the literal search text nowhere else but as this operand in its own formula (Excel's real generated shape being e.g. NOT(ISERROR(SEARCH("text",A1))) for containsText -- see conditional-format-ex.ts's own top comment for the full citation). Walks the whole token stream via parseFormulaText's own onStringLiteral hook rather than scanning for the PtgStr opcode directly, since a raw byte scan cannot tell an opcode byte from a length or count belonging to some other token's own payload.
|
|
456
|
+
*/
|
|
457
|
+
function extractFirstStringLiteral(rgce, context) {
|
|
458
|
+
let literal;
|
|
459
|
+
parseFormulaText(rgce, context, { onStringLiteral: (value) => {
|
|
460
|
+
literal ??= value;
|
|
461
|
+
} });
|
|
462
|
+
return literal;
|
|
463
|
+
}
|
|
451
464
|
/** PtgExp's own opcode ([MS-XLS] f9aa266f): 0x01, a reserved bit, then the row/col of the Formula record that carries the shared or array formula's real expression -- see readPtgExpBase. */
|
|
452
465
|
const PTG_EXP_OPCODE = 1;
|
|
453
466
|
/** PtgExp's own fixed size: the opcode byte plus a Rw (2 bytes) and a Col (2 bytes), [MS-XLS] f9aa266f. */
|
|
@@ -467,4 +480,4 @@ function readPtgExpBase(rgce) {
|
|
|
467
480
|
};
|
|
468
481
|
}
|
|
469
482
|
//#endregion
|
|
470
|
-
export { parseFormulaText, readPtgExpBase };
|
|
483
|
+
export { extractFirstStringLiteral, parseFormulaText, readPtgExpBase };
|
|
@@ -64,14 +64,30 @@ const RECORD_CONDFMT = 432;
|
|
|
64
64
|
const RECORD_CF = 433;
|
|
65
65
|
/** Marks the start of a collection of CF12 records, the "future record" (FRT) equivalent of CondFmt for the rule types Excel 97's own CF record cannot express ([MS-XLS] 2.4.57). Wraps a CondFmtStructure -- the same ccf/flags/refBound/sqref shape CondFmt's own body carries, just prefixed by a 12-byte FrtRefHeaderU this reader never needs to read. */
|
|
66
66
|
const RECORD_CONDFMT12 = 2169;
|
|
67
|
-
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43).
|
|
67
|
+
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43). */
|
|
68
68
|
const RECORD_CF12 = 2170;
|
|
69
|
+
/** Extends an existing CondFmt-owned rule with icfTemplate/priority metadata a legacy (Excel 97) CF record has no field for -- CF12's counterpart for a rule Excel keeps expressible as a plain formula condition for pre-2007 readers, most notably the containsText family ([MS-XLS] 2.4.63). Read by workbook/conditional-format-ex.ts. */
|
|
70
|
+
const RECORD_CFEX = 2171;
|
|
69
71
|
/** A cell comment's anchor -- row, column, and its own author, linking to the Obj record that names its text ([MS-XLS] 2.4.179). */
|
|
70
72
|
const RECORD_NOTE = 28;
|
|
71
73
|
/** A drawing object's common properties (id, type) and, for a comment, its FtNts sub-structure ([MS-XLS] 2.4.181). */
|
|
72
74
|
const RECORD_OBJ = 93;
|
|
73
75
|
/** The rich text of a text box or comment, its characters and formatting runs carried in trailing Continue records ([MS-XLS] 2.4.329). */
|
|
74
76
|
const RECORD_TXO = 438;
|
|
77
|
+
/** One worksheet's own MS-ODRAW (Escher) drawing bytes, chunked across as many of these records as the drawing needs ([MS-XLS] 2.4.180's sibling "MsoDrawing", https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/1b0b0ea3-5e1d-41ce-8e79-e27f1041331e) -- every MsoDrawing record's own data in one worksheet substream concatenates, in stream order, into one continuous Escher byte stream (src/drawing/escher.ts reads it). */
|
|
78
|
+
const RECORD_MSODRAWING = 236;
|
|
79
|
+
/** The workbook-wide counterpart of MsoDrawing, carrying the drawing group's own shared state -- most importantly the Blip Store (`OfficeArtBStoreContainer`) every worksheet's picture/chart shapes reference by index -- concatenated the same way, but read from the WORKBOOK GLOBALS substream rather than a worksheet's. */
|
|
80
|
+
const RECORD_MSODRAWINGGROUP = 235;
|
|
81
|
+
/** Which Escher shapes a worksheet had selected when it was last saved -- UI state this package has no use for, named here only so a reader that walks every record type in a worksheet substream can recognise and skip it rather than mistake it for drawing bytes. */
|
|
82
|
+
const RECORD_MSODRAWINGSELECTION = 237;
|
|
83
|
+
/** One data series' own type/count header and, following it, its four AI (BRAI) links -- categories, values, bubble sizes, name, each identified by the AI's own `id` field rather than by position ([MS-XLS] "Series"). */
|
|
84
|
+
const RECORD_SERIES = 4099;
|
|
85
|
+
/** A series' cached NAME text, when the file states one as a literal rather than through its own `AI id=0` formula reference ([MS-XLS] "SeriesText"): a ShortXLUnicodeString (one-byte length prefix), unlike the double-byte-length XLUnicodeString most other BIFF8 strings use. */
|
|
86
|
+
const RECORD_SERIESTEXT = 4109;
|
|
87
|
+
/** A data-role link on a series -- name, categories, values, or bubble sizes, selected by the record's own `id` field -- carrying either a literal value/text or a `ChartParsedFormula` range reference this package's own Ptg reference tokens (PtgArea3d/PtgRef3d) can resolve ([MS-XLS] "AI"/BRAI, restricted to a narrower Ptg grammar than a worksheet cell's own Formula record). */
|
|
88
|
+
const RECORD_AI = 4177;
|
|
89
|
+
/** Precedes each of the up-to-three chart-wide cached data blocks (values, categories, bubble sizes) a `SERIESDATA` production carries, its own `numIndex` field naming which of the three follows ([MS-XLS] "SIIndex"). Each cached `Number`/`BoolErr`/`Blank`/`Label` record that follows carries the same `col` field the worksheet cell-record family already does, here reused as the zero-based Series-record index the cached value belongs to. */
|
|
90
|
+
const RECORD_SIINDEX = 4197;
|
|
75
91
|
/** Whether the row and column headers are printed ([MS-XLS] 2.4.203). */
|
|
76
92
|
const RECORD_PRINTROWCOL = 42;
|
|
77
93
|
/** Whether the gridlines are printed ([MS-XLS] 2.4.202). */
|
|
@@ -147,6 +163,7 @@ exports.BOF_TYPE_MACRO = BOF_TYPE_MACRO;
|
|
|
147
163
|
exports.BOF_TYPE_WORKBOOK = BOF_TYPE_WORKBOOK;
|
|
148
164
|
exports.BOF_TYPE_WORKSHEET = BOF_TYPE_WORKSHEET;
|
|
149
165
|
exports.MAX_RECORD_DATA_SIZE = MAX_RECORD_DATA_SIZE;
|
|
166
|
+
exports.RECORD_AI = RECORD_AI;
|
|
150
167
|
exports.RECORD_ARRAY = RECORD_ARRAY;
|
|
151
168
|
exports.RECORD_BLANK = RECORD_BLANK;
|
|
152
169
|
exports.RECORD_BOF = RECORD_BOF;
|
|
@@ -160,6 +177,7 @@ exports.RECORD_CALCREFMODE = RECORD_CALCREFMODE;
|
|
|
160
177
|
exports.RECORD_CALCSAVERECALC = RECORD_CALCSAVERECALC;
|
|
161
178
|
exports.RECORD_CF = RECORD_CF;
|
|
162
179
|
exports.RECORD_CF12 = RECORD_CF12;
|
|
180
|
+
exports.RECORD_CFEX = RECORD_CFEX;
|
|
163
181
|
exports.RECORD_COLINFO = RECORD_COLINFO;
|
|
164
182
|
exports.RECORD_CONDFMT = RECORD_CONDFMT;
|
|
165
183
|
exports.RECORD_CONDFMT12 = RECORD_CONDFMT12;
|
|
@@ -185,6 +203,9 @@ exports.RECORD_LABELSST = RECORD_LABELSST;
|
|
|
185
203
|
exports.RECORD_LBL = RECORD_LBL;
|
|
186
204
|
exports.RECORD_LEFTMARGIN = RECORD_LEFTMARGIN;
|
|
187
205
|
exports.RECORD_MERGECELLS = RECORD_MERGECELLS;
|
|
206
|
+
exports.RECORD_MSODRAWING = RECORD_MSODRAWING;
|
|
207
|
+
exports.RECORD_MSODRAWINGGROUP = RECORD_MSODRAWINGGROUP;
|
|
208
|
+
exports.RECORD_MSODRAWINGSELECTION = RECORD_MSODRAWINGSELECTION;
|
|
188
209
|
exports.RECORD_MULBLANK = RECORD_MULBLANK;
|
|
189
210
|
exports.RECORD_MULRK = RECORD_MULRK;
|
|
190
211
|
exports.RECORD_NOTE = RECORD_NOTE;
|
|
@@ -198,8 +219,11 @@ exports.RECORD_RK = RECORD_RK;
|
|
|
198
219
|
exports.RECORD_ROW = RECORD_ROW;
|
|
199
220
|
exports.RECORD_RRDHEAD = RECORD_RRDHEAD;
|
|
200
221
|
exports.RECORD_RRDINFO = RECORD_RRDINFO;
|
|
222
|
+
exports.RECORD_SERIES = RECORD_SERIES;
|
|
223
|
+
exports.RECORD_SERIESTEXT = RECORD_SERIESTEXT;
|
|
201
224
|
exports.RECORD_SETUP = RECORD_SETUP;
|
|
202
225
|
exports.RECORD_SHRFMLA = RECORD_SHRFMLA;
|
|
226
|
+
exports.RECORD_SIINDEX = RECORD_SIINDEX;
|
|
203
227
|
exports.RECORD_SST = RECORD_SST;
|
|
204
228
|
exports.RECORD_STRING = RECORD_STRING;
|
|
205
229
|
exports.RECORD_STYLE = RECORD_STYLE;
|
|
@@ -63,14 +63,30 @@ declare const RECORD_CONDFMT = 432;
|
|
|
63
63
|
declare const RECORD_CF = 433;
|
|
64
64
|
/** Marks the start of a collection of CF12 records, the "future record" (FRT) equivalent of CondFmt for the rule types Excel 97's own CF record cannot express ([MS-XLS] 2.4.57). Wraps a CondFmtStructure -- the same ccf/flags/refBound/sqref shape CondFmt's own body carries, just prefixed by a 12-byte FrtRefHeaderU this reader never needs to read. */
|
|
65
65
|
declare const RECORD_CONDFMT12 = 2169;
|
|
66
|
-
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43).
|
|
66
|
+
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43). */
|
|
67
67
|
declare const RECORD_CF12 = 2170;
|
|
68
|
+
/** Extends an existing CondFmt-owned rule with icfTemplate/priority metadata a legacy (Excel 97) CF record has no field for -- CF12's counterpart for a rule Excel keeps expressible as a plain formula condition for pre-2007 readers, most notably the containsText family ([MS-XLS] 2.4.63). Read by workbook/conditional-format-ex.ts. */
|
|
69
|
+
declare const RECORD_CFEX = 2171;
|
|
68
70
|
/** A cell comment's anchor -- row, column, and its own author, linking to the Obj record that names its text ([MS-XLS] 2.4.179). */
|
|
69
71
|
declare const RECORD_NOTE = 28;
|
|
70
72
|
/** A drawing object's common properties (id, type) and, for a comment, its FtNts sub-structure ([MS-XLS] 2.4.181). */
|
|
71
73
|
declare const RECORD_OBJ = 93;
|
|
72
74
|
/** The rich text of a text box or comment, its characters and formatting runs carried in trailing Continue records ([MS-XLS] 2.4.329). */
|
|
73
75
|
declare const RECORD_TXO = 438;
|
|
76
|
+
/** One worksheet's own MS-ODRAW (Escher) drawing bytes, chunked across as many of these records as the drawing needs ([MS-XLS] 2.4.180's sibling "MsoDrawing", https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/1b0b0ea3-5e1d-41ce-8e79-e27f1041331e) -- every MsoDrawing record's own data in one worksheet substream concatenates, in stream order, into one continuous Escher byte stream (src/drawing/escher.ts reads it). */
|
|
77
|
+
declare const RECORD_MSODRAWING = 236;
|
|
78
|
+
/** The workbook-wide counterpart of MsoDrawing, carrying the drawing group's own shared state -- most importantly the Blip Store (`OfficeArtBStoreContainer`) every worksheet's picture/chart shapes reference by index -- concatenated the same way, but read from the WORKBOOK GLOBALS substream rather than a worksheet's. */
|
|
79
|
+
declare const RECORD_MSODRAWINGGROUP = 235;
|
|
80
|
+
/** Which Escher shapes a worksheet had selected when it was last saved -- UI state this package has no use for, named here only so a reader that walks every record type in a worksheet substream can recognise and skip it rather than mistake it for drawing bytes. */
|
|
81
|
+
declare const RECORD_MSODRAWINGSELECTION = 237;
|
|
82
|
+
/** One data series' own type/count header and, following it, its four AI (BRAI) links -- categories, values, bubble sizes, name, each identified by the AI's own `id` field rather than by position ([MS-XLS] "Series"). */
|
|
83
|
+
declare const RECORD_SERIES = 4099;
|
|
84
|
+
/** A series' cached NAME text, when the file states one as a literal rather than through its own `AI id=0` formula reference ([MS-XLS] "SeriesText"): a ShortXLUnicodeString (one-byte length prefix), unlike the double-byte-length XLUnicodeString most other BIFF8 strings use. */
|
|
85
|
+
declare const RECORD_SERIESTEXT = 4109;
|
|
86
|
+
/** A data-role link on a series -- name, categories, values, or bubble sizes, selected by the record's own `id` field -- carrying either a literal value/text or a `ChartParsedFormula` range reference this package's own Ptg reference tokens (PtgArea3d/PtgRef3d) can resolve ([MS-XLS] "AI"/BRAI, restricted to a narrower Ptg grammar than a worksheet cell's own Formula record). */
|
|
87
|
+
declare const RECORD_AI = 4177;
|
|
88
|
+
/** Precedes each of the up-to-three chart-wide cached data blocks (values, categories, bubble sizes) a `SERIESDATA` production carries, its own `numIndex` field naming which of the three follows ([MS-XLS] "SIIndex"). Each cached `Number`/`BoolErr`/`Blank`/`Label` record that follows carries the same `col` field the worksheet cell-record family already does, here reused as the zero-based Series-record index the cached value belongs to. */
|
|
89
|
+
declare const RECORD_SIINDEX = 4197;
|
|
74
90
|
/** Whether the row and column headers are printed ([MS-XLS] 2.4.203). */
|
|
75
91
|
declare const RECORD_PRINTROWCOL = 42;
|
|
76
92
|
/** Whether the gridlines are printed ([MS-XLS] 2.4.202). */
|
|
@@ -140,4 +156,4 @@ declare const BIFF8_VERSION = 1536;
|
|
|
140
156
|
/** [MS-XLS] 2.1.4: "The record size ... MUST be less than or equal to 8224." The ceiling a writer splits a record at, and the bound a reader can sanity-check a declared size against. */
|
|
141
157
|
declare const MAX_RECORD_DATA_SIZE = 8224;
|
|
142
158
|
//#endregion
|
|
143
|
-
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
|
159
|
+
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_AI, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_CFEX, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MSODRAWING, RECORD_MSODRAWINGGROUP, RECORD_MSODRAWINGSELECTION, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SERIES, RECORD_SERIESTEXT, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SIINDEX, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
|
@@ -63,14 +63,30 @@ declare const RECORD_CONDFMT = 432;
|
|
|
63
63
|
declare const RECORD_CF = 433;
|
|
64
64
|
/** Marks the start of a collection of CF12 records, the "future record" (FRT) equivalent of CondFmt for the rule types Excel 97's own CF record cannot express ([MS-XLS] 2.4.57). Wraps a CondFmtStructure -- the same ccf/flags/refBound/sqref shape CondFmt's own body carries, just prefixed by a 12-byte FrtRefHeaderU this reader never needs to read. */
|
|
65
65
|
declare const RECORD_CONDFMT12 = 2169;
|
|
66
|
-
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43).
|
|
66
|
+
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43). */
|
|
67
67
|
declare const RECORD_CF12 = 2170;
|
|
68
|
+
/** Extends an existing CondFmt-owned rule with icfTemplate/priority metadata a legacy (Excel 97) CF record has no field for -- CF12's counterpart for a rule Excel keeps expressible as a plain formula condition for pre-2007 readers, most notably the containsText family ([MS-XLS] 2.4.63). Read by workbook/conditional-format-ex.ts. */
|
|
69
|
+
declare const RECORD_CFEX = 2171;
|
|
68
70
|
/** A cell comment's anchor -- row, column, and its own author, linking to the Obj record that names its text ([MS-XLS] 2.4.179). */
|
|
69
71
|
declare const RECORD_NOTE = 28;
|
|
70
72
|
/** A drawing object's common properties (id, type) and, for a comment, its FtNts sub-structure ([MS-XLS] 2.4.181). */
|
|
71
73
|
declare const RECORD_OBJ = 93;
|
|
72
74
|
/** The rich text of a text box or comment, its characters and formatting runs carried in trailing Continue records ([MS-XLS] 2.4.329). */
|
|
73
75
|
declare const RECORD_TXO = 438;
|
|
76
|
+
/** One worksheet's own MS-ODRAW (Escher) drawing bytes, chunked across as many of these records as the drawing needs ([MS-XLS] 2.4.180's sibling "MsoDrawing", https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/1b0b0ea3-5e1d-41ce-8e79-e27f1041331e) -- every MsoDrawing record's own data in one worksheet substream concatenates, in stream order, into one continuous Escher byte stream (src/drawing/escher.ts reads it). */
|
|
77
|
+
declare const RECORD_MSODRAWING = 236;
|
|
78
|
+
/** The workbook-wide counterpart of MsoDrawing, carrying the drawing group's own shared state -- most importantly the Blip Store (`OfficeArtBStoreContainer`) every worksheet's picture/chart shapes reference by index -- concatenated the same way, but read from the WORKBOOK GLOBALS substream rather than a worksheet's. */
|
|
79
|
+
declare const RECORD_MSODRAWINGGROUP = 235;
|
|
80
|
+
/** Which Escher shapes a worksheet had selected when it was last saved -- UI state this package has no use for, named here only so a reader that walks every record type in a worksheet substream can recognise and skip it rather than mistake it for drawing bytes. */
|
|
81
|
+
declare const RECORD_MSODRAWINGSELECTION = 237;
|
|
82
|
+
/** One data series' own type/count header and, following it, its four AI (BRAI) links -- categories, values, bubble sizes, name, each identified by the AI's own `id` field rather than by position ([MS-XLS] "Series"). */
|
|
83
|
+
declare const RECORD_SERIES = 4099;
|
|
84
|
+
/** A series' cached NAME text, when the file states one as a literal rather than through its own `AI id=0` formula reference ([MS-XLS] "SeriesText"): a ShortXLUnicodeString (one-byte length prefix), unlike the double-byte-length XLUnicodeString most other BIFF8 strings use. */
|
|
85
|
+
declare const RECORD_SERIESTEXT = 4109;
|
|
86
|
+
/** A data-role link on a series -- name, categories, values, or bubble sizes, selected by the record's own `id` field -- carrying either a literal value/text or a `ChartParsedFormula` range reference this package's own Ptg reference tokens (PtgArea3d/PtgRef3d) can resolve ([MS-XLS] "AI"/BRAI, restricted to a narrower Ptg grammar than a worksheet cell's own Formula record). */
|
|
87
|
+
declare const RECORD_AI = 4177;
|
|
88
|
+
/** Precedes each of the up-to-three chart-wide cached data blocks (values, categories, bubble sizes) a `SERIESDATA` production carries, its own `numIndex` field naming which of the three follows ([MS-XLS] "SIIndex"). Each cached `Number`/`BoolErr`/`Blank`/`Label` record that follows carries the same `col` field the worksheet cell-record family already does, here reused as the zero-based Series-record index the cached value belongs to. */
|
|
89
|
+
declare const RECORD_SIINDEX = 4197;
|
|
74
90
|
/** Whether the row and column headers are printed ([MS-XLS] 2.4.203). */
|
|
75
91
|
declare const RECORD_PRINTROWCOL = 42;
|
|
76
92
|
/** Whether the gridlines are printed ([MS-XLS] 2.4.202). */
|
|
@@ -140,4 +156,4 @@ declare const BIFF8_VERSION = 1536;
|
|
|
140
156
|
/** [MS-XLS] 2.1.4: "The record size ... MUST be less than or equal to 8224." The ceiling a writer splits a record at, and the bound a reader can sanity-check a declared size against. */
|
|
141
157
|
declare const MAX_RECORD_DATA_SIZE = 8224;
|
|
142
158
|
//#endregion
|
|
143
|
-
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
|
159
|
+
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_AI, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_CFEX, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MSODRAWING, RECORD_MSODRAWINGGROUP, RECORD_MSODRAWINGSELECTION, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SERIES, RECORD_SERIESTEXT, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SIINDEX, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
|
@@ -63,14 +63,30 @@ const RECORD_CONDFMT = 432;
|
|
|
63
63
|
const RECORD_CF = 433;
|
|
64
64
|
/** Marks the start of a collection of CF12 records, the "future record" (FRT) equivalent of CondFmt for the rule types Excel 97's own CF record cannot express ([MS-XLS] 2.4.57). Wraps a CondFmtStructure -- the same ccf/flags/refBound/sqref shape CondFmt's own body carries, just prefixed by a 12-byte FrtRefHeaderU this reader never needs to read. */
|
|
65
65
|
const RECORD_CONDFMT12 = 2169;
|
|
66
|
-
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43).
|
|
66
|
+
/** One extended conditional-formatting rule: colour scale, data bar, icon set, a filter-dispatched template (top10, aboveAverage, contains-text, a date/time period, …), or a plain comparison/formula rule re-expressed in the newer record shape ([MS-XLS] 2.4.43). */
|
|
67
67
|
const RECORD_CF12 = 2170;
|
|
68
|
+
/** Extends an existing CondFmt-owned rule with icfTemplate/priority metadata a legacy (Excel 97) CF record has no field for -- CF12's counterpart for a rule Excel keeps expressible as a plain formula condition for pre-2007 readers, most notably the containsText family ([MS-XLS] 2.4.63). Read by workbook/conditional-format-ex.ts. */
|
|
69
|
+
const RECORD_CFEX = 2171;
|
|
68
70
|
/** A cell comment's anchor -- row, column, and its own author, linking to the Obj record that names its text ([MS-XLS] 2.4.179). */
|
|
69
71
|
const RECORD_NOTE = 28;
|
|
70
72
|
/** A drawing object's common properties (id, type) and, for a comment, its FtNts sub-structure ([MS-XLS] 2.4.181). */
|
|
71
73
|
const RECORD_OBJ = 93;
|
|
72
74
|
/** The rich text of a text box or comment, its characters and formatting runs carried in trailing Continue records ([MS-XLS] 2.4.329). */
|
|
73
75
|
const RECORD_TXO = 438;
|
|
76
|
+
/** One worksheet's own MS-ODRAW (Escher) drawing bytes, chunked across as many of these records as the drawing needs ([MS-XLS] 2.4.180's sibling "MsoDrawing", https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/1b0b0ea3-5e1d-41ce-8e79-e27f1041331e) -- every MsoDrawing record's own data in one worksheet substream concatenates, in stream order, into one continuous Escher byte stream (src/drawing/escher.ts reads it). */
|
|
77
|
+
const RECORD_MSODRAWING = 236;
|
|
78
|
+
/** The workbook-wide counterpart of MsoDrawing, carrying the drawing group's own shared state -- most importantly the Blip Store (`OfficeArtBStoreContainer`) every worksheet's picture/chart shapes reference by index -- concatenated the same way, but read from the WORKBOOK GLOBALS substream rather than a worksheet's. */
|
|
79
|
+
const RECORD_MSODRAWINGGROUP = 235;
|
|
80
|
+
/** Which Escher shapes a worksheet had selected when it was last saved -- UI state this package has no use for, named here only so a reader that walks every record type in a worksheet substream can recognise and skip it rather than mistake it for drawing bytes. */
|
|
81
|
+
const RECORD_MSODRAWINGSELECTION = 237;
|
|
82
|
+
/** One data series' own type/count header and, following it, its four AI (BRAI) links -- categories, values, bubble sizes, name, each identified by the AI's own `id` field rather than by position ([MS-XLS] "Series"). */
|
|
83
|
+
const RECORD_SERIES = 4099;
|
|
84
|
+
/** A series' cached NAME text, when the file states one as a literal rather than through its own `AI id=0` formula reference ([MS-XLS] "SeriesText"): a ShortXLUnicodeString (one-byte length prefix), unlike the double-byte-length XLUnicodeString most other BIFF8 strings use. */
|
|
85
|
+
const RECORD_SERIESTEXT = 4109;
|
|
86
|
+
/** A data-role link on a series -- name, categories, values, or bubble sizes, selected by the record's own `id` field -- carrying either a literal value/text or a `ChartParsedFormula` range reference this package's own Ptg reference tokens (PtgArea3d/PtgRef3d) can resolve ([MS-XLS] "AI"/BRAI, restricted to a narrower Ptg grammar than a worksheet cell's own Formula record). */
|
|
87
|
+
const RECORD_AI = 4177;
|
|
88
|
+
/** Precedes each of the up-to-three chart-wide cached data blocks (values, categories, bubble sizes) a `SERIESDATA` production carries, its own `numIndex` field naming which of the three follows ([MS-XLS] "SIIndex"). Each cached `Number`/`BoolErr`/`Blank`/`Label` record that follows carries the same `col` field the worksheet cell-record family already does, here reused as the zero-based Series-record index the cached value belongs to. */
|
|
89
|
+
const RECORD_SIINDEX = 4197;
|
|
74
90
|
/** Whether the row and column headers are printed ([MS-XLS] 2.4.203). */
|
|
75
91
|
const RECORD_PRINTROWCOL = 42;
|
|
76
92
|
/** Whether the gridlines are printed ([MS-XLS] 2.4.202). */
|
|
@@ -140,4 +156,4 @@ const BIFF8_VERSION = 1536;
|
|
|
140
156
|
/** [MS-XLS] 2.1.4: "The record size ... MUST be less than or equal to 8224." The ceiling a writer splits a record at, and the bound a reader can sanity-check a declared size against. */
|
|
141
157
|
const MAX_RECORD_DATA_SIZE = 8224;
|
|
142
158
|
//#endregion
|
|
143
|
-
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
|
159
|
+
export { BIFF8_VERSION, BOF_TYPE_CHART, BOF_TYPE_MACRO, BOF_TYPE_WORKBOOK, BOF_TYPE_WORKSHEET, MAX_RECORD_DATA_SIZE, RECORD_AI, RECORD_ARRAY, RECORD_BLANK, RECORD_BOF, RECORD_BOOLERR, RECORD_BOTTOMMARGIN, RECORD_BOUNDSHEET8, RECORD_CALCCOUNT, RECORD_CALCDELTA, RECORD_CALCITER, RECORD_CALCREFMODE, RECORD_CALCSAVERECALC, RECORD_CF, RECORD_CF12, RECORD_CFEX, RECORD_COLINFO, RECORD_CONDFMT, RECORD_CONDFMT12, RECORD_CONTINUE, RECORD_CONTINUEFRT12, RECORD_DATE1904, RECORD_DEFAULTROWHEIGHT, RECORD_DEFCOLWIDTH, RECORD_DIMENSIONS, RECORD_DV, RECORD_DVAL, RECORD_EOF, RECORD_EXTERNSHEET, RECORD_FILELOCK, RECORD_FILEPASS, RECORD_FONT, RECORD_FORMAT, RECORD_FORMULA, RECORD_HORIZONTALPAGEBREAKS, RECORD_INTERFACEHDR, RECORD_LABEL, RECORD_LABELSST, RECORD_LBL, RECORD_LEFTMARGIN, RECORD_MERGECELLS, RECORD_MSODRAWING, RECORD_MSODRAWINGGROUP, RECORD_MSODRAWINGSELECTION, RECORD_MULBLANK, RECORD_MULRK, RECORD_NOTE, RECORD_NUMBER, RECORD_OBJ, RECORD_PALETTE, RECORD_PRINTGRID, RECORD_PRINTROWCOL, RECORD_RIGHTMARGIN, RECORD_RK, RECORD_ROW, RECORD_RRDHEAD, RECORD_RRDINFO, RECORD_SERIES, RECORD_SERIESTEXT, RECORD_SETUP, RECORD_SHRFMLA, RECORD_SIINDEX, RECORD_SST, RECORD_STRING, RECORD_STYLE, RECORD_SUPBOOK, RECORD_TABLE, RECORD_TOPMARGIN, RECORD_TXO, RECORD_USREXCL, RECORD_VERTICALPAGEBREAKS, RECORD_WSBOOL, RECORD_XF };
|
package/dist/biff/strings.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BlockCursor } from "../cursor-
|
|
1
|
+
import { t as BlockCursor } from "../cursor-CnEuX5qE.cjs";
|
|
2
2
|
//#region src/biff/strings.d.ts
|
|
3
3
|
/** An XLUnicodeString ([MS-XLS] 2.5.294): a two-byte character count, a flags byte, then the characters. Continuable, since the String record ([MS-XLS] 2.4.268) carrying a formula's string result is one of these and its own production admits trailing Continues. */
|
|
4
4
|
declare function readXLUnicodeString(cursor: BlockCursor): string;
|
package/dist/biff/strings.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BlockCursor } from "../cursor-
|
|
1
|
+
import { t as BlockCursor } from "../cursor-CnEuX5qE.js";
|
|
2
2
|
//#region src/biff/strings.d.ts
|
|
3
3
|
/** An XLUnicodeString ([MS-XLS] 2.5.294): a two-byte character count, a flags byte, then the characters. Continuable, since the String record ([MS-XLS] 2.4.268) carrying a formula's string result is one of these and its own production admits trailing Continues. */
|
|
4
4
|
declare function readXLUnicodeString(cursor: BlockCursor): string;
|
package/dist/biff/substreams.cjs
CHANGED
|
@@ -34,16 +34,14 @@ function groupRecords(records) {
|
|
|
34
34
|
}
|
|
35
35
|
/** The BOF record's own fixed prefix: a two-byte vers followed by a two-byte dt. */
|
|
36
36
|
const BOF_PREFIX_SIZE = 4;
|
|
37
|
-
/** Splits a grouped record sequence into its substreams, verifying each BOF declares BIFF8. */
|
|
37
|
+
/** Splits a grouped record sequence into its substreams, verifying each BOF declares BIFF8. A BOF met while a substream is already open pushes that substream onto a stack and starts a nested one; the nested substream is closed and reported (via its own EOF) before its parent resumes collecting records -- see this module's own top comment for why a stack, not a flat "BOF ends the previous substream", is what a chart embedded in a worksheet needs. */
|
|
38
38
|
function splitSubstreams(groups) {
|
|
39
39
|
const substreams = [];
|
|
40
|
+
const stack = [];
|
|
40
41
|
let current;
|
|
41
42
|
for (const group of groups) {
|
|
42
43
|
if (group.type === 2057) {
|
|
43
|
-
if (current !== void 0)
|
|
44
|
-
...current,
|
|
45
|
-
index: substreams.length
|
|
46
|
-
});
|
|
44
|
+
if (current !== void 0) stack.push(current);
|
|
47
45
|
current = {
|
|
48
46
|
documentType: readBofDocumentType(group),
|
|
49
47
|
records: [],
|
|
@@ -57,14 +55,15 @@ function splitSubstreams(groups) {
|
|
|
57
55
|
...current,
|
|
58
56
|
index: substreams.length
|
|
59
57
|
});
|
|
60
|
-
current =
|
|
58
|
+
current = stack.pop();
|
|
61
59
|
}
|
|
62
60
|
continue;
|
|
63
61
|
}
|
|
64
62
|
current?.records.push(group);
|
|
65
63
|
}
|
|
66
|
-
if (current !== void 0)
|
|
67
|
-
|
|
64
|
+
if (current !== void 0) stack.push(current);
|
|
65
|
+
for (const open of stack.reverse()) substreams.push({
|
|
66
|
+
...open,
|
|
68
67
|
index: substreams.length
|
|
69
68
|
});
|
|
70
69
|
return substreams;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as splitSubstreams, i as recordByteLength, n as Substream, r as groupRecords, t as RecordGroup } from "../substreams-
|
|
1
|
+
import { a as splitSubstreams, i as recordByteLength, n as Substream, r as groupRecords, t as RecordGroup } from "../substreams-XDNgDvRJ.cjs";
|
|
2
2
|
export { RecordGroup, Substream, groupRecords, recordByteLength, splitSubstreams };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as splitSubstreams, i as recordByteLength, n as Substream, r as groupRecords, t as RecordGroup } from "../substreams-
|
|
1
|
+
import { a as splitSubstreams, i as recordByteLength, n as Substream, r as groupRecords, t as RecordGroup } from "../substreams-CgTHx5kX.js";
|
|
2
2
|
export { RecordGroup, Substream, groupRecords, recordByteLength, splitSubstreams };
|
package/dist/biff/substreams.js
CHANGED
|
@@ -33,16 +33,14 @@ function groupRecords(records) {
|
|
|
33
33
|
}
|
|
34
34
|
/** The BOF record's own fixed prefix: a two-byte vers followed by a two-byte dt. */
|
|
35
35
|
const BOF_PREFIX_SIZE = 4;
|
|
36
|
-
/** Splits a grouped record sequence into its substreams, verifying each BOF declares BIFF8. */
|
|
36
|
+
/** Splits a grouped record sequence into its substreams, verifying each BOF declares BIFF8. A BOF met while a substream is already open pushes that substream onto a stack and starts a nested one; the nested substream is closed and reported (via its own EOF) before its parent resumes collecting records -- see this module's own top comment for why a stack, not a flat "BOF ends the previous substream", is what a chart embedded in a worksheet needs. */
|
|
37
37
|
function splitSubstreams(groups) {
|
|
38
38
|
const substreams = [];
|
|
39
|
+
const stack = [];
|
|
39
40
|
let current;
|
|
40
41
|
for (const group of groups) {
|
|
41
42
|
if (group.type === 2057) {
|
|
42
|
-
if (current !== void 0)
|
|
43
|
-
...current,
|
|
44
|
-
index: substreams.length
|
|
45
|
-
});
|
|
43
|
+
if (current !== void 0) stack.push(current);
|
|
46
44
|
current = {
|
|
47
45
|
documentType: readBofDocumentType(group),
|
|
48
46
|
records: [],
|
|
@@ -56,14 +54,15 @@ function splitSubstreams(groups) {
|
|
|
56
54
|
...current,
|
|
57
55
|
index: substreams.length
|
|
58
56
|
});
|
|
59
|
-
current =
|
|
57
|
+
current = stack.pop();
|
|
60
58
|
}
|
|
61
59
|
continue;
|
|
62
60
|
}
|
|
63
61
|
current?.records.push(group);
|
|
64
62
|
}
|
|
65
|
-
if (current !== void 0)
|
|
66
|
-
|
|
63
|
+
if (current !== void 0) stack.push(current);
|
|
64
|
+
for (const open of stack.reverse()) substreams.push({
|
|
65
|
+
...open,
|
|
67
66
|
index: substreams.length
|
|
68
67
|
});
|
|
69
68
|
return substreams;
|