starlight-cannoli-plugins 2.16.0 → 2.17.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/README.md +27 -1
- package/dist/{chunk-C2VXRQOK.js → chunk-7D2KLZGE.js} +52 -0
- package/dist/{chunk-QPHWDN2I.js → chunk-BM7LMGAH.js} +18 -8
- package/dist/{chunk-WFN7OFMJ.js → chunk-EEPQVOZC.js} +1 -1
- package/dist/{chunk-RAKGKJJO.js → chunk-FDEHNCBK.js} +1 -1
- package/dist/{chunk-JFHWCFHF.js → chunk-GTVQDNAE.js} +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.js +34 -5
- package/dist/plugins/astro-latex-compile.js +2 -2
- package/dist/plugins/astro-sync-docs-to-public/page-script.d.ts +6 -1
- package/dist/plugins/astro-sync-docs-to-public/page-script.js +62 -25
- package/dist/plugins/astro-sync-docs-to-public.d.ts +9 -0
- package/dist/plugins/astro-sync-docs-to-public.js +3 -3
- package/dist/plugins/starlight-dom-patches/page-script.js +1 -8
- package/dist/plugins/starlight-index-only-sidebar.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -231,6 +231,28 @@ The following attributes can be added to the opening fence:
|
|
|
231
231
|
```
|
|
232
232
|
````
|
|
233
233
|
|
|
234
|
+
### Remark GFM Slug
|
|
235
|
+
|
|
236
|
+
A remark plugin that assigns heading IDs using the same GFM slug algorithm as VS Code and GitHub, before Astro's internal `rehypeHeadingIds` runs. Since `rehypeHeadingIds` skips headings that already have an `id`, this takes precedence and produces fragment anchors that match what VS Code's markdown link resolver expects.
|
|
237
|
+
|
|
238
|
+
This is especially useful when headings contain inline math or other syntax that Astro/Starlight would otherwise slugify from the rendered HTML output (producing long encoded IDs that differ from VS Code's raw-text slugification).
|
|
239
|
+
|
|
240
|
+
**Usage:**
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
// astro.config.mjs
|
|
244
|
+
import { defineConfig } from "astro/config";
|
|
245
|
+
import { remarkGfmSlug } from "starlight-cannoli-plugins";
|
|
246
|
+
|
|
247
|
+
export default defineConfig({
|
|
248
|
+
markdown: {
|
|
249
|
+
remarkPlugins: [
|
|
250
|
+
remarkGfmSlug, // must come before remark-math or other transforming plugins
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
234
256
|
### Rehype Validate Links
|
|
235
257
|
|
|
236
258
|
A rehype plugin that validates all internal links in your Markdown/MDX files at build time. Links without matching files will cause the build to fail.
|
|
@@ -342,11 +364,15 @@ export default defineConfig({
|
|
|
342
364
|
|
|
343
365
|
- `preserveDirs` (required): Names of child directories inside `public/` to preserve during sync. These will not be deleted when re-syncing.
|
|
344
366
|
- `ignorePatterns` (optional): Glob patterns for files to exclude from syncing. Patterns are matched against paths relative to `src/content/docs/`.
|
|
367
|
+
- `exposePageSrcButton` (optional, default: `false`): Injects a client-side script on every page that adds a `⋮` dropdown next to the page's `<h1>` with "Copy Page", "Copy raw URL", and "View raw" actions for the page's raw markdown source.
|
|
368
|
+
- `enableAskAiOption` (optional, default: `false`): Adds "Ask ChatGPT", "Ask Claude", and "Ask Gemini" entries to the same `⋮` dropdown, each opening the respective chat app in a new tab with a prompt pre-filled to read the page's raw markdown URL. Independent of `exposePageSrcButton` — enabling this on its own still injects the dropdown button, containing only the "Ask" entries.
|
|
345
369
|
|
|
346
370
|
```ts
|
|
347
371
|
syncDocsToPublic({
|
|
348
372
|
preserveDirs: ["static"],
|
|
349
373
|
ignorePatterns: ["**/*.txt", "**/drafts/**"],
|
|
374
|
+
exposePageSrcButton: true,
|
|
375
|
+
enableAskAiOption: true,
|
|
350
376
|
});
|
|
351
377
|
```
|
|
352
378
|
|
|
@@ -360,7 +386,7 @@ An Astro integration that injects a client-side script to apply opt-in DOM patch
|
|
|
360
386
|
- `syncTocLabelsFromHeadings` (optional, default: `false`): Copies the rendered HTML of each heading into its matching Starlight TOC anchor label, so the TOC properly reflects any custom markup (e.g. math) present in the heading.
|
|
361
387
|
- `limitDetailsElementHeight` (optional, default: `false`): Limits the height of expanded `<details>` elements and makes their content scrollable.
|
|
362
388
|
- `offerToggleAllDetails` (optional, default: `false`): Injects an "Expand All Dropdowns" toggle checkbox into the right sidebar (before `nav[aria-labelledby="starlight__on-this-page"]`). Clicking it opens or closes every `<details>` element on the page at once. Only appears on pages that contain at least one visible `<details>` element.
|
|
363
|
-
- `offerTabbedContent` (optional, default: `false`): Injects a "Tabbed view" toggle checkbox immediately after `#starlight__on-this-page` in the right sidebar. When enabled by the user, the page's markdown content is reorganised into tabs — one per `<h2>` heading, plus an optional "Main" tab for any content that appears before the first `<h2>`. The toggle
|
|
389
|
+
- `offerTabbedContent` (optional, default: `false`): Injects a "Tabbed view" toggle checkbox immediately after `#starlight__on-this-page` in the right sidebar. When enabled by the user, the page's markdown content is reorganised into tabs — one per `<h2>` heading, plus an optional "Main" tab for any content that appears before the first `<h2>`. The toggle defaults to off on every page load and is not persisted. Only activates when the page has at least two sections (i.e. two or more `<h2>` elements, or one `<h2>` with pre-heading content). Has no effect on pages that lack `#starlight__on-this-page` (e.g. pages with the TOC disabled). Clicking a TOC anchor while tabs are enabled automatically switches to the tab containing the target heading. The generated elements use the classes `tabbed-content`, `tabbed-content-nav`, `tabbed-content-tab`, and `tabbed-content-panel` for styling; toggle button uses the existing `.toggle-checkbox-btn` class.
|
|
364
390
|
- `decorateExternalLinks` (optional): Scans all links inside `.sl-markdown-content` and prepends a destination-specific icon to recognised link targets. Pass an object enabling each supported destination individually:
|
|
365
391
|
- `youtube` (default: `false`): prepends a YouTube play-button SVG (class `yt-icon`, `aria-hidden`, inherits `currentColor`) to links pointing to `youtube.com` or `youtu.be`.
|
|
366
392
|
|
|
@@ -13502,8 +13502,58 @@ import { visit } from "unist-util-visit";
|
|
|
13502
13502
|
import path from "path";
|
|
13503
13503
|
import { pathToFileURL } from "url";
|
|
13504
13504
|
|
|
13505
|
+
// node_modules/github-slugger/regex.js
|
|
13506
|
+
var regex = /[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g;
|
|
13507
|
+
|
|
13505
13508
|
// node_modules/github-slugger/index.js
|
|
13506
13509
|
var own4 = Object.hasOwnProperty;
|
|
13510
|
+
var BananaSlug = class {
|
|
13511
|
+
/**
|
|
13512
|
+
* Create a new slug class.
|
|
13513
|
+
*/
|
|
13514
|
+
constructor() {
|
|
13515
|
+
this.occurrences;
|
|
13516
|
+
this.reset();
|
|
13517
|
+
}
|
|
13518
|
+
/**
|
|
13519
|
+
* Generate a unique slug.
|
|
13520
|
+
*
|
|
13521
|
+
* Tracks previously generated slugs: repeated calls with the same value
|
|
13522
|
+
* will result in different slugs.
|
|
13523
|
+
* Use the `slug` function to get same slugs.
|
|
13524
|
+
*
|
|
13525
|
+
* @param {string} value
|
|
13526
|
+
* String of text to slugify
|
|
13527
|
+
* @param {boolean} [maintainCase=false]
|
|
13528
|
+
* Keep the current case, otherwise make all lowercase
|
|
13529
|
+
* @return {string}
|
|
13530
|
+
* A unique slug string
|
|
13531
|
+
*/
|
|
13532
|
+
slug(value, maintainCase) {
|
|
13533
|
+
const self2 = this;
|
|
13534
|
+
let result = slug(value, maintainCase === true);
|
|
13535
|
+
const originalSlug = result;
|
|
13536
|
+
while (own4.call(self2.occurrences, result)) {
|
|
13537
|
+
self2.occurrences[originalSlug]++;
|
|
13538
|
+
result = originalSlug + "-" + self2.occurrences[originalSlug];
|
|
13539
|
+
}
|
|
13540
|
+
self2.occurrences[result] = 0;
|
|
13541
|
+
return result;
|
|
13542
|
+
}
|
|
13543
|
+
/**
|
|
13544
|
+
* Reset - Forget all previous slugs
|
|
13545
|
+
*
|
|
13546
|
+
* @return void
|
|
13547
|
+
*/
|
|
13548
|
+
reset() {
|
|
13549
|
+
this.occurrences = /* @__PURE__ */ Object.create(null);
|
|
13550
|
+
}
|
|
13551
|
+
};
|
|
13552
|
+
function slug(value, maintainCase) {
|
|
13553
|
+
if (typeof value !== "string") return "";
|
|
13554
|
+
if (!maintainCase) value = value.toLowerCase();
|
|
13555
|
+
return value.replace(regex, "").replace(/ /g, "-");
|
|
13556
|
+
}
|
|
13507
13557
|
|
|
13508
13558
|
// node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js
|
|
13509
13559
|
import { visit as visit2 } from "unist-util-visit";
|
|
@@ -13522,8 +13572,10 @@ import { visit as visit4 } from "unist-util-visit";
|
|
|
13522
13572
|
var isPerformanceBenchmark = Boolean(process.env.ASTRO_PERFORMANCE_BENCHMARK);
|
|
13523
13573
|
|
|
13524
13574
|
export {
|
|
13575
|
+
toString2 as toString,
|
|
13525
13576
|
remarkParse,
|
|
13526
13577
|
unified,
|
|
13578
|
+
BananaSlug,
|
|
13527
13579
|
parseFrontmatter
|
|
13528
13580
|
};
|
|
13529
13581
|
/*! Bundled license information:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseFrontmatter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EEPQVOZC.js";
|
|
4
4
|
|
|
5
5
|
// src/plugins/astro-sync-docs-to-public/index.ts
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
@@ -138,17 +138,18 @@ var DEFAULT_SRC_DIR = "src/content/docs";
|
|
|
138
138
|
var DEFAULT_PUBLIC_DIR = "public";
|
|
139
139
|
function validateOptions(options) {
|
|
140
140
|
const mdProbePaths = ["test.md", "test.mdx", "foo/test.md", "foo/test.mdx"];
|
|
141
|
-
|
|
141
|
+
const needsRawMd = options.exposePageSrcButton || options.enableAskAiOption;
|
|
142
|
+
if (!needsRawMd) return;
|
|
142
143
|
const offendingMdPatterns = (options.ignorePatterns ?? []).filter(
|
|
143
144
|
(pattern) => mdProbePaths.some((probe) => minimatch(probe, pattern, { dot: true }))
|
|
144
145
|
);
|
|
145
146
|
const offendingMtPatternsStr = offendingMdPatterns.map((p) => ` - "${p}"`).join("\n");
|
|
146
147
|
if (offendingMdPatterns.length > 0) {
|
|
147
148
|
throw new Error(
|
|
148
|
-
`The 'exposePageSrcButton' option is enabled but the following 'ignorePatterns' values conflict with it:
|
|
149
|
+
`The 'exposePageSrcButton'/'enableAskAiOption' option is enabled but the following 'ignorePatterns' values conflict with it:
|
|
149
150
|
${offendingMtPatternsStr}
|
|
150
151
|
|
|
151
|
-
Since these ignore patterns match md/mdx files, the page
|
|
152
|
+
Since these ignore patterns match md/mdx files, the page action button would break. Either disable these options or remove these patterns.`
|
|
152
153
|
);
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -256,7 +257,8 @@ function syncDocsToPublic(options) {
|
|
|
256
257
|
const {
|
|
257
258
|
preserveDirs: rawPreserveDirs,
|
|
258
259
|
ignorePatterns = [],
|
|
259
|
-
exposePageSrcButton = false
|
|
260
|
+
exposePageSrcButton = false,
|
|
261
|
+
enableAskAiOption = false
|
|
260
262
|
} = options;
|
|
261
263
|
const preserveDirs = rawPreserveDirs.map((d) => d.replace(/\/+$/, ""));
|
|
262
264
|
return {
|
|
@@ -264,7 +266,7 @@ function syncDocsToPublic(options) {
|
|
|
264
266
|
hooks: {
|
|
265
267
|
"astro:config:setup": ({ injectScript }) => {
|
|
266
268
|
validateOptions(options);
|
|
267
|
-
if (exposePageSrcButton) {
|
|
269
|
+
if (exposePageSrcButton || enableAskAiOption) {
|
|
268
270
|
injectScript(
|
|
269
271
|
"page",
|
|
270
272
|
`
|
|
@@ -288,8 +290,16 @@ function syncDocsToPublic(options) {
|
|
|
288
290
|
import.meta.url
|
|
289
291
|
);
|
|
290
292
|
}
|
|
291
|
-
const scriptPath = fileURLToPath(pageScriptUrl);
|
|
292
|
-
|
|
293
|
+
const scriptPath = JSON.stringify(fileURLToPath(pageScriptUrl));
|
|
294
|
+
const actionBarOptions = JSON.stringify({
|
|
295
|
+
exposePageSrcButton,
|
|
296
|
+
enableAskAiOption
|
|
297
|
+
});
|
|
298
|
+
injectScript(
|
|
299
|
+
"page",
|
|
300
|
+
`import { initPageActionBar } from ${scriptPath};
|
|
301
|
+
initPageActionBar(${actionBarOptions});`
|
|
302
|
+
);
|
|
293
303
|
}
|
|
294
304
|
},
|
|
295
305
|
"astro:build:start": async () => {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { HookParameters } from '@astrojs/starlight/types';
|
|
|
3
3
|
export { DomPatchesOptions, starlightDomPatches } from './plugins/starlight-dom-patches.js';
|
|
4
4
|
export { SyncDocsToPublicOptions, syncDocsToPublic } from './plugins/astro-sync-docs-to-public.js';
|
|
5
5
|
export { rehypeValidateLinks } from './plugins/rehype-validate-links.js';
|
|
6
|
+
import { Root } from 'mdast';
|
|
7
|
+
import { Plugin } from 'unified';
|
|
6
8
|
export { astroNormalizePaths } from './plugins/astro-normalize-paths.js';
|
|
7
9
|
export { expressiveCodeEmphasis } from './plugins/expressive-code-emphasis.js';
|
|
8
10
|
import { AstroIntegration } from 'astro';
|
|
@@ -10,7 +12,6 @@ import { LatexCompilePluginOptions } from './plugins/astro-latex-compile.js';
|
|
|
10
12
|
import 'hast';
|
|
11
13
|
import 'vfile';
|
|
12
14
|
import 'expressive-code';
|
|
13
|
-
import 'mdast';
|
|
14
15
|
|
|
15
16
|
type TBadgeVariant = "note" | "danger" | "success" | "caution" | "tip" | "default";
|
|
16
17
|
type TIndexMarker = {
|
|
@@ -66,6 +67,14 @@ declare function starlightIndexSourcedSidebar(options: TOptions): {
|
|
|
66
67
|
};
|
|
67
68
|
};
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Remark plugin that assigns heading IDs matching VS Code's markdown link
|
|
72
|
+
* resolver: GFM slugification of the raw heading text, with math nodes stripped.
|
|
73
|
+
* Runs before Astro's rehypeHeadingIds, which skips headings that already
|
|
74
|
+
* have an id, so this takes precedence.
|
|
75
|
+
*/
|
|
76
|
+
declare const remarkGfmSlug: Plugin<[], Root>;
|
|
77
|
+
|
|
69
78
|
interface LatexCompileOptions extends LatexCompilePluginOptions {
|
|
70
79
|
/**
|
|
71
80
|
* When `true`, SVG files in `svgOutputDir` that are no longer referenced by
|
|
@@ -78,4 +87,4 @@ interface LatexCompileOptions extends LatexCompilePluginOptions {
|
|
|
78
87
|
}
|
|
79
88
|
declare function astroLatexCompile(options: LatexCompileOptions): AstroIntegration;
|
|
80
89
|
|
|
81
|
-
export { type LatexCompileOptions, astroLatexCompile, starlightIndexSourcedSidebar };
|
|
90
|
+
export { type LatexCompileOptions, astroLatexCompile, remarkGfmSlug, starlightIndexSourcedSidebar };
|
package/dist/index.js
CHANGED
|
@@ -3,27 +3,29 @@ import {
|
|
|
3
3
|
} from "./chunk-O2TZASB7.js";
|
|
4
4
|
import {
|
|
5
5
|
starlightIndexOnlySidebar
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GTVQDNAE.js";
|
|
7
7
|
import {
|
|
8
8
|
rehypeValidateLinks
|
|
9
9
|
} from "./chunk-3UMY7T6G.js";
|
|
10
10
|
import {
|
|
11
11
|
latexCompileTransformer
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-FDEHNCBK.js";
|
|
13
13
|
import {
|
|
14
14
|
astroNormalizePaths
|
|
15
15
|
} from "./chunk-TLOFSB33.js";
|
|
16
16
|
import "./chunk-LJWSZSPB.js";
|
|
17
17
|
import {
|
|
18
18
|
syncDocsToPublic
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-BM7LMGAH.js";
|
|
20
20
|
import {
|
|
21
21
|
parseFrontmatter
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EEPQVOZC.js";
|
|
23
23
|
import {
|
|
24
|
+
BananaSlug,
|
|
24
25
|
remarkParse,
|
|
26
|
+
toString,
|
|
25
27
|
unified
|
|
26
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-7D2KLZGE.js";
|
|
27
29
|
import {
|
|
28
30
|
starlightDomPatches
|
|
29
31
|
} from "./chunk-SKQV57MG.js";
|
|
@@ -228,6 +230,32 @@ function starlightIndexSourcedSidebar(options) {
|
|
|
228
230
|
};
|
|
229
231
|
}
|
|
230
232
|
|
|
233
|
+
// src/plugins/remark-gfm-slug.ts
|
|
234
|
+
import { visit as visit2 } from "unist-util-visit";
|
|
235
|
+
var STRIP_NODE_TYPES = /* @__PURE__ */ new Set(["math", "inlineMath"]);
|
|
236
|
+
function headingText(node) {
|
|
237
|
+
const parts = [];
|
|
238
|
+
for (const child of node.children) {
|
|
239
|
+
if (STRIP_NODE_TYPES.has(child.type)) continue;
|
|
240
|
+
parts.push(toString(child, { includeImageAlt: false }));
|
|
241
|
+
}
|
|
242
|
+
return parts.join("").trim();
|
|
243
|
+
}
|
|
244
|
+
var remarkGfmSlug = () => {
|
|
245
|
+
return (tree) => {
|
|
246
|
+
const slugger = new BananaSlug();
|
|
247
|
+
visit2(tree, "heading", (node) => {
|
|
248
|
+
const text = headingText(node);
|
|
249
|
+
const id = slugger.slug(text);
|
|
250
|
+
const data = node.data ??= {};
|
|
251
|
+
data.id = id;
|
|
252
|
+
data.hProperties ??= {};
|
|
253
|
+
data.hProperties.id = id;
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
var remark_gfm_slug_default = remarkGfmSlug;
|
|
258
|
+
|
|
231
259
|
// src/plugins/astro-latex-compile/astro-integration.ts
|
|
232
260
|
import fs2 from "fs";
|
|
233
261
|
import { readdir, rm } from "fs/promises";
|
|
@@ -328,6 +356,7 @@ export {
|
|
|
328
356
|
astroNormalizePaths,
|
|
329
357
|
expressiveCodeEmphasis,
|
|
330
358
|
rehypeValidateLinks,
|
|
359
|
+
remark_gfm_slug_default as remarkGfmSlug,
|
|
331
360
|
starlightDomPatches,
|
|
332
361
|
starlightIndexOnlySidebar,
|
|
333
362
|
starlightIndexSourcedSidebar,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import "../../chunk-4VNS5WPM.js";
|
|
2
|
+
|
|
1
3
|
// src/plugins/astro-sync-docs-to-public/page-script.ts
|
|
2
4
|
function showBanner(message, variant) {
|
|
3
5
|
const banner = document.createElement("div");
|
|
@@ -28,7 +30,21 @@ async function getRawMdUrl() {
|
|
|
28
30
|
}
|
|
29
31
|
return new URL("index.md", base).toString();
|
|
30
32
|
}
|
|
31
|
-
|
|
33
|
+
var LLM_ASK_TARGETS = [
|
|
34
|
+
{
|
|
35
|
+
label: "Ask ChatGPT",
|
|
36
|
+
buildUrl: (prompt) => `https://chatgpt.com/?${new URLSearchParams({ q: prompt })}`
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
label: "Ask Claude",
|
|
40
|
+
buildUrl: (prompt) => `https://claude.ai/new?${new URLSearchParams({ q: prompt })}`
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: "Ask Gemini",
|
|
44
|
+
buildUrl: (prompt) => `https://gemini.google.com/app?${new URLSearchParams({ q: prompt })}`
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
function createActionBar(options) {
|
|
32
48
|
const bar = document.createElement("div");
|
|
33
49
|
bar.className = "page-src-action-bar";
|
|
34
50
|
const menuBtn = document.createElement("button");
|
|
@@ -39,29 +55,48 @@ function createActionBar() {
|
|
|
39
55
|
}
|
|
40
56
|
const menu = document.createElement("div");
|
|
41
57
|
menu.className = "page-src-action-bar__menu";
|
|
42
|
-
const menuItems = [
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
const menuItems = [];
|
|
59
|
+
if (options.exposePageSrcButton) {
|
|
60
|
+
menuItems.push(
|
|
61
|
+
{
|
|
62
|
+
label: "Copy Page",
|
|
63
|
+
action: () => {
|
|
64
|
+
setLoading(true);
|
|
65
|
+
getRawMdUrl().then((url) => fetch(url)).then((resp) => resp.text()).then((text) => navigator.clipboard.writeText(text)).then(
|
|
66
|
+
() => showBanner("Page source copied to clipboard!", "success")
|
|
67
|
+
).catch(() => showBanner("Failed to copy page source.", "error")).finally(() => setLoading(false));
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: "Copy raw URL",
|
|
72
|
+
action: () => {
|
|
73
|
+
setLoading(true);
|
|
74
|
+
getRawMdUrl().then((url) => navigator.clipboard.writeText(url)).then(() => showBanner("Raw URL copied to clipboard!", "success")).catch(() => showBanner("Failed to copy raw URL.", "error")).finally(() => setLoading(false));
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
label: "View raw",
|
|
79
|
+
action: () => {
|
|
80
|
+
setLoading(true);
|
|
81
|
+
getRawMdUrl().then((url) => window.open(url, "_blank")).catch(() => showBanner("Failed to open raw source.", "error")).finally(() => setLoading(false));
|
|
82
|
+
}
|
|
62
83
|
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (options.enableAskAiOption) {
|
|
87
|
+
for (const { label, buildUrl } of LLM_ASK_TARGETS) {
|
|
88
|
+
menuItems.push({
|
|
89
|
+
label,
|
|
90
|
+
action: () => {
|
|
91
|
+
setLoading(true);
|
|
92
|
+
getRawMdUrl().then((url) => {
|
|
93
|
+
const prompt = `Read from ${url} so I can ask questions about it.`;
|
|
94
|
+
window.open(buildUrl(prompt), "_blank");
|
|
95
|
+
}).catch(() => showBanner(`Failed to open ${label}.`, "error")).finally(() => setLoading(false));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
63
98
|
}
|
|
64
|
-
|
|
99
|
+
}
|
|
65
100
|
for (const item of menuItems) {
|
|
66
101
|
const btn = document.createElement("button");
|
|
67
102
|
btn.className = "page-src-action-bar__menu-item";
|
|
@@ -93,13 +128,15 @@ function createActionBar() {
|
|
|
93
128
|
bar.appendChild(menu);
|
|
94
129
|
return bar;
|
|
95
130
|
}
|
|
96
|
-
function
|
|
131
|
+
function initPageActionBar(options) {
|
|
97
132
|
const h1 = document.querySelector(".sl-container > h1");
|
|
98
133
|
if (h1 === null) return;
|
|
99
134
|
const wrapper = document.createElement("div");
|
|
100
135
|
wrapper.className = "page-src-h1-wrapper";
|
|
101
136
|
h1.replaceWith(wrapper);
|
|
102
137
|
wrapper.appendChild(h1);
|
|
103
|
-
wrapper.appendChild(createActionBar());
|
|
138
|
+
wrapper.appendChild(createActionBar(options));
|
|
104
139
|
}
|
|
105
|
-
|
|
140
|
+
export {
|
|
141
|
+
initPageActionBar
|
|
142
|
+
};
|
|
@@ -17,6 +17,15 @@ interface SyncDocsToPublicOptions {
|
|
|
17
17
|
* dev and build modes.
|
|
18
18
|
*/
|
|
19
19
|
exposePageSrcButton?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* When true, adds "Ask ChatGPT", "Ask Claude", and "Ask Gemini" entries to
|
|
22
|
+
* the page action dropdown menu, each opening the respective chat app with
|
|
23
|
+
* a prompt pre-filled to read the current page's raw markdown URL.
|
|
24
|
+
*
|
|
25
|
+
* Independent of `exposePageSrcButton` — enabling this on its own still
|
|
26
|
+
* injects the dropdown button, containing only the "Ask" entries.
|
|
27
|
+
*/
|
|
28
|
+
enableAskAiOption?: boolean;
|
|
20
29
|
}
|
|
21
30
|
declare function syncDocsToPublic(options: SyncDocsToPublicOptions): AstroIntegration;
|
|
22
31
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
syncDocsToPublic
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-BM7LMGAH.js";
|
|
4
|
+
import "../chunk-EEPQVOZC.js";
|
|
5
|
+
import "../chunk-7D2KLZGE.js";
|
|
6
6
|
import "../chunk-4VNS5WPM.js";
|
|
7
7
|
export {
|
|
8
8
|
syncDocsToPublic
|
|
@@ -50,7 +50,6 @@ function syncTocLabelsFromHeadings() {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
function tabbedH2Content() {
|
|
53
|
-
const LS_KEY = "starlight-dom-patches:tabbed-content";
|
|
54
53
|
const contentContainer = document.querySelector(
|
|
55
54
|
".main-pane .sl-markdown-content"
|
|
56
55
|
);
|
|
@@ -241,16 +240,10 @@ function tabbedH2Content() {
|
|
|
241
240
|
);
|
|
242
241
|
viewToggleCheckbox2.addEventListener("change", () => {
|
|
243
242
|
setEnabled(viewToggleCheckbox2.checked);
|
|
244
|
-
localStorage.setItem(
|
|
245
|
-
LS_KEY,
|
|
246
|
-
viewToggleCheckbox2.checked ? "enabled" : "disabled"
|
|
247
|
-
);
|
|
248
243
|
});
|
|
249
244
|
}
|
|
250
245
|
const viewToggleCheckbox = buildToggle();
|
|
251
|
-
|
|
252
|
-
viewToggleCheckbox.checked = initialEnabled;
|
|
253
|
-
setEnabled(initialEnabled);
|
|
246
|
+
setEnabled(false);
|
|
254
247
|
if (window.location.hash) navigateToHash(window.location.hash);
|
|
255
248
|
wireInteractions(viewToggleCheckbox);
|
|
256
249
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
starlightIndexOnlySidebar
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-GTVQDNAE.js";
|
|
4
|
+
import "../chunk-EEPQVOZC.js";
|
|
5
|
+
import "../chunk-7D2KLZGE.js";
|
|
6
6
|
import "../chunk-4VNS5WPM.js";
|
|
7
7
|
export {
|
|
8
8
|
starlightIndexOnlySidebar
|
package/package.json
CHANGED