@rse/specbook 1.3.2 → 1.4.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/README.md +9 -2
- package/dst/specbook-api.d.ts +5 -1
- package/dst/specbook-api.js +23 -9
- package/dst/specbook-cli.js +8 -5
- package/dst/specbook-cmd-export.js +2 -2
- package/dst/specbook-cmd-init.js +16 -2
- package/dst/specbook-coverage.js +1 -1
- package/dst/specbook-diagram.d.ts +1 -1
- package/dst/specbook-diagram.js +12 -10
- package/dst/specbook-export-ast.d.ts +1 -1
- package/dst/specbook-export-ast.js +21 -4
- package/dst/specbook-export-code.d.ts +14 -0
- package/dst/specbook-export-code.js +155 -0
- package/dst/specbook-export-common.d.ts +8 -2
- package/dst/specbook-export-common.js +126 -6
- package/dst/specbook-export-diagram.d.ts +15 -0
- package/dst/specbook-export-diagram.js +211 -0
- package/dst/specbook-export-html-fold.d.ts +20 -0
- package/dst/specbook-export-html-fold.js +458 -0
- package/dst/specbook-export-html-render.d.ts +51 -0
- package/dst/specbook-export-html-render.js +748 -0
- package/dst/specbook-export-html-search.js +6 -5
- package/dst/specbook-export-html-template.d.ts +21 -0
- package/dst/specbook-export-html-template.js +282 -0
- package/dst/specbook-export-html-widget.d.ts +12 -0
- package/dst/specbook-export-html-widget.js +605 -0
- package/dst/specbook-export-html.css +325 -50
- package/dst/specbook-export-html.js +62 -1931
- package/dst/specbook-export-image.d.ts +2 -0
- package/dst/specbook-export-image.js +161 -9
- package/dst/specbook-export-md.js +60 -12
- package/dst/specbook-format-schema.d.ts +1 -1
- package/dst/specbook-format-schema.js +1 -1
- package/dst/specbook-format-spec.d.ts +1 -0
- package/dst/specbook-format-spec.js +1 -0
- package/dst/specbook-format.md +173 -19
- package/dst/specbook-format.yaml +265 -24
- package/dst/specbook-ignore.js +2 -0
- package/dst/specbook-link.js +21 -5
- package/dst/specbook-mcp.js +9 -5
- package/dst/specbook-parse-common.d.ts +24 -0
- package/dst/specbook-parse-common.js +137 -10
- package/dst/specbook-parse-semantic.js +2 -0
- package/dst/specbook-parse-syntax.js +81 -20
- package/dst/specbook-parse.js +1 -1
- package/dst/specbook-project.d.ts +1 -0
- package/dst/specbook-project.js +10 -1
- package/dst/specbook-theme.d.ts +1 -0
- package/dst/specbook-theme.js +2 -0
- package/package.json +18 -12
package/dst/specbook-format.md
CHANGED
|
@@ -123,7 +123,7 @@ type SchemaDiagram = {
|
|
|
123
123
|
config?: Partial<GradiaConfig>
|
|
124
124
|
}
|
|
125
125
|
type SchemaFormat = {
|
|
126
|
-
type?: "auto" | "complex" | "concise"
|
|
126
|
+
type?: "auto" | "complex" | "compact" | "concise"
|
|
127
127
|
maxTableColumns?: number
|
|
128
128
|
maxCellHeight?: number
|
|
129
129
|
withUnusedProps?: boolean
|
|
@@ -323,7 +323,8 @@ type SchemaGradiaConfig = Partial<{
|
|
|
323
323
|
- `SchemaDiagram.center?: string | SchemaDiagramCenter`:
|
|
324
324
|
object a `hub` diagram is projected onto (default: `self`), or a
|
|
325
325
|
synthetic center node, labeled from a referenced `source` object (or
|
|
326
|
-
one of its properties, via `property
|
|
326
|
+
one of its properties, via `property`, falling back onto the `label`
|
|
327
|
+
or the object name while absent) or a literal `label`, typed
|
|
327
328
|
(under `qualified`) by `kind`, and linked to the `source` object,
|
|
328
329
|
BECAUSE the focus of a hub is not always a specification object --
|
|
329
330
|
the solution itself, e.g., sits in the middle of a context diagram
|
|
@@ -429,8 +430,9 @@ type SchemaGradiaConfig = Partial<{
|
|
|
429
430
|
HTML/PDF rendering of the objects of an object kind among their siblings,
|
|
430
431
|
BECAUSE one uniform rendering fits neither rich nor numerous objects
|
|
431
432
|
|
|
432
|
-
- `SchemaFormat.type?: "auto" | "complex" | "concise"`:
|
|
433
|
-
rendering: `complex` (sections), `concise` (tables),
|
|
433
|
+
- `SchemaFormat.type?: "auto" | "complex" | "compact" | "concise"`:
|
|
434
|
+
rendering: `complex` (sections), `concise` (tables), `compact`
|
|
435
|
+
(tables of section-like cells), or `auto`,
|
|
434
436
|
BECAUSE sections bury small objects, tables truncate rich ones
|
|
435
437
|
|
|
436
438
|
- `SchemaFormat.maxTableColumns?: number`:
|
|
@@ -571,7 +573,8 @@ Instead of naming an existing object, `center` can also declare a
|
|
|
571
573
|
*synthetic* center node, which represents something no specification
|
|
572
574
|
object models -- like the solution itself in the middle of a context
|
|
573
575
|
diagram. Such a center is labeled from a referenced `source` object (or
|
|
574
|
-
one of its properties, via `property
|
|
576
|
+
one of its properties, via `property`, falling back onto the `label` or
|
|
577
|
+
the object name while the property is absent) or a literal `label`, and links
|
|
575
578
|
to the `source` object. As the nodes carry no `[[xxx]]` reference to a
|
|
576
579
|
synthetic center, `centerEdges` synthesizes the edges from a direction
|
|
577
580
|
`property` of the node objects: its `inbound` value maps onto a
|
|
@@ -649,15 +652,20 @@ how the HTML/PDF export renders the objects of that kind among their
|
|
|
649
652
|
siblings, so that the sibling kinds below one parent can render
|
|
650
653
|
differently (e.g. one kind as a table, another as sections). Its `type`
|
|
651
654
|
selects the rendering: `complex` (nested sections), `concise` (one
|
|
652
|
-
compact table of all sibling objects of the kind),
|
|
653
|
-
|
|
655
|
+
compact table of all sibling objects of the kind), `compact` (one
|
|
656
|
+
table of the name and a single cell per object, which renders the
|
|
657
|
+
object like `complex`, but without its heading: diagram, properties as
|
|
658
|
+
key/value lines, and description, for a kind whose many properties a
|
|
659
|
+
table row cannot hold), or the default `auto`, which collapses only the
|
|
660
|
+
deepest level into tables.
|
|
654
661
|
|
|
655
662
|
Inside a `concise` table, unconfigured child kinds implicitly stay
|
|
656
663
|
`concise` and render as sub-tables inside the description cells, while
|
|
657
664
|
an explicitly configured `type` is always honored, even a `complex`
|
|
658
665
|
rendering pressed into a cell. `maxTableColumns` (default: `4`) bounds
|
|
659
666
|
the columns of the compact table of the kind (a wider group chunks
|
|
660
|
-
its properties into embedded per-object tables
|
|
667
|
+
its properties into embedded per-object tables, while a `compact`
|
|
668
|
+
one ignores it), `maxCellHeight`
|
|
661
669
|
(default: `40`) is the percentage a table cell of the kind may exceed
|
|
662
670
|
the height of every other non-empty cell of its row before the HTML
|
|
663
671
|
export folds its remaining text away, and `withUnusedProps`
|
|
@@ -702,6 +710,7 @@ type SpecObject = {
|
|
|
702
710
|
type SpecDescription = {
|
|
703
711
|
description: string
|
|
704
712
|
rationale?: string
|
|
713
|
+
elaboration?: string
|
|
705
714
|
embedding?: string[]
|
|
706
715
|
}
|
|
707
716
|
type SpecProperty = {
|
|
@@ -776,7 +785,7 @@ type SpecProperty = {
|
|
|
776
785
|
BECAUSE a specification is a tree, not a flat list of statements
|
|
777
786
|
|
|
778
787
|
- `SpecDescription`:
|
|
779
|
-
description of an object: statement, rationale, and images,
|
|
788
|
+
description of an object: statement, rationale, elaboration, and images,
|
|
780
789
|
BECAUSE the WHAT and the WHY are stored apart to be rendered apart
|
|
781
790
|
|
|
782
791
|
- `SpecDescription.description: string`:
|
|
@@ -785,11 +794,18 @@ type SpecProperty = {
|
|
|
785
794
|
|
|
786
795
|
- `SpecDescription.rationale?: string`:
|
|
787
796
|
rationale text behind the `, BECAUSE ` split (the WHY),
|
|
797
|
+
up to the end of its paragraph,
|
|
788
798
|
BECAUSE a statement without its WHY cannot be judged or revised
|
|
789
799
|
|
|
800
|
+
- `SpecDescription.elaboration?: string`:
|
|
801
|
+
blocks following the paragraph of the rationale (e.g. images or diagrams),
|
|
802
|
+
BECAUSE further content must not end up inside the WHY
|
|
803
|
+
|
|
790
804
|
- `SpecDescription.embedding?: string[]`:
|
|
791
|
-
image files embedded via ``,
|
|
792
|
-
one entry per file in markup order (
|
|
805
|
+
image, diagram source, and source code files embedded via ``,
|
|
806
|
+
inlined at parse time, one entry per file in markup order (those of
|
|
807
|
+
the statement first, those of the elaboration second, and empty for
|
|
808
|
+
an unreadable file),
|
|
793
809
|
BECAUSE the exports have to stand alone, without the image files
|
|
794
810
|
|
|
795
811
|
- `SpecProperty`:
|
|
@@ -805,7 +821,8 @@ type SpecProperty = {
|
|
|
805
821
|
BECAUSE constraints and references are checked against this text
|
|
806
822
|
|
|
807
823
|
- `SpecProperty.embedding?: string[]`:
|
|
808
|
-
image files embedded in the value,
|
|
824
|
+
image, diagram source, and source code files embedded in the value,
|
|
825
|
+
inlined at parse time,
|
|
809
826
|
one entry per file in markup order (empty for an unreadable file),
|
|
810
827
|
BECAUSE the exports have to stand alone, without the image files
|
|
811
828
|
|
|
@@ -992,10 +1009,15 @@ paragraphs, blockquotes, ordered lists (e.g. scenario steps or test
|
|
|
992
1009
|
case procedures), and fenced code blocks. A fenced code block of
|
|
993
1010
|
language `gradia` is skipped, as it is the derived diagram which
|
|
994
1011
|
**SpecBook** itself emits into exported Markdown and which must not
|
|
995
|
-
become authored content on a re-parse.
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1012
|
+
become authored content on a re-parse. A fenced code block of language
|
|
1013
|
+
`mermaid` (alias `mmd`) or `d2` is a [Mermaid](https://mermaid.js.org/)
|
|
1014
|
+
or [D2](https://d2lang.com/) diagram, which the HTML/PDF export renders
|
|
1015
|
+
as a diagram instead of as code (see "Diagram Embeddings" below). A
|
|
1016
|
+
fenced code block of any other known language is a syntax-highlighted
|
|
1017
|
+
code listing (see "Code Listings" below). In
|
|
1018
|
+
the Concise Format, the description is formed by the non-property
|
|
1019
|
+
segments of the item, so a description carrying a `;` cannot be a
|
|
1020
|
+
segment either and forces its object into the Complex Format.
|
|
999
1021
|
|
|
1000
1022
|
A description is split into its *statement* and *rationale* at the first
|
|
1001
1023
|
`, BECAUSE ` (or `, **BECAUSE** `) occurrence:
|
|
@@ -1005,10 +1027,25 @@ The event is created and configured but not visible to attendees,
|
|
|
1005
1027
|
BECAUSE an event needs a private setup phase.
|
|
1006
1028
|
```
|
|
1007
1029
|
|
|
1030
|
+
The rationale ends with its paragraph: all blocks following it (further
|
|
1031
|
+
paragraphs, embedded images, and diagrams) form the *elaboration*, which
|
|
1032
|
+
is rendered below the statement and its rationale, so the description
|
|
1033
|
+
of a Complex Format object can state its WHAT and WHY first and
|
|
1034
|
+
illustrate them afterwards:
|
|
1035
|
+
|
|
1036
|
+
````
|
|
1037
|
+
The event is created and configured but not visible to attendees,
|
|
1038
|
+
BECAUSE an event needs a private setup phase.
|
|
1039
|
+
|
|
1040
|
+

|
|
1041
|
+
````
|
|
1042
|
+
|
|
1008
1043
|
### Wiki-Style References
|
|
1009
1044
|
|
|
1010
1045
|
A `[[<reference/>]]` anywhere in a name, property value, description, or
|
|
1011
|
-
rationale
|
|
1046
|
+
rationale (except inside a fenced code block, whose code stays verbatim,
|
|
1047
|
+
so e.g. a shell test `[[ -f x ]]` is no reference) is a Wiki-style
|
|
1048
|
+
reference to another object, which is checked
|
|
1012
1049
|
for unique resolvability and rendered as a hyperlink in the HTML/PDF
|
|
1013
1050
|
exports. A reference is a `.`-separated path of segments, where each
|
|
1014
1051
|
segment matches a single object as:
|
|
@@ -1046,7 +1083,21 @@ SVG files are inlined as-is; PNG/JPEG/WebP files are embedded as base64
|
|
|
1046
1083
|
`data:` URLs. URLs and other file types are left untouched. The
|
|
1047
1084
|
HTML/PDF export optimizes the embedded images on its own (downscaled
|
|
1048
1085
|
and re-encoded PNG/JPEG/WebP, minified SVG), so the files can stay in their
|
|
1049
|
-
original resolution.
|
|
1086
|
+
original resolution. Like a diagram, an embedded image (except the logo
|
|
1087
|
+
of the title page) folds, maximizes, and is omitted (`-O diagram:image`,
|
|
1088
|
+
or by nesting level) in the HTML/PDF export, while the AST exports keep
|
|
1089
|
+
it.
|
|
1090
|
+
|
|
1091
|
+
A page of a PDF document is embedded like an image --
|
|
1092
|
+
`` for the first page, or
|
|
1093
|
+
`` for the 1-based page number `<n/>` --
|
|
1094
|
+
where the document is inlined at parse time. The exports convert the
|
|
1095
|
+
page through `pdfjs-dist` into a vector SVG with its texts as glyph
|
|
1096
|
+
outlines and then treat it exactly like an embedded SVG image, while a
|
|
1097
|
+
page failing to render (e.g. an absent page number) is omitted with a
|
|
1098
|
+
notice. A presentation (e.g. PowerPoint), a spreadsheet (e.g. Excel), or
|
|
1099
|
+
any other office document is embedded through its PDF export, which
|
|
1100
|
+
carries its exact rendering and fonts.
|
|
1050
1101
|
|
|
1051
1102
|
A reference carrying the `{theme}` placeholder -- e.g.
|
|
1052
1103
|
`` -- is a *theme-aware* embedding: it expands
|
|
@@ -1056,10 +1107,113 @@ HTML export shows just the variant matching the color theme currently
|
|
|
1056
1107
|
active in the document, while the PDF export (like print in general)
|
|
1057
1108
|
always uses the `light` variant.
|
|
1058
1109
|
|
|
1110
|
+
An image without a dark variant is treated on the dark theme of the HTML
|
|
1111
|
+
export as its `dark` fragment parameter says (see "Fragment Parameters"
|
|
1112
|
+
below), while print always keeps it as it is. An image defaults to
|
|
1113
|
+
`dark=auto`, which inverts it (with its hues rotated back) if it most
|
|
1114
|
+
likely draws dark lines onto a transparent or light canvas: an SVG if it
|
|
1115
|
+
neither adapts itself (via `light-dark()` colors, `prefers-color-scheme`
|
|
1116
|
+
rules, or a `color-scheme` declaration, which follows the color theme of
|
|
1117
|
+
the document anyway), nor embeds a raster image, nor paints a background
|
|
1118
|
+
which is not light, and a raster image (PNG/JPEG/WebP) if at least 60%
|
|
1119
|
+
of its pixels are transparent or near-white and the others are dark on
|
|
1120
|
+
average and of a few colors only (unlike a photo or a colorful
|
|
1121
|
+
screenshot). As the detection cannot tell a logo or illustration with
|
|
1122
|
+
brand colors from a line drawing, `#dark=none` keeps such an image as it
|
|
1123
|
+
is, while `#dark=invert` forces the inversion (e.g.
|
|
1124
|
+
``). A
|
|
1125
|
+
[draw.io](https://www.drawio.com/) diagram is best embedded as its
|
|
1126
|
+
editable SVG (`.drawio.svg`, which draw.io keeps current on every save)
|
|
1127
|
+
with its "Adaptive Colors" page setting on "Automatic", as it then
|
|
1128
|
+
adapts all its colors itself. A theme-aware embedding ignores the
|
|
1129
|
+
fragment, as its `dark` variant already serves the dark theme.
|
|
1130
|
+
|
|
1059
1131
|
The reference-style image `![<alt/>][<label/>]` embeds the image of its
|
|
1060
1132
|
definition `[<label/>]: data:image/<type/>;base64,<data/>` (SVG, PNG,
|
|
1061
|
-
JPEG, or WebP
|
|
1133
|
+
JPEG, or WebP, where a `;dark=invert` or `;dark=none` parameter behind
|
|
1134
|
+
the type carries the treatment on the dark theme, which the export
|
|
1135
|
+
always resolves for an SVG) in the same file, the only supported link
|
|
1136
|
+
definition.
|
|
1062
1137
|
This is the form the normalized Markdown export emits for every embedded
|
|
1063
1138
|
image (a theme-aware one by its `light` variant), with the definitions
|
|
1064
1139
|
at the end of the document, so it stands alone without the image files.
|
|
1065
1140
|
Author the inline form; the reference-style one is for re-parsing only.
|
|
1141
|
+
|
|
1142
|
+
### Diagram Embeddings
|
|
1143
|
+
|
|
1144
|
+
A [Mermaid](https://mermaid.js.org/) or [D2](https://d2lang.com/)
|
|
1145
|
+
diagram is either written inline into a description as a fenced code
|
|
1146
|
+
block of language `mermaid` (alias `mmd`) or `d2`, or kept in a file of
|
|
1147
|
+
its own and embedded like an image -- ``,
|
|
1148
|
+
``, or `` -- inside a
|
|
1149
|
+
description or property value, where its source is inlined at parse time.
|
|
1150
|
+
The HTML/PDF export renders every such diagram (Mermaid through
|
|
1151
|
+
`beautiful-mermaid`, D2 through `@terrastruct/d2`) in the theme colors of
|
|
1152
|
+
the document, once per color theme, like a theme-aware image. It folds,
|
|
1153
|
+
maximizes, and is omitted (`-O diagram:code`, for diagrams as code, or
|
|
1154
|
+
by nesting level) like a derived Gradia diagram. A diagram failing to render
|
|
1155
|
+
is omitted with a notice. The normalized Markdown and the AST exports
|
|
1156
|
+
carry the source of a fenced diagram as part of the description, and an
|
|
1157
|
+
embedded diagram file as its rendered SVG (the `light` variant).
|
|
1158
|
+
|
|
1159
|
+
### Code Listings
|
|
1160
|
+
|
|
1161
|
+
A code snippet is either written inline into a description as a fenced
|
|
1162
|
+
code block of a known language (any language id or alias of
|
|
1163
|
+
[Shiki](https://shiki.style/), like `ts`, `java`, `css`, or `html`), or
|
|
1164
|
+
kept in a source code file of its own and embedded like an image --
|
|
1165
|
+
``, where `<ext/>` is such a language id or
|
|
1166
|
+
alias (e.g. `.ts`, `.java`, `.css`, `.html`) -- inside a description or
|
|
1167
|
+
property value, where its source is inlined at parse time. A fenced code
|
|
1168
|
+
block of no or an unknown language stays plain preformatted text.
|
|
1169
|
+
|
|
1170
|
+
The HTML/PDF export renders every such snippet as a *code listing* in
|
|
1171
|
+
DejaVu Sans Mono, with line numbers and with its keywords, operators,
|
|
1172
|
+
and punctuation in the accent color and bold, its literals in the signal
|
|
1173
|
+
color, and its comments in the dim color and italic. A code listing
|
|
1174
|
+
folds, maximizes, and is omitted (`-O diagram:listing`, or by nesting
|
|
1175
|
+
level) like a diagram.
|
|
1176
|
+
|
|
1177
|
+
A fenced code listing takes whitespace-separated parameters behind its
|
|
1178
|
+
language, and an embedded one takes them as its fragment (see "Fragment
|
|
1179
|
+
Parameters" below):
|
|
1180
|
+
|
|
1181
|
+
- `start=<n/>` (fenced only): the number of the first line (default `1`).
|
|
1182
|
+
- `lines=<a/>-<b/>` or `lines=<a/>` (embedded only): the excerpt of the
|
|
1183
|
+
1-based lines `<a/>` to `<b/>` (or line `<a/>` alone), numbered from
|
|
1184
|
+
`<a/>`, where an empty range is reported as an error.
|
|
1185
|
+
- `mark=<a/>[-<b/>][,...]`: the lines or line ranges to mark (in the
|
|
1186
|
+
shown line numbers) on a very light signal background.
|
|
1187
|
+
|
|
1188
|
+
````
|
|
1189
|
+
```ts start=10 mark=12-13
|
|
1190
|
+
const greeter = new Greeter("World")
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+

|
|
1194
|
+
````
|
|
1195
|
+
|
|
1196
|
+
The AST exports carry an embedded source code file as its
|
|
1197
|
+
`data:text/x-code;lang=<lang/>;start=<n/>[;mark=<hunks/>];base64,<data/>`
|
|
1198
|
+
URL, while the normalized Markdown export turns one of a description into
|
|
1199
|
+
a fenced code block (with its `start` and `mark` parameters) at the end
|
|
1200
|
+
of the elaboration, and keeps one of a property value as a
|
|
1201
|
+
reference-style image definition of that URL.
|
|
1202
|
+
|
|
1203
|
+
#### Fragment Parameters
|
|
1204
|
+
|
|
1205
|
+
The fragment of an embedding reference is a list of `<key/>=<value/>`
|
|
1206
|
+
parameters joined by `&`, in any order and each at most once, with the
|
|
1207
|
+
values optionally URI-encoded (e.g. `%20` for a space): `page`
|
|
1208
|
+
(documents), `dark` (documents and images), and `lines` and `mark`
|
|
1209
|
+
(source code files, see "Code Listings" above). A fragment carrying any
|
|
1210
|
+
other key or an invalid value is reported as an error. The `dark`
|
|
1211
|
+
parameter selects the treatment on the dark theme of the HTML export,
|
|
1212
|
+
while print always shows the original: `dark=invert` inverts the
|
|
1213
|
+
embedding with its hues rotated back, `dark=none` shows it as it is, and
|
|
1214
|
+
`dark=auto` (the default) decides by the content of the image or the
|
|
1215
|
+
rendered document page (inverting a light canvas with dark ink, but
|
|
1216
|
+
neither a dark one nor one carrying a photo), as an image and a document
|
|
1217
|
+
page can be anything (line drawings, photos, logos); e.g.
|
|
1218
|
+
`` keeps a page which the
|
|
1219
|
+
detection would invert, but whose colors have to stay.
|