postext 0.3.39 → 0.3.41
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/__bench__/chapter.bench.test.d.ts +2 -0
- package/dist/__bench__/chapter.bench.test.d.ts.map +1 -0
- package/dist/__bench__/chapter.bench.test.js +80 -0
- package/dist/__bench__/chapter.bench.test.js.map +1 -0
- package/dist/__tests__/buildAsync.test.d.ts +2 -0
- package/dist/__tests__/buildAsync.test.d.ts.map +1 -0
- package/dist/__tests__/buildAsync.test.js +50 -0
- package/dist/__tests__/buildAsync.test.js.map +1 -0
- package/dist/__tests__/hyphenateMemo.test.d.ts +2 -0
- package/dist/__tests__/hyphenateMemo.test.d.ts.map +1 -0
- package/dist/__tests__/hyphenateMemo.test.js +21 -0
- package/dist/__tests__/hyphenateMemo.test.js.map +1 -0
- package/dist/__tests__/knuthPlassMerge.test.d.ts +2 -0
- package/dist/__tests__/knuthPlassMerge.test.d.ts.map +1 -0
- package/dist/__tests__/knuthPlassMerge.test.js +55 -0
- package/dist/__tests__/knuthPlassMerge.test.js.map +1 -0
- package/dist/__tests__/memos.test.d.ts +2 -0
- package/dist/__tests__/memos.test.d.ts.map +1 -0
- package/dist/__tests__/memos.test.js +37 -0
- package/dist/__tests__/memos.test.js.map +1 -0
- package/dist/canvas-backend/index.d.ts +5 -0
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +7 -4
- package/dist/canvas-backend/index.js.map +1 -1
- package/dist/hyphenate.d.ts.map +1 -1
- package/dist/hyphenate.js +50 -1
- package/dist/hyphenate.js.map +1 -1
- package/dist/knuthPlass/breakpoints.d.ts.map +1 -1
- package/dist/knuthPlass/breakpoints.js +7 -1
- package/dist/knuthPlass/breakpoints.js.map +1 -1
- package/dist/knuthPlass/types.d.ts +8 -0
- package/dist/knuthPlass/types.d.ts.map +1 -1
- package/dist/measure/plain.d.ts.map +1 -1
- package/dist/measure/plain.js +1 -0
- package/dist/measure/plain.js.map +1 -1
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +1 -0
- package/dist/measure/rich.js.map +1 -1
- package/dist/parse/blockParser.d.ts +5 -3
- package/dist/parse/blockParser.d.ts.map +1 -1
- package/dist/parse/blockParser.js +32 -21
- package/dist/parse/blockParser.js.map +1 -1
- package/dist/pipeline/bandCaps.d.ts +16 -0
- package/dist/pipeline/bandCaps.d.ts.map +1 -1
- package/dist/pipeline/bandCaps.js +22 -0
- package/dist/pipeline/bandCaps.js.map +1 -1
- package/dist/pipeline/build.d.ts +33 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +63 -12
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/config.d.ts.map +1 -1
- package/dist/pipeline/config.js +18 -0
- package/dist/pipeline/config.js.map +1 -1
- package/dist/pipeline/index.d.ts +2 -2
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +1 -1
- package/dist/pipeline/index.js.map +1 -1
- package/dist/worker/client.d.ts +18 -2
- package/dist/worker/client.d.ts.map +1 -1
- package/dist/worker/client.js +28 -3
- package/dist/worker/client.js.map +1 -1
- package/dist/worker/layout.worker.js +135 -56
- package/dist/worker/layout.worker.js.map +1 -1
- package/dist/worker/protocol.d.ts +27 -2
- package/dist/worker/protocol.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/pipeline/build.js
CHANGED
|
@@ -26,7 +26,7 @@ import { computeHeadingContext, computeResourceNumbering, } from './resourceNumb
|
|
|
26
26
|
import { defaultResourceTypes } from '../defaults/resourceTypes';
|
|
27
27
|
import { buildHeadersAndFooters, measureHeadingAdvancedDesignHeight } from './headerFooter';
|
|
28
28
|
import { proposeBalanceLines, collectColumnGaps, firstDivergentColumn, gapLinesIn, pageSegments, MAX_BALANCING_PASSES, MAX_BALANCING_PASSES_PER_DOCUMENT, balanceKey } from './columnBalancing';
|
|
29
|
-
import { applyBandCap, uncapBand, columnBottom, bandCapLines, bandTop,
|
|
29
|
+
import { applyBandCap, uncapBand, columnBottom, bandCapLines, bandTop, resolveBandCapsGen, drainPasses, resolveTrailingCapsGen, bandCapLinesAroundZone, } from './bandCaps';
|
|
30
30
|
import { raggedLooseLines } from './raggedLines';
|
|
31
31
|
/** Tolerance for "does this block fit" checks against a column's free
|
|
32
32
|
* height, absorbing floating-point drift between grid multiples. */
|
|
@@ -2923,6 +2923,48 @@ export function buildDocumentPass(content, config, cache, options, hints = {}) {
|
|
|
2923
2923
|
* first, for the page labels it prints to settle. */
|
|
2924
2924
|
const MAX_TOC_ROUNDS = 3;
|
|
2925
2925
|
export function buildDocument(content, config, cache, options) {
|
|
2926
|
+
return drainPasses(buildDocumentGen(content, config, cache, options));
|
|
2927
|
+
}
|
|
2928
|
+
/** Let the event loop turn: `scheduler.yield()` where it exists, else a
|
|
2929
|
+
* message-channel hop (a `setTimeout(0)` is clamped to 4 ms once nested). */
|
|
2930
|
+
export function yieldToEventLoop() {
|
|
2931
|
+
const scheduler = globalThis.scheduler;
|
|
2932
|
+
if (scheduler?.yield)
|
|
2933
|
+
return scheduler.yield();
|
|
2934
|
+
if (typeof MessageChannel !== 'undefined') {
|
|
2935
|
+
return new Promise((resolve) => {
|
|
2936
|
+
const channel = new MessageChannel();
|
|
2937
|
+
channel.port1.onmessage = () => {
|
|
2938
|
+
channel.port1.close();
|
|
2939
|
+
resolve();
|
|
2940
|
+
};
|
|
2941
|
+
channel.port2.postMessage(null);
|
|
2942
|
+
});
|
|
2943
|
+
}
|
|
2944
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
2945
|
+
}
|
|
2946
|
+
/**
|
|
2947
|
+
* {@link buildDocument}, yielding to the event loop between placement
|
|
2948
|
+
* passes. A build is several passes (band caps, column balancing, contents
|
|
2949
|
+
* rounds), each a synchronous re-placement of the document; in a worker
|
|
2950
|
+
* this lets a `cancel` posted mid-build be observed at the next pass
|
|
2951
|
+
* boundary — `shouldCancel` is polled there as well as inside a pass —
|
|
2952
|
+
* instead of after the whole build.
|
|
2953
|
+
*/
|
|
2954
|
+
export async function buildDocumentAsync(content, config, cache, options) {
|
|
2955
|
+
const gen = buildDocumentGen(content, config, cache, options);
|
|
2956
|
+
const pause = options?.yieldBetweenPasses ?? yieldToEventLoop;
|
|
2957
|
+
for (;;) {
|
|
2958
|
+
const step = gen.next();
|
|
2959
|
+
if (step.done)
|
|
2960
|
+
return step.value;
|
|
2961
|
+
await pause();
|
|
2962
|
+
if (options?.shouldCancel?.())
|
|
2963
|
+
throw new BuildCancelledError();
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
/** The build as a generator: one `yield` after every placement pass. */
|
|
2967
|
+
export function* buildDocumentGen(content, config, cache, options) {
|
|
2926
2968
|
// A document printing its own table of contents (`:::toc` with no
|
|
2927
2969
|
// host-supplied outline) is laid out with the page labels of the previous
|
|
2928
2970
|
// build until they no longer change: the contents' own length moves what
|
|
@@ -2932,36 +2974,44 @@ export function buildDocument(content, config, cache, options) {
|
|
|
2932
2974
|
const parsed = parseMarkdownMemo(extractFrontmatter(content.markdown).content);
|
|
2933
2975
|
if (hasTocDirective(parsed)) {
|
|
2934
2976
|
let outline = computeOutline(parsed, resolveAllConfig(config), content.continuation?.headings);
|
|
2935
|
-
let doc = buildDocumentBalanced({ ...content, outline }, config, cache, options);
|
|
2977
|
+
let doc = yield* buildDocumentBalanced({ ...content, outline }, config, cache, options, 0);
|
|
2936
2978
|
for (let round = 0; round < MAX_TOC_ROUNDS; round++) {
|
|
2937
2979
|
const after = outlineFromDoc(doc, outline);
|
|
2938
2980
|
if (sameOutline(after, outline))
|
|
2939
2981
|
break;
|
|
2940
2982
|
outline = after;
|
|
2941
|
-
doc = buildDocumentBalanced({ ...content, outline }, config, cache, options);
|
|
2983
|
+
doc = yield* buildDocumentBalanced({ ...content, outline }, config, cache, options, round + 1);
|
|
2942
2984
|
}
|
|
2943
2985
|
return doc;
|
|
2944
2986
|
}
|
|
2945
2987
|
}
|
|
2946
|
-
return buildDocumentBalanced(content, config, cache, options);
|
|
2988
|
+
return yield* buildDocumentBalanced(content, config, cache, options);
|
|
2947
2989
|
}
|
|
2948
|
-
|
|
2990
|
+
const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now());
|
|
2991
|
+
function* buildDocumentBalanced(content, config, cache, options, tocRound = 0) {
|
|
2949
2992
|
// Each pass reports its own progress, numbered in build order.
|
|
2950
2993
|
let passIndex = 0;
|
|
2951
2994
|
const onProgress = options?.onProgress;
|
|
2995
|
+
const onPass = options?.onPass;
|
|
2952
2996
|
const passOptions = onProgress
|
|
2953
2997
|
? { ...options, onProgress: (p) => onProgress({ ...p, pass: passIndex }) }
|
|
2954
2998
|
: options;
|
|
2955
2999
|
const runPass = (hints) => {
|
|
2956
3000
|
passIndex++;
|
|
2957
|
-
|
|
3001
|
+
const started = onPass ? now() : 0;
|
|
3002
|
+
const result = buildDocumentPass(content, config, cache, passOptions, hints);
|
|
3003
|
+
onPass?.({ pass: passIndex, tocRound, ms: now() - started, pages: result.doc.pages.length });
|
|
3004
|
+
return result;
|
|
2958
3005
|
};
|
|
3006
|
+
// The first pass is a pass too: let a cancel land before the caps run.
|
|
3007
|
+
const initial = runPass();
|
|
3008
|
+
yield;
|
|
2959
3009
|
// --- Band caps (page-span blocks mid-page) -----------------------------
|
|
2960
3010
|
// A span block that arrived in an uneven band proposes a cap; the driver
|
|
2961
3011
|
// re-places the document with it (and grows / drops caps whose band
|
|
2962
3012
|
// overflowed) before balancing runs. Documents without such blocks get
|
|
2963
3013
|
// their first pass back untouched — no extra pass.
|
|
2964
|
-
const bands =
|
|
3014
|
+
const bands = yield* resolveBandCapsGen(initial, (bandCaps) => runPass({ bandCaps }));
|
|
2965
3015
|
let best = bands.result;
|
|
2966
3016
|
const bandCaps = bands.bandCaps;
|
|
2967
3017
|
let passCount = bands.passCount;
|
|
@@ -3154,7 +3204,7 @@ function buildDocumentBalanced(content, config, cache, options) {
|
|
|
3154
3204
|
return blacklist(null);
|
|
3155
3205
|
};
|
|
3156
3206
|
let balancingPasses = 0;
|
|
3157
|
-
|
|
3207
|
+
function* balance() {
|
|
3158
3208
|
while (balancingPasses < MAX_BALANCING_PASSES_PER_DOCUMENT) {
|
|
3159
3209
|
const active = segments.filter((s) => !s.done);
|
|
3160
3210
|
if (active.length === 0)
|
|
@@ -3224,6 +3274,7 @@ function buildDocumentBalanced(content, config, cache, options) {
|
|
|
3224
3274
|
const next = runPass(hintsFrom(proposal.lines, proposal.loose, proposal.looseBudget));
|
|
3225
3275
|
passCount++;
|
|
3226
3276
|
balancingPasses++;
|
|
3277
|
+
yield;
|
|
3227
3278
|
const nextGaps = collectColumnGaps(next.doc, next.forcedBreakPages);
|
|
3228
3279
|
const capPage = pageOfContent(best.doc);
|
|
3229
3280
|
const accepted = [];
|
|
@@ -3287,9 +3338,9 @@ function buildDocumentBalanced(content, config, cache, options) {
|
|
|
3287
3338
|
if (accepted.length > 0)
|
|
3288
3339
|
best = spliceSegments(next, accepted);
|
|
3289
3340
|
}
|
|
3290
|
-
}
|
|
3341
|
+
}
|
|
3291
3342
|
resetSegments();
|
|
3292
|
-
balance();
|
|
3343
|
+
yield* balance();
|
|
3293
3344
|
// --- Trailing bands (closing columns cut level) -------------------------
|
|
3294
3345
|
// Once the balancing levers have settled the earlier pages, level the
|
|
3295
3346
|
// closing band of every chapter / the document with a trailing cap. It is
|
|
@@ -3300,14 +3351,14 @@ function buildDocumentBalanced(content, config, cache, options) {
|
|
|
3300
3351
|
// fill what the cut left short (a column ending a line under the cap).
|
|
3301
3352
|
if (balancing.trailing) {
|
|
3302
3353
|
const frozen = hintsFrom(applied.lines, applied.loose);
|
|
3303
|
-
const trailing =
|
|
3354
|
+
const trailing = yield* resolveTrailingCapsGen(best, bandCaps, (caps) => runPass({ ...frozen, bandCaps: caps }));
|
|
3304
3355
|
passCount += trailing.passCount;
|
|
3305
3356
|
if (trailing.result !== best) {
|
|
3306
3357
|
best = trailing.result;
|
|
3307
3358
|
for (const [i, cap] of trailing.caps)
|
|
3308
3359
|
bandCaps.set(i, cap);
|
|
3309
3360
|
resetSegments();
|
|
3310
|
-
balance();
|
|
3361
|
+
yield* balance();
|
|
3311
3362
|
}
|
|
3312
3363
|
}
|
|
3313
3364
|
best.doc.iterationCount = passCount;
|