@staticbolt/docs 0.0.1-beta.1 → 0.0.1-beta.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/lib/ec-config.mjs +2 -1
- package/lib/{collapsible-plugin-Bwt7dmKE.mjs → html-ts-script-lang-DthQZbmB.mjs} +45 -1
- package/lib/index.d.mts +10 -1
- package/lib/plugins.mjs +2 -2
- package/package.json +2 -2
- package/sources/parts/callouts/callouts.part.html +1 -1
- package/sources/parts/color-scheme-switch/color-scheme-switch.part.html +4 -10
- package/sources/parts/document/document.part.html +1 -1
- package/sources/parts/header/header.part.html +3 -7
- package/sources/parts/mermaid/mermaid.part.html +1 -1
- package/sources/parts/pagefind/pagefind.part.html +5 -10
- package/sources/parts/pagination-links/pagination-links.part.html +1 -1
- package/sources/parts/sidebar/sidebar.part.html +5 -6
- package/sources/parts/table-of-content/table-of-content-desktop.part.html +2 -2
- package/sources/parts/table-of-content/table-of-content-mobile.part.html +1 -1
package/lib/ec-config.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as pluginCollapsible, t as htmlWithTypeScriptScripts } from "./html-ts-script-lang-DthQZbmB.mjs";
|
|
2
2
|
import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections";
|
|
3
3
|
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
|
|
4
4
|
import { pluginFileIcons } from "@xt0rted/expressive-code-file-icons";
|
|
@@ -17,6 +17,7 @@ const rehypeExpressiveCodeOptions = {
|
|
|
17
17
|
collapseStyle: "collapsible-auto"
|
|
18
18
|
},
|
|
19
19
|
useDarkModeMediaQuery: false,
|
|
20
|
+
shiki: { langs: [htmlWithTypeScriptScripts] },
|
|
20
21
|
styleOverrides: {
|
|
21
22
|
codeBackground: "var(--sb-code-background)",
|
|
22
23
|
borderColor: "var(--sb-color-gray-5)",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { definePlugin } from "@expressive-code/core";
|
|
2
2
|
import { h } from "@expressive-code/core/hast";
|
|
3
|
+
import htmlLangs from "@shikijs/langs/html";
|
|
4
|
+
import tsLangs from "@shikijs/langs/typescript";
|
|
3
5
|
//#region plugins/collapsible-plugin.ts
|
|
4
6
|
/**
|
|
5
7
|
* Collapses opted-in code blocks to a fixed number of preview lines.
|
|
@@ -129,4 +131,46 @@ function pluginCollapsible(options = {}) {
|
|
|
129
131
|
});
|
|
130
132
|
}
|
|
131
133
|
//#endregion
|
|
132
|
-
|
|
134
|
+
//#region plugins/html-ts-script-lang.ts
|
|
135
|
+
const typeAlternation = ["application/x-typescript"].map((t) => t.replace(/[/+.-]/g, String.raw`\$&`)).join("|");
|
|
136
|
+
const typescriptScriptPattern = {
|
|
137
|
+
begin: String.raw`(?i:(?=type\s*=\s*(["']?)(?:${typeAlternation})["'>\s]))`,
|
|
138
|
+
end: "((<))(?=/(?i:script))",
|
|
139
|
+
endCaptures: {
|
|
140
|
+
"0": { name: "meta.tag.metadata.script.end.html" },
|
|
141
|
+
"1": { name: "punctuation.definition.tag.begin.html" },
|
|
142
|
+
"2": { name: "source.ts" }
|
|
143
|
+
},
|
|
144
|
+
patterns: [{
|
|
145
|
+
begin: String.raw`\G`,
|
|
146
|
+
end: "(>)",
|
|
147
|
+
endCaptures: { "1": { name: "punctuation.definition.tag.end.html" } },
|
|
148
|
+
name: "meta.tag.metadata.script.start.html",
|
|
149
|
+
patterns: [{ include: "#attribute" }]
|
|
150
|
+
}, {
|
|
151
|
+
begin: String.raw`(?!\G)`,
|
|
152
|
+
end: "(?=</(?i:script))",
|
|
153
|
+
name: "source.ts",
|
|
154
|
+
patterns: [{ include: "source.ts" }]
|
|
155
|
+
}]
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Shiki's bundled HTML grammar only highlights `<script>` contents when the `type` attribute is a known JavaScript type, leaving
|
|
159
|
+
* TypeScript script blocks unhighlighted. These registrations are a drop-in replacement for the `html` language that also embeds
|
|
160
|
+
* TypeScript.
|
|
161
|
+
*/
|
|
162
|
+
const htmlWithTypeScriptScripts = (() => {
|
|
163
|
+
const langs = structuredClone(htmlLangs);
|
|
164
|
+
const html = langs.find((lang) => lang.scopeName === "text.html.basic");
|
|
165
|
+
if (!html) {
|
|
166
|
+
console.warn("[html-ts-script-lang] Shiki's HTML grammar was not found; TypeScript script blocks stay unhighlighted.");
|
|
167
|
+
return [...langs, ...tsLangs];
|
|
168
|
+
}
|
|
169
|
+
const scriptTag = html.repository?.["tags-valid"]?.patterns?.[1]?.patterns?.[0]?.patterns?.[0];
|
|
170
|
+
if (scriptTag?.patterns) scriptTag.patterns.splice(2, 0, typescriptScriptPattern);
|
|
171
|
+
else console.warn("[html-ts-script-lang] Shiki's HTML script-tag patterns moved; TypeScript script blocks stay unhighlighted.");
|
|
172
|
+
html.embeddedLangs = [...html.embeddedLangs ?? [], "typescript"];
|
|
173
|
+
return [...langs, ...tsLangs];
|
|
174
|
+
})();
|
|
175
|
+
//#endregion
|
|
176
|
+
export { pluginCollapsible as n, htmlWithTypeScriptScripts as t };
|
package/lib/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { Plugin } from "@staticbolt/core";
|
|
|
2
2
|
import { RehypeExpressiveCodeOptions } from "rehype-expressive-code";
|
|
3
3
|
import { ExpressiveCodePlugin } from "@expressive-code/core";
|
|
4
4
|
import { Root } from "hast";
|
|
5
|
+
import { LanguageRegistration } from "shiki";
|
|
5
6
|
import { Plugin as Plugin$1 } from "unified";
|
|
6
7
|
import { Root as Root$1 } from "mdast";
|
|
7
8
|
import { Node } from "unist";
|
|
@@ -269,6 +270,14 @@ declare function ecCachePlugin(): Plugin;
|
|
|
269
270
|
*/
|
|
270
271
|
declare function cachedRehypeExpressiveCode(this: unknown, options: RehypeExpressiveCodeOptions): (tree: Root, ...rest: unknown[]) => Promise<Root | undefined>;
|
|
271
272
|
//#endregion
|
|
273
|
+
//#region plugins/html-ts-script-lang.d.ts
|
|
274
|
+
/**
|
|
275
|
+
* Shiki's bundled HTML grammar only highlights `<script>` contents when the `type` attribute is a known JavaScript type, leaving
|
|
276
|
+
* TypeScript script blocks unhighlighted. These registrations are a drop-in replacement for the `html` language that also embeds
|
|
277
|
+
* TypeScript.
|
|
278
|
+
*/
|
|
279
|
+
declare const htmlWithTypeScriptScripts: LanguageRegistration[];
|
|
280
|
+
//#endregion
|
|
272
281
|
//#region plugins/katex-fonts-plugin.d.ts
|
|
273
282
|
/**
|
|
274
283
|
* Ships the KaTeX fonts `katex.css` loads. In production, references into the theme's `sources/assets` are rewritten to
|
|
@@ -374,4 +383,4 @@ declare function pagefindPlugin({ glob }?: PagefindPluginOptions): Plugin;
|
|
|
374
383
|
//#region plugins/wrap-table.d.ts
|
|
375
384
|
declare function wrapTables(): (tree: Node) => void;
|
|
376
385
|
//#endregion
|
|
377
|
-
export { CollapsiblePluginOptions, HtmlCodeBlockPlugin, PersistentCache, RemarkObsidianCommentsOptions, cachedRehypeExpressiveCode, contentPlugin, ecCachePlugin, ecCacheSalt, katexFontsPlugin, llmsPlugin, normalizeTitle, pagefindPlugin, pluginCollapsible, rehypeMermaidFence, remarkObsidianComments, remarkObsidianTags, sha1, wrapTables };
|
|
386
|
+
export { CollapsiblePluginOptions, HtmlCodeBlockPlugin, PersistentCache, RemarkObsidianCommentsOptions, cachedRehypeExpressiveCode, contentPlugin, ecCachePlugin, ecCacheSalt, htmlWithTypeScriptScripts, katexFontsPlugin, llmsPlugin, normalizeTitle, pagefindPlugin, pluginCollapsible, rehypeMermaidFence, remarkObsidianComments, remarkObsidianTags, sha1, wrapTables };
|
package/lib/plugins.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as pluginCollapsible, t as htmlWithTypeScriptScripts } from "./html-ts-script-lang-DthQZbmB.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { isHtmlMetadata, isValidRelativePath, path, splitHtmlLink } from "@staticbolt/core";
|
|
4
4
|
import { ExpressiveCodeBlock } from "expressive-code";
|
|
@@ -1122,4 +1122,4 @@ function wrapTables() {
|
|
|
1122
1122
|
};
|
|
1123
1123
|
}
|
|
1124
1124
|
//#endregion
|
|
1125
|
-
export { HtmlCodeBlockPlugin, PersistentCache, cachedRehypeExpressiveCode, contentPlugin, ecCachePlugin, ecCacheSalt, katexFontsPlugin, llmsPlugin, normalizeTitle, pagefindPlugin, pluginCollapsible, rehypeMermaidFence, remarkObsidianComments, remarkObsidianTags, sha1, wrapTables };
|
|
1125
|
+
export { HtmlCodeBlockPlugin, PersistentCache, cachedRehypeExpressiveCode, contentPlugin, ecCachePlugin, ecCacheSalt, htmlWithTypeScriptScripts, katexFontsPlugin, llmsPlugin, normalizeTitle, pagefindPlugin, pluginCollapsible, rehypeMermaidFence, remarkObsidianComments, remarkObsidianTags, sha1, wrapTables };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@staticbolt/docs",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.2",
|
|
4
4
|
"description": "Documentation theme for staticbolt: layout parts, styles, and plugins shared by every docs site.",
|
|
5
5
|
"author": "Ahmed ALABSI",
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@eslint/markdown": "^8.0.1",
|
|
84
84
|
"@html-eslint/eslint-plugin": "^0.60.0",
|
|
85
85
|
"@html-eslint/parser": "^0.60.0",
|
|
86
|
-
"@staticbolt/core": "
|
|
86
|
+
"@staticbolt/core": "beta",
|
|
87
87
|
"@stylistic/stylelint-config": "^5.0.0",
|
|
88
88
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
89
89
|
"@types/hast": "^3.0.5",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- ::: Collapsible callouts (`> [!note]-`) render as `<details>`; swap them for sv-accordion ::: -->
|
|
2
|
-
<script build-time>
|
|
2
|
+
<script type="application/x-typescript" build-time>
|
|
3
3
|
for (const callout of document.querySelectorAll("details.callout")) {
|
|
4
4
|
const accordion = document.createElement("sv-accordion");
|
|
5
5
|
accordion.setAttribute("data-callout", callout.getAttribute("data-callout"));
|
|
@@ -29,13 +29,12 @@
|
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
<insert selector="head">
|
|
32
|
-
<script>
|
|
33
|
-
// @ts-check
|
|
32
|
+
<script type="application/x-typescript">
|
|
34
33
|
(() => {
|
|
35
34
|
const STORAGE_KEY = "color-scheme";
|
|
36
35
|
const PREFERS_DARK = window.matchMedia("(prefers-color-scheme: dark)");
|
|
37
36
|
|
|
38
|
-
let currentScheme = PREFERS_DARK.matches ? "dark" : "light";
|
|
37
|
+
let currentScheme: "light" | "dark" = PREFERS_DARK.matches ? "dark" : "light";
|
|
39
38
|
|
|
40
39
|
// Override with stored value
|
|
41
40
|
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
@@ -44,11 +43,7 @@
|
|
|
44
43
|
document.documentElement.style.colorScheme = stored;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
* @param {"light" | "dark"} scheme
|
|
49
|
-
* @param {NodeListOf<HTMLButtonElement>} buttons
|
|
50
|
-
*/
|
|
51
|
-
const applyScheme = (scheme, buttons) => {
|
|
46
|
+
const applyScheme = (scheme: "light" | "dark", buttons: NodeListOf<HTMLButtonElement>) => {
|
|
52
47
|
const isDark = scheme === "dark";
|
|
53
48
|
|
|
54
49
|
for (const button of buttons) {
|
|
@@ -62,8 +57,7 @@
|
|
|
62
57
|
};
|
|
63
58
|
|
|
64
59
|
const onReady = () => {
|
|
65
|
-
|
|
66
|
-
const colorSchemeButtons = document.querySelectorAll(".color-scheme-switch");
|
|
60
|
+
const colorSchemeButtons = document.querySelectorAll<HTMLButtonElement>(".color-scheme-switch");
|
|
67
61
|
|
|
68
62
|
const isDark = currentScheme === "dark";
|
|
69
63
|
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
` }}
|
|
53
53
|
|
|
54
54
|
<!-- ::: Page title and skip link ::: -->
|
|
55
|
-
<script build-time>
|
|
55
|
+
<script type="application/x-typescript" build-time>
|
|
56
56
|
const heading = document.querySelector("h1[id]");
|
|
57
57
|
const title = document.querySelector("title");
|
|
58
58
|
const ogTitle = document.querySelector('meta[property="og:title"]');
|
|
@@ -36,18 +36,14 @@
|
|
|
36
36
|
</header>
|
|
37
37
|
|
|
38
38
|
<!-- ::: Toggle the sidebar ::: -->
|
|
39
|
-
<script type="module
|
|
40
|
-
// @ts-check
|
|
41
|
-
|
|
39
|
+
<script type="application/x-typescript" module>
|
|
42
40
|
(() => {
|
|
43
|
-
|
|
44
|
-
const menuTrigger = document.querySelector(".side-menu-trigger-button");
|
|
41
|
+
const menuTrigger = document.querySelector<HTMLButtonElement>(".side-menu-trigger-button");
|
|
45
42
|
if (!menuTrigger) {
|
|
46
43
|
return;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
const sidebar = document.querySelector(".sidebar");
|
|
46
|
+
const sidebar = document.querySelector<HTMLDivElement>(".sidebar");
|
|
51
47
|
if (!sidebar) {
|
|
52
48
|
menuTrigger.remove();
|
|
53
49
|
return;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<script type="module" data-mermaid-script src="@staticbolt/docs/scripts/mermaid.ts"></script>
|
|
3
3
|
|
|
4
4
|
<!-- ::: Drop the script from pages without a diagram ::: -->
|
|
5
|
-
<script build-time>
|
|
5
|
+
<script type="application/x-typescript" build-time>
|
|
6
6
|
const mermaidScript = document.querySelector("[data-mermaid-script]");
|
|
7
7
|
|
|
8
8
|
if (mermaidScript) {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<pagefind-modal></pagefind-modal>
|
|
12
12
|
|
|
13
13
|
<!-- ::: Path from this page to the Pagefind bundle, so the site works on any subpath ::: -->
|
|
14
|
-
<script type="
|
|
14
|
+
<script type="application/x-typescript" build-time module>
|
|
15
15
|
import { dirname, relative } from "node:path";
|
|
16
16
|
|
|
17
17
|
const modal = document.querySelector("pagefind-modal");
|
|
@@ -21,14 +21,11 @@
|
|
|
21
21
|
<insert selector="body">
|
|
22
22
|
<link class="pagefind-stylesheet" as="style" bundle href="./pagefind.style.css" rel="preload" />
|
|
23
23
|
|
|
24
|
-
<script type="module
|
|
25
|
-
// @ts-check
|
|
26
|
-
|
|
24
|
+
<script type="application/x-typescript" module>
|
|
27
25
|
(async () => {
|
|
28
26
|
// ::: Lazy-load the Pagefind UI. :::
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
const pagefindStyleSheet = document.querySelector(".pagefind-stylesheet");
|
|
28
|
+
const pagefindStyleSheet = document.querySelector<HTMLLinkElement>(".pagefind-stylesheet");
|
|
32
29
|
if (!pagefindStyleSheet) {
|
|
33
30
|
console.error("Could not find pagefind stylesheet element");
|
|
34
31
|
return;
|
|
@@ -53,15 +50,13 @@
|
|
|
53
50
|
|
|
54
51
|
// ::: Open the Pagefind modal when the search button is clicked. :::
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
const pagefindModalTrigger = document.querySelector("pagefind-modal-trigger");
|
|
53
|
+
const pagefindModalTrigger = document.querySelector<HTMLElement & { openModal(): void }>("pagefind-modal-trigger");
|
|
58
54
|
if (!pagefindModalTrigger) {
|
|
59
55
|
console.error("Could not find pagefind modal trigger element");
|
|
60
56
|
return;
|
|
61
57
|
}
|
|
62
58
|
|
|
63
|
-
|
|
64
|
-
const triggerModalIconButton = document.querySelector(".pagefind-modal-trigger-button");
|
|
59
|
+
const triggerModalIconButton = document.querySelector<HTMLButtonElement>(".pagefind-modal-trigger-button");
|
|
65
60
|
if (!triggerModalIconButton) {
|
|
66
61
|
console.error("Could not find pagefind modal trigger button element");
|
|
67
62
|
return;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
<!-- This script will run once at build time for each page -->
|
|
28
|
-
<script type="
|
|
28
|
+
<script type="application/x-typescript" build-time module>
|
|
29
29
|
// ::: Get current link and populate previous/next links :::
|
|
30
30
|
import { join, dirname, normalize } from "node:path";
|
|
31
31
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
-
<script type="
|
|
17
|
+
<script type="application/x-typescript" build-time module>
|
|
18
18
|
import { join, dirname, normalize } from "node:path";
|
|
19
19
|
|
|
20
20
|
// ::: Mark current page links as active and expand matching accordions. :::
|
|
@@ -42,17 +42,16 @@
|
|
|
42
42
|
</script>
|
|
43
43
|
|
|
44
44
|
<!-- ::: Persist sidebar navigation state across page loads. ::: -->
|
|
45
|
-
<script>
|
|
45
|
+
<script type="application/x-typescript">
|
|
46
46
|
(() => {
|
|
47
|
-
|
|
48
|
-
const accordions = document.querySelectorAll(".sidebar-accordion");
|
|
47
|
+
const accordions = document.querySelectorAll<HTMLDivElement>(".sidebar-accordion");
|
|
49
48
|
|
|
50
49
|
// ::: Restore the accordion's previous open state. :::
|
|
51
50
|
try {
|
|
52
|
-
const state = JSON.parse(sessionStorage.getItem("sidebar-state") ?? {});
|
|
51
|
+
const state = JSON.parse(sessionStorage.getItem("sidebar-state") ?? "{}");
|
|
53
52
|
|
|
54
53
|
for (const [accordionIndex, opened] of Object.entries(state)) {
|
|
55
|
-
const accordion =
|
|
54
|
+
const accordion = accordions[Number(accordionIndex)];
|
|
56
55
|
if (!accordion) continue;
|
|
57
56
|
|
|
58
57
|
// Keep accordions containing the active link expanded by default
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</div>
|
|
7
7
|
</aside>
|
|
8
8
|
|
|
9
|
-
<script build-time>
|
|
9
|
+
<script type="application/x-typescript" build-time>
|
|
10
10
|
const tocContents = document.querySelectorAll(".toc-content");
|
|
11
11
|
const headings = document
|
|
12
12
|
.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]")
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
</script>
|
|
67
67
|
|
|
68
|
-
<script>
|
|
68
|
+
<script type="application/x-typescript">
|
|
69
69
|
(() => {
|
|
70
70
|
// All links in the mobile and desktop TOC
|
|
71
71
|
const links = document.querySelectorAll(".toc-list a");
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
<!-- ::: Close the accordion when a link is clicked ::: -->
|
|
15
|
-
<script type="module
|
|
15
|
+
<script type="application/x-typescript" module>
|
|
16
16
|
const tocAccordion = document.querySelector(".toc-accordion");
|
|
17
17
|
const tocLinks = document.querySelectorAll(".toc-accordion a");
|
|
18
18
|
|