@segnavia/format 0.26.0 → 0.28.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/book-section.d.ts +274 -0
- package/dist/book-section.js +208 -0
- package/dist/book.d.ts +675 -38
- package/dist/book.js +78 -29
- package/dist/direction.d.ts +1 -0
- package/dist/direction.js +33 -30
- package/dist/fonts.d.ts +77 -0
- package/dist/fonts.js +49 -0
- package/dist/index.d.ts +483 -9
- package/dist/index.js +24 -6
- package/dist/motif.d.ts +157 -0
- package/dist/motif.js +193 -0
- package/dist/numbering.d.ts +2 -0
- package/dist/numbering.js +8 -1
- package/dist/printed-page-imposition.d.ts +5 -0
- package/dist/printed-page-imposition.js +12 -0
- package/dist/printed-pages.d.ts +125 -0
- package/dist/printed-pages.js +196 -0
- package/package.json +1 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { BOOK_FURNITURE } from "./motif.js";
|
|
2
|
+
import { NumberSystem } from "./numbering.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/printed-pages.ts
|
|
5
|
+
const PRINTED_PAGE_LIMIT = 500;
|
|
6
|
+
const PRINTED_PAGE_ROLES = [
|
|
7
|
+
"every",
|
|
8
|
+
"first",
|
|
9
|
+
"recto",
|
|
10
|
+
"verso",
|
|
11
|
+
"last"
|
|
12
|
+
];
|
|
13
|
+
const ParentPageMargin = z.object({
|
|
14
|
+
top: z.number().nonnegative(),
|
|
15
|
+
bottom: z.number().nonnegative(),
|
|
16
|
+
inner: z.number().nonnegative(),
|
|
17
|
+
outer: z.number().nonnegative()
|
|
18
|
+
});
|
|
19
|
+
const ParentPage = z.object({
|
|
20
|
+
name: z.string().min(1),
|
|
21
|
+
basedOn: z.string().min(1).optional(),
|
|
22
|
+
margin: ParentPageMargin.optional(),
|
|
23
|
+
head: z.string().optional(),
|
|
24
|
+
foot: z.string().optional()
|
|
25
|
+
});
|
|
26
|
+
const ParentName = z.string().min(1);
|
|
27
|
+
const PrintedPageRules = z.object({
|
|
28
|
+
every: z.string({ error: "every is required; name the default parent page to clear this refusal" }).min(1),
|
|
29
|
+
first: ParentName.optional(),
|
|
30
|
+
recto: ParentName.optional(),
|
|
31
|
+
verso: ParentName.optional(),
|
|
32
|
+
last: ParentName.optional()
|
|
33
|
+
}).passthrough().superRefine((rules, ctx) => {
|
|
34
|
+
const unknown = Object.keys(rules).filter((key) => !PRINTED_PAGE_ROLES.includes(key));
|
|
35
|
+
if (unknown.length) ctx.addIssue({
|
|
36
|
+
code: "custom",
|
|
37
|
+
message: `unknown printed-page role ${unknown.map((key) => JSON.stringify(key)).join(", ")}; use only every, first, recto, verso or last to clear this refusal`
|
|
38
|
+
});
|
|
39
|
+
}).transform(({ every, first, recto, verso, last }) => ({
|
|
40
|
+
every,
|
|
41
|
+
...first === void 0 ? {} : { first },
|
|
42
|
+
...recto === void 0 ? {} : { recto },
|
|
43
|
+
...verso === void 0 ? {} : { verso },
|
|
44
|
+
...last === void 0 ? {} : { last }
|
|
45
|
+
}));
|
|
46
|
+
const PrintedPages = z.object({
|
|
47
|
+
parents: z.array(ParentPage).min(1),
|
|
48
|
+
rules: PrintedPageRules,
|
|
49
|
+
numbering: NumberSystem.optional()
|
|
50
|
+
});
|
|
51
|
+
const BOOK_PARENT_NAMES = {
|
|
52
|
+
recto: "segnavia:recto",
|
|
53
|
+
verso: "segnavia:verso",
|
|
54
|
+
opener: "segnavia:opener",
|
|
55
|
+
blank: "segnavia:blank"
|
|
56
|
+
};
|
|
57
|
+
function furniture(region) {
|
|
58
|
+
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
|
+
}
|
|
60
|
+
function bookParentPages(margin) {
|
|
61
|
+
const held = () => ({ ...margin });
|
|
62
|
+
const head = furniture("head");
|
|
63
|
+
const foot = furniture("foot");
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
name: BOOK_PARENT_NAMES.recto,
|
|
67
|
+
margin: held(),
|
|
68
|
+
head,
|
|
69
|
+
foot
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: BOOK_PARENT_NAMES.verso,
|
|
73
|
+
margin: held(),
|
|
74
|
+
head,
|
|
75
|
+
foot
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: BOOK_PARENT_NAMES.opener,
|
|
79
|
+
margin: held(),
|
|
80
|
+
foot
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: BOOK_PARENT_NAMES.blank,
|
|
84
|
+
margin: held()
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
const ZERO_PARENT_MARGIN = {
|
|
89
|
+
top: 0,
|
|
90
|
+
bottom: 0,
|
|
91
|
+
inner: 0,
|
|
92
|
+
outer: 0
|
|
93
|
+
};
|
|
94
|
+
function resolveParentPages(parents) {
|
|
95
|
+
const source = new Map(parents.map((parent) => [parent.name, parent]));
|
|
96
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
97
|
+
const resolve = (parent) => {
|
|
98
|
+
const held = resolved.get(parent.name);
|
|
99
|
+
if (held) return held;
|
|
100
|
+
const baseParent = parent.basedOn ? source.get(parent.basedOn) : void 0;
|
|
101
|
+
const base = baseParent ? resolve(baseParent) : void 0;
|
|
102
|
+
const result = {
|
|
103
|
+
name: parent.name,
|
|
104
|
+
margin: parent.margin ?? base?.margin ?? ZERO_PARENT_MARGIN,
|
|
105
|
+
head: parent.head ?? base?.head ?? "",
|
|
106
|
+
foot: parent.foot ?? base?.foot ?? ""
|
|
107
|
+
};
|
|
108
|
+
resolved.set(parent.name, result);
|
|
109
|
+
return result;
|
|
110
|
+
};
|
|
111
|
+
return parents.map(resolve);
|
|
112
|
+
}
|
|
113
|
+
function parentListIssues(parents, options = {}) {
|
|
114
|
+
const issues = [];
|
|
115
|
+
const root = options.path ?? ["parents"];
|
|
116
|
+
const listed = /* @__PURE__ */ new Map();
|
|
117
|
+
const known = /* @__PURE__ */ new Set([...options.known ?? []]);
|
|
118
|
+
parents.forEach((parent, index) => {
|
|
119
|
+
if (listed.has(parent.name)) issues.push({
|
|
120
|
+
path: [
|
|
121
|
+
...root,
|
|
122
|
+
index,
|
|
123
|
+
"name"
|
|
124
|
+
],
|
|
125
|
+
message: `parent page "${parent.name}" is duplicated; give every parent page a unique name to clear this refusal`
|
|
126
|
+
});
|
|
127
|
+
listed.set(parent.name, parent);
|
|
128
|
+
known.add(parent.name);
|
|
129
|
+
});
|
|
130
|
+
parents.forEach((parent, index) => {
|
|
131
|
+
if (parent.basedOn && !known.has(parent.basedOn)) issues.push({
|
|
132
|
+
path: [
|
|
133
|
+
...root,
|
|
134
|
+
index,
|
|
135
|
+
"basedOn"
|
|
136
|
+
],
|
|
137
|
+
message: `parent page "${parent.name}" is based on unknown parent page "${parent.basedOn}"; add that parent page or remove basedOn to clear this refusal`
|
|
138
|
+
});
|
|
139
|
+
const chain = [];
|
|
140
|
+
let cursor = parent;
|
|
141
|
+
while (cursor) {
|
|
142
|
+
if (chain.includes(cursor.name)) {
|
|
143
|
+
issues.push({
|
|
144
|
+
path: [
|
|
145
|
+
...root,
|
|
146
|
+
index,
|
|
147
|
+
"basedOn"
|
|
148
|
+
],
|
|
149
|
+
message: `parent page inheritance has a cycle ${[...chain, cursor.name].join(" -> ")}; remove a basedOn link to clear this refusal`
|
|
150
|
+
});
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
chain.push(cursor.name);
|
|
154
|
+
cursor = cursor.basedOn ? listed.get(cursor.basedOn) : void 0;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return issues;
|
|
158
|
+
}
|
|
159
|
+
function printedPagesIssues(value) {
|
|
160
|
+
const issues = parentListIssues(value.parents);
|
|
161
|
+
const names = new Set(value.parents.map((parent) => parent.name));
|
|
162
|
+
for (const [role, name] of Object.entries(value.rules)) {
|
|
163
|
+
if (name === void 0) continue;
|
|
164
|
+
if (!names.has(name)) issues.push({
|
|
165
|
+
path: ["rules", role],
|
|
166
|
+
message: `${role} names unknown parent page "${name}"; add that parent page or name an existing one to clear this refusal`
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return issues;
|
|
170
|
+
}
|
|
171
|
+
function pagePrintedPagesIssues(page) {
|
|
172
|
+
if (!page.printedPages) return [];
|
|
173
|
+
const issues = printedPagesIssues(page.printedPages).map((issue) => ({
|
|
174
|
+
...issue,
|
|
175
|
+
path: ["printedPages", ...issue.path]
|
|
176
|
+
}));
|
|
177
|
+
if (!page.print) issues.push({
|
|
178
|
+
path: ["print"],
|
|
179
|
+
message: "printedPages could not establish a paper; add print.paper to clear this refusal"
|
|
180
|
+
});
|
|
181
|
+
if (page.scripts !== "refuse") issues.push({
|
|
182
|
+
path: ["scripts"],
|
|
183
|
+
message: "printedPages could not establish deterministic cloned content; set scripts to \"refuse\" to clear this refusal"
|
|
184
|
+
});
|
|
185
|
+
if (page.print?.margin) issues.push({
|
|
186
|
+
path: ["print", "margin"],
|
|
187
|
+
message: "printedPages and print.margin both own the margins; remove print.margin to clear this refusal"
|
|
188
|
+
});
|
|
189
|
+
if (page.print && (page.print.bleed > 0 || page.print.marks)) issues.push({
|
|
190
|
+
path: ["print"],
|
|
191
|
+
message: "printedPages could not establish one composed paper with bleed or marks; remove bleed and marks to clear this refusal"
|
|
192
|
+
});
|
|
193
|
+
return issues;
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
export { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages };
|