@rse/specbook 1.2.3 → 1.2.4

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.
@@ -122,7 +122,7 @@ const templates = {
122
122
  "TocPanelEntries": textframe `
123
123
  <ul>
124
124
  {% for entry in Entries %}
125
- <li><a href="#{{ entry.id }}"><span class="entry"><span class="object-kind"{% if entry.info %} data-info="{{ entry.info }}" data-info-path="{{ entry.infopath }}"{% endif %}>{{ entry.kind }}:</span> <span class="object-name"{% if entry.spec %} data-info-spec="{{ entry.spec }}" data-info-path="{{ entry.specpath }}"{% endif %}>{{ entry.name }}</span></span></a>{{ entry.childs }}</li>
125
+ <li><a href="#{{ entry.id }}"><span class="entry"><span class="object-kind"{% if entry.info %} data-info="{{ entry.info }}" data-info-path="{{ entry.infopath }}"{% endif %}>{{ entry.kind }}:</span> <span class="object-name"{% if entry.spec %} data-info-spec="{{ entry.spec }}" data-info-path="{{ entry.specpath }}"{% endif %}>{{ entry.name }}</span></span></a>{{ entry.children }}</li>
126
126
  {% endfor %}
127
127
  </ul>
128
128
  `,
@@ -146,7 +146,7 @@ const templates = {
146
146
  {{ Object.diagram }}
147
147
  {{ Object.properties }}
148
148
  {{ Object.description }}
149
- {{ Object.childs }}
149
+ {{ Object.children }}
150
150
  </section>
151
151
  `,
152
152
  /* <Properties/> */
@@ -800,7 +800,7 @@ const collectInfo = (nodes, prefix, keys, info) => {
800
800
  }
801
801
  if (entry.d !== undefined || entry.p !== undefined)
802
802
  info[path] = entry;
803
- collectInfo(schema.childs ?? [], path, keys, info);
803
+ collectInfo(schema.children ?? [], path, keys, info);
804
804
  }
805
805
  };
806
806
  /* inject the description popup maps into their client-side script ("<"
@@ -888,7 +888,7 @@ const collectSpec = (objects, spec) => {
888
888
  .trim();
889
889
  if (text !== "")
890
890
  spec[anchorOf(object)] = scoped(object, () => block(text, true).toString().trim());
891
- collectSpec(object.childs, spec);
891
+ collectSpec(object.children, spec);
892
892
  }
893
893
  };
894
894
  /* the literal members of an "enum(...)"/"tags(...)" expression, or
@@ -913,7 +913,7 @@ const collectMembers = (nodes, result) => {
913
913
  /* an invalid expression is the concern of lint */
914
914
  }
915
915
  }
916
- collectMembers(schema.childs ?? [], result);
916
+ collectMembers(schema.children ?? [], result);
917
917
  }
918
918
  return result;
919
919
  };
@@ -976,20 +976,20 @@ const effectiveProperties = (object) => {
976
976
  order (unknown keys appended in occurrence order), with
977
977
  "withUnusedProps" injecting the defined but still unused schema
978
978
  properties as additional columns */
979
- const tableShape = (childs) => {
980
- const used = [...new Set(childs.flatMap((child) => child.properties.map((property) => property.key)))];
981
- const schema = schemas?.get(childs[0]);
979
+ const tableShape = (children) => {
980
+ const used = [...new Set(children.flatMap((child) => child.properties.map((property) => property.key)))];
981
+ const schema = schemas?.get(children[0]);
982
982
  const names = (schema?.props ?? []).map((prop) => prop.name);
983
983
  const known = schema?.format?.withUnusedProps === true ?
984
984
  names : names.filter((name) => used.includes(name));
985
985
  const keys = [...known, ...used.filter((key) => !names.includes(key))];
986
- return { keys, desc: childs.some((child) => child.description !== undefined || child.childs.length > 0) };
986
+ return { keys, desc: children.some((child) => child.description !== undefined || child.children.length > 0) };
987
987
  };
988
- /* provide the childs of an object taking part in the regular document
988
+ /* provide the children of an object taking part in the regular document
989
989
  flow: a nested title object leaves the flow, as it is rendered as the
990
990
  title page instead (a top-level one instead removes its whole artifact) */
991
- const flowChilds = (object) => object.childs.filter((child) => !isTitleObject(child));
992
- /* decide whether a single-kind group of childs collapses into the
991
+ const flowChildren = (object) => object.children.filter((child) => !isTitleObject(child));
992
+ /* decide whether a single-kind group of children collapses into the
993
993
  concise (tabular) rendering: an explicit "format" type of the kind
994
994
  wins, "auto" collapses the deepest level only, and inside an already
995
995
  concise rendering context "auto" groups implicitly stay concise, too */
@@ -997,12 +997,12 @@ const conciseGroup = (group, schemaMap, concise) => {
997
997
  const type = schemaMap?.get(group[0])?.format?.type ?? "auto";
998
998
  if (type !== "auto")
999
999
  return type === "concise";
1000
- return concise || group.every((child) => child.childs.length === 0);
1000
+ return concise || group.every((child) => child.children.length === 0);
1001
1001
  };
1002
- /* group the childs of an object by their kind, preserving order */
1003
- const groupChilds = (childs) => {
1002
+ /* group the children of an object by their kind, preserving order */
1003
+ const groupChildren = (children) => {
1004
1004
  const groups = new Map();
1005
- for (const child of childs) {
1005
+ for (const child of children) {
1006
1006
  const group = groups.get(child.kind);
1007
1007
  if (group === undefined)
1008
1008
  groups.set(child.kind, [child]);
@@ -1011,21 +1011,21 @@ const groupChilds = (childs) => {
1011
1011
  }
1012
1012
  return [...groups.values()];
1013
1013
  };
1014
- /* render the childs of an object group-wise by kind: a concise group
1014
+ /* render the children of an object group-wise by kind: a concise group
1015
1015
  as one compact table, a complex group as regular nested object
1016
1016
  renderings */
1017
- const renderChilds = (object, level, concise) => groupChilds(flowChilds(object)).map((group) => conciseGroup(group, schemas, concise) ?
1017
+ const renderChildren = (object, level, concise) => groupChildren(flowChildren(object)).map((group) => conciseGroup(group, schemas, concise) ?
1018
1018
  renderTable(group, maxColumnsOf(group[0])) :
1019
1019
  group.map((child) => renderObject(child, level, concise)).join("")).join("");
1020
1020
  /* render the description cell of a table row: the description of the
1021
- object followed by its recursively rendered childs (implicitly or
1021
+ object followed by its recursively rendered children (implicitly or
1022
1022
  explicitly concise groups as nested sub-tables, explicitly complex
1023
1023
  ones as regular nested object renderings pressed into the cell);
1024
1024
  a cell left without any content renders as the absent marker,
1025
1025
  exactly like a property cell of a not given property */
1026
1026
  const renderCell = (child) => {
1027
1027
  let html = child.description !== undefined ? renderDescription(child.description) : "";
1028
- html += renderChilds(child, 6, true);
1028
+ html += renderChildren(child, 6, true);
1029
1029
  return html.trim() !== "" ? html : "<span class=\"value-absent\"></span>";
1030
1030
  };
1031
1031
  /* the pre-rendered diagram of an object as an embeddable block
@@ -1034,27 +1034,27 @@ const diagramOf = (object) => {
1034
1034
  const diagram = diagrams?.get(object);
1035
1035
  return diagram !== undefined ? safe(`<div class="diagram">${diagram}</div>`) : "";
1036
1036
  };
1037
- /* render a single-kind group of childs into one compact table:
1037
+ /* render a single-kind group of children into one compact table:
1038
1038
  the name first, then the property columns, then the description;
1039
1039
  a group wider than maxColumns, or carrying diagrams, instead chunks
1040
1040
  the property and description cells (and the leading diagram) of
1041
1041
  every object into an embedded per-object table, as a diagram is
1042
1042
  identifiable only under a header of its own, not under the column
1043
1043
  headers of a plain table */
1044
- const renderTable = (childs, maxColumns) => {
1045
- const { keys, desc } = tableShape(childs);
1046
- const diagrammed = childs.some((child) => diagramOf(child) !== "");
1044
+ const renderTable = (children, maxColumns) => {
1045
+ const { keys, desc } = tableShape(children);
1046
+ const diagrammed = children.some((child) => diagramOf(child) !== "");
1047
1047
  if (!diagrammed && 1 + keys.length + (desc ? 1 : 0) <= maxColumns)
1048
1048
  return render("Table", { Table: {
1049
- head: childs[0].kind !== "" ? childs[0].kind : "Name",
1050
- info: infoKeyOf(childs[0]),
1051
- infopath: infoPathOf(childs[0], false),
1049
+ head: children[0].kind !== "" ? children[0].kind : "Name",
1050
+ info: infoKeyOf(children[0]),
1051
+ infopath: infoPathOf(children[0], false),
1052
1052
  keys,
1053
1053
  desc,
1054
1054
  /* under the fixed table layout the description column claims
1055
1055
  twice the share of a regular column, compressing the others */
1056
1056
  width: Math.round(200 / (keys.length + 3)),
1057
- rows: childs.map((child, i) => scoped(child, () => ({
1057
+ rows: children.map((child, i) => scoped(child, () => ({
1058
1058
  id: anchorOf(child),
1059
1059
  paren: child.paren,
1060
1060
  primary: child.primary,
@@ -1071,11 +1071,11 @@ const renderTable = (childs, maxColumns) => {
1071
1071
  with the last cell spanning the leftover columns of the final row */
1072
1072
  const size = Math.max(1, maxColumns - 1);
1073
1073
  return render("TableChunked", { Table: {
1074
- head: childs[0].kind !== "" ? childs[0].kind : "Name",
1075
- info: infoKeyOf(childs[0]),
1076
- infopath: infoPathOf(childs[0], false),
1074
+ head: children[0].kind !== "" ? children[0].kind : "Name",
1075
+ info: infoKeyOf(children[0]),
1076
+ infopath: infoPathOf(children[0], false),
1077
1077
  width: Math.round(100 / maxColumns),
1078
- rows: childs.map((child, i) => scoped(child, () => {
1078
+ rows: children.map((child, i) => scoped(child, () => {
1079
1079
  const cells = keys.map((key) => ({ key, desc: false, span: 1,
1080
1080
  value: inlineValue(child.kind, child.properties.find((property) => property.key === key)) }));
1081
1081
  if (desc)
@@ -1125,7 +1125,7 @@ const renderObject = (object, level, concise) => {
1125
1125
  safe(render("Properties", { Properties: inlineProperties(object, properties) })) : "",
1126
1126
  description: object.description !== undefined ?
1127
1127
  safe(renderDescription(object.description)) : "",
1128
- childs: safe(renderChilds(object, level + 1, concise))
1128
+ children: safe(renderChildren(object, level + 1, concise))
1129
1129
  } }));
1130
1130
  };
1131
1131
  /* format a timestamp as its calendar date in local time (the
@@ -1167,10 +1167,10 @@ const renderTitlePage = (object, created, modified) => {
1167
1167
  const renderArtifact = (artifact) => render("Artifact", { Artifact: {
1168
1168
  objects: safe(artifact.objects.map((object) => renderObject(object, 1, false)).join(""))
1169
1169
  } });
1170
- /* provide the childs of an object rendered with headings of their own
1170
+ /* provide the children of an object rendered with headings of their own
1171
1171
  (skipping the child groups collapsing into compact tables), which
1172
1172
  are the ones taking part in the table of contents and its side panel */
1173
- const headingChilds = (object) => groupChilds(flowChilds(object))
1173
+ const headingChildren = (object) => groupChildren(flowChildren(object))
1174
1174
  .filter((group) => !conciseGroup(group, schemas, false))
1175
1175
  .flat();
1176
1176
  /* flatten the hierarchy of the rendered object headings (exactly like
@@ -1185,7 +1185,7 @@ const tocEntries = (objects, pages) => {
1185
1185
  info: infoKeyOf(object), infopath: infoPathOf(object, false),
1186
1186
  spec: infoParents !== null ? id : undefined, specpath: infoPathOf(object),
1187
1187
  name: inline(object.name), level: Math.min(level, 6), page: pages?.get(id) });
1188
- collect(headingChilds(object), level + 1);
1188
+ collect(headingChildren(object), level + 1);
1189
1189
  }
1190
1190
  };
1191
1191
  collect(objects, 1);
@@ -1205,7 +1205,7 @@ const renderTocPanel = (objects, title, doc) => {
1205
1205
  spec: infoParents !== null ? anchorOf(object) : undefined,
1206
1206
  specpath: infoPathOf(object),
1207
1207
  name: inline(object.name),
1208
- childs: safe(entries(headingChilds(object)))
1208
+ children: safe(entries(headingChildren(object)))
1209
1209
  })) });
1210
1210
  return render("TocPanel", { TocPanel: { title, doc, entries: safe(entries(objects)) } });
1211
1211
  };
@@ -1217,7 +1217,7 @@ export const htmlOutline = (specification, config) => {
1217
1217
  const entry = (object) => ({
1218
1218
  title: (object.kind !== "" ? `${object.kind}: ` : "") + plainText(object.name),
1219
1219
  anchor: paths.get(object) ?? object.id,
1220
- childs: groupChilds(flowChilds(object))
1220
+ children: groupChildren(flowChildren(object))
1221
1221
  .filter((group) => !conciseGroup(group, schemaMap, false))
1222
1222
  .flatMap((group) => group.map(entry))
1223
1223
  });
@@ -39,11 +39,11 @@ const nameSuffixMd = (object) => (object.primary === true ? " (*)" : "") +
39
39
  code block, an ordered list, a blockquote, or multiple paragraphs) or
40
40
  one carrying a ";", as only a ";"-free description stays a single
41
41
  segment on re-parsing instead of splitting off a spurious property */
42
- const complexBelowMd = (object) => object.childs.some((child) => child.name.includes(";")
42
+ const complexBelowMd = (object) => object.children.some((child) => child.name.includes(";")
43
43
  || (child.description !== undefined
44
44
  && /[\n;]/.test(renderDescriptionMd(child.description))) || complexBelowMd(child));
45
45
  /* render an object in the Concise Format as a list item of the
46
- given nesting depth, with its childs as nested list items */
46
+ given nesting depth, with its children as nested list items */
47
47
  const renderConciseMd = (object, depth = 0) => {
48
48
  const indent = " ".repeat(depth * 4);
49
49
  const segments = [`${object.kind}: ${object.name}${nameSuffixMd(object)}`];
@@ -62,14 +62,14 @@ const renderConciseMd = (object, depth = 0) => {
62
62
  `${indent}- ${segments.join("; ").replace(/\.?$/, ".")}` :
63
63
  `${indent}- ${segments.join("; ")};`;
64
64
  return [item, renderKeyValuesMd(wrapped, `${indent} `),
65
- ...object.childs.map((child) => renderConciseMd(child, depth + 1))]
65
+ ...object.children.map((child) => renderConciseMd(child, depth + 1))]
66
66
  .filter((part) => part !== "").join("\n");
67
67
  };
68
- /* render an object in the Complex Format (levels 1-3), with childs from
68
+ /* render an object in the Complex Format (levels 1-3), with children from
69
69
  level 4 upwards in the Concise Format -- unless a descendant carries
70
- a description no concise item can carry, so all childs (as siblings
70
+ a description no concise item can carry, so all children (as siblings
71
71
  have to share the format) stay in the Complex Format down to heading
72
- level 6, the deepest one Markdown knows, below which the childs are
72
+ level 6, the deepest one Markdown knows, below which the children are
73
73
  concise regardless -- and the optionally derived Gradia diagram spec
74
74
  embedded as a "gradia" fenced code block below the heading */
75
75
  const renderObjectMd = (object, level, diagrams) => {
@@ -83,12 +83,12 @@ const renderObjectMd = (object, level, diagrams) => {
83
83
  parts.push(renderKeyValuesMd(object.properties));
84
84
  if (object.description !== undefined)
85
85
  parts.push(renderDescriptionMd(object.description));
86
- /* the childs share one format, as a concise item following
86
+ /* the children share one format, as a concise item following
87
87
  a heading would attach to the heading's object instead */
88
88
  if (level >= 6 || (level >= 3 && !complexBelowMd(object)))
89
- parts.push(object.childs.map((child) => renderConciseMd(child)).join("\n"));
89
+ parts.push(object.children.map((child) => renderConciseMd(child)).join("\n"));
90
90
  else
91
- parts.push(...object.childs.map((child) => renderObjectMd(child, level + 1, diagrams)));
91
+ parts.push(...object.children.map((child) => renderObjectMd(child, level + 1, diagrams)));
92
92
  return parts.filter((part) => part !== "").join("\n\n");
93
93
  };
94
94
  /* render the entire specification into normalized Markdown */
@@ -28,7 +28,7 @@ const anchorPages = async (pdf) => {
28
28
  };
29
29
  /* attach a hierarchical PDF outline (the "bookmarks" of the viewer
30
30
  side-bar) to a document, resolving the entry anchors against the
31
- named destinations and hoisting the childs of an unresolvable entry */
31
+ named destinations and hoisting the children of an unresolvable entry */
32
32
  const addOutline = async (doc, entries) => {
33
33
  const { PDFName, PDFDict, PDFArray, PDFRef, PDFHexString } = await import("pdf-lib");
34
34
  const context = doc.context;
@@ -48,8 +48,8 @@ const addOutline = async (doc, entries) => {
48
48
  }
49
49
  const resolve = (entries) => entries.flatMap((entry) => {
50
50
  const dest = targets.get(entry.anchor);
51
- const childs = resolve(entry.childs);
52
- return dest !== undefined ? [{ title: entry.title, dest, childs }] : childs;
51
+ const children = resolve(entry.children);
52
+ return dest !== undefined ? [{ title: entry.title, dest, children }] : children;
53
53
  });
54
54
  const items = resolve(entries);
55
55
  if (items.length === 0)
@@ -59,16 +59,16 @@ const addOutline = async (doc, entries) => {
59
59
  const materialize = (items, parent) => {
60
60
  const refs = items.map(() => context.nextRef());
61
61
  items.forEach((item, i) => {
62
- const childs = item.childs.length > 0 ? materialize(item.childs, refs[i]) : undefined;
62
+ const children = item.children.length > 0 ? materialize(item.children, refs[i]) : undefined;
63
63
  context.assign(refs[i], context.obj({
64
64
  Title: PDFHexString.fromText(item.title),
65
65
  Parent: parent,
66
66
  Prev: i > 0 ? refs[i - 1] : undefined,
67
67
  Next: i < refs.length - 1 ? refs[i + 1] : undefined,
68
- First: childs?.first,
69
- Last: childs?.last,
68
+ First: children?.first,
69
+ Last: children?.last,
70
70
  /* a negative count keeps the sub-tree initially collapsed */
71
- Count: childs !== undefined ? -item.childs.length : undefined,
71
+ Count: children !== undefined ? -item.children.length : undefined,
72
72
  Dest: item.dest
73
73
  }));
74
74
  });
@@ -14,7 +14,7 @@ export type SchemaObject = {
14
14
  diagram?: SchemaDiagram;
15
15
  format?: SchemaFormat;
16
16
  props?: SchemaProperty[];
17
- childs?: SchemaObject[];
17
+ children?: SchemaObject[];
18
18
  };
19
19
  export type SchemaAutomaton = {
20
20
  nodes: string;
@@ -17,7 +17,7 @@ const GradiaConfigSchemas = Object.fromEntries(Object.entries(Gradia.config).map
17
17
  const SchemaDiagramConfig = v.partial(v.strictObject(GradiaConfigSchemas, (issue) => issue.expected === "never" ? "unknown Gradia rendering option" :
18
18
  "expected a map of Gradia rendering options"));
19
19
  /* the Valibot schemas mirroring the types above, with the object
20
- kind schema referencing itself lazily for the nested childs */
20
+ kind schema referencing itself lazily for the nested children */
21
21
  const SchemaProperty = v.strictObject({
22
22
  name: v.string(),
23
23
  desc: v.optional(v.string()),
@@ -87,6 +87,6 @@ const SchemaObject = v.strictObject({
87
87
  diagram: v.optional(SchemaDiagram),
88
88
  format: v.optional(SchemaFormat),
89
89
  props: v.optional(v.array(SchemaProperty)),
90
- childs: v.optional(v.array(v.lazy(() => SchemaObject)))
90
+ children: v.optional(v.array(v.lazy(() => SchemaObject)))
91
91
  });
92
92
  export const Schema = v.pipe(v.array(SchemaObject), v.minLength(1));
@@ -16,7 +16,7 @@ export type SpecObject = {
16
16
  primary?: boolean;
17
17
  description?: SpecDescription;
18
18
  properties: SpecProperty[];
19
- childs: SpecObject[];
19
+ children: SpecObject[];
20
20
  };
21
21
  export type SpecDescription = {
22
22
  description: string;
@@ -6,7 +6,7 @@
6
6
  import * as v from "valibot";
7
7
  /* ==== Schema ==== */
8
8
  /* the Valibot schemas mirroring the types above, with the object
9
- schema referencing itself lazily for the nested childs */
9
+ schema referencing itself lazily for the nested children */
10
10
  const SpecProperty = v.object({
11
11
  key: v.string(),
12
12
  value: v.string(),
@@ -26,7 +26,7 @@ const SpecObject = v.object({
26
26
  primary: v.optional(v.boolean()),
27
27
  description: v.optional(SpecDescription),
28
28
  properties: v.array(SpecProperty),
29
- childs: v.array(v.lazy(() => SpecObject))
29
+ children: v.array(v.lazy(() => SpecObject))
30
30
  });
31
31
  const SpecArtifact = v.object({
32
32
  created: v.date(),
@@ -78,7 +78,7 @@ type SchemaObject = {
78
78
  diagram?: SchemaDiagram
79
79
  format?: SchemaFormat
80
80
  props?: SchemaProperty[]
81
- childs?: SchemaObject[]
81
+ children?: SchemaObject[]
82
82
  }
83
83
  type SchemaAutomaton = {
84
84
  nodes: string
@@ -251,7 +251,7 @@ type SchemaGradiaConfig = Partial<{
251
251
  properties allowed on objects of this kind,
252
252
  BECAUSE they carry the structured, machine-checkable content
253
253
 
254
- - `SchemaObject.childs?: SchemaObject[]`:
254
+ - `SchemaObject.children?: SchemaObject[]`:
255
255
  object kinds allowed one level below this object (RECURSION),
256
256
  BECAUSE the nesting defines and bounds the document structure
257
257
 
@@ -579,7 +579,7 @@ type SpecObject = {
579
579
  primary?: boolean
580
580
  description?: SpecDescription
581
581
  properties: SpecProperty[]
582
- childs: SpecObject[]
582
+ children: SpecObject[]
583
583
  }
584
584
  type SpecDescription = {
585
585
  description: string
@@ -653,7 +653,7 @@ type SpecProperty = {
653
653
  key/value properties of the object, in canonical order,
654
654
  BECAUSE properties carry the structured, machine-checkable content
655
655
 
656
- - `SpecObject.childs: SpecObject[]`:
656
+ - `SpecObject.children: SpecObject[]`:
657
657
  child objects nested one level below this object (RECURSION),
658
658
  BECAUSE a specification is a tree, not a flat list of statements
659
659