@segnavia/format 0.27.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.
@@ -0,0 +1,274 @@
1
+ import "./printed-pages.js";
2
+ import { z } from "zod";
3
+ //#region src/book-section.d.ts
4
+ export declare const BookOpens: z.ZodEnum<{
5
+ any: "any";
6
+ recto: "recto";
7
+ verso: "verso";
8
+ }>;
9
+ export type BookOpens = z.infer<typeof BookOpens>;
10
+ export declare const BookSectionParents: z.ZodObject<{
11
+ opener: z.ZodOptional<z.ZodString>;
12
+ recto: z.ZodOptional<z.ZodString>;
13
+ verso: z.ZodOptional<z.ZodString>;
14
+ blank: z.ZodOptional<z.ZodString>;
15
+ fixed: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>;
17
+ export type BookSectionParents = z.infer<typeof BookSectionParents>;
18
+ export declare const DesignedPage: z.ZodObject<{
19
+ html: z.ZodString;
20
+ }, z.core.$strip>;
21
+ export type DesignedPage = z.infer<typeof DesignedPage>;
22
+ export declare const REGION_NAME: RegExp;
23
+ export declare const TemplatedPage: z.ZodObject<{
24
+ template: z.ZodOptional<z.ZodString>;
25
+ regions: z.ZodRecord<z.ZodString, z.ZodString>;
26
+ }, z.core.$strip>;
27
+ export type TemplatedPage = z.infer<typeof TemplatedPage>;
28
+ export declare const BookTemplate: z.ZodObject<{
29
+ name: z.ZodString;
30
+ html: z.ZodString;
31
+ parents: z.ZodOptional<z.ZodObject<{
32
+ opener: z.ZodOptional<z.ZodString>;
33
+ recto: z.ZodOptional<z.ZodString>;
34
+ verso: z.ZodOptional<z.ZodString>;
35
+ blank: z.ZodOptional<z.ZodString>;
36
+ fixed: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>>;
38
+ }, z.core.$strip>;
39
+ export type BookTemplate = z.infer<typeof BookTemplate>;
40
+ export declare const DesignedSection: z.ZodObject<{
41
+ pages: z.ZodArray<z.ZodObject<{
42
+ html: z.ZodString;
43
+ }, z.core.$strip>>;
44
+ title: z.ZodOptional<z.ZodString>;
45
+ contents: z.ZodDefault<z.ZodBoolean>;
46
+ opens: z.ZodOptional<z.ZodEnum<{
47
+ any: "any";
48
+ recto: "recto";
49
+ verso: "verso";
50
+ }>>;
51
+ parents: z.ZodOptional<z.ZodObject<{
52
+ opener: z.ZodOptional<z.ZodString>;
53
+ recto: z.ZodOptional<z.ZodString>;
54
+ verso: z.ZodOptional<z.ZodString>;
55
+ blank: z.ZodOptional<z.ZodString>;
56
+ fixed: z.ZodOptional<z.ZodString>;
57
+ }, z.core.$strip>>;
58
+ kind: z.ZodLiteral<"designed">;
59
+ }, z.core.$strip>;
60
+ export type DesignedSection = z.infer<typeof DesignedSection>;
61
+ export declare const TemplatedSection: z.ZodObject<{
62
+ template: z.ZodString;
63
+ pages: z.ZodArray<z.ZodObject<{
64
+ template: z.ZodOptional<z.ZodString>;
65
+ regions: z.ZodRecord<z.ZodString, z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ title: z.ZodOptional<z.ZodString>;
68
+ contents: z.ZodDefault<z.ZodBoolean>;
69
+ opens: z.ZodOptional<z.ZodEnum<{
70
+ any: "any";
71
+ recto: "recto";
72
+ verso: "verso";
73
+ }>>;
74
+ parents: z.ZodOptional<z.ZodObject<{
75
+ opener: z.ZodOptional<z.ZodString>;
76
+ recto: z.ZodOptional<z.ZodString>;
77
+ verso: z.ZodOptional<z.ZodString>;
78
+ blank: z.ZodOptional<z.ZodString>;
79
+ fixed: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$strip>>;
81
+ kind: z.ZodLiteral<"templated">;
82
+ }, z.core.$strip>;
83
+ export type TemplatedSection = z.infer<typeof TemplatedSection>;
84
+ export declare const BookSection: z.ZodObject<{
85
+ title: z.ZodOptional<z.ZodString>;
86
+ contents: z.ZodDefault<z.ZodBoolean>;
87
+ opens: z.ZodOptional<z.ZodEnum<{
88
+ any: "any";
89
+ recto: "recto";
90
+ verso: "verso";
91
+ }>>;
92
+ parents: z.ZodOptional<z.ZodObject<{
93
+ opener: z.ZodOptional<z.ZodString>;
94
+ recto: z.ZodOptional<z.ZodString>;
95
+ verso: z.ZodOptional<z.ZodString>;
96
+ blank: z.ZodOptional<z.ZodString>;
97
+ fixed: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$strip>>;
99
+ html: z.ZodString;
100
+ }, z.core.$strip>;
101
+ export type BookSection = z.infer<typeof BookSection>;
102
+ export declare const BookContents: z.ZodObject<{
103
+ kind: z.ZodLiteral<"contents">;
104
+ title: z.ZodOptional<z.ZodString>;
105
+ opens: z.ZodOptional<z.ZodEnum<{
106
+ any: "any";
107
+ recto: "recto";
108
+ verso: "verso";
109
+ }>>;
110
+ parents: z.ZodOptional<z.ZodObject<{
111
+ opener: z.ZodOptional<z.ZodString>;
112
+ recto: z.ZodOptional<z.ZodString>;
113
+ verso: z.ZodOptional<z.ZodString>;
114
+ blank: z.ZodOptional<z.ZodString>;
115
+ fixed: z.ZodOptional<z.ZodString>;
116
+ }, z.core.$strip>>;
117
+ }, z.core.$strip>;
118
+ export type BookContents = z.infer<typeof BookContents>;
119
+ export declare const BookFrontMatterEntry: z.ZodDiscriminatedUnion<[z.ZodObject<{
120
+ pages: z.ZodArray<z.ZodObject<{
121
+ html: z.ZodString;
122
+ }, z.core.$strip>>;
123
+ title: z.ZodOptional<z.ZodString>;
124
+ contents: z.ZodDefault<z.ZodBoolean>;
125
+ opens: z.ZodOptional<z.ZodEnum<{
126
+ any: "any";
127
+ recto: "recto";
128
+ verso: "verso";
129
+ }>>;
130
+ parents: z.ZodOptional<z.ZodObject<{
131
+ opener: z.ZodOptional<z.ZodString>;
132
+ recto: z.ZodOptional<z.ZodString>;
133
+ verso: z.ZodOptional<z.ZodString>;
134
+ blank: z.ZodOptional<z.ZodString>;
135
+ fixed: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$strip>>;
137
+ kind: z.ZodLiteral<"designed">;
138
+ }, z.core.$strip>, z.ZodObject<{
139
+ template: z.ZodString;
140
+ pages: z.ZodArray<z.ZodObject<{
141
+ template: z.ZodOptional<z.ZodString>;
142
+ regions: z.ZodRecord<z.ZodString, z.ZodString>;
143
+ }, z.core.$strip>>;
144
+ title: z.ZodOptional<z.ZodString>;
145
+ contents: z.ZodDefault<z.ZodBoolean>;
146
+ opens: z.ZodOptional<z.ZodEnum<{
147
+ any: "any";
148
+ recto: "recto";
149
+ verso: "verso";
150
+ }>>;
151
+ parents: z.ZodOptional<z.ZodObject<{
152
+ opener: z.ZodOptional<z.ZodString>;
153
+ recto: z.ZodOptional<z.ZodString>;
154
+ verso: z.ZodOptional<z.ZodString>;
155
+ blank: z.ZodOptional<z.ZodString>;
156
+ fixed: z.ZodOptional<z.ZodString>;
157
+ }, z.core.$strip>>;
158
+ kind: z.ZodLiteral<"templated">;
159
+ }, z.core.$strip>, z.ZodObject<{
160
+ kind: z.ZodLiteral<"contents">;
161
+ title: z.ZodOptional<z.ZodString>;
162
+ opens: z.ZodOptional<z.ZodEnum<{
163
+ any: "any";
164
+ recto: "recto";
165
+ verso: "verso";
166
+ }>>;
167
+ parents: z.ZodOptional<z.ZodObject<{
168
+ opener: z.ZodOptional<z.ZodString>;
169
+ recto: z.ZodOptional<z.ZodString>;
170
+ verso: z.ZodOptional<z.ZodString>;
171
+ blank: z.ZodOptional<z.ZodString>;
172
+ fixed: z.ZodOptional<z.ZodString>;
173
+ }, z.core.$strip>>;
174
+ }, z.core.$strip>, z.ZodObject<{
175
+ title: z.ZodOptional<z.ZodString>;
176
+ contents: z.ZodDefault<z.ZodBoolean>;
177
+ opens: z.ZodOptional<z.ZodEnum<{
178
+ any: "any";
179
+ recto: "recto";
180
+ verso: "verso";
181
+ }>>;
182
+ parents: z.ZodOptional<z.ZodObject<{
183
+ opener: z.ZodOptional<z.ZodString>;
184
+ recto: z.ZodOptional<z.ZodString>;
185
+ verso: z.ZodOptional<z.ZodString>;
186
+ blank: z.ZodOptional<z.ZodString>;
187
+ fixed: z.ZodOptional<z.ZodString>;
188
+ }, z.core.$strip>>;
189
+ html: z.ZodString;
190
+ kind: z.ZodOptional<z.ZodLiteral<"front">>;
191
+ }, z.core.$strip>], "kind">;
192
+ export type BookFrontMatterEntry = z.infer<typeof BookFrontMatterEntry>;
193
+ export declare const Chapter: z.ZodObject<{
194
+ title: z.ZodString;
195
+ html: z.ZodString;
196
+ runningHead: z.ZodOptional<z.ZodString>;
197
+ opens: z.ZodOptional<z.ZodEnum<{
198
+ any: "any";
199
+ recto: "recto";
200
+ verso: "verso";
201
+ }>>;
202
+ parents: z.ZodOptional<z.ZodObject<{
203
+ opener: z.ZodOptional<z.ZodString>;
204
+ recto: z.ZodOptional<z.ZodString>;
205
+ verso: z.ZodOptional<z.ZodString>;
206
+ blank: z.ZodOptional<z.ZodString>;
207
+ fixed: z.ZodOptional<z.ZodString>;
208
+ }, z.core.$strip>>;
209
+ }, z.core.$strip>;
210
+ export type Chapter = z.infer<typeof Chapter>;
211
+ export declare const BookChapterEntry: z.ZodDiscriminatedUnion<[z.ZodObject<{
212
+ pages: z.ZodArray<z.ZodObject<{
213
+ html: z.ZodString;
214
+ }, z.core.$strip>>;
215
+ title: z.ZodOptional<z.ZodString>;
216
+ contents: z.ZodDefault<z.ZodBoolean>;
217
+ opens: z.ZodOptional<z.ZodEnum<{
218
+ any: "any";
219
+ recto: "recto";
220
+ verso: "verso";
221
+ }>>;
222
+ parents: z.ZodOptional<z.ZodObject<{
223
+ opener: z.ZodOptional<z.ZodString>;
224
+ recto: z.ZodOptional<z.ZodString>;
225
+ verso: z.ZodOptional<z.ZodString>;
226
+ blank: z.ZodOptional<z.ZodString>;
227
+ fixed: z.ZodOptional<z.ZodString>;
228
+ }, z.core.$strip>>;
229
+ kind: z.ZodLiteral<"designed">;
230
+ }, z.core.$strip>, z.ZodObject<{
231
+ template: z.ZodString;
232
+ pages: z.ZodArray<z.ZodObject<{
233
+ template: z.ZodOptional<z.ZodString>;
234
+ regions: z.ZodRecord<z.ZodString, z.ZodString>;
235
+ }, z.core.$strip>>;
236
+ title: z.ZodOptional<z.ZodString>;
237
+ contents: z.ZodDefault<z.ZodBoolean>;
238
+ opens: z.ZodOptional<z.ZodEnum<{
239
+ any: "any";
240
+ recto: "recto";
241
+ verso: "verso";
242
+ }>>;
243
+ parents: z.ZodOptional<z.ZodObject<{
244
+ opener: z.ZodOptional<z.ZodString>;
245
+ recto: z.ZodOptional<z.ZodString>;
246
+ verso: z.ZodOptional<z.ZodString>;
247
+ blank: z.ZodOptional<z.ZodString>;
248
+ fixed: z.ZodOptional<z.ZodString>;
249
+ }, z.core.$strip>>;
250
+ kind: z.ZodLiteral<"templated">;
251
+ }, z.core.$strip>, z.ZodObject<{
252
+ title: z.ZodString;
253
+ html: z.ZodString;
254
+ runningHead: z.ZodOptional<z.ZodString>;
255
+ opens: z.ZodOptional<z.ZodEnum<{
256
+ any: "any";
257
+ recto: "recto";
258
+ verso: "verso";
259
+ }>>;
260
+ parents: z.ZodOptional<z.ZodObject<{
261
+ opener: z.ZodOptional<z.ZodString>;
262
+ recto: z.ZodOptional<z.ZodString>;
263
+ verso: z.ZodOptional<z.ZodString>;
264
+ blank: z.ZodOptional<z.ZodString>;
265
+ fixed: z.ZodOptional<z.ZodString>;
266
+ }, z.core.$strip>>;
267
+ kind: z.ZodOptional<z.ZodLiteral<"chapter">>;
268
+ }, z.core.$strip>], "kind">;
269
+ export type BookChapterEntry = z.infer<typeof BookChapterEntry>;
270
+ export declare function isBookContents(entry: BookFrontMatterEntry): entry is BookContents;
271
+ export declare function isDesignedSection(entry: BookFrontMatterEntry | BookChapterEntry): entry is DesignedSection;
272
+ export declare function isTemplatedSection(entry: BookFrontMatterEntry | BookChapterEntry): entry is TemplatedSection;
273
+ export declare function isChapter(entry: BookChapterEntry): entry is Chapter;
274
+ //#endregion
@@ -0,0 +1,208 @@
1
+ import { BOOK_PARENT_NAMES, parentListIssues } from "./printed-pages.js";
2
+ import { z } from "zod";
3
+ //#region src/book-section.ts
4
+ const BookOpens = z.enum([
5
+ "recto",
6
+ "verso",
7
+ "any"
8
+ ]);
9
+ const BookSectionParents = z.object({
10
+ opener: z.string().min(1).optional(),
11
+ recto: z.string().min(1).optional(),
12
+ verso: z.string().min(1).optional(),
13
+ blank: z.string().min(1).optional(),
14
+ fixed: z.string().min(1).optional()
15
+ });
16
+ const DesignedPage = z.object({ html: z.string() });
17
+ const REGION_NAME = /^[A-Za-z][\w-]*$/;
18
+ const TemplatedPage = z.object({
19
+ template: z.string().min(1).optional(),
20
+ regions: z.record(z.string(), z.string())
21
+ });
22
+ const BookTemplate = z.object({
23
+ name: z.string().min(1),
24
+ html: z.string(),
25
+ parents: BookSectionParents.optional()
26
+ });
27
+ const designedPagesRefusal = "a designed section needs at least one page; add a page or remove the section to clear this refusal";
28
+ const templatedPagesRefusal = "a templated section needs at least one page; add a page or remove the section to clear this refusal";
29
+ const regionNameClear = "use a letter followed by letters, digits, hyphens or underscores to clear this refusal";
30
+ const sectionFields = {
31
+ title: z.string().optional(),
32
+ contents: z.boolean().default(true),
33
+ opens: BookOpens.optional(),
34
+ parents: BookSectionParents.optional()
35
+ };
36
+ const DesignedSection = z.object({
37
+ kind: z.literal("designed"),
38
+ ...sectionFields,
39
+ pages: z.array(DesignedPage, { error: designedPagesRefusal }).min(1, designedPagesRefusal)
40
+ });
41
+ const TemplatedSection = z.object({
42
+ kind: z.literal("templated"),
43
+ ...sectionFields,
44
+ template: z.string().min(1),
45
+ pages: z.array(TemplatedPage, { error: templatedPagesRefusal }).min(1, templatedPagesRefusal)
46
+ });
47
+ const BookSection = z.object({
48
+ html: z.string(),
49
+ ...sectionFields
50
+ });
51
+ const BookContents = z.object({
52
+ kind: z.literal("contents"),
53
+ title: z.string().optional(),
54
+ opens: BookOpens.optional(),
55
+ parents: BookSectionParents.optional()
56
+ });
57
+ const flowingFront = BookSection.extend({ kind: z.literal("front").optional() });
58
+ const BookFrontMatterEntry = z.discriminatedUnion("kind", [
59
+ DesignedSection,
60
+ TemplatedSection,
61
+ BookContents,
62
+ flowingFront
63
+ ]);
64
+ const Chapter = z.object({
65
+ title: z.string(),
66
+ html: z.string(),
67
+ runningHead: z.string().optional(),
68
+ opens: BookOpens.optional(),
69
+ parents: BookSectionParents.optional()
70
+ });
71
+ const flowingChapter = Chapter.extend({ kind: z.literal("chapter").optional() });
72
+ const BookChapterEntry = z.discriminatedUnion("kind", [
73
+ DesignedSection,
74
+ TemplatedSection,
75
+ flowingChapter
76
+ ]);
77
+ function isBookContents(entry) {
78
+ return "kind" in entry && entry.kind === "contents";
79
+ }
80
+ function isDesignedSection(entry) {
81
+ return "kind" in entry && entry.kind === "designed";
82
+ }
83
+ function isTemplatedSection(entry) {
84
+ return "kind" in entry && entry.kind === "templated";
85
+ }
86
+ function isChapter(entry) {
87
+ return !isDesignedSection(entry) && !isTemplatedSection(entry);
88
+ }
89
+ function namedSections(book) {
90
+ const front = book.frontMatter.map((entry, index) => {
91
+ const path = ["frontMatter", index];
92
+ return {
93
+ label: entry.title ?? `frontMatter[${index}]`,
94
+ path,
95
+ parents: entry.parents,
96
+ templated: isTemplatedSection(entry) ? entry : void 0
97
+ };
98
+ });
99
+ const chapters = book.chapters.map((entry, index) => {
100
+ const path = ["chapters", index];
101
+ if (isDesignedSection(entry) || isTemplatedSection(entry)) return {
102
+ label: entry.title ?? `chapters[${index}]`,
103
+ path,
104
+ parents: entry.parents,
105
+ templated: isTemplatedSection(entry) ? entry : void 0
106
+ };
107
+ return {
108
+ label: entry.title,
109
+ path,
110
+ parents: entry.parents
111
+ };
112
+ });
113
+ return [...front, ...chapters];
114
+ }
115
+ function hasKind(book, match) {
116
+ return book.frontMatter.some(match) || book.chapters.some(match);
117
+ }
118
+ function unknownParent(label, role, name, path) {
119
+ return {
120
+ path: [
121
+ ...path,
122
+ "parents",
123
+ role
124
+ ],
125
+ message: `${label} names unknown parent page "${name}"; add that parent page or name an existing one to clear this refusal`
126
+ };
127
+ }
128
+ function parentNameIssues(label, path, parents, known) {
129
+ if (!parents) return [];
130
+ return Object.entries(parents).flatMap(([role, name]) => name && !known.has(name) ? [unknownParent(label, role, name, path)] : []);
131
+ }
132
+ function templateListIssues(templates, knownParents) {
133
+ const issues = [];
134
+ const seen = /* @__PURE__ */ new Set();
135
+ templates.forEach((template, index) => {
136
+ const path = ["templates", index];
137
+ if (!REGION_NAME.test(template.name)) issues.push({
138
+ path: [...path, "name"],
139
+ message: `template "${template.name}" is not an HTML name token; ${regionNameClear}`
140
+ });
141
+ if (seen.has(template.name)) issues.push({
142
+ path: [...path, "name"],
143
+ message: `template "${template.name}" is duplicated; give every template a unique name to clear this refusal`
144
+ });
145
+ seen.add(template.name);
146
+ issues.push(...parentNameIssues(`template ${template.name}`, path, template.parents, knownParents));
147
+ });
148
+ return issues;
149
+ }
150
+ function templatedPageIssues(section, knownTemplates) {
151
+ const entry = section.templated;
152
+ if (!entry) return [];
153
+ const issues = [];
154
+ if (!knownTemplates.has(entry.template)) issues.push({
155
+ path: [...section.path, "template"],
156
+ message: `section ${section.label} names unknown template "${entry.template}"; add that template or name an existing one to clear this refusal`
157
+ });
158
+ entry.pages.forEach((page, index) => {
159
+ if (page.template !== void 0 && !knownTemplates.has(page.template)) issues.push({
160
+ path: [
161
+ ...section.path,
162
+ "pages",
163
+ index,
164
+ "template"
165
+ ],
166
+ message: `section ${section.label} page ${index + 1} names unknown template "${page.template}"; add that template or name an existing one to clear this refusal`
167
+ });
168
+ for (const key of Object.keys(page.regions)) {
169
+ if (REGION_NAME.test(key)) continue;
170
+ issues.push({
171
+ path: [
172
+ ...section.path,
173
+ "pages",
174
+ index,
175
+ "regions",
176
+ key
177
+ ],
178
+ message: `section ${section.label} page ${index + 1} region "${key}" is not an HTML name token; ${regionNameClear}`
179
+ });
180
+ }
181
+ });
182
+ return issues;
183
+ }
184
+ function bookParentIssues(book) {
185
+ const issues = [];
186
+ if (book.mode === "continuous" && hasKind(book, isDesignedSection)) issues.push({
187
+ path: ["mode"],
188
+ message: "designed sections print in paginated mode; set mode: 'paginated' to clear this refusal"
189
+ });
190
+ if (book.mode === "continuous" && hasKind(book, isTemplatedSection)) issues.push({
191
+ path: ["mode"],
192
+ message: "templated sections print in paginated mode; set mode: 'paginated' to clear this refusal"
193
+ });
194
+ issues.push(...parentListIssues(book.parentPages, {
195
+ path: ["parentPages"],
196
+ known: Object.values(BOOK_PARENT_NAMES)
197
+ }));
198
+ const knownParents = /* @__PURE__ */ new Set([...Object.values(BOOK_PARENT_NAMES), ...book.parentPages.map((parent) => parent.name)]);
199
+ issues.push(...templateListIssues(book.templates, knownParents));
200
+ const knownTemplates = new Set(book.templates.map((template) => template.name));
201
+ for (const section of namedSections(book)) {
202
+ issues.push(...parentNameIssues(`section ${section.label}`, section.path, section.parents, knownParents));
203
+ issues.push(...templatedPageIssues(section, knownTemplates));
204
+ }
205
+ return issues;
206
+ }
207
+ //#endregion
208
+ export { BookChapterEntry, BookContents, BookFrontMatterEntry, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, REGION_NAME, TemplatedPage, TemplatedSection, bookParentIssues, isBookContents, isChapter, isDesignedSection, isTemplatedSection };