@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
package/dist/book.js
CHANGED
|
@@ -1,28 +1,14 @@
|
|
|
1
|
-
import { Direction } from "./direction.js";
|
|
1
|
+
import { Direction, resolveDirection } from "./direction.js";
|
|
2
2
|
import { Scripts } from "./scripts.js";
|
|
3
|
-
import {
|
|
3
|
+
import { Slots } from "./slots.js";
|
|
4
|
+
import { FontReference } from "./fonts.js";
|
|
5
|
+
import { NoteMarker, NumberSystem, isHebrew } from "./numbering.js";
|
|
6
|
+
import { ParentPage, bookParentPages } from "./printed-pages.js";
|
|
7
|
+
import { BookChapterEntry, BookContents, BookFrontMatterEntry, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, REGION_NAME, TemplatedPage, TemplatedSection, bookParentIssues, isBookContents, isChapter, isDesignedSection, isTemplatedSection } from "./book-section.js";
|
|
4
8
|
import { Orientation, Paper, sheetMm } from "./paper.js";
|
|
5
9
|
import { z } from "zod";
|
|
6
10
|
//#region src/book.ts
|
|
7
11
|
const BookMode = z.enum(["continuous", "paginated"]);
|
|
8
|
-
const BookSection = z.object({
|
|
9
|
-
title: z.string().optional(),
|
|
10
|
-
html: z.string(),
|
|
11
|
-
contents: z.boolean().default(true)
|
|
12
|
-
});
|
|
13
|
-
const BookContents = z.object({
|
|
14
|
-
kind: z.literal("contents"),
|
|
15
|
-
title: z.string().optional()
|
|
16
|
-
});
|
|
17
|
-
const BookFrontMatterEntry = z.union([BookSection, BookContents]);
|
|
18
|
-
function isBookContents(entry) {
|
|
19
|
-
return "kind" in entry && entry.kind === "contents";
|
|
20
|
-
}
|
|
21
|
-
const Chapter = z.object({
|
|
22
|
-
title: z.string(),
|
|
23
|
-
html: z.string(),
|
|
24
|
-
runningHead: z.string().optional()
|
|
25
|
-
});
|
|
26
12
|
const BookPage = z.object({
|
|
27
13
|
paper: Paper,
|
|
28
14
|
orientation: Orientation.default("portrait"),
|
|
@@ -31,7 +17,16 @@ const BookPage = z.object({
|
|
|
31
17
|
bottom: z.number().nonnegative(),
|
|
32
18
|
inner: z.number().nonnegative(),
|
|
33
19
|
outer: z.number().nonnegative()
|
|
34
|
-
})
|
|
20
|
+
}),
|
|
21
|
+
columnGap: z.number().nonnegative().default(4)
|
|
22
|
+
});
|
|
23
|
+
const BookRunningHeadSource = z.union([z.literal("title"), z.object({
|
|
24
|
+
mark: z.string().min(1),
|
|
25
|
+
which: z.enum(["first", "last"])
|
|
26
|
+
})]);
|
|
27
|
+
const BookRunningHead = z.object({
|
|
28
|
+
recto: BookRunningHeadSource.default("title"),
|
|
29
|
+
verso: BookRunningHeadSource.default("title")
|
|
35
30
|
});
|
|
36
31
|
const BookShape = z.object({
|
|
37
32
|
title: z.string(),
|
|
@@ -41,7 +36,12 @@ const BookShape = z.object({
|
|
|
41
36
|
dir: Direction.optional(),
|
|
42
37
|
lang: z.string().optional(),
|
|
43
38
|
frontMatter: z.array(BookFrontMatterEntry).default([]),
|
|
44
|
-
chapters: z.array(
|
|
39
|
+
chapters: z.array(BookChapterEntry).min(1),
|
|
40
|
+
parentPages: z.array(ParentPage).default([]),
|
|
41
|
+
templates: z.array(BookTemplate).default([]),
|
|
42
|
+
slots: Slots.optional(),
|
|
43
|
+
fonts: z.array(FontReference).optional(),
|
|
44
|
+
css: z.string().optional(),
|
|
45
45
|
numbering: z.object({
|
|
46
46
|
frontMatter: NumberSystem.optional(),
|
|
47
47
|
body: NumberSystem.optional()
|
|
@@ -56,6 +56,12 @@ const BookShape = z.object({
|
|
|
56
56
|
title: z.string().optional()
|
|
57
57
|
}).default({ placement: "book" }),
|
|
58
58
|
rectoOpenings: z.boolean().default(false),
|
|
59
|
+
orphans: z.number().int().min(1).default(2),
|
|
60
|
+
widows: z.number().int().min(1).default(2),
|
|
61
|
+
runningHead: BookRunningHead.default({
|
|
62
|
+
recto: "title",
|
|
63
|
+
verso: "title"
|
|
64
|
+
}),
|
|
59
65
|
contents: z.object({
|
|
60
66
|
pageNumbers: z.boolean().default(true),
|
|
61
67
|
depth: z.number().int().min(1).max(6).default(2)
|
|
@@ -64,19 +70,41 @@ const BookShape = z.object({
|
|
|
64
70
|
depth: 2
|
|
65
71
|
})
|
|
66
72
|
});
|
|
73
|
+
const BookViewPagination = z.object({
|
|
74
|
+
paper: z.object({
|
|
75
|
+
width: z.number().positive(),
|
|
76
|
+
height: z.number().positive()
|
|
77
|
+
}),
|
|
78
|
+
margin: BookPage.shape.margin,
|
|
79
|
+
columnGap: z.number().nonnegative(),
|
|
80
|
+
direction: z.enum(["ltr", "rtl"]),
|
|
81
|
+
numbering: z.object({
|
|
82
|
+
frontMatter: NumberSystem,
|
|
83
|
+
body: NumberSystem
|
|
84
|
+
}),
|
|
85
|
+
rectoOpenings: z.boolean(),
|
|
86
|
+
orphans: z.number().int().min(1),
|
|
87
|
+
widows: z.number().int().min(1),
|
|
88
|
+
parents: z.array(ParentPage),
|
|
89
|
+
endnotePlacement: z.enum(["book", "chapter"]),
|
|
90
|
+
contents: z.object({
|
|
91
|
+
pageNumbers: z.boolean(),
|
|
92
|
+
depth: z.number().int().min(1).max(6)
|
|
93
|
+
}),
|
|
94
|
+
runningHead: BookRunningHead
|
|
95
|
+
});
|
|
67
96
|
const BookView = BookShape.pick({
|
|
68
97
|
title: true,
|
|
69
98
|
dir: true,
|
|
70
99
|
lang: true,
|
|
71
|
-
scripts: true
|
|
100
|
+
scripts: true,
|
|
101
|
+
fonts: true,
|
|
102
|
+
css: true
|
|
72
103
|
}).extend({
|
|
73
104
|
title: BookShape.shape.title.optional(),
|
|
74
|
-
html: z.string()
|
|
105
|
+
html: z.string(),
|
|
106
|
+
pagination: BookViewPagination.optional()
|
|
75
107
|
});
|
|
76
|
-
function isHebrew(lang) {
|
|
77
|
-
const primary = lang?.split("-")[0]?.toLowerCase();
|
|
78
|
-
return primary === "he" || primary === "iw";
|
|
79
|
-
}
|
|
80
108
|
const Book = BookShape.transform((book) => {
|
|
81
109
|
const hebrew = isHebrew(book.lang);
|
|
82
110
|
return {
|
|
@@ -117,6 +145,10 @@ const Book = BookShape.transform((book) => {
|
|
|
117
145
|
path: ["endnotes", "placement"],
|
|
118
146
|
message: "endnotes are placed at the end of each chapter only in paginated mode; use book placement or paginated mode"
|
|
119
147
|
});
|
|
148
|
+
for (const issue of bookParentIssues(book)) ctx.addIssue({
|
|
149
|
+
code: "custom",
|
|
150
|
+
...issue
|
|
151
|
+
});
|
|
120
152
|
if (!book.page) return;
|
|
121
153
|
const trim = sheetMm(book.page);
|
|
122
154
|
const vertical = book.page.margin.top + book.page.margin.bottom;
|
|
@@ -132,9 +164,26 @@ const Book = BookShape.transform((book) => {
|
|
|
132
164
|
message: `the inner and outer margins total ${horizontal}mm and the page is ${trim.width}mm wide; reduce the horizontal margins to leave a text area`
|
|
133
165
|
});
|
|
134
166
|
});
|
|
167
|
+
function resolveBookPagination(book) {
|
|
168
|
+
if (book.mode !== "paginated" || !book.page) return void 0;
|
|
169
|
+
return {
|
|
170
|
+
paper: sheetMm(book.page),
|
|
171
|
+
margin: book.page.margin,
|
|
172
|
+
columnGap: book.page.columnGap,
|
|
173
|
+
direction: resolveDirection(book.dir, book.lang, book.title),
|
|
174
|
+
numbering: book.numbering,
|
|
175
|
+
rectoOpenings: book.rectoOpenings,
|
|
176
|
+
orphans: book.orphans,
|
|
177
|
+
widows: book.widows,
|
|
178
|
+
parents: [...bookParentPages(book.page.margin), ...book.parentPages],
|
|
179
|
+
endnotePlacement: book.endnotes.placement,
|
|
180
|
+
contents: book.contents,
|
|
181
|
+
runningHead: book.runningHead
|
|
182
|
+
};
|
|
183
|
+
}
|
|
135
184
|
function noteMarkerIssues(book, used) {
|
|
136
185
|
if (!used.footnotes || !used.endnotes || book.footnotes.marker !== book.endnotes.marker) return [];
|
|
137
186
|
return [`footnote and endnote markers are both ${book.footnotes.marker}; the two must differ when both kinds are used`];
|
|
138
187
|
}
|
|
139
188
|
//#endregion
|
|
140
|
-
export { Book, BookContents, BookFrontMatterEntry, BookMode, BookPage, BookSection, BookShape, BookView, Chapter, isBookContents,
|
|
189
|
+
export { Book, BookChapterEntry, BookContents, BookFrontMatterEntry, BookMode, BookOpens, BookPage, BookRunningHead, BookRunningHeadSource, BookSection, BookSectionParents, BookShape, BookTemplate, BookView, BookViewPagination, Chapter, DesignedPage, DesignedSection, REGION_NAME, TemplatedPage, TemplatedSection, isBookContents, isChapter, isDesignedSection, isTemplatedSection, noteMarkerIssues, resolveBookPagination };
|
package/dist/direction.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare const TextDirection: z.ZodEnum<{
|
|
|
10
10
|
rtl: "rtl";
|
|
11
11
|
}>;
|
|
12
12
|
export type TextDirection = z.infer<typeof TextDirection>;
|
|
13
|
+
export declare function textDirection(dir: string | undefined, lang: string | undefined, sample: string): TextDirection | null;
|
|
13
14
|
export declare function firstStrongDirection(text: string): TextDirection | null;
|
|
14
15
|
export declare function languageDirection(lang: string | undefined): TextDirection | null;
|
|
15
16
|
export declare function resolveDirection(dir: 'ltr' | 'rtl' | 'auto' | undefined, lang: string | undefined, sample: string): TextDirection;
|
package/dist/direction.js
CHANGED
|
@@ -6,41 +6,44 @@ const Direction = z.enum([
|
|
|
6
6
|
"auto"
|
|
7
7
|
]);
|
|
8
8
|
const TextDirection = z.enum(["ltr", "rtl"]);
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
9
|
+
function textDirection(dir, lang, sample) {
|
|
10
|
+
const rtlLetter = /[\p{Script=Hebrew}\p{Script=Arabic}\p{Script=Syriac}\p{Script=Thaana}\p{Script=Nko}\p{Script=Samaritan}\p{Script=Mandaic}\p{Script=Adlam}\p{Script=Hanifi_Rohingya}\p{Script=Mende_Kikakui}\p{Script=Old_Hungarian}\p{Script=Imperial_Aramaic}\p{Script=Phoenician}]/u;
|
|
11
|
+
const letter = /\p{L}/u;
|
|
12
|
+
const rtlLanguages = /* @__PURE__ */ new Set([
|
|
13
|
+
"ar",
|
|
14
|
+
"arc",
|
|
15
|
+
"ckb",
|
|
16
|
+
"dv",
|
|
17
|
+
"fa",
|
|
18
|
+
"he",
|
|
19
|
+
"iw",
|
|
20
|
+
"ji",
|
|
21
|
+
"ks",
|
|
22
|
+
"ku",
|
|
23
|
+
"nqo",
|
|
24
|
+
"ps",
|
|
25
|
+
"sd",
|
|
26
|
+
"syr",
|
|
27
|
+
"ug",
|
|
28
|
+
"ur",
|
|
29
|
+
"yi"
|
|
30
|
+
]);
|
|
31
|
+
if (dir === "ltr" || dir === "rtl") return dir;
|
|
32
|
+
if (lang) return rtlLanguages.has(lang.toLowerCase().split("-")[0] ?? "") ? "rtl" : "ltr";
|
|
33
|
+
for (const char of sample) {
|
|
34
|
+
if (rtlLetter.test(char)) return "rtl";
|
|
35
|
+
if (letter.test(char)) return "ltr";
|
|
34
36
|
}
|
|
35
37
|
return null;
|
|
36
38
|
}
|
|
39
|
+
function firstStrongDirection(text) {
|
|
40
|
+
return textDirection(void 0, void 0, text);
|
|
41
|
+
}
|
|
37
42
|
function languageDirection(lang) {
|
|
38
|
-
|
|
39
|
-
return RTL_LANGUAGES.has(lang.toLowerCase().split("-")[0] ?? "") ? "rtl" : "ltr";
|
|
43
|
+
return lang ? textDirection(void 0, lang, "") : null;
|
|
40
44
|
}
|
|
41
45
|
function resolveDirection(dir, lang, sample) {
|
|
42
|
-
|
|
43
|
-
return languageDirection(lang) ?? firstStrongDirection(sample) ?? "ltr";
|
|
46
|
+
return textDirection(dir, lang, sample) ?? "ltr";
|
|
44
47
|
}
|
|
45
48
|
//#endregion
|
|
46
|
-
export { Direction, TextDirection, firstStrongDirection, languageDirection, resolveDirection };
|
|
49
|
+
export { Direction, TextDirection, firstStrongDirection, languageDirection, resolveDirection, textDirection };
|
package/dist/fonts.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/fonts.d.ts
|
|
3
|
+
export declare const APP_FONT_NAME: RegExp;
|
|
4
|
+
export declare const APP_FONT_NAME_MESSAGE = "app font names are lowercase letters, digits and hyphens";
|
|
5
|
+
export declare const FontReference: z.ZodUnion<readonly [z.ZodObject<{
|
|
6
|
+
app: z.ZodString;
|
|
7
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
8
|
+
local: z.ZodString;
|
|
9
|
+
fallback: z.ZodString;
|
|
10
|
+
}, z.core.$strip>]>;
|
|
11
|
+
export type FontReference = z.infer<typeof FontReference>;
|
|
12
|
+
export declare const FontReferenceInput: z.ZodUnion<readonly [z.ZodObject<{
|
|
13
|
+
app: z.ZodString;
|
|
14
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
15
|
+
local: z.ZodString;
|
|
16
|
+
fallback: z.ZodString;
|
|
17
|
+
}, z.core.$strict>]>;
|
|
18
|
+
export type FontReferenceInput = z.input<typeof FontReferenceInput>;
|
|
19
|
+
export declare function localFontReferences(references: readonly FontReference[]): Array<{
|
|
20
|
+
local: string;
|
|
21
|
+
fallback: string;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const FONT_FORMATS: readonly ["woff2", "woff", "truetype", "opentype"];
|
|
24
|
+
export type FontFormat = (typeof FONT_FORMATS)[number];
|
|
25
|
+
export declare const LocalFaceTransport: z.ZodObject<{
|
|
26
|
+
family: z.ZodString;
|
|
27
|
+
format: z.ZodEnum<{
|
|
28
|
+
woff2: "woff2";
|
|
29
|
+
woff: "woff";
|
|
30
|
+
truetype: "truetype";
|
|
31
|
+
opentype: "opentype";
|
|
32
|
+
}>;
|
|
33
|
+
weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
|
|
34
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
normal: "normal";
|
|
36
|
+
italic: "italic";
|
|
37
|
+
}>>;
|
|
38
|
+
data: z.ZodString;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
export type LocalFaceTransport = z.infer<typeof LocalFaceTransport>;
|
|
41
|
+
export declare const LocalFacesTransport: z.ZodArray<z.ZodObject<{
|
|
42
|
+
family: z.ZodString;
|
|
43
|
+
format: z.ZodEnum<{
|
|
44
|
+
woff2: "woff2";
|
|
45
|
+
woff: "woff";
|
|
46
|
+
truetype: "truetype";
|
|
47
|
+
opentype: "opentype";
|
|
48
|
+
}>;
|
|
49
|
+
weight: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
|
|
50
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
normal: "normal";
|
|
52
|
+
italic: "italic";
|
|
53
|
+
}>>;
|
|
54
|
+
data: z.ZodString;
|
|
55
|
+
}, z.core.$strict>>;
|
|
56
|
+
export type LocalFacesInput = LocalFaceTransport[];
|
|
57
|
+
export declare const FONT_GENERICS: readonly ["serif", "sans-serif", "monospace", "cursive", "fantasy", "system-ui"];
|
|
58
|
+
export type FontGeneric = (typeof FONT_GENERICS)[number];
|
|
59
|
+
export interface FontFace {
|
|
60
|
+
family: string;
|
|
61
|
+
data: Uint8Array;
|
|
62
|
+
format: FontFormat;
|
|
63
|
+
weight?: number | string;
|
|
64
|
+
style?: 'normal' | 'italic';
|
|
65
|
+
unicodeRange?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface AppFont {
|
|
68
|
+
family: string;
|
|
69
|
+
faces: FontFace[];
|
|
70
|
+
generic?: FontGeneric;
|
|
71
|
+
}
|
|
72
|
+
export interface FontSource {
|
|
73
|
+
font(name: string, options: {
|
|
74
|
+
signal: AbortSignal;
|
|
75
|
+
}): Promise<AppFont | undefined>;
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
package/dist/fonts.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/fonts.ts
|
|
3
|
+
const APP_FONT_NAME = /^[a-z0-9-]+$/;
|
|
4
|
+
const APP_FONT_NAME_MESSAGE = "app font names are lowercase letters, digits and hyphens";
|
|
5
|
+
const AppFontName = z.string().min(1).regex(APP_FONT_NAME, APP_FONT_NAME_MESSAGE);
|
|
6
|
+
const AppFontShape = { app: AppFontName };
|
|
7
|
+
const LocalFontShape = {
|
|
8
|
+
local: z.string().min(1),
|
|
9
|
+
fallback: AppFontName
|
|
10
|
+
};
|
|
11
|
+
const FontReference = z.union([z.object(AppFontShape), z.object(LocalFontShape)]);
|
|
12
|
+
const FontReferenceInput = z.union([z.strictObject(AppFontShape), z.strictObject(LocalFontShape)]);
|
|
13
|
+
function localFontReferences(references) {
|
|
14
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15
|
+
const locals = [];
|
|
16
|
+
for (const reference of references) {
|
|
17
|
+
if (!("local" in reference)) continue;
|
|
18
|
+
const key = JSON.stringify(reference);
|
|
19
|
+
if (seen.has(key)) continue;
|
|
20
|
+
seen.add(key);
|
|
21
|
+
locals.push(reference);
|
|
22
|
+
}
|
|
23
|
+
return locals;
|
|
24
|
+
}
|
|
25
|
+
const FONT_FORMATS = [
|
|
26
|
+
"woff2",
|
|
27
|
+
"woff",
|
|
28
|
+
"truetype",
|
|
29
|
+
"opentype"
|
|
30
|
+
];
|
|
31
|
+
const LocalFaceTransportShape = {
|
|
32
|
+
family: z.string().min(1),
|
|
33
|
+
format: z.enum(FONT_FORMATS),
|
|
34
|
+
weight: z.union([z.number(), z.string()]).optional(),
|
|
35
|
+
style: z.enum(["normal", "italic"]).optional(),
|
|
36
|
+
data: z.string()
|
|
37
|
+
};
|
|
38
|
+
const LocalFaceTransport = z.strictObject(LocalFaceTransportShape);
|
|
39
|
+
const LocalFacesTransport = z.array(LocalFaceTransport);
|
|
40
|
+
const FONT_GENERICS = [
|
|
41
|
+
"serif",
|
|
42
|
+
"sans-serif",
|
|
43
|
+
"monospace",
|
|
44
|
+
"cursive",
|
|
45
|
+
"fantasy",
|
|
46
|
+
"system-ui"
|
|
47
|
+
];
|
|
48
|
+
//#endregion
|
|
49
|
+
export { APP_FONT_NAME, APP_FONT_NAME_MESSAGE, FONT_FORMATS, FONT_GENERICS, FontReference, FontReferenceInput, LocalFaceTransport, LocalFacesTransport, localFontReferences };
|