postext 1.39.1 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/comics/frames.test.js +0 -8
- package/dist/__tests__/comics/frames.test.js.map +1 -1
- package/dist/__tests__/comics/textPanelsStripsSpreads.test.d.ts +2 -0
- package/dist/__tests__/comics/textPanelsStripsSpreads.test.d.ts.map +1 -0
- package/dist/__tests__/comics/textPanelsStripsSpreads.test.js +277 -0
- package/dist/__tests__/comics/textPanelsStripsSpreads.test.js.map +1 -0
- package/dist/__tests__/composed/crossChapterJumps.test.d.ts +2 -0
- package/dist/__tests__/composed/crossChapterJumps.test.d.ts.map +1 -0
- package/dist/__tests__/composed/crossChapterJumps.test.js +299 -0
- package/dist/__tests__/composed/crossChapterJumps.test.js.map +1 -0
- package/dist/__tests__/composed/fit.test.js +77 -0
- package/dist/__tests__/composed/fit.test.js.map +1 -1
- package/dist/__tests__/composed/frameModesChain.test.d.ts +2 -0
- package/dist/__tests__/composed/frameModesChain.test.d.ts.map +1 -0
- package/dist/__tests__/composed/frameModesChain.test.js +69 -0
- package/dist/__tests__/composed/frameModesChain.test.js.map +1 -0
- package/dist/__tests__/composed/framePictures.test.d.ts +2 -0
- package/dist/__tests__/composed/framePictures.test.d.ts.map +1 -0
- package/dist/__tests__/composed/framePictures.test.js +121 -0
- package/dist/__tests__/composed/framePictures.test.js.map +1 -0
- package/dist/__tests__/composed/frameWritingMode.test.js +79 -3
- package/dist/__tests__/composed/frameWritingMode.test.js.map +1 -1
- package/dist/__tests__/composed/labels.test.js +19 -0
- package/dist/__tests__/composed/labels.test.js.map +1 -1
- package/dist/__tests__/composed/labelsMirrored.test.d.ts +2 -0
- package/dist/__tests__/composed/labelsMirrored.test.d.ts.map +1 -0
- package/dist/__tests__/composed/labelsMirrored.test.js +128 -0
- package/dist/__tests__/composed/labelsMirrored.test.js.map +1 -0
- package/dist/__tests__/composed/measureMemo.test.d.ts +2 -0
- package/dist/__tests__/composed/measureMemo.test.d.ts.map +1 -0
- package/dist/__tests__/composed/measureMemo.test.js +45 -0
- package/dist/__tests__/composed/measureMemo.test.js.map +1 -0
- package/dist/__tests__/composedTemplates.test.js +5 -2
- package/dist/__tests__/composedTemplates.test.js.map +1 -1
- package/dist/__tests__/exports.test.js +6 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/migrate/labelsOnPictures.test.js +49 -1
- package/dist/__tests__/migrate/labelsOnPictures.test.js.map +1 -1
- package/dist/bundle/book.d.ts +5 -0
- package/dist/bundle/book.d.ts.map +1 -1
- package/dist/bundle/book.js +53 -7
- package/dist/bundle/book.js.map +1 -1
- package/dist/bundle/layoutCache.d.ts +5 -0
- package/dist/bundle/layoutCache.d.ts.map +1 -1
- package/dist/bundle/layoutCache.js.map +1 -1
- package/dist/canvas-backend/composed.d.ts +2 -2
- package/dist/canvas-backend/composed.d.ts.map +1 -1
- package/dist/canvas-backend/composed.js +11 -2
- package/dist/canvas-backend/composed.js.map +1 -1
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +10 -1
- package/dist/canvas-backend/index.js.map +1 -1
- package/dist/canvas-backend/mirrorFrame.d.ts +19 -0
- package/dist/canvas-backend/mirrorFrame.d.ts.map +1 -1
- package/dist/canvas-backend/mirrorFrame.js +47 -0
- package/dist/canvas-backend/mirrorFrame.js.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
- package/dist/canvas-backend/renderResourceBlock.js +35 -26
- package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
- package/dist/comics/frames.d.ts +5 -0
- package/dist/comics/frames.d.ts.map +1 -1
- package/dist/comics/frames.js +7 -0
- package/dist/comics/frames.js.map +1 -1
- package/dist/comics/layoutPage.d.ts +5 -0
- package/dist/comics/layoutPage.d.ts.map +1 -1
- package/dist/comics/layoutPage.js +9 -0
- package/dist/comics/layoutPage.js.map +1 -1
- package/dist/comics/sourceMap.d.ts.map +1 -1
- package/dist/comics/sourceMap.js +6 -4
- package/dist/comics/sourceMap.js.map +1 -1
- package/dist/comics/spread.d.ts +6 -1
- package/dist/comics/spread.d.ts.map +1 -1
- package/dist/comics/spread.js +15 -1
- package/dist/comics/spread.js.map +1 -1
- package/dist/comics/textPanels.d.ts +30 -6
- package/dist/comics/textPanels.d.ts.map +1 -1
- package/dist/comics/textPanels.js +226 -69
- package/dist/comics/textPanels.js.map +1 -1
- package/dist/comics/transform.d.ts.map +1 -1
- package/dist/comics/transform.js +4 -2
- package/dist/comics/transform.js.map +1 -1
- package/dist/composed/carry.d.ts +53 -0
- package/dist/composed/carry.d.ts.map +1 -0
- package/dist/composed/carry.js +114 -0
- package/dist/composed/carry.js.map +1 -0
- package/dist/composed/carryTypes.d.ts +76 -0
- package/dist/composed/carryTypes.d.ts.map +1 -0
- package/dist/composed/carryTypes.js +2 -0
- package/dist/composed/carryTypes.js.map +1 -0
- package/dist/composed/continuation.d.ts +8 -0
- package/dist/composed/continuation.d.ts.map +1 -1
- package/dist/composed/continuation.js.map +1 -1
- package/dist/composed/labels.d.ts +9 -0
- package/dist/composed/labels.d.ts.map +1 -1
- package/dist/composed/labels.js +36 -4
- package/dist/composed/labels.js.map +1 -1
- package/dist/composed/paint.d.ts +10 -6
- package/dist/composed/paint.d.ts.map +1 -1
- package/dist/composed/paint.js +38 -7
- package/dist/composed/paint.js.map +1 -1
- package/dist/composed/sourceMap.d.ts +16 -0
- package/dist/composed/sourceMap.d.ts.map +1 -1
- package/dist/composed/sourceMap.js +43 -9
- package/dist/composed/sourceMap.js.map +1 -1
- package/dist/composed/templates.d.ts.map +1 -1
- package/dist/composed/templates.js +9 -4
- package/dist/composed/templates.js.map +1 -1
- package/dist/composed/types.d.ts +9 -4
- package/dist/composed/types.d.ts.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +36 -14
- package/dist/html-backend.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/migrate/pageDesign.d.ts +6 -1
- package/dist/migrate/pageDesign.d.ts.map +1 -1
- package/dist/migrate/pageDesign.js +26 -10
- package/dist/migrate/pageDesign.js.map +1 -1
- package/dist/migrate/textToMarkdown.js +4 -3
- package/dist/migrate/textToMarkdown.js.map +1 -1
- package/dist/pipeline/build.d.ts +12 -0
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +304 -25
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts +13 -17
- package/dist/pipeline/calloutLayout.d.ts.map +1 -1
- package/dist/pipeline/calloutLayout.js +20 -1
- package/dist/pipeline/calloutLayout.js.map +1 -1
- package/dist/pipeline/composedLayout.d.ts +12 -0
- package/dist/pipeline/composedLayout.d.ts.map +1 -1
- package/dist/pipeline/composedLayout.js +179 -25
- package/dist/pipeline/composedLayout.js.map +1 -1
- package/dist/pipeline/contentWarnings.d.ts.map +1 -1
- package/dist/pipeline/contentWarnings.js +5 -3
- package/dist/pipeline/contentWarnings.js.map +1 -1
- package/dist/pipeline/continuation.d.ts +11 -0
- package/dist/pipeline/continuation.d.ts.map +1 -1
- package/dist/pipeline/continuation.js +36 -0
- package/dist/pipeline/continuation.js.map +1 -1
- package/dist/pipeline/cutTypes.d.ts +42 -0
- package/dist/pipeline/cutTypes.d.ts.map +1 -0
- package/dist/pipeline/cutTypes.js +6 -0
- package/dist/pipeline/cutTypes.js.map +1 -0
- package/dist/pipeline/frameLayout.d.ts +8 -22
- package/dist/pipeline/frameLayout.d.ts.map +1 -1
- package/dist/pipeline/frameLayout.js +1 -0
- package/dist/pipeline/frameLayout.js.map +1 -1
- package/dist/pipeline/index.d.ts +2 -1
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +2 -1
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/measureMemo.d.ts +39 -0
- package/dist/pipeline/measureMemo.d.ts.map +1 -0
- package/dist/pipeline/measureMemo.js +61 -0
- package/dist/pipeline/measureMemo.js.map +1 -0
- package/dist/pipeline/mirrorFrame.d.ts +2 -1
- package/dist/pipeline/mirrorFrame.d.ts.map +1 -1
- package/dist/pipeline/mirrorFrame.js +31 -5
- package/dist/pipeline/mirrorFrame.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +53 -0
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js.map +1 -1
- package/package.json +1 -1
package/dist/pipeline/build.js
CHANGED
|
@@ -44,7 +44,8 @@ import { layoutComposedSpread } from '../composed/spread';
|
|
|
44
44
|
import { assignJumpReceivers, assignReceivers, continuationTarget, MAX_CONTINUATION_PAGES } from '../composed/continuation';
|
|
45
45
|
import { frameElementId } from '../composed/ids';
|
|
46
46
|
import { nextFrameOf } from '../composed/geometry';
|
|
47
|
-
import { composedPageAt, frameStyleOf, layoutComposedPage, planComposedPages } from './composedLayout';
|
|
47
|
+
import { carriedPass, composedPageAt, frameStyleOf, layoutComposedPage, planComposedPages } from './composedLayout';
|
|
48
|
+
import { importJumps } from '../composed/carry';
|
|
48
49
|
import { configKeyOf, layoutComposedPageMemo } from '../composed/pageMemo';
|
|
49
50
|
import { anchorOutline, computeOutline, hasIndexDirective, hasTocDirective, headingNumberingOptions, headingTemplatesOf, outlineFromDoc, sameOutline } from './outline';
|
|
50
51
|
import { expandTocDirectives } from './toc';
|
|
@@ -55,8 +56,8 @@ import { resetLinePositions, createPageWithColumns, currentColumn, advanceToNext
|
|
|
55
56
|
import { chooseParagraphSplit } from './orphanWidow';
|
|
56
57
|
import { layoutComicPage, comicPageLayoutWarnings } from '../comics/layoutPage';
|
|
57
58
|
import { comicStripExtent, comicStripOffset, comicStripPlacement, comicStripWidth, layoutComicStrip } from '../comics/strip';
|
|
58
|
-
import { isComicSpread, layoutComicSpread } from '../comics/spread';
|
|
59
|
-
import { comicTextPanelsSupported, layoutComicTextFrames, planComicTextPanels, wrapComicTextPanels } from '../comics/textPanels';
|
|
59
|
+
import { comicSpreadGutter, isComicSpread, layoutComicSpread } from '../comics/spread';
|
|
60
|
+
import { comicTextPanelsSupported, layoutComicTextFrames, layoutStripTextFrames, planComicTextPanels, wrapComicTextPanels } from '../comics/textPanels';
|
|
60
61
|
import { applyStyleAttrs, computePageMetrics, flowPageMirrored, pageMirrored, sheetRectToFlow, isMarkerBlock, nextNonMarkerBlock, spaceLinesAfter, prevNonMarkerBlock, rollbackTrailingBlocks, } from './buildHelpers';
|
|
61
62
|
import { measureContentBlock } from './measureContentBlock';
|
|
62
63
|
import { containerStyle, paragraphStyleIdOf, planParagraphContainers } from './paragraphContainers';
|
|
@@ -485,7 +486,9 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
485
486
|
const anchorRefs = hasAnchorRefs(parsedBlocks, resourceIds);
|
|
486
487
|
const outline = content.outline
|
|
487
488
|
?? (hasTocDirective(parsedBlocks) || hasIndexDirective(parsedBlocks) || anchorRefs ? computeOutline(parsedBlocks, resolved, headingStart, continuation?.statementCounters) : undefined);
|
|
488
|
-
|
|
489
|
+
// A story carried in from another chapter (#943) may refer to anchors too.
|
|
490
|
+
const carriedRefs = continuation?.jumps?.some((j) => j.outline) === true;
|
|
491
|
+
const anchorRefContext = anchorRefs || carriedRefs
|
|
489
492
|
? { targets: anchorTargetsOf(outline), strings: resolved.crossRefs }
|
|
490
493
|
: undefined;
|
|
491
494
|
const indexExpanded = expandIndexDirectives(expandTocDirectives(parsedBlocks, outline, resolved), outline, resolved);
|
|
@@ -518,6 +521,15 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
518
521
|
// callout machinery places and splits.
|
|
519
522
|
const codeBoxes = wrapCodeBlocks(spanEmbeds.blocks, resolved);
|
|
520
523
|
const contentBlocks = codeBoxes.blocks;
|
|
524
|
+
// Stories of earlier chapters that jump into a page of this one (#943):
|
|
525
|
+
// appended past the chapter's blocks by the composed pages' layout, with
|
|
526
|
+
// the notes they cite numbered as their chapter numbered them.
|
|
527
|
+
const carried = continuation?.jumps && continuation.jumps.length > 0 ? importJumps(continuation.jumps, contentBlocks.length, bodyOffset) : undefined;
|
|
528
|
+
for (const note of carried?.footnotes ?? []) {
|
|
529
|
+
footnoteNumbering.numbers.set(note.id, note.number);
|
|
530
|
+
if (note.def)
|
|
531
|
+
footnoteDefs.set(note.id, note.def);
|
|
532
|
+
}
|
|
521
533
|
if (indexExpanded.warnings.length > 0)
|
|
522
534
|
indexWarnings.set(doc, indexExpanded.warnings);
|
|
523
535
|
const isNumbered = (b) => headingIsNumbered(b, resolved);
|
|
@@ -5712,7 +5724,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
5712
5724
|
* needed; the verso and the recto after it get one half each
|
|
5713
5725
|
* (`layoutComicSpread`). The cursor is left on the recto.
|
|
5714
5726
|
*/
|
|
5715
|
-
const placeComicSpread = (source) => {
|
|
5727
|
+
const placeComicSpread = (source, textPlan) => {
|
|
5716
5728
|
breakToEvenPage();
|
|
5717
5729
|
const verso = doc.pages[cursor.pageIndex];
|
|
5718
5730
|
verso.columns = [createVDTColumn(0, verso.contentArea)];
|
|
@@ -5738,6 +5750,17 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
5738
5750
|
});
|
|
5739
5751
|
verso.comic = versoIsLeft ? left : right;
|
|
5740
5752
|
recto.comic = versoIsLeft ? right : left;
|
|
5753
|
+
// The text panels (#959): each on the page that holds most of its
|
|
5754
|
+
// panel, off the gutter.
|
|
5755
|
+
if (textPlan) {
|
|
5756
|
+
const sides = [[verso, verso.comic, recto.comic], [recto, recto.comic, verso.comic]];
|
|
5757
|
+
for (const [page, own, other] of sides) {
|
|
5758
|
+
const width = (c, index) => c.panels.find((q) => q.index === index)?.bbox.width ?? 0;
|
|
5759
|
+
const mine = new Set(own.panels.filter((q) => width(own, q.index) > width(other, q.index) || (width(own, q.index) === width(other, q.index) && page === (versoIsLeft ? verso : recto))).map((q) => q.index));
|
|
5760
|
+
const gutter = comicSpreadGutter(own, dpi, page.height);
|
|
5761
|
+
placeComicText(page, own, textPlan, { only: mine, ...(gutter ? { avoid: [gutter] } : {}) });
|
|
5762
|
+
}
|
|
5763
|
+
}
|
|
5741
5764
|
};
|
|
5742
5765
|
/**
|
|
5743
5766
|
* `:::strip` (#566): a comic in the flow, kept together. Set `here`, it
|
|
@@ -5986,6 +6009,93 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
5986
6009
|
}
|
|
5987
6010
|
/** Stories waiting for the later page fence they jump to, by its id. */
|
|
5988
6011
|
const jumps = new Map();
|
|
6012
|
+
/** The closing marker of the fence each composed page was set from. */
|
|
6013
|
+
const fenceEnd = new Map();
|
|
6014
|
+
/** The carried stories are laid through a pass that answers for them;
|
|
6015
|
+
* they wait for their fence with the others. */
|
|
6016
|
+
const composedPass = carried ? carriedPass(framePass, carried) : framePass;
|
|
6017
|
+
/** Stories of this chapter that jump into a page of a later one (#943). */
|
|
6018
|
+
const pendingJumps = [];
|
|
6019
|
+
/** The rest of the story `c` cut, as the chapter it goes to needs it
|
|
6020
|
+
* (#943): its box and children as this chapter has them ready to lay,
|
|
6021
|
+
* the cut, and the numbers the lookups by position would give. */
|
|
6022
|
+
const exportJump = (c, page) => {
|
|
6023
|
+
const startIdx = c.story.startIdx;
|
|
6024
|
+
const again = carried?.stories.get(startIdx);
|
|
6025
|
+
const all = composedPass.contentBlocks;
|
|
6026
|
+
const blocks = all.slice(startIdx, c.story.plan.endIdx + 1);
|
|
6027
|
+
const numbers = again ? [...(again.jump.numbers ?? [])] : [];
|
|
6028
|
+
if (!again) {
|
|
6029
|
+
for (let i = startIdx; i <= c.story.plan.endIdx; i++) {
|
|
6030
|
+
if (headingPrefixes[i] === undefined && headingNumbers[i] === undefined)
|
|
6031
|
+
continue;
|
|
6032
|
+
numbers.push({
|
|
6033
|
+
at: i - startIdx,
|
|
6034
|
+
...(headingPrefixes[i] !== undefined ? { prefix: headingPrefixes[i] } : {}),
|
|
6035
|
+
...(headingNumbers[i] !== undefined ? { value: headingNumbers[i] } : {}),
|
|
6036
|
+
...(chapterNumberByBlock[i] ? { chapterNumber: chapterNumberByBlock[i] } : {}),
|
|
6037
|
+
});
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
6040
|
+
const notes = [];
|
|
6041
|
+
const seen = new Set();
|
|
6042
|
+
for (const b of blocks) {
|
|
6043
|
+
for (const span of b.spans) {
|
|
6044
|
+
const id = span.footnote?.id;
|
|
6045
|
+
if (id === undefined || seen.has(id))
|
|
6046
|
+
continue;
|
|
6047
|
+
seen.add(id);
|
|
6048
|
+
const number = footnoteNumbering.numbers.get(id);
|
|
6049
|
+
if (number === undefined)
|
|
6050
|
+
continue;
|
|
6051
|
+
const def = footnoteDefs.get(id);
|
|
6052
|
+
notes.push({ id, number, ...(def ? { def } : {}) });
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
const rule = c.rule;
|
|
6056
|
+
const frame = continueInPage(rule)?.frame;
|
|
6057
|
+
return {
|
|
6058
|
+
...(again ? { chapter: again.chapter } : {}),
|
|
6059
|
+
target: page,
|
|
6060
|
+
...(frame !== undefined ? { targetFrame: frame } : {}),
|
|
6061
|
+
rule,
|
|
6062
|
+
frame: c.frame,
|
|
6063
|
+
fromFrameId: c.fromFrameId,
|
|
6064
|
+
head: c.head,
|
|
6065
|
+
template: c.template,
|
|
6066
|
+
collapsed: c.collapsed,
|
|
6067
|
+
slot: c.slot,
|
|
6068
|
+
pieces: c.pieces,
|
|
6069
|
+
headBlockId: c.headBlockId,
|
|
6070
|
+
...(c.trailing ? { trailing: c.trailing } : {}),
|
|
6071
|
+
...(c.fromMark !== undefined ? { fromMark: c.fromMark } : {}),
|
|
6072
|
+
cut: c.cut,
|
|
6073
|
+
blocks: blocks,
|
|
6074
|
+
bodyOffset,
|
|
6075
|
+
...(numbers.length > 0 ? { numbers } : {}),
|
|
6076
|
+
orderedLevelIndentsPx: again?.jump.orderedLevelIndentsPx ?? orderedLevelIndentsPx,
|
|
6077
|
+
...(notes.length > 0 ? { footnotes: notes } : {}),
|
|
6078
|
+
...(hasAnchorRefs(blocks, new Set((content.resources ?? []).map((r) => r.id))) ? { outline: true } : {}),
|
|
6079
|
+
};
|
|
6080
|
+
};
|
|
6081
|
+
for (const [id, list] of carried?.byTarget ?? []) {
|
|
6082
|
+
if (fenceById.has(id)) {
|
|
6083
|
+
jumps.set(id, [...(jumps.get(id) ?? []), ...list]);
|
|
6084
|
+
continue;
|
|
6085
|
+
}
|
|
6086
|
+
// The host named this chapter for a page it does not have.
|
|
6087
|
+
for (const c of list) {
|
|
6088
|
+
composedNotes.push({
|
|
6089
|
+
kind: 'continueTargetMissing',
|
|
6090
|
+
template: c.template,
|
|
6091
|
+
frame: c.frame,
|
|
6092
|
+
fenceIndex: -1,
|
|
6093
|
+
target: id,
|
|
6094
|
+
fromChapter: c.foreign?.chapter ?? -1,
|
|
6095
|
+
configPath: '',
|
|
6096
|
+
});
|
|
6097
|
+
}
|
|
6098
|
+
}
|
|
5989
6099
|
/** Set the composed page `planned` on a fresh page (#855), or a spread
|
|
5990
6100
|
* template on the two facing pages from the next verso (#861). */
|
|
5991
6101
|
const placeComposedPage = (planned, fence) => {
|
|
@@ -5999,7 +6109,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
5999
6109
|
* other templates of the same kind (single pages for this side, or
|
|
6000
6110
|
* spreads). */
|
|
6001
6111
|
const common = (page, current) => ({
|
|
6002
|
-
pass:
|
|
6112
|
+
pass: composedPass,
|
|
6003
6113
|
fence,
|
|
6004
6114
|
startIdx: planned.startIdx,
|
|
6005
6115
|
endIdx: planned.endIdx,
|
|
@@ -6132,6 +6242,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6132
6242
|
const commit = (list) => {
|
|
6133
6243
|
for (const { page, composed, blocks } of list) {
|
|
6134
6244
|
page.composed = composed;
|
|
6245
|
+
fenceEnd.set(composed, planned.endIdx);
|
|
6135
6246
|
const floats = (page.floats ??= []);
|
|
6136
6247
|
for (const b of blocks) {
|
|
6137
6248
|
floats.push(b);
|
|
@@ -6153,12 +6264,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6153
6264
|
indexFrames(placed);
|
|
6154
6265
|
/** The sending frame of `c` points to the frame `to` that took it, and
|
|
6155
6266
|
* its page's log says where it went. */
|
|
6156
|
-
const
|
|
6157
|
-
const src = frameAt.get(c.fromFrameId);
|
|
6158
|
-
const dst = frameAt.get(to);
|
|
6159
|
-
if (!src || !dst)
|
|
6160
|
-
return;
|
|
6161
|
-
src.frame.continuesTo = to;
|
|
6267
|
+
const logContinued = (src, c, event) => {
|
|
6162
6268
|
const log = src.page.composed.log;
|
|
6163
6269
|
let at = log.length;
|
|
6164
6270
|
for (let i = log.length - 1; i >= 0; i--) {
|
|
@@ -6167,7 +6273,19 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6167
6273
|
break;
|
|
6168
6274
|
}
|
|
6169
6275
|
}
|
|
6170
|
-
log.splice(at, 0, { frame: c.frame, kind: 'continued',
|
|
6276
|
+
log.splice(at, 0, { frame: c.frame, kind: 'continued', ...event });
|
|
6277
|
+
};
|
|
6278
|
+
const link = (c, to) => {
|
|
6279
|
+
// The sending frame is on a page of another chapter: the host links
|
|
6280
|
+
// the two (`resolveJumpMarks`).
|
|
6281
|
+
if (c.foreign)
|
|
6282
|
+
return;
|
|
6283
|
+
const src = frameAt.get(c.fromFrameId);
|
|
6284
|
+
const dst = frameAt.get(to);
|
|
6285
|
+
if (!src || !dst)
|
|
6286
|
+
return;
|
|
6287
|
+
src.frame.continuesTo = to;
|
|
6288
|
+
logContinued(src, c, { toPage: dst.page.index, toFrame: to });
|
|
6171
6289
|
};
|
|
6172
6290
|
for (const [name, c] of jumpReceivers)
|
|
6173
6291
|
link(c, frameElementId(fence.fenceIndex, name));
|
|
@@ -6190,6 +6308,16 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6190
6308
|
continue;
|
|
6191
6309
|
}
|
|
6192
6310
|
const from = frameAt.get(c.fromFrameId);
|
|
6311
|
+
// A page of a later chapter (#943): the host hands the rest over.
|
|
6312
|
+
const later = !to && content.laterPageIds && Object.prototype.hasOwnProperty.call(content.laterPageIds, target.page) ? content.laterPageIds[target.page] : undefined;
|
|
6313
|
+
if (later !== undefined) {
|
|
6314
|
+
pendingJumps.push(exportJump(c, target.page));
|
|
6315
|
+
if (from) {
|
|
6316
|
+
from.frame.continuesToChapter = later;
|
|
6317
|
+
logContinued(from, c, { toChapter: later });
|
|
6318
|
+
}
|
|
6319
|
+
continue;
|
|
6320
|
+
}
|
|
6193
6321
|
composedNotes.push({
|
|
6194
6322
|
kind: 'continueTargetMissing',
|
|
6195
6323
|
template: c.template,
|
|
@@ -6308,13 +6436,12 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6308
6436
|
* frame (`layoutComicTextFrames`), its blocks floats of the page; the
|
|
6309
6437
|
* stories laid are done for the main loop.
|
|
6310
6438
|
*/
|
|
6311
|
-
const
|
|
6439
|
+
const comicTextBase = (page, plan) => {
|
|
6312
6440
|
const frameless = calloutStyles.find((st) => st.id === FRAME_STYLE_ID);
|
|
6313
|
-
|
|
6441
|
+
return {
|
|
6314
6442
|
pass: framePass,
|
|
6315
6443
|
resolved,
|
|
6316
6444
|
page,
|
|
6317
|
-
comic,
|
|
6318
6445
|
plan,
|
|
6319
6446
|
styleOf: (frame) => frameStyleOf((frame.style ? resolved.calloutStyles.find((st) => st.id === frame.style) : undefined) ?? frameless, frame),
|
|
6320
6447
|
dpi,
|
|
@@ -6323,19 +6450,64 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6323
6450
|
mirrored: mirroredOf(page),
|
|
6324
6451
|
pushGapPx: wrapGapPx(resolved.layout.wrap?.gap, dpi, bodyStyle.fontSizePx, floatGapPx),
|
|
6325
6452
|
locale: resolvedLocale(resolved),
|
|
6326
|
-
}
|
|
6453
|
+
};
|
|
6454
|
+
};
|
|
6455
|
+
/** The blocks a comic's text frames set, floats of the page. */
|
|
6456
|
+
const addComicTextBlocks = (page, blocks) => {
|
|
6327
6457
|
const floats = (page.floats ??= []);
|
|
6328
|
-
for (const b of
|
|
6458
|
+
for (const b of blocks) {
|
|
6329
6459
|
floats.push(b);
|
|
6330
6460
|
doc.blocks.push(b);
|
|
6331
6461
|
}
|
|
6462
|
+
};
|
|
6463
|
+
/** The stories of a plan are done for the main loop. */
|
|
6464
|
+
const markComicStoriesLaid = (plan, laid) => {
|
|
6332
6465
|
for (const [key, story] of plan.stories) {
|
|
6333
|
-
if (!
|
|
6466
|
+
if (laid && !laid.has(key))
|
|
6334
6467
|
continue;
|
|
6335
6468
|
for (let i = story.startIdx; i <= story.plan.endIdx; i++)
|
|
6336
6469
|
composedLaid.add(i);
|
|
6337
6470
|
}
|
|
6338
6471
|
};
|
|
6472
|
+
// The text panels of a strip are laid where the strip ends up
|
|
6473
|
+
// (`placeStripTexts`): the blocks that follow it are done from the start.
|
|
6474
|
+
for (const [idx, plan] of comicTextPlans)
|
|
6475
|
+
if (contentBlocks[idx]?.directiveName === 'strip')
|
|
6476
|
+
markComicStoriesLaid(plan);
|
|
6477
|
+
const placeComicText = (page, comic, plan, extra) => {
|
|
6478
|
+
const out = layoutComicTextFrames({ ...extra, ...comicTextBase(page, plan), comic });
|
|
6479
|
+
addComicTextBlocks(page, out.blocks);
|
|
6480
|
+
markComicStoriesLaid(plan, out.laid);
|
|
6481
|
+
return out;
|
|
6482
|
+
};
|
|
6483
|
+
/**
|
|
6484
|
+
* The text panels of the strips on the pages (#959), laid where the strips
|
|
6485
|
+
* stand once the pass has placed everything (a strip moves with its
|
|
6486
|
+
* column, its band and the pages' final adjustments): each strip's comic
|
|
6487
|
+
* moved onto the sheet, its stories set in the page's flow frame, the
|
|
6488
|
+
* result written back on the strip.
|
|
6489
|
+
*/
|
|
6490
|
+
const placeStripTexts = () => {
|
|
6491
|
+
if (comicTextPlans.size === 0)
|
|
6492
|
+
return;
|
|
6493
|
+
for (const page of doc.pages) {
|
|
6494
|
+
const strips = new Set();
|
|
6495
|
+
for (const col of page.columns)
|
|
6496
|
+
for (const b of col.blocks)
|
|
6497
|
+
if (b.comic && !b.hidden)
|
|
6498
|
+
strips.add(b);
|
|
6499
|
+
for (const b of page.floats ?? [])
|
|
6500
|
+
if (b.comic && !b.hidden)
|
|
6501
|
+
strips.add(b);
|
|
6502
|
+
for (const block of strips) {
|
|
6503
|
+
const plan = block.contentIndex !== undefined && block.contentIndex >= 0 ? comicTextPlans.get(block.contentIndex) : undefined;
|
|
6504
|
+
if (!plan)
|
|
6505
|
+
continue;
|
|
6506
|
+
const out = layoutStripTextFrames({ ...comicTextBase(page, plan), block });
|
|
6507
|
+
addComicTextBlocks(page, out.blocks);
|
|
6508
|
+
}
|
|
6509
|
+
}
|
|
6510
|
+
};
|
|
6339
6511
|
/** The first block of the document that sets something: a heading there
|
|
6340
6512
|
* opens the document's first page (`openerPages`, #749). */
|
|
6341
6513
|
const firstFlowBlockIdx = contentBlocks.findIndex((b) => !isMarkerBlock(b) && b.type !== 'directive');
|
|
@@ -6607,7 +6779,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
6607
6779
|
leaveCurrentPage();
|
|
6608
6780
|
cursor.columnIndex = 0;
|
|
6609
6781
|
if (isComicSpread(rawBlock.comic))
|
|
6610
|
-
placeComicSpread(rawBlock.comic);
|
|
6782
|
+
placeComicSpread(rawBlock.comic, comicTextPlans.get(blockIdx));
|
|
6611
6783
|
else {
|
|
6612
6784
|
const page = doc.pages[cursor.pageIndex];
|
|
6613
6785
|
page.columns = [createVDTColumn(0, page.contentArea)];
|
|
@@ -8518,6 +8690,8 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
8518
8690
|
if (page)
|
|
8519
8691
|
centrePageText(page, reservedOf);
|
|
8520
8692
|
}
|
|
8693
|
+
// The text panels of the strips, where the strips stand now (#959).
|
|
8694
|
+
placeStripTexts();
|
|
8521
8695
|
// A band that is still cut at the end of the pass (a trailing cap: the
|
|
8522
8696
|
// closing band of a chapter or of the document) must hold what it took,
|
|
8523
8697
|
// under the same rules as an uncut one. Two ways a cut too low breaks
|
|
@@ -8642,6 +8816,10 @@ function placeDocumentPass(content, config, cache, options, hints) {
|
|
|
8642
8816
|
// Composed pages (#855): frames whose content does not fit.
|
|
8643
8817
|
if (composedNotes.length > 0)
|
|
8644
8818
|
composedWarningsByDoc.set(doc, composedNotes);
|
|
8819
|
+
if (pendingJumps.length > 0)
|
|
8820
|
+
doc.pendingJumps = pendingJumps;
|
|
8821
|
+
if (carried)
|
|
8822
|
+
stampCarriedSource(doc, carried, fenceEnd);
|
|
8645
8823
|
// The composition rules (#749): short lists cut, floats on opener pages.
|
|
8646
8824
|
const ruleNotes = [...shortListWarnings(), ...openerFloatNotes, ...tocGroupWarnings()];
|
|
8647
8825
|
if (ruleNotes.length > 0)
|
|
@@ -8810,6 +8988,39 @@ function afterTextWarnings(doc) {
|
|
|
8810
8988
|
}
|
|
8811
8989
|
return out;
|
|
8812
8990
|
}
|
|
8991
|
+
/**
|
|
8992
|
+
* Mark the blocks laid from stories that came in from other chapters
|
|
8993
|
+
* (#943): `VDTBlock.sourceChapter` says whose file their source offsets
|
|
8994
|
+
* are offsets in.
|
|
8995
|
+
*/
|
|
8996
|
+
function stampCarriedSource(doc, carried, fenceEnd) {
|
|
8997
|
+
const stories = [...carried.stories.values()];
|
|
8998
|
+
const noteChapter = new Map(carried.footnotes.map((n) => [n.id, n.chapter]));
|
|
8999
|
+
for (const block of doc.blocks) {
|
|
9000
|
+
const note = block.footnoteNote !== undefined ? noteChapter.get(block.footnoteNote) : undefined;
|
|
9001
|
+
if (note !== undefined)
|
|
9002
|
+
block.sourceChapter = note;
|
|
9003
|
+
const at = block.contentIndex;
|
|
9004
|
+
if (at === undefined)
|
|
9005
|
+
continue;
|
|
9006
|
+
const story = stories.find((st) => at >= st.startIdx && at <= st.endIdx);
|
|
9007
|
+
if (story)
|
|
9008
|
+
block.sourceChapter = story.chapter;
|
|
9009
|
+
}
|
|
9010
|
+
// The frames that set a carried story's text: the box (a block of the
|
|
9011
|
+
// frame) says whose it is.
|
|
9012
|
+
for (const page of doc.pages) {
|
|
9013
|
+
for (const frame of page.composed?.frames ?? []) {
|
|
9014
|
+
const box = frame.blockIds.length > 0 ? page.floats?.find((b) => b.id === frame.blockIds[0]) : undefined;
|
|
9015
|
+
if (box?.sourceChapter === undefined)
|
|
9016
|
+
continue;
|
|
9017
|
+
frame.sourceChapter = box.sourceChapter;
|
|
9018
|
+
const end = fenceEnd.get(page.composed);
|
|
9019
|
+
if (end !== undefined)
|
|
9020
|
+
frame.readIndex = end + 0.5;
|
|
9021
|
+
}
|
|
9022
|
+
}
|
|
9023
|
+
}
|
|
8813
9024
|
/**
|
|
8814
9025
|
* Write the page numbers into the continuation marks of composed pages'
|
|
8815
9026
|
* frames (#917, `VDTDesignTextBlock.pageMark`): `{page}` becomes the label
|
|
@@ -8823,6 +9034,22 @@ function fillPageMarks(pages) {
|
|
|
8823
9034
|
for (const f of p.composed?.frames ?? [])
|
|
8824
9035
|
if (!f.facingBlocks)
|
|
8825
9036
|
frames.set(f.id, p);
|
|
9037
|
+
forEachPageMark(pages, (f, d) => {
|
|
9038
|
+
// A page of another chapter is `resolveJumpMarks`'s (its frame ids are
|
|
9039
|
+
// another chapter's).
|
|
9040
|
+
if ((d.pageMark.page === 'to' ? f.continuesToChapter : f.continuedFromChapter) !== undefined)
|
|
9041
|
+
return undefined;
|
|
9042
|
+
const other = d.pageMark.page === 'to' ? f.continuesTo : f.continuedFrom;
|
|
9043
|
+
const at = other !== undefined ? frames.get(other) : undefined;
|
|
9044
|
+
return at ? pageLabelOf(at) : undefined;
|
|
9045
|
+
});
|
|
9046
|
+
}
|
|
9047
|
+
/** The label a page prints. */
|
|
9048
|
+
const pageLabelOf = (page) => page.pageLabel ?? String(page.pageNumberValue ?? page.index + 1);
|
|
9049
|
+
/** Each continuation mark with a page number of `pages`' composed frames,
|
|
9050
|
+
* with `label` answering for the page it names: the mark's text is laid
|
|
9051
|
+
* out again with the number when it answers. */
|
|
9052
|
+
function forEachPageMark(pages, label) {
|
|
8826
9053
|
for (const p of pages) {
|
|
8827
9054
|
for (const f of p.composed?.frames ?? []) {
|
|
8828
9055
|
for (const id of f.blockIds) {
|
|
@@ -8830,12 +9057,10 @@ function fillPageMarks(pages) {
|
|
|
8830
9057
|
for (const d of box?.designOverlay?.blocks ?? []) {
|
|
8831
9058
|
if (d.kind !== 'text' || !d.pageMark)
|
|
8832
9059
|
continue;
|
|
8833
|
-
const
|
|
8834
|
-
|
|
8835
|
-
if (!at)
|
|
9060
|
+
const shown = label(f, d);
|
|
9061
|
+
if (shown === undefined)
|
|
8836
9062
|
continue;
|
|
8837
|
-
const
|
|
8838
|
-
const text = d.pageMark.text.split('{page}').join(label);
|
|
9063
|
+
const text = d.pageMark.text.split('{page}').join(shown);
|
|
8839
9064
|
const lh = d.lines.length > 0 ? d.bbox.height / d.lines.length : d.bbox.height;
|
|
8840
9065
|
const first = d.lines[0];
|
|
8841
9066
|
const slack0 = first ? d.bbox.width - first.width : 0;
|
|
@@ -8853,6 +9078,60 @@ function fillPageMarks(pages) {
|
|
|
8853
9078
|
}
|
|
8854
9079
|
}
|
|
8855
9080
|
}
|
|
9081
|
+
/**
|
|
9082
|
+
* Link the stories that jump from one chapter to a page of another (#943)
|
|
9083
|
+
* and write the page numbers into their continuation marks. `docs` is the
|
|
9084
|
+
* book laid out, one document per chapter, in the order of the book (a
|
|
9085
|
+
* story's `chapter` is its position in it): the sending frame gets the
|
|
9086
|
+
* frame that took the rest (`continuesTo`, its `continued` event the page
|
|
9087
|
+
* and frame there), and every mark naming a page of another chapter
|
|
9088
|
+
* prints that page's label as its chapter numbered it. Marks within a
|
|
9089
|
+
* chapter were filled by its own build. Safe to run again on the same
|
|
9090
|
+
* documents.
|
|
9091
|
+
*/
|
|
9092
|
+
export function resolveJumpMarks(docs) {
|
|
9093
|
+
const byId = docs.map((doc) => {
|
|
9094
|
+
const out = new Map();
|
|
9095
|
+
for (const p of doc.pages)
|
|
9096
|
+
for (const f of p.composed?.frames ?? [])
|
|
9097
|
+
if (!f.facingBlocks)
|
|
9098
|
+
out.set(f.id, p);
|
|
9099
|
+
return out;
|
|
9100
|
+
});
|
|
9101
|
+
const frameOf = (chapter, id) => {
|
|
9102
|
+
const page = byId[chapter]?.get(id);
|
|
9103
|
+
const frame = page?.composed?.frames.find((f) => f.id === id);
|
|
9104
|
+
return page && frame ? { page, frame } : undefined;
|
|
9105
|
+
};
|
|
9106
|
+
// The receiving frames name where their story came from; give the
|
|
9107
|
+
// sending frame the way on.
|
|
9108
|
+
docs.forEach((doc) => {
|
|
9109
|
+
for (const p of doc.pages) {
|
|
9110
|
+
for (const f of p.composed?.frames ?? []) {
|
|
9111
|
+
if (f.continuedFromChapter === undefined || f.continuedFrom === undefined)
|
|
9112
|
+
continue;
|
|
9113
|
+
const from = frameOf(f.continuedFromChapter, f.continuedFrom);
|
|
9114
|
+
if (!from)
|
|
9115
|
+
continue;
|
|
9116
|
+
from.frame.continuesTo = f.id;
|
|
9117
|
+
const event = from.page.composed.log.find((e) => e.kind === 'continued' && e.frame === from.frame.name && e.toChapter !== undefined);
|
|
9118
|
+
if (event) {
|
|
9119
|
+
event.toPage = p.index;
|
|
9120
|
+
event.toFrame = f.id;
|
|
9121
|
+
}
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
9124
|
+
});
|
|
9125
|
+
docs.forEach((doc) => {
|
|
9126
|
+
forEachPageMark(doc.pages, (f, d) => {
|
|
9127
|
+
const [chapter, id] = d.pageMark.page === 'to' ? [f.continuesToChapter, f.continuesTo] : [f.continuedFromChapter, f.continuedFrom];
|
|
9128
|
+
if (chapter === undefined || id === undefined)
|
|
9129
|
+
return undefined;
|
|
9130
|
+
const at = byId[chapter]?.get(id);
|
|
9131
|
+
return at ? pageLabelOf(at) : undefined;
|
|
9132
|
+
});
|
|
9133
|
+
});
|
|
9134
|
+
}
|
|
8856
9135
|
/** `doc` with the page of each of its index marks (`doc.indexMarks`). */
|
|
8857
9136
|
function withIndexMarks(doc, content) {
|
|
8858
9137
|
const { content: body, contentOffset } = extractFrontmatter(content.markdown);
|