@segnavia/format 0.27.0 → 0.29.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/motif.d.ts CHANGED
@@ -13,12 +13,26 @@ export declare const BOOK_FURNITURE: readonly [{
13
13
  readonly value: "folio";
14
14
  readonly className: "segnavia-folio";
15
15
  readonly region: "foot";
16
+ readonly fields: readonly [];
16
17
  }, {
17
18
  readonly key: "segnavia:running-head";
18
19
  readonly path: "printedPage.runningHead";
19
20
  readonly value: "runningHead";
20
21
  readonly className: "segnavia-running-head";
21
22
  readonly region: "head";
23
+ readonly fields: readonly [];
24
+ }, {
25
+ readonly key: "segnavia:mark";
26
+ readonly className: "segnavia-mark";
27
+ readonly region: "head";
28
+ readonly fields: readonly [{
29
+ readonly key: "name";
30
+ readonly required: true;
31
+ }, {
32
+ readonly key: "which";
33
+ readonly choices: readonly ["first", "last"];
34
+ readonly default: "first";
35
+ }];
22
36
  }];
23
37
  export type BookFurniture = (typeof BOOK_FURNITURE)[number];
24
38
  export declare const motifFieldAttribute: (key: string) => string;
package/dist/motif.js CHANGED
@@ -9,19 +9,37 @@ const PRINTED_PAGE_TOTAL_PATH = `${PRINTED_PAGE_CONTEXT}.total`;
9
9
  const PRINTED_PAGE_FOLIO_PATH = `${PRINTED_PAGE_CONTEXT}.folio`;
10
10
  const PRINTED_PAGE_RUNNING_HEAD_PATH = `${PRINTED_PAGE_CONTEXT}.runningHead`;
11
11
  const LIBRARY_MOTIF_PREFIX = "segnavia:";
12
- const BOOK_FURNITURE = [{
13
- key: "segnavia:folio",
14
- path: PRINTED_PAGE_FOLIO_PATH,
15
- value: "folio",
16
- className: "segnavia-folio",
17
- region: "foot"
18
- }, {
19
- key: "segnavia:running-head",
20
- path: PRINTED_PAGE_RUNNING_HEAD_PATH,
21
- value: "runningHead",
22
- className: "segnavia-running-head",
23
- region: "head"
24
- }];
12
+ const BOOK_FURNITURE = [
13
+ {
14
+ key: "segnavia:folio",
15
+ path: PRINTED_PAGE_FOLIO_PATH,
16
+ value: "folio",
17
+ className: "segnavia-folio",
18
+ region: "foot",
19
+ fields: []
20
+ },
21
+ {
22
+ key: "segnavia:running-head",
23
+ path: PRINTED_PAGE_RUNNING_HEAD_PATH,
24
+ value: "runningHead",
25
+ className: "segnavia-running-head",
26
+ region: "head",
27
+ fields: []
28
+ },
29
+ {
30
+ key: "segnavia:mark",
31
+ className: "segnavia-mark",
32
+ region: "head",
33
+ fields: [{
34
+ key: "name",
35
+ required: true
36
+ }, {
37
+ key: "which",
38
+ choices: ["first", "last"],
39
+ default: "first"
40
+ }]
41
+ }
42
+ ];
25
43
  const motifFieldAttribute = (key) => `${MOTIF_ATTRIBUTE}-${key}`;
26
44
  const uniqueChoices = (field, ctx) => {
27
45
  if (field.choices && new Set(field.choices).size !== field.choices.length) ctx.addIssue({
@@ -99,6 +99,13 @@ export interface ResolvedParentPage {
99
99
  foot: string;
100
100
  }
101
101
  export declare function resolveParentPages(parents: ParentPage[]): ResolvedParentPage[];
102
+ export declare function parentListIssues(parents: ParentPage[], options?: {
103
+ path?: (string | number)[];
104
+ known?: Iterable<string>;
105
+ }): Array<{
106
+ path: (string | number)[];
107
+ message: string;
108
+ }>;
102
109
  export declare function printedPagesIssues(value: PrintedPages): Array<{
103
110
  path: (string | number)[];
104
111
  message: string;
@@ -1,5 +1,5 @@
1
- import { NumberSystem } from "./numbering.js";
2
1
  import { BOOK_FURNITURE } from "./motif.js";
2
+ import { NumberSystem } from "./numbering.js";
3
3
  import { z } from "zod";
4
4
  //#region src/printed-pages.ts
5
5
  const PRINTED_PAGE_LIMIT = 500;
@@ -55,7 +55,7 @@ const BOOK_PARENT_NAMES = {
55
55
  blank: "segnavia:blank"
56
56
  };
57
57
  function furniture(region) {
58
- return BOOK_FURNITURE.filter((item) => item.region === region).map((item) => `<div class="${item.className}" data-motif="${item.key}"></div>`).join("");
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
59
  }
60
60
  function bookParentPages(margin) {
61
61
  const held = () => ({ ...margin });
@@ -110,56 +110,64 @@ function resolveParentPages(parents) {
110
110
  };
111
111
  return parents.map(resolve);
112
112
  }
113
- function printedPagesIssues(value) {
113
+ function parentListIssues(parents, options = {}) {
114
114
  const issues = [];
115
- const parents = /* @__PURE__ */ new Map();
116
- value.parents.forEach((parent, index) => {
117
- if (parents.has(parent.name)) issues.push({
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({
118
120
  path: [
119
- "parents",
121
+ ...root,
120
122
  index,
121
123
  "name"
122
124
  ],
123
125
  message: `parent page "${parent.name}" is duplicated; give every parent page a unique name to clear this refusal`
124
126
  });
125
- parents.set(parent.name, parent);
127
+ listed.set(parent.name, parent);
128
+ known.add(parent.name);
126
129
  });
127
- for (const [role, name] of Object.entries(value.rules)) {
128
- if (name === void 0) continue;
129
- if (!parents.has(name)) issues.push({
130
- path: ["rules", role],
131
- message: `${role} names unknown parent page "${name}"; add that parent page or name an existing one to clear this refusal`
132
- });
133
- }
134
- value.parents.forEach((parent, index) => {
135
- if (parent.basedOn && !parents.has(parent.basedOn)) issues.push({
130
+ parents.forEach((parent, index) => {
131
+ if (parent.basedOn && !known.has(parent.basedOn)) issues.push({
136
132
  path: [
137
- "parents",
133
+ ...root,
138
134
  index,
139
135
  "basedOn"
140
136
  ],
141
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`
142
138
  });
143
- const path = [];
139
+ const chain = [];
144
140
  let cursor = parent;
145
141
  while (cursor) {
146
- if (path.includes(cursor.name)) {
142
+ if (chain.includes(cursor.name)) {
147
143
  issues.push({
148
144
  path: [
149
- "parents",
145
+ ...root,
150
146
  index,
151
147
  "basedOn"
152
148
  ],
153
- message: `parent page inheritance has a cycle ${[...path, cursor.name].join(" -> ")}; remove a basedOn link to clear this refusal`
149
+ message: `parent page inheritance has a cycle ${[...chain, cursor.name].join(" -> ")}; remove a basedOn link to clear this refusal`
154
150
  });
155
151
  break;
156
152
  }
157
- path.push(cursor.name);
158
- cursor = cursor.basedOn ? parents.get(cursor.basedOn) : void 0;
153
+ chain.push(cursor.name);
154
+ cursor = cursor.basedOn ? listed.get(cursor.basedOn) : void 0;
159
155
  }
160
156
  });
161
157
  return issues;
162
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
+ }
163
171
  function pagePrintedPagesIssues(page) {
164
172
  if (!page.printedPages) return [];
165
173
  const issues = printedPagesIssues(page.printedPages).map((issue) => ({
@@ -185,4 +193,4 @@ function pagePrintedPagesIssues(page) {
185
193
  return issues;
186
194
  }
187
195
  //#endregion
188
- export { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, pagePrintedPagesIssues, printedPagesIssues, resolveParentPages };
196
+ export { BOOK_PARENT_NAMES, PRINTED_PAGE_LIMIT, PRINTED_PAGE_ROLES, ParentPage, ParentPageMargin, PrintedPageRules, PrintedPages, bookParentPages, pagePrintedPagesIssues, parentListIssues, printedPagesIssues, resolveParentPages };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segnavia/format",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {