postext 1.34.0 → 1.34.1
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__/bundle.test.js +33 -1
- package/dist/__tests__/bundle.test.js.map +1 -1
- package/dist/__tests__/codeBlocks.test.js +88 -0
- package/dist/__tests__/codeBlocks.test.js.map +1 -1
- package/dist/__tests__/composed/fixtures/page8.d.ts +20 -0
- package/dist/__tests__/composed/fixtures/page8.d.ts.map +1 -0
- package/dist/__tests__/composed/fixtures/page8.js +159 -0
- package/dist/__tests__/composed/fixtures/page8.js.map +1 -0
- package/dist/__tests__/composed/layout.test.d.ts +2 -0
- package/dist/__tests__/composed/layout.test.d.ts.map +1 -0
- package/dist/__tests__/composed/layout.test.js +387 -0
- package/dist/__tests__/composed/layout.test.js.map +1 -0
- package/dist/__tests__/composed/slotChecks.test.js +6 -3
- package/dist/__tests__/composed/slotChecks.test.js.map +1 -1
- package/dist/__tests__/composedPaint.test.d.ts +2 -0
- package/dist/__tests__/composedPaint.test.d.ts.map +1 -0
- package/dist/__tests__/composedPaint.test.js +191 -0
- package/dist/__tests__/composedPaint.test.js.map +1 -0
- package/dist/__tests__/defaults/stripRoundTrip.test.js +3 -2
- package/dist/__tests__/defaults/stripRoundTrip.test.js.map +1 -1
- package/dist/__tests__/exports.test.js +12 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/highlightMarks.test.d.ts +2 -0
- package/dist/__tests__/highlightMarks.test.d.ts.map +1 -0
- package/dist/__tests__/highlightMarks.test.js +169 -0
- package/dist/__tests__/highlightMarks.test.js.map +1 -0
- package/dist/__tests__/tocPartLeader.test.d.ts +2 -0
- package/dist/__tests__/tocPartLeader.test.d.ts.map +1 -0
- package/dist/__tests__/tocPartLeader.test.js +133 -0
- package/dist/__tests__/tocPartLeader.test.js.map +1 -0
- package/dist/bundle/api.d.ts +8 -0
- package/dist/bundle/api.d.ts.map +1 -1
- package/dist/bundle/api.js +6 -3
- package/dist/bundle/api.js.map +1 -1
- package/dist/bundle/codec.d.ts +5 -0
- package/dist/bundle/codec.d.ts.map +1 -1
- package/dist/bundle/codec.js +4 -0
- package/dist/bundle/codec.js.map +1 -1
- package/dist/bundle/index.d.ts +2 -2
- package/dist/bundle/index.d.ts.map +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/index.js.map +1 -1
- package/dist/bundle/manifest.d.ts +14 -0
- package/dist/bundle/manifest.d.ts.map +1 -1
- package/dist/bundle/manifest.js +13 -0
- package/dist/bundle/manifest.js.map +1 -1
- package/dist/bundle/types.d.ts +7 -0
- package/dist/bundle/types.d.ts.map +1 -1
- package/dist/canvas-backend/annotations.d.ts +6 -0
- package/dist/canvas-backend/annotations.d.ts.map +1 -1
- package/dist/canvas-backend/annotations.js +39 -0
- package/dist/canvas-backend/annotations.js.map +1 -1
- package/dist/canvas-backend/blockRender.d.ts.map +1 -1
- package/dist/canvas-backend/blockRender.js +6 -1
- package/dist/canvas-backend/blockRender.js.map +1 -1
- package/dist/canvas-backend/composed.d.ts +15 -0
- package/dist/canvas-backend/composed.d.ts.map +1 -0
- package/dist/canvas-backend/composed.js +41 -0
- package/dist/canvas-backend/composed.js.map +1 -0
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +15 -1
- 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 +4 -1
- package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
- package/dist/composed/geometry.d.ts +108 -0
- package/dist/composed/geometry.d.ts.map +1 -0
- package/dist/composed/geometry.js +241 -0
- package/dist/composed/geometry.js.map +1 -0
- package/dist/composed/paint.d.ts +41 -0
- package/dist/composed/paint.d.ts.map +1 -0
- package/dist/composed/paint.js +83 -0
- package/dist/composed/paint.js.map +1 -0
- package/dist/composed/types.d.ts +1 -44
- package/dist/composed/types.d.ts.map +1 -1
- package/dist/composed/wrap.d.ts +52 -0
- package/dist/composed/wrap.d.ts.map +1 -0
- package/dist/composed/wrap.js +234 -0
- package/dist/composed/wrap.js.map +1 -0
- package/dist/configWarnings.js +1 -1
- package/dist/configWarnings.js.map +1 -1
- package/dist/defaults/codeStyle.d.ts.map +1 -1
- package/dist/defaults/codeStyle.js +1 -0
- package/dist/defaults/codeStyle.js.map +1 -1
- package/dist/defaults/index.d.ts +1 -0
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +9 -0
- package/dist/defaults/index.js.map +1 -1
- package/dist/defaults/markStyles.d.ts +23 -0
- package/dist/defaults/markStyles.d.ts.map +1 -0
- package/dist/defaults/markStyles.js +80 -0
- package/dist/defaults/markStyles.js.map +1 -0
- package/dist/defaults/shared.d.ts.map +1 -1
- package/dist/defaults/shared.js +12 -0
- package/dist/defaults/shared.js.map +1 -1
- package/dist/design/bidiText.d.ts +4 -1
- package/dist/design/bidiText.d.ts.map +1 -1
- package/dist/design/bidiText.js +5 -2
- package/dist/design/bidiText.js.map +1 -1
- package/dist/design/layout.d.ts +10 -0
- package/dist/design/layout.d.ts.map +1 -1
- package/dist/design/layout.js +110 -8
- package/dist/design/layout.js.map +1 -1
- package/dist/design/placeholders.d.ts +28 -2
- package/dist/design/placeholders.d.ts.map +1 -1
- package/dist/design/placeholders.js +24 -1
- package/dist/design/placeholders.js.map +1 -1
- package/dist/design/richText.d.ts +2 -0
- package/dist/design/richText.d.ts.map +1 -1
- package/dist/design/richText.js.map +1 -1
- package/dist/highlightMarks.d.ts +33 -0
- package/dist/highlightMarks.d.ts.map +1 -0
- package/dist/highlightMarks.js +209 -0
- package/dist/highlightMarks.js.map +1 -0
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +65 -8
- package/dist/html-backend.js.map +1 -1
- package/dist/htmlAnnotations.d.ts +5 -0
- package/dist/htmlAnnotations.d.ts.map +1 -1
- package/dist/htmlAnnotations.js +16 -0
- package/dist/htmlAnnotations.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/knuthPlass/richAdapter.d.ts +3 -0
- package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
- package/dist/knuthPlass/richAdapter.js +3 -2
- package/dist/knuthPlass/richAdapter.js.map +1 -1
- package/dist/measure/cache.js +3 -3
- package/dist/measure/cache.js.map +1 -1
- package/dist/measure/chipEdges.d.ts +13 -1
- package/dist/measure/chipEdges.d.ts.map +1 -1
- package/dist/measure/chipEdges.js +59 -1
- package/dist/measure/chipEdges.js.map +1 -1
- package/dist/measure/links.d.ts.map +1 -1
- package/dist/measure/links.js +78 -5
- package/dist/measure/links.js.map +1 -1
- package/dist/measure/rich.d.ts +3 -0
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +19 -4
- package/dist/measure/rich.js.map +1 -1
- package/dist/parse/inlineFormatting.d.ts +14 -0
- package/dist/parse/inlineFormatting.d.ts.map +1 -1
- package/dist/parse/inlineFormatting.js +104 -5
- package/dist/parse/inlineFormatting.js.map +1 -1
- package/dist/parse/links.js +1 -1
- package/dist/parse/links.js.map +1 -1
- package/dist/parse/softBreaks.js +1 -1
- package/dist/parse/softBreaks.js.map +1 -1
- package/dist/parse/sourceMapping.d.ts.map +1 -1
- package/dist/parse/sourceMapping.js +19 -3
- package/dist/parse/sourceMapping.js.map +1 -1
- package/dist/parse/types.d.ts +24 -0
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +156 -300
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts +33 -0
- package/dist/pipeline/calloutLayout.d.ts.map +1 -1
- package/dist/pipeline/calloutLayout.js +91 -2
- package/dist/pipeline/calloutLayout.js.map +1 -1
- package/dist/pipeline/codeInline.d.ts +10 -1
- package/dist/pipeline/codeInline.d.ts.map +1 -1
- package/dist/pipeline/codeInline.js +96 -15
- package/dist/pipeline/codeInline.js.map +1 -1
- package/dist/pipeline/composedLayout.d.ts +88 -0
- package/dist/pipeline/composedLayout.d.ts.map +1 -0
- package/dist/pipeline/composedLayout.js +320 -0
- package/dist/pipeline/composedLayout.js.map +1 -0
- package/dist/pipeline/config.d.ts.map +1 -1
- package/dist/pipeline/config.js +2 -1
- package/dist/pipeline/config.js.map +1 -1
- package/dist/pipeline/contentWarnings.d.ts.map +1 -1
- package/dist/pipeline/contentWarnings.js +32 -1
- package/dist/pipeline/contentWarnings.js.map +1 -1
- package/dist/pipeline/floatSlots.js +1 -1
- package/dist/pipeline/floatSlots.js.map +1 -1
- package/dist/pipeline/frameLayout.d.ts +120 -0
- package/dist/pipeline/frameLayout.d.ts.map +1 -0
- package/dist/pipeline/frameLayout.js +279 -0
- package/dist/pipeline/frameLayout.js.map +1 -0
- package/dist/pipeline/headerFooter.d.ts.map +1 -1
- package/dist/pipeline/headerFooter.js +48 -3
- package/dist/pipeline/headerFooter.js.map +1 -1
- package/dist/pipeline/pageRoles.d.ts +1 -0
- package/dist/pipeline/pageRoles.d.ts.map +1 -1
- package/dist/pipeline/pageRoles.js +3 -0
- package/dist/pipeline/pageRoles.js.map +1 -1
- package/dist/pipeline/placement.js +1 -1
- package/dist/pipeline/placement.js.map +1 -1
- package/dist/pipeline/resourceLayout.d.ts.map +1 -1
- package/dist/pipeline/resourceLayout.js +5 -3
- package/dist/pipeline/resourceLayout.js.map +1 -1
- package/dist/pipeline/tabs.js +1 -1
- package/dist/pipeline/tabs.js.map +1 -1
- package/dist/types.d.ts +69 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +169 -1
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js.map +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* as they are. Without `codeStyle.inline` inline code is set in the text's
|
|
8
8
|
* face, as before #624.
|
|
9
9
|
*/
|
|
10
|
-
import type { ContentBlock } from '../parse';
|
|
10
|
+
import type { ContentBlock, InlineSpan } from '../parse';
|
|
11
|
+
import type { ResolvedInlineCodeStyleConfig } from '../types';
|
|
11
12
|
import type { ResolvedConfig } from '../vdt';
|
|
12
13
|
/** Style id of an inline code chip: no chip style can name it. */
|
|
13
14
|
export declare const INLINE_CODE_CHIP_STYLE = "__postext-code";
|
|
@@ -19,4 +20,12 @@ export declare const INLINE_CODE_CHIP_STYLE = "__postext-code";
|
|
|
19
20
|
* between backticks.
|
|
20
21
|
*/
|
|
21
22
|
export declare function withInlineCode(block: ContentBlock, raw: ContentBlock, resolved: ResolvedConfig, fontSizePx: number): ContentBlock;
|
|
23
|
+
/**
|
|
24
|
+
* The spans of an inline snippet (a table cell, a caption, a note) with the
|
|
25
|
+
* characters of its inline code set as code chips, when `inline` is set and
|
|
26
|
+
* `content` (the snippet as written, which `spans` were parsed from) has
|
|
27
|
+
* inline code. Run on the spans {@link parseInlineSnippetSpans} returns,
|
|
28
|
+
* before formulas and references are resolved.
|
|
29
|
+
*/
|
|
30
|
+
export declare function withSnippetInlineCode(spans: InlineSpan[], content: string, inline: ResolvedInlineCodeStyleConfig | undefined, dpi: number, fontSizePx: number): InlineSpan[];
|
|
22
31
|
//# sourceMappingURL=codeInline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeInline.d.ts","sourceRoot":"","sources":["../../src/pipeline/codeInline.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAW,YAAY,
|
|
1
|
+
{"version":3,"file":"codeInline.d.ts","sourceRoot":"","sources":["../../src/pipeline/codeInline.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAW,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAM7C,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAyBvD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAajI;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,UAAU,EAAE,CAad"}
|
|
@@ -8,16 +8,13 @@
|
|
|
8
8
|
* face, as before #624.
|
|
9
9
|
*/
|
|
10
10
|
import { sliceSpan } from '../parse/links';
|
|
11
|
+
import { computeSourceMap } from '../parse/sourceMapping';
|
|
11
12
|
import { setsObject } from '../measure/rich';
|
|
12
13
|
import { dimensionToPx } from '../units';
|
|
13
14
|
/** Style id of an inline code chip: no chip style can name it. */
|
|
14
15
|
export const INLINE_CODE_CHIP_STYLE = '__postext-code';
|
|
15
16
|
/** The chip box of inline code in text of `fontSizePx`. */
|
|
16
|
-
function inlineCodeBox(
|
|
17
|
-
const inline = resolved.codeStyle?.inline;
|
|
18
|
-
if (!inline)
|
|
19
|
-
return undefined;
|
|
20
|
-
const dpi = resolved.page.dpi;
|
|
17
|
+
function inlineCodeBox(inline, dpi, fontSizePx) {
|
|
21
18
|
const sizePx = dimensionToPx(inline.fontSize, dpi, fontSizePx);
|
|
22
19
|
const px = (d) => Math.max(0, dimensionToPx(d, dpi, sizePx));
|
|
23
20
|
const borderWidthPx = inline.borderColor ? px(inline.borderWidth) : 0;
|
|
@@ -35,6 +32,7 @@ function inlineCodeBox(resolved, fontSizePx) {
|
|
|
35
32
|
paddingXPx: px(inline.paddingX),
|
|
36
33
|
paddingYPx: px(inline.paddingY),
|
|
37
34
|
gapPx: 0,
|
|
35
|
+
direction: 'ltr',
|
|
38
36
|
};
|
|
39
37
|
}
|
|
40
38
|
/**
|
|
@@ -46,24 +44,108 @@ function inlineCodeBox(resolved, fontSizePx) {
|
|
|
46
44
|
*/
|
|
47
45
|
export function withInlineCode(block, raw, resolved, fontSizePx) {
|
|
48
46
|
const ranges = raw.inlineCode;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const box = inlineCodeBox(resolved, fontSizePx);
|
|
52
|
-
if (!box)
|
|
47
|
+
const inline = resolved.codeStyle?.inline;
|
|
48
|
+
if (!ranges || ranges.length === 0 || !inline)
|
|
53
49
|
return block;
|
|
54
50
|
const prefix = block.text.length - raw.text.length;
|
|
55
51
|
const map = raw.sourceMap;
|
|
56
|
-
const
|
|
52
|
+
const spans = codeChipSpans(block.spans, (p) => {
|
|
57
53
|
const i = p - prefix;
|
|
58
54
|
if (i < 0 || i >= map.length)
|
|
59
55
|
return false;
|
|
60
56
|
const at = map[i];
|
|
61
57
|
return ranges.some((r) => at >= r.start && at < r.end);
|
|
62
|
-
};
|
|
58
|
+
}, inlineCodeBox(inline, resolved.page.dpi, fontSizePx), inline.otherScripts === 'text');
|
|
59
|
+
return spans === block.spans ? block : { ...block, spans };
|
|
60
|
+
}
|
|
61
|
+
/** Inline code between two backticks on one line, outside an escape, as
|
|
62
|
+
* the block parser reads it. */
|
|
63
|
+
const SNIPPET_CODE_RE = /(?<!\\)`([^`\n]+?)`/g;
|
|
64
|
+
/**
|
|
65
|
+
* The spans of an inline snippet (a table cell, a caption, a note) with the
|
|
66
|
+
* characters of its inline code set as code chips, when `inline` is set and
|
|
67
|
+
* `content` (the snippet as written, which `spans` were parsed from) has
|
|
68
|
+
* inline code. Run on the spans {@link parseInlineSnippetSpans} returns,
|
|
69
|
+
* before formulas and references are resolved.
|
|
70
|
+
*/
|
|
71
|
+
export function withSnippetInlineCode(spans, content, inline, dpi, fontSizePx) {
|
|
72
|
+
if (!inline || !content.includes('`'))
|
|
73
|
+
return spans;
|
|
74
|
+
const ranges = [];
|
|
75
|
+
SNIPPET_CODE_RE.lastIndex = 0;
|
|
76
|
+
for (let m = SNIPPET_CODE_RE.exec(content); m; m = SNIPPET_CODE_RE.exec(content)) {
|
|
77
|
+
ranges.push({ start: m.index + 1, end: m.index + 1 + m[1].length });
|
|
78
|
+
}
|
|
79
|
+
if (ranges.length === 0)
|
|
80
|
+
return spans;
|
|
81
|
+
const map = computeSourceMap(content, 0, content.length, spans.map((s) => s.text).join(''));
|
|
82
|
+
return codeChipSpans(spans, (p) => {
|
|
83
|
+
const at = map[p];
|
|
84
|
+
return at !== undefined && ranges.some((r) => at >= r.start && at < r.end);
|
|
85
|
+
}, inlineCodeBox(inline, dpi, fontSizePx), inline.otherScripts === 'text');
|
|
86
|
+
}
|
|
87
|
+
/** The spans of one run of inline code: a chip per piece between its
|
|
88
|
+
* inner spaces, each space a code space a line may break at (#845), so a
|
|
89
|
+
* long piece of code never leaves a line it cannot fill. A hyphen between
|
|
90
|
+
* a letter or digit and a letter (`simp-chinese-informal`) is a place to
|
|
91
|
+
* break too, behind an empty code space: the hyphen stays the code's, and
|
|
92
|
+
* none is added. Spaces that open or close the run stay inside its first
|
|
93
|
+
* or last piece. */
|
|
94
|
+
function codePieces(span, text, box, textFace) {
|
|
95
|
+
const chip = (t, joinNext) => ({
|
|
96
|
+
text: t, bold: span.bold, italic: span.italic,
|
|
97
|
+
chip: { style: INLINE_CODE_CHIP_STYLE, spans: textFace ? codeWords(t) : [{ text: t, bold: false, italic: false }], box, ...(joinNext ? { joinNext: true } : {}) },
|
|
98
|
+
});
|
|
99
|
+
const parts = /^(\s*)(.*?)(\s*)$/s.exec(text);
|
|
100
|
+
const inner = parts[2].split(/( +)|(?<=[\p{L}\p{N}]-)(?=\p{L})/u).map((t) => t ?? '');
|
|
101
|
+
if (inner.length === 1)
|
|
102
|
+
return [chip(text, false)];
|
|
103
|
+
inner[0] = parts[1] + inner[0];
|
|
104
|
+
inner[inner.length - 1] = inner[inner.length - 1] + parts[3];
|
|
105
|
+
const out = [];
|
|
106
|
+
for (let i = 0; i < inner.length; i += 2) {
|
|
107
|
+
const last = i === inner.length - 1;
|
|
108
|
+
out.push(chip(inner[i], !last));
|
|
109
|
+
if (!last)
|
|
110
|
+
out.push({ text: inner[i + 1], bold: span.bold, italic: span.italic, codeSpace: box });
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
/** Letters a code face does not carry: Arabic, Hebrew, Syriac and Thaana,
|
|
115
|
+
* and Chinese, Japanese and Korean, with their full-width marks. */
|
|
116
|
+
const TEXT_FACE_RE = /[\p{Script=Arabic}\p{Script=Hebrew}\p{Script=Syriac}\p{Script=Thaana}\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Bopomofo}\u3000-\u303f\uff00-\uffef]/u;
|
|
117
|
+
const MARK_RE = /\p{M}/u;
|
|
118
|
+
/** The words of a piece of code: one span, or, when it holds letters a
|
|
119
|
+
* code face does not carry (an Arabic word in `:index[…]`, kanji in a
|
|
120
|
+
* ruby), a span per run, those runs set in the text's face (#845). A
|
|
121
|
+
* combining mark goes with the letter before it. */
|
|
122
|
+
function codeWords(text) {
|
|
123
|
+
if (!TEXT_FACE_RE.test(text))
|
|
124
|
+
return [{ text, bold: false, italic: false }];
|
|
125
|
+
const out = [];
|
|
126
|
+
let run = '';
|
|
127
|
+
let face = false;
|
|
128
|
+
for (const ch of text) {
|
|
129
|
+
const own = MARK_RE.test(ch) && run ? face : TEXT_FACE_RE.test(ch);
|
|
130
|
+
if (run && own !== face) {
|
|
131
|
+
out.push({ text: run, bold: false, italic: false, ...(face ? { textFace: true } : {}) });
|
|
132
|
+
run = '';
|
|
133
|
+
}
|
|
134
|
+
face = own;
|
|
135
|
+
run += ch;
|
|
136
|
+
}
|
|
137
|
+
if (run)
|
|
138
|
+
out.push({ text: run, bold: false, italic: false, ...(face ? { textFace: true } : {}) });
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
/** `spans` with every run of characters `isCode` names (by offset in the
|
|
142
|
+
* spans' joined text) set as one code chip in `box`; `spans` itself when
|
|
143
|
+
* none is. Objects (formulas, references, chips…) stay as they are. */
|
|
144
|
+
function codeChipSpans(spans, isCode, box, textFace) {
|
|
63
145
|
const out = [];
|
|
64
146
|
let at = 0;
|
|
65
147
|
let changed = false;
|
|
66
|
-
for (const span of
|
|
148
|
+
for (const span of spans) {
|
|
67
149
|
const len = span.text.length;
|
|
68
150
|
if (setsObject(span) || span.tab || span.inserted || len === 0) {
|
|
69
151
|
out.push(span);
|
|
@@ -80,14 +162,13 @@ export function withInlineCode(block, raw, resolved, fontSizePx) {
|
|
|
80
162
|
out.push(k === 0 && j === len ? span : sliceSpan(span, k, j));
|
|
81
163
|
}
|
|
82
164
|
else {
|
|
83
|
-
|
|
84
|
-
out.push({ text, bold: span.bold, italic: span.italic, chip: { style: INLINE_CODE_CHIP_STYLE, spans: [{ text, bold: false, italic: false }], box } });
|
|
165
|
+
out.push(...codePieces(span, span.text.slice(k, j), box, textFace));
|
|
85
166
|
changed = true;
|
|
86
167
|
}
|
|
87
168
|
k = j;
|
|
88
169
|
}
|
|
89
170
|
at += len;
|
|
90
171
|
}
|
|
91
|
-
return changed ?
|
|
172
|
+
return changed ? out : spans;
|
|
92
173
|
}
|
|
93
174
|
//# sourceMappingURL=codeInline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeInline.js","sourceRoot":"","sources":["../../src/pipeline/codeInline.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"codeInline.js","sourceRoot":"","sources":["../../src/pipeline/codeInline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lay out one composed page (#855, DESIGN §5.1–5.2): place the frames of
|
|
3
|
+
* its template, pour each story (`composed/wrap.ts`) into its frames with
|
|
4
|
+
* the box typesetter (`frameLayout.ts`), and hand back the blocks for the
|
|
5
|
+
* page's floats with the page's `VDTComposedPage`.
|
|
6
|
+
*
|
|
7
|
+
* Per frame, in {@link frameOrder}: its box ({@link placeBox}, an `'auto'`
|
|
8
|
+
* height measured with the content the frame will hold), then its content:
|
|
9
|
+
* the story from where the frame before it in the chain stopped, cut at the
|
|
10
|
+
* frame's foot when a `next` frame takes the rest, else laid whole and
|
|
11
|
+
* clipped at the foot (`frameOverflow`). Text runs round the frames that
|
|
12
|
+
* push it (`exclude: 'push'`) already placed. The groups' negotiation
|
|
13
|
+
* (#856), the reflow ladder (#858) and continuation on other pages (#859)
|
|
14
|
+
* build on this.
|
|
15
|
+
*/
|
|
16
|
+
import type { ComposedPageFence, ContentBlock } from '../parse/types';
|
|
17
|
+
import type { ResolvedCalloutStyleConfig } from '../types';
|
|
18
|
+
import type { ContentWarning, VDTBlock, VDTComposedPage, VDTPage } from '../vdt';
|
|
19
|
+
import { dimensionToPx } from '../units';
|
|
20
|
+
import { type FrameAreas } from '../composed/geometry';
|
|
21
|
+
import type { ResolvedFrame, ResolvedPageTemplate } from '../composed/types';
|
|
22
|
+
import { type PageTemplateSource } from '../composed/templates';
|
|
23
|
+
import { type PlannedCallout } from './calloutLayout';
|
|
24
|
+
import { type FrameLayoutPass } from './frameLayout';
|
|
25
|
+
/** A story of the page: the box `composed/wrap.ts` made of a chain's
|
|
26
|
+
* content, by the name of the chain's first frame. */
|
|
27
|
+
export interface ComposedStory {
|
|
28
|
+
startIdx: number;
|
|
29
|
+
plan: PlannedCallout;
|
|
30
|
+
}
|
|
31
|
+
export interface ComposedPageInput {
|
|
32
|
+
pass: FrameLayoutPass;
|
|
33
|
+
page: VDTPage;
|
|
34
|
+
template: ResolvedPageTemplate;
|
|
35
|
+
fence: ComposedPageFence;
|
|
36
|
+
/** Content index of the page's opening and closing markers. */
|
|
37
|
+
startIdx: number;
|
|
38
|
+
endIdx: number;
|
|
39
|
+
/** The page's stories by head frame name. */
|
|
40
|
+
stories: ReadonlyMap<string, ComposedStory>;
|
|
41
|
+
/** The style a frame is drawn with: its `style`, or frameless. */
|
|
42
|
+
styleOf(frame: ResolvedFrame): ResolvedCalloutStyleConfig;
|
|
43
|
+
areas: FrameAreas;
|
|
44
|
+
dpi: number;
|
|
45
|
+
emPx: number;
|
|
46
|
+
/** Source offset of the body in the chapter file. */
|
|
47
|
+
bodyOffset: number;
|
|
48
|
+
/** The page swaps its mirrored margins (an `'outer'` corner icon). */
|
|
49
|
+
mirrored: boolean;
|
|
50
|
+
/** The gap text keeps from a frame that pushes it. */
|
|
51
|
+
pushGapPx: number;
|
|
52
|
+
}
|
|
53
|
+
export interface ComposedPageLayout {
|
|
54
|
+
composed: VDTComposedPage;
|
|
55
|
+
/** Frame boxes and their content, in paint-independent page order (each
|
|
56
|
+
* frame's box first): for `page.floats` and `doc.blocks`. */
|
|
57
|
+
blocks: VDTBlock[];
|
|
58
|
+
warnings: ContentWarning[];
|
|
59
|
+
/** Story heads laid in a frame of this page. A story left out (its frame
|
|
60
|
+
* is missing on this side) is set in the flow after the page. */
|
|
61
|
+
laid: Set<string>;
|
|
62
|
+
}
|
|
63
|
+
export declare function layoutComposedPage(input: ComposedPageInput): ComposedPageLayout;
|
|
64
|
+
/** The callout style a frame is drawn with: `base` (its `style`, or the
|
|
65
|
+
* frameless frame style) with what a frame sets of its own: its padding
|
|
66
|
+
* (side by side) and a measure that is the frame's. A style's placement,
|
|
67
|
+
* span, width and margins do not apply to a frame. */
|
|
68
|
+
export declare function frameStyleOf(base: ResolvedCalloutStyleConfig, frame: ResolvedFrame): ResolvedCalloutStyleConfig;
|
|
69
|
+
/** The story heads of a composed page's stories, by the head frame's
|
|
70
|
+
* name, read from the boxes `wrapComposedPages` made (`FRAME_ATTR`). */
|
|
71
|
+
export declare function composedStories(startIdx: number, endIdx: number, plans: ReadonlyMap<number, PlannedCallout>): Map<string, ComposedStory>;
|
|
72
|
+
/** `d` in px, 0 when unset. */
|
|
73
|
+
export declare function lengthPx(d: Parameters<typeof dimensionToPx>[0] | undefined, dpi: number, emPx: number): number;
|
|
74
|
+
/** A composed page of the pass whose template is known: its markers and
|
|
75
|
+
* its stories. */
|
|
76
|
+
export interface PlannedComposedPage {
|
|
77
|
+
startIdx: number;
|
|
78
|
+
endIdx: number;
|
|
79
|
+
stories: Map<string, ComposedStory>;
|
|
80
|
+
/** The story box holding block `idx`, if any. */
|
|
81
|
+
storyAt(idx: number): ComposedStory | undefined;
|
|
82
|
+
}
|
|
83
|
+
/** The composed pages of `blocks` whose template `source` has, by their
|
|
84
|
+
* opening marker's index. */
|
|
85
|
+
export declare function planComposedPages(blocks: readonly ContentBlock[], plans: ReadonlyMap<number, PlannedCallout>, source: PageTemplateSource): Map<number, PlannedComposedPage>;
|
|
86
|
+
/** The planned composed page whose markers enclose block `idx`. */
|
|
87
|
+
export declare function composedPageAt(pages: ReadonlyMap<number, PlannedComposedPage>, idx: number): PlannedComposedPage | undefined;
|
|
88
|
+
//# sourceMappingURL=composedLayout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composedLayout.d.ts","sourceRoot":"","sources":["../../src/pipeline/composedLayout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { dimensionToPx } from '../units';
|
|
2
|
+
import { frameBounds } from '../composed/paint';
|
|
3
|
+
import { FRAME_ATTR } from '../composed/wrap';
|
|
4
|
+
import { frameOrder, framePlaceable, nextFrameOf, groupPlaceable, placeBox, unionRect } from '../composed/geometry';
|
|
5
|
+
import { resolvePageTemplate } from '../composed/templates';
|
|
6
|
+
import { offsetCalloutToAbsolute } from './calloutLayout';
|
|
7
|
+
import { CUT_START, fragmentRange, makeCalloutLayouter, splitCalloutFragment } from './frameLayout';
|
|
8
|
+
const MM_PER_IN = 25.4;
|
|
9
|
+
export function layoutComposedPage(input) {
|
|
10
|
+
const { pass, page, template, fence, dpi } = input;
|
|
11
|
+
const fi = fence.fenceIndex;
|
|
12
|
+
const frameIdOf = (name) => `cp${fi}:${name}`;
|
|
13
|
+
const byName = new Map(template.frames.map((f) => [f.name, f]));
|
|
14
|
+
const prev = new Map();
|
|
15
|
+
for (const f of template.frames) {
|
|
16
|
+
const n = nextFrameOf(f);
|
|
17
|
+
if (n && byName.has(n) && !prev.has(n))
|
|
18
|
+
prev.set(n, f.name);
|
|
19
|
+
}
|
|
20
|
+
/** The head of the chain a frame belongs to. */
|
|
21
|
+
const headOf = (name) => {
|
|
22
|
+
let at = name;
|
|
23
|
+
const seen = new Set([at]);
|
|
24
|
+
for (let p = prev.get(at); p !== undefined && !seen.has(p); p = prev.get(at)) {
|
|
25
|
+
seen.add(p);
|
|
26
|
+
at = p;
|
|
27
|
+
}
|
|
28
|
+
return at;
|
|
29
|
+
};
|
|
30
|
+
/** Place and fill every frame. `seed`: the boxes of the frames that push
|
|
31
|
+
* text, from a first run, so a frame placed before one that pushes it
|
|
32
|
+
* (the photo anchored to its box) still runs round it. */
|
|
33
|
+
const run = (seed) => {
|
|
34
|
+
const pushRects = new Map();
|
|
35
|
+
const states = new Map();
|
|
36
|
+
const stateOf = (frame) => {
|
|
37
|
+
const head = headOf(frame.name);
|
|
38
|
+
const known = states.get(head);
|
|
39
|
+
if (known)
|
|
40
|
+
return known;
|
|
41
|
+
const story = input.stories.get(head);
|
|
42
|
+
const headFrame = byName.get(head);
|
|
43
|
+
if (!story || !headFrame)
|
|
44
|
+
return undefined;
|
|
45
|
+
const st = {
|
|
46
|
+
story,
|
|
47
|
+
L: makeCalloutLayouter(pass, story.startIdx, story.plan, input.styleOf(frame)),
|
|
48
|
+
cut: CUT_START,
|
|
49
|
+
pieces: 0,
|
|
50
|
+
headBlockId: frameIdOf(head),
|
|
51
|
+
headFrameId: frameIdOf(head),
|
|
52
|
+
};
|
|
53
|
+
states.set(head, st);
|
|
54
|
+
return st;
|
|
55
|
+
};
|
|
56
|
+
const atEnd = (st) => st.cut.child >= st.L.end.child && st.cut.line === 0 && !st.cut.group;
|
|
57
|
+
const rects = new Map();
|
|
58
|
+
const groupRect = (name) => {
|
|
59
|
+
const g = template.groups.find((gr) => gr.name === name);
|
|
60
|
+
if (!g)
|
|
61
|
+
return undefined;
|
|
62
|
+
const own = groupPlaceable(g);
|
|
63
|
+
if (own)
|
|
64
|
+
return placeBox(own, template, input, (n) => rects.get(n) ?? groupRect(n), () => 0);
|
|
65
|
+
return unionRect(g.frames.flatMap((m) => (rects.has(m) ? [rects.get(m)] : [])));
|
|
66
|
+
};
|
|
67
|
+
const refOf = (name) => rects.get(name) ?? groupRect(name);
|
|
68
|
+
const frames = [];
|
|
69
|
+
const vdtByName = new Map();
|
|
70
|
+
const blocks = [];
|
|
71
|
+
const warnings = [];
|
|
72
|
+
const log = [];
|
|
73
|
+
const laid = new Set();
|
|
74
|
+
const pushed = seed ? [...seed].map(([name, box]) => ({ name, box })) : [];
|
|
75
|
+
/** The rectangles of the pushing frames placed so far that `rect`
|
|
76
|
+
* meets, in the frame block's coordinates. */
|
|
77
|
+
const exclusionsFor = (frame, rect, open) => {
|
|
78
|
+
const out = [];
|
|
79
|
+
const g = input.pushGapPx;
|
|
80
|
+
for (const p of pushed) {
|
|
81
|
+
if (p.name === frame.name)
|
|
82
|
+
continue;
|
|
83
|
+
const b = p.box;
|
|
84
|
+
const below = open ? true : b.y < rect.y + rect.height;
|
|
85
|
+
if (b.x - g >= rect.x + rect.width || b.x + b.width + g <= rect.x || !below || b.y + b.height + g <= rect.y)
|
|
86
|
+
continue;
|
|
87
|
+
out.push({ x: b.x - g - rect.x, y: b.y - g - rect.y, width: b.width + 2 * g, height: b.height + 2 * g });
|
|
88
|
+
}
|
|
89
|
+
return out.length > 0 ? out : undefined;
|
|
90
|
+
};
|
|
91
|
+
for (const frame of frameOrder(template)) {
|
|
92
|
+
const st = stateOf(frame);
|
|
93
|
+
// Each frame of a chain sets the story in its own style: the cuts are
|
|
94
|
+
// positions in the story's blocks, the same in any.
|
|
95
|
+
if (st)
|
|
96
|
+
st.L = makeCalloutLayouter(pass, st.story.startIdx, st.story.plan, input.styleOf(frame));
|
|
97
|
+
// A frame continues its story only once the frame before it in the
|
|
98
|
+
// chain was filled (a frame placed before it, through an anchor, starts
|
|
99
|
+
// empty).
|
|
100
|
+
const before = prev.get(frame.name);
|
|
101
|
+
const reached = st !== undefined && (before === undefined || vdtByName.has(before));
|
|
102
|
+
const holds = reached && !atEnd(st);
|
|
103
|
+
const continuation = st !== undefined && st.pieces > 0;
|
|
104
|
+
const blockId = st && st.pieces > 0 ? `${st.headBlockId}-cont-${st.pieces}` : frameIdOf(frame.name);
|
|
105
|
+
const style = input.styleOf(frame);
|
|
106
|
+
const placeable = framePlaceable(frame);
|
|
107
|
+
/** The content's height at `width`, running round the pushing
|
|
108
|
+
* frames below the top of `at` (the frame's box as first placed). */
|
|
109
|
+
const natural = (at) => (width) => {
|
|
110
|
+
if (!holds)
|
|
111
|
+
return 0;
|
|
112
|
+
const exclusions = at ? exclusionsFor(frame, { ...at, width }, true) : undefined;
|
|
113
|
+
const r = st.L.layoutRange(st.cut, st.L.end, width, blockId, continuation, input.mirrored, exclusions ? { exclusions } : undefined);
|
|
114
|
+
return r.totalHeight;
|
|
115
|
+
};
|
|
116
|
+
// The box: placed with the content's own height, then again with the
|
|
117
|
+
// height it takes running round the frames that push it there.
|
|
118
|
+
const rect0 = placeBox(placeable, template, input, refOf, natural());
|
|
119
|
+
const rect = holds && exclusionsFor(frame, rect0, true) ? placeBox(placeable, template, input, refOf, natural(rect0)) : rect0;
|
|
120
|
+
rects.set(frame.name, rect);
|
|
121
|
+
let result;
|
|
122
|
+
let overflowPx = 0;
|
|
123
|
+
const from = st?.cut ?? CUT_START;
|
|
124
|
+
if (holds) {
|
|
125
|
+
const opts = {
|
|
126
|
+
boxHeight: rect.height,
|
|
127
|
+
verticalAlign: frame.verticalAlign,
|
|
128
|
+
...(exclusionsFor(frame, rect, false) ? { exclusions: exclusionsFor(frame, rect, false) } : {}),
|
|
129
|
+
};
|
|
130
|
+
const whole = st.L.layoutRange(from, st.L.end, rect.width, blockId, continuation, input.mirrored, opts);
|
|
131
|
+
const nextName = nextFrameOf(frame);
|
|
132
|
+
const nextFrame = nextName !== undefined ? byName.get(nextName) : undefined;
|
|
133
|
+
if ((whole.overflowPx ?? 0) > 0.5 && nextFrame && !vdtByName.has(nextFrame.name)) {
|
|
134
|
+
// The rest goes on in the next frame of the chain.
|
|
135
|
+
const minLines = Math.max(1, style.splitMinLines);
|
|
136
|
+
const frag = splitCalloutFragment(pass, st.L, from, rect.width, rect.height, blockId, continuation, minLines, input.mirrored, opts.exclusions ? { exclusions: opts.exclusions } : undefined);
|
|
137
|
+
const to = frag?.to ?? from;
|
|
138
|
+
result = frag
|
|
139
|
+
? st.L.layoutRange(from, to, rect.width, blockId, continuation, input.mirrored, opts)
|
|
140
|
+
: undefined;
|
|
141
|
+
st.cut = to;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
result = whole;
|
|
145
|
+
overflowPx = whole.overflowPx ?? 0;
|
|
146
|
+
st.cut = st.L.end;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (st && frame.style) {
|
|
150
|
+
// A styled frame with nothing (left) to hold still draws its box.
|
|
151
|
+
result = st.L.layoutRange(st.L.end, st.L.end, rect.width, blockId, true, input.mirrored, { boxHeight: rect.height });
|
|
152
|
+
}
|
|
153
|
+
const vdt = {
|
|
154
|
+
id: frameIdOf(frame.name),
|
|
155
|
+
name: frame.name,
|
|
156
|
+
rect: { ...rect },
|
|
157
|
+
rotate: frame.rotate,
|
|
158
|
+
layer: frame.layer,
|
|
159
|
+
...(frame.style ? { styleId: frame.style } : {}),
|
|
160
|
+
scale: 1,
|
|
161
|
+
overflowPx,
|
|
162
|
+
blockIds: [],
|
|
163
|
+
configPath: frame.configPath,
|
|
164
|
+
...(frame.exclude === 'push' ? { push: true } : {}),
|
|
165
|
+
};
|
|
166
|
+
if (before && vdtByName.has(before) && st && st.lastFrameId) {
|
|
167
|
+
vdt.continuedFrom = st.lastFrameId;
|
|
168
|
+
const p = frames.find((f) => f.id === st.lastFrameId);
|
|
169
|
+
if (p)
|
|
170
|
+
p.continuesTo = vdt.id;
|
|
171
|
+
}
|
|
172
|
+
if (result && st) {
|
|
173
|
+
const range = fragmentRange(st.L, from, st.cut);
|
|
174
|
+
commitFrame(result, rect, st.story, range, input, vdt, blocks);
|
|
175
|
+
st.pieces++;
|
|
176
|
+
st.lastFrameId = vdt.id;
|
|
177
|
+
laid.add(headOf(frame.name));
|
|
178
|
+
}
|
|
179
|
+
if (overflowPx > 0.5) {
|
|
180
|
+
const overflowMm = Math.round((overflowPx / dpi) * MM_PER_IN * 10) / 10;
|
|
181
|
+
log.push({ frame: frame.name, kind: 'overflow', toMm: overflowMm });
|
|
182
|
+
warnings.push({
|
|
183
|
+
kind: 'frameOverflow',
|
|
184
|
+
template: template.id,
|
|
185
|
+
frame: frame.name,
|
|
186
|
+
fenceIndex: fi,
|
|
187
|
+
overflowMm,
|
|
188
|
+
configPath: frame.configPath,
|
|
189
|
+
...(vdt.sourceStart !== undefined ? { sourceStart: vdt.sourceStart, sourceEnd: vdt.sourceEnd } : {}),
|
|
190
|
+
pageIndex: page.index,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (frame.exclude === 'push') {
|
|
194
|
+
const box = frameBounds({ rect, rotate: frame.rotate });
|
|
195
|
+
pushRects.set(frame.name, box);
|
|
196
|
+
if (!seed)
|
|
197
|
+
pushed.push({ name: frame.name, box });
|
|
198
|
+
}
|
|
199
|
+
frames.push(vdt);
|
|
200
|
+
vdtByName.set(frame.name, vdt);
|
|
201
|
+
}
|
|
202
|
+
return { frames, blocks, warnings, log, laid, pushRects };
|
|
203
|
+
};
|
|
204
|
+
const first = run();
|
|
205
|
+
const { frames, blocks, warnings, log, laid } = first.pushRects.size > 0 ? run(first.pushRects) : first;
|
|
206
|
+
// Template order on the page record.
|
|
207
|
+
const order = new Map(template.frames.map((f, i) => [f.name, i]));
|
|
208
|
+
frames.sort((a, b) => order.get(a.name) - order.get(b.name));
|
|
209
|
+
const contentBlocks = pass.contentBlocks;
|
|
210
|
+
const composed = {
|
|
211
|
+
template: template.id,
|
|
212
|
+
...(template.variant ? { variant: template.variant } : {}),
|
|
213
|
+
fenceIndex: fi,
|
|
214
|
+
role: template.role,
|
|
215
|
+
attrs: { ...fence.attrs },
|
|
216
|
+
attrSources: Object.fromEntries(Object.entries(fence.attrSources).map(([k, v]) => [k, { sourceStart: v.sourceStart + input.bodyOffset, sourceEnd: v.sourceEnd + input.bodyOffset }])),
|
|
217
|
+
frames,
|
|
218
|
+
log,
|
|
219
|
+
configPath: template.configPath,
|
|
220
|
+
sourceStart: contentBlocks[input.startIdx].sourceStart + input.bodyOffset,
|
|
221
|
+
sourceEnd: contentBlocks[input.endIdx].sourceEnd + input.bodyOffset,
|
|
222
|
+
};
|
|
223
|
+
return { composed, blocks, warnings, laid };
|
|
224
|
+
}
|
|
225
|
+
/** Stamp a frame's laid-out box with its source and page, move it to the
|
|
226
|
+
* frame's place and add it (box first) to `out` and to the frame's ids. */
|
|
227
|
+
function commitFrame(result, rect, story, range, input, vdt, out) {
|
|
228
|
+
const { pass, page, bodyOffset } = input;
|
|
229
|
+
const blocks = pass.contentBlocks;
|
|
230
|
+
const box = result.frame;
|
|
231
|
+
box.contentIndex = story.startIdx;
|
|
232
|
+
const first = blocks[Math.max(story.startIdx + 1, Math.min(range.firstChildIdx, story.plan.endIdx - 1))];
|
|
233
|
+
const last = blocks[Math.max(story.startIdx + 1, Math.min(range.lastChildIdx, story.plan.endIdx - 1))];
|
|
234
|
+
if (first && last && range.lastChildIdx >= range.firstChildIdx) {
|
|
235
|
+
box.sourceStart = first.sourceStart + bodyOffset;
|
|
236
|
+
box.sourceEnd = last.sourceEnd + bodyOffset;
|
|
237
|
+
vdt.sourceStart = box.sourceStart;
|
|
238
|
+
vdt.sourceEnd = box.sourceEnd;
|
|
239
|
+
}
|
|
240
|
+
box.pageIndex = page.index;
|
|
241
|
+
box.columnIndex = 0;
|
|
242
|
+
offsetCalloutToAbsolute(result, rect.x, rect.y);
|
|
243
|
+
out.push(box);
|
|
244
|
+
vdt.blockIds.push(box.id);
|
|
245
|
+
for (const child of result.children) {
|
|
246
|
+
child.pageIndex = page.index;
|
|
247
|
+
child.columnIndex = 0;
|
|
248
|
+
out.push(child);
|
|
249
|
+
vdt.blockIds.push(child.id);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/** The callout style a frame is drawn with: `base` (its `style`, or the
|
|
253
|
+
* frameless frame style) with what a frame sets of its own: its padding
|
|
254
|
+
* (side by side) and a measure that is the frame's. A style's placement,
|
|
255
|
+
* span, width and margins do not apply to a frame. */
|
|
256
|
+
export function frameStyleOf(base, frame) {
|
|
257
|
+
const padding = frame.padding ? { ...base.padding, ...frame.padding } : base.padding;
|
|
258
|
+
return {
|
|
259
|
+
...base,
|
|
260
|
+
padding,
|
|
261
|
+
width: 'fill',
|
|
262
|
+
placement: 'here',
|
|
263
|
+
span: 'column',
|
|
264
|
+
marginTop: { value: 0, unit: 'px' },
|
|
265
|
+
marginBottom: { value: 0, unit: 'px' },
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/** The story heads of a composed page's stories, by the head frame's
|
|
269
|
+
* name, read from the boxes `wrapComposedPages` made (`FRAME_ATTR`). */
|
|
270
|
+
export function composedStories(startIdx, endIdx, plans) {
|
|
271
|
+
const out = new Map();
|
|
272
|
+
for (let i = startIdx + 1; i < endIdx; i++) {
|
|
273
|
+
const plan = plans.get(i);
|
|
274
|
+
if (!plan)
|
|
275
|
+
continue;
|
|
276
|
+
const head = plan.attrs[FRAME_ATTR];
|
|
277
|
+
if (head !== undefined && !out.has(head))
|
|
278
|
+
out.set(head, { startIdx: i, plan });
|
|
279
|
+
i = plan.endIdx;
|
|
280
|
+
}
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
283
|
+
/** `d` in px, 0 when unset. */
|
|
284
|
+
export function lengthPx(d, dpi, emPx) {
|
|
285
|
+
return d ? dimensionToPx(d, dpi, emPx) : 0;
|
|
286
|
+
}
|
|
287
|
+
/** The composed pages of `blocks` whose template `source` has, by their
|
|
288
|
+
* opening marker's index. */
|
|
289
|
+
export function planComposedPages(blocks, plans, source) {
|
|
290
|
+
const out = new Map();
|
|
291
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
292
|
+
const b = blocks[i];
|
|
293
|
+
if (b.type !== 'containerStart' || b.containerName !== 'composedPage' || !b.composedPage)
|
|
294
|
+
continue;
|
|
295
|
+
let end = i + 1;
|
|
296
|
+
while (end < blocks.length && !(blocks[end].type === 'containerEnd' && blocks[end].containerId === b.containerId))
|
|
297
|
+
end++;
|
|
298
|
+
end = Math.min(end, blocks.length - 1);
|
|
299
|
+
if (resolvePageTemplate(source, b.composedPage.template)) {
|
|
300
|
+
const stories = composedStories(i, end, plans);
|
|
301
|
+
const list = [...stories.values()];
|
|
302
|
+
out.set(i, {
|
|
303
|
+
startIdx: i,
|
|
304
|
+
endIdx: end,
|
|
305
|
+
stories,
|
|
306
|
+
storyAt: (idx) => list.find((s) => idx > s.startIdx && idx < s.plan.endIdx),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
i = end;
|
|
310
|
+
}
|
|
311
|
+
return out;
|
|
312
|
+
}
|
|
313
|
+
/** The planned composed page whose markers enclose block `idx`. */
|
|
314
|
+
export function composedPageAt(pages, idx) {
|
|
315
|
+
for (const p of pages.values())
|
|
316
|
+
if (idx > p.startIdx && idx < p.endIdx)
|
|
317
|
+
return p;
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=composedLayout.js.map
|