@entropicwarrior/sdoc 0.2.3 → 0.2.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.
@@ -265,6 +265,15 @@ Content of Section B.
265
265
  ```
266
266
 
267
267
  Width: \`auto\` (shrink to content), \`NN%\` (percentage), or \`NNpx\` (pixels). Default is 100%. Alignment: \`left\` (default), \`center\`, or \`right\`. All flags compose freely in any order.
268
+
269
+ To include a literal \`|\` in a cell (e.g. for math), escape it with \`\\|\`:
270
+
271
+ ```
272
+ {[table]
273
+ Expression | Value
274
+ \|x\| + \|y\| | 8
275
+ }
276
+ ```
268
277
  }
269
278
 
270
279
  # Inline Formatting @inline-formatting
@@ -470,7 +479,7 @@ Content of Section B.
470
479
  {
471
480
  Backslash escapes special characters: \`\\\\\` \`\\{\` \`\\}\` \`\\@\`
472
481
  \`\\[\` \`\\]\` \`\\(\` \`\\)\` \`\\*\` \`\\~\` \`\\#\` \`\\!\` \`\\\<\`
473
- \`\\\>\` \`\\\$\` \`\\+\` \`\\=\` \`\\-\` \`\\^\` \`\\?\`
482
+ \`\\\>\` \`\\\$\` \`\\+\` \`\\=\` \`\\-\` \`\\^\` \`\\?\` \`\\|\`
474
483
 
475
484
  A line starting with \`\\#\` renders as a literal \`#\` (not a heading). Use \`\\\$\` to prevent a dollar sign from starting math mode.
476
485
  }
@@ -510,11 +510,11 @@ Content of Section B.
510
510
 
511
511
  # Escaping @escaping
512
512
  {
513
- In normal text (including headings and paragraphs), a backslash escapes: `\\` `\{` `\}` `\@` `\[` `\]` `\(` `\)` `\*` `\~` `\#` `\!` `\<` `\>` `\$` `\+` `\=` `\-` `\^` `\?` and `` \` ``.
513
+ In normal text (including headings and paragraphs), a backslash escapes: `\\` `\{` `\}` `\@` `\[` `\]` `\(` `\)` `\*` `\~` `\#` `\!` `\<` `\>` `\$` `\+` `\=` `\-` `\^` `\?` `\|` and `` \` ``.
514
514
 
515
515
  Escapes are processed before reference detection.
516
516
 
517
- If a line begins with `\#`, it is treated as a normal paragraph line (rendered with a literal `#`). If a line begins with `\>`, it is treated as a normal paragraph line (rendered with a literal `>`). Use `\$` to prevent a dollar sign from starting math mode.
517
+ If a line begins with `\#`, it is treated as a normal paragraph line (rendered with a literal `#`). If a line begins with `\>`, it is treated as a normal paragraph line (rendered with a literal `>`). Use `\$` to prevent a dollar sign from starting math mode. Use `\|` to include a literal pipe character inside a table cell without it being treated as a column delimiter.
518
518
  }
519
519
 
520
520
  # Code Blocks @code-blocks
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.2.3",
5
+ "version": "0.2.5",
6
6
  "publisher": "entropicwarrior",
7
7
  "license": "MIT",
8
8
  "repository": {
package/src/sdoc.js CHANGED
@@ -13,7 +13,7 @@ const COMMAND_LIST_NUMBER = "{[#]";
13
13
  const COMMAND_TABLE = "{[table]";
14
14
  const COMMAND_CODE_FENCE = "```";
15
15
 
16
- const ESCAPABLE = new Set(["\\", "{", "}", "@", "[", "]", "(", ")", "*", "`", "#", "!", "~", "<", ">", "$", "+", "=", "-", "^", "?"]);
16
+ const ESCAPABLE = new Set(["\\", "{", "}", "@", "[", "]", "(", ")", "*", "`", "#", "!", "~", "<", ">", "$", "+", "=", "-", "^", "?", "|"]);
17
17
 
18
18
  let _katex = null;
19
19
  let _katexLoaded = false;
@@ -797,7 +797,7 @@ function parseTableBody(cursor, tableStartLine, options) {
797
797
  break;
798
798
  }
799
799
 
800
- const cells = trimmed.split("|").map((cell) => cell.trim());
800
+ const cells = trimmed.split(/(?<!\\)\|/).map((cell) => cell.trim().replace(/\\\|/g, "|"));
801
801
  rows.push(cells);
802
802
  cursor.next();
803
803
  }
@@ -1309,7 +1309,35 @@ function parseInline(text) {
1309
1309
  }
1310
1310
  }
1311
1311
 
1312
- if (ch === "@" && next && isIdentStart(next)) {
1312
+ // Bare email autolink: local@domain.tld
1313
+ if (ch === "@" && next && /[A-Za-z0-9]/.test(next)) {
1314
+ const prevCh = i > 0 ? text[i - 1] : "";
1315
+ if (/[A-Za-z0-9._+-]/.test(prevCh)) {
1316
+ // Scan forward for domain part (letters, digits, dots, hyphens)
1317
+ let j = i + 1;
1318
+ while (j < text.length && /[A-Za-z0-9.-]/.test(text[j])) j++;
1319
+ // Strip trailing dots/hyphens
1320
+ while (j > i + 1 && /[.-]/.test(text[j - 1])) j--;
1321
+ const domain = text.slice(i + 1, j);
1322
+ // Must have at least one dot with content on both sides
1323
+ if (/^[A-Za-z0-9]([A-Za-z0-9-]*\.)+[A-Za-z]{2,}$/.test(domain)) {
1324
+ // Extract local part from buffer
1325
+ let k = buffer.length;
1326
+ while (k > 0 && /[A-Za-z0-9._+\-]/.test(buffer[k - 1])) k--;
1327
+ const local = buffer.slice(k);
1328
+ if (local.length > 0) {
1329
+ buffer = buffer.slice(0, k);
1330
+ const email = local + "@" + domain;
1331
+ flush();
1332
+ nodes.push({ type: "link", href: "mailto:" + email, children: [{ type: "text", value: email }] });
1333
+ i = j;
1334
+ continue;
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+
1340
+ if (ch === "@" && next && isIdentStart(next) && !(i > 0 && /[A-Za-z0-9._+-]/.test(text[i - 1]))) {
1313
1341
  let j = i + 1;
1314
1342
  while (j < text.length && isIdentChar(text[j])) {
1315
1343
  j += 1;