@entropicwarrior/sdoc 0.1.3 → 0.1.5
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/knowledge.js +2 -0
- package/lexica/sdoc-authoring.sdoc +445 -0
- package/lexica/slide-authoring.sdoc +411 -0
- package/lexica/specification.sdoc +779 -0
- package/package.json +5 -2
- package/src/slide-pdf.js +99 -0
- package/src/slide-renderer.js +344 -0
package/knowledge.js
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
# SDOC Authoring Guide @sdoc-authoring
|
|
2
|
+
{
|
|
3
|
+
# Meta @meta
|
|
4
|
+
{
|
|
5
|
+
type: skill
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
# About @about
|
|
9
|
+
{
|
|
10
|
+
How to write correct SDOC files. Covers document structure, inline
|
|
11
|
+
formatting, block types (lists, tables, code, blockquotes), and common
|
|
12
|
+
mistakes. Read the Quick Reference for everyday authoring. Read Common
|
|
13
|
+
Mistakes before generating SDOC for the first time.
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# Quick Reference @quick-reference
|
|
17
|
+
{
|
|
18
|
+
# Core Principle @core-principle
|
|
19
|
+
{
|
|
20
|
+
Structure comes from explicit brace scoping. \`{ }\` provides unambiguous scope boundaries. Whitespace and indentation are cosmetic — use them freely for readability but they never affect meaning.
|
|
21
|
+
|
|
22
|
+
Write each paragraph as a single long line. Do not hard-wrap body text at 72 or 80 characters. The renderer handles line wrapping based on the viewer's window width. A blank line separates paragraphs.
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Scopes @scopes
|
|
26
|
+
{
|
|
27
|
+
A scope is a heading followed by content in braces:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
# Document Title
|
|
31
|
+
{
|
|
32
|
+
# Section @section-id
|
|
33
|
+
{
|
|
34
|
+
Paragraph text goes here.
|
|
35
|
+
|
|
36
|
+
# Subsection
|
|
37
|
+
{
|
|
38
|
+
Deeper content.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
{[.]
|
|
45
|
+
- \`#\` starts a heading (multiple \`#\` characters are allowed but don't affect depth — only nesting does)
|
|
46
|
+
- \`@slug\` at the end of a heading line assigns a referenceable ID — the \`@\` character followed directly by the slug. There is no \`@id\` keyword.
|
|
47
|
+
- \`{ }\` delimits the scope's content
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
The opening brace can appear at the end of the heading line (K&R style):
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
# Title {
|
|
54
|
+
Content goes here.
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Smart Pointers @smart-ptrs {
|
|
58
|
+
The @slug goes before the brace.
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Error Handling @error-handling {
|
|
62
|
+
Another example with a slug.
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Braceless Scopes @braceless-scopes
|
|
68
|
+
{
|
|
69
|
+
A heading not followed by \`{\` creates a braceless scope. Content
|
|
70
|
+
runs until the next \`#\` heading, a closing \`}\`, or end of file:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
# Section A
|
|
74
|
+
Content of Section A.
|
|
75
|
+
It can span multiple lines.
|
|
76
|
+
|
|
77
|
+
# Section B
|
|
78
|
+
Content of Section B.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Braceless and explicit scopes can be mixed freely in the same
|
|
82
|
+
document.
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Paragraphs @paragraphs
|
|
86
|
+
{
|
|
87
|
+
Consecutive text lines form a paragraph. A blank line or a new scope
|
|
88
|
+
ends the paragraph.
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
# About
|
|
92
|
+
{
|
|
93
|
+
This is the first paragraph.
|
|
94
|
+
These lines join together.
|
|
95
|
+
|
|
96
|
+
This is a second paragraph.
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Lists @lists
|
|
102
|
+
{
|
|
103
|
+
**Simple bullet lists** — inside a normal scope, a run of \`-\` lines automatically becomes an implicit list. This is the easiest form for simple single-line items:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
# Features {
|
|
107
|
+
- Fast parsing
|
|
108
|
+
- Explicit structure
|
|
109
|
+
- Easy references
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Explicit list blocks** — use \`{[.]\` (note: no closing \`}\` on this line) for bullet lists or \`{[#]\` for numbered lists. The block is closed by a separate \`}\` after the items. Use explicit blocks when items need body content or for numbered lists:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
{[.]
|
|
117
|
+
- Item with details
|
|
118
|
+
{
|
|
119
|
+
This paragraph belongs to the item above.
|
|
120
|
+
Code blocks, nested lists, etc. go here too.
|
|
121
|
+
}
|
|
122
|
+
- Simple item
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
{[#]
|
|
126
|
+
1. Install the extension
|
|
127
|
+
2. Create a .sdoc file
|
|
128
|
+
3. Open the preview
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Important:** \`{[.]}\` with the closing brace on the same line creates an empty list — the brace closes the block immediately. Always put the closing \`}\` on a separate line after the items.
|
|
133
|
+
|
|
134
|
+
Implicit lists only work for bullet lists (\`-\`) where every item is a single line. For numbered lists, always use the explicit \`{[#]\` block form.
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# Tables @tables
|
|
138
|
+
{
|
|
139
|
+
Opened with \`{[table]\` (no closing brace on this line). First row is the header, columns separated by \`|\`. Closed by a separate \`}\`:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
{[table]
|
|
143
|
+
Name | Age | City
|
|
144
|
+
Alice | 30 | NYC
|
|
145
|
+
Bob | 25 | LA
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Optional flags control rendering:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
{[table borderless]
|
|
153
|
+
Feature | Status
|
|
154
|
+
Parser | Complete
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
{[table headerless]
|
|
158
|
+
Alice | 30
|
|
159
|
+
Bob | 25
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
{[table borderless headerless]
|
|
163
|
+
 | 
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
\`borderless\` removes borders and row striping. \`headerless\` treats all rows as data (no header). Flags combine in any order.
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Inline Formatting @inline-formatting
|
|
171
|
+
{
|
|
172
|
+
{[table]
|
|
173
|
+
Syntax | Result
|
|
174
|
+
\`*text*\` | Emphasis
|
|
175
|
+
\`**text**\` | Strong
|
|
176
|
+
\`~~text~~\` | Strikethrough
|
|
177
|
+
\`\\\`code\\\`\` | Inline code
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
Links: \`[Link text](https://example.com)\`
|
|
181
|
+
|
|
182
|
+
Images: \`\`
|
|
183
|
+
|
|
184
|
+
Images with width and alignment:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+

|
|
188
|
+

|
|
189
|
+

|
|
190
|
+

|
|
191
|
+
 
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Autolinks: \`\<https://example.com\>\`
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# References @references
|
|
198
|
+
{
|
|
199
|
+
Assign a slug with \`@slug\` on a heading, then reference it anywhere with \`@slug\`:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
# Setup @setup {
|
|
203
|
+
Follow these instructions.
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Usage {
|
|
207
|
+
Make sure you complete @setup first.
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
# Code Blocks @code-blocks
|
|
213
|
+
{
|
|
214
|
+
Fenced with triple backticks. Content inside is raw (no parsing):
|
|
215
|
+
|
|
216
|
+
````
|
|
217
|
+
```javascript
|
|
218
|
+
function hello() {
|
|
219
|
+
console.log("Hello!");
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
````
|
|
223
|
+
|
|
224
|
+
# Include by Link @code-includes
|
|
225
|
+
{
|
|
226
|
+
A code block can reference an external file with \`src:\` on the fence line — the content stays in sync:
|
|
227
|
+
|
|
228
|
+
`````
|
|
229
|
+
```json src:./data.json
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```json src:./data.json lines:3-5
|
|
233
|
+
```
|
|
234
|
+
`````
|
|
235
|
+
|
|
236
|
+
\`src:\` takes a file path (relative to the document) or URL. \`lines:\` optionally limits to a range (1-based, inclusive). The code block body is replaced by the resolved content.
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Mermaid Diagrams @mermaid
|
|
241
|
+
{
|
|
242
|
+
Code blocks with the \`mermaid\` language tag are rendered as SVG diagrams using the Mermaid JS library. No special syntax is needed — use a standard code fence:
|
|
243
|
+
|
|
244
|
+
````
|
|
245
|
+
```mermaid
|
|
246
|
+
graph LR
|
|
247
|
+
A[Client] --> B[Server]
|
|
248
|
+
B --> C[Database]
|
|
249
|
+
```
|
|
250
|
+
````
|
|
251
|
+
|
|
252
|
+
Mermaid supports flowcharts (\`graph\`), sequence diagrams (\`sequenceDiagram\`), class diagrams (\`classDiagram\`), state diagrams (\`stateDiagram-v2\`), and more. The Mermaid library is loaded from CDN only when a document contains mermaid blocks.
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# Blockquotes @blockquotes
|
|
256
|
+
{
|
|
257
|
+
```
|
|
258
|
+
> This is a quoted line.
|
|
259
|
+
> Another line in the same quote.
|
|
260
|
+
```
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
# Meta Scope @meta-scope
|
|
264
|
+
{
|
|
265
|
+
The reserved \`@meta\` scope configures per-file settings and is not rendered in the document body. Use the bare \`@meta\` form (preferred) or the heading form:
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
@meta {
|
|
269
|
+
type: doc
|
|
270
|
+
|
|
271
|
+
company: Irreversible Inc.
|
|
272
|
+
|
|
273
|
+
confidential: true
|
|
274
|
+
|
|
275
|
+
style: styles/custom.css
|
|
276
|
+
|
|
277
|
+
header: My Header
|
|
278
|
+
|
|
279
|
+
footer: My Footer
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The heading form \`# Meta @meta { }\` also works but the bare form is preferred because \`@meta\` is structural, not content.
|
|
284
|
+
|
|
285
|
+
Supported properties (separate each with a blank line):
|
|
286
|
+
|
|
287
|
+
\`type: doc\` or \`type: skill\` or \`type: slides\` — document type.
|
|
288
|
+
|
|
289
|
+
\`company: Name\` — company name, shown in the document footer.
|
|
290
|
+
|
|
291
|
+
\`confidential: true\` — adds a confidentiality notice banner.
|
|
292
|
+
Uses the \`company\` name if set. Use \`confidential: Custom Entity\`
|
|
293
|
+
to override with a specific entity name.
|
|
294
|
+
|
|
295
|
+
\`style: path/to/file.css\` — custom stylesheet (replaces default).
|
|
296
|
+
|
|
297
|
+
\`style-append: path/to/file.css\` — additional stylesheet (appended).
|
|
298
|
+
|
|
299
|
+
\`header: text\` — page header text (or use a \`# Header\` sub-scope
|
|
300
|
+
for rich content).
|
|
301
|
+
|
|
302
|
+
\`footer: text\` — page footer text (or use a \`# Footer\` sub-scope
|
|
303
|
+
for rich content).
|
|
304
|
+
|
|
305
|
+
\`uuid: ...\` — unique identifier.
|
|
306
|
+
|
|
307
|
+
\`tags: tag1, tag2\` — comma-separated tags.
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
# About Scope @about-scope
|
|
311
|
+
{
|
|
312
|
+
The reserved \`@about\` scope provides a discovery summary for the document. It is used by \`list_knowledge\` to describe the file but is not rendered in the document body. Use the bare \`@about\` form (preferred) or the heading form:
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
@about {
|
|
316
|
+
How to write correct SDOC files. Covers document structure, inline formatting, block types, and common mistakes.
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
The heading form \`# About @about { }\` also works but the bare form is preferred.
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
# Escaping @escaping
|
|
324
|
+
{
|
|
325
|
+
Backslash escapes special characters: \`\\\\\` \`\\{\` \`\\}\` \`\\@\`
|
|
326
|
+
\`\\[\` \`\\]\` \`\\(\` \`\\)\` \`\\*\` \`\\~\` \`\\#\` \`\\!\` \`\\\<\`
|
|
327
|
+
\`\\\>\`
|
|
328
|
+
|
|
329
|
+
A line starting with \`\\#\` renders as a literal \`#\` (not a heading).
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
# Common Mistakes @common-mistakes
|
|
334
|
+
{
|
|
335
|
+
These are easy errors to make — especially for AI agents generating SDOC.
|
|
336
|
+
|
|
337
|
+
# Self-Closing Block Syntax @self-closing-blocks
|
|
338
|
+
{
|
|
339
|
+
Writing \`{[.]}\` or \`{[table]}\` with the closing brace on the same line creates an empty block — the \`}\` closes it immediately. Items that follow are bare content outside the block and will not render correctly.
|
|
340
|
+
|
|
341
|
+
**Wrong** — the \`}\` closes the block on the same line:
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
{[.]}
|
|
345
|
+
- Item one
|
|
346
|
+
- Item two
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Right** — the opening \`{[.]\` has no closing brace; items go inside; a separate \`}\` closes:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
{[.]
|
|
353
|
+
- Item one
|
|
354
|
+
- Item two
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Same applies to \`{[#]}\` and \`{[table]}\`.
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
# Bare Content Inside List Blocks @bare-content-in-lists
|
|
362
|
+
{
|
|
363
|
+
Inside a list block (\`{[.]}\` or \`{[#]}\`), the **only** valid
|
|
364
|
+
children are list items (\`-\`, \`1.\`, \`#\` headings, or anonymous
|
|
365
|
+
\`{ }\` blocks). Bare paragraphs, code fences, or other content
|
|
366
|
+
floating between items is a **parser error**.
|
|
367
|
+
|
|
368
|
+
**Wrong** — bare paragraph inside a list block:
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
{[.]
|
|
372
|
+
- First item title
|
|
373
|
+
|
|
374
|
+
This paragraph is NOT inside a body block.
|
|
375
|
+
It will cause a parser error.
|
|
376
|
+
|
|
377
|
+
- Second item
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Right** — wrap rich content in a \`{ }\` body block:
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
{[.]
|
|
385
|
+
- First item title
|
|
386
|
+
{
|
|
387
|
+
This paragraph belongs to the item above.
|
|
388
|
+
|
|
389
|
+
So does this one, and any code blocks, nested lists, etc.
|
|
390
|
+
}
|
|
391
|
+
- Second item
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
This is the single most common SDOC mistake. If a list item needs
|
|
396
|
+
**anything** beyond its title line, that content **must** go in a
|
|
397
|
+
\`{ }\` body block immediately after the item.
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
# Unescaped Angle Brackets @unescaped-angles
|
|
401
|
+
{
|
|
402
|
+
Angle brackets in regular text (outside of inline code backticks)
|
|
403
|
+
can be misinterpreted as autolinks. Escape them with \`\\\<\` and
|
|
404
|
+
\`\\\>\`:
|
|
405
|
+
|
|
406
|
+
**Wrong:** \`observer<T>\`
|
|
407
|
+
|
|
408
|
+
**Right:** \`observer\\\<T\\\>\` or \`\\\`observer<T>\\\`\`
|
|
409
|
+
|
|
410
|
+
Inside backtick code spans, angle brackets are fine — code spans
|
|
411
|
+
are raw.
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
# Blank Lines Stop Multi-Line List Titles @blank-lines-in-lists
|
|
415
|
+
{
|
|
416
|
+
A list item title can span multiple continuation lines, but a blank
|
|
417
|
+
line terminates the title. Content after the blank line is bare
|
|
418
|
+
content in the list block (a parser error) unless wrapped in a body
|
|
419
|
+
block:
|
|
420
|
+
|
|
421
|
+
**Wrong:**
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
{[.]
|
|
425
|
+
- This is a long item title
|
|
426
|
+
that continues here
|
|
427
|
+
|
|
428
|
+
But this is NOT a continuation — it's a bare paragraph (error).
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Right:**
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
{[.]
|
|
436
|
+
- This is a long item title
|
|
437
|
+
that continues here
|
|
438
|
+
{
|
|
439
|
+
This extra content is properly in a body block.
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|