@segnavia/format 0.37.0 → 0.39.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/board-edit.d.ts +2 -1
- package/dist/board-geometry.d.ts +2 -1
- package/dist/board-section-grid.d.ts +2 -1
- package/dist/board-sections.d.ts +2 -1
- package/dist/board.d.ts +8 -8
- package/dist/board.js +15 -11
- package/dist/book-exports.d.ts +4 -0
- package/dist/book-section.d.ts +225 -3
- package/dist/book-section.js +82 -17
- package/dist/book.d.ts +878 -416
- package/dist/book.js +236 -37
- package/dist/cover.d.ts +337 -0
- package/dist/cover.js +100 -0
- package/dist/deck-from-slides.d.ts +23 -4
- package/dist/deck.d.ts +144 -42
- package/dist/deck.js +22 -24
- package/dist/dependency-policy.d.ts +12 -0
- package/dist/dependency-policy.js +42 -0
- package/dist/direction.d.ts +1 -1
- package/dist/font-collection.d.ts +8 -0
- package/dist/font-collection.js +191 -0
- package/dist/font-face.d.ts +8 -0
- package/dist/font-face.js +24 -0
- package/dist/font-refusal.d.ts +5 -0
- package/dist/font-refusal.js +9 -0
- package/dist/font-signature.d.ts +5 -0
- package/dist/font-signature.js +13 -0
- package/dist/fonts.d.ts +6 -1
- package/dist/fonts.js +3 -1
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.js +18 -0
- package/dist/image-fit.d.ts +10 -0
- package/dist/image-fit.js +10 -0
- package/dist/imposition-marks.d.ts +1 -1
- package/dist/imposition-schema.d.ts +185 -0
- package/dist/imposition-schema.js +122 -0
- package/dist/imposition.d.ts +8 -6
- package/dist/index.d.ts +29 -1797
- package/dist/index.js +30 -210
- package/dist/json-schemas.d.ts +1860 -0
- package/dist/json-schemas.js +43 -0
- package/dist/local-font-limits.d.ts +15 -0
- package/dist/local-font-limits.js +24 -0
- package/dist/media.d.ts +152 -0
- package/dist/media.js +119 -0
- package/dist/note-series.d.ts +70 -0
- package/dist/note-series.js +153 -0
- package/dist/page.d.ts +174 -0
- package/dist/page.js +37 -0
- package/dist/paper.d.ts +2 -1
- package/dist/paper.js +2 -1
- package/dist/placement-cycle.d.ts +5 -0
- package/dist/placement-cycle.js +30 -0
- package/dist/placement-refusal.d.ts +5 -0
- package/dist/placement-refusal.js +6 -0
- package/dist/placement.d.ts +76 -0
- package/dist/placement.js +100 -0
- package/dist/print.d.ts +72 -0
- package/dist/print.js +38 -0
- package/dist/printed-page-imposition.d.ts +2 -1
- package/dist/printed-pages.d.ts +14 -0
- package/dist/printed-pages.js +14 -1
- package/dist/shots-used.d.ts +0 -1
- package/dist/shots-used.js +2 -2
- package/dist/slots.d.ts +13 -13
- package/package.json +1 -1
package/dist/page.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/page.d.ts
|
|
3
|
+
export declare const FLUID_WIDTH = 1024;
|
|
4
|
+
export declare const PageSize: z.ZodUnion<readonly [z.ZodLiteral<"fluid">, z.ZodObject<{
|
|
5
|
+
width: z.ZodNumber;
|
|
6
|
+
height: z.ZodNumber;
|
|
7
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
8
|
+
width: z.ZodNumber;
|
|
9
|
+
height: z.ZodLiteral<"auto">;
|
|
10
|
+
}, z.core.$strip>]>;
|
|
11
|
+
export type PageSize = z.infer<typeof PageSize>;
|
|
12
|
+
export declare const Page: z.ZodObject<{
|
|
13
|
+
id: z.ZodOptional<z.ZodString>;
|
|
14
|
+
html: z.ZodString;
|
|
15
|
+
size: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"fluid">, z.ZodObject<{
|
|
16
|
+
width: z.ZodNumber;
|
|
17
|
+
height: z.ZodNumber;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
width: z.ZodNumber;
|
|
20
|
+
height: z.ZodLiteral<"auto">;
|
|
21
|
+
}, z.core.$strip>]>>;
|
|
22
|
+
scripts: z.ZodDefault<z.ZodEnum<{
|
|
23
|
+
refuse: "refuse";
|
|
24
|
+
sandboxed: "sandboxed";
|
|
25
|
+
}>>;
|
|
26
|
+
dir: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
auto: "auto";
|
|
28
|
+
ltr: "ltr";
|
|
29
|
+
rtl: "rtl";
|
|
30
|
+
}>>;
|
|
31
|
+
lang: z.ZodOptional<z.ZodString>;
|
|
32
|
+
print: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
paper: z.ZodUnion<readonly [z.ZodEnum<{
|
|
34
|
+
letter: "letter";
|
|
35
|
+
legal: "legal";
|
|
36
|
+
tabloid: "tabloid";
|
|
37
|
+
a3: "a3";
|
|
38
|
+
a4: "a4";
|
|
39
|
+
a5: "a5";
|
|
40
|
+
"business-card-us": "business-card-us";
|
|
41
|
+
"business-card-eu": "business-card-eu";
|
|
42
|
+
"business-card-square-us": "business-card-square-us";
|
|
43
|
+
"business-card-slim-us": "business-card-slim-us";
|
|
44
|
+
"postcard-4x6": "postcard-4x6";
|
|
45
|
+
"postcard-5x7": "postcard-5x7";
|
|
46
|
+
"postcard-6x9": "postcard-6x9";
|
|
47
|
+
"postcard-6x11": "postcard-6x11";
|
|
48
|
+
"card-square-4in": "card-square-4in";
|
|
49
|
+
"half-letter": "half-letter";
|
|
50
|
+
a6: "a6";
|
|
51
|
+
dl: "dl";
|
|
52
|
+
"rack-card-4x9": "rack-card-4x9";
|
|
53
|
+
"rack-card-3.5x8.5": "rack-card-3.5x8.5";
|
|
54
|
+
"poster-12x18": "poster-12x18";
|
|
55
|
+
"poster-16x20": "poster-16x20";
|
|
56
|
+
"poster-18x24": "poster-18x24";
|
|
57
|
+
"poster-24x36": "poster-24x36";
|
|
58
|
+
a2: "a2";
|
|
59
|
+
a1: "a1";
|
|
60
|
+
a0: "a0";
|
|
61
|
+
}>, z.ZodObject<{
|
|
62
|
+
width: z.ZodNumber;
|
|
63
|
+
height: z.ZodNumber;
|
|
64
|
+
unit: z.ZodEnum<{
|
|
65
|
+
mm: "mm";
|
|
66
|
+
in: "in";
|
|
67
|
+
pt: "pt";
|
|
68
|
+
}>;
|
|
69
|
+
}, z.core.$strip>]>;
|
|
70
|
+
orientation: z.ZodDefault<z.ZodEnum<{
|
|
71
|
+
portrait: "portrait";
|
|
72
|
+
landscape: "landscape";
|
|
73
|
+
}>>;
|
|
74
|
+
margin: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
top: z.ZodDefault<z.ZodNumber>;
|
|
76
|
+
right: z.ZodDefault<z.ZodNumber>;
|
|
77
|
+
bottom: z.ZodDefault<z.ZodNumber>;
|
|
78
|
+
left: z.ZodDefault<z.ZodNumber>;
|
|
79
|
+
}, z.core.$strip>>;
|
|
80
|
+
bleed: z.ZodDefault<z.ZodNumber>;
|
|
81
|
+
safe: z.ZodDefault<z.ZodNumber>;
|
|
82
|
+
marks: z.ZodDefault<z.ZodBoolean>;
|
|
83
|
+
markColor: z.ZodDefault<z.ZodEnum<{
|
|
84
|
+
black: "black";
|
|
85
|
+
registration: "registration";
|
|
86
|
+
}>>;
|
|
87
|
+
}, z.core.$strip>>;
|
|
88
|
+
printedPages: z.ZodOptional<z.ZodObject<{
|
|
89
|
+
parents: z.ZodArray<z.ZodObject<{
|
|
90
|
+
name: z.ZodString;
|
|
91
|
+
basedOn: z.ZodOptional<z.ZodString>;
|
|
92
|
+
margin: z.ZodOptional<z.ZodObject<{
|
|
93
|
+
top: z.ZodNumber;
|
|
94
|
+
bottom: z.ZodNumber;
|
|
95
|
+
inner: z.ZodNumber;
|
|
96
|
+
outer: z.ZodNumber;
|
|
97
|
+
}, z.core.$strip>>;
|
|
98
|
+
head: z.ZodOptional<z.ZodString>;
|
|
99
|
+
foot: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, z.core.$strip>>;
|
|
101
|
+
rules: z.ZodPipe<z.ZodObject<{
|
|
102
|
+
every: z.ZodString;
|
|
103
|
+
first: z.ZodOptional<z.ZodString>;
|
|
104
|
+
recto: z.ZodOptional<z.ZodString>;
|
|
105
|
+
verso: z.ZodOptional<z.ZodString>;
|
|
106
|
+
last: z.ZodOptional<z.ZodString>;
|
|
107
|
+
}, z.core.$loose>, z.ZodTransform<{
|
|
108
|
+
last?: string | undefined;
|
|
109
|
+
verso?: string | undefined;
|
|
110
|
+
recto?: string | undefined;
|
|
111
|
+
first?: string | undefined;
|
|
112
|
+
every: string;
|
|
113
|
+
}, {
|
|
114
|
+
[x: string]: unknown;
|
|
115
|
+
every: string;
|
|
116
|
+
first?: string | undefined;
|
|
117
|
+
recto?: string | undefined;
|
|
118
|
+
verso?: string | undefined;
|
|
119
|
+
last?: string | undefined;
|
|
120
|
+
}>>;
|
|
121
|
+
numbering: z.ZodOptional<z.ZodEnum<{
|
|
122
|
+
arabic: "arabic";
|
|
123
|
+
"roman-lower": "roman-lower";
|
|
124
|
+
"roman-upper": "roman-upper";
|
|
125
|
+
hebrew: "hebrew";
|
|
126
|
+
}>>;
|
|
127
|
+
}, z.core.$strip>>;
|
|
128
|
+
slots: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
129
|
+
key: z.ZodString;
|
|
130
|
+
label: z.ZodString;
|
|
131
|
+
type: z.ZodEnum<{
|
|
132
|
+
text: "text";
|
|
133
|
+
image: "image";
|
|
134
|
+
phone: "phone";
|
|
135
|
+
email: "email";
|
|
136
|
+
link: "link";
|
|
137
|
+
qr: "qr";
|
|
138
|
+
}>;
|
|
139
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
140
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
141
|
+
overflow: z.ZodDefault<z.ZodEnum<{
|
|
142
|
+
refuse: "refuse";
|
|
143
|
+
shrink: "shrink";
|
|
144
|
+
truncate: "truncate";
|
|
145
|
+
wrap: "wrap";
|
|
146
|
+
}>>;
|
|
147
|
+
minSize: z.ZodOptional<z.ZodNumber>;
|
|
148
|
+
}, z.core.$strip>, z.ZodTransform<{
|
|
149
|
+
key: string;
|
|
150
|
+
label: string;
|
|
151
|
+
type: "text" | "image" | "phone" | "email" | "link" | "qr";
|
|
152
|
+
required: boolean;
|
|
153
|
+
overflow: "refuse" | "shrink" | "truncate" | "wrap";
|
|
154
|
+
placeholder?: string | undefined;
|
|
155
|
+
minSize?: number | undefined;
|
|
156
|
+
}, {
|
|
157
|
+
key: string;
|
|
158
|
+
label: string;
|
|
159
|
+
type: "text" | "image" | "phone" | "email" | "link" | "qr";
|
|
160
|
+
required: boolean;
|
|
161
|
+
overflow: "refuse" | "shrink" | "truncate" | "wrap";
|
|
162
|
+
placeholder?: string | undefined;
|
|
163
|
+
minSize?: number | undefined;
|
|
164
|
+
}>>>>;
|
|
165
|
+
fonts: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
166
|
+
app: z.ZodString;
|
|
167
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
168
|
+
local: z.ZodString;
|
|
169
|
+
fallback: z.ZodString;
|
|
170
|
+
}, z.core.$strip>]>>>;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
export type Page = z.infer<typeof Page>;
|
|
173
|
+
export type PageInput = z.input<typeof Page>;
|
|
174
|
+
//#endregion
|
package/dist/page.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Direction } from "./direction.js";
|
|
2
|
+
import { Size } from "./geometry.js";
|
|
3
|
+
import { Scripts } from "./scripts.js";
|
|
4
|
+
import { Slots } from "./slots.js";
|
|
5
|
+
import { FontReference } from "./fonts.js";
|
|
6
|
+
import { PrintedPages, pagePrintedPagesIssues } from "./printed-pages.js";
|
|
7
|
+
import { Print } from "./print.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
//#region src/page.ts
|
|
10
|
+
const FLUID_WIDTH = 1024;
|
|
11
|
+
const PageSize = z.union([
|
|
12
|
+
z.literal("fluid"),
|
|
13
|
+
Size,
|
|
14
|
+
z.object({
|
|
15
|
+
width: z.number().int().positive(),
|
|
16
|
+
height: z.literal("auto")
|
|
17
|
+
})
|
|
18
|
+
]);
|
|
19
|
+
const Page = z.object({
|
|
20
|
+
id: z.string().optional(),
|
|
21
|
+
html: z.string(),
|
|
22
|
+
size: PageSize.default("fluid"),
|
|
23
|
+
scripts: Scripts.default("refuse"),
|
|
24
|
+
dir: Direction.optional(),
|
|
25
|
+
lang: z.string().optional(),
|
|
26
|
+
print: Print.optional(),
|
|
27
|
+
printedPages: PrintedPages.optional(),
|
|
28
|
+
slots: Slots.optional(),
|
|
29
|
+
fonts: z.array(FontReference).optional()
|
|
30
|
+
}).superRefine((page, ctx) => {
|
|
31
|
+
for (const issue of pagePrintedPagesIssues(page)) ctx.addIssue({
|
|
32
|
+
code: "custom",
|
|
33
|
+
...issue
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//#endregion
|
|
37
|
+
export { FLUID_WIDTH, Page, PageSize };
|
package/dist/paper.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Print } from "./
|
|
1
|
+
import { Print } from "./print.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region src/paper.d.ts
|
|
4
4
|
export declare const NAMED_PAPERS: readonly ["letter", "legal", "tabloid", "a3", "a4", "a5", "business-card-us", "business-card-eu", "business-card-square-us", "business-card-slim-us", "postcard-4x6", "postcard-5x7", "postcard-6x9", "postcard-6x11", "card-square-4in", "half-letter", "a6", "dl", "rack-card-4x9", "rack-card-3.5x8.5", "poster-12x18", "poster-16x20", "poster-18x24", "poster-24x36", "a2", "a1", "a0"];
|
|
@@ -305,6 +305,7 @@ export declare function sheetMm(print: Pick<Print, 'paper' | 'orientation'>): {
|
|
|
305
305
|
height: number;
|
|
306
306
|
};
|
|
307
307
|
export declare const PX_PER_MM: number;
|
|
308
|
+
export declare const PX_PER_PT: number;
|
|
308
309
|
export declare const paperPixels: (millimeters: number) => number;
|
|
309
310
|
export declare function printProperties(print: Pick<Print, 'bleed' | 'safe'>, unit?: 'mm' | 'in' | 'pt'): string;
|
|
310
311
|
export declare function printPadding(edges: {
|
package/dist/paper.js
CHANGED
|
@@ -375,6 +375,7 @@ function sheetMm(print) {
|
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
377
|
const PX_PER_MM = 96 / 25.4;
|
|
378
|
+
const PX_PER_PT = PX_PER_MM * MM_PER_PT;
|
|
378
379
|
const paperPixels = (millimeters) => Math.ceil(millimeters * PX_PER_MM - 1e-9);
|
|
379
380
|
function printProperties(print, unit = "mm") {
|
|
380
381
|
return `:root{--segnavia-bleed:${roundMillimeters(toMillimeters(print.bleed, unit))}mm;--segnavia-safe:${roundMillimeters(toMillimeters(print.safe, unit))}mm}`;
|
|
@@ -485,4 +486,4 @@ function printBoxes(print) {
|
|
|
485
486
|
};
|
|
486
487
|
}
|
|
487
488
|
//#endregion
|
|
488
|
-
export { CUSTOM_PAPER_MAX_MM, CUSTOM_PAPER_MIN_MM, FOLD_DASH_OFF_MM, FOLD_DASH_ON_MM, MARK_GAP_MM, MARK_LENGTH_MM, MM_PER_PT, NAMED_PAPERS, ORIENTATIONS, Orientation, PAPER_GROUPS, PAPER_METADATA, PAPER_MM, PAPER_UNITS, PX_PER_MM, Paper, PaperUnit, PrintSetting, PrintSettingInput, fromMillimeters, paperPixels, printBoxes, printPadding, printProperties, roundMillimeters, sheetMm, toMillimeters };
|
|
489
|
+
export { CUSTOM_PAPER_MAX_MM, CUSTOM_PAPER_MIN_MM, FOLD_DASH_OFF_MM, FOLD_DASH_ON_MM, MARK_GAP_MM, MARK_LENGTH_MM, MM_PER_PT, NAMED_PAPERS, ORIENTATIONS, Orientation, PAPER_GROUPS, PAPER_METADATA, PAPER_MM, PAPER_UNITS, PX_PER_MM, PX_PER_PT, Paper, PaperUnit, PrintSetting, PrintSettingInput, fromMillimeters, paperPixels, printBoxes, printPadding, printProperties, roundMillimeters, sheetMm, toMillimeters };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/placement-cycle.d.ts
|
|
2
|
+
export type PlacementGraph = Readonly<Record<string, readonly string[]>>;
|
|
3
|
+
export declare function findPlacementCycle(graph: PlacementGraph): string[] | undefined;
|
|
4
|
+
export declare function checkPlacementCycles(graph: PlacementGraph): void;
|
|
5
|
+
//#endregion
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PlacementRefusedError } from "./placement-refusal.js";
|
|
2
|
+
//#region src/placement-cycle.ts
|
|
3
|
+
function findPlacementCycle(graph) {
|
|
4
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
5
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6
|
+
const path = [];
|
|
7
|
+
const visit = (address) => {
|
|
8
|
+
if (visiting.has(address)) return [...path.slice(path.indexOf(address)), address];
|
|
9
|
+
if (visited.has(address)) return void 0;
|
|
10
|
+
visiting.add(address);
|
|
11
|
+
path.push(address);
|
|
12
|
+
for (const child of graph[address] ?? []) {
|
|
13
|
+
const cycle = visit(child);
|
|
14
|
+
if (cycle) return cycle;
|
|
15
|
+
}
|
|
16
|
+
path.pop();
|
|
17
|
+
visiting.delete(address);
|
|
18
|
+
visited.add(address);
|
|
19
|
+
};
|
|
20
|
+
for (const address of Object.keys(graph)) {
|
|
21
|
+
const cycle = visit(address);
|
|
22
|
+
if (cycle) return cycle;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function checkPlacementCycles(graph) {
|
|
26
|
+
const cycle = findPlacementCycle(graph);
|
|
27
|
+
if (cycle) throw new PlacementRefusedError(`address could not be accepted because the placement chain ${cycle.join(" → ")} is a cycle; remove any one placement in the chain to clear this refusal`);
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { checkPlacementCycles, findPlacementCycle };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Media } from "./media.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/placement.d.ts
|
|
4
|
+
export declare const PLACEMENT_ACCEPTS: {
|
|
5
|
+
readonly board: readonly ["deck", "page", "paper", "book", "media", "shot"];
|
|
6
|
+
readonly book: readonly ["media", "page"];
|
|
7
|
+
readonly page: readonly ["media"];
|
|
8
|
+
readonly deck: readonly ["media"];
|
|
9
|
+
readonly paper: readonly ["media"];
|
|
10
|
+
};
|
|
11
|
+
export declare const AssetKind: z.ZodEnum<{
|
|
12
|
+
deck: "deck";
|
|
13
|
+
page: "page";
|
|
14
|
+
paper: "paper";
|
|
15
|
+
book: "book";
|
|
16
|
+
media: "media";
|
|
17
|
+
shot: "shot";
|
|
18
|
+
}>;
|
|
19
|
+
export type AssetKind = z.infer<typeof AssetKind>;
|
|
20
|
+
export type PlacementContainer = keyof typeof PLACEMENT_ACCEPTS;
|
|
21
|
+
export declare const CropEdge: z.ZodString;
|
|
22
|
+
export type CropEdge = z.infer<typeof CropEdge>;
|
|
23
|
+
export declare const PlacementCrop: z.ZodObject<{
|
|
24
|
+
top: z.ZodOptional<z.ZodString>;
|
|
25
|
+
right: z.ZodOptional<z.ZodString>;
|
|
26
|
+
bottom: z.ZodOptional<z.ZodString>;
|
|
27
|
+
left: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export type PlacementCrop = z.infer<typeof PlacementCrop>;
|
|
30
|
+
export declare const PlacementShape: z.ZodObject<{
|
|
31
|
+
kind: z.ZodEnum<{
|
|
32
|
+
deck: "deck";
|
|
33
|
+
page: "page";
|
|
34
|
+
paper: "paper";
|
|
35
|
+
book: "book";
|
|
36
|
+
media: "media";
|
|
37
|
+
shot: "shot";
|
|
38
|
+
}>;
|
|
39
|
+
address: z.ZodString;
|
|
40
|
+
page: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
41
|
+
box: z.ZodOptional<z.ZodEnum<{
|
|
42
|
+
media: "media";
|
|
43
|
+
bleed: "bleed";
|
|
44
|
+
crop: "crop";
|
|
45
|
+
trim: "trim";
|
|
46
|
+
art: "art";
|
|
47
|
+
}>>;
|
|
48
|
+
crop: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
top: z.ZodOptional<z.ZodString>;
|
|
50
|
+
right: z.ZodOptional<z.ZodString>;
|
|
51
|
+
bottom: z.ZodOptional<z.ZodString>;
|
|
52
|
+
left: z.ZodOptional<z.ZodString>;
|
|
53
|
+
}, z.core.$strip>>;
|
|
54
|
+
fit: z.ZodOptional<z.ZodEnum<{
|
|
55
|
+
width: "width";
|
|
56
|
+
contain: "contain";
|
|
57
|
+
cover: "cover";
|
|
58
|
+
focus: "focus";
|
|
59
|
+
}>>;
|
|
60
|
+
alt: z.ZodOptional<z.ZodObject<{
|
|
61
|
+
text: z.ZodString;
|
|
62
|
+
lang: z.ZodOptional<z.ZodString>;
|
|
63
|
+
dir: z.ZodOptional<z.ZodEnum<{
|
|
64
|
+
auto: "auto";
|
|
65
|
+
ltr: "ltr";
|
|
66
|
+
rtl: "rtl";
|
|
67
|
+
}>>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export type Placement = z.infer<typeof PlacementShape>;
|
|
71
|
+
export type PlacementInput = z.input<typeof PlacementShape>;
|
|
72
|
+
declare function parsePlacement(input: PlacementInput, container: PlacementContainer, placed?: Media): Placement;
|
|
73
|
+
export declare const Placement: {
|
|
74
|
+
parse: typeof parsePlacement;
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ImageFit } from "./image-fit.js";
|
|
2
|
+
import { MEDIA_FORMATS, MediaText, PAGE_BOXES, PageBoxName, PageSelector } from "./media.js";
|
|
3
|
+
import { PlacementRefusedError } from "./placement-refusal.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/placement.ts
|
|
6
|
+
const PLACEMENT_ACCEPTS = {
|
|
7
|
+
board: [
|
|
8
|
+
"deck",
|
|
9
|
+
"page",
|
|
10
|
+
"paper",
|
|
11
|
+
"book",
|
|
12
|
+
"media",
|
|
13
|
+
"shot"
|
|
14
|
+
],
|
|
15
|
+
book: ["media", "page"],
|
|
16
|
+
page: ["media"],
|
|
17
|
+
deck: ["media"],
|
|
18
|
+
paper: ["media"]
|
|
19
|
+
};
|
|
20
|
+
const AssetKind = z.enum(PLACEMENT_ACCEPTS.board);
|
|
21
|
+
const CropEdge = z.string().regex(/^(?:0|(?:\d+(?:\.\d+)?|\.\d+)(?:%|px|pt|mm|cm|in))$/, "crop edge must be 0 or a non-negative CSS length or percentage");
|
|
22
|
+
function percentage(edge) {
|
|
23
|
+
return edge?.endsWith("%") ? Number(edge.slice(0, -1)) : void 0;
|
|
24
|
+
}
|
|
25
|
+
function addCropAxisIssue(crop, first, second, ctx) {
|
|
26
|
+
const one = percentage(crop[first]);
|
|
27
|
+
const two = percentage(crop[second]);
|
|
28
|
+
const overfull = one !== void 0 && one > 100 ? first : two !== void 0 && two > 100 ? second : void 0;
|
|
29
|
+
if (overfull !== void 0) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: "custom",
|
|
32
|
+
path: [overfull],
|
|
33
|
+
message: `${overfull} crop percentage must be at most 100%; lower it to clear this refusal`
|
|
34
|
+
});
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if ((one ?? 0) + (two ?? 0) < 100) return;
|
|
38
|
+
const percentageEdges = [one === void 0 ? void 0 : first, two === void 0 ? void 0 : second].filter((edge) => edge !== void 0);
|
|
39
|
+
const subject = percentageEdges.join(" and ");
|
|
40
|
+
ctx.addIssue({
|
|
41
|
+
code: "custom",
|
|
42
|
+
path: [first],
|
|
43
|
+
message: percentageEdges.length === 1 ? `${subject} crop percentage leaves no area; lower ${subject} below 100% to clear this refusal` : `${subject} crop percentages leave no area; lower either edge so their sum is below 100% to clear this refusal`
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const PlacementCrop = z.object({
|
|
47
|
+
top: CropEdge.optional(),
|
|
48
|
+
right: CropEdge.optional(),
|
|
49
|
+
bottom: CropEdge.optional(),
|
|
50
|
+
left: CropEdge.optional()
|
|
51
|
+
}).superRefine((crop, ctx) => {
|
|
52
|
+
for (const [first, second] of [["top", "bottom"], ["left", "right"]]) addCropAxisIssue(crop, first, second, ctx);
|
|
53
|
+
});
|
|
54
|
+
const PlacementShape = z.object({
|
|
55
|
+
kind: AssetKind,
|
|
56
|
+
address: z.string().min(1),
|
|
57
|
+
page: PageSelector.optional(),
|
|
58
|
+
box: PageBoxName.optional(),
|
|
59
|
+
crop: PlacementCrop.optional(),
|
|
60
|
+
fit: ImageFit.optional(),
|
|
61
|
+
alt: MediaText.optional()
|
|
62
|
+
});
|
|
63
|
+
const FIELD_REMEDIES = {
|
|
64
|
+
kind: `pass one of ${AssetKind.options.join(", ")}`,
|
|
65
|
+
address: "pass a non-empty address",
|
|
66
|
+
page: "pass a positive page number or a non-empty page name",
|
|
67
|
+
box: `pass one of ${PAGE_BOXES.join(", ")}`,
|
|
68
|
+
crop: "pass non-negative crop edges using supported CSS units",
|
|
69
|
+
fit: "pass contain, cover, width or focus",
|
|
70
|
+
alt: "pass non-empty alt text with an optional language and direction"
|
|
71
|
+
};
|
|
72
|
+
function shapeRefusal(error) {
|
|
73
|
+
const issue = error.issues[0];
|
|
74
|
+
const field = String(issue?.path[0] ?? "kind");
|
|
75
|
+
const detail = issue?.message ?? "the value is invalid";
|
|
76
|
+
if (issue?.code === "custom") return new PlacementRefusedError(`${field} could not be accepted: ${detail}`);
|
|
77
|
+
return new PlacementRefusedError(`${field} could not be accepted: ${detail}; ${FIELD_REMEDIES[field]} to clear this refusal`);
|
|
78
|
+
}
|
|
79
|
+
const PLACEMENT_SETTING_NEEDS = {
|
|
80
|
+
page: "pages",
|
|
81
|
+
box: "pages",
|
|
82
|
+
crop: "media"
|
|
83
|
+
};
|
|
84
|
+
function parsePlacement(input, container, placed) {
|
|
85
|
+
const parsed = PlacementShape.safeParse(input);
|
|
86
|
+
if (!parsed.success) throw shapeRefusal(parsed.error);
|
|
87
|
+
const placement = parsed.data;
|
|
88
|
+
const accepted = PLACEMENT_ACCEPTS[container];
|
|
89
|
+
if (accepted === void 0) throw new PlacementRefusedError(`container could not be accepted: ${container}; place into one of ${Object.keys(PLACEMENT_ACCEPTS).join(", ")} to clear this refusal`);
|
|
90
|
+
if (!accepted.includes(placement.kind)) throw new PlacementRefusedError(`kind could not be accepted: ${container} does not accept ${placement.kind}; place one of ${accepted.join(", ")} to clear this refusal`);
|
|
91
|
+
for (const field of Object.keys(PLACEMENT_SETTING_NEEDS)) {
|
|
92
|
+
const need = PLACEMENT_SETTING_NEEDS[field];
|
|
93
|
+
if (placement[field] !== void 0 && placement.kind !== "media") throw new PlacementRefusedError(`${field} could not be accepted on ${placement.kind}; remove ${field} or place media to clear this refusal`);
|
|
94
|
+
if (placement[field] !== void 0 && need === "pages" && placed && !MEDIA_FORMATS[placed.format].pages) throw new PlacementRefusedError(`${field} could not be accepted for ${placed.format} media; remove ${field} or place media with pages to clear this refusal`);
|
|
95
|
+
}
|
|
96
|
+
return placement;
|
|
97
|
+
}
|
|
98
|
+
const Placement = { parse: parsePlacement };
|
|
99
|
+
//#endregion
|
|
100
|
+
export { AssetKind, CropEdge, PLACEMENT_ACCEPTS, Placement, PlacementCrop, PlacementShape };
|
package/dist/print.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/print.d.ts
|
|
3
|
+
export declare const Margin: z.ZodObject<{
|
|
4
|
+
top: z.ZodDefault<z.ZodNumber>;
|
|
5
|
+
right: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
bottom: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
left: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
export declare const MarkColor: z.ZodEnum<{
|
|
10
|
+
black: "black";
|
|
11
|
+
registration: "registration";
|
|
12
|
+
}>;
|
|
13
|
+
export type MarkColor = z.infer<typeof MarkColor>;
|
|
14
|
+
export declare const Print: z.ZodObject<{
|
|
15
|
+
paper: z.ZodUnion<readonly [z.ZodEnum<{
|
|
16
|
+
letter: "letter";
|
|
17
|
+
legal: "legal";
|
|
18
|
+
tabloid: "tabloid";
|
|
19
|
+
a3: "a3";
|
|
20
|
+
a4: "a4";
|
|
21
|
+
a5: "a5";
|
|
22
|
+
"business-card-us": "business-card-us";
|
|
23
|
+
"business-card-eu": "business-card-eu";
|
|
24
|
+
"business-card-square-us": "business-card-square-us";
|
|
25
|
+
"business-card-slim-us": "business-card-slim-us";
|
|
26
|
+
"postcard-4x6": "postcard-4x6";
|
|
27
|
+
"postcard-5x7": "postcard-5x7";
|
|
28
|
+
"postcard-6x9": "postcard-6x9";
|
|
29
|
+
"postcard-6x11": "postcard-6x11";
|
|
30
|
+
"card-square-4in": "card-square-4in";
|
|
31
|
+
"half-letter": "half-letter";
|
|
32
|
+
a6: "a6";
|
|
33
|
+
dl: "dl";
|
|
34
|
+
"rack-card-4x9": "rack-card-4x9";
|
|
35
|
+
"rack-card-3.5x8.5": "rack-card-3.5x8.5";
|
|
36
|
+
"poster-12x18": "poster-12x18";
|
|
37
|
+
"poster-16x20": "poster-16x20";
|
|
38
|
+
"poster-18x24": "poster-18x24";
|
|
39
|
+
"poster-24x36": "poster-24x36";
|
|
40
|
+
a2: "a2";
|
|
41
|
+
a1: "a1";
|
|
42
|
+
a0: "a0";
|
|
43
|
+
}>, z.ZodObject<{
|
|
44
|
+
width: z.ZodNumber;
|
|
45
|
+
height: z.ZodNumber;
|
|
46
|
+
unit: z.ZodEnum<{
|
|
47
|
+
mm: "mm";
|
|
48
|
+
in: "in";
|
|
49
|
+
pt: "pt";
|
|
50
|
+
}>;
|
|
51
|
+
}, z.core.$strip>]>;
|
|
52
|
+
orientation: z.ZodDefault<z.ZodEnum<{
|
|
53
|
+
portrait: "portrait";
|
|
54
|
+
landscape: "landscape";
|
|
55
|
+
}>>;
|
|
56
|
+
margin: z.ZodOptional<z.ZodObject<{
|
|
57
|
+
top: z.ZodDefault<z.ZodNumber>;
|
|
58
|
+
right: z.ZodDefault<z.ZodNumber>;
|
|
59
|
+
bottom: z.ZodDefault<z.ZodNumber>;
|
|
60
|
+
left: z.ZodDefault<z.ZodNumber>;
|
|
61
|
+
}, z.core.$strip>>;
|
|
62
|
+
bleed: z.ZodDefault<z.ZodNumber>;
|
|
63
|
+
safe: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
marks: z.ZodDefault<z.ZodBoolean>;
|
|
65
|
+
markColor: z.ZodDefault<z.ZodEnum<{
|
|
66
|
+
black: "black";
|
|
67
|
+
registration: "registration";
|
|
68
|
+
}>>;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export type Print = z.infer<typeof Print>;
|
|
71
|
+
export type PrintInput = z.input<typeof Print>;
|
|
72
|
+
//#endregion
|
package/dist/print.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Orientation, Paper, sheetMm } from "./paper.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/print.ts
|
|
4
|
+
const Margin = z.object({
|
|
5
|
+
top: z.number().nonnegative().default(0),
|
|
6
|
+
right: z.number().nonnegative().default(0),
|
|
7
|
+
bottom: z.number().nonnegative().default(0),
|
|
8
|
+
left: z.number().nonnegative().default(0)
|
|
9
|
+
});
|
|
10
|
+
const MarkColor = z.enum(["black", "registration"]);
|
|
11
|
+
const Print = z.object({
|
|
12
|
+
paper: Paper,
|
|
13
|
+
orientation: Orientation.default("portrait"),
|
|
14
|
+
margin: Margin.optional(),
|
|
15
|
+
bleed: z.number().nonnegative().default(0),
|
|
16
|
+
safe: z.number().nonnegative().default(0),
|
|
17
|
+
marks: z.boolean().default(false),
|
|
18
|
+
markColor: MarkColor.default("black")
|
|
19
|
+
}).superRefine((print, ctx) => {
|
|
20
|
+
if (print.markColor === "registration" && !print.marks) ctx.addIssue({
|
|
21
|
+
code: "custom",
|
|
22
|
+
path: ["markColor"],
|
|
23
|
+
message: "markColor requires marks to be true"
|
|
24
|
+
});
|
|
25
|
+
const trim = sheetMm(print);
|
|
26
|
+
if (print.safe * 2 >= trim.width) ctx.addIssue({
|
|
27
|
+
code: "custom",
|
|
28
|
+
path: ["safe"],
|
|
29
|
+
message: `safe is ${print.safe}mm on the left and right, but the trim is ${trim.width}mm wide; safe must leave area inside the trim`
|
|
30
|
+
});
|
|
31
|
+
if (print.safe * 2 >= trim.height) ctx.addIssue({
|
|
32
|
+
code: "custom",
|
|
33
|
+
path: ["safe"],
|
|
34
|
+
message: `safe is ${print.safe}mm on the top and bottom, but the trim is ${trim.height}mm high; safe must leave area inside the trim`
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Margin, MarkColor, Print };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Print } from "./print.js";
|
|
2
|
+
import { Imposition } from "./imposition-schema.js";
|
|
2
3
|
//#region src/printed-page-imposition.d.ts
|
|
3
4
|
/** True when an imposition leaves one printed page unchanged on one paper. */
|
|
4
5
|
export declare function isPrintedPageIdentityImposition(print: Print, imposition: Imposition): boolean;
|
package/dist/printed-pages.d.ts
CHANGED
|
@@ -91,6 +91,12 @@ export declare const BOOK_PARENT_NAMES: {
|
|
|
91
91
|
readonly opener: "segnavia:opener";
|
|
92
92
|
readonly blank: "segnavia:blank";
|
|
93
93
|
};
|
|
94
|
+
export interface FlowingParentNames {
|
|
95
|
+
opener: string;
|
|
96
|
+
recto: string;
|
|
97
|
+
verso: string;
|
|
98
|
+
}
|
|
99
|
+
export declare function flowingParentNames(parents?: Partial<FlowingParentNames>): FlowingParentNames;
|
|
94
100
|
export declare function bookParentPages(margin: ParentPageMargin): ParentPage[];
|
|
95
101
|
export interface ResolvedParentPage {
|
|
96
102
|
name: string;
|
|
@@ -98,6 +104,14 @@ export interface ResolvedParentPage {
|
|
|
98
104
|
head: string;
|
|
99
105
|
foot: string;
|
|
100
106
|
}
|
|
107
|
+
export interface TextArea {
|
|
108
|
+
width: number;
|
|
109
|
+
height: number;
|
|
110
|
+
}
|
|
111
|
+
export declare function textArea(parent: Pick<ResolvedParentPage, 'margin'>, paper: {
|
|
112
|
+
width: number;
|
|
113
|
+
height: number;
|
|
114
|
+
}): TextArea;
|
|
101
115
|
export declare function resolveParentPages(parents: ParentPage[]): ResolvedParentPage[];
|
|
102
116
|
export declare function parentListIssues(parents: ParentPage[], options?: {
|
|
103
117
|
path?: (string | number)[];
|
package/dist/printed-pages.js
CHANGED
|
@@ -54,6 +54,13 @@ const BOOK_PARENT_NAMES = {
|
|
|
54
54
|
opener: "segnavia:opener",
|
|
55
55
|
blank: "segnavia:blank"
|
|
56
56
|
};
|
|
57
|
+
function flowingParentNames(parents) {
|
|
58
|
+
return {
|
|
59
|
+
opener: parents?.opener ?? "segnavia:opener",
|
|
60
|
+
recto: parents?.recto ?? "segnavia:recto",
|
|
61
|
+
verso: parents?.verso ?? "segnavia:verso"
|
|
62
|
+
};
|
|
63
|
+
}
|
|
57
64
|
function furniture(region) {
|
|
58
65
|
return BOOK_FURNITURE.filter((item) => item.region === region).filter((item) => item.fields.every((field) => !("required" in field) || !field.required)).map((item) => `<div class="${item.className}" data-motif="${item.key}"></div>`).join("");
|
|
59
66
|
}
|
|
@@ -85,6 +92,12 @@ function bookParentPages(margin) {
|
|
|
85
92
|
}
|
|
86
93
|
];
|
|
87
94
|
}
|
|
95
|
+
function textArea(parent, paper) {
|
|
96
|
+
return {
|
|
97
|
+
width: paper.width - parent.margin.inner - parent.margin.outer,
|
|
98
|
+
height: paper.height - parent.margin.top - parent.margin.bottom
|
|
99
|
+
};
|
|
100
|
+
}
|
|
88
101
|
const ZERO_PARENT_MARGIN = {
|
|
89
102
|
top: 0,
|
|
90
103
|
bottom: 0,
|
|
@@ -193,4 +206,4 @@ function pagePrintedPagesIssues(page) {
|
|
|
193
206
|
return issues;
|
|
194
207
|
}
|
|
195
208
|
//#endregion
|
|
196
|
-
export { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages };
|
|
209
|
+
export { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, flowingParentNames, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages, textArea };
|
package/dist/shots-used.d.ts
CHANGED
package/dist/shots-used.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/shots-used.ts
|
|
2
2
|
function shotsUsed(deck) {
|
|
3
3
|
return deck.slides.flatMap((slide) => {
|
|
4
|
-
if (slide.content.kind === "shot") return [{
|
|
4
|
+
if ("kind" in slide.content && slide.content.kind === "shot") return [{
|
|
5
5
|
slide: slide.id,
|
|
6
6
|
key: slide.content.shot.key
|
|
7
7
|
}];
|
|
8
|
-
if (slide.content.kind === "shot-ref") return [{
|
|
8
|
+
if ("kind" in slide.content && slide.content.kind === "shot-ref") return [{
|
|
9
9
|
slide: slide.id,
|
|
10
10
|
href: slide.content.href
|
|
11
11
|
}];
|