@entropicwarrior/sdoc 0.1.14 → 0.1.17

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.
@@ -0,0 +1,502 @@
1
+ # Syntax Reference
2
+ {
3
+ @meta {
4
+ sdoc-version: 0.1
5
+ }
6
+
7
+ This is a practical reference for writing SDOC files. For the formal specification (edge cases, grammar, parsing rules), see \`lexica/specification.sdoc\`.
8
+
9
+ # Scopes
10
+ {
11
+ A scope is a heading line followed by a brace-delimited block:
12
+
13
+ ```
14
+ # Heading @optional-id
15
+ {
16
+ Body content here.
17
+ }
18
+ ```
19
+
20
+ {[.]
21
+ - The heading starts with `#` (after optional indentation)
22
+ - Multiple `#` characters are allowed but do not affect depth; depth comes from nesting
23
+ - The optional `@id` must be the last token on the heading line, separated by whitespace
24
+ - IDs may contain letters, digits, underscores, and hyphens (must start with a letter or underscore)
25
+ }
26
+
27
+ In the VSCode interactive preview, scopes with children display a collapsible toggle triangle on hover. Clicking the triangle collapses or expands the scope's children. Collapse state persists across preview refreshes.
28
+
29
+ # Braceless Scopes
30
+ {
31
+ A heading not followed by `{` or a block opener creates a braceless scope. Content runs until the next `#` heading, a closing `}`, or end of file:
32
+
33
+ ```
34
+ # Section A
35
+ Content of Section A.
36
+
37
+ # Section B
38
+ Content of Section B.
39
+ ```
40
+
41
+ {[.]
42
+ - Braceless scopes support paragraphs, code blocks, blockquotes, implicit lists, HRs, and tables
43
+ - Encountering another `#` heading ends the braceless scope (the heading becomes a sibling)
44
+ - A closing `}` also terminates a braceless scope
45
+ - Braceless and explicit scopes can be mixed freely
46
+ }
47
+ }
48
+
49
+ # Headingless Scopes
50
+ {
51
+ A bare `{` block without a preceding heading creates a scope with no heading:
52
+
53
+ ```
54
+ # Outer
55
+ {
56
+ Some text.
57
+
58
+ {
59
+ This content is indented one level deeper, with no heading.
60
+ }
61
+ }
62
+ ```
63
+
64
+ Headingless scopes nest like normal scopes and are useful for grouping paragraphs or adding visual indentation without a title.
65
+ }
66
+
67
+ # K&R Brace Style
68
+ {
69
+ The opening brace (or list/table opener) can appear at the end of a heading line:
70
+
71
+ ```
72
+ # Title {
73
+ Content goes here.
74
+ }
75
+
76
+ # My List {[.]
77
+ - Item 1
78
+ - Item 2
79
+ }
80
+
81
+ # Data {[table]
82
+ Name | Age
83
+ Alice | 30
84
+ }
85
+ ```
86
+
87
+ {[.]
88
+ - Works with `{`, `{[.]`, `{[#]`, `{[table]`, and `{[table <flags>]`
89
+ - Also works on list item lines: `- Item {`
90
+ - The `@id` goes before the opener: `# Title @id {`
91
+ - Table options work in K&R style: `# Data {[table borderless]`
92
+ - Trailing whitespace after the opener is allowed
93
+ - The closing `}` must still appear on its own line
94
+ - Inline blocks (`{ content }`) are not affected
95
+ }
96
+
97
+ K&R and Allman styles can be mixed freely in the same document.
98
+ }
99
+
100
+ # Inline Blocks
101
+ {
102
+ For simple content, a scope body can be written on one line:
103
+
104
+ ```
105
+ # Name
106
+ { John Doe }
107
+
108
+ # Count
109
+ { 42 }
110
+ ```
111
+
112
+ Inline blocks must not contain unescaped `{` or `}` characters.
113
+ }
114
+ }
115
+
116
+ # Paragraphs
117
+ {
118
+ Consecutive text lines are joined into a single paragraph. A blank line, a new scope, or a list ends the current paragraph.
119
+
120
+ ```
121
+ # Example
122
+ {
123
+ This is one paragraph
124
+ that spans two lines.
125
+
126
+ This is a second paragraph.
127
+ }
128
+ ```
129
+ }
130
+
131
+ # Lists
132
+ {
133
+ # Explicit Lists
134
+ {
135
+ Use `{[.]` for bulleted lists and `{[#]` for numbered lists:
136
+
137
+ ```
138
+ # Fruits
139
+ {[.]
140
+ - Apples
141
+ - Bananas
142
+ - Cherries
143
+ }
144
+
145
+ # Steps
146
+ {[#]
147
+ 1. First step
148
+ 2. Second step
149
+ 3. Third step
150
+ }
151
+ ```
152
+
153
+ List items can have bodies:
154
+
155
+ ```
156
+ {[.]
157
+ - Item title
158
+ {
159
+ Body text for this item.
160
+ }
161
+ }
162
+ ```
163
+
164
+ Commas between list items are allowed but ignored.
165
+ }
166
+
167
+ # Multi-line List Items
168
+ {
169
+ Inside an explicit list block (`{[.]` or `{[#]`), a list item's title can span multiple lines. Lines after the marker that aren't a command token are joined with a space:
170
+
171
+ ```
172
+ {[.]
173
+ - This is a long list item
174
+ that continues on the next line
175
+ - Short item
176
+ }
177
+ ```
178
+
179
+ Continuation stops at blank lines, list markers, headings, braces, code fences, blockquotes, and horizontal rules. A body block can still follow the completed multi-line title. This only applies to explicit list blocks, not implicit lists.
180
+ }
181
+
182
+ # Implicit Lists
183
+ {
184
+ Inside a normal scope, a run of `- ` lines automatically forms a bulleted list, and a run of `1. ` lines forms a numbered list:
185
+
186
+ ```
187
+ # Notes
188
+ {
189
+ - First point
190
+ - Second point
191
+ - Third point
192
+ }
193
+ ```
194
+
195
+ Mixed markers end the implicit list.
196
+ }
197
+
198
+ # Task Lists
199
+ {
200
+ Checkboxes work inside list blocks:
201
+
202
+ ```
203
+ {[.]
204
+ - [ ] Pending task
205
+ - [x] Completed task
206
+ }
207
+ ```
208
+ }
209
+
210
+ # Anonymous List Items
211
+ {
212
+ A list item can start with a block directly, without a heading:
213
+
214
+ ```
215
+ {[.]
216
+ {
217
+ This item has no heading line.
218
+ }
219
+ }
220
+ ```
221
+ }
222
+ }
223
+
224
+ # Tables
225
+ {
226
+ Use `{[table]` to create a table. The first row is the header:
227
+
228
+ ```
229
+ {[table]
230
+ Name | Age | City
231
+ Alice | 30 | New York
232
+ Bob | 25 | Los Angeles
233
+ }
234
+ ```
235
+
236
+ {[.]
237
+ - Columns are separated by `|`
238
+ - The first row is always the header (unless `headerless` is specified)
239
+ - Cell contents support inline formatting
240
+ - Leading and trailing whitespace in cells is trimmed
241
+ }
242
+
243
+ # Table Options
244
+ {
245
+ Add flags after `table` to control rendering:
246
+
247
+ ```
248
+ {[table borderless]
249
+ Feature | Status
250
+ Parser | Complete
251
+ Renderer | Complete
252
+ }
253
+
254
+ {[table headerless]
255
+ Alice | 30 | New York
256
+ Bob | 25 | Los Angeles
257
+ }
258
+
259
+ {[table borderless headerless]
260
+ ![](a.png =100%) | ![](b.png =100%)
261
+ ![](c.png =100%) | ![](d.png =100%)
262
+ }
263
+ ```
264
+
265
+ {[.]
266
+ - `borderless` removes all borders and row striping
267
+ - `headerless` treats the first row as data (no header)
268
+ - Flags can be combined in any order
269
+ - Works with K&R brace style: `# Data {[table borderless]`
270
+ }
271
+ }
272
+ }
273
+
274
+ # Inline Formatting
275
+ {
276
+ {[.]
277
+ - `*emphasis*` renders as *emphasis*
278
+ - `**strong**` renders as **strong**
279
+ - `~~strikethrough~~` renders as ~~strikethrough~~
280
+ - `` `code` `` renders as `code`
281
+ - `$x^2$` renders as inline math (KaTeX)
282
+ - `$$E = mc^2$$` renders as display math (centered)
283
+ - `{+text+}` renders as {+positive (green) marker+}
284
+ - `{=text=}` renders as {=neutral (blue) marker=}
285
+ - `{^text^}` renders as {^note (amber) marker^}
286
+ - `{?text?}` renders as {?caution (dark amber) marker?}
287
+ - `{!text!}` renders as {!warning (orange) marker!}
288
+ - `{-text-}` renders as {-negative (red) marker-}
289
+ - `{~text~}` renders as {~highlighted text~}
290
+ }
291
+
292
+ A plain `$` followed by a digit (e.g. `$100`) does not trigger math. Use `\$` to escape dollar signs adjacent to math.
293
+ }
294
+
295
+ # Links and Images
296
+ {
297
+ # Links
298
+ {
299
+ ```
300
+ [Link text](https://example.com)
301
+ ```
302
+ }
303
+
304
+ # Autolinks
305
+ {
306
+ ```
307
+ <https://example.com>
308
+ <mailto:hello@example.com>
309
+ ```
310
+
311
+ Only `http`, `https`, and `mailto` schemes are recognised.
312
+ }
313
+
314
+ # Images
315
+ {
316
+ ```
317
+ ![Alt text](https://example.com/image.png)
318
+ ```
319
+
320
+ # Image Width and Alignment
321
+ {
322
+ Add `=<width>` after the URL (separated by a space) to control size. An optional alignment keyword follows:
323
+
324
+ ```
325
+ ![Photo](photo.png =50%)
326
+ ![Photo](photo.png =200px)
327
+ ![Photo](photo.png =50% center)
328
+ ![Photo](photo.png =35% left)
329
+ ![Photo](photo.png =35% right)
330
+ ```
331
+
332
+ {[.]
333
+ - `center` centres the image with auto margins
334
+ - `left` floats the image left (text wraps right)
335
+ - `right` floats the image right (text wraps left)
336
+ - Without alignment, images display inline — two adjacent images with widths sit side by side
337
+ }
338
+ }
339
+ }
340
+ }
341
+
342
+ # References
343
+ {
344
+ Tag a scope with `@id` on its heading line, then reference it anywhere with `@id` in text:
345
+
346
+ ```
347
+ # Overview @overview
348
+ {
349
+ This section is tagged.
350
+ }
351
+
352
+ # Details
353
+ {
354
+ See @overview for the introduction.
355
+ }
356
+ ```
357
+
358
+ References render as clickable links to the target scope.
359
+ }
360
+
361
+ # Blockquotes
362
+ {
363
+ Lines starting with `>` form a blockquote:
364
+
365
+ ```
366
+ > A quoted line.
367
+ > Another line in the same quote.
368
+ ```
369
+
370
+ A blank `>` line breaks paragraphs within the blockquote. Escape with `\>` to use a literal `>` at the start of a line.
371
+ }
372
+
373
+ # Code Blocks
374
+ {
375
+ Fenced code blocks use three backticks to delimit raw text. An optional language tag follows the opening fence.
376
+
377
+ {[.]
378
+ - Opening fence: three backticks, optionally followed by a language name (e.g. `javascript`, `python`)
379
+ - Closing fence: three backticks on their own line
380
+ - Content inside is raw text -- no parsing, no escapes, no inline formatting
381
+ - Braces, `#`, `@`, and all other special characters are treated as literal text inside code blocks
382
+ - The special language tag `math` renders the block as a display equation via KaTeX (no copy button)
383
+ - The special language tag `mermaid` renders the block as an SVG diagram
384
+ }
385
+
386
+ # Include by Link
387
+ {
388
+ A code block can reference an external file with `src:` metadata on the fence line. The file contents replace the code block body:
389
+
390
+ `````
391
+ ```json src:./data.json
392
+ ```
393
+
394
+ ```json src:./data.json lines:3-5
395
+ ```
396
+
397
+ ```src:https://example.com/schema.json
398
+ ```
399
+ `````
400
+
401
+ {[.]
402
+ - `src:<path>` references a file (relative to the document) or URL
403
+ - `lines:<start>-<end>` limits to a line range (1-based, inclusive)
404
+ - The language tag is optional and goes before `src:`
405
+ - If the file cannot be read, an error message is shown in the code block
406
+ }
407
+ }
408
+ }
409
+
410
+ # Horizontal Rules
411
+ {
412
+ A line of three or more identical characters (`-`, `*`, or `_`):
413
+
414
+ ```
415
+ ---
416
+ ```
417
+ }
418
+
419
+ # Escaping
420
+ {
421
+ A backslash escapes special characters: `\\` `\{` `\}` `\@` `\[` `\]` `\(` `\)` `\*` `\~` `\#` `\!` `\<` `\>` `\$` and `` \` ``.
422
+
423
+ {[.]
424
+ - `\#` at the start of a line makes it a paragraph line instead of a heading
425
+ - `\>` at the start of a line makes it a paragraph line instead of a blockquote
426
+ - `\$` prevents a dollar sign from starting math mode
427
+ - Escapes are processed before reference detection
428
+ }
429
+ }
430
+
431
+ # Implicit Root
432
+ {
433
+ If the first heading in a document is not followed by `{` or a block opener, the entire document is wrapped in an implicit root scope:
434
+
435
+ ```
436
+ # My Document
437
+
438
+ # Section A
439
+ Content of section A.
440
+
441
+ # Section B
442
+ {
443
+ Content of section B.
444
+ }
445
+ ```
446
+
447
+ This is equivalent to wrapping everything after the first heading in `{ ... }`. If the first heading IS followed by `{`, the document uses explicit root mode (existing behavior).
448
+ }
449
+
450
+ # Meta Scope
451
+ {
452
+ A reserved `@meta` scope at the top level overrides rendering options per file:
453
+
454
+ ```
455
+ # Meta @meta
456
+ {
457
+ # Style
458
+ { path/to/custom.css }
459
+ # StyleAppend
460
+ { path/to/overrides.css }
461
+ # Header
462
+ { My *custom* header }
463
+ # Footer
464
+ { Page-specific footer }
465
+ }
466
+ ```
467
+
468
+ {[.]
469
+ - The `@meta` scope is not rendered in the document body
470
+ - `Style` and `StyleAppend` are file paths relative to the SDOC file
471
+ - `Header` and `Footer` support inline formatting
472
+ - Per-file meta overrides `sdoc.config.json` values
473
+ }
474
+
475
+ # Key:Value Meta Syntax
476
+ {
477
+ For simpler metadata, use key:value pairs instead of sub-scopes:
478
+
479
+ ```
480
+ # Meta @meta
481
+ {
482
+ style: path/to/custom.css
483
+ header: My Header
484
+ footer: My Footer
485
+ author: Jane Smith
486
+ date: 2026-02-09
487
+ version: 1.0
488
+ sdoc-version: 0.1
489
+ }
490
+ ```
491
+
492
+ {[.]
493
+ - Key matching is case-insensitive
494
+ - Requires at least one space after the colon
495
+ - Well-known keys: `style`, `styleappend`/`style-append`, `header`, `footer`, `sdoc-version`
496
+ - `sdoc-version` identifies the format version (current: `0.1`); a warning is emitted when missing
497
+ - Other keys (e.g., `author`, `date`, `version`) are stored as custom properties
498
+ - Sub-scope syntax takes precedence over key:value when both exist
499
+ }
500
+ }
501
+ }
502
+ }
@@ -0,0 +1,117 @@
1
+ # First Steps with SDOC
2
+ {
3
+ @meta {
4
+ sdoc-version: 0.1
5
+ }
6
+
7
+ # Step 1: Create a File
8
+ {
9
+ Create a new file with a `.sdoc` extension, for example `notes.sdoc`:
10
+
11
+ ```
12
+ # My Notes
13
+
14
+ Hello, this is my first SDOC document.
15
+ ```
16
+
17
+ The simplest SDOC file is just a heading followed by content. The heading becomes the document title and everything after it is the body (this is called an implicit root scope). You can also use explicit braces for more control:
18
+
19
+ ```
20
+ # My Notes
21
+ {
22
+ Hello, this is my first SDOC document.
23
+ }
24
+ ```
25
+ }
26
+
27
+ # Step 2: Add Nested Sections
28
+ {
29
+ Add structure by nesting scopes inside the top-level block:
30
+
31
+ ```
32
+ # My Notes
33
+ {
34
+ # Introduction
35
+ {
36
+ This is the introduction.
37
+ }
38
+
39
+ # Details
40
+ {
41
+ Here are the details.
42
+ }
43
+ }
44
+ ```
45
+
46
+ Each nested scope renders as a subsection with a smaller heading.
47
+ }
48
+
49
+ # Step 3: Preview in VS Code
50
+ {
51
+ Open your `.sdoc` file in VS Code and run the command **SDOC: Open Preview to the Side**. You should see a rendered view that updates as you type.
52
+ }
53
+
54
+ # Step 4: Add Formatting
55
+ {
56
+ Try adding inline formatting, math, and a list:
57
+
58
+ ```
59
+ # My Notes
60
+ {
61
+ # Introduction
62
+ {
63
+ SDOC supports *emphasis*, **strong**, `code`, ~~strikethrough~~, and math like $E = mc^2$.
64
+
65
+ Semantic markers: {+passed+}, {=info=}, {^note^}, {?caution?}, {!warning!}, {-failed-}, and {~highlighted~}.
66
+ }
67
+
68
+ # To Do
69
+ {[.]
70
+ - [ ] Learn the basics
71
+ - [ ] Write a real document
72
+ - [x] Install the extension
73
+ }
74
+ }
75
+ ```
76
+ }
77
+
78
+ # Step 5: Use References
79
+ {
80
+ Tag sections with `@id` and cross-reference them:
81
+
82
+ ```
83
+ # Overview @overview
84
+ {
85
+ This section introduces the project.
86
+ }
87
+
88
+ # Details
89
+ {
90
+ As described in @overview, the project has three parts.
91
+ }
92
+ ```
93
+
94
+ The `@overview` in the text becomes a clickable link to the tagged section.
95
+ }
96
+
97
+ # Step 6: Add Blockquotes and Code
98
+ {
99
+ Blockquotes use `>` at the start of each line:
100
+
101
+ ```
102
+ > Documentation is a love letter
103
+ > that you write to your future self.
104
+ ```
105
+
106
+ Code blocks use three backticks as opening and closing fences, with an optional language tag. Everything inside is raw text -- braces, `#`, and `@` are not parsed.
107
+ }
108
+
109
+ # What's Next
110
+ {
111
+ {[.]
112
+ - Read `docs/reference/syntax.sdoc` for all available features
113
+ - Read `docs/reference/cli.sdoc` for the document server and CLI tools
114
+ - Look at `examples/example.sdoc` for a quick-reference document
115
+ }
116
+ }
117
+ }
package/knowledge.js CHANGED
@@ -1,2 +1,12 @@
1
1
  const path = require('path');
2
+
3
+ // Knowledge files shipped with this package for consumption by MCP servers
4
+ // and other knowledge infrastructure. Each entry has a cache key and absolute path.
5
+ module.exports.knowledgeFiles = [
6
+ { key: 'specification.sdoc', path: path.join(__dirname, 'lexica', 'specification.sdoc') },
7
+ { key: 'sdoc-authoring.sdoc', path: path.join(__dirname, 'docs', 'reference', 'sdoc-authoring.sdoc') },
8
+ { key: 'slide-authoring.sdoc', path: path.join(__dirname, 'docs', 'reference', 'slide-authoring.sdoc') },
9
+ ];
10
+
11
+ // Backward compat — prefer knowledgeFiles for explicit file enumeration
2
12
  module.exports.knowledgeDir = path.join(__dirname, 'lexica');
package/llms.txt ADDED
@@ -0,0 +1,20 @@
1
+ # SDOC
2
+
3
+ > A plain-text documentation format with explicit brace scoping. Deterministic parsing, surgical section extraction, and 10-50x token savings compared to Markdown. Zero-dependency JavaScript parser, VS Code extension, slide generation, and PDF export.
4
+
5
+ SDOC uses `{ }` braces to define document structure explicitly. Two parsers, same input, same tree — always. AI agents can navigate an SDOC knowledge base in ~200 tokens of discovery, then extract exactly the section they need in ~200-1000 tokens, instead of loading entire files at 5,000-50,000 tokens each.
6
+
7
+ The authoring guide (`docs/reference/sdoc-authoring.sdoc`) is written as an AI agent skill document. Drop it into any agent's context and it can read and write SDOC immediately.
8
+
9
+ ## Docs
10
+
11
+ - [SDOC Authoring Guide](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/reference/sdoc-authoring.sdoc): Skill document — how to write correct SDOC files. Covers document structure, inline formatting, block types (lists, tables, code, blockquotes), mermaid diagrams, and common mistakes. Start here to learn the format.
12
+ - [SDOC Specification](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/lexica/specification.sdoc): Formal v0.1 specification with EBNF grammar. Defines syntax for scopes, lists, tables, code blocks, inline formatting, references, and the meta scope.
13
+ - [Why SDOC Over Markdown](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/guide/why-sdoc.sdoc): The case for SDOC — structural problems with Markdown, why explicit scoping solves them, parsing safety as a security property, and the adoption path forward.
14
+
15
+ ## Optional
16
+
17
+ - [Requirements](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/lexica/requirements.sdoc): Why SDOC exists and what it must achieve. Ten abstract requirements (R1-R10) and concrete constraints (C1-C6).
18
+ - [Slide Authoring Guide](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/reference/slide-authoring.sdoc): How to create HTML slide decks from SDOC files.
19
+ - [Introduction](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/guide/intro.sdoc): Gentle introduction to the format for newcomers.
20
+ - [Syntax Reference](https://raw.githubusercontent.com/entropicwarrior/sdoc/main/docs/reference/syntax.sdoc): Practical syntax reference with examples.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@entropicwarrior/sdoc",
3
3
  "displayName": "SDOC",
4
4
  "description": "A plain-text documentation format with explicit brace scoping — deterministic parsing, AI-agent efficiency, and 10-50x token savings vs Markdown.",
5
- "version": "0.1.14",
5
+ "version": "0.1.17",
6
6
  "publisher": "entropicwarrior",
7
7
  "license": "MIT",
8
8
  "repository": {
File without changes
File without changes