postext 0.3.30 → 0.3.31
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__/pipeline/paragraphStyles.test.js +19 -0
- package/dist/__tests__/pipeline/paragraphStyles.test.js.map +1 -1
- package/dist/__tests__/pipeline/raggedLines.test.d.ts +2 -0
- package/dist/__tests__/pipeline/raggedLines.test.d.ts.map +1 -0
- package/dist/__tests__/pipeline/raggedLines.test.js +26 -0
- package/dist/__tests__/pipeline/raggedLines.test.js.map +1 -0
- package/dist/__tests__/pipeline/spanFloatAtCut.test.js +6 -2
- package/dist/__tests__/pipeline/spanFloatAtCut.test.js.map +1 -1
- package/dist/__tests__/pipeline/trailingBand.test.js +67 -0
- package/dist/__tests__/pipeline/trailingBand.test.js.map +1 -1
- package/dist/pipeline/bandCaps.d.ts +10 -6
- package/dist/pipeline/bandCaps.d.ts.map +1 -1
- package/dist/pipeline/bandCaps.js +33 -17
- package/dist/pipeline/bandCaps.js.map +1 -1
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +35 -19
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/columnBalancing.d.ts.map +1 -1
- package/dist/pipeline/columnBalancing.js +4 -1
- package/dist/pipeline/columnBalancing.js.map +1 -1
- package/dist/pipeline/paragraphContainers.d.ts.map +1 -1
- package/dist/pipeline/paragraphContainers.js +4 -1
- package/dist/pipeline/paragraphContainers.js.map +1 -1
- package/dist/pipeline/raggedLines.d.ts +16 -0
- package/dist/pipeline/raggedLines.d.ts.map +1 -0
- package/dist/pipeline/raggedLines.js +28 -0
- package/dist/pipeline/raggedLines.js.map +1 -0
- package/dist/vdt.d.ts +4 -0
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js.map +1 -1
- package/package.json +1 -1
- package/dist/__tests__/pipeline/raggedUrl.test.d.ts +0 -2
- package/dist/__tests__/pipeline/raggedUrl.test.d.ts.map +0 -1
- package/dist/__tests__/pipeline/raggedUrl.test.js +0 -22
- package/dist/__tests__/pipeline/raggedUrl.test.js.map +0 -1
- package/dist/pipeline/raggedUrl.d.ts +0 -15
- package/dist/pipeline/raggedUrl.d.ts.map +0 -1
- package/dist/pipeline/raggedUrl.js +0 -28
- package/dist/pipeline/raggedUrl.js.map +0 -1
package/dist/pipeline/build.js
CHANGED
|
@@ -24,7 +24,10 @@ import { defaultResourceTypes } from '../defaults/resourceTypes';
|
|
|
24
24
|
import { buildHeadersAndFooters, measureHeadingAdvancedDesignHeight } from './headerFooter';
|
|
25
25
|
import { totalGapLines, proposeBalanceLines, collectColumnGaps, firstDivergentColumn, MAX_BALANCING_PASSES, balanceKey } from './columnBalancing';
|
|
26
26
|
import { applyBandCap, uncapBand, columnBottom, bandCapLines, bandTop, resolveBandCaps, resolveTrailingCaps, bandCapLinesAroundZone, } from './bandCaps';
|
|
27
|
-
import {
|
|
27
|
+
import { raggedLooseLines } from './raggedLines';
|
|
28
|
+
/** Tolerance for "does this block fit" checks against a column's free
|
|
29
|
+
* height, absorbing floating-point drift between grid multiples. */
|
|
30
|
+
const FIT_EPS = 0.01;
|
|
28
31
|
export class BuildCancelledError extends Error {
|
|
29
32
|
constructor() {
|
|
30
33
|
super('Build cancelled');
|
|
@@ -828,7 +831,7 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
828
831
|
for (const [spanIndex, cap] of bandCaps) {
|
|
829
832
|
if (cap.startContentIndex !== contentIndex || cap.startPart !== part)
|
|
830
833
|
continue;
|
|
831
|
-
applyBandCap(bandColumns(page, band), cap.lines * baselineGrid, uncappedBottoms, cap.zone);
|
|
834
|
+
applyBandCap(bandColumns(page, band), cap.lines * baselineGrid, uncappedBottoms, cap.zone, cap.kind === 'trailing');
|
|
832
835
|
activeCap = { spanIndex, pageIndex: page.index, band };
|
|
833
836
|
bandCapsApplied.add(spanIndex);
|
|
834
837
|
break;
|
|
@@ -863,13 +866,16 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
863
866
|
const cols = bandColumns(page, band).filter((c) => c.bbox.height > 0.5);
|
|
864
867
|
if (cols.length < 2 || cols.some((c) => c.forcedBreak))
|
|
865
868
|
return;
|
|
866
|
-
if (
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
spanPlacedInBand.add(boundaryIndex);
|
|
870
|
-
}
|
|
869
|
+
if (activeCap && activeCap.spanIndex === boundaryIndex
|
|
870
|
+
&& activeCap.pageIndex === page.index && activeCap.band === band) {
|
|
871
|
+
spanPlacedInBand.add(boundaryIndex);
|
|
871
872
|
return;
|
|
872
873
|
}
|
|
874
|
+
// A cap in force for this boundary that did not open the band the
|
|
875
|
+
// boundary is reached in (an earlier cap moved the flow under it, or
|
|
876
|
+
// its own band overflowed) still gets a fresh proposal below: the
|
|
877
|
+
// driver replaces a cap that no longer applies with it, and ignores it
|
|
878
|
+
// while retrying an applied cap a line taller.
|
|
873
879
|
if (activeCap && activeCap.pageIndex === page.index && activeCap.band === band)
|
|
874
880
|
return;
|
|
875
881
|
if (!cols.some((c) => c.blocks.length > 0))
|
|
@@ -1949,11 +1955,16 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
1949
1955
|
? paragraphContainers.byId.get(rawBlock.containerId)
|
|
1950
1956
|
: undefined;
|
|
1951
1957
|
if (pc) {
|
|
1958
|
+
// Margins collapse with the pending spacing; a negative one pulls
|
|
1959
|
+
// the flow up past it instead (the container starts inside the
|
|
1960
|
+
// space the previous block left, or the next block inside the
|
|
1961
|
+
// container's).
|
|
1962
|
+
const collapse = (margin) => margin < 0 ? pendingSpacing + margin : Math.max(pendingSpacing, margin);
|
|
1952
1963
|
if (rawBlock.type === 'containerStart') {
|
|
1953
|
-
pendingSpacing =
|
|
1964
|
+
pendingSpacing = collapse(pc.marginTopPx);
|
|
1954
1965
|
}
|
|
1955
1966
|
else if (contentBlocks[blockIdx - 1]?.type !== 'paragraph') {
|
|
1956
|
-
pendingSpacing =
|
|
1967
|
+
pendingSpacing = collapse(pc.marginBottomPx);
|
|
1957
1968
|
}
|
|
1958
1969
|
}
|
|
1959
1970
|
continue;
|
|
@@ -2120,8 +2131,9 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2120
2131
|
// List items may split too — orphan/widow protection per-list is gated by
|
|
2121
2132
|
// `avoidOrphansInLists` / `avoidWidowsInLists`; bullet stays on first part.
|
|
2122
2133
|
const canSplit = vdtType === 'paragraph' || vdtType === 'blockquote' || vdtType === 'listItem';
|
|
2123
|
-
// A justified line
|
|
2124
|
-
|
|
2134
|
+
// A justified line the breaker could not fill (a link breaking at its
|
|
2135
|
+
// joints, a last word that cannot come up) is set ragged, not stretched.
|
|
2136
|
+
let remainingLines = [...raggedLooseLines(measured.lines, style.textAlign)];
|
|
2125
2137
|
let partIndex = 0;
|
|
2126
2138
|
/** Times this block left an EMPTY short column (see `shortColumn`) —
|
|
2127
2139
|
* bounded so a page whose columns are all short (footnotes, design
|
|
@@ -2251,7 +2263,7 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2251
2263
|
: 1;
|
|
2252
2264
|
const splitAt = remainingLines.length - 1;
|
|
2253
2265
|
if (splitAt >= effectiveWidowMin) {
|
|
2254
|
-
if (spacingBefore
|
|
2266
|
+
if (spacingBefore !== 0)
|
|
2255
2267
|
curCol.availableHeight -= spacingBefore;
|
|
2256
2268
|
const splitLines = remainingLines.slice(0, splitAt);
|
|
2257
2269
|
const blk = createVDTBlock(id, vdtType, style.fontString, style.color, style.textAlign);
|
|
@@ -2327,8 +2339,10 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2327
2339
|
const shortColumn = shortColumnMoves < 4
|
|
2328
2340
|
&& !uncappedBottoms.has(curCol)
|
|
2329
2341
|
&& curCol.bbox.height < contentArea.height - baselineGrid;
|
|
2330
|
-
// Block fits in current column
|
|
2331
|
-
|
|
2342
|
+
// Block fits in current column (a hair of tolerance: a capped column
|
|
2343
|
+
// and the grid lines balancing adds above a block differ by floating
|
|
2344
|
+
// point noise, which must not push the block over the cut).
|
|
2345
|
+
if (effectiveRemainHeight <= effectiveAvailable + FIT_EPS) {
|
|
2332
2346
|
// Heading keep-with-next: never leave a heading as the last block of a
|
|
2333
2347
|
// column. If the following (non-heading) block wouldn't have room to
|
|
2334
2348
|
// place at least its widow-minimum number of lines after this heading,
|
|
@@ -2373,8 +2387,8 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2373
2387
|
continue;
|
|
2374
2388
|
}
|
|
2375
2389
|
}
|
|
2376
|
-
// Consume spacing
|
|
2377
|
-
if (spacingBefore
|
|
2390
|
+
// Consume spacing (negative: a container margin pulling the block up)
|
|
2391
|
+
if (spacingBefore !== 0) {
|
|
2378
2392
|
curCol.availableHeight -= spacingBefore;
|
|
2379
2393
|
}
|
|
2380
2394
|
const partId = partIndex === 0 ? id : `${id}-cont-${partIndex}`;
|
|
@@ -2437,7 +2451,9 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2437
2451
|
// the grid (e.g. marginBottom is an exact multiple of baselineGrid),
|
|
2438
2452
|
// don't round up to the next line.
|
|
2439
2453
|
const snappedBottom = Math.ceil((naturalBottom - 0.01) / baselineGrid) * baselineGrid;
|
|
2440
|
-
|
|
2454
|
+
// A negative margin below a container tail may snap the flow back
|
|
2455
|
+
// above the text's own bottom; never below the block's top.
|
|
2456
|
+
h = Math.max(0, snappedBottom - usedHeight);
|
|
2441
2457
|
}
|
|
2442
2458
|
placeBlockInColumn(blk, h, curCol, cursor);
|
|
2443
2459
|
finalizeListItem(blk, partIndex === 0);
|
|
@@ -2483,8 +2499,8 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2483
2499
|
slackWeight: resolved.bodyText.slackWeight,
|
|
2484
2500
|
});
|
|
2485
2501
|
if (choice.splitAt > 0) {
|
|
2486
|
-
// Consume spacing
|
|
2487
|
-
if (spacingBefore
|
|
2502
|
+
// Consume spacing (negative: a container margin pulling the block up)
|
|
2503
|
+
if (spacingBefore !== 0) {
|
|
2488
2504
|
curCol.availableHeight -= spacingBefore;
|
|
2489
2505
|
}
|
|
2490
2506
|
const partId = partIndex === 0 ? id : `${id}-cont-${partIndex}`;
|