@rse/specbook 1.5.2 → 1.6.1
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/LICENSE.txt +201 -0
- package/README.md +288 -43
- package/dst/specbook-api.d.ts +23 -3
- package/dst/specbook-api.js +133 -59
- package/dst/specbook-cli.js +93 -26
- package/dst/specbook-cmd-describe.js +4 -4
- package/dst/specbook-cmd-export-schema.d.ts +8 -0
- package/dst/specbook-cmd-export-schema.js +441 -0
- package/dst/specbook-cmd-export.js +23 -6
- package/dst/specbook-cmd-init-sample.d.ts +4 -0
- package/dst/specbook-cmd-init-sample.js +322 -0
- package/dst/specbook-cmd-init.d.ts +1 -0
- package/dst/specbook-cmd-init.js +42 -10
- package/dst/specbook-cmd-lint.js +46 -48
- package/dst/specbook-cmd-query.d.ts +30 -0
- package/dst/specbook-cmd-query.js +165 -0
- package/dst/specbook-config.d.ts +9 -1
- package/dst/specbook-config.js +135 -10
- package/dst/specbook-coverage.js +2 -2
- package/dst/specbook-diagram.d.ts +7 -5
- package/dst/specbook-diagram.js +546 -143
- package/dst/specbook-export-ast.d.ts +1 -1
- package/dst/specbook-export-ast.js +11 -8
- package/dst/specbook-export-code.js +3 -3
- package/dst/specbook-export-common.d.ts +1 -1
- package/dst/specbook-export-common.js +3 -2
- package/dst/specbook-export-diagram.d.ts +1 -1
- package/dst/specbook-export-diagram.js +25 -7
- package/dst/specbook-export-html-fold.d.ts +16 -6
- package/dst/specbook-export-html-fold.js +65 -44
- package/dst/specbook-export-html-render.js +107 -26
- package/dst/specbook-export-html-search.js +18 -20
- package/dst/specbook-export-html-template.js +38 -9
- package/dst/specbook-export-html-widget.d.ts +2 -0
- package/dst/specbook-export-html-widget.js +219 -19
- package/dst/specbook-export-html.css +208 -38
- package/dst/specbook-export-html.js +96 -53
- package/dst/specbook-export-md.d.ts +2 -1
- package/dst/specbook-export-md.js +7 -8
- package/dst/specbook-export-pdf.js +1 -1
- package/dst/specbook-files.d.ts +2 -0
- package/dst/specbook-files.js +41 -0
- package/dst/specbook-format-meta.yaml +401 -0
- package/dst/specbook-format-pm.yaml +1240 -0
- package/dst/specbook-format-schema.d.ts +33 -3
- package/dst/specbook-format-schema.js +49 -3
- package/dst/specbook-format.md +427 -47
- package/dst/specbook-format.yaml +524 -228
- package/dst/specbook-ignore.js +2 -2
- package/dst/specbook-link.d.ts +4 -0
- package/dst/specbook-link.js +61 -6
- package/dst/specbook-mcp.js +103 -19
- package/dst/specbook-parse-semantic.d.ts +1 -0
- package/dst/specbook-parse-semantic.js +11 -4
- package/dst/specbook-parse-syntax.d.ts +1 -0
- package/dst/specbook-parse-syntax.js +1 -1
- package/dst/specbook-parse.d.ts +1 -1
- package/dst/specbook-parse.js +3 -3
- package/dst/specbook-project.d.ts +2 -0
- package/dst/specbook-project.js +15 -5
- package/dst/specbook-remote.d.ts +28 -0
- package/dst/specbook-remote.js +429 -0
- package/package.json +32 -20
package/dst/specbook-format.md
CHANGED
|
@@ -76,11 +76,26 @@ type SchemaObject = {
|
|
|
76
76
|
referenced?: string[]
|
|
77
77
|
coverage?: string[]
|
|
78
78
|
automaton?: SchemaAutomaton
|
|
79
|
-
|
|
79
|
+
badge?: SchemaBadge
|
|
80
|
+
multiple?: SchemaMultiple
|
|
81
|
+
diagram?: SchemaDiagram | SchemaDiagram[]
|
|
80
82
|
format?: SchemaFormat
|
|
81
83
|
props?: SchemaProperty[]
|
|
82
84
|
children?: SchemaObject[]
|
|
83
85
|
}
|
|
86
|
+
type SchemaBadge = BadgeIcon | {
|
|
87
|
+
property: string
|
|
88
|
+
map: Record<string, BadgeIcon>
|
|
89
|
+
default?: BadgeIcon
|
|
90
|
+
}
|
|
91
|
+
type SchemaMultiple = {
|
|
92
|
+
property: string
|
|
93
|
+
pattern: string
|
|
94
|
+
}
|
|
95
|
+
type BadgeIcon =
|
|
96
|
+
"person" | "team" | "bot" | "device" | "mobile" | "browser" | "service" |
|
|
97
|
+
"function" | "api" | "code" | "package" | "database" | "cache" | "queue" |
|
|
98
|
+
"document" | "mail" | "communication" | "clock" | "security" | "cloud" | "network"
|
|
84
99
|
type SchemaAutomaton = {
|
|
85
100
|
nodes: string
|
|
86
101
|
edges: string
|
|
@@ -103,24 +118,48 @@ type SchemaDiagramCenterEdges = {
|
|
|
103
118
|
labeled?: string
|
|
104
119
|
via?: string
|
|
105
120
|
}
|
|
121
|
+
type SchemaDiagramNest = {
|
|
122
|
+
properties?: string[]
|
|
123
|
+
parent?: boolean
|
|
124
|
+
kind?: boolean
|
|
125
|
+
layout?: "graph" | "hub" | "grid"
|
|
126
|
+
crossing?: "nodes" | "target" | "both"
|
|
127
|
+
}
|
|
106
128
|
type SchemaDiagram = {
|
|
107
|
-
type?: "graph" | "hub" | "grid"
|
|
129
|
+
type?: "graph" | "hub" | "grid" | "state" | "layer" |
|
|
130
|
+
"slice" | "tree" | "matrix" | "sequence" | "petri" |
|
|
131
|
+
"gantt"
|
|
108
132
|
nodes?: string
|
|
109
133
|
edges?: string
|
|
134
|
+
local?: boolean
|
|
110
135
|
center?: string | SchemaDiagramCenter
|
|
111
136
|
centerEdges?: SchemaDiagramCenterEdges
|
|
112
|
-
links?: "props" | "all"
|
|
137
|
+
links?: "props" | "all" | string[]
|
|
113
138
|
labeled?: boolean
|
|
114
139
|
edgeSource?: string
|
|
115
140
|
edgeTarget?: string
|
|
116
141
|
edgeArity?: string
|
|
142
|
+
edgeGuard?: string
|
|
143
|
+
edgeKind?: string
|
|
144
|
+
edgeDuration?: string
|
|
145
|
+
edgeTime?: string
|
|
146
|
+
places?: string
|
|
147
|
+
tokens?: string
|
|
148
|
+
capacity?: string
|
|
149
|
+
duration?: string
|
|
150
|
+
start?: string
|
|
117
151
|
hierarchy?: boolean
|
|
118
152
|
deep?: boolean
|
|
153
|
+
descend?: string[]
|
|
154
|
+
reverse?: string[]
|
|
119
155
|
onlyConnected?: boolean
|
|
120
156
|
collapse?: boolean
|
|
121
157
|
qualified?: boolean
|
|
158
|
+
ordered?: boolean
|
|
159
|
+
markUncovered?: "none" | "referenced" | "coverage" | "all"
|
|
160
|
+
nest?: SchemaDiagramNest
|
|
122
161
|
properties?: string[]
|
|
123
|
-
config?:
|
|
162
|
+
config?: SchemaGradiaConfig
|
|
124
163
|
}
|
|
125
164
|
type SchemaFormat = {
|
|
126
165
|
type?: "auto" | "complex" | "compact" | "concise"
|
|
@@ -154,13 +193,31 @@ type SchemaGradiaConfig = Partial<{
|
|
|
154
193
|
"color-node-self-name": string
|
|
155
194
|
"color-node-self-box": string
|
|
156
195
|
"color-node-self-border": string
|
|
196
|
+
"color-node-lifeline": string
|
|
157
197
|
"color-group-name": string
|
|
158
198
|
"color-group-box": string
|
|
159
199
|
"color-group-border": string
|
|
200
|
+
"color-container-name": string
|
|
201
|
+
"color-container-box": string
|
|
202
|
+
"color-container-border": string
|
|
203
|
+
"color-composite-border": string
|
|
204
|
+
"color-node-pseudo-name": string
|
|
205
|
+
"color-node-pseudo-box": string
|
|
206
|
+
"color-node-pseudo-border": string
|
|
207
|
+
"color-node-place-name": string
|
|
208
|
+
"color-node-place-box": string
|
|
209
|
+
"color-node-place-border": string
|
|
160
210
|
"color-edge-line": string
|
|
161
211
|
"color-edge-name": string
|
|
162
212
|
"color-edge-arity": string
|
|
163
213
|
"color-edge-halo": string
|
|
214
|
+
"color-mark-violation": string
|
|
215
|
+
"color-mark-critical": string
|
|
216
|
+
"size-font-node": number
|
|
217
|
+
"size-font-type": number
|
|
218
|
+
"size-font-prop": number
|
|
219
|
+
"size-font-edge": number
|
|
220
|
+
"size-font-arity": number
|
|
164
221
|
"size-canvas-margin": number
|
|
165
222
|
"size-node-width-min": number
|
|
166
223
|
"size-node-width-max": number
|
|
@@ -171,6 +228,7 @@ type SchemaGradiaConfig = Partial<{
|
|
|
171
228
|
"size-edge-port-gap": number
|
|
172
229
|
"group-box-padding": number
|
|
173
230
|
"group-box-gap": number
|
|
231
|
+
"container-box-padding": number
|
|
174
232
|
"graph-columns-max": number
|
|
175
233
|
"graph-channel-width-max": number
|
|
176
234
|
"graph-channel-width-min": number
|
|
@@ -183,12 +241,28 @@ type SchemaGradiaConfig = Partial<{
|
|
|
183
241
|
"hub-channel-width-min": number
|
|
184
242
|
"hub-node-gap": number
|
|
185
243
|
"hub-node-degree-max": number
|
|
244
|
+
"hub-node-count-max": number
|
|
186
245
|
"grid-columns-max": number
|
|
187
246
|
"grid-columns-min": number
|
|
188
247
|
"grid-gap-horizontal": number
|
|
189
248
|
"grid-gap-vertical": number
|
|
190
249
|
"grid-node-width-equal": boolean
|
|
191
250
|
"grid-node-height-equal": boolean
|
|
251
|
+
"sequence-column-gap": number
|
|
252
|
+
"sequence-message-gap": number
|
|
253
|
+
"tree-level-gap": number
|
|
254
|
+
"tree-sibling-gap": number
|
|
255
|
+
"tree-row-max": number
|
|
256
|
+
"tree-stack-min": number
|
|
257
|
+
"tree-stack-double": boolean
|
|
258
|
+
"tree-node-width-equal": boolean
|
|
259
|
+
"tree-horizontal": boolean
|
|
260
|
+
"gantt-unit-width": number
|
|
261
|
+
"gantt-unit-name": string
|
|
262
|
+
"gantt-critical": boolean
|
|
263
|
+
"mark-violation": boolean
|
|
264
|
+
"layer-numbered": boolean
|
|
265
|
+
"slice-numbered": boolean
|
|
192
266
|
}>
|
|
193
267
|
```
|
|
194
268
|
|
|
@@ -206,17 +280,22 @@ type SchemaGradiaConfig = Partial<{
|
|
|
206
280
|
BECAUSE it discriminates objects and anchors `[[xxx]]` references
|
|
207
281
|
|
|
208
282
|
- `SchemaObject.name?: string`:
|
|
209
|
-
exact artifact name (level 1) or name regex (deeper levels),
|
|
210
|
-
|
|
283
|
+
exact artifact name (level 1) or name regex (deeper levels), where a
|
|
284
|
+
level 1 object kind with neither `name` nor `id` is a *recurring*
|
|
285
|
+
artifact, which any number (also none) of level 1 objects of its
|
|
286
|
+
kind match, all in its `file`,
|
|
287
|
+
BECAUSE artifacts are fixed documents, deeper names need a rule only,
|
|
288
|
+
while a catalog of equally shaped artifacts knows no fixed names
|
|
211
289
|
|
|
212
290
|
- `SchemaObject.id?: string`:
|
|
213
291
|
short locally-unique identifier the object explicitly carries in its heading,
|
|
214
292
|
BECAUSE stable ids keep `[[xxx]]` references free of prose names
|
|
215
293
|
|
|
216
294
|
- `SchemaObject.file?: string`:
|
|
217
|
-
Markdown file the level 1 artifact is generated into
|
|
295
|
+
Markdown file the level 1 artifact is generated into (by `init`),
|
|
218
296
|
optionally shared with the other artifacts carrying the same file,
|
|
219
|
-
BECAUSE artifacts must map deterministically onto files
|
|
297
|
+
BECAUSE artifacts must map deterministically onto files when created,
|
|
298
|
+
while every `.md` file below the base directory is parsed afterwards
|
|
220
299
|
|
|
221
300
|
- `SchemaObject.desc?: string`:
|
|
222
301
|
prose description of the object kind,
|
|
@@ -253,10 +332,38 @@ type SchemaGradiaConfig = Partial<{
|
|
|
253
332
|
BECAUSE a lifecycle is only trustworthy when its dead-ends and
|
|
254
333
|
livelocks are ruled out
|
|
255
334
|
|
|
256
|
-
- `SchemaObject.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
335
|
+
- `SchemaObject.badge?: SchemaBadge`:
|
|
336
|
+
badge icon drawn inside the node box of every object of this kind in
|
|
337
|
+
every diagram (left out when the configuration is emitted compressed
|
|
338
|
+
by level 2 or higher),
|
|
339
|
+
BECAUSE the nature of a node is recognized at a glance from an icon,
|
|
340
|
+
while its type label has to be read
|
|
341
|
+
|
|
342
|
+
- `SchemaBadge`:
|
|
343
|
+
a fixed icon, or the icon the value of the `property` of an object
|
|
344
|
+
maps onto through `map` (a mapped value of an `enum(...)` valued
|
|
345
|
+
property has to be one of its members), else the `default` icon,
|
|
346
|
+
else none,
|
|
347
|
+
BECAUSE the kind alone does not always tell the nature of an object
|
|
348
|
+
-- a `Server` node and a `Function` node deserve different icons
|
|
349
|
+
|
|
350
|
+
- `SchemaObject.multiple?: SchemaMultiple`:
|
|
351
|
+
the several instances an object of this kind stands for, drawn as a
|
|
352
|
+
stack of node boxes in every diagram: whenever the value of the
|
|
353
|
+
`property` matches the (unanchored) regular expression `pattern`,
|
|
354
|
+
e.g. `0..n per environment` matched by a pattern for a range with an
|
|
355
|
+
upper bound beyond 1 (left out when the configuration is emitted
|
|
356
|
+
compressed by level 2 or higher),
|
|
357
|
+
BECAUSE a replicated node is a different operational beast than a
|
|
358
|
+
single one, yet both are specified by one object
|
|
359
|
+
|
|
360
|
+
- `SchemaObject.diagram?: SchemaDiagram | SchemaDiagram[]`:
|
|
361
|
+
diagram, or list of diagrams (rendered in their order), generated for
|
|
362
|
+
every object of this kind (left out when the configuration is emitted
|
|
363
|
+
compressed by level 2 or higher), where merged configuration files
|
|
364
|
+
match the diagrams of a list by their `type`,
|
|
365
|
+
BECAUSE relations buried in references are graspable only when drawn,
|
|
366
|
+
and the same relations often tell more than one story
|
|
260
367
|
|
|
261
368
|
- `SchemaObject.format?: SchemaFormat`:
|
|
262
369
|
HTML/PDF rendering format of the objects of this kind (left out when
|
|
@@ -308,8 +415,19 @@ type SchemaGradiaConfig = Partial<{
|
|
|
308
415
|
diagram derived for every object of an object kind,
|
|
309
416
|
BECAUSE the relations of a specification are graspable only when drawn
|
|
310
417
|
|
|
311
|
-
- `SchemaDiagram.type?: "graph" | "hub" | "grid"
|
|
418
|
+
- `SchemaDiagram.type?: "graph" | "hub" | "grid" | "state" | "layer" |
|
|
419
|
+
"slice" | "tree" | "matrix" | "sequence" | "petri" | "gantt"`:
|
|
312
420
|
diagram shape: `graph` (free), `hub` (centered), `grid` (edge-less),
|
|
421
|
+
`state` (state machine, with the `automaton` flags as pseudo-states),
|
|
422
|
+
`layer` (stacked bands, with the `nest` containers as the layers),
|
|
423
|
+
`slice` (side-by-side bands, with the `nest` containers as the
|
|
424
|
+
slices), `tree` (tidy tree, with the `nest` containers as the
|
|
425
|
+
parents), `matrix` (dependency structure matrix, with the `nest`
|
|
426
|
+
containers as the partitions), `sequence` (sequence diagram, with
|
|
427
|
+
the edge objects as the messages), `petri` (Petri net, with the
|
|
428
|
+
`places` objects as the places and all other nodes as the transitions),
|
|
429
|
+
`gantt` (Gantt chart, with the nodes as the tasks, the edges as their
|
|
430
|
+
dependencies, and the `nest` containers as the partitions),
|
|
313
431
|
BECAUSE one object set tells different stories as different shapes
|
|
314
432
|
|
|
315
433
|
- `SchemaDiagram.nodes?: string`:
|
|
@@ -320,6 +438,12 @@ type SchemaGradiaConfig = Partial<{
|
|
|
320
438
|
comma-separated `[[xxx]]` patterns of the objects acting as edges, not nodes,
|
|
321
439
|
BECAUSE some relations are objects, yet still connect two nodes
|
|
322
440
|
|
|
441
|
+
- `SchemaDiagram.local?: boolean`:
|
|
442
|
+
whether the `nodes` and `edges` patterns match only the object
|
|
443
|
+
itself and its descendants (default: `false`),
|
|
444
|
+
BECAUSE the patterns match corpus-wide, while a per-object diagram
|
|
445
|
+
of a recurring kind shows the own subtree only
|
|
446
|
+
|
|
323
447
|
- `SchemaDiagram.center?: string | SchemaDiagramCenter`:
|
|
324
448
|
object a `hub` diagram is projected onto (default: `self`), or a
|
|
325
449
|
synthetic center node, labeled from a referenced `source` object (or
|
|
@@ -341,9 +465,12 @@ type SchemaGradiaConfig = Partial<{
|
|
|
341
465
|
synthetic center, so their relation to it lives in a direction
|
|
342
466
|
property instead
|
|
343
467
|
|
|
344
|
-
- `SchemaDiagram.links?: "props" | "all"`:
|
|
345
|
-
edge source: property values (`props`)
|
|
346
|
-
|
|
468
|
+
- `SchemaDiagram.links?: "props" | "all" | string[]`:
|
|
469
|
+
edge source: property values (`props`), also texts (`all`), or the
|
|
470
|
+
values of the listed properties only (e.g. `[ DEPENDS-ON ]`, where
|
|
471
|
+
an empty list derives no reference edges at all),
|
|
472
|
+
BECAUSE prose references are incidental and need an opt-in, and a
|
|
473
|
+
diagram about one relation must not mix in the others
|
|
347
474
|
|
|
348
475
|
- `SchemaDiagram.labeled?: boolean`:
|
|
349
476
|
whether the edges derived from property values carry the lower-cased
|
|
@@ -356,13 +483,35 @@ type SchemaGradiaConfig = Partial<{
|
|
|
356
483
|
|
|
357
484
|
- `SchemaDiagram.edgeTarget?: string`:
|
|
358
485
|
edge property naming the target node (default: the first non-source
|
|
359
|
-
property whose value is a single reference),
|
|
486
|
+
property whose value is a single reference), where a `list(...)`
|
|
487
|
+
of references yields one edge per target,
|
|
360
488
|
BECAUSE the convention breaks on multiple references per object
|
|
361
489
|
|
|
362
490
|
- `SchemaDiagram.edgeArity?: string`:
|
|
363
491
|
edge property carrying the edge arity (default: `ARITY`),
|
|
364
492
|
BECAUSE cardinality labels are named domain-specifically
|
|
365
493
|
|
|
494
|
+
- `SchemaDiagram.edgeGuard?: string`:
|
|
495
|
+
edge property whose value follows the edge name in brackets
|
|
496
|
+
(e.g. `submit [complete]`), rendered italic in a `state` diagram,
|
|
497
|
+
BECAUSE a transition is only understood together with its condition
|
|
498
|
+
|
|
499
|
+
- `SchemaDiagram.edgeKind?: string`:
|
|
500
|
+
edge property whose value is the message kind of a `sequence`
|
|
501
|
+
diagram: `Call` (the default), `Signal`, `Return`, `Create`, or
|
|
502
|
+
`Destroy` (case-insensitive, plus the Gradia names `sync` and `async`),
|
|
503
|
+
BECAUSE a call, a notification, and a response read differently
|
|
504
|
+
|
|
505
|
+
- `SchemaDiagram.edgeDuration?: string`:
|
|
506
|
+
edge property whose value is the duration constraint of a call of a
|
|
507
|
+
`sequence` diagram up to its return (e.g. `< 200ms`),
|
|
508
|
+
BECAUSE response time budgets belong to the interaction they bound
|
|
509
|
+
|
|
510
|
+
- `SchemaDiagram.edgeTime?: string`:
|
|
511
|
+
edge property whose value is the time constraint or observation at
|
|
512
|
+
the start of a message of a `sequence` diagram (e.g. `t = now`),
|
|
513
|
+
BECAUSE some interactions are defined by their timing
|
|
514
|
+
|
|
366
515
|
- `SchemaDiagram.hierarchy?: boolean`:
|
|
367
516
|
whether containment edges derive from the nesting (default: `false`),
|
|
368
517
|
BECAUSE the nesting carries no reference and would stay invisible
|
|
@@ -372,8 +521,54 @@ type SchemaGradiaConfig = Partial<{
|
|
|
372
521
|
counted as the arity (default: `false`),
|
|
373
522
|
BECAUSE the relations between coarse objects live in their fine parts
|
|
374
523
|
|
|
524
|
+
- `SchemaDiagram.descend?: string[]`:
|
|
525
|
+
child object kinds whose references (and those of their descendants
|
|
526
|
+
of the listed kinds) count as the uncounted own references of their
|
|
527
|
+
node, labeled with the lower-cased kind under `labeled` (e.g.
|
|
528
|
+
`[ MESSAGE ]`, so an interaction references the components its
|
|
529
|
+
messages involve),
|
|
530
|
+
BECAUSE a relation can live in a part of an object without the
|
|
531
|
+
whole object's references being worth counting
|
|
532
|
+
|
|
533
|
+
- `SchemaDiagram.reverse?: string[]`:
|
|
534
|
+
properties whose reference edges point back from the referenced
|
|
535
|
+
object onto the referencing node (e.g. `[ CONSUMES ]`, so a unit
|
|
536
|
+
consuming a resource yields the arc from the resource to the unit),
|
|
537
|
+
BECAUSE a relation drawn against the direction of its reference
|
|
538
|
+
keeps the references of the specification pointing backward
|
|
539
|
+
|
|
540
|
+
- `SchemaDiagram.places?: string`:
|
|
541
|
+
comma-separated `[[xxx]]` patterns of the node objects acting as the
|
|
542
|
+
places of a `petri` diagram, all other nodes acting as its
|
|
543
|
+
transitions (without it, Gradia infers them from the arcs),
|
|
544
|
+
BECAUSE the kind of an object, not its position in the net, tells
|
|
545
|
+
whether it holds items or does work
|
|
546
|
+
|
|
547
|
+
- `SchemaDiagram.tokens?: string`:
|
|
548
|
+
property of a place carrying its initial tokens (an integer of at
|
|
549
|
+
least 0) in a `petri` diagram,
|
|
550
|
+
BECAUSE the analysis of the net starts from its initial marking
|
|
551
|
+
|
|
552
|
+
- `SchemaDiagram.capacity?: string`:
|
|
553
|
+
property of a place carrying its capacity (an integer of at least 1)
|
|
554
|
+
in a `petri` diagram, an absent one leaving the place unbounded,
|
|
555
|
+
BECAUSE a bound decides whether a producer has to wait
|
|
556
|
+
|
|
557
|
+
- `SchemaDiagram.duration?: string`:
|
|
558
|
+
property of a task carrying its duration (a non-negative number of
|
|
559
|
+
time units) in a `gantt` diagram, an absent one making the task a
|
|
560
|
+
milestone,
|
|
561
|
+
BECAUSE the length of a bar is the one fact a schedule rests on
|
|
562
|
+
|
|
563
|
+
- `SchemaDiagram.start?: string`:
|
|
564
|
+
property of a task carrying its earliest start (a non-negative number
|
|
565
|
+
of time units, default: `0`) in a `gantt` diagram,
|
|
566
|
+
BECAUSE some tasks start at an agreed time, not when their
|
|
567
|
+
dependencies allow
|
|
568
|
+
|
|
375
569
|
- `SchemaDiagram.onlyConnected?: boolean`:
|
|
376
|
-
whether a `
|
|
570
|
+
whether a diagram (except a `hub` or `grid`) drops its edge-less
|
|
571
|
+
nodes (default: `false`),
|
|
377
572
|
BECAUSE isolated nodes dilute a diagram about relationships
|
|
378
573
|
|
|
379
574
|
- `SchemaDiagram.collapse?: boolean`:
|
|
@@ -391,12 +586,25 @@ type SchemaGradiaConfig = Partial<{
|
|
|
391
586
|
BECAUSE in a coarse-to-fine specification the references then all
|
|
392
587
|
point backward, i.e. upward
|
|
393
588
|
|
|
589
|
+
- `SchemaDiagram.markUncovered?: "none" | "referenced" | "coverage" | "all"`:
|
|
590
|
+
which uncovered nodes are marked as incomplete, i.e. drawn with a
|
|
591
|
+
border in the violation (signal) color: none (`none`, the default),
|
|
592
|
+
the ones lacking the reference coverage their `referenced` kind
|
|
593
|
+
demands (`referenced`), the ones the `coverage` reports count
|
|
594
|
+
as unreferenced while no report counts them as referenced
|
|
595
|
+
(`coverage`, e.g. the requirements no test case references), or
|
|
596
|
+
both (`all`),
|
|
597
|
+
BECAUSE a coverage lapse spotted in the overview is fixed sooner
|
|
598
|
+
than one listed among the lint warnings or coverage ratios only
|
|
599
|
+
|
|
394
600
|
- `SchemaDiagram.nest?: SchemaDiagramNest`:
|
|
395
601
|
nesting of the nodes into container nodes,
|
|
396
602
|
BECAUSE a containment drawn as a box beats one drawn as an edge
|
|
397
603
|
|
|
398
604
|
- `SchemaDiagramNest.properties?: string[]`:
|
|
399
|
-
properties whose single referenced object is the container of a node
|
|
605
|
+
properties whose single referenced object is the container of a node
|
|
606
|
+
(in a `tree` diagram the first of several referenced objects, the
|
|
607
|
+
others becoming further parents),
|
|
400
608
|
BECAUSE a `PART-OF` or `TIER` reference is a containment, not a relation
|
|
401
609
|
|
|
402
610
|
- `SchemaDiagramNest.parent?: boolean`:
|
|
@@ -419,7 +627,11 @@ type SchemaGradiaConfig = Partial<{
|
|
|
419
627
|
BECAUSE a bundle of references into a container reads as one edge onto it
|
|
420
628
|
|
|
421
629
|
- `SchemaDiagram.properties?: string[]`:
|
|
422
|
-
property names attached to the nodes as key/value annotations,
|
|
630
|
+
property names attached to the nodes as key/value annotations, none
|
|
631
|
+
of which may be a node attribute Gradia reserves (`url`, `type`,
|
|
632
|
+
`primary`, `group`, `cluster`, `parent`, `container`, `order`,
|
|
633
|
+
`badge`, `multiple`, `mark`, `layer`, `slice`, `state`, `region`,
|
|
634
|
+
`petri`, `tokens`, `capacity`, `duration`, or `start`),
|
|
423
635
|
BECAUSE the node name alone rarely makes the nodes comparable
|
|
424
636
|
|
|
425
637
|
- `SchemaDiagram.config?: SchemaGradiaConfig`:
|
|
@@ -506,15 +718,24 @@ type SchemaGradiaConfig = Partial<{
|
|
|
506
718
|
|
|
507
719
|
- `SchemaGradiaConfig."color-node-*": string`:
|
|
508
720
|
colors of the node boxes in their regular, primary, ghost, and self
|
|
509
|
-
role,
|
|
721
|
+
role, of the pseudo-states of a `state` diagram, of the places of a
|
|
722
|
+
`petri` diagram, and of the lifelines of a `sequence` diagram,
|
|
510
723
|
BECAUSE the role of a node has to be readable at a glance
|
|
511
724
|
|
|
512
|
-
- `SchemaGradiaConfig."color-group
|
|
513
|
-
colors of the group
|
|
725
|
+
- `SchemaGradiaConfig."color-{group,container,composite,edge}-*": string`:
|
|
726
|
+
colors of the group, container, and composite boxes and of the
|
|
727
|
+
edges and their labels,
|
|
514
728
|
BECAUSE both have to stay visible yet recede behind the nodes
|
|
515
729
|
|
|
516
|
-
- `SchemaGradiaConfig."
|
|
517
|
-
|
|
730
|
+
- `SchemaGradiaConfig."color-mark-*": string`:
|
|
731
|
+
colors of the violation marks and of the critical path of a `gantt`
|
|
732
|
+
diagram,
|
|
733
|
+
BECAUSE a flaw or a bottleneck has to stand out from the regular drawing
|
|
734
|
+
|
|
735
|
+
- `SchemaGradiaConfig."size-*", "group-box-*", "container-box-*": number`:
|
|
736
|
+
font sizes of the node names, types, properties, edge names, and
|
|
737
|
+
arities, and geometry of the canvas, the node, group, and container
|
|
738
|
+
boxes, and the edge routing,
|
|
518
739
|
BECAUSE the geometry has to fit both the page and the text lengths
|
|
519
740
|
|
|
520
741
|
- `SchemaGradiaConfig."graph-*": number`:
|
|
@@ -522,32 +743,62 @@ type SchemaGradiaConfig = Partial<{
|
|
|
522
743
|
BECAUSE a free network needs room for its edges, not just its nodes
|
|
523
744
|
|
|
524
745
|
- `SchemaGradiaConfig."hub-*": number`:
|
|
525
|
-
layout of a `hub`: channel widths, node gap,
|
|
746
|
+
layout of a `hub`: channel widths, node gap, node degree, and the
|
|
747
|
+
node count of a column before it wraps into two staggered sub-columns,
|
|
526
748
|
BECAUSE a hub grows sideways and has to be bounded per side
|
|
527
749
|
|
|
528
750
|
- `SchemaGradiaConfig."grid-*": number | boolean`:
|
|
529
751
|
layout of a `grid`: column bounds, tile gaps, and tile width,
|
|
530
752
|
BECAUSE a catalog reads best as evenly sized tiles in stable columns
|
|
531
753
|
|
|
754
|
+
- `SchemaGradiaConfig."sequence-*": number`:
|
|
755
|
+
layout of a `sequence`: the gap between the lifelines and between
|
|
756
|
+
the messages,
|
|
757
|
+
BECAUSE an interaction reads top-down only with room between its steps
|
|
758
|
+
|
|
759
|
+
- `SchemaGradiaConfig."tree-*": number | boolean`:
|
|
760
|
+
layout of a `tree`: level and sibling gaps, the nodes per row, the
|
|
761
|
+
stacking of leaf siblings, equal node widths, and a horizontal
|
|
762
|
+
orientation,
|
|
763
|
+
BECAUSE a wide or deep hierarchy has to fit the page width
|
|
764
|
+
|
|
765
|
+
- `SchemaGradiaConfig."gantt-*": number | string | boolean`:
|
|
766
|
+
layout of a `gantt`: the width and the name of a time unit and the
|
|
767
|
+
marking of the critical path,
|
|
768
|
+
BECAUSE the time scale of a schedule is domain-specific
|
|
769
|
+
|
|
770
|
+
- `SchemaGradiaConfig."mark-violation", "layer-numbered", "slice-numbered": boolean`:
|
|
771
|
+
whether violations are marked at all (e.g. the cycles of a `matrix`
|
|
772
|
+
or the cross links of a `tree`) and whether the bands of a `layer`
|
|
773
|
+
or `slice` diagram are numbered,
|
|
774
|
+
BECAUSE a structure which is legitimate in one domain is a flaw in another
|
|
775
|
+
|
|
532
776
|
### Links
|
|
533
777
|
|
|
534
778
|
The edges are derived from the `[[xxx]]` references of the node objects
|
|
535
779
|
-- from their property values only, or, with `links: all`, from their
|
|
536
|
-
descriptions as well
|
|
780
|
+
descriptions as well, or, with a list of property names, from the
|
|
781
|
+
values of these properties only. Every referenced object is lifted to its nearest
|
|
537
782
|
ancestor-or-self within the node set, so a reference onto the scenario
|
|
538
783
|
of a use case yields an edge onto the use case. With `deep: true` the
|
|
539
784
|
references of all descendants of a node object count as its own and the
|
|
540
785
|
number of references behind an edge becomes its arity, so a diagram of
|
|
541
786
|
coarse objects (like the artifacts of a whole specification) shows the
|
|
542
|
-
relations living in their fine-grained parts. With `
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
787
|
+
relations living in their fine-grained parts. With `descend` the
|
|
788
|
+
references of the descendants of the listed kinds alone count as the
|
|
789
|
+
node's own, uncounted, so one edge per target remains. With `labeled:
|
|
790
|
+
true` an edge derived from a property value carries the lower-cased
|
|
791
|
+
property key as its label (or, for a `descend` descendant, its
|
|
792
|
+
lower-cased kind), telling the edges of different properties apart,
|
|
793
|
+
while the edges derived from descriptions stay unlabeled.
|
|
546
794
|
|
|
547
795
|
An object acting as an edge (`edges`) connects its parent object to the
|
|
548
796
|
object its target property references. Where an edge object is a sibling
|
|
549
797
|
of its own source instead of a child of it, `edgeSource` names the
|
|
550
|
-
property carrying that source
|
|
798
|
+
property carrying that source, and where the target property named by
|
|
799
|
+
`edgeTarget` carries a `list(...)` of references, the edge object yields
|
|
800
|
+
one edge per resolvable target. With `edgeGuard`, the value of the named
|
|
801
|
+
property follows the name of every such edge in brackets.
|
|
551
802
|
|
|
552
803
|
As the *nesting* of the objects carries no such reference, `hierarchy:
|
|
553
804
|
true` additionally derives a containment edge from every node object to
|
|
@@ -561,14 +812,120 @@ This is what turns a parent object into the hub of its own children. A
|
|
|
561
812
|
|
|
562
813
|
An object kind can additionally carry a `diagram` field, which derives
|
|
563
814
|
a [Gradia](https://github.com/rse/gradia) diagram for every object of
|
|
564
|
-
that kind
|
|
565
|
-
|
|
815
|
+
that kind -- or a list of such diagram configurations, which derives
|
|
816
|
+
all of them, in their order. Its `type` selects the diagram shape
|
|
817
|
+
(`graph`, `hub`, `grid`, `state`, `layer`, `slice`, `tree`,
|
|
818
|
+
`matrix`, `sequence`, `petri`, or `gantt`), `nodes` and
|
|
819
|
+
`edges` select the participating objects through
|
|
566
820
|
comma-separated `[[xxx]]` reference patterns (`nodes` defaults to the
|
|
567
|
-
object itself plus all objects below it
|
|
821
|
+
object itself plus all objects below it, and `local: true` restricts the
|
|
822
|
+
matches of both patterns to the object itself plus all objects below it,
|
|
823
|
+
as the patterns match corpus-wide), and `center` names the object
|
|
568
824
|
a `hub` is projected onto (default: `self`). An edge object of the
|
|
569
825
|
center targeting the center itself (a self-reference) places the center
|
|
570
826
|
a second time among its outputs, rendered as a dashed "self" node.
|
|
571
827
|
|
|
828
|
+
A `state` diagram is laid out like a `graph`, but draws a state machine:
|
|
829
|
+
where its object kind carries an `automaton`, a single initial
|
|
830
|
+
pseudo-state (a dot) leads into every node flagged `initial`, and every
|
|
831
|
+
node flagged `final` leads into a single final pseudo-state (a
|
|
832
|
+
bullseye), so a final node may still have outgoing edges. A `state`
|
|
833
|
+
diagram accepts no `nest`, as every container would be a composite
|
|
834
|
+
state needing an initial state of its own.
|
|
835
|
+
|
|
836
|
+
A `layer` diagram draws a layered architecture: the `nest` container of
|
|
837
|
+
a node names the band it sits in, the bands stack top-down in the
|
|
838
|
+
document order of their first node and are numbered bottom-up (unless
|
|
839
|
+
`config` sets `layer-numbered: false`), and the containers enclosing a
|
|
840
|
+
container group its band into a cluster column. The containers are no
|
|
841
|
+
nodes there, so the edges ending at a container are dropped, an edge
|
|
842
|
+
pointing upwards against the layering is marked as a violation, and
|
|
843
|
+
neither `nest.layout`, a lifting `nest.crossing`, nor `ordered` apply.
|
|
844
|
+
A `slice` diagram is its side-by-side companion: the bands line up
|
|
845
|
+
left-to-right (numbered only with `config` setting `slice-numbered:
|
|
846
|
+
true`), the nodes of a band stack top-down, the enclosing containers
|
|
847
|
+
group the bands into cluster rows, and an edge pointing back to a left
|
|
848
|
+
band closing a direct cycle is marked as a violation.
|
|
849
|
+
|
|
850
|
+
A `tree` diagram draws a tidy tree (or a forest of them): the `nest`
|
|
851
|
+
container of a node becomes its parent, so a child-to-parent reference
|
|
852
|
+
like `BROADER` or `PART-OF`, named by `nest.properties`, yields the
|
|
853
|
+
tree, while the containers stay nodes. Where such a property carries
|
|
854
|
+
several references (like a multiple `INHERITS`), the first one names
|
|
855
|
+
the parent and the others further parents. Every other edge (the ones
|
|
856
|
+
from the further parents included) is drawn as a dashed cross link and
|
|
857
|
+
marked as a violation (unless `config` sets `mark-violation: false`, as
|
|
858
|
+
for a legitimate multiple inheritance), so `links: []` derives a pure
|
|
859
|
+
tree (plus its further parents). With
|
|
860
|
+
`ordered: true` the children follow the document order. A `tree`
|
|
861
|
+
diagram accepts neither `nest.layout` nor a lifting `nest.crossing`.
|
|
862
|
+
|
|
863
|
+
A `matrix` diagram draws a dependency structure matrix: the nodes are
|
|
864
|
+
both its rows and its columns, the cell of a row and a column counts the
|
|
865
|
+
edges from the one to the other (a numeric arity counting as its
|
|
866
|
+
number), and the nodes are ordered topologically (with `ordered: true`
|
|
867
|
+
in document order instead), so all entries lie above the diagonal
|
|
868
|
+
except the ones of the cycles, which are outlined and marked as
|
|
869
|
+
violations (unless `config` sets `mark-violation: false`, as for
|
|
870
|
+
relations where mutual references are regular). A `nest` container
|
|
871
|
+
partitions its members, and the partitions are outlined on the
|
|
872
|
+
diagonal: a container taking part in the relation itself stays a row
|
|
873
|
+
and a column of its own, heading its partition, while a mere grouping
|
|
874
|
+
object (without any edge) names the partition only. `qualified: true`
|
|
875
|
+
puts the shared object kind into the corner. A `matrix` diagram accepts
|
|
876
|
+
no `nest.layout`. It usually restricts the `links` onto the very
|
|
877
|
+
relation it is about, e.g. `links: [ DEPENDS-ON ]`.
|
|
878
|
+
|
|
879
|
+
A `sequence` diagram draws the edge objects (`edges`) as its messages,
|
|
880
|
+
top-down in document order and never merged, so a repeated message
|
|
881
|
+
stays: `edgeSource` and `edgeTarget` name the sender and the receivers,
|
|
882
|
+
`edgeKind` the message kind (a `Return` answering the latest unanswered
|
|
883
|
+
`Call` of its sender, which activates the callee until then),
|
|
884
|
+
`edgeDuration` a duration constraint of a call, and `edgeTime` a time
|
|
885
|
+
constraint at a message. Its participants are the senders and receivers
|
|
886
|
+
of its messages, lined up in the order the messages first involve
|
|
887
|
+
them (unless `nodes` restricts them), so `local: true` usually
|
|
888
|
+
restricts the messages onto the own subtree. A `sequence` diagram
|
|
889
|
+
derives no reference edges and hence accepts neither `links`,
|
|
890
|
+
`hierarchy`, `deep`, `labeled`, `nest`, nor `ordered`, while `edgeKind`,
|
|
891
|
+
`edgeDuration`, and `edgeTime` apply to it alone. Its messages are
|
|
892
|
+
validated, each violation reported on its edge object: a participant is
|
|
893
|
+
created only by the first message it takes part in, takes part in no
|
|
894
|
+
message after its destruction, and a duration constraint belongs to a
|
|
895
|
+
call answered by a return.
|
|
896
|
+
|
|
897
|
+
A `petri` diagram draws a Petri net from the reference edges: the node
|
|
898
|
+
objects matching `places` are its places (drawn as circles holding their
|
|
899
|
+
`tokens` and showing their `capacity`), all other nodes its
|
|
900
|
+
transitions, and every edge an arc, where `reverse` turns the edges of
|
|
901
|
+
a consuming property into the arcs from the place to the transition, so
|
|
902
|
+
both arc directions stem from references of the transitions. Gradia
|
|
903
|
+
analyzes the net from its initial marking (within a bounded
|
|
904
|
+
exploration budget) and marks the unbounded places (missing
|
|
905
|
+
backpressure), the places holding a token in a deadlock, and the dead
|
|
906
|
+
and non-live transitions. The net is validated, each violation reported
|
|
907
|
+
on its object: the tokens are an integer of at least 0, the capacity one
|
|
908
|
+
of at least 1 holding them, and an arc connects a place with a
|
|
909
|
+
transition. A `petri` diagram accepts no `nest`, `places`, `tokens`,
|
|
910
|
+
and `capacity` apply to it alone, and `tokens` and `capacity` require
|
|
911
|
+
`places`.
|
|
912
|
+
|
|
913
|
+
A `gantt` diagram draws a Gantt chart: the node objects are its tasks
|
|
914
|
+
(one row each, a task without a `duration` being a milestone), the
|
|
915
|
+
edges its finish-to-start dependencies (so a property referencing the
|
|
916
|
+
*preceding* tasks is listed under `reverse`, as a dependency arrow runs
|
|
917
|
+
from the predecessor), and the `nest` containers the partitions of its
|
|
918
|
+
rows (like in a `matrix`, the containers themselves being no tasks).
|
|
919
|
+
The `duration` and `start` options name the properties of the tasks
|
|
920
|
+
carrying their duration and earliest start in abstract time units (a
|
|
921
|
+
`gantt-unit-name` in `config` labels them), from which Gradia schedules
|
|
922
|
+
the tasks as early as possible, draws the slack of every task, and
|
|
923
|
+
marks the critical path. The schedule is validated, each violation
|
|
924
|
+
reported on its object: the duration and the start are non-negative
|
|
925
|
+
numbers, and the dependencies form no cycle. A `gantt` diagram accepts
|
|
926
|
+
no `nest` layout or crossing, and `duration` and `start` apply to it
|
|
927
|
+
alone.
|
|
928
|
+
|
|
572
929
|
Instead of naming an existing object, `center` can also declare a
|
|
573
930
|
*synthetic* center node, which represents something no specification
|
|
574
931
|
object models -- like the solution itself in the middle of a context
|
|
@@ -592,6 +949,11 @@ rendering options (e.g. `grid-columns-max: 2`) through to the diagram.
|
|
|
592
949
|
As the Gradia defaults are dimensioned for a stand-alone canvas,
|
|
593
950
|
SpecBook presets a compact geometry for every diagram, which `config`
|
|
594
951
|
overrides: `size-canvas-margin: 8`, `size-node-height-scale: 2`,
|
|
952
|
+
`size-font-type`, `size-font-edge`, and `size-font-arity: 19` (about
|
|
953
|
+
20% over the Gradia defaults, as the diagrams are embedded at half
|
|
954
|
+
their coordinate scale), `size-edge-track-gap: 20` (the parallel edges
|
|
955
|
+
spread further apart), `graph-channel-width-max: 1000` (a capped
|
|
956
|
+
channel squeezes its many edges into an unreadable bundle),
|
|
595
957
|
`hub-node-gap: 10`, `hub-node-count-max: 6` (a `hub` column of more
|
|
596
958
|
nodes wraps into two staggered sub-columns), `grid-gap-horizontal: 24`,
|
|
597
959
|
`grid-gap-vertical: 12`, and `grid-columns-min: 4` (the square
|
|
@@ -670,7 +1032,12 @@ one ignores it), `maxCellHeight`
|
|
|
670
1032
|
the height of every other non-empty cell of its row before the HTML
|
|
671
1033
|
export folds its remaining text away, and `withUnusedProps`
|
|
672
1034
|
(default: `false`) unconditionally renders the defined but unused
|
|
673
|
-
properties of that kind, as property table lines or table columns.
|
|
1035
|
+
properties of that kind, as property table lines or table columns.
|
|
1036
|
+
Within a `concise` table, the name column takes a fixed fifth of the
|
|
1037
|
+
width, the description column two shares of the rest, and every property
|
|
1038
|
+
column one to two and a half shares by its longest word (its header
|
|
1039
|
+
included), so a property name or a reference kind label never breaks
|
|
1040
|
+
inside a narrow column. In
|
|
674
1041
|
the HTML/PDF export, a property absent from an object shows an "empty
|
|
675
1042
|
set" marker in place of its value, which tells it apart from a property
|
|
676
1043
|
given with an empty value.
|
|
@@ -725,7 +1092,7 @@ type SpecProperty = {
|
|
|
725
1092
|
BECAUSE a specification is one corpus of separately authored files
|
|
726
1093
|
|
|
727
1094
|
- `Spec.artifacts: SpecArtifact[]`:
|
|
728
|
-
all artifacts parsed from the Markdown files the
|
|
1095
|
+
all artifacts parsed from the Markdown files below the base directory,
|
|
729
1096
|
BECAUSE the corpus is parsed as a whole to resolve references
|
|
730
1097
|
|
|
731
1098
|
- `SpecArtifact`:
|
|
@@ -837,16 +1204,20 @@ several such files, merged in order into one schema (the later files
|
|
|
837
1204
|
into the earlier ones, where the objects merge deeply and the elements
|
|
838
1205
|
of the lists are matched by their identity). If no particular schema is
|
|
839
1206
|
given, the standard schema configuration bundled with **SpecBook**
|
|
840
|
-
applies.
|
|
1207
|
+
applies. Beside it (named `std`), **SpecBook** bundles the meta schema
|
|
1208
|
+
configuration (named `meta`), which describes a schema configuration
|
|
1209
|
+
itself, and the project management schema configuration (named `pm`),
|
|
1210
|
+
which plans the delivery of the solution a specification describes.
|
|
841
1211
|
|
|
842
1212
|
SpecBook SPEC Model
|
|
843
1213
|
-------------------
|
|
844
1214
|
|
|
845
1215
|
### Artifacts
|
|
846
1216
|
|
|
847
|
-
A specification consists of Markdown *artifact* files
|
|
848
|
-
|
|
849
|
-
|
|
1217
|
+
A specification consists of Markdown *artifact* files: every `.md` file
|
|
1218
|
+
below a base directory (recursively, except below `.`-prefixed entries),
|
|
1219
|
+
whatever its name, while the `file` fields of the SCHEMA Model only tell
|
|
1220
|
+
where the generated files are created. Every file has to start with
|
|
850
1221
|
a "frontmatter" block carrying the `Created:` and `Modified:` timestamps
|
|
851
1222
|
(format `yyyy-LL-dd HH:mm`):
|
|
852
1223
|
|
|
@@ -859,10 +1230,11 @@ Modified: 2026-06-18 10:18
|
|
|
859
1230
|
|
|
860
1231
|
Every level 1 heading opens a new *artifact*, so usually each file
|
|
861
1232
|
carries exactly one. Several artifacts nevertheless reside in one file
|
|
862
|
-
whenever the schema configures the same `file` for them
|
|
863
|
-
follow each other on level 1, below the
|
|
864
|
-
file. Both ATX headings (`# <text/>`,
|
|
865
|
-
headings (`<text/>` underlined with `===`
|
|
1233
|
+
whenever the schema configures the same `file` for them (or the author
|
|
1234
|
+
places them so): they then follow each other on level 1, below the
|
|
1235
|
+
single frontmatter block of that file. Both ATX headings (`# <text/>`,
|
|
1236
|
+
`## <text/>`, ...) and Setext headings (`<text/>` underlined with `===`
|
|
1237
|
+
or `---`) are supported.
|
|
866
1238
|
|
|
867
1239
|
As the timestamps are a property of the *file* and not of the individual
|
|
868
1240
|
artifact, the normalized Markdown export -- which merges the entire
|
|
@@ -1027,6 +1399,13 @@ The event is created and configured but not visible to attendees,
|
|
|
1027
1399
|
BECAUSE an event needs a private setup phase.
|
|
1028
1400
|
```
|
|
1029
1401
|
|
|
1402
|
+
The `, BECAUSE ` keyword is the source syntax and stays English in every
|
|
1403
|
+
document language, while the HTML/PDF export follows the bold `BECAUSE`
|
|
1404
|
+
with its non-bold, lower-case translation in parentheses into the
|
|
1405
|
+
language of the `LANG` property of the title object (`BECAUSE (weil)`
|
|
1406
|
+
for `de`, `BECAUSE (parce que)` for `fr`, and so on, while `en` and an
|
|
1407
|
+
unknown language render the bare `BECAUSE`).
|
|
1408
|
+
|
|
1030
1409
|
The rationale ends with its paragraph: all blocks following it (further
|
|
1031
1410
|
paragraphs, embedded images, and diagrams) form the *elaboration*, which
|
|
1032
1411
|
is rendered below the statement and its rationale, so the description
|
|
@@ -1043,8 +1422,9 @@ BECAUSE an event needs a private setup phase.
|
|
|
1043
1422
|
### Wiki-Style References
|
|
1044
1423
|
|
|
1045
1424
|
A `[[<reference/>]]` anywhere in a name, property value, description, or
|
|
1046
|
-
rationale (except inside a fenced code block
|
|
1047
|
-
so e.g. a shell test `[[ -f x ]]` is no
|
|
1425
|
+
rationale (except inside a fenced code block or an inline code span,
|
|
1426
|
+
whose code stays verbatim, so e.g. a shell test `[[ -f x ]]` is no
|
|
1427
|
+
reference) is a Wiki-style
|
|
1048
1428
|
reference to another object, which is checked
|
|
1049
1429
|
for unique resolvability and rendered as a hyperlink in the HTML/PDF
|
|
1050
1430
|
exports. A reference is a `.`-separated path of segments, where each
|