@sheetxl/query 0.7.28-beta.4 → 0.8.0-beta.2
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/browser/cjs/index.cjs +44 -25
- package/browser/esm/index.mjs +3094 -1131
- package/node/esm/index.mjs +3331 -1334
- package/package.json +3 -3
- package/types/src/Tool.d.ts +38 -0
- package/types/src/api/apiTool.d.ts +22 -0
- package/types/src/api/index.d.ts +4 -0
- package/types/src/api/lookupApi.d.ts +127 -0
- package/types/src/api/renderApi.d.ts +13 -0
- package/types/src/grep/GrepTypes.d.ts +75 -17
- package/types/src/grep/grep.d.ts +4 -1
- package/types/src/index.d.ts +9 -0
- package/types/src/markdown/appendDependencies.d.ts +106 -0
- package/types/src/markdown/appendPivotTables.d.ts +22 -0
- package/types/src/markdown/appendSections.d.ts +37 -108
- package/types/src/markdown/describeChart.d.ts +72 -0
- package/types/src/markdown/describeHistogram.d.ts +186 -0
- package/types/src/markdown/describeRegionPayload.d.ts +1 -1
- package/types/src/markdown/findLabels.d.ts +26 -0
- package/types/src/markdown/index.d.ts +3 -0
- package/types/src/markdown/profileRegion.d.ts +56 -1
- package/types/src/markdown/registry.d.ts +11 -2
- package/types/src/markdown/renderCell.d.ts +13 -11
- package/types/src/markdown/renderCellRange.d.ts +3 -2
- package/types/src/markdown/renderModules.d.ts +55 -0
- package/types/src/markdown/renderMovable.d.ts +69 -13
- package/types/src/markdown/renderNames.d.ts +2 -2
- package/types/src/markdown/renderProtection.d.ts +81 -0
- package/types/src/markdown/renderRegions.d.ts +1 -0
- package/types/src/markdown/renderSheet.d.ts +6 -7
- package/types/src/markdown/renderTable.d.ts +11 -3
- package/types/src/markdown/renderWorkbook.d.ts +33 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ICellRange, IAnchored, ICellRanges, INamed } from '@sheetxl/sdk';
|
|
1
|
+
import { ICellRange, IAnchored, ICellRanges, ICellRegion, INamed } from '@sheetxl/sdk';
|
|
2
2
|
import { MarkdownBuilder } from './MarkdownBuilder';
|
|
3
3
|
/**
|
|
4
4
|
* Options for the feature sections.
|
|
@@ -13,7 +13,7 @@ export interface AppendFeatureOptions {
|
|
|
13
13
|
* A **reporting** filter, not a query one. Partitioning by feature is what
|
|
14
14
|
* {@link ICellRange.getRegions} is for and this does not duplicate it — it decides which of
|
|
15
15
|
* those partitions a report bothers to print, which is why it lives on the renderer and not on
|
|
16
|
-
* the range. `--features fill,
|
|
16
|
+
* the range. `--features fill,borders` on a sheet with forty formatted regions is the
|
|
17
17
|
* difference between an answer and a haystack.
|
|
18
18
|
*
|
|
19
19
|
* The scalar kinds are accepted and reach `Counts`; they have no partition to list, so they
|
|
@@ -69,7 +69,7 @@ export interface AppendFeatureOptions {
|
|
|
69
69
|
*/
|
|
70
70
|
export declare const REPORTED_FEATURES: readonly ICellRange.Feature[];
|
|
71
71
|
/**
|
|
72
|
-
* Parses a comma-separated feature list — the `--features fill,
|
|
72
|
+
* Parses a comma-separated feature list — the `--features fill,borders` flag's value.
|
|
73
73
|
*
|
|
74
74
|
* @remarks
|
|
75
75
|
* Matching is case-insensitive against the enum's values, so `Fill`, `fill` and `numberFormat`
|
|
@@ -118,26 +118,12 @@ export declare const describeQualifiedExtent: (range: ICellRange) => string;
|
|
|
118
118
|
* Appends the `Kind` section — what the contentful cells ARE, kind by kind.
|
|
119
119
|
*
|
|
120
120
|
* @remarks
|
|
121
|
-
* The heading carries the contentful count; the
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* numbers".
|
|
121
|
+
* The heading carries the contentful count; the lines are the census, largest first, and they
|
|
122
|
+
* sum to it — see {@link countKinds}, which the workbook's `content` row reads too, so a sheet is
|
|
123
|
+
* described in the same words and the same numbers at both altitudes. Features are not here: each
|
|
124
|
+
* has a partition to list, and carries its cell count on its own section heading.
|
|
126
125
|
*
|
|
127
|
-
*
|
|
128
|
-
* `profileKinds` already read — rather than `getCounts()`: `getCounts([Feature.Number, ...])` is a
|
|
129
|
-
* SECOND, independent value-scan inside the engine (`Sheet._featureCounts`'s own comment says so
|
|
130
|
-
* — "the scalar kinds ... count from values in one pass"), answering the identical question. One
|
|
131
|
-
* scan, one source of truth, and `RichData` is no longer a silent zero — it falls out of the same
|
|
132
|
-
* typed counts for free, where the old `Feature`-keyed list had nowhere to carry it (`Feature` has
|
|
133
|
-
* no `RichData` member).
|
|
134
|
-
*
|
|
135
|
-
* `Date` is the one line still read through a dedicated pass — `countDates`, a value scan via
|
|
136
|
-
* `getInteropType()`. It is not a `ScalarType` at all — it is numeric value ∩ date-category
|
|
137
|
-
* format — and `Feature.DateFormat` alone would overcount (a blank or text cell carrying that
|
|
138
|
-
* format is not a date). A date cell counts as both `Number` and `Date`, so the lines need not
|
|
139
|
-
* sum to the heading. Zero kinds are elided, and blanks appear nowhere — empty is not a kind of
|
|
140
|
-
* content.
|
|
126
|
+
* Zero kinds are elided, and blanks appear nowhere — empty is not a kind of content.
|
|
141
127
|
*/
|
|
142
128
|
export declare function appendKinds(md: MarkdownBuilder, range: ICellRange): void;
|
|
143
129
|
/**
|
|
@@ -161,6 +147,21 @@ export declare function appendKinds(md: MarkdownBuilder, range: ICellRange): voi
|
|
|
161
147
|
* sees which before paying for a drill.
|
|
162
148
|
*/
|
|
163
149
|
export declare function appendRegions(md: MarkdownBuilder, range: ICellRange, options?: AppendFeatureOptions): void;
|
|
150
|
+
/**
|
|
151
|
+
* The blocks of content in `range` — occupancy, cut where an authored table begins and ends.
|
|
152
|
+
*
|
|
153
|
+
* @remarks
|
|
154
|
+
* Occupancy alone yields maximal SOLID rectangles, and a table is not one: a title sitting over
|
|
155
|
+
* its first column makes that column run one cell longer than the rest, so the table came back as
|
|
156
|
+
* `C3:J111` plus a `B2:B111` list — two blocks, neither of them the table, at a size the `Tables`
|
|
157
|
+
* section contradicts. A table's edge is a boundary its author drew, so the partition honors it:
|
|
158
|
+
* the table is one block, at its own extent, and the title is a 1×1 above it.
|
|
159
|
+
*
|
|
160
|
+
* Refinement only ever cuts at a table's edge, so a sheet with no tables partitions exactly as
|
|
161
|
+
* occupancy does. A refined partition yields every region carrying EITHER feature, so a blank cell
|
|
162
|
+
* inside a table comes back too; a region is uniform, which makes its anchor the test.
|
|
163
|
+
*/
|
|
164
|
+
export declare const contentfulBlocks: (range: ICellRange) => ICellRegion[];
|
|
164
165
|
/**
|
|
165
166
|
* Options for {@link appendNames}.
|
|
166
167
|
*/
|
|
@@ -246,91 +247,7 @@ export declare const describeQualifiedName: (named: INamed) => string;
|
|
|
246
247
|
* `Hidden` and `Comment` appear only when some row has one — per block. `false` on every visible
|
|
247
248
|
* row is token noise, and blank-means-normal is how these reports already speak.
|
|
248
249
|
*/
|
|
249
|
-
export declare function appendNames(md: MarkdownBuilder, names: readonly INamed[], options?: AppendNamesOptions): void
|
|
250
|
-
/**
|
|
251
|
-
* Options for the dependency trees.
|
|
252
|
-
*/
|
|
253
|
-
export interface AppendDependencyOptions {
|
|
254
|
-
/**
|
|
255
|
-
* How many hops from the subject to walk.
|
|
256
|
-
*
|
|
257
|
-
* @defaultValue 3
|
|
258
|
-
*/
|
|
259
|
-
maxDepth?: number;
|
|
260
|
-
/**
|
|
261
|
-
* Cap on nodes per tree; the tree notes truncation when exceeded.
|
|
262
|
-
*
|
|
263
|
-
* @defaultValue 50
|
|
264
|
-
*/
|
|
265
|
-
maxNodes?: number;
|
|
266
|
-
}
|
|
267
|
-
/** The calculation-graph surface shared by {@link ICell} and {@link ICellRange}. */
|
|
268
|
-
export interface DependencySource {
|
|
269
|
-
getDirectPrecedents(): ICellRanges | null;
|
|
270
|
-
getPrecedents(): ICellRanges | null;
|
|
271
|
-
getDirectDependents(): ICellRanges | null;
|
|
272
|
-
getDependents(): ICellRanges | null;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Appends the `Precedents` and `Dependents` trees for anything that exposes the calculation
|
|
276
|
-
* graph — a cell or a range, which answer the same questions with the same shape.
|
|
277
|
-
*
|
|
278
|
-
* @remarks
|
|
279
|
-
* **A tree, walked one hop at a time, rather than a `direct`/`all` pair.** The flat form gives
|
|
280
|
-
* the two ends of the chain and throws away everything between them: `D6` reading `B2:D4`
|
|
281
|
-
* "eventually" does not say whether that is one indirection or nine, and the shape is the thing a
|
|
282
|
-
* reader is actually trying to see. Repeated `getDirect*` calls cost the same as one `getAll*`
|
|
283
|
-
* — the graph is indexed either way — so the tree is strictly more answer for the same work.
|
|
284
|
-
*
|
|
285
|
-
* Each node carries its **payload at the right altitude**: a single cell shows its value, a
|
|
286
|
-
* multi-cell range shows its size. A range node is not expanded into cells; that is the same
|
|
287
|
-
* expansion the region rules exist to prevent.
|
|
288
|
-
*
|
|
289
|
-
* Bounded three ways, each stated in the output rather than applied silently — depth, node count,
|
|
290
|
-
* and revisits.
|
|
291
|
-
*
|
|
292
|
-
* **The two kinds of revisit get different marks, and that distinction is the point.** A node
|
|
293
|
-
* reached twice by different branches is a re-convergence: completely normal in any model, and
|
|
294
|
-
* marked `↑ shown above`. A node reached again while it is still on the current path is a
|
|
295
|
-
* genuine cycle — a defect, or a deliberate iterative calculation — and is marked `↺ circular`.
|
|
296
|
-
* One glyph for both would bury the second inside a busy tree, and it is the one finding here
|
|
297
|
-
* that cannot afford to be missed.
|
|
298
|
-
*/
|
|
299
|
-
export declare function appendDependencies(md: MarkdownBuilder, target: DependencySource, options?: AppendDependencyOptions): void;
|
|
300
|
-
/**
|
|
301
|
-
* How a graph member LABELS itself: its address, the sheet it lives on, and whether it is a name.
|
|
302
|
-
*
|
|
303
|
-
* @remarks
|
|
304
|
-
* Shared by the tree and the flat {@link ICellRanges} listing, so the two cannot label the same
|
|
305
|
-
* member differently — the flat list is the tree's rows without the hop structure, and a reader
|
|
306
|
-
* comparing them is comparing the same text.
|
|
307
|
-
*
|
|
308
|
-
* A name member leads with its NAME: its address is only an anchor, and two names authored from
|
|
309
|
-
* the same cell would otherwise print as identical, anonymous cells.
|
|
310
|
-
*
|
|
311
|
-
* The address comes back **unqualified**. A listing standing on one sheet says so once, in its
|
|
312
|
-
* heading; a qualifier goes back on every row only when the collection spans sheets, which is the
|
|
313
|
-
* caller's decision because only the caller has seen every member. A trailing `!` is `#REF!`, not
|
|
314
|
-
* a qualifier, so it is left whole.
|
|
315
|
-
*/
|
|
316
|
-
export declare function describeNodeLabel(range: ICellRange): {
|
|
317
|
-
address: string;
|
|
318
|
-
sheet: string;
|
|
319
|
-
isName: boolean;
|
|
320
|
-
};
|
|
321
|
-
/**
|
|
322
|
-
* A node's payload: the value for a single cell, the size for a range.
|
|
323
|
-
*
|
|
324
|
-
* @remarks
|
|
325
|
-
* The whole point of walking as a tree rather than listing addresses — `1,204,880` beside
|
|
326
|
-
* `Model!O30` is what makes the chain readable as a model rather than as a set of coordinates.
|
|
327
|
-
* A formula node shows its expression too, because at that point the node explains itself.
|
|
328
|
-
*
|
|
329
|
-
* Shared with the flat {@link ICellRanges} listing (`renderRanges`) for the same reason
|
|
330
|
-
* {@link describeNodeLabel} is: the flat list is these rows without the hop structure, so the two
|
|
331
|
-
* shapes cannot be allowed to drift into describing one member two ways.
|
|
332
|
-
*/
|
|
333
|
-
export declare function describeNode(range: ICellRange): string;
|
|
250
|
+
export declare function appendNames(md: MarkdownBuilder, names: readonly INamed[], options?: AppendNamesOptions): Promise<void>;
|
|
334
251
|
/**
|
|
335
252
|
* One rule listing — `## Conditional Formats (2)` over ` A1:D10 > 100 → fill #FFFF00` rows.
|
|
336
253
|
*
|
|
@@ -346,6 +263,18 @@ export declare function describeNode(range: ICellRange): string;
|
|
|
346
263
|
* listing would hide the very relationship `stop if true` is read against.
|
|
347
264
|
*/
|
|
348
265
|
export declare function appendRules<T extends IAnchored>(md: MarkdownBuilder, heading: string, items: readonly T[], describe: (item: T) => string): void;
|
|
266
|
+
/**
|
|
267
|
+
* The defined names whose target region intersects `range`, in collection order.
|
|
268
|
+
*
|
|
269
|
+
* @remarks
|
|
270
|
+
* Scope-checked, not merely rectangle-checked: a name pointing at `Sheet2!A1:D4` overlaps this
|
|
271
|
+
* sheet's `A1:D4` as coordinates and is a different region entirely. Defined names only — a
|
|
272
|
+
* table's name has its own section.
|
|
273
|
+
*
|
|
274
|
+
* @param includeOwned Also admit this sheet's private names that designate no region
|
|
275
|
+
* (`TaxRate = 0.21`), which have nothing to intersect and belong to the sheet by ownership.
|
|
276
|
+
*/
|
|
277
|
+
export declare function findNames(range: ICellRange, includeOwned?: boolean): INamed[];
|
|
349
278
|
/**
|
|
350
279
|
* Appends the sheet-level objects that intersect `range`: named ranges, hidden headers, tables,
|
|
351
280
|
* conditional formats and data validations.
|
|
@@ -360,5 +289,5 @@ export declare function appendRules<T extends IAnchored>(md: MarkdownBuilder, he
|
|
|
360
289
|
* token cost on the common path, and it buries the sections that do carry something. Absence is
|
|
361
290
|
* already how these reports say "not here".
|
|
362
291
|
*/
|
|
363
|
-
export declare function appendSheetObjects(md: MarkdownBuilder, range: ICellRange): void
|
|
292
|
+
export declare function appendSheetObjects(md: MarkdownBuilder, range: ICellRange): Promise<void>;
|
|
364
293
|
//# sourceMappingURL=appendSections.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ISheet, ICellRange, ICellRanges, IChart, IMovable } from '@sheetxl/sdk';
|
|
2
|
+
import { MarkdownBuilder } from './MarkdownBuilder';
|
|
3
|
+
/** The chart a movable holds, or `null` for any other content. */
|
|
4
|
+
export declare const chartOf: (movable: IMovable) => IChart | null;
|
|
5
|
+
/**
|
|
6
|
+
* `line · 8 series · values NOI!C4:J111 · categories NOI!B4:B111` — a chart as one listing row's
|
|
7
|
+
* prose, or `null` when nothing about it is known.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* What the chart PLOTS leads, because it is the fact that ties the floating layer to the cells: it
|
|
11
|
+
* says which ranges the author treats as the output, and it is what breaks when the sheet under
|
|
12
|
+
* it is restructured. Series that do not collapse to one block are counted here and listed on the
|
|
13
|
+
* chart's own report.
|
|
14
|
+
*
|
|
15
|
+
* Each range is labeled with its role. `A by B` read as a formula to anyone who did not already
|
|
16
|
+
* know the convention, and `by` is the word the series line uses for orientation (`by column`).
|
|
17
|
+
*/
|
|
18
|
+
export declare function describeChartRow(chart: IChart): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* A chart's facts as `label`/`value` pairs — the lines a `Charts` section indents under its row,
|
|
21
|
+
* the way a `Tables` section does.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* The type is not here: it is the row's own column. Series that do not tile are counted, and
|
|
25
|
+
* listed one by one on the chart's own report.
|
|
26
|
+
*/
|
|
27
|
+
export declare function describeChartDetails(chart: IChart): [label: string, value: string][];
|
|
28
|
+
/** `line`, for the type column of a `Charts` row; `''` where the model has no answer. */
|
|
29
|
+
export declare const describeChartType: (chart: IChart) => string;
|
|
30
|
+
/**
|
|
31
|
+
* The `Type` / `Title` / `Series` / `Axes` facts of a chart's own report.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* `Title: (none)` is printed rather than omitted: that a chart is untitled is information, and a
|
|
35
|
+
* reader asked to tidy a model wants it. An axis with no title says so for the same reason — axis
|
|
36
|
+
* titles are where a chart states its units, often the only place anything does.
|
|
37
|
+
*/
|
|
38
|
+
export declare function appendChartFacts(md: MarkdownBuilder, chart: IChart): void;
|
|
39
|
+
/** A series reference that no longer names cells. */
|
|
40
|
+
export interface BrokenChartReference {
|
|
41
|
+
movable: IMovable;
|
|
42
|
+
/** `series "South" values Data!#REF!` */
|
|
43
|
+
detail: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Every series on `sheet` whose name, values or categories reference is `#REF!`.
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* A broken series reference is an audit finding exactly like one in a formula — the chart has
|
|
50
|
+
* stopped plotting what its author pointed it at — and no cell carries it, so no cell scan finds it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function collectBrokenChartReferences(sheet: ISheet): BrokenChartReference[];
|
|
53
|
+
/** A chart that plots the subject of a report, or something computed from it. */
|
|
54
|
+
export interface ChartReader {
|
|
55
|
+
movable: IMovable;
|
|
56
|
+
/** `true` when a series names the subject's own cells; `false` when it names cells that depend on them. */
|
|
57
|
+
direct: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The charts that read `subject`, or that read what depends on it.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* A chart is a dependent the calculation graph does not hold: it reads cells and is changed by
|
|
64
|
+
* them, and nothing recalculates it. For "what else moves if I write here" it belongs in the same
|
|
65
|
+
* answer, so this is the graph's dependents carried one step further — into the floating layer.
|
|
66
|
+
*
|
|
67
|
+
* @param dependents The subject's full downstream reach, as the graph answers it.
|
|
68
|
+
*/
|
|
69
|
+
export declare function findChartReaders(subject: ICellRange, dependents: ICellRanges | null): ChartReader[];
|
|
70
|
+
/** `Charts!B2:H15 "Chart 1"`, marked when the chart reads the subject only through its dependents. */
|
|
71
|
+
export declare const describeChartReader: (reader: ChartReader) => string;
|
|
72
|
+
//# sourceMappingURL=describeChart.d.ts.map
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { ICellRange, ICellRegion, IRange, ISheet, IStyle } from '@sheetxl/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Per-attribute histograms for the style feature sections.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* A style partition lists blocks; a reader wants **conventions**: which colors mean input, how
|
|
7
|
+
* many fonts there are, whether one cell is formatted differently from its row. A histogram per
|
|
8
|
+
* *attribute* answers that on one line each — `color blue ×216 · white ×18 · #0070C0 ×1 R13` — and
|
|
9
|
+
* degrades to a count when there is no convention to find.
|
|
10
|
+
*
|
|
11
|
+
* Pipeline, per feature: **project** each region's authored style onto one attribute → **coalesce**
|
|
12
|
+
* adjacent rectangles with the same projected value (a region is uniform in the whole feature,
|
|
13
|
+
* so `bold 10pt` and `10pt` are two regions with one family) → **promote** whole-column and
|
|
14
|
+
* whole-row rectangles to their own tiers, the way the file format does, so a column style is
|
|
15
|
+
* named once instead of counted as a million cells → **histogram** the cell tier.
|
|
16
|
+
*
|
|
17
|
+
* Every count is cells, never blocks. Content cells lead — the intersection with the
|
|
18
|
+
* `Contentful` partition — and the styled cells that hold nothing follow in parentheses, so a
|
|
19
|
+
* format over empty cells (`Currency 0dp ×0 (+1 blank) K2`) is stated rather than hidden. A value that lives
|
|
20
|
+
* in one block prints its address whatever its size; a scattered one prints its largest block
|
|
21
|
+
* and how many more.
|
|
22
|
+
*
|
|
23
|
+
* **Only authored differences are histogrammed.** An attribute equal to the workbook's `Normal`
|
|
24
|
+
* style is not a choice anyone made — every cell has *some* family — so it does not appear; the
|
|
25
|
+
* base itself is stated once, on the `normal` line, which is where "Calibri is the base" comes
|
|
26
|
+
* from without any clustering.
|
|
27
|
+
*/
|
|
28
|
+
/** A rectangle in sheet coordinates, closed on both ends. */
|
|
29
|
+
type Rect = Readonly<IRange.Coords>;
|
|
30
|
+
/**
|
|
31
|
+
* Merges adjacent rectangles that share a key into maximal rectangles.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Greedy: a column pass joins horizontal neighbors with equal row extents, a row pass joins
|
|
35
|
+
* vertical neighbors with equal column extents, repeated until nothing merges. Not guaranteed
|
|
36
|
+
* minimal, but the input is already a partition (no overlaps), the count is blocks not cells, and
|
|
37
|
+
* the store's own seams are exactly the horizontal-then-vertical cuts this undoes.
|
|
38
|
+
*/
|
|
39
|
+
export declare function coalesceRects<T extends Rect & {
|
|
40
|
+
key: string;
|
|
41
|
+
}>(rects: readonly T[]): T[];
|
|
42
|
+
/** One value of one attribute: where it is and how much of it there is. */
|
|
43
|
+
export interface HistogramEntry {
|
|
44
|
+
/** Display form of the value. */
|
|
45
|
+
label: string;
|
|
46
|
+
/** Cells carrying the value that also hold content. */
|
|
47
|
+
content: number;
|
|
48
|
+
/** All cells carrying the value (cell tier only — never a whole column). */
|
|
49
|
+
styled: number;
|
|
50
|
+
/** The value's blocks, largest first. */
|
|
51
|
+
blocks: readonly Rect[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Options for {@link describeHistogramLine}.
|
|
55
|
+
*/
|
|
56
|
+
export interface HistogramLineOptions {
|
|
57
|
+
/** Values printed in full before the line degrades to a count. @defaultValue 8 */
|
|
58
|
+
maxValues?: number;
|
|
59
|
+
/** Above this many distinct values the line leads with the count, not the values. @defaultValue 20 */
|
|
60
|
+
manyDistinct?: number;
|
|
61
|
+
/** How to get the rest — appended after `+n more`. */
|
|
62
|
+
recovery?: string;
|
|
63
|
+
/**
|
|
64
|
+
* A label to leave off the line — the attribute's own name, for a boolean attribute whose
|
|
65
|
+
* value IS its name (`bold 87` rather than `bold bold 87`).
|
|
66
|
+
*/
|
|
67
|
+
hideLabel?: string;
|
|
68
|
+
/**
|
|
69
|
+
* How a count reads: `cells` (`blue ×216 (+105 blank)` — content cells, then the styled cells
|
|
70
|
+
* holding nothing) for a style attribute, `times` (`2.5 ×4`) for a value, whose count is
|
|
71
|
+
* occurrences and has no second figure.
|
|
72
|
+
*
|
|
73
|
+
* @defaultValue `'cells'`
|
|
74
|
+
*/
|
|
75
|
+
countStyle?: 'cells' | 'times';
|
|
76
|
+
}
|
|
77
|
+
/** Width of the attribute-name column; every line of a histogram section aligns on it. */
|
|
78
|
+
export declare const HISTOGRAM_LABEL_WIDTH = 10;
|
|
79
|
+
/**
|
|
80
|
+
* One histogram line — the values of one attribute, most common first, degrading to a count.
|
|
81
|
+
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* The flood rule, stated once for every histogram (style attributes, formulas, values):
|
|
84
|
+
*
|
|
85
|
+
* 1. Up to `maxValues` distinct values print in full, sorted by content cells (then styled).
|
|
86
|
+
* 2. Beyond that, the top half of the budget prints, then the **rarest values that hold
|
|
87
|
+
* content** — a one-off format on a data cell is the finding, and a sort by count alone
|
|
88
|
+
* would bury it — then `+n more` with the call that lists everything.
|
|
89
|
+
* 3. Beyond `manyDistinct`, the line leads with the count and says **no convention** when the
|
|
90
|
+
* most common value does not even cover half the content: a random-color sheet is described
|
|
91
|
+
* by its count, not by a sample of its colors, and it costs one line however many there are.
|
|
92
|
+
*/
|
|
93
|
+
export declare function describeHistogramLine(entries: readonly HistogramEntry[], options?: HistogramLineOptions): string;
|
|
94
|
+
/**
|
|
95
|
+
* `Accounting 1dp` — the dialog category plus its decimals, so ten spellings of one intent read
|
|
96
|
+
* as one value. `General` is the absence of a format and contributes nothing.
|
|
97
|
+
*/
|
|
98
|
+
export declare function describeNumberFormatCategory(code: string | null | undefined): string | null;
|
|
99
|
+
/** Whether a feature gets a histogram. */
|
|
100
|
+
export declare const hasStyleHistogram: (feature: ICellRange.Feature) => boolean;
|
|
101
|
+
/**
|
|
102
|
+
* One feature's histogram: the tier lines and one line per attribute, ready to append.
|
|
103
|
+
*/
|
|
104
|
+
export interface StyleHistogram {
|
|
105
|
+
/** Distinct authored payloads across every region of the feature. */
|
|
106
|
+
distinct: number;
|
|
107
|
+
/**
|
|
108
|
+
* Styled cells in the cell tier, inside the used range — the finite number a heading can
|
|
109
|
+
* carry. The column and row tiers are named on their own lines, never counted.
|
|
110
|
+
*/
|
|
111
|
+
cells: number;
|
|
112
|
+
/** `normal Arial Narrow · 11pt · #000000` — what `Normal` says about this feature; see {@link describeNormal}. */
|
|
113
|
+
normal: string | null;
|
|
114
|
+
/** `sheet` / `columns` / `rows` tier lines, each `label runs payload`. */
|
|
115
|
+
tiers: string[];
|
|
116
|
+
/**
|
|
117
|
+
* `family Open Sans ×355 (+230 blank) B14:M25, +38 blocks · …`, one per attribute with a value —
|
|
118
|
+
* or, for number formats, one row per category (see `describeNumberFormatRows`).
|
|
119
|
+
*/
|
|
120
|
+
attributes: string[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Builds the histogram for a style feature over a whole sheet.
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* Reads the sheet's **entire** partition rather than the used range's, because a column style
|
|
127
|
+
* is only recognizable unclipped: the used-range view cuts `O:Q` to `O1:Q43` and it looks like a
|
|
128
|
+
* block. Cell counts are then taken inside the used range, where finite numbers live.
|
|
129
|
+
*/
|
|
130
|
+
export declare function describeStyleHistogram(sheet: ISheet, feature: ICellRange.Feature, normal: IStyle | null, options?: HistogramLineOptions & {
|
|
131
|
+
/** The sheet's contentful rectangles, when the caller already has them (one partition serves every feature). */
|
|
132
|
+
content?: readonly IRange.Coords[];
|
|
133
|
+
}): StyleHistogram | null;
|
|
134
|
+
/** The formula section's histogram lines. */
|
|
135
|
+
export interface FormulaHistogram {
|
|
136
|
+
/** Distinct formulas by R1C1 text — `=SUM(B5:B7)` and `=SUM(C5:C7)` are one. */
|
|
137
|
+
distinct: number;
|
|
138
|
+
/** `distinct =R[-3]C-R[-1]C ×26 B11:N11, +1 block · …` and `functions SUM ×44 · no function ×52`. */
|
|
139
|
+
lines: string[];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Builds the formula section's histograms from its partition.
|
|
143
|
+
*
|
|
144
|
+
* @remarks
|
|
145
|
+
* The partition already groups by R1C1 — a region IS one formula filled across cells — so the
|
|
146
|
+
* `distinct` line is the partition re-keyed: the same R1C1 in several regions (a total column
|
|
147
|
+
* split by blank rows) is one value with several blocks. A one-off R1C1 in a row of thirteen is
|
|
148
|
+
* the H26 finding, printed with its address. `functions` counts cells, not regions, so `SUM ×44`
|
|
149
|
+
* is how many cells sum; `no function` is arithmetic-only cells — on a P&L that is most of them.
|
|
150
|
+
*
|
|
151
|
+
* `most complex` is deliberately absent: by function count every formula on a typical model ties
|
|
152
|
+
* at one, and a tie printed as a superlative is a lie. It arrives with the precedents depth.
|
|
153
|
+
*/
|
|
154
|
+
export declare function describeFormulaHistogram(regions: readonly ICellRegion[], options?: HistogramLineOptions): FormulaHistogram | null;
|
|
155
|
+
/**
|
|
156
|
+
* The kind census of `range` — `number 864 · date 108 · text 10` — largest first.
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* **Disjoint, so the counts sum to the contentful cells.** Every cell is counted under exactly
|
|
160
|
+
* one kind, which is what lets a reader check the census against the heading above it; a census
|
|
161
|
+
* whose lines overlap cannot be told from one that is wrong.
|
|
162
|
+
*
|
|
163
|
+
* A formula cell's value is a number or a string too, so the typed counts alone say `number 313`
|
|
164
|
+
* where 96 of those are computed; the reader wants how much was TYPED (the inputs) against how
|
|
165
|
+
* much is formula (the model). Formula cells are counted once, under `formula`, and their values
|
|
166
|
+
* are subtracted from the typed kinds — read off the formula partition's own stats.
|
|
167
|
+
*
|
|
168
|
+
* `date` is carved out of `number` the same way: a date IS a number, under a date-category format,
|
|
169
|
+
* and a column of them is a time axis — the one fact about a block of numbers that changes how
|
|
170
|
+
* every other column in it is read.
|
|
171
|
+
*/
|
|
172
|
+
export declare function countKinds(range: ICellRange, formulaRegions: readonly ICellRegion[]): [label: string, count: number][];
|
|
173
|
+
/** The census as one row's prose: `number ×217 · formula ×96 · text ×45`, or `null` when empty. */
|
|
174
|
+
export declare function describeKinds(range: ICellRange, formulaRegions: readonly ICellRegion[]): string | null;
|
|
175
|
+
/**
|
|
176
|
+
* What the workbook's `Normal` style says about `feature`, or `null` when it says nothing.
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* **The style of every cell no section lists.** A font always has one — and the font lines are
|
|
180
|
+
* differences from it, so it is always stated. For the rest `Normal` is nearly always empty, and
|
|
181
|
+
* then there is no line; but a `Normal` that carries a fill or a number format paints every
|
|
182
|
+
* untouched cell in the book, and no region reports it, because nobody authored it on a cell.
|
|
183
|
+
*/
|
|
184
|
+
export declare function describeNormal(feature: ICellRange.Feature, normal: IStyle): string | null;
|
|
185
|
+
export {};
|
|
186
|
+
//# sourceMappingURL=describeHistogram.d.ts.map
|
|
@@ -38,7 +38,7 @@ export declare function regionPayload(feature: ICellRange.Feature, normal: IStyl
|
|
|
38
38
|
* payload and they join in the order the caller named them, so the row reads as the tuple the
|
|
39
39
|
* partition actually splits on.
|
|
40
40
|
*
|
|
41
|
-
* Features with nothing to say per region (`AutoTable
|
|
41
|
+
* Features with nothing to say per region (`AutoTable`) contribute nothing rather than
|
|
42
42
|
* an empty column, and a partition where none of them do returns `undefined` so the listing stays
|
|
43
43
|
* addresses-only.
|
|
44
44
|
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IRange, ISheet } from '@sheetxl/sdk';
|
|
2
|
+
/** A label and where it was read from. */
|
|
3
|
+
export interface FoundLabel {
|
|
4
|
+
text: string;
|
|
5
|
+
address: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The text that labels a cell's row (`'row'`) or column (`'column'`).
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Deterministic, and the address is always returned so a reader can judge it:
|
|
12
|
+
*
|
|
13
|
+
* 1. The first cell of the line within the cell's current region (Ctrl+Shift+*), when it is text —
|
|
14
|
+
* the row label at the left edge of the block, the header at its top.
|
|
15
|
+
* 2. Otherwise the nearest text cell before the cell on that line — leftward for a row, upward for
|
|
16
|
+
* a column. Only contentful cells are visited, so the walk costs the populated cells between,
|
|
17
|
+
* not the distance; there is no cap, because a cap is only a different arbitrary answer.
|
|
18
|
+
*
|
|
19
|
+
* `null` when the cell is itself the first cell of the line or nothing before it is text.
|
|
20
|
+
*/
|
|
21
|
+
export declare function findLabel(sheet: ISheet, cell: IRange.CellCoords, axis: 'row' | 'column'): FoundLabel | null;
|
|
22
|
+
/** `"JUN" (G4)` — a label as the reports print it. */
|
|
23
|
+
export declare const describeLabel: (label: FoundLabel | null) => string | null;
|
|
24
|
+
/** 0-based column index to its A1 letter. */
|
|
25
|
+
export declare function columnLetter(index: number): string;
|
|
26
|
+
//# sourceMappingURL=findLabels.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './appendDependencies';
|
|
1
2
|
export * from './appendSections';
|
|
2
3
|
export * from './describeRegionPayload';
|
|
3
4
|
export * from './describeRule';
|
|
@@ -11,8 +12,10 @@ export * from './renderConditionalFormat';
|
|
|
11
12
|
export * from './renderCounts';
|
|
12
13
|
export * from './renderDataValidation';
|
|
13
14
|
export * from './renderFormula';
|
|
15
|
+
export * from './renderModules';
|
|
14
16
|
export * from './renderMovable';
|
|
15
17
|
export * from './renderNames';
|
|
18
|
+
export * from './renderProtection';
|
|
16
19
|
export * from './renderRecords';
|
|
17
20
|
export * from './renderRanges';
|
|
18
21
|
export * from './renderRegions';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ICellRange, ICellRegion } from '@sheetxl/sdk';
|
|
2
|
+
import { FoundLabel } from './findLabels';
|
|
2
3
|
/**
|
|
3
4
|
* What {@link profileRegion} needs to read — the anchor cell and the extent, nothing a partition
|
|
4
5
|
* knows that a plain range does not.
|
|
@@ -48,6 +49,10 @@ export interface ProfileRegionOptions {
|
|
|
48
49
|
* exactly one, and a block has one per column (or row). This is the same discipline that keeps a
|
|
49
50
|
* range from rendering cell facets — bounded by construction rather than by a limit that has to
|
|
50
51
|
* fire.
|
|
52
|
+
*
|
|
53
|
+
* Data for a caller, never printed: a listing row already carries the size (`1×1`, `110×1`) and
|
|
54
|
+
* the header note, so a shape word beside them is a second vocabulary for the same fact — and
|
|
55
|
+
* `table` has to stay free to mean an authored {@link ITable}.
|
|
51
56
|
*/
|
|
52
57
|
export type RegionShape = 'cell' | 'list' | 'table' | 'block';
|
|
53
58
|
/**
|
|
@@ -58,7 +63,7 @@ export type RegionShape = 'cell' | 'list' | 'table' | 'block';
|
|
|
58
63
|
*/
|
|
59
64
|
export interface RegionProfile {
|
|
60
65
|
shape: RegionShape;
|
|
61
|
-
/** The one-line description that sits beside the address — `
|
|
66
|
+
/** The one-line description that sits beside the address — `header row 1`, or a 1×1's value. */
|
|
62
67
|
summary: string;
|
|
63
68
|
/** One line per column (or row); empty for `cell` and `list`, whose profile is in `summary`. */
|
|
64
69
|
series: string[];
|
|
@@ -88,6 +93,56 @@ export interface RegionProfile {
|
|
|
88
93
|
* elision is explicit, per the same rule that governs every truncated listing here.
|
|
89
94
|
*/
|
|
90
95
|
export declare function profileRegion(region: ProfileSource, options?: ProfileRegionOptions): RegionProfile;
|
|
96
|
+
/** A line the stats leave out, and why. */
|
|
97
|
+
export interface TotalsLine {
|
|
98
|
+
/** Absolute row (or column, on a block profiled by row). */
|
|
99
|
+
index: number;
|
|
100
|
+
label: FoundLabel | null;
|
|
101
|
+
/** Set on the first line only when it was found by value: how it compares with the Σ above it. */
|
|
102
|
+
sums?: TotalsSums;
|
|
103
|
+
}
|
|
104
|
+
/** How a totals line's values compare with the sums of the body above them. */
|
|
105
|
+
export interface TotalsSums {
|
|
106
|
+
matches: number;
|
|
107
|
+
candidates: number;
|
|
108
|
+
/** The line holds no formulas. */
|
|
109
|
+
typed: boolean;
|
|
110
|
+
/** The sums run down columns (the line is a row) rather than across rows. */
|
|
111
|
+
byColumn: boolean;
|
|
112
|
+
/** The cells that do not equal their Σ — `H26 text`, `C26 400 ≠ Σ 411`. */
|
|
113
|
+
misses: string[];
|
|
114
|
+
}
|
|
115
|
+
/** Where a block's body stops. */
|
|
116
|
+
export interface Totals {
|
|
117
|
+
/** The block runs down its rows (`true`) or across its columns. */
|
|
118
|
+
byColumn: boolean;
|
|
119
|
+
/** Absolute index of the first line left out of the body. */
|
|
120
|
+
start: number;
|
|
121
|
+
/** Every line from {@link start} to the block's end. */
|
|
122
|
+
lines: TotalsLine[];
|
|
123
|
+
/** The profile summary's fragment — `rows 26:27 not profiled: …`. */
|
|
124
|
+
note: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Where a block's body stops: the first line whose values equal the Σ of the body above them.
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* One deterministic test, the same for a `=SUM` row and a pasted one — a total equals the sum it
|
|
131
|
+
* totals by value, however it was entered. It needs two matches and a majority of the numeric
|
|
132
|
+
* series, so a coincidence in one column does not end a block. A table's totals row is taken as
|
|
133
|
+
* authored.
|
|
134
|
+
*
|
|
135
|
+
* Every line from there to the end of the block is left out of the stats, and each is named with
|
|
136
|
+
* its label so a reader can see what was set aside: the total, and whatever runs on below it
|
|
137
|
+
* (`Earnings Before Interest & Taxes` under `Total Expenses`). Labels are reported, never
|
|
138
|
+
* interpreted — deciding by its wording that a line is "a total" is the call a reader makes better.
|
|
139
|
+
*
|
|
140
|
+
* The first line's comparison is part of the fact: `typed` when it holds no formulas, and the cells
|
|
141
|
+
* that do not match, which on a pasted total are the finding.
|
|
142
|
+
*/
|
|
143
|
+
export declare function detectTotals(range: ICellRange, maxProfileCells?: number): Totals | null;
|
|
144
|
+
/** `= Σ above (13 of 13)` / `typed, = Σ above (12 of 13; H26 text)` / `= Σ to the left (2 of 2)`. */
|
|
145
|
+
export declare function describeSums(sums: TotalsSums): string;
|
|
91
146
|
/**
|
|
92
147
|
* Per-kind stats, pooled across the WHOLE range regardless of column — "what's actually in here,
|
|
93
148
|
* broken down by type" in one shot, as opposed to {@link profileSeries}'s per-column breakdown.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { IWorkbook } from '@sheetxl/sdk';
|
|
2
|
-
import { AppendDependencyOptions } from './
|
|
2
|
+
import { AppendDependencyOptions } from './appendDependencies';
|
|
3
3
|
import { RenderCellRangeOptions } from './renderCellRange';
|
|
4
4
|
import { RenderFormulaOptions } from './renderFormula';
|
|
5
|
+
import { RenderModulesOptions } from './renderModules';
|
|
5
6
|
import { RenderNamesOptions } from './renderNames';
|
|
6
7
|
import { RenderRecordsOptions } from './renderRecords';
|
|
7
8
|
import { RenderRangesOptions } from './renderRanges';
|
|
@@ -31,7 +32,7 @@ export declare namespace Renderer {
|
|
|
31
32
|
* alternative is making the caller name the kind, which is the dispatch the registry exists
|
|
32
33
|
* to remove.
|
|
33
34
|
*/
|
|
34
|
-
type Options = RenderCellRangeOptions & RenderSheetOptions & RenderRegionsOptions & RenderValuesOptions & RenderFormulaOptions & RenderRecordsOptions & RenderNamesOptions & RenderRangesOptions & AppendDependencyOptions;
|
|
35
|
+
type Options = RenderCellRangeOptions & RenderSheetOptions & RenderRegionsOptions & RenderValuesOptions & RenderFormulaOptions & RenderRecordsOptions & RenderNamesOptions & RenderRangesOptions & RenderModulesOptions & AppendDependencyOptions;
|
|
35
36
|
/**
|
|
36
37
|
* One renderable kind.
|
|
37
38
|
*/
|
|
@@ -54,6 +55,14 @@ export declare namespace Renderer {
|
|
|
54
55
|
* must be read as a table rather than as its first element or as N reports.
|
|
55
56
|
*/
|
|
56
57
|
export declare const RENDERERS: readonly Renderer.Entry[];
|
|
58
|
+
/**
|
|
59
|
+
* The name of every renderable kind, in dispatch order.
|
|
60
|
+
*
|
|
61
|
+
* @remarks
|
|
62
|
+
* What a host's help text lists. Derived, because a hand-written copy of this list is a second
|
|
63
|
+
* registry that nothing keeps in step with the first.
|
|
64
|
+
*/
|
|
65
|
+
export declare const RENDERABLE_KINDS: readonly string[];
|
|
57
66
|
/**
|
|
58
67
|
* Thrown by {@link renderMarkdown} when nothing in the registry accepts the value.
|
|
59
68
|
*
|