@segnavia/format 0.37.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.
package/dist/index.js CHANGED
@@ -8,10 +8,11 @@ import { Board, BoardItem, BoardLabel, BoardSection, GridCell } from "./board.js
8
8
  import { APP_FONT_NAME, APP_FONT_NAME_MESSAGE, FONT_FORMATS, FONT_GENERICS, FontReference, FontReferenceInput, LocalFaceTransport, LocalFacesTransport, localFontReferences } from "./fonts.js";
9
9
  import { BOOK_FURNITURE, LIBRARY_MOTIF_PREFIX, MOTIF_ATTRIBUTE, Motif, MotifField, MotifFieldInput, MotifInput, MotifVersion, MotifVersionInput, PRINTED_PAGE_CONTEXT, PRINTED_PAGE_FOLIO_PATH, PRINTED_PAGE_NUMBER_PATH, PRINTED_PAGE_RUNNING_HEAD_PATH, PRINTED_PAGE_TOTAL_PATH, chooseMotifVersion, motifFieldAttribute } from "./motif.js";
10
10
  import { NoteMarker, NumberSystem, defaultPageNumbering, formatNumber, isHebrew, noteMarker } from "./numbering.js";
11
- import { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages } from "./printed-pages.js";
12
- import { BookChapterEntry, BookContents, BookFrontMatterEntry, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, REGION_NAME, TemplatedPage, TemplatedSection, isBookContents, isChapter, isDesignedSection, isTemplatedSection } from "./book-section.js";
13
- import { 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 } from "./paper.js";
14
- import { Book, BookMode, BookPage, BookRunningHead, BookRunningHeadSource, BookShape, BookView, BookViewPagination, noteMarkerIssues, resolveBookPagination } from "./book.js";
11
+ import { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, flowingParentNames, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages, textArea } from "./printed-pages.js";
12
+ import { BookChapterEntry, BookContents, BookFrontMatterEntry, BookItem, BookOpens, BookSection, BookSectionParents, BookTemplate, Chapter, DesignedPage, DesignedSection, MAX_PART_DEPTH, Part, REGION_NAME, TemplatedPage, TemplatedSection, bookSections, isBookContents, isChapter, isDesignedSection, isPart, isTemplatedSection } from "./book-section.js";
13
+ import { NoteNumbering, NotePlacement, NoteSeries, noteMarkerIssues, resolveNoteSeries } from "./note-series.js";
14
+ import { 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 } from "./paper.js";
15
+ import { Book, BookMode, BookPage, BookRunningHead, BookRunningHeadSource, BookShape, BookView, BookViewPagination, resolveBookPagination } from "./book.js";
15
16
  import { PAPER_FIT_TOLERANCE_MM, refuseOverflow, refuseSafe } from "./imposition-fit.js";
16
17
  import { FOLD_KINDS, FOLD_TUCK_IN_MM, foldCellPages, foldColumns, foldPageCountMessage, foldPanelMap, refineFold, resolveImposition } from "./fold.js";
17
18
  import { Lexicon, PronunciationEntry, lexiconVersion } from "./lexicon.js";
@@ -24,8 +25,10 @@ import { assignMembership, fitSection, fitTouchedSections, makeRoom, settleBoard
24
25
  import { deckFromSlides } from "./deck-from-slides.js";
25
26
  import { fitPage, impose, mirrorPlacement, pagePlacementLayout } from "./imposition.js";
26
27
  import { MIN_MARK_LENGTH_MM, impositionMarks } from "./imposition-marks.js";
28
+ import { LOCAL_FONT_LIMITS, localFontLimitRefusal } from "./local-font-limits.js";
27
29
  import { isPrintedPageIdentityImposition } from "./printed-page-imposition.js";
28
30
  import { shotsUsed } from "./shots-used.js";
31
+ import { dependencyDecision, dependencyOriginSet, originSet } from "./dependency-policy.js";
29
32
  import { z } from "zod";
30
33
  //#region src/index.ts
31
34
  const Margin = z.object({
@@ -224,4 +227,4 @@ function jsonSchemas() {
224
227
  };
225
228
  }
226
229
  //#endregion
227
- export { APP_FONT_NAME, APP_FONT_NAME_MESSAGE, Annotation, BOOK_FURNITURE, BOOK_PARENT_NAMES, Board, BoardItem, BoardLabel, BoardSection, Book, BookChapterEntry, BookContents, BookFrontMatterEntry, BookMode, BookOpens, BookPage, BookRunningHead, BookRunningHeadSource, BookSection, BookSectionParents, BookTemplate, BookView, BookViewPagination, Box, CUSTOM_PAPER_MAX_MM, CUSTOM_PAPER_MIN_MM, Chapter, Cue, DECK_SIZE, DEFAULT_TRANSITION_DURATION_MS, Deck, DesignedPage, DesignedSection, Direction, FOLD_DASH_OFF_MM, FOLD_DASH_ON_MM, FOLD_KINDS, FOLD_TUCK_IN_MM, FONT_FORMATS, FONT_GENERICS, FillValues, FontReference, FontReferenceInput, GridCell, ImageFit, Imposition, LIBRARY_MOTIF_PREFIX, Lexicon, LocalFaceTransport, LocalFacesTransport, MAKE_ROOM_LIMIT, MARK_GAP_MM, MARK_LENGTH_MM, MAX_BOARD_ZOOM, MAX_IMPOSITION_CELLS, MAX_SLIDE_TIMING_MS, MAX_TRANSITION_DURATION_MS, MIN_BOARD_ITEM_WIDTH, MIN_BOARD_ZOOM, MIN_MARK_LENGTH_MM, MIN_TRANSITION_DURATION_MS, MM_PER_PT, MOTIF_ATTRIBUTE, Manifest, Margin, MarkColor, Motif, MotifField, MotifFieldInput, MotifInput, MotifVersion, MotifVersionInput, NAMED_PAPERS, Narration, NoteMarker, NumberSystem, ORIENTATIONS, Orientation, PAPER_FIT_TOLERANCE_MM, PAPER_GROUPS, PAPER_METADATA, PAPER_MM, PAPER_UNITS, PLAYBACK_MODES, PRINTED_PAGE_CONTEXT, PRINTED_PAGE_FOLIO_PATH, PRINTED_PAGE_LIMIT, PRINTED_PAGE_NUMBER_PATH, PRINTED_PAGE_ROLES, PRINTED_PAGE_RUNNING_HEAD_PATH, PRINTED_PAGE_TOTAL_PATH, PX_PER_MM, Page, PageSize, Paper, PaperUnit, ParentPage, ParentPageMargin, Playback, Point, Print, PrintSetting, PrintSettingInput, PrintedPageRules, PrintedPages, PronunciationEntry, PublishedShot, REGION_NAME, SECTION_GAP, SECTION_MIN_SIZE, SECTION_PADDING, SECTION_TITLE_ROOM, SHOT_KEY, SLOT_TYPES, Scripts, Shot, Size, Slide, SlideContent, SlotDeclaration, SlotDeclarationInput, SlotKey, SlotType, SlotValue, Slots, SlotsInput, TemplatedPage, TemplatedSection, TextDirection, Transition, Word, addItem, annotationCueIssues, arrange, assignMembership, boardBounds, boardListing, boardListingIsEmpty, boardToScreen, bookParentPages, chooseMotifVersion, deckFromSlides, defaultPageNumbering, deriveSectionCells, exceedsLimits, firstStrongDirection, fitPage, fitSection, fitTouchedSections, foldCellPages, foldColumns, foldForSearch, foldPageCountMessage, foldPanelMap, formatNumber, fromMillimeters, gridDropMarkerBox, gridDropTarget, impose, impositionMarks, insertIntoGrid, isBookContents, isChapter, isDesignedSection, isHebrew, isPrintedPageIdentityImposition, isTemplatedSection, itemAt, itemHeight, jsonSchemas, languageDirection, layoutSection, lexiconVersion, localFontReferences, makeRoom, mergeSlotDeclarations, mirrorPlacement, motifFieldAttribute, moveItems, moveSection, nameMatches, noteMarker, noteMarkerIssues, pagePlacementLayout, pagePrintedPagesIssues, paperPixels, parentListIssues, parsePlayback, printBoxes, printPadding, printProperties, printedPagesIssues, removeFromGrid, removeItems, resizeItem, resolveBookPagination, resolveDirection, resolveParentPages, revealView, roundMillimeters, screenToBoard, settleBoard, sheetMm, shotsUsed, textDirection, toMillimeters, visibleItems, zoomAt, zoomToFit };
230
+ export { APP_FONT_NAME, APP_FONT_NAME_MESSAGE, Annotation, BOOK_FURNITURE, BOOK_PARENT_NAMES, Board, BoardItem, BoardLabel, BoardSection, Book, BookChapterEntry, BookContents, BookFrontMatterEntry, BookItem, BookMode, BookOpens, BookPage, BookRunningHead, BookRunningHeadSource, BookSection, BookSectionParents, BookTemplate, BookView, BookViewPagination, Box, CUSTOM_PAPER_MAX_MM, CUSTOM_PAPER_MIN_MM, Chapter, Cue, DECK_SIZE, DEFAULT_TRANSITION_DURATION_MS, Deck, DesignedPage, DesignedSection, Direction, FOLD_DASH_OFF_MM, FOLD_DASH_ON_MM, FOLD_KINDS, FOLD_TUCK_IN_MM, FONT_FORMATS, FONT_GENERICS, FillValues, FontReference, FontReferenceInput, GridCell, ImageFit, Imposition, LIBRARY_MOTIF_PREFIX, LOCAL_FONT_LIMITS, Lexicon, LocalFaceTransport, LocalFacesTransport, MAKE_ROOM_LIMIT, MARK_GAP_MM, MARK_LENGTH_MM, MAX_BOARD_ZOOM, MAX_IMPOSITION_CELLS, MAX_PART_DEPTH, MAX_SLIDE_TIMING_MS, MAX_TRANSITION_DURATION_MS, MIN_BOARD_ITEM_WIDTH, MIN_BOARD_ZOOM, MIN_MARK_LENGTH_MM, MIN_TRANSITION_DURATION_MS, MM_PER_PT, MOTIF_ATTRIBUTE, Manifest, Margin, MarkColor, Motif, MotifField, MotifFieldInput, MotifInput, MotifVersion, MotifVersionInput, NAMED_PAPERS, Narration, NoteMarker, NoteNumbering, NotePlacement, NoteSeries, NumberSystem, ORIENTATIONS, Orientation, PAPER_FIT_TOLERANCE_MM, PAPER_GROUPS, PAPER_METADATA, PAPER_MM, PAPER_UNITS, PLAYBACK_MODES, PRINTED_PAGE_CONTEXT, PRINTED_PAGE_FOLIO_PATH, PRINTED_PAGE_LIMIT, PRINTED_PAGE_NUMBER_PATH, PRINTED_PAGE_ROLES, PRINTED_PAGE_RUNNING_HEAD_PATH, PRINTED_PAGE_TOTAL_PATH, PX_PER_MM, PX_PER_PT, Page, PageSize, Paper, PaperUnit, ParentPage, ParentPageMargin, Part, Playback, Point, Print, PrintSetting, PrintSettingInput, PrintedPageRules, PrintedPages, PronunciationEntry, PublishedShot, REGION_NAME, SECTION_GAP, SECTION_MIN_SIZE, SECTION_PADDING, SECTION_TITLE_ROOM, SHOT_KEY, SLOT_TYPES, Scripts, Shot, Size, Slide, SlideContent, SlotDeclaration, SlotDeclarationInput, SlotKey, SlotType, SlotValue, Slots, SlotsInput, TemplatedPage, TemplatedSection, TextDirection, Transition, Word, addItem, annotationCueIssues, arrange, assignMembership, boardBounds, boardListing, boardListingIsEmpty, boardToScreen, bookParentPages, bookSections, chooseMotifVersion, deckFromSlides, defaultPageNumbering, dependencyDecision, dependencyOriginSet, deriveSectionCells, exceedsLimits, firstStrongDirection, fitPage, fitSection, fitTouchedSections, flowingParentNames, foldCellPages, foldColumns, foldForSearch, foldPageCountMessage, foldPanelMap, formatNumber, fromMillimeters, gridDropMarkerBox, gridDropTarget, impose, impositionMarks, insertIntoGrid, isBookContents, isChapter, isDesignedSection, isHebrew, isPart, isPrintedPageIdentityImposition, isTemplatedSection, itemAt, itemHeight, jsonSchemas, languageDirection, layoutSection, lexiconVersion, localFontLimitRefusal, localFontReferences, makeRoom, mergeSlotDeclarations, mirrorPlacement, motifFieldAttribute, moveItems, moveSection, nameMatches, noteMarker, noteMarkerIssues, originSet, pagePlacementLayout, pagePrintedPagesIssues, paperPixels, parentListIssues, parsePlayback, printBoxes, printPadding, printProperties, printedPagesIssues, removeFromGrid, removeItems, resizeItem, resolveBookPagination, resolveDirection, resolveNoteSeries, resolveParentPages, revealView, roundMillimeters, screenToBoard, settleBoard, sheetMm, shotsUsed, textArea, textDirection, toMillimeters, visibleItems, zoomAt, zoomToFit };
@@ -0,0 +1,15 @@
1
+ //#region src/local-font-limits.d.ts
2
+ export interface LocalFontLimits {
3
+ count?: number;
4
+ bytes?: number;
5
+ }
6
+ export interface LocalFontLimitFace {
7
+ family: string;
8
+ bytes: number;
9
+ }
10
+ export declare const LOCAL_FONT_LIMITS: {
11
+ readonly count: 64;
12
+ readonly bytes: number;
13
+ };
14
+ export declare function localFontLimitRefusal(faces: readonly LocalFontLimitFace[], limits?: LocalFontLimits): string | undefined;
15
+ //#endregion
@@ -0,0 +1,24 @@
1
+ //#region src/local-font-limits.ts
2
+ const LOCAL_FONT_LIMITS = {
3
+ count: 64,
4
+ bytes: 33554432
5
+ };
6
+ function limit(value, fallback, label) {
7
+ const resolved = value ?? fallback;
8
+ if (!Number.isSafeInteger(resolved) || resolved < 0) return `The local font ${label} limit must be a non-negative safe integer; pass valid limits to clear this refusal.`;
9
+ return resolved;
10
+ }
11
+ function localFontLimitRefusal(faces, limits = {}) {
12
+ const countLimit = limit(limits.count, LOCAL_FONT_LIMITS.count, "count");
13
+ if (typeof countLimit === "string") return countLimit;
14
+ const byteLimit = limit(limits.bytes, LOCAL_FONT_LIMITS.bytes, "byte");
15
+ if (typeof byteLimit === "string") return byteLimit;
16
+ if (faces.length > countLimit) return `The local face ${JSON.stringify(faces[countLimit]?.family ?? "unknown family")} exceeds the count limit of ${countLimit}; pass higher limits or declare fewer local font families to clear this refusal.`;
17
+ let bytes = 0;
18
+ for (const face of faces) {
19
+ bytes += face.bytes;
20
+ if (bytes > byteLimit) return `The local face ${JSON.stringify(face.family)} exceeds the byte limit of ${byteLimit}; pass higher limits or declare fewer local font families to clear this refusal.`;
21
+ }
22
+ }
23
+ //#endregion
24
+ export { LOCAL_FONT_LIMITS, localFontLimitRefusal };
@@ -0,0 +1,70 @@
1
+ import { NoteMarker } from "./numbering.js";
2
+ import { z } from "zod";
3
+ //#region src/note-series.d.ts
4
+ export declare const NotePlacement: z.ZodEnum<{
5
+ page: "page";
6
+ chapter: "chapter";
7
+ book: "book";
8
+ part: "part";
9
+ }>;
10
+ export type NotePlacement = z.infer<typeof NotePlacement>;
11
+ export declare const NoteNumbering: z.ZodEnum<{
12
+ chapter: "chapter";
13
+ book: "book";
14
+ part: "part";
15
+ }>;
16
+ export type NoteNumbering = z.infer<typeof NoteNumbering>;
17
+ export declare const NoteSeries: z.ZodObject<{
18
+ name: z.ZodString;
19
+ placement: z.ZodOptional<z.ZodEnum<{
20
+ page: "page";
21
+ chapter: "chapter";
22
+ book: "book";
23
+ part: "part";
24
+ }>>;
25
+ numbering: z.ZodOptional<z.ZodEnum<{
26
+ chapter: "chapter";
27
+ book: "book";
28
+ part: "part";
29
+ }>>;
30
+ marker: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
31
+ arabic: "arabic";
32
+ "roman-lower": "roman-lower";
33
+ "roman-upper": "roman-upper";
34
+ hebrew: "hebrew";
35
+ }>, z.ZodLiteral<"symbols">]>>;
36
+ title: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ export type NoteSeriesInput = z.input<typeof NoteSeries>;
39
+ export interface ResolvedNoteSeries {
40
+ name: string;
41
+ placement: NotePlacement;
42
+ numbering: NoteNumbering;
43
+ marker: NoteMarker;
44
+ title: string;
45
+ idStem: string;
46
+ idScope: 'chapter' | 'numbering';
47
+ blockClass: string;
48
+ bodyClass: string;
49
+ titleClass: string;
50
+ sectionIdPrefix: string;
51
+ markerLabel: string;
52
+ markerConflictSuffixes: Readonly<Record<string, string>>;
53
+ markBlockSeries: boolean;
54
+ }
55
+ interface NoteSeriesSettings {
56
+ lang?: string;
57
+ footnotes: {
58
+ marker?: NoteMarker;
59
+ restart: 'chapter' | 'book';
60
+ };
61
+ endnotes: {
62
+ marker?: NoteMarker;
63
+ placement: 'book' | 'chapter';
64
+ title?: string;
65
+ };
66
+ notes: NoteSeriesInput[];
67
+ }
68
+ export declare function resolveNoteSeries(settings: NoteSeriesSettings): ResolvedNoteSeries[];
69
+ export declare function noteMarkerIssues(series: ResolvedNoteSeries[], used: ReadonlySet<string>): string[];
70
+ //#endregion
@@ -0,0 +1,158 @@
1
+ import { NoteMarker, isHebrew } from "./numbering.js";
2
+ import { REGION_NAME } from "./book-section.js";
3
+ import { z } from "zod";
4
+ //#region src/note-series.ts
5
+ const NotePlacement = z.enum([
6
+ "page",
7
+ "chapter",
8
+ "part",
9
+ "book"
10
+ ]);
11
+ const NoteNumbering = z.enum([
12
+ "chapter",
13
+ "part",
14
+ "book"
15
+ ]);
16
+ const NoteSeries = z.object({
17
+ name: z.string().regex(REGION_NAME, "a note series name must be an HTML name token"),
18
+ placement: NotePlacement.optional(),
19
+ numbering: NoteNumbering.optional(),
20
+ marker: NoteMarker.optional(),
21
+ title: z.string().optional()
22
+ });
23
+ function markerOrder(lang) {
24
+ return isHebrew(lang) ? [
25
+ "hebrew",
26
+ "arabic",
27
+ "symbols",
28
+ "roman-lower"
29
+ ] : [
30
+ "symbols",
31
+ "arabic",
32
+ "roman-lower",
33
+ "hebrew"
34
+ ];
35
+ }
36
+ function unusedMarker(lang, used) {
37
+ return markerOrder(lang).find((marker) => !used.has(marker)) ?? "symbols";
38
+ }
39
+ function resolveCustomSeries(series) {
40
+ if (series.placement === void 0 || series.numbering === void 0) throw new Error(`note series ${series.name} needs placement and numbering`);
41
+ return {
42
+ ...series,
43
+ placement: series.placement,
44
+ numbering: series.numbering,
45
+ title: series.title ?? series.name,
46
+ idStem: `note-${series.name}`,
47
+ idScope: "numbering",
48
+ blockClass: `segnavia-notes-${series.name}`,
49
+ bodyClass: `segnavia-note-${series.name}`,
50
+ titleClass: "segnavia-notes-title",
51
+ sectionIdPrefix: `segnavia-notes-${series.name}`,
52
+ markerLabel: `note series ${series.name}`,
53
+ markerConflictSuffixes: {},
54
+ markBlockSeries: true
55
+ };
56
+ }
57
+ function resolveNoteSeries(settings) {
58
+ const hebrew = isHebrew(settings.lang);
59
+ const declared = new Map(settings.notes.map((series) => [series.name, series]));
60
+ const footnotePresentation = {
61
+ idStem: "fn",
62
+ idScope: "chapter",
63
+ blockClass: "segnavia-footnotes",
64
+ bodyClass: "segnavia-footnote",
65
+ titleClass: "segnavia-notes-title",
66
+ sectionIdPrefix: "segnavia-notes-footnote",
67
+ markerLabel: "footnote",
68
+ markerConflictSuffixes: { endnote: "the two must differ when both kinds are used" },
69
+ markBlockSeries: false
70
+ };
71
+ const endnotePresentation = {
72
+ idStem: "en",
73
+ idScope: "numbering",
74
+ blockClass: "segnavia-notes-endnote",
75
+ bodyClass: "segnavia-endnote",
76
+ titleClass: "segnavia-endnotes-title",
77
+ sectionIdPrefix: "segnavia-endnotes",
78
+ markerLabel: "endnote",
79
+ markerConflictSuffixes: {},
80
+ markBlockSeries: true
81
+ };
82
+ const inputs = [
83
+ {
84
+ name: "footnote",
85
+ placement: "page",
86
+ numbering: settings.footnotes.restart,
87
+ marker: settings.footnotes.marker ?? (hebrew ? "hebrew" : "symbols"),
88
+ title: hebrew ? "מקורות" : "Footnotes",
89
+ ...footnotePresentation,
90
+ ...declared.get("footnote")
91
+ },
92
+ {
93
+ name: "endnote",
94
+ placement: settings.endnotes.placement,
95
+ numbering: "book",
96
+ marker: settings.endnotes.marker ?? "arabic",
97
+ title: settings.endnotes.title ?? (hebrew ? "הערות" : "Notes"),
98
+ ...endnotePresentation,
99
+ ...declared.get("endnote")
100
+ },
101
+ ...settings.notes.filter(({ name }) => name !== "footnote" && name !== "endnote").map(resolveCustomSeries)
102
+ ];
103
+ const used = /* @__PURE__ */ new Set();
104
+ return inputs.map((series) => {
105
+ const marker = series.marker ?? unusedMarker(settings.lang, used);
106
+ used.add(marker);
107
+ return {
108
+ name: series.name,
109
+ placement: series.placement,
110
+ numbering: series.numbering,
111
+ marker,
112
+ title: series.title,
113
+ idStem: series.idStem,
114
+ idScope: series.idScope,
115
+ blockClass: series.blockClass,
116
+ bodyClass: series.bodyClass,
117
+ titleClass: series.titleClass,
118
+ sectionIdPrefix: series.sectionIdPrefix,
119
+ markerLabel: series.markerLabel,
120
+ markerConflictSuffixes: series.markerConflictSuffixes,
121
+ markBlockSeries: series.markBlockSeries
122
+ };
123
+ });
124
+ }
125
+ function noteSeriesIssues(series, mode) {
126
+ const issues = [];
127
+ series.forEach((item, index) => {
128
+ if (mode === "continuous" && (item.placement === "chapter" || item.placement === "part")) issues.push({
129
+ path: [
130
+ "notes",
131
+ index,
132
+ "placement"
133
+ ],
134
+ message: `note series ${item.name} uses ${item.placement} placement only available in paginated mode; use page or book placement, or paginated mode`
135
+ });
136
+ });
137
+ const page = series.filter(({ placement }) => placement === "page");
138
+ if (page.length > 1) issues.push({
139
+ path: ["notes"],
140
+ message: `note series ${page.map(({ name }) => name).join(" and ")} are both page-placed; declare one page-placed series`
141
+ });
142
+ return issues;
143
+ }
144
+ function noteMarkerIssues(series, used) {
145
+ const active = series.filter(({ name }) => used.has(name));
146
+ const issues = [];
147
+ for (let left = 0; left < active.length; left += 1) for (let right = left + 1; right < active.length; right += 1) {
148
+ const a = active[left];
149
+ const b = active[right];
150
+ if (!a || !b) continue;
151
+ if (a.marker !== b.marker) continue;
152
+ const suffix = a.markerConflictSuffixes[b.name] ?? b.markerConflictSuffixes[a.name] ?? "used series must have different markers";
153
+ issues.push(`${a.markerLabel} and ${b.markerLabel} markers are both ${a.marker}; ${suffix}`);
154
+ }
155
+ return issues;
156
+ }
157
+ //#endregion
158
+ export { NoteNumbering, NotePlacement, NoteSeries, noteMarkerIssues, noteSeriesIssues, resolveNoteSeries };
package/dist/paper.d.ts CHANGED
@@ -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 };
@@ -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)[];
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segnavia/format",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {