@entropicwarrior/sdoc 0.2.1 → 0.2.2
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/package.json +1 -1
- package/src/sdoc.js +54 -2
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.
|
|
5
|
+
"version": "0.2.2",
|
|
6
6
|
"publisher": "entropicwarrior",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
package/src/sdoc.js
CHANGED
|
@@ -2122,6 +2122,36 @@ const PRINT_STYLE = `
|
|
|
2122
2122
|
|
|
2123
2123
|
const MERMAID_CDN = "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js";
|
|
2124
2124
|
const KATEX_CDN_CSS = "https://cdn.jsdelivr.net/npm/katex@0.16/dist/katex.min.css";
|
|
2125
|
+
const HLJS_CDN = "https://cdn.jsdelivr.net/npm/@highlightjs/cdn-assets@11.11.1/highlight.min.js";
|
|
2126
|
+
|
|
2127
|
+
// Custom highlight.js grammar for SDOC language – registered before highlightElement calls
|
|
2128
|
+
const HLJS_SDOC_GRAMMAR = `hljs.registerLanguage('sdoc',function(hljs){return{name:'SDOC',aliases:['sdoc'],contains:[
|
|
2129
|
+
hljs.COMMENT('^\\\\s*//','$'),
|
|
2130
|
+
{className:'section',begin:'^\\\\s*#+\\\\s+',end:'$',contains:[
|
|
2131
|
+
{className:'symbol',begin:'@[A-Za-z_][A-Za-z0-9_-]*'}
|
|
2132
|
+
]},
|
|
2133
|
+
{className:'meta',begin:'^\\\\s*@[A-Za-z_][A-Za-z0-9_-]*',end:'(?=\\\\s*\\\\{|$)'},
|
|
2134
|
+
{className:'code',begin:'\`\`\`',end:'\`\`\`',contains:[hljs.BACKSLASH_ESCAPE]},
|
|
2135
|
+
{className:'code',begin:'\`[^\`]+\`'},
|
|
2136
|
+
{className:'string',begin:'\\\\[',end:'\\\\]\\\\([^)]*\\\\)',contains:[
|
|
2137
|
+
{className:'link',begin:'\\\\(',end:'\\\\)'}
|
|
2138
|
+
]},
|
|
2139
|
+
{className:'keyword',begin:'\\\\{[!?+\\\\-=~^]',end:'[!?+\\\\-=~^]\\\\}'},
|
|
2140
|
+
{className:'keyword',begin:'\\\\{\\\\[(?:\\\\.|#|\\\\d+|table)\\\\]'},
|
|
2141
|
+
{className:'strong',begin:'\\\\*\\\\*',end:'\\\\*\\\\*'},
|
|
2142
|
+
{className:'emphasis',begin:'(?<!\\\\*)\\\\*(?!\\\\*)',end:'\\\\*(?!\\\\*)'},
|
|
2143
|
+
{className:'deletion',begin:'~~',end:'~~'},
|
|
2144
|
+
{className:'bullet',begin:'^\\\\s*[-]\\\\s'},
|
|
2145
|
+
{className:'bullet',begin:'^\\\\s*\\\\d+[.)]\\\\ '},
|
|
2146
|
+
{className:'quote',begin:'^\\\\s*>',end:'$'},
|
|
2147
|
+
{className:'symbol',begin:'(?<!\\\\\\\\)@[A-Za-z_][A-Za-z0-9_-]*'},
|
|
2148
|
+
{className:'attr',begin:'[A-Za-z_][A-Za-z0-9_-]*(?=\\\\s*:)',end:':',excludeEnd:true}
|
|
2149
|
+
]}});`;
|
|
2150
|
+
|
|
2151
|
+
// Highlight.js GitHub light theme (inline so it works inside shadow DOM in the web viewer)
|
|
2152
|
+
const HLJS_LIGHT_CSS = "pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}";
|
|
2153
|
+
// Highlight.js GitHub dark theme color overrides (used in @media and VS Code dark-mode CSS)
|
|
2154
|
+
const HLJS_DARK_COLORS_CSS = ".hljs{color:#c9d1d9;background:transparent}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}";
|
|
2125
2155
|
|
|
2126
2156
|
function hasMermaidBlocks(nodes) {
|
|
2127
2157
|
for (const node of nodes) {
|
|
@@ -2136,6 +2166,19 @@ function hasMermaidBlocks(nodes) {
|
|
|
2136
2166
|
return false;
|
|
2137
2167
|
}
|
|
2138
2168
|
|
|
2169
|
+
function hasHighlightableCodeBlocks(nodes) {
|
|
2170
|
+
for (const node of nodes) {
|
|
2171
|
+
if (node.type === "code" && node.lang && node.lang !== "mermaid" && node.lang !== "math") return true;
|
|
2172
|
+
if (node.children && hasHighlightableCodeBlocks(node.children)) return true;
|
|
2173
|
+
if (node.items) {
|
|
2174
|
+
for (const item of node.items) {
|
|
2175
|
+
if (item.children && hasHighlightableCodeBlocks(item.children)) return true;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
return false;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2139
2182
|
function renderBodyNodes(nodes) {
|
|
2140
2183
|
return nodes
|
|
2141
2184
|
.map((node, index) => {
|
|
@@ -2186,6 +2229,15 @@ function renderHtmlDocumentFromParsed(parsed, title, options = {}) {
|
|
|
2186
2229
|
const katexCssTag = body.includes('class="katex"')
|
|
2187
2230
|
? `\n<link rel="stylesheet" href="${KATEX_CDN_CSS}" />`
|
|
2188
2231
|
: "";
|
|
2232
|
+
const hasHljs = hasHighlightableCodeBlocks(parsed.nodes);
|
|
2233
|
+
// Highlight.js CSS is inlined (not a <link>) so it is extracted by parseDocHtml in the web viewer
|
|
2234
|
+
// and applied inside shadow DOM. The @media query handles dark mode in browsers.
|
|
2235
|
+
const hljsCssInline = hasHljs
|
|
2236
|
+
? `\n${HLJS_LIGHT_CSS}\n.sdoc-code code.hljs{padding:0;background:transparent}\n@media (prefers-color-scheme:dark){${HLJS_DARK_COLORS_CSS}}`
|
|
2237
|
+
: "";
|
|
2238
|
+
const hljsScript = hasHljs
|
|
2239
|
+
? `\n<script src="${HLJS_CDN}"></script>\n<script>${HLJS_SDOC_GRAMMAR}\ndocument.querySelectorAll('pre.sdoc-code code[class*="language-"]').forEach(function(b){hljs.highlightElement(b);});</script>`
|
|
2240
|
+
: "";
|
|
2189
2241
|
|
|
2190
2242
|
return `<!DOCTYPE html>
|
|
2191
2243
|
<html lang="en">
|
|
@@ -2194,7 +2246,7 @@ function renderHtmlDocumentFromParsed(parsed, title, options = {}) {
|
|
|
2194
2246
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
2195
2247
|
<title>${escapeHtml(title)}</title>
|
|
2196
2248
|
<style>
|
|
2197
|
-
${cssBase}${cssAppend}
|
|
2249
|
+
${cssBase}${cssAppend}${hljsCssInline}
|
|
2198
2250
|
</style>${katexCssTag}
|
|
2199
2251
|
</head>
|
|
2200
2252
|
<body>
|
|
@@ -2208,7 +2260,7 @@ ${cssBase}${cssAppend}
|
|
|
2208
2260
|
</main>
|
|
2209
2261
|
</div>
|
|
2210
2262
|
${footerContent ? `<footer class="sdoc-page-footer">${footerContent}</footer>` : ""}
|
|
2211
|
-
</div>${scriptTag}${mermaidScript}
|
|
2263
|
+
</div>${scriptTag}${mermaidScript}${hljsScript}
|
|
2212
2264
|
</body>
|
|
2213
2265
|
</html>`;
|
|
2214
2266
|
}
|