@nubisco/docs-sdk 0.0.0-stage → 0.0.0
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/LICENSE +20 -0
- package/README.md +101 -2
- package/THIRD_PARTY_NOTICES.md +100 -0
- package/dist/cli.js +33 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +361 -0
- package/package.json +122 -4
- package/src/plugins/mermaid/Mermaid.vue +93 -0
- package/src/plugins/mermaid/index.ts +66 -0
- package/src/plugins/mermaid/mermaid-markdown.ts +34 -0
- package/src/plugins/mermaid/mermaid-plugin.ts +46 -0
- package/src/plugins/mermaid/mermaid.ts +21 -0
- package/src/plugins/tabs/components/ContentTab.vue +41 -0
- package/src/plugins/tabs/components/ContentTabs.vue +150 -0
- package/src/plugins/tabs/components/index.ts +10 -0
- package/src/plugins/tabs/components/useStabilizeScrollPosition.ts +36 -0
- package/src/plugins/tabs/components/useTabLabels.ts +18 -0
- package/src/plugins/tabs/components/useTabsSelectedState.ts +95 -0
- package/src/plugins/tabs/components/useTabsSingleState.ts +22 -0
- package/src/plugins/tabs/index.ts +1 -0
- package/src/plugins/tabs/markdown/index.ts +1 -0
- package/src/plugins/tabs/markdown/markdownPlugin.ts +47 -0
- package/src/plugins/tabs/markdown/ruleBlockTab.ts +97 -0
- package/src/theme/Layout.vue +32 -0
- package/src/theme/Nubisco.vue +480 -0
- package/src/theme/components/DocHeader.vue +599 -0
- package/src/theme/components/DocOutline.vue +235 -0
- package/src/theme/components/DocsControls.vue +173 -0
- package/src/theme/components/DocsSidebarNav.vue +313 -0
- package/src/theme/custom.css +591 -0
- package/src/theme/index.ts +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nubisco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to use,
|
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
9
|
+
Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
19
|
+
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="fixture/docs/public/logo.svg" alt="Nubisco" width="96" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">@nubisco/docs-sdk</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">The Nubisco documentation design as one package: VitePress, the theme, the plugins and a config helper. A product supplies its content and a small config.</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/@nubisco/docs-sdk"><img src="https://img.shields.io/npm/v/@nubisco/docs-sdk" alt="npm" /></a>
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/npm/l/@nubisco/docs-sdk" alt="license" /></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
## What it gives you
|
|
15
|
+
|
|
16
|
+
- **The design.** Neutral layer colours, a page header that is an inset card and closes
|
|
17
|
+
into a bar as you scroll, tabs that are pages, a left navigation with a filter, and
|
|
18
|
+
"On this page" on the right. Light, dark and auto.
|
|
19
|
+
- **VitePress, bundled.** Your project depends on this package, not on VitePress. One
|
|
20
|
+
version of VitePress across every site.
|
|
21
|
+
- **The plugins.** Tabs, mermaid diagrams and grouped code icons, already wired.
|
|
22
|
+
- **A config helper.** `defineNubiscoDocs` sets everything the design fixes. You state
|
|
23
|
+
your name, address, repository, navigation and footer.
|
|
24
|
+
- **A CLI.** `nubisco-docs dev | build | preview`.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pnpm add -D @nubisco/docs-sdk @nubisco/ui vue
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`@nubisco/ui` and `vue` are peer dependencies: the theme is built from the library's
|
|
33
|
+
components and tokens, and there must be one copy of each.
|
|
34
|
+
|
|
35
|
+
## Use
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// docs/.vitepress/config.ts
|
|
39
|
+
import { defineNubiscoDocs } from '@nubisco/docs-sdk'
|
|
40
|
+
|
|
41
|
+
export default defineNubiscoDocs({
|
|
42
|
+
title: 'Acta',
|
|
43
|
+
description: 'What Acta is, in one sentence.',
|
|
44
|
+
base: '/acta/',
|
|
45
|
+
hostname: 'https://docs.nubisco.io/acta/',
|
|
46
|
+
repo: 'nubisco/acta',
|
|
47
|
+
nav: [
|
|
48
|
+
{ text: 'Users', link: '/users/' },
|
|
49
|
+
{ text: 'Developers', link: '/developers/' },
|
|
50
|
+
],
|
|
51
|
+
sidebar: {
|
|
52
|
+
'/users/': [
|
|
53
|
+
{ text: 'Start', items: [{ text: 'Welcome', link: '/users/' }] },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
footer: {
|
|
57
|
+
copyright: 'Copyright © 2026 <a href="https://nubisco.io">Nubisco</a>',
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// docs/.vitepress/theme/index.ts
|
|
64
|
+
import theme from '@nubisco/docs-sdk/theme'
|
|
65
|
+
export default theme
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"scripts": {
|
|
71
|
+
"docs:dev": "nubisco-docs dev",
|
|
72
|
+
"docs:build": "nubisco-docs build"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Pages opt in with `layout: nubisco` in frontmatter. The fields the layout reads are
|
|
78
|
+
`title`, `intro` (one paragraph of inline Markdown), `status` (`stable`, `beta`, `labs`...),
|
|
79
|
+
`source` (a path in the repository, for the source link) and, for a page with facets,
|
|
80
|
+
`pageTabs` plus `tab`.
|
|
81
|
+
|
|
82
|
+
The `fixture/` folder is a complete small site that uses the package exactly as above. It is
|
|
83
|
+
built in CI on every change.
|
|
84
|
+
|
|
85
|
+
## Contributing
|
|
86
|
+
|
|
87
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). Contributions are made under the
|
|
88
|
+
[Contributor License Agreement](docs/CLA-INDIVIDUAL.md). Security reports: see
|
|
89
|
+
[SECURITY.md](SECURITY.md).
|
|
90
|
+
|
|
91
|
+
## Acknowledgements
|
|
92
|
+
|
|
93
|
+
The layout draws inspiration from [IBM Carbon Design System](https://carbondesignsystem.com)
|
|
94
|
+
documentation structure. Carbon is the work of IBM and its contributors, licensed under Apache 2.0.
|
|
95
|
+
The tabs and mermaid plugins are adapted from `vitepress-plugin-tabs` and
|
|
96
|
+
`vitepress-plugin-mermaid`, both MIT. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
`@nubisco/docs-sdk` is released under the MIT License (see `LICENSE`). It contains code
|
|
4
|
+
adapted from the projects below, and it is used with the fonts and libraries listed at
|
|
5
|
+
the end. Each keeps its own licence and copyright, reproduced here as those licences
|
|
6
|
+
require.
|
|
7
|
+
|
|
8
|
+
## Code adapted into this package
|
|
9
|
+
|
|
10
|
+
### vitepress-plugin-tabs
|
|
11
|
+
|
|
12
|
+
Adapted into `src/plugins/tabs/` (the tabs markdown rule and the tab components).
|
|
13
|
+
Source: https://github.com/sapphi-red/vitepress-plugins (package `vitepress-plugin-tabs`, MIT).
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
MIT License
|
|
17
|
+
|
|
18
|
+
Copyright (c) 2022 sapphi-red
|
|
19
|
+
|
|
20
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
21
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
22
|
+
in the Software without restriction, including without limitation the rights
|
|
23
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
24
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
25
|
+
furnished to do so, subject to the following conditions:
|
|
26
|
+
|
|
27
|
+
The above copyright notice and this permission notice shall be included in all
|
|
28
|
+
copies or substantial portions of the Software.
|
|
29
|
+
|
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
31
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
32
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
33
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
34
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
35
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
36
|
+
SOFTWARE.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### vitepress-plugin-mermaid
|
|
40
|
+
|
|
41
|
+
Adapted into `src/plugins/mermaid/` (the mermaid markdown rule, the Vite plugin and the
|
|
42
|
+
diagram component). Source: https://github.com/emersonbottero/vitepress-plugin-mermaid
|
|
43
|
+
(package `vitepress-plugin-mermaid`, MIT).
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
MIT License
|
|
47
|
+
|
|
48
|
+
Copyright (c) 2022 emersonbottero
|
|
49
|
+
|
|
50
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
51
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
52
|
+
in the Software without restriction, including without limitation the rights
|
|
53
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
54
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
55
|
+
furnished to do so, subject to the following conditions:
|
|
56
|
+
|
|
57
|
+
The above copyright notice and this permission notice shall be included in all
|
|
58
|
+
copies or substantial portions of the Software.
|
|
59
|
+
|
|
60
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
61
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
62
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
63
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
64
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
65
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
66
|
+
SOFTWARE.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Design reference (no code taken)
|
|
70
|
+
|
|
71
|
+
The layout draws on the structure of the documentation of IBM's Carbon Design System
|
|
72
|
+
(https://carbondesignsystem.com), which is the work of IBM and its contributors and is
|
|
73
|
+
licensed under Apache 2.0. This package contains none of Carbon's code, assets or marks.
|
|
74
|
+
"Carbon" and "IBM" are trademarks of International Business Machines Corporation.
|
|
75
|
+
|
|
76
|
+
## Dependencies
|
|
77
|
+
|
|
78
|
+
Installed with this package, not copied into it. Their licences travel with them.
|
|
79
|
+
|
|
80
|
+
| Package | Licence |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `vitepress`, `vue`, `vite`, `mermaid`, `vite-svg-loader`, `vitepress-plugin-group-icons`, `markdown-it-container`, `sass-embedded` | MIT |
|
|
83
|
+
| `@nubisco/ui` (peer dependency) | MIT |
|
|
84
|
+
| `@fontsource/plus-jakarta-sans` (Plus Jakarta Sans) | SIL Open Font License 1.1 |
|
|
85
|
+
| `@fontsource/fira-code` (Fira Code) | SIL Open Font License 1.1 |
|
|
86
|
+
|
|
87
|
+
### Fonts
|
|
88
|
+
|
|
89
|
+
The sites this package builds serve Plus Jakarta Sans (Copyright 2020 The Plus Jakarta
|
|
90
|
+
Sans Project Authors, https://github.com/tokotype/PlusJakartaSans) and Fira Code
|
|
91
|
+
(Copyright 2014-2020 The Fira Code Project Authors, https://github.com/tonsky/FiraCode),
|
|
92
|
+
both under the SIL Open Font License, Version 1.1
|
|
93
|
+
(https://openfontlicense.org). The fonts are not part of this package's own files: they
|
|
94
|
+
come from the `@fontsource` packages, which carry the full licence text. A site that
|
|
95
|
+
republishes the font files keeps that licence file with them.
|
|
96
|
+
|
|
97
|
+
### Icons
|
|
98
|
+
|
|
99
|
+
The icons the theme draws come from `@nubisco/ui`, which builds them from Phosphor Icons
|
|
100
|
+
(https://phosphoricons.com, MIT, Copyright (c) 2023 Phosphor Icons).
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/node/cli.ts
|
|
4
|
+
import { build, createServer, serve } from "vitepress";
|
|
5
|
+
var USAGE = `nubisco-docs <command> [root] [--port <n>]
|
|
6
|
+
|
|
7
|
+
dev start the dev server
|
|
8
|
+
build build the static site
|
|
9
|
+
preview serve a built site
|
|
10
|
+
|
|
11
|
+
root is the docs folder, "docs" by default.`;
|
|
12
|
+
var [command, ...rest] = process.argv.slice(2);
|
|
13
|
+
var flagAt = rest.indexOf("--port");
|
|
14
|
+
var port = flagAt === -1 ? void 0 : Number(rest[flagAt + 1]);
|
|
15
|
+
var root = rest.find((arg, i) => !arg.startsWith("--") && rest[i - 1] !== "--port") ?? "docs";
|
|
16
|
+
async function main() {
|
|
17
|
+
if (command === "dev") {
|
|
18
|
+
const server = await createServer(root, { port });
|
|
19
|
+
await server.listen();
|
|
20
|
+
server.printUrls();
|
|
21
|
+
} else if (command === "build") {
|
|
22
|
+
await build(root);
|
|
23
|
+
} else if (command === "preview") {
|
|
24
|
+
await serve({ root, port });
|
|
25
|
+
} else {
|
|
26
|
+
console.error(USAGE);
|
|
27
|
+
process.exit(command ? 1 : 0);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
main().catch((error) => {
|
|
31
|
+
console.error(error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DefaultTheme, UserConfig } from 'vitepress';
|
|
2
|
+
|
|
3
|
+
/** What the Nubisco theme reads from `themeConfig.nubisco`. */
|
|
4
|
+
interface INubiscoDocsThemeConfig {
|
|
5
|
+
/** `owner/name` on GitHub. Drives the source and issue links in the page header. */
|
|
6
|
+
repo?: string;
|
|
7
|
+
/** The branch the source links point at. Defaults to `master`. */
|
|
8
|
+
branch?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Show the Square and Round switch beside the colour mode. It belongs to the
|
|
11
|
+
* component library's own docs and is off everywhere else.
|
|
12
|
+
*/
|
|
13
|
+
appearanceControl?: boolean;
|
|
14
|
+
}
|
|
15
|
+
interface INubiscoDocsOptions {
|
|
16
|
+
/** The product's name, shown in the top bar and the page header. */
|
|
17
|
+
title: string;
|
|
18
|
+
/** One sentence, for search engines and link previews. */
|
|
19
|
+
description: string;
|
|
20
|
+
/** URL prefix the site is served under, with both slashes: `/acta/`. */
|
|
21
|
+
base: string;
|
|
22
|
+
/** The public address of the site, for the sitemap: `https://docs.nubisco.io/acta/`. */
|
|
23
|
+
hostname: string;
|
|
24
|
+
/** `owner/name` on GitHub: `nubisco/acta`. */
|
|
25
|
+
repo: string;
|
|
26
|
+
/** Branch the edit and source links point at. Defaults to `master`. */
|
|
27
|
+
branch?: string;
|
|
28
|
+
/** Folder of the docs inside the repository, for the edit link. Defaults to `docs/`. */
|
|
29
|
+
docsDir?: string;
|
|
30
|
+
/** Path of the product's mark under `public/`. Defaults to `/logo.svg`. */
|
|
31
|
+
logo?: string;
|
|
32
|
+
/** Browser chrome colour. Defaults to the dark ground. */
|
|
33
|
+
themeColor?: string;
|
|
34
|
+
/** The top bar's links, in the order the standard sets (see the docs standard). */
|
|
35
|
+
nav: DefaultTheme.NavItem[];
|
|
36
|
+
/** The left navigation. Keyed by path prefix, or one list. */
|
|
37
|
+
sidebar: DefaultTheme.Sidebar;
|
|
38
|
+
/** HTML for the two footer lines. Links are allowed. */
|
|
39
|
+
footer?: {
|
|
40
|
+
message?: string;
|
|
41
|
+
copyright?: string;
|
|
42
|
+
};
|
|
43
|
+
/** Analytics script. Nubisco's by default, `false` for none. */
|
|
44
|
+
analytics?: string | false;
|
|
45
|
+
/** Show the Square and Round switch. Component library only. */
|
|
46
|
+
appearanceControl?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Anything else VitePress accepts, merged over the defaults. `vite` and
|
|
49
|
+
* `themeConfig` are merged one level deep, `head` is appended, and a
|
|
50
|
+
* `markdown.config` is called after the SDK's own.
|
|
51
|
+
*/
|
|
52
|
+
vitepress?: UserConfig<DefaultTheme.Config>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The VitePress config for a Nubisco product's documentation.
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* // docs/.vitepress/config.ts
|
|
60
|
+
* import { defineNubiscoDocs } from '@nubisco/docs-sdk'
|
|
61
|
+
*
|
|
62
|
+
* export default defineNubiscoDocs({
|
|
63
|
+
* title: 'Acta',
|
|
64
|
+
* description: '…',
|
|
65
|
+
* base: '/acta/',
|
|
66
|
+
* hostname: 'https://docs.nubisco.io/acta/',
|
|
67
|
+
* repo: 'nubisco/acta',
|
|
68
|
+
* nav: [...],
|
|
69
|
+
* sidebar: { ... },
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Everything the design standard fixes is set here, so a product states only
|
|
74
|
+
* what is its own: its name, its address, its navigation and its footer.
|
|
75
|
+
*/
|
|
76
|
+
declare function defineNubiscoDocs(options: INubiscoDocsOptions): UserConfig<DefaultTheme.Config>;
|
|
77
|
+
|
|
78
|
+
export { type INubiscoDocsOptions, type INubiscoDocsThemeConfig, defineNubiscoDocs };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
// src/node/index.ts
|
|
2
|
+
import { defineConfig } from "vitepress";
|
|
3
|
+
import svgLoader from "vite-svg-loader";
|
|
4
|
+
import {
|
|
5
|
+
groupIconMdPlugin,
|
|
6
|
+
groupIconVitePlugin
|
|
7
|
+
} from "vitepress-plugin-group-icons";
|
|
8
|
+
import { nubiscoUI } from "@nubisco/ui/vite";
|
|
9
|
+
import { fonts } from "@nubisco/ui/plugins/fonts";
|
|
10
|
+
|
|
11
|
+
// src/plugins/tabs/markdown/markdownPlugin.ts
|
|
12
|
+
import container from "markdown-it-container";
|
|
13
|
+
|
|
14
|
+
// src/plugins/tabs/markdown/ruleBlockTab.ts
|
|
15
|
+
var tabMarker = "=";
|
|
16
|
+
var tabMarkerCode = tabMarker.charCodeAt(0);
|
|
17
|
+
var minTabMarkerLen = 2;
|
|
18
|
+
var ruleBlockTab = (state, startLine, endLine, silent) => {
|
|
19
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
20
|
+
const max = state.eMarks[startLine];
|
|
21
|
+
if (state.parentType !== "container") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (pos + minTabMarkerLen > max) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const marker = state.src.charCodeAt(pos);
|
|
28
|
+
if (marker !== tabMarkerCode) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const mem = pos;
|
|
32
|
+
pos = state.skipChars(pos + 1, marker);
|
|
33
|
+
const tabMarkerLen = pos - mem;
|
|
34
|
+
if (tabMarkerLen < minTabMarkerLen - 1) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (silent) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
let nextLine = startLine;
|
|
41
|
+
let endStart = mem;
|
|
42
|
+
let endPos = pos;
|
|
43
|
+
for (; ; ) {
|
|
44
|
+
nextLine++;
|
|
45
|
+
if (nextLine >= endLine) {
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
endStart = state.bMarks[nextLine] + state.tShift[nextLine];
|
|
49
|
+
const max2 = state.eMarks[nextLine];
|
|
50
|
+
if (endStart < max2 && state.sCount[nextLine] < state.blkIndent) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
const startCharCode = state.src.charCodeAt(endStart);
|
|
54
|
+
if (startCharCode !== tabMarkerCode) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const p = state.skipChars(endStart + 1, marker);
|
|
58
|
+
if (p - endStart !== tabMarkerLen) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
endPos = p;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
const oldParent = state.parentType;
|
|
65
|
+
const oldLineMax = state.lineMax;
|
|
66
|
+
state.parentType = "tab";
|
|
67
|
+
state.lineMax = nextLine;
|
|
68
|
+
const startToken = state.push("tab_open", "div", 1);
|
|
69
|
+
startToken.markup = state.src.slice(mem, pos);
|
|
70
|
+
startToken.block = true;
|
|
71
|
+
startToken.info = state.src.slice(pos, max).trimStart();
|
|
72
|
+
startToken.map = [startLine, nextLine - 1];
|
|
73
|
+
state.md.block.tokenize(state, startLine + 1, nextLine);
|
|
74
|
+
const endToken = state.push("tab_close", "div", -1);
|
|
75
|
+
endToken.markup = state.src.slice(endStart, endPos);
|
|
76
|
+
endToken.block = true;
|
|
77
|
+
state.parentType = oldParent;
|
|
78
|
+
state.lineMax = oldLineMax;
|
|
79
|
+
state.line = nextLine;
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/plugins/tabs/markdown/markdownPlugin.ts
|
|
84
|
+
var parseTabsParams = (input) => {
|
|
85
|
+
const match = input.match(/key:(\S+)/);
|
|
86
|
+
return {
|
|
87
|
+
shareStateKey: match?.[1]
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
var tabsPlugin = (md) => {
|
|
91
|
+
md.use(container, "tabs", {
|
|
92
|
+
render(tokens, index) {
|
|
93
|
+
const token = tokens[index];
|
|
94
|
+
if (token.nesting === 1) {
|
|
95
|
+
const params = parseTabsParams(token.info);
|
|
96
|
+
const shareStateKeyProp = params.shareStateKey ? `sharedStateKey="${md.utils.escapeHtml(params.shareStateKey)}"` : "";
|
|
97
|
+
return `<ContentTabs ${shareStateKeyProp}>
|
|
98
|
+
`;
|
|
99
|
+
} else {
|
|
100
|
+
return `</ContentTabs>
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
md.block.ruler.after("container_tabs", "tab", ruleBlockTab);
|
|
106
|
+
const renderTab = (tokens, index) => {
|
|
107
|
+
const token = tokens[index];
|
|
108
|
+
if (token.nesting === 1) {
|
|
109
|
+
const label = token.info;
|
|
110
|
+
const labelProp = `label="${md.utils.escapeHtml(label)}"`;
|
|
111
|
+
return `<ContentTab ${labelProp}>
|
|
112
|
+
`;
|
|
113
|
+
} else {
|
|
114
|
+
return `</ContentTab>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
md.renderer.rules["tab_open"] = renderTab;
|
|
119
|
+
md.renderer.rules["tab_close"] = renderTab;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/plugins/mermaid/mermaid-markdown.ts
|
|
123
|
+
var MermaidMarkdown = (md, pluginOptions) => {
|
|
124
|
+
const fence = md.renderer.rules.fence.bind(md.renderer.rules);
|
|
125
|
+
md.renderer.rules.fence = (tokens, index, options, env, slf) => {
|
|
126
|
+
const token = tokens[index];
|
|
127
|
+
if (token.info.trim() === "mermaid") {
|
|
128
|
+
try {
|
|
129
|
+
const key = index;
|
|
130
|
+
const cssClass = pluginOptions?.class || "mermaid";
|
|
131
|
+
return `
|
|
132
|
+
<Suspense>
|
|
133
|
+
<template #default>
|
|
134
|
+
<Mermaid id="mermaid-${key}" class="${cssClass}" graph="${encodeURIComponent(token.content)}"></Mermaid>
|
|
135
|
+
</template>
|
|
136
|
+
<!-- loading state via #fallback slot -->
|
|
137
|
+
<template #fallback>
|
|
138
|
+
Loading...
|
|
139
|
+
</template>
|
|
140
|
+
</Suspense>`;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
return `<pre>${err}</pre>`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (token.info.trim() === "mmd") {
|
|
146
|
+
tokens[index].info = "mermaid";
|
|
147
|
+
}
|
|
148
|
+
return fence(tokens, index, options, env, slf);
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// src/plugins/mermaid/mermaid-plugin.ts
|
|
153
|
+
var DEFAULT_OPTIONS = {
|
|
154
|
+
// we set loose as default here because is needed to load images
|
|
155
|
+
securityLevel: "loose",
|
|
156
|
+
startOnLoad: false
|
|
157
|
+
};
|
|
158
|
+
function MermaidPlugin(inlineOptions) {
|
|
159
|
+
const options = {
|
|
160
|
+
...DEFAULT_OPTIONS,
|
|
161
|
+
...inlineOptions
|
|
162
|
+
};
|
|
163
|
+
const virtualModuleId = "virtual:mermaid-config";
|
|
164
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
165
|
+
return {
|
|
166
|
+
name: "vite-plugin-mermaid",
|
|
167
|
+
// The component is registered by the theme (`src/theme/index.ts`), not
|
|
168
|
+
// injected into VitePress's client entry by a path in the consumer's tree.
|
|
169
|
+
async resolveId(id) {
|
|
170
|
+
if (id === virtualModuleId) {
|
|
171
|
+
return resolvedVirtualModuleId;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
async load(id) {
|
|
175
|
+
if (id === resolvedVirtualModuleId) {
|
|
176
|
+
return `export default ${JSON.stringify(options)};`;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/plugins/mermaid/index.ts
|
|
183
|
+
var withMermaid = (config) => {
|
|
184
|
+
if (!config.markdown) config.markdown = {};
|
|
185
|
+
const markdownConfigOriginal = config.markdown.config || (() => {
|
|
186
|
+
});
|
|
187
|
+
config.markdown.config = (...args) => {
|
|
188
|
+
MermaidMarkdown(...args, config.mermaidPlugin);
|
|
189
|
+
markdownConfigOriginal(...args);
|
|
190
|
+
};
|
|
191
|
+
if (!config.vite) config.vite = {};
|
|
192
|
+
if (!config.vite.plugins) config.vite.plugins = [];
|
|
193
|
+
config.vite.plugins.push(MermaidPlugin(config.mermaid));
|
|
194
|
+
if (!config.vite.optimizeDeps) config.vite.optimizeDeps = {};
|
|
195
|
+
if (!config.vite.optimizeDeps.include) config.vite.optimizeDeps.include = [];
|
|
196
|
+
config.vite.optimizeDeps.include = [
|
|
197
|
+
...config.vite.optimizeDeps.include,
|
|
198
|
+
"@braintree/sanitize-url",
|
|
199
|
+
"dayjs",
|
|
200
|
+
"debug",
|
|
201
|
+
"cytoscape-cose-bilkent",
|
|
202
|
+
"cytoscape"
|
|
203
|
+
];
|
|
204
|
+
if (!config.vite.resolve) config.vite.resolve = {};
|
|
205
|
+
const mermaidPluginAlias = {
|
|
206
|
+
"dayjs/plugin/advancedFormat.js": "dayjs/esm/plugin/advancedFormat",
|
|
207
|
+
"dayjs/plugin/customParseFormat.js": "dayjs/esm/plugin/customParseFormat",
|
|
208
|
+
"dayjs/plugin/isoWeek.js": "dayjs/esm/plugin/isoWeek",
|
|
209
|
+
"cytoscape/dist/cytoscape.umd.js": "cytoscape/dist/cytoscape.esm.js"
|
|
210
|
+
};
|
|
211
|
+
if (!config.vite.resolve.alias) config.vite.resolve.alias = mermaidPluginAlias;
|
|
212
|
+
else if (Array.isArray(config.vite.resolve.alias)) {
|
|
213
|
+
config.vite.resolve.alias = [
|
|
214
|
+
...config.vite.resolve.alias,
|
|
215
|
+
...Object.entries(mermaidPluginAlias).map(([find, replacement]) => ({
|
|
216
|
+
find,
|
|
217
|
+
replacement
|
|
218
|
+
}))
|
|
219
|
+
];
|
|
220
|
+
} else {
|
|
221
|
+
config.vite.resolve.alias = {
|
|
222
|
+
...config.vite.resolve.alias,
|
|
223
|
+
...mermaidPluginAlias
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return config;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// src/node/index.ts
|
|
230
|
+
var ANALYTICS = "https://analytics.nubisco.io/script.js";
|
|
231
|
+
function defineNubiscoDocs(options) {
|
|
232
|
+
const base = options.base;
|
|
233
|
+
const logo = options.logo ?? "/logo.svg";
|
|
234
|
+
const extra = options.vitepress ?? {};
|
|
235
|
+
const analytics = options.analytics ?? ANALYTICS;
|
|
236
|
+
const docsDir = options.docsDir ?? "docs/";
|
|
237
|
+
const branch = options.branch ?? "master";
|
|
238
|
+
const config = defineConfig({
|
|
239
|
+
...extra,
|
|
240
|
+
title: options.title,
|
|
241
|
+
description: options.description,
|
|
242
|
+
base,
|
|
243
|
+
// The theme owns light and dark (`useTheme()` sets `.dark`), so VitePress's
|
|
244
|
+
// own appearance switch stays off.
|
|
245
|
+
appearance: false,
|
|
246
|
+
// `_shared.md` fragments are included by tab pages. They are not pages.
|
|
247
|
+
srcExclude: ["**/_*.md", ...extra.srcExclude ?? []],
|
|
248
|
+
lastUpdated: true,
|
|
249
|
+
head: [
|
|
250
|
+
["link", { rel: "icon", href: `${base}favicon.ico`, sizes: "any" }],
|
|
251
|
+
[
|
|
252
|
+
"link",
|
|
253
|
+
{
|
|
254
|
+
rel: "icon",
|
|
255
|
+
type: "image/png",
|
|
256
|
+
sizes: "32x32",
|
|
257
|
+
href: `${base}favicon-32x32.png`
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
[
|
|
261
|
+
"link",
|
|
262
|
+
{
|
|
263
|
+
rel: "icon",
|
|
264
|
+
type: "image/png",
|
|
265
|
+
sizes: "16x16",
|
|
266
|
+
href: `${base}favicon-16x16.png`
|
|
267
|
+
}
|
|
268
|
+
],
|
|
269
|
+
[
|
|
270
|
+
"link",
|
|
271
|
+
{
|
|
272
|
+
rel: "apple-touch-icon",
|
|
273
|
+
sizes: "180x180",
|
|
274
|
+
href: `${base}apple-touch-icon.png`
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
["link", { rel: "manifest", href: `${base}site.webmanifest` }],
|
|
278
|
+
[
|
|
279
|
+
"meta",
|
|
280
|
+
{ name: "theme-color", content: options.themeColor ?? "#0d0d0f" }
|
|
281
|
+
],
|
|
282
|
+
...analytics ? [
|
|
283
|
+
["script", { defer: "", src: analytics }]
|
|
284
|
+
] : [],
|
|
285
|
+
...extra.head ?? []
|
|
286
|
+
],
|
|
287
|
+
markdown: {
|
|
288
|
+
...extra.markdown,
|
|
289
|
+
config(md) {
|
|
290
|
+
md.use(tabsPlugin);
|
|
291
|
+
md.use(groupIconMdPlugin);
|
|
292
|
+
extra.markdown?.config?.(md);
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
sitemap: { hostname: options.hostname, ...extra.sitemap },
|
|
296
|
+
vite: {
|
|
297
|
+
...extra.vite,
|
|
298
|
+
plugins: [
|
|
299
|
+
svgLoader(),
|
|
300
|
+
groupIconVitePlugin(),
|
|
301
|
+
// The theme passes icon modules to NbIcon at run time, which the glyph
|
|
302
|
+
// transform cannot see through. They need no catalogue.
|
|
303
|
+
nubiscoUI({ glyphs: { catalog: "off", warnUnresolved: false } }),
|
|
304
|
+
fonts(),
|
|
305
|
+
...extra.vite?.plugins ?? []
|
|
306
|
+
],
|
|
307
|
+
ssr: {
|
|
308
|
+
...extra.vite?.ssr,
|
|
309
|
+
// The theme and the library ship Vue sources and ESM, which VitePress
|
|
310
|
+
// must compile with the page, not load from node_modules as is.
|
|
311
|
+
noExternal: [
|
|
312
|
+
"@nubisco/docs-sdk",
|
|
313
|
+
"@nubisco/ui",
|
|
314
|
+
"vue",
|
|
315
|
+
...extra.vite?.ssr?.noExternal ?? []
|
|
316
|
+
]
|
|
317
|
+
},
|
|
318
|
+
optimizeDeps: {
|
|
319
|
+
...extra.vite?.optimizeDeps,
|
|
320
|
+
exclude: [
|
|
321
|
+
"@nubisco/docs-sdk",
|
|
322
|
+
...extra.vite?.optimizeDeps?.exclude ?? []
|
|
323
|
+
]
|
|
324
|
+
},
|
|
325
|
+
css: {
|
|
326
|
+
...extra.vite?.css,
|
|
327
|
+
preprocessorOptions: {
|
|
328
|
+
scss: { api: "modern-compiler" },
|
|
329
|
+
...extra.vite?.css?.preprocessorOptions
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
themeConfig: {
|
|
334
|
+
siteTitle: options.title,
|
|
335
|
+
logo: { src: logo, width: 24, height: 24 },
|
|
336
|
+
nav: options.nav,
|
|
337
|
+
sidebar: options.sidebar,
|
|
338
|
+
socialLinks: [
|
|
339
|
+
{ icon: "github", link: `https://github.com/${options.repo}` }
|
|
340
|
+
],
|
|
341
|
+
editLink: {
|
|
342
|
+
pattern: `https://github.com/${options.repo}/edit/${branch}/${docsDir}:path`,
|
|
343
|
+
text: "Edit this page on GitHub"
|
|
344
|
+
},
|
|
345
|
+
search: { provider: "local" },
|
|
346
|
+
lastUpdated: { text: "Last updated" },
|
|
347
|
+
footer: options.footer,
|
|
348
|
+
...extra.themeConfig,
|
|
349
|
+
// Read by the theme. Typed in `INubiscoDocsThemeConfig`.
|
|
350
|
+
nubisco: {
|
|
351
|
+
repo: options.repo,
|
|
352
|
+
branch,
|
|
353
|
+
appearanceControl: options.appearanceControl ?? false
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
return withMermaid(config);
|
|
358
|
+
}
|
|
359
|
+
export {
|
|
360
|
+
defineNubiscoDocs
|
|
361
|
+
};
|