@segnavia/format 0.36.0 → 0.38.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,4 @@
1
+ import { BookChapterEntry, BookContents, BookDivision, BookDivisions, BookFrontMatterEntry, BookItem, BookOpens, BookSection, BookSectionEntry, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, MAX_PART_DEPTH, Part, REGION_NAME, TemplatedPage, TemplatedSection, bookSections, isBookContents, isChapter, isDesignedSection, isPart, isTemplatedSection } from "./book-section.js";
2
+ import { NoteNumbering, NotePlacement, NoteSeries, NoteSeriesInput, ResolvedNoteSeries, noteMarkerIssues, resolveNoteSeries } from "./note-series.js";
3
+ import { Book, BookInput, BookMode, BookPage, BookRunningHead, BookRunningHeadSource, BookView, BookViewInput, BookViewPagination, resolveBookPagination } from "./book.js";
4
+ export { Book, BookChapterEntry, BookContents, type BookDivision, type BookDivisions, BookFrontMatterEntry, type BookInput, BookItem, BookMode, BookOpens, BookPage, BookRunningHead, BookRunningHeadSource, BookSection, type BookSectionEntry, BookSectionParents, BookTemplate, BookView, type BookViewInput, BookViewPagination, Chapter, DesignedPage, DesignedSection, MAX_PART_DEPTH, NoteNumbering, NotePlacement, NoteSeries, type NoteSeriesInput, Part, REGION_NAME, type ResolvedNoteSeries, TemplatedPage, TemplatedSection, bookSections, isBookContents, isChapter, isDesignedSection, isPart, isTemplatedSection, noteMarkerIssues, resolveBookPagination, resolveNoteSeries };
@@ -20,6 +20,7 @@ export declare const DesignedPage: z.ZodObject<{
20
20
  }, z.core.$strip>;
21
21
  export type DesignedPage = z.infer<typeof DesignedPage>;
22
22
  export declare const REGION_NAME: RegExp;
23
+ export declare const MAX_PART_DEPTH = 6;
23
24
  export declare const TemplatedPage: z.ZodObject<{
24
25
  template: z.ZodOptional<z.ZodString>;
25
26
  regions: z.ZodRecord<z.ZodString, z.ZodString>;
@@ -37,6 +38,25 @@ export declare const BookTemplate: z.ZodObject<{
37
38
  }, z.core.$strip>>;
38
39
  }, z.core.$strip>;
39
40
  export type BookTemplate = z.infer<typeof BookTemplate>;
41
+ declare const partFields: {
42
+ name: z.ZodString;
43
+ title: z.ZodOptional<z.ZodString>;
44
+ html: 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
+ runningHead: z.ZodOptional<z.ZodString>;
59
+ };
40
60
  export declare const DesignedSection: z.ZodObject<{
41
61
  pages: z.ZodArray<z.ZodObject<{
42
62
  html: z.ZodString;
@@ -267,8 +287,39 @@ export declare const BookChapterEntry: z.ZodDiscriminatedUnion<[z.ZodObject<{
267
287
  kind: z.ZodOptional<z.ZodLiteral<"chapter">>;
268
288
  }, z.core.$strip>], "kind">;
269
289
  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;
290
+ export interface Part extends z.infer<z.ZodObject<typeof partFields>> {
291
+ children: BookItem[];
292
+ }
293
+ export type BookItem = Part | BookFrontMatterEntry | BookChapterEntry;
294
+ export declare const Part: z.ZodType<Part>;
295
+ export declare const BookItem: z.ZodType<BookItem>;
296
+ export type BookDivision = 'front' | 'body' | 'end';
297
+ interface BookSectionLocation {
298
+ ancestry: Array<{
299
+ name: string;
300
+ title?: string;
301
+ runningHead?: string;
302
+ id: string;
303
+ }>;
304
+ depth: number;
305
+ path: (string | number)[];
306
+ }
307
+ export type BookSectionEntry = BookSectionLocation & {
308
+ entry: BookItem;
309
+ division: BookDivision;
310
+ id?: string;
311
+ };
312
+ export declare function isPart(entry: BookItem): entry is Part;
313
+ export interface BookDivisions {
314
+ frontMatter: BookItem[];
315
+ body: BookItem[];
316
+ bodyKey?: 'body' | 'chapters';
317
+ endMatter: BookItem[];
318
+ }
319
+ /** The canonical reading order for every feature that consumes a book. */
320
+ export declare function bookSections(book: BookDivisions): BookSectionEntry[];
321
+ export declare function isBookContents(entry: BookItem): entry is BookContents;
322
+ export declare function isDesignedSection(entry: BookItem): entry is DesignedSection;
323
+ export declare function isTemplatedSection(entry: BookItem): entry is TemplatedSection;
273
324
  export declare function isChapter(entry: BookChapterEntry): entry is Chapter;
274
325
  //#endregion
@@ -15,6 +15,7 @@ const BookSectionParents = z.object({
15
15
  });
16
16
  const DesignedPage = z.object({ html: z.string() });
17
17
  const REGION_NAME = /^[A-Za-z][\w-]*$/;
18
+ const MAX_PART_DEPTH = 6;
18
19
  const TemplatedPage = z.object({
19
20
  template: z.string().min(1).optional(),
20
21
  regions: z.record(z.string(), z.string())
@@ -33,6 +34,15 @@ const sectionFields = {
33
34
  opens: BookOpens.optional(),
34
35
  parents: BookSectionParents.optional()
35
36
  };
37
+ const partFields = {
38
+ name: z.string().regex(REGION_NAME, "a part name must be an HTML name token"),
39
+ title: z.string().optional(),
40
+ html: z.string().optional(),
41
+ contents: z.boolean().default(true),
42
+ opens: BookOpens.optional(),
43
+ parents: BookSectionParents.optional(),
44
+ runningHead: z.string().optional()
45
+ };
36
46
  const DesignedSection = z.object({
37
47
  kind: z.literal("designed"),
38
48
  ...sectionFields,
@@ -74,6 +84,58 @@ const BookChapterEntry = z.discriminatedUnion("kind", [
74
84
  TemplatedSection,
75
85
  flowingChapter
76
86
  ]);
87
+ const Part = z.lazy(() => z.object({
88
+ ...partFields,
89
+ children: z.array(BookItem).default([])
90
+ }));
91
+ const BookItem = z.lazy(() => z.union([
92
+ Part,
93
+ BookFrontMatterEntry,
94
+ BookChapterEntry
95
+ ]));
96
+ function isPart(entry) {
97
+ return "name" in entry;
98
+ }
99
+ /** The canonical reading order for every feature that consumes a book. */
100
+ function bookSections(book) {
101
+ const sections = [];
102
+ let partNumber = 0;
103
+ const walk = (items, division, parentPath, ancestry) => {
104
+ items.forEach((entry, index) => {
105
+ const path = [...parentPath, index];
106
+ if (!isPart(entry)) {
107
+ sections.push({
108
+ entry,
109
+ division,
110
+ ancestry,
111
+ depth: ancestry.length,
112
+ path
113
+ });
114
+ return;
115
+ }
116
+ partNumber += 1;
117
+ const id = `segnavia-part-${partNumber}`;
118
+ if (entry.html !== void 0 || entry.title !== void 0) sections.push({
119
+ entry,
120
+ division,
121
+ ancestry,
122
+ depth: ancestry.length,
123
+ path,
124
+ id
125
+ });
126
+ walk(entry.children, division, [...path, "children"], [...ancestry, {
127
+ name: entry.name,
128
+ title: entry.title,
129
+ runningHead: entry.runningHead,
130
+ id
131
+ }]);
132
+ });
133
+ };
134
+ walk(book.frontMatter, "front", ["frontMatter"], []);
135
+ walk(book.body, "body", [book.bodyKey ?? "body"], []);
136
+ walk(book.endMatter, "end", ["endMatter"], []);
137
+ return sections;
138
+ }
77
139
  function isBookContents(entry) {
78
140
  return "kind" in entry && entry.kind === "contents";
79
141
  }
@@ -86,34 +148,26 @@ function isTemplatedSection(entry) {
86
148
  function isChapter(entry) {
87
149
  return !isDesignedSection(entry) && !isTemplatedSection(entry);
88
150
  }
151
+ function pathLabel(path) {
152
+ return path.join(".");
153
+ }
89
154
  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];
155
+ return bookSections(book).map(({ entry, path }) => {
101
156
  if (isDesignedSection(entry) || isTemplatedSection(entry)) return {
102
- label: entry.title ?? `chapters[${index}]`,
157
+ label: entry.title ?? pathLabel(path),
103
158
  path,
104
159
  parents: entry.parents,
105
160
  templated: isTemplatedSection(entry) ? entry : void 0
106
161
  };
107
162
  return {
108
- label: entry.title,
163
+ label: entry.title ?? pathLabel(path),
109
164
  path,
110
165
  parents: entry.parents
111
166
  };
112
167
  });
113
- return [...front, ...chapters];
114
168
  }
115
169
  function hasKind(book, match) {
116
- return book.frontMatter.some(match) || book.chapters.some(match);
170
+ return bookSections(book).some(({ entry }) => match(entry));
117
171
  }
118
172
  function unknownParent(label, role, name, path) {
119
173
  return {
@@ -205,4 +259,4 @@ function bookParentIssues(book) {
205
259
  return issues;
206
260
  }
207
261
  //#endregion
208
- export { BookChapterEntry, BookContents, BookFrontMatterEntry, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, REGION_NAME, TemplatedPage, TemplatedSection, bookParentIssues, isBookContents, isChapter, isDesignedSection, isTemplatedSection };
262
+ export { BookChapterEntry, BookContents, BookFrontMatterEntry, BookItem, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, MAX_PART_DEPTH, Part, REGION_NAME, TemplatedPage, TemplatedSection, bookParentIssues, bookSections, isBookContents, isChapter, isDesignedSection, isPart, isTemplatedSection };