postext 0.3.19 → 0.3.21
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/dist/__tests__/columnBalancing.test.js +36 -2
- package/dist/__tests__/columnBalancing.test.js.map +1 -1
- package/dist/__tests__/defaults/calloutStyles.test.d.ts +2 -0
- package/dist/__tests__/defaults/calloutStyles.test.d.ts.map +1 -0
- package/dist/__tests__/defaults/calloutStyles.test.js +201 -0
- package/dist/__tests__/defaults/calloutStyles.test.js.map +1 -0
- package/dist/__tests__/defaults/captionStyle.test.d.ts +2 -0
- package/dist/__tests__/defaults/captionStyle.test.d.ts.map +1 -0
- package/dist/__tests__/defaults/captionStyle.test.js +87 -0
- package/dist/__tests__/defaults/captionStyle.test.js.map +1 -0
- package/dist/__tests__/defaults/pageSizePreset.test.d.ts +2 -0
- package/dist/__tests__/defaults/pageSizePreset.test.d.ts.map +1 -0
- package/dist/__tests__/defaults/pageSizePreset.test.js +24 -0
- package/dist/__tests__/defaults/pageSizePreset.test.js.map +1 -0
- package/dist/__tests__/defaults/paragraphStyles.test.d.ts +2 -0
- package/dist/__tests__/defaults/paragraphStyles.test.d.ts.map +1 -0
- package/dist/__tests__/defaults/paragraphStyles.test.js +93 -0
- package/dist/__tests__/defaults/paragraphStyles.test.js.map +1 -0
- package/dist/__tests__/design/pageAnchors.test.d.ts +2 -0
- package/dist/__tests__/design/pageAnchors.test.d.ts.map +1 -0
- package/dist/__tests__/design/pageAnchors.test.js +140 -0
- package/dist/__tests__/design/pageAnchors.test.js.map +1 -0
- package/dist/__tests__/directives.test.js +58 -0
- package/dist/__tests__/directives.test.js.map +1 -1
- package/dist/__tests__/exports.test.js +19 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/mirroredMargins.test.d.ts +2 -0
- package/dist/__tests__/mirroredMargins.test.d.ts.map +1 -0
- package/dist/__tests__/mirroredMargins.test.js +136 -0
- package/dist/__tests__/mirroredMargins.test.js.map +1 -0
- package/dist/__tests__/numbering.test.js +54 -0
- package/dist/__tests__/numbering.test.js.map +1 -1
- package/dist/__tests__/openerTitleSource.test.d.ts +2 -0
- package/dist/__tests__/openerTitleSource.test.d.ts.map +1 -0
- package/dist/__tests__/openerTitleSource.test.js +108 -0
- package/dist/__tests__/openerTitleSource.test.js.map +1 -0
- package/dist/__tests__/overStretch.test.d.ts +2 -0
- package/dist/__tests__/overStretch.test.d.ts.map +1 -0
- package/dist/__tests__/overStretch.test.js +35 -0
- package/dist/__tests__/overStretch.test.js.map +1 -0
- package/dist/__tests__/pageRoles.test.d.ts +2 -0
- package/dist/__tests__/pageRoles.test.d.ts.map +1 -0
- package/dist/__tests__/pageRoles.test.js +95 -0
- package/dist/__tests__/pageRoles.test.js.map +1 -0
- package/dist/__tests__/parse/containers.test.d.ts +2 -0
- package/dist/__tests__/parse/containers.test.d.ts.map +1 -0
- package/dist/__tests__/parse/containers.test.js +204 -0
- package/dist/__tests__/parse/containers.test.js.map +1 -0
- package/dist/__tests__/parse/headingAttrs.test.d.ts +2 -0
- package/dist/__tests__/parse/headingAttrs.test.d.ts.map +1 -0
- package/dist/__tests__/parse/headingAttrs.test.js +62 -0
- package/dist/__tests__/parse/headingAttrs.test.js.map +1 -0
- package/dist/__tests__/parse/inlineRef.test.js +26 -0
- package/dist/__tests__/parse/inlineRef.test.js.map +1 -1
- package/dist/__tests__/parts.test.d.ts +2 -0
- package/dist/__tests__/parts.test.d.ts.map +1 -0
- package/dist/__tests__/parts.test.js +405 -0
- package/dist/__tests__/parts.test.js.map +1 -0
- package/dist/__tests__/pipeline/calloutLayout.test.d.ts +2 -0
- package/dist/__tests__/pipeline/calloutLayout.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/calloutLayout.test.js +273 -0
- package/dist/__tests__/pipeline/calloutLayout.test.js.map +1 -0
- package/dist/__tests__/pipeline/calloutPlacement.test.d.ts +2 -0
- package/dist/__tests__/pipeline/calloutPlacement.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/calloutPlacement.test.js +239 -0
- package/dist/__tests__/pipeline/calloutPlacement.test.js.map +1 -0
- package/dist/__tests__/pipeline/captionLayout.test.d.ts +2 -0
- package/dist/__tests__/pipeline/captionLayout.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/captionLayout.test.js +269 -0
- package/dist/__tests__/pipeline/captionLayout.test.js.map +1 -0
- package/dist/__tests__/pipeline/inlineRefRender.test.js +53 -0
- package/dist/__tests__/pipeline/inlineRefRender.test.js.map +1 -1
- package/dist/__tests__/pipeline/orderedSeparator.test.d.ts +2 -0
- package/dist/__tests__/pipeline/orderedSeparator.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/orderedSeparator.test.js +196 -0
- package/dist/__tests__/pipeline/orderedSeparator.test.js.map +1 -0
- package/dist/__tests__/pipeline/paragraphStyles.test.d.ts +2 -0
- package/dist/__tests__/pipeline/paragraphStyles.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/paragraphStyles.test.js +172 -0
- package/dist/__tests__/pipeline/paragraphStyles.test.js.map +1 -0
- package/dist/__tests__/pipeline/spanBands.test.d.ts +2 -0
- package/dist/__tests__/pipeline/spanBands.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/spanBands.test.js +303 -0
- package/dist/__tests__/pipeline/spanBands.test.js.map +1 -0
- package/dist/__tests__/pipeline/spanBlocks.test.d.ts +2 -0
- package/dist/__tests__/pipeline/spanBlocks.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/spanBlocks.test.js +407 -0
- package/dist/__tests__/pipeline/spanBlocks.test.js.map +1 -0
- package/dist/__tests__/placeholders.test.d.ts +2 -0
- package/dist/__tests__/placeholders.test.d.ts.map +1 -0
- package/dist/__tests__/placeholders.test.js +130 -0
- package/dist/__tests__/placeholders.test.js.map +1 -0
- package/dist/__tests__/table/model.test.js +24 -0
- package/dist/__tests__/table/model.test.js.map +1 -1
- package/dist/__tests__/tracking.test.d.ts +2 -0
- package/dist/__tests__/tracking.test.d.ts.map +1 -0
- package/dist/__tests__/tracking.test.js +37 -0
- package/dist/__tests__/tracking.test.js.map +1 -0
- package/dist/__tests__/urlBreaks.test.d.ts +2 -0
- package/dist/__tests__/urlBreaks.test.d.ts.map +1 -0
- package/dist/__tests__/urlBreaks.test.js +57 -0
- package/dist/__tests__/urlBreaks.test.js.map +1 -0
- package/dist/canvas-backend/blockRender.d.ts.map +1 -1
- package/dist/canvas-backend/blockRender.js +20 -1
- package/dist/canvas-backend/blockRender.js.map +1 -1
- package/dist/canvas-backend/decorations.d.ts +3 -0
- package/dist/canvas-backend/decorations.d.ts.map +1 -1
- package/dist/canvas-backend/decorations.js +14 -8
- package/dist/canvas-backend/decorations.js.map +1 -1
- package/dist/canvas-backend/headerFooter.d.ts.map +1 -1
- package/dist/canvas-backend/headerFooter.js +23 -0
- package/dist/canvas-backend/headerFooter.js.map +1 -1
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +4 -2
- package/dist/canvas-backend/index.js.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.js +33 -5
- package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
- package/dist/columnRule.d.ts +19 -0
- package/dist/columnRule.d.ts.map +1 -0
- package/dist/columnRule.js +36 -0
- package/dist/columnRule.js.map +1 -0
- package/dist/defaults/bodyText.js +1 -1
- package/dist/defaults/bodyText.js.map +1 -1
- package/dist/defaults/calloutStyles.d.ts +61 -0
- package/dist/defaults/calloutStyles.d.ts.map +1 -0
- package/dist/defaults/calloutStyles.js +292 -0
- package/dist/defaults/calloutStyles.js.map +1 -0
- package/dist/defaults/captionStyle.d.ts +11 -1
- package/dist/defaults/captionStyle.d.ts.map +1 -1
- package/dist/defaults/captionStyle.js +127 -2
- package/dist/defaults/captionStyle.js.map +1 -1
- package/dist/defaults/headerFooter.d.ts.map +1 -1
- package/dist/defaults/headerFooter.js +3 -0
- package/dist/defaults/headerFooter.js.map +1 -1
- package/dist/defaults/headings.d.ts +3 -0
- package/dist/defaults/headings.d.ts.map +1 -1
- package/dist/defaults/headings.js +33 -6
- package/dist/defaults/headings.js.map +1 -1
- package/dist/defaults/index.d.ts +4 -1
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +28 -1
- package/dist/defaults/index.js.map +1 -1
- package/dist/defaults/orderedLists.d.ts +9 -8
- package/dist/defaults/orderedLists.d.ts.map +1 -1
- package/dist/defaults/orderedLists.js +66 -4
- package/dist/defaults/orderedLists.js.map +1 -1
- package/dist/defaults/page.d.ts.map +1 -1
- package/dist/defaults/page.js +14 -3
- package/dist/defaults/page.js.map +1 -1
- package/dist/defaults/paragraphStyles.d.ts +10 -0
- package/dist/defaults/paragraphStyles.d.ts.map +1 -0
- package/dist/defaults/paragraphStyles.js +67 -0
- package/dist/defaults/paragraphStyles.js.map +1 -0
- package/dist/defaults/parts.d.ts +22 -0
- package/dist/defaults/parts.d.ts.map +1 -0
- package/dist/defaults/parts.js +139 -0
- package/dist/defaults/parts.js.map +1 -0
- package/dist/defaults/shared.d.ts.map +1 -1
- package/dist/defaults/shared.js +110 -17
- package/dist/defaults/shared.js.map +1 -1
- package/dist/defaults/tableStyle.d.ts.map +1 -1
- package/dist/defaults/tableStyle.js +6 -0
- package/dist/defaults/tableStyle.js.map +1 -1
- package/dist/design/layout.d.ts +27 -1
- package/dist/design/layout.d.ts.map +1 -1
- package/dist/design/layout.js +39 -8
- package/dist/design/layout.js.map +1 -1
- package/dist/design/placeholders.d.ts +21 -4
- package/dist/design/placeholders.d.ts.map +1 -1
- package/dist/design/placeholders.js +38 -7
- package/dist/design/placeholders.js.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +75 -16
- package/dist/html-backend.js.map +1 -1
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/knuthPlass/breakpoints.d.ts.map +1 -1
- package/dist/knuthPlass/breakpoints.js +4 -2
- package/dist/knuthPlass/breakpoints.js.map +1 -1
- package/dist/knuthPlass/constants.d.ts +7 -0
- package/dist/knuthPlass/constants.d.ts.map +1 -1
- package/dist/knuthPlass/constants.js +7 -0
- package/dist/knuthPlass/constants.js.map +1 -1
- package/dist/knuthPlass/richAdapter.d.ts +2 -0
- package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/richAdapter.js +6 -6
- package/dist/knuthPlass/richAdapter.js.map +1 -1
- package/dist/measure/cache.js +2 -2
- package/dist/measure/cache.js.map +1 -1
- package/dist/measure/rich.d.ts +8 -0
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +54 -10
- package/dist/measure/rich.js.map +1 -1
- package/dist/measure/types.d.ts +4 -0
- package/dist/measure/types.d.ts.map +1 -1
- package/dist/measure/types.js.map +1 -1
- package/dist/parse/attrs.d.ts +10 -0
- package/dist/parse/attrs.d.ts.map +1 -0
- package/dist/parse/attrs.js +20 -0
- package/dist/parse/attrs.js.map +1 -0
- package/dist/parse/blockParser.d.ts +8 -4
- package/dist/parse/blockParser.d.ts.map +1 -1
- package/dist/parse/blockParser.js +134 -20
- package/dist/parse/blockParser.js.map +1 -1
- package/dist/parse/index.d.ts +2 -2
- package/dist/parse/index.d.ts.map +1 -1
- package/dist/parse/index.js +1 -1
- package/dist/parse/index.js.map +1 -1
- package/dist/parse/inlineFormatting.d.ts +17 -1
- package/dist/parse/inlineFormatting.d.ts.map +1 -1
- package/dist/parse/inlineFormatting.js +56 -7
- package/dist/parse/inlineFormatting.js.map +1 -1
- package/dist/parse/sourceMapping.d.ts.map +1 -1
- package/dist/parse/sourceMapping.js +13 -1
- package/dist/parse/sourceMapping.js.map +1 -1
- package/dist/parse/types.d.ts +55 -5
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/pipeline/bandCaps.d.ts +86 -0
- package/dist/pipeline/bandCaps.d.ts.map +1 -0
- package/dist/pipeline/bandCaps.js +142 -0
- package/dist/pipeline/bandCaps.js.map +1 -0
- package/dist/pipeline/build.d.ts +41 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +675 -168
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/buildBlockKind.d.ts +8 -0
- package/dist/pipeline/buildBlockKind.d.ts.map +1 -1
- package/dist/pipeline/buildBlockKind.js +40 -11
- package/dist/pipeline/buildBlockKind.js.map +1 -1
- package/dist/pipeline/buildHelpers.d.ts +23 -1
- package/dist/pipeline/buildHelpers.d.ts.map +1 -1
- package/dist/pipeline/buildHelpers.js +50 -6
- package/dist/pipeline/buildHelpers.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts +107 -0
- package/dist/pipeline/calloutLayout.d.ts.map +1 -0
- package/dist/pipeline/calloutLayout.js +498 -0
- package/dist/pipeline/calloutLayout.js.map +1 -0
- package/dist/pipeline/columnBalancing.d.ts +26 -8
- package/dist/pipeline/columnBalancing.d.ts.map +1 -1
- package/dist/pipeline/columnBalancing.js +50 -18
- package/dist/pipeline/columnBalancing.js.map +1 -1
- package/dist/pipeline/config.d.ts.map +1 -1
- package/dist/pipeline/config.js +17 -5
- package/dist/pipeline/config.js.map +1 -1
- package/dist/pipeline/headerFooter.d.ts +37 -2
- package/dist/pipeline/headerFooter.d.ts.map +1 -1
- package/dist/pipeline/headerFooter.js +231 -15
- package/dist/pipeline/headerFooter.js.map +1 -1
- package/dist/pipeline/lists.d.ts +15 -0
- package/dist/pipeline/lists.d.ts.map +1 -1
- package/dist/pipeline/lists.js +73 -16
- package/dist/pipeline/lists.js.map +1 -1
- package/dist/pipeline/measureContentBlock.d.ts +65 -0
- package/dist/pipeline/measureContentBlock.d.ts.map +1 -0
- package/dist/pipeline/measureContentBlock.js +134 -0
- package/dist/pipeline/measureContentBlock.js.map +1 -0
- package/dist/pipeline/pageRoles.d.ts +23 -0
- package/dist/pipeline/pageRoles.d.ts.map +1 -0
- package/dist/pipeline/pageRoles.js +54 -0
- package/dist/pipeline/pageRoles.js.map +1 -0
- package/dist/pipeline/paragraphContainers.d.ts +32 -0
- package/dist/pipeline/paragraphContainers.d.ts.map +1 -0
- package/dist/pipeline/paragraphContainers.js +61 -0
- package/dist/pipeline/paragraphContainers.js.map +1 -0
- package/dist/pipeline/parts.d.ts +47 -0
- package/dist/pipeline/parts.d.ts.map +1 -0
- package/dist/pipeline/parts.js +230 -0
- package/dist/pipeline/parts.js.map +1 -0
- package/dist/pipeline/placeholders.d.ts +46 -1
- package/dist/pipeline/placeholders.d.ts.map +1 -1
- package/dist/pipeline/placeholders.js +93 -11
- package/dist/pipeline/placeholders.js.map +1 -1
- package/dist/pipeline/placement.d.ts +61 -7
- package/dist/pipeline/placement.d.ts.map +1 -1
- package/dist/pipeline/placement.js +151 -12
- package/dist/pipeline/placement.js.map +1 -1
- package/dist/pipeline/resourceLayout.d.ts +18 -5
- package/dist/pipeline/resourceLayout.d.ts.map +1 -1
- package/dist/pipeline/resourceLayout.js +145 -23
- package/dist/pipeline/resourceLayout.js.map +1 -1
- package/dist/pipeline/styles.d.ts +9 -1
- package/dist/pipeline/styles.d.ts.map +1 -1
- package/dist/pipeline/styles.js +50 -0
- package/dist/pipeline/styles.js.map +1 -1
- package/dist/table/model.d.ts.map +1 -1
- package/dist/table/model.js +16 -2
- package/dist/table/model.js.map +1 -1
- package/dist/types.d.ts +468 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +132 -4
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js +2 -1
- package/dist/vdt.js.map +1 -1
- package/package.json +8 -8
package/dist/parse/types.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
export type ContentBlockType = 'heading' | 'paragraph' | 'blockquote' | 'listItem' | 'mathDisplay' | 'resourceBlock' | 'directive';
|
|
1
|
+
export type ContentBlockType = 'heading' | 'paragraph' | 'blockquote' | 'listItem' | 'mathDisplay' | 'resourceBlock' | 'directive' | 'containerStart' | 'containerEnd';
|
|
2
2
|
/** Attributes parsed from a `:::name{key="v" other=bare flag}` directive.
|
|
3
3
|
* Values are kept as strings; directive consumers validate/coerce. A bare
|
|
4
4
|
* `flag` becomes `{ flag: '' }`. */
|
|
5
5
|
export type DirectiveAttrs = Record<string, string>;
|
|
6
6
|
/** Recognized directive names. Unknown names are not parsed as directives —
|
|
7
7
|
* they fall through to the paragraph branch and surface via warnings. */
|
|
8
|
-
export type DirectiveName = 'pagebreak' | 'numbering';
|
|
8
|
+
export type DirectiveName = 'pagebreak' | 'numbering' | 'columnbreak';
|
|
9
|
+
/** Recognized fenced-container names. A container opens with a
|
|
10
|
+
* `:::name{attrs}` line and closes with a bare `:::` line; the blocks in
|
|
11
|
+
* between are parsed as usual and bracketed by a `containerStart` /
|
|
12
|
+
* `containerEnd` marker pair sharing a `containerId`. */
|
|
13
|
+
export type ContainerName = 'callout' | 'paragraphs' | 'part';
|
|
14
|
+
/** Letter-case transform applied to the computed label of an inline `:ref`
|
|
15
|
+
* (never to the number, never to a `text=` override). */
|
|
16
|
+
export type RefCase = 'lower' | 'upper' | 'capitalize';
|
|
9
17
|
/** Metadata attached to an `InlineSpan` when it represents a math formula.
|
|
10
18
|
* The span's `text` is a single `\uFFFC` (object replacement character)
|
|
11
19
|
* acting as a one-char-wide atomic placeholder in the plain text. */
|
|
@@ -42,6 +50,9 @@ export interface InlineSpan {
|
|
|
42
50
|
style?: 'default' | 'number' | 'full';
|
|
43
51
|
/** Optional override text to display instead of the computed label. */
|
|
44
52
|
text?: string;
|
|
53
|
+
/** Optional letter-case transform for the label part (`Fig.` /
|
|
54
|
+
* `Figure`) of the computed label. Ignored when `text` is set. */
|
|
55
|
+
case?: RefCase;
|
|
45
56
|
};
|
|
46
57
|
}
|
|
47
58
|
/** Convenience discriminants for inline span iteration. */
|
|
@@ -52,23 +63,51 @@ export type MathSpan = InlineSpan & {
|
|
|
52
63
|
math: MathMeta;
|
|
53
64
|
};
|
|
54
65
|
export type ListKind = 'unordered' | 'ordered' | 'task';
|
|
55
|
-
export type ParseIssueKind = 'unclosedMath' | 'unclosedMathBlock';
|
|
56
|
-
|
|
66
|
+
export type ParseIssueKind = 'unclosedMath' | 'unclosedMathBlock' | 'unclosedContainer';
|
|
67
|
+
interface ParseIssueBase {
|
|
57
68
|
kind: ParseIssueKind;
|
|
58
|
-
delimiter: '$' | '$$';
|
|
69
|
+
delimiter: '$' | '$$' | ':::';
|
|
59
70
|
/** Absolute source offset of the unmatched opening delimiter. */
|
|
60
71
|
sourceStart: number;
|
|
61
72
|
/** End of the scanned region (usually the line or block end). */
|
|
62
73
|
sourceEnd: number;
|
|
74
|
+
}
|
|
75
|
+
/** An inline `$…` or display `$$…` formula whose closing delimiter is
|
|
76
|
+
* missing. */
|
|
77
|
+
export interface UnclosedMathIssue extends ParseIssueBase {
|
|
78
|
+
kind: 'unclosedMath' | 'unclosedMathBlock';
|
|
79
|
+
delimiter: '$' | '$$';
|
|
63
80
|
/** Raw TeX captured up to the end of the scanned region, for warning
|
|
64
81
|
* messages — may be empty. */
|
|
65
82
|
tex: string;
|
|
66
83
|
}
|
|
84
|
+
/** A `:::name` container fence that was still open at end of input. The
|
|
85
|
+
* parser auto-closes it; `sourceStart`/`sourceEnd` cover the opening line. */
|
|
86
|
+
export interface UnclosedContainerIssue extends ParseIssueBase {
|
|
87
|
+
kind: 'unclosedContainer';
|
|
88
|
+
delimiter: ':::';
|
|
89
|
+
containerName: ContainerName;
|
|
90
|
+
containerId: number;
|
|
91
|
+
}
|
|
92
|
+
export type ParseIssue = UnclosedMathIssue | UnclosedContainerIssue;
|
|
67
93
|
export interface ContentBlock {
|
|
68
94
|
type: ContentBlockType;
|
|
69
95
|
text: string;
|
|
70
96
|
spans: InlineSpan[];
|
|
71
97
|
level?: number;
|
|
98
|
+
/** For `heading` blocks: attributes parsed from a trailing
|
|
99
|
+
* `{key="value" other=bare}` on the heading line (e.g.
|
|
100
|
+
* `# Title {author="I. Zango"}`). The braces and their content are
|
|
101
|
+
* removed from `text`. Absent when the heading carries no attributes. */
|
|
102
|
+
attrs?: DirectiveAttrs;
|
|
103
|
+
/** Absolute source range of each quoted attribute value, so editors can
|
|
104
|
+
* map text rendered from `{attr.<key>}` back to the markdown. */
|
|
105
|
+
attrSources?: Record<string, {
|
|
106
|
+
start: number;
|
|
107
|
+
end: number;
|
|
108
|
+
}>;
|
|
109
|
+
/** Plain-text indices of forced title breaks (`\\` in the source). */
|
|
110
|
+
titleBreaks?: number[];
|
|
72
111
|
/** Depth (1-based) for listItem blocks. Level 1 = outermost. */
|
|
73
112
|
depth?: number;
|
|
74
113
|
/** Discriminator for listItem blocks. Defaults to 'unordered' when absent. */
|
|
@@ -85,6 +124,16 @@ export interface ContentBlock {
|
|
|
85
124
|
directiveAttrs?: DirectiveAttrs;
|
|
86
125
|
/** For `resourceBlock` blocks: the referenced `Resource.id`. */
|
|
87
126
|
resourceId?: string;
|
|
127
|
+
/** For `containerStart` / `containerEnd` marker blocks: the container
|
|
128
|
+
* name (`'callout'`, `'paragraphs'`, `'part'`). */
|
|
129
|
+
containerName?: ContainerName;
|
|
130
|
+
/** For `containerStart` blocks: attributes parsed from the opening fence.
|
|
131
|
+
* Always present on a start marker (empty object when the fence carries
|
|
132
|
+
* no `{…}`). */
|
|
133
|
+
containerAttrs?: DirectiveAttrs;
|
|
134
|
+
/** For container marker blocks: identifier shared by the matching
|
|
135
|
+
* start/end pair. Ids start at 1 and increase per parse. */
|
|
136
|
+
containerId?: number;
|
|
88
137
|
/** Character offset of the first source character of this block in the original markdown */
|
|
89
138
|
sourceStart: number;
|
|
90
139
|
/** Character offset just past the last source character of this block */
|
|
@@ -96,4 +145,5 @@ export interface ContentBlock {
|
|
|
96
145
|
*/
|
|
97
146
|
sourceMap: number[];
|
|
98
147
|
}
|
|
148
|
+
export {};
|
|
99
149
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,WAAW,GACX,YAAY,GACZ,UAAU,GACV,aAAa,GACb,eAAe,GACf,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,WAAW,GACX,YAAY,GACZ,UAAU,GACV,aAAa,GACb,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,cAAc,CAAC;AAEnB;;qCAEqC;AACrC,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD;0EAC0E;AAC1E,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;AAEtE;;;0DAG0D;AAC1D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,MAAM,CAAC;AAE9D;0DAC0D;AAC1D,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,CAAC;AAEvD;;sEAEsE;AACtE,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB;;kDAE8C;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;uEACmE;IACnE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;8DAC0D;IAC1D,UAAU,CAAC,EAAE,OAAO,eAAe,EAAE,UAAU,CAAC;IAChD;;kDAE8C;IAC9C,GAAG,CAAC,EAAE;QACJ,oCAAoC;QACpC,UAAU,EAAE,MAAM,CAAC;QACnB;;sBAEc;QACd,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;QACtC,uEAAuE;QACvE,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;2EACmE;QACnE,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAED,2DAA2D;AAC3D,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAExF,UAAU,cAAc;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;IAC9B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;eACe;AACf,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,IAAI,EAAE,cAAc,GAAG,mBAAmB,CAAC;IAC3C,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB;mCAC+B;IAC/B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;+EAC+E;AAC/E,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,KAAK,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,sBAAsB,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;8EAG0E;IAC1E,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;sEACkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,iDAAiD;IACjD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;wDACoD;IACpD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;qBAEiB;IACjB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;iEAC6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4FAA4F;IAC5F,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Band caps — page-span blocks, stage 2 (mid-page bands).
|
|
3
|
+
*
|
|
4
|
+
* Stage 1 (`placement.ts`) only inserts a page-span block where the current
|
|
5
|
+
* column band is *level*; a block arriving with the columns uneven moves to
|
|
6
|
+
* the top of the next page. Stage 2 lets it land mid-page the way a
|
|
7
|
+
* compositor would set it: the text above the box is cut level across all
|
|
8
|
+
* columns, the box spans the page, and the columns resume below it.
|
|
9
|
+
*
|
|
10
|
+
* Rather than redistributing already-placed blocks in place (which would
|
|
11
|
+
* bypass orphan / widow / keep-with-next), the engine re-runs the placement
|
|
12
|
+
* pass with a **band cap**: the columns of the band that opens with a given
|
|
13
|
+
* content block are shortened to `lines` grid lines, so they fill and
|
|
14
|
+
* overflow into each other naturally — every placement rule keeps applying
|
|
15
|
+
* — and end level at `bandTop + lines·grid`, where the span block then cuts
|
|
16
|
+
* the band. A cap is proposed by the pass that saw the block arrive in an
|
|
17
|
+
* uneven band with room below (`lines = ceil(Σ used px / N / grid)`), and
|
|
18
|
+
* consumed by the next pass. When the capped band overflows differently
|
|
19
|
+
* (e.g. keep-with-next moved a heading and the text no longer fits above
|
|
20
|
+
* the cut), the cap is retried one line taller a bounded number of times,
|
|
21
|
+
* then dropped — the block falls back to stage 1.
|
|
22
|
+
*/
|
|
23
|
+
import type { VDTColumn } from '../vdt';
|
|
24
|
+
/** Cap on the band that opens with content block `startContentIndex`
|
|
25
|
+
* (part `startPart` — a split paragraph's continuation can open a band
|
|
26
|
+
* too), keyed in `bandCaps` by the span block's own content index. */
|
|
27
|
+
export interface BandCap {
|
|
28
|
+
startContentIndex: number;
|
|
29
|
+
/** Part index of the band's opening block (`0` unless it is the
|
|
30
|
+
* continuation of a paragraph split across columns / pages). */
|
|
31
|
+
startPart: number;
|
|
32
|
+
/** Height of the capped band in baseline-grid lines. */
|
|
33
|
+
lines: number;
|
|
34
|
+
/** Times the cap has been grown by one line after an overflow. */
|
|
35
|
+
retries: number;
|
|
36
|
+
}
|
|
37
|
+
/** Maximum number of extra placement passes the band-cap driver may run on
|
|
38
|
+
* top of the initial pass (proposals + retries). */
|
|
39
|
+
export declare const MAX_BAND_PASSES = 4;
|
|
40
|
+
/** Maximum number of `lines + 1` retries for a cap whose band overflowed. */
|
|
41
|
+
export declare const MAX_BAND_CAP_RETRIES = 3;
|
|
42
|
+
/** What a placement pass reports back to the band-cap driver. */
|
|
43
|
+
export interface BandPassReport {
|
|
44
|
+
/** New caps, keyed by the proposing span block's content index. */
|
|
45
|
+
bandCapProposals: ReadonlyMap<number, BandCap>;
|
|
46
|
+
/** Span blocks inserted in the band their cap was applied to. */
|
|
47
|
+
spanPlacedInBand: ReadonlySet<number>;
|
|
48
|
+
/** Caps whose opening block did open a band in this pass. */
|
|
49
|
+
bandCapsApplied: ReadonlySet<number>;
|
|
50
|
+
}
|
|
51
|
+
/** Shorten every column of a (still empty) band to `capPx`, remembering
|
|
52
|
+
* each column's true bottom in `uncappedBottoms` so the band can be
|
|
53
|
+
* restored (`uncapBand`) when the span block cuts it. Idempotent; a column
|
|
54
|
+
* already shorter than the cap (bottom float) is left alone. A column that
|
|
55
|
+
* already holds content keeps its used height — the cap then only trims
|
|
56
|
+
* what is left. */
|
|
57
|
+
export declare function applyBandCap(cols: readonly VDTColumn[], capPx: number, uncappedBottoms: Map<VDTColumn, number>): void;
|
|
58
|
+
/** Give capped columns their true bottom back (the slack below the cap
|
|
59
|
+
* returns to `availableHeight`). */
|
|
60
|
+
export declare function uncapBand(cols: readonly VDTColumn[], uncappedBottoms: Map<VDTColumn, number>): void;
|
|
61
|
+
/** True bottom of a column — the remembered one while it is capped. */
|
|
62
|
+
export declare function columnBottom(col: VDTColumn, uncappedBottoms: ReadonlyMap<VDTColumn, number>): number;
|
|
63
|
+
/** Grid lines a level cut of the band would need: the content spread over
|
|
64
|
+
* the band's columns evenly, rounded up to whole lines. */
|
|
65
|
+
export declare function bandCapLines(cols: readonly VDTColumn[], gridPx: number): number;
|
|
66
|
+
/**
|
|
67
|
+
* Drive the band-cap passes. `initial` is the plain first pass; `runPass`
|
|
68
|
+
* re-places the document with the given caps. Returns the layout to carry
|
|
69
|
+
* into column balancing, the caps it was built with, and the number of
|
|
70
|
+
* passes run (including the initial one).
|
|
71
|
+
*
|
|
72
|
+
* Each round first settles the caps of the previous pass — a cap whose
|
|
73
|
+
* block was not inserted in its band is retried one line taller (while it
|
|
74
|
+
* did apply and `retries` allows), otherwise dropped — then adopts the new
|
|
75
|
+
* proposals (never one already tried). Rounds stop when nothing changes or
|
|
76
|
+
* `MAX_BAND_PASSES` extra passes were run. The layout returned never carries
|
|
77
|
+
* an undelivered cap: failing caps are removed and, when none survive, the
|
|
78
|
+
* initial pass is returned untouched — a document whose span blocks all
|
|
79
|
+
* fit stage 1 costs no extra pass at all.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveBandCaps<T extends BandPassReport>(initial: T, runPass: (bandCaps: ReadonlyMap<number, BandCap>) => T): {
|
|
82
|
+
result: T;
|
|
83
|
+
bandCaps: Map<number, BandCap>;
|
|
84
|
+
passCount: number;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=bandCaps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bandCaps.d.ts","sourceRoot":"","sources":["../../src/pipeline/bandCaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC;;uEAEuE;AACvE,MAAM,WAAW,OAAO;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B;qEACiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;qDACqD;AACrD,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,iEAAiE;IACjE,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,6DAA6D;IAC7D,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACtC;AAED;;;;;oBAKoB;AACpB,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GACtC,IAAI,CAQN;AAED;qCACqC;AACrC,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,eAAe,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GACtC,IAAI,CASN;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,MAAM,CAEpG;AAED;4DAC4D;AAC5D,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI/E;AAKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,cAAc,EACtD,OAAO,EAAE,CAAC,EACV,OAAO,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,GACrD;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAiDlE"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Band caps — page-span blocks, stage 2 (mid-page bands).
|
|
3
|
+
*
|
|
4
|
+
* Stage 1 (`placement.ts`) only inserts a page-span block where the current
|
|
5
|
+
* column band is *level*; a block arriving with the columns uneven moves to
|
|
6
|
+
* the top of the next page. Stage 2 lets it land mid-page the way a
|
|
7
|
+
* compositor would set it: the text above the box is cut level across all
|
|
8
|
+
* columns, the box spans the page, and the columns resume below it.
|
|
9
|
+
*
|
|
10
|
+
* Rather than redistributing already-placed blocks in place (which would
|
|
11
|
+
* bypass orphan / widow / keep-with-next), the engine re-runs the placement
|
|
12
|
+
* pass with a **band cap**: the columns of the band that opens with a given
|
|
13
|
+
* content block are shortened to `lines` grid lines, so they fill and
|
|
14
|
+
* overflow into each other naturally — every placement rule keeps applying
|
|
15
|
+
* — and end level at `bandTop + lines·grid`, where the span block then cuts
|
|
16
|
+
* the band. A cap is proposed by the pass that saw the block arrive in an
|
|
17
|
+
* uneven band with room below (`lines = ceil(Σ used px / N / grid)`), and
|
|
18
|
+
* consumed by the next pass. When the capped band overflows differently
|
|
19
|
+
* (e.g. keep-with-next moved a heading and the text no longer fits above
|
|
20
|
+
* the cut), the cap is retried one line taller a bounded number of times,
|
|
21
|
+
* then dropped — the block falls back to stage 1.
|
|
22
|
+
*/
|
|
23
|
+
/** Maximum number of extra placement passes the band-cap driver may run on
|
|
24
|
+
* top of the initial pass (proposals + retries). */
|
|
25
|
+
export const MAX_BAND_PASSES = 4;
|
|
26
|
+
/** Maximum number of `lines + 1` retries for a cap whose band overflowed. */
|
|
27
|
+
export const MAX_BAND_CAP_RETRIES = 3;
|
|
28
|
+
/** Shorten every column of a (still empty) band to `capPx`, remembering
|
|
29
|
+
* each column's true bottom in `uncappedBottoms` so the band can be
|
|
30
|
+
* restored (`uncapBand`) when the span block cuts it. Idempotent; a column
|
|
31
|
+
* already shorter than the cap (bottom float) is left alone. A column that
|
|
32
|
+
* already holds content keeps its used height — the cap then only trims
|
|
33
|
+
* what is left. */
|
|
34
|
+
export function applyBandCap(cols, capPx, uncappedBottoms) {
|
|
35
|
+
for (const c of cols) {
|
|
36
|
+
if (c.bbox.height <= capPx + 0.01)
|
|
37
|
+
continue;
|
|
38
|
+
if (!uncappedBottoms.has(c))
|
|
39
|
+
uncappedBottoms.set(c, c.bbox.y + c.bbox.height);
|
|
40
|
+
const trimmed = c.bbox.height - capPx;
|
|
41
|
+
c.bbox.height = capPx;
|
|
42
|
+
c.availableHeight = Math.max(0, c.availableHeight - trimmed);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Give capped columns their true bottom back (the slack below the cap
|
|
46
|
+
* returns to `availableHeight`). */
|
|
47
|
+
export function uncapBand(cols, uncappedBottoms) {
|
|
48
|
+
for (const c of cols) {
|
|
49
|
+
const bottom = uncappedBottoms.get(c);
|
|
50
|
+
if (bottom === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
const height = bottom - c.bbox.y;
|
|
53
|
+
c.availableHeight += height - c.bbox.height;
|
|
54
|
+
c.bbox.height = height;
|
|
55
|
+
uncappedBottoms.delete(c);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** True bottom of a column — the remembered one while it is capped. */
|
|
59
|
+
export function columnBottom(col, uncappedBottoms) {
|
|
60
|
+
return uncappedBottoms.get(col) ?? col.bbox.y + col.bbox.height;
|
|
61
|
+
}
|
|
62
|
+
/** Grid lines a level cut of the band would need: the content spread over
|
|
63
|
+
* the band's columns evenly, rounded up to whole lines. */
|
|
64
|
+
export function bandCapLines(cols, gridPx) {
|
|
65
|
+
let total = 0;
|
|
66
|
+
for (const c of cols)
|
|
67
|
+
total += c.bbox.height - c.availableHeight;
|
|
68
|
+
return Math.max(1, Math.ceil((total / cols.length - 0.01) / gridPx));
|
|
69
|
+
}
|
|
70
|
+
const capKey = (spanIndex, cap) => `${spanIndex}:${cap.startContentIndex}:${cap.startPart}:${cap.lines}`;
|
|
71
|
+
/**
|
|
72
|
+
* Drive the band-cap passes. `initial` is the plain first pass; `runPass`
|
|
73
|
+
* re-places the document with the given caps. Returns the layout to carry
|
|
74
|
+
* into column balancing, the caps it was built with, and the number of
|
|
75
|
+
* passes run (including the initial one).
|
|
76
|
+
*
|
|
77
|
+
* Each round first settles the caps of the previous pass — a cap whose
|
|
78
|
+
* block was not inserted in its band is retried one line taller (while it
|
|
79
|
+
* did apply and `retries` allows), otherwise dropped — then adopts the new
|
|
80
|
+
* proposals (never one already tried). Rounds stop when nothing changes or
|
|
81
|
+
* `MAX_BAND_PASSES` extra passes were run. The layout returned never carries
|
|
82
|
+
* an undelivered cap: failing caps are removed and, when none survive, the
|
|
83
|
+
* initial pass is returned untouched — a document whose span blocks all
|
|
84
|
+
* fit stage 1 costs no extra pass at all.
|
|
85
|
+
*/
|
|
86
|
+
export function resolveBandCaps(initial, runPass) {
|
|
87
|
+
const caps = new Map();
|
|
88
|
+
let result = initial;
|
|
89
|
+
let passCount = 1;
|
|
90
|
+
if (initial.bandCapProposals.size === 0)
|
|
91
|
+
return { result, bandCaps: caps, passCount };
|
|
92
|
+
const tried = new Set();
|
|
93
|
+
for (let extra = 0; extra < MAX_BAND_PASSES; extra++) {
|
|
94
|
+
let changed = false;
|
|
95
|
+
for (const [spanIndex, cap] of [...caps]) {
|
|
96
|
+
if (result.spanPlacedInBand.has(spanIndex))
|
|
97
|
+
continue;
|
|
98
|
+
changed = true;
|
|
99
|
+
if (result.bandCapsApplied.has(spanIndex) && cap.retries < MAX_BAND_CAP_RETRIES) {
|
|
100
|
+
caps.set(spanIndex, { ...cap, lines: cap.lines + 1, retries: cap.retries + 1 });
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
caps.delete(spanIndex);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const [spanIndex, cap] of result.bandCapProposals) {
|
|
107
|
+
if (caps.has(spanIndex) || tried.has(capKey(spanIndex, cap)))
|
|
108
|
+
continue;
|
|
109
|
+
caps.set(spanIndex, { ...cap });
|
|
110
|
+
changed = true;
|
|
111
|
+
}
|
|
112
|
+
if (!changed)
|
|
113
|
+
break;
|
|
114
|
+
if (caps.size === 0) {
|
|
115
|
+
// Every cap was dropped and nothing new came up: the plain layout.
|
|
116
|
+
result = initial;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
for (const [spanIndex, cap] of caps)
|
|
120
|
+
tried.add(capKey(spanIndex, cap));
|
|
121
|
+
result = runPass(caps);
|
|
122
|
+
passCount++;
|
|
123
|
+
}
|
|
124
|
+
// Never hand back a layout whose columns were capped for a box that did
|
|
125
|
+
// not arrive: strip the failing caps (dropping an earlier cap can unsettle
|
|
126
|
+
// a later one, hence the loop — each round removes at least one).
|
|
127
|
+
while (caps.size > 0) {
|
|
128
|
+
const failing = [...caps.keys()].filter((i) => !result.spanPlacedInBand.has(i));
|
|
129
|
+
if (failing.length === 0)
|
|
130
|
+
break;
|
|
131
|
+
for (const i of failing)
|
|
132
|
+
caps.delete(i);
|
|
133
|
+
if (caps.size === 0) {
|
|
134
|
+
result = initial;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
result = runPass(caps);
|
|
138
|
+
passCount++;
|
|
139
|
+
}
|
|
140
|
+
return { result, bandCaps: caps, passCount };
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=bandCaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bandCaps.js","sourceRoot":"","sources":["../../src/pipeline/bandCaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAkBH;qDACqD;AACrD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAYtC;;;;;oBAKoB;AACpB,MAAM,UAAU,YAAY,CAC1B,IAA0B,EAC1B,KAAa,EACb,eAAuC;IAEvC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,GAAG,IAAI;YAAE,SAAS;QAC5C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACtC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,GAAG,OAAO,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;qCACqC;AACrC,MAAM,UAAU,SAAS,CACvB,IAA0B,EAC1B,eAAuC;IAEvC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,eAAe,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5C,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,GAAc,EAAE,eAA+C;IAC1F,OAAO,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAClE,CAAC;AAED;4DAC4D;AAC5D,MAAM,UAAU,YAAY,CAAC,IAA0B,EAAE,MAAc;IACrE,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,eAAe,CAAC;IACjE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAE,GAAY,EAAU,EAAE,CACzD,GAAG,SAAS,IAAI,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;AAExE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAU,EACV,OAAsD;IAEtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAmB,CAAC;IACxC,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAEtF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC;gBAAE,SAAS;YACrD,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,OAAO,GAAG,oBAAoB,EAAE,CAAC;gBAChF,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACvD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBAAE,SAAS;YACvE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YAChC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,MAAM;QACpB,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACpB,mEAAmE;YACnE,MAAM,GAAG,OAAO,CAAC;YACjB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QACvE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,SAAS,EAAE,CAAC;IACd,CAAC;IAED,wEAAwE;IACxE,2EAA2E;IAC3E,kEAAkE;IAClE,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM;QAChC,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,GAAG,OAAO,CAAC;YACjB,MAAM;QACR,CAAC;QACD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,SAAS,EAAE,CAAC;IACd,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC/C,CAAC"}
|
package/dist/pipeline/build.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { PostextContent, PostextConfig } from '../types';
|
|
2
2
|
import { type VDTDocument } from '../vdt';
|
|
3
3
|
import type { MeasurementCache } from '../measure';
|
|
4
|
+
import { type LooseBudget } from './columnBalancing';
|
|
5
|
+
import { type BandCap, type BandPassReport } from './bandCaps';
|
|
4
6
|
export interface BuildDocumentOptions {
|
|
5
7
|
/**
|
|
6
8
|
* Cooperative cancellation hook. Called once per top-level content block
|
|
@@ -13,5 +15,44 @@ export interface BuildDocumentOptions {
|
|
|
13
15
|
export declare class BuildCancelledError extends Error {
|
|
14
16
|
constructor();
|
|
15
17
|
}
|
|
18
|
+
/** Cross-pass hints a placement pass consumes. All keyed by content-block
|
|
19
|
+
* index; every map is optional so the plain first pass carries none. */
|
|
20
|
+
export interface PassHints {
|
|
21
|
+
/** Column balancing: extra top spacing (px) per heading / list-end target. */
|
|
22
|
+
balanceExtraPx?: ReadonlyMap<number, number>;
|
|
23
|
+
/** Column balancing: K-P looseness per paragraph re-broken one line longer. */
|
|
24
|
+
balanceLooseness?: ReadonlyMap<number, number>;
|
|
25
|
+
/** Column balancing: shared budget of the loose candidates offered together
|
|
26
|
+
* (the pass stops loosening a column once it gained what it needs). */
|
|
27
|
+
balanceLooseBudget?: ReadonlyMap<number, LooseBudget>;
|
|
28
|
+
/** Band caps keyed by the span block's content index (see `bandCaps.ts`). */
|
|
29
|
+
bandCaps?: ReadonlyMap<number, BandCap>;
|
|
30
|
+
}
|
|
31
|
+
export interface PassResult extends BandPassReport {
|
|
32
|
+
doc: VDTDocument;
|
|
33
|
+
/** Pages whose break into the next page was explicit (`:::pagebreak`,
|
|
34
|
+
* heading `breakBefore`, chapter opener) rather than natural content
|
|
35
|
+
* overflow — those pages keep their short last column. */
|
|
36
|
+
forcedBreakPages: Set<number>;
|
|
37
|
+
bandCapProposals: Map<number, BandCap>;
|
|
38
|
+
spanPlacedInBand: Set<number>;
|
|
39
|
+
bandCapsApplied: Set<number>;
|
|
40
|
+
/** Column balancing: per loose paragraph tried in this pass, the tracking
|
|
41
|
+
* (thousandths of an em) that gained its extra line — `null` when no rung
|
|
42
|
+
* of the ladder did, so the driver can blacklist it. Candidates left
|
|
43
|
+
* untried because their column's budget was already met are absent. */
|
|
44
|
+
looseOutcome: Map<number, number | null>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Single placement pass. `hints` carries the cross-pass adjustments: the
|
|
48
|
+
* column-balancing spacing / looseness and the band caps of page-span
|
|
49
|
+
* blocks. Besides the document it reports `forcedBreakPages` (for
|
|
50
|
+
* balancing) and the band-cap bookkeeping the driver in `buildDocument`
|
|
51
|
+
* needs — new cap proposals, the span blocks that landed in their capped
|
|
52
|
+
* band, and the caps that were actually applied.
|
|
53
|
+
*
|
|
54
|
+
* @internal Exposed for tests only; use `buildDocument`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildDocumentPass(content: PostextContent, config?: PostextConfig, cache?: MeasurementCache, options?: BuildDocumentOptions, hints?: PassHints): PassResult;
|
|
16
57
|
export declare function buildDocument(content: PostextContent, config?: PostextConfig, cache?: MeasurementCache, options?: BuildDocumentOptions): VDTDocument;
|
|
17
58
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/pipeline/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/pipeline/build.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAA8C,MAAM,UAAU,CAAC;AAG1G,OAAO,EAIL,KAAK,WAAW,EAKjB,MAAM,QAAQ,CAAC;AAWhB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA2DnD,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;CAC9B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAWD;yEACyE;AACzE,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;4EACwE;IACxE,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,GAAG,EAAE,WAAW,CAAC;IACjB;;+DAE2D;IAC3D,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B;;;4EAGwE;IACxE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C;AAuCD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,EACtB,KAAK,CAAC,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,KAAK,GAAE,SAAc,GACpB,UAAU,CAu9CZ;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,cAAc,EACvB,MAAM,CAAC,EAAE,aAAa,EACtB,KAAK,CAAC,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,WAAW,CA6Fb"}
|