vitepress-allyouneed 0.4.3 → 0.5.0-beta.3
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/CHANGELOG.md +82 -0
- package/README.md +54 -8
- package/dist/index.cjs +91 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +91 -43
- package/dist/index.js.map +1 -1
- package/dist/theme/components/DocHeader.vue +55 -15
- package/dist/theme/components/Tags.vue +24 -5
- package/dist/theme/components/VaultGraph.vue +223 -65
- package/dist/theme/components/VaultStats.vue +34 -10
- package/dist/theme/composables/useVaultData.cjs +21 -6
- package/dist/theme/composables/useVaultData.cjs.map +1 -1
- package/dist/theme/composables/useVaultData.d.cts +12 -1
- package/dist/theme/composables/useVaultData.d.ts +12 -1
- package/dist/theme/composables/useVaultData.js +19 -5
- package/dist/theme/composables/useVaultData.js.map +1 -1
- package/dist/theme/index.cjs +37 -14
- package/dist/theme/index.cjs.map +1 -1
- package/dist/theme/index.d.cts +8 -0
- package/dist/theme/index.d.ts +8 -0
- package/dist/theme/index.js +36 -14
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/styles/callouts.css +9 -3
- package/dist/theme/styles/doc-header.css +10 -1
- package/dist/theme/styles/graph.css +84 -11
- package/dist/theme/styles/index.css +24 -1
- package/dist/theme/styles/shared.css +12 -2
- package/dist/theme/styles/stats.css +11 -0
- package/dist/theme/styles/tags.css +17 -3
- package/dist/vite.cjs +46 -36
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +46 -36
- package/dist/vite.js.map +1 -1
- package/dist/vitepress.cjs +91 -43
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.js +91 -43
- package/dist/vitepress.js.map +1 -1
- package/package.json +7 -2
- package/style.css +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/);版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.5.0-beta.3] - 2026-05-22
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Tags 视图(可能也包括其它视图)整片失样**:0.5.0-beta.0/.1/.2 的 `@layer` 声明用了 `@import url('./x.css') layer(vitepress-allyouneed)` 这种"在 @import 子句上挂 layer"语法。CSS 标准支持,但 **Vite + postcss-import / lightningcss 不同链路对它支持参差**:某些组合下 `layer()` 子句被吞,resolve 后的规则**没进 layer**;另一些组合下规则进了 layer 但没正确链入 layer order,被埋在最底层 specificity 一概输掉。Tags chip 失去 pill 样式就是这个症状(`.ayn-tag-chip` 的 padding/border/radius/bg 全输给 user-agent + VP)。
|
|
9
|
+
- **改法**:不再用 `@import ... layer()`。每个 .css 文件**自己头尾**包 `@layer vitepress-allyouneed { ... }`,这是浏览器原生 cascade layer 语法,不经过 bundler 黑盒,100% 可靠。`styles/index.css` 退回最朴素的 `@import './x.css'`。
|
|
10
|
+
- 行为不变:7 个 .css 全 layered,主题作者 unlayered CSS 自动赢。
|
|
11
|
+
|
|
12
|
+
### Files touched
|
|
13
|
+
- `src/theme/styles/index.css`(去 layer() 子句)
|
|
14
|
+
- `src/theme/styles/shared.css`、`stats.css`、`tags.css`、`graph.css`、`callouts.css`、`doc-header.css`(各自头尾包 @layer block)
|
|
15
|
+
- `style.css`(同上)
|
|
16
|
+
|
|
17
|
+
## [0.5.0-beta.2] - 2026-05-22
|
|
18
|
+
|
|
19
|
+
更彻底的修法:把 DocHeader 的 banner title 改成 `<div role="heading" aria-level="1">`,把 doc-header.css 放回 @layer,所有 7 个 .css 终于统一 layered。
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **DocHeader banner 元素 `<h1>` → `<div role="heading" aria-level="1">`**:`.vp-doc h1` 选择器不再匹配我们,@layer 内 layered CSS 不再被 VitePress 默认 unlayered 32px 字号覆盖。
|
|
23
|
+
- 视觉:无差(`.ayn-doc-banner-title` 字号/字重等都生效)
|
|
24
|
+
- 辅助技术:WAI-ARIA 标准,屏幕阅读器按 h1 念出,跟原生 `<h1>` 等同
|
|
25
|
+
- SEO:Google 早期声明 `role="heading" aria-level="1"` 跟 `<h1>` 等价对待
|
|
26
|
+
- 文档大纲算法:99% 工具支持;少数 reader-mode 工具可能少识别一个标题
|
|
27
|
+
- **doc-header.css 放回 `@layer vitepress-allyouneed`**:0.5.0-beta.1 的"豁免"特例不再需要。**所有 7 个 .css 都 layered**,主题作者覆盖故事彻底干净
|
|
28
|
+
- `styles/index.css` 不再 split "layered / unlayered",注释简化
|
|
29
|
+
|
|
30
|
+
### Why
|
|
31
|
+
0.5.0-beta.0 引入 @layer 后,banner title 是 `<h1>` 在 `.vp-doc` 内,VP 默认 `.vp-doc h1 { font-size: 32px }` 是 unlayered,我们 layered CSS 永远输 → banner title 字号塌缩。0.5.0-beta.1 临时方案:doc-header.css 不 layer。0.5.0-beta.2 釜底抽薪:banner 不用 `<h1>` 元素了,VP 选择器抓不到我们。
|
|
32
|
+
|
|
33
|
+
## [0.5.0-beta.1] - 2026-05-22
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- **DocHeader banner title 字号丢失**(0.5.0-beta.0 回归):banner title 是 `<h1>` 在 `.vp-doc` 内,VitePress 默认 `.vp-doc h1 { font-size: 32px }` 是 unlayered;0.5.0-beta.0 把 `doc-header.css` 包进 `@layer vitepress-allyouneed` 后,**layered 永远输 unlayered**,我们的 `clamp(2rem, 4.5vw, 3.25rem)` 大字号被 VP 32px 覆盖 → "大标题"看起来变小。
|
|
37
|
+
- **修法**:`doc-header.css` 不再 layer。原则上"必须压过 VP unlayered defaults 的 CSS"不能 layer;"用户可覆盖的装饰"才 layer。文档 `styles/index.css` 顶部添加注释说明这条边界
|
|
38
|
+
- 其它 6 个 CSS 文件继续 layer(它们的 selector 不跟 VP 默认强冲突)
|
|
39
|
+
|
|
40
|
+
### Note for theme authors
|
|
41
|
+
想覆盖 banner title:写 `.ayn-doc-banner-title { ... }` —— 跟 0.4.x 行为一致(unlayered 源顺序赢)。注意我们文件在 `defineTheme` import 时加载,你 CSS 必须在它之后 import 才赢。
|
|
42
|
+
|
|
43
|
+
## [0.5.0-beta.0] - 2026-05-21
|
|
44
|
+
|
|
45
|
+
主题集成大改 —— **目标:让 3rd-party VitePress 主题作者完全不需要知道本插件**。
|
|
46
|
+
|
|
47
|
+
### Theme: CSS 用 `@layer` 包裹(底层化)
|
|
48
|
+
- 全部 7 个 .css 文件通过 `styles/index.css` 用 `@import ... layer(vitepress-allyouneed)` 加载,所有规则进 `vitepress-allyouneed` cascade layer
|
|
49
|
+
- **后果**:用户(或第三方主题)写的任何 unlayered CSS **自动赢**我们,无论 specificity 或 import 顺序。`.wikilink { color: red }` 真就 red,不用知道我们有个 `.wikilink`
|
|
50
|
+
- 删除全部 3 处 `!important`(`callouts.css` callout-title 色、`shared.css` mark 内 mathjax bg、`tags.css` tag link 下划线 reset)—— 它们都不需要 `!important`,specificity 已够,且 `!important` 会在 layer 内反向打败用户 unlayered。删了用户 100% 能盖
|
|
51
|
+
- 浏览器支持:`@layer` Chrome/Edge 99 / Firefox 97 / Safari 15.4+(2022 春)
|
|
52
|
+
|
|
53
|
+
### Theme: 新 `defineTheme()` 工厂(替代之前的 `withAllYouNeed` 设想)
|
|
54
|
+
- `vitepress-allyouneed/theme` 默认导出仍是开箱即用的 Theme 对象,**额外**导出 `defineTheme(userTheme?)` 工厂
|
|
55
|
+
- 三种用户场景:
|
|
56
|
+
1. **零配置**:`export { default } from 'vitepress-allyouneed/theme'` — 一行完事(DefaultTheme + 我们组件 + 我们 CSS)
|
|
57
|
+
2. **自定义 Layout / 加自己组件**:`defineTheme({ Layout, enhanceApp })`
|
|
58
|
+
3. **嵌 3rd-party 主题**:`defineTheme({ extends: SomeAwesomeTheme })`
|
|
59
|
+
- 内部:用户 `enhanceApp` 在我们之后跑 → 同名 `app.component()` 注册**自动赢**(Vue last-registration-wins);用户 `Layout`、`setup` 直接替换
|
|
60
|
+
- 主题包作者的工作流跟有没有本插件**完全无关**:他们写正常 VitePress 主题,published,最终用户负责 `defineTheme({ extends: ... })` 一行接入
|
|
61
|
+
|
|
62
|
+
### Theme: 可被替换的 Vue 组件清单(API 契约)
|
|
63
|
+
| 组件名 | 干什么 | 用户怎么换 |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `Layout` | DefaultTheme.Layout + 自动 `<DocHeader />` + `frontmatter.cssclasses` → body | `defineTheme({ Layout: MyLayout })` |
|
|
66
|
+
| `DocHeader` | 文档头:banner / 标题 / 时间 / tags | `app.component('DocHeader', MyDocHeader)` |
|
|
67
|
+
| `VaultGraph` | d3 力导向关系图 | 同上 |
|
|
68
|
+
| `VaultStats` | 统计卡片 | 同上 |
|
|
69
|
+
| `Tags` | 标签云 + 搜索 + 列表 | 同上 |
|
|
70
|
+
|
|
71
|
+
### Composables(显式契约)
|
|
72
|
+
`useVaultData()` 早已暴露;0.5.0 起明确这是"给写自己 UI 的人"的公共 API。
|
|
73
|
+
|
|
74
|
+
### Docs
|
|
75
|
+
- `src/theme/index.ts` 文件头三段示例覆盖三种场景
|
|
76
|
+
- README "当前版本" 章节同步
|
|
77
|
+
- DOCS.md 新增 "Theming" 章节(下个 beta 补全)
|
|
78
|
+
|
|
79
|
+
### Why beta
|
|
80
|
+
- @layer 在 Vite CSS pipeline 的实际行为没在我这边 prod build 跑过,需要真实项目验证
|
|
81
|
+
- `defineTheme()` 是新 API,等用户回声再 stabilize
|
|
82
|
+
- 老 0.4.x 用户 `import AllYouNeedTheme from 'vitepress-allyouneed/theme'` 仍兼容(default export 没变),只是多了 `defineTheme` 命名导出
|
|
83
|
+
|
|
84
|
+
### Migration from 0.4.x
|
|
85
|
+
**完全无 breaking** —— 老代码继续跑。新代码推荐用 `defineTheme()`,见 README。
|
|
86
|
+
|
|
5
87
|
## [0.4.1] - 2026-05-21
|
|
6
88
|
|
|
7
89
|
修 0.4.0 几个回归 + 小幅 UX 优化。
|
package/README.md
CHANGED
|
@@ -4,16 +4,62 @@
|
|
|
4
4
|
|
|
5
5
|
Forked from [`actuallysomecat/markdown-it-wikilinks-plus`](https://github.com/actuallysomecat/markdown-it-wikilinks-plus) (MIT) 并针对 VitePress 大幅重写。
|
|
6
6
|
|
|
7
|
-
## 当前版本:0.
|
|
7
|
+
## 当前版本:0.5.0-beta.0(2026-05-21)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**主题集成大改 —— 目标:让第三方 VitePress 主题作者不需要知道本插件存在**
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
### CSS 自动让用户赢(`@layer`)
|
|
12
|
+
|
|
13
|
+
我们所有 CSS 包在 `@layer vitepress-allyouneed` 里。CSS 标准规则:**任何 unlayered CSS 永远赢 layered CSS**,无关顺序、specificity。所以:
|
|
14
|
+
|
|
15
|
+
```css
|
|
16
|
+
/* 第三方主题随便写,自动赢 */
|
|
17
|
+
.wikilink { color: red; }
|
|
18
|
+
.callout { border-radius: 12px; }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
零知识负担。
|
|
22
|
+
|
|
23
|
+
### Vue 组件:`defineTheme()` 工厂
|
|
24
|
+
|
|
25
|
+
三种场景,递进式:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// 1. 零配置(默认主题 + 我们)
|
|
29
|
+
export { default } from 'vitepress-allyouneed/theme'
|
|
30
|
+
|
|
31
|
+
// 2. 自定义 Layout / 覆盖某个视图
|
|
32
|
+
import { defineTheme } from 'vitepress-allyouneed/theme'
|
|
33
|
+
import MyLayout from './MyLayout.vue'
|
|
34
|
+
import MyVaultGraph from './MyVaultGraph.vue'
|
|
35
|
+
export default defineTheme({
|
|
36
|
+
Layout: MyLayout,
|
|
37
|
+
enhanceApp({ app }) {
|
|
38
|
+
app.component('VaultGraph', MyVaultGraph) // 同名注册自动覆盖
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// 3. 嵌别人写的 VitePress 主题(主题包作者无需感知本插件)
|
|
43
|
+
import { defineTheme } from 'vitepress-allyouneed/theme'
|
|
44
|
+
import SomeTheme from 'some-vitepress-theme'
|
|
45
|
+
export default defineTheme({ extends: SomeTheme })
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
可被替换的全局组件:`Layout` / `DocHeader` / `VaultGraph` / `VaultStats` / `Tags`。
|
|
49
|
+
|
|
50
|
+
### 4.x 兼容
|
|
51
|
+
|
|
52
|
+
老代码 `import theme from 'vitepress-allyouneed/theme'; export default theme` 继续跑,没有 breaking。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### 0.4.x 重要变更(从 0.3.x 升级看这里)
|
|
57
|
+
|
|
58
|
+
- **`sidebarAuto.autoFolderIndex` 已删除**。文件夹链接由 `sidebarAuto.folderLinkOrder`(默认 `['same-name', 'index', 'readme', 'first-file']`)在 sidebar/nav/wikilink 解析时直接处理。
|
|
59
|
+
- **数字排序修正(0.4.1)**:`1, 2, 10, 11` 真按数字大小排。
|
|
60
|
+
- **`markdown.math: true`** 自动检测 — 没装 `markdown-it-mathjax3` 时给清晰提示。
|
|
61
|
+
- **dev HMR**:`.md` add/remove 或 `_sidebar.md` 改动自动 server restart。
|
|
62
|
+
- **leading-number 锚点**:`#13` 能匹 `## 13) Optik`、`13: ...` 等。
|
|
17
63
|
|
|
18
64
|
完整 changelog 见 [`CHANGELOG.md`](./CHANGELOG.md);配置参考见 [`DOCS.md`](./DOCS.md)。
|
|
19
65
|
|
package/dist/index.cjs
CHANGED
|
@@ -2102,11 +2102,10 @@ var markdown_it_default = allYouNeedMarkdownIt;
|
|
|
2102
2102
|
|
|
2103
2103
|
// src/vite.ts
|
|
2104
2104
|
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
2105
|
-
var
|
|
2105
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
2106
2106
|
|
|
2107
2107
|
// src/core/asset-pipeline/dev-middleware.ts
|
|
2108
2108
|
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
2109
|
-
var import_node_path5 = __toESM(require("path"), 1);
|
|
2110
2109
|
function createDevMiddleware(index, options) {
|
|
2111
2110
|
return (req, res, next) => {
|
|
2112
2111
|
if (!req.url) return next();
|
|
@@ -2124,25 +2123,38 @@ function createDevMiddleware(index, options) {
|
|
|
2124
2123
|
if (!/\.[a-zA-Z0-9]+$/.test(decoded)) return next();
|
|
2125
2124
|
const relCandidate = decoded.replace(/^\/+/, "");
|
|
2126
2125
|
let asset = index.assetsByRelativePath.get(relCandidate);
|
|
2127
|
-
if (!asset) {
|
|
2126
|
+
if (!asset && !relCandidate.includes("/")) {
|
|
2128
2127
|
const bn = basename(decoded);
|
|
2129
2128
|
const map = options.caseSensitive ? index.assetsByBasename : index.assetsByBasenameLower;
|
|
2130
2129
|
const key = options.caseSensitive ? bn : bn.toLowerCase();
|
|
2131
2130
|
const candidates = map.get(key);
|
|
2132
|
-
if (candidates && candidates.length > 0)
|
|
2131
|
+
if (candidates && candidates.length > 0) {
|
|
2132
|
+
asset = [...candidates].sort(
|
|
2133
|
+
(a, b) => a.relativePath.length - b.relativePath.length
|
|
2134
|
+
)[0];
|
|
2135
|
+
}
|
|
2133
2136
|
}
|
|
2134
2137
|
if (!asset) return next();
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2138
|
+
const etag = `W/"${asset.size.toString(16)}-${Math.floor(asset.mtime).toString(16)}"`;
|
|
2139
|
+
const lastModified = new Date(asset.mtime).toUTCString();
|
|
2140
|
+
const ifNoneMatch = req.headers["if-none-match"];
|
|
2141
|
+
const ifModifiedSince = req.headers["if-modified-since"];
|
|
2142
|
+
if (ifNoneMatch === etag || ifModifiedSince && Date.parse(ifModifiedSince) >= Math.floor(asset.mtime)) {
|
|
2143
|
+
res.statusCode = 304;
|
|
2144
|
+
res.setHeader("ETag", etag);
|
|
2145
|
+
res.setHeader("Last-Modified", lastModified);
|
|
2146
|
+
return res.end();
|
|
2140
2147
|
}
|
|
2141
2148
|
res.statusCode = 200;
|
|
2142
2149
|
res.setHeader("Content-Type", guessMime(asset.extension));
|
|
2143
|
-
res.setHeader("Content-Length", String(
|
|
2150
|
+
res.setHeader("Content-Length", String(asset.size));
|
|
2144
2151
|
res.setHeader("Cache-Control", "no-cache");
|
|
2145
|
-
|
|
2152
|
+
res.setHeader("ETag", etag);
|
|
2153
|
+
res.setHeader("Last-Modified", lastModified);
|
|
2154
|
+
import_node_fs4.default.createReadStream(asset.absolutePath).on("error", () => {
|
|
2155
|
+
if (!res.headersSent) next();
|
|
2156
|
+
else res.destroy();
|
|
2157
|
+
}).pipe(res);
|
|
2146
2158
|
};
|
|
2147
2159
|
}
|
|
2148
2160
|
var MIME = {
|
|
@@ -2174,14 +2186,14 @@ function guessMime(ext) {
|
|
|
2174
2186
|
|
|
2175
2187
|
// src/core/views/generate-md.ts
|
|
2176
2188
|
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
2177
|
-
var
|
|
2189
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
2178
2190
|
var VIEW_SENTINEL = "<!-- generated by vitepress-allyouneed (do not edit; will be regenerated) -->";
|
|
2179
2191
|
function generateViewMarkdown(options, index) {
|
|
2180
2192
|
const report = { written: [], skipped: [] };
|
|
2181
2193
|
if (!options.modules.views) return report;
|
|
2182
|
-
const srcDir =
|
|
2194
|
+
const srcDir = import_node_path5.default.resolve(options.srcDir);
|
|
2183
2195
|
const prefix = options.views.urlPrefix;
|
|
2184
|
-
const viewDir = prefix ?
|
|
2196
|
+
const viewDir = prefix ? import_node_path5.default.join(srcDir, prefix) : srcDir;
|
|
2185
2197
|
if (prefix) {
|
|
2186
2198
|
try {
|
|
2187
2199
|
import_node_fs5.default.mkdirSync(viewDir, { recursive: true });
|
|
@@ -2190,7 +2202,7 @@ function generateViewMarkdown(options, index) {
|
|
|
2190
2202
|
}
|
|
2191
2203
|
const views = buildViewList(options);
|
|
2192
2204
|
for (const v of views) {
|
|
2193
|
-
const target =
|
|
2205
|
+
const target = import_node_path5.default.join(viewDir, v.fileName);
|
|
2194
2206
|
if (import_node_fs5.default.existsSync(target)) {
|
|
2195
2207
|
let existing;
|
|
2196
2208
|
try {
|
|
@@ -2271,8 +2283,8 @@ function renderTemplate(v) {
|
|
|
2271
2283
|
|
|
2272
2284
|
// src/core/views/generate-data.ts
|
|
2273
2285
|
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
2274
|
-
var
|
|
2275
|
-
var PLUGIN_VERSION = "0.
|
|
2286
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
2287
|
+
var PLUGIN_VERSION = true ? "0.5.0-beta.3" : "0.0.0-dev";
|
|
2276
2288
|
var WIKILINK_RE = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
2277
2289
|
var DEFAULT_BODY_TAG_RE = /(?:^|[\s([{,;。,;])#([\p{L}_][\p{L}\p{N}_/-]*)/gu;
|
|
2278
2290
|
function buildBodyTagRe(userPattern) {
|
|
@@ -2329,19 +2341,6 @@ function buildVaultData(index, options) {
|
|
|
2329
2341
|
const edges = [...edgeMap.values()];
|
|
2330
2342
|
const bodyTagRe = buildBodyTagRe(options.views.inlineTagPattern);
|
|
2331
2343
|
const tagsMap = /* @__PURE__ */ new Map();
|
|
2332
|
-
for (const f of userFiles) {
|
|
2333
|
-
const allTags = new Set(f.tags);
|
|
2334
|
-
if (options.views.parseInlineTags) {
|
|
2335
|
-
for (const tm of f.content.matchAll(bodyTagRe)) {
|
|
2336
|
-
allTags.add(tm[1]);
|
|
2337
|
-
}
|
|
2338
|
-
}
|
|
2339
|
-
for (const tag of allTags) {
|
|
2340
|
-
const arr = tagsMap.get(tag) ?? [];
|
|
2341
|
-
arr.push(f);
|
|
2342
|
-
tagsMap.set(tag, arr);
|
|
2343
|
-
}
|
|
2344
|
-
}
|
|
2345
2344
|
const allTagsByFile = /* @__PURE__ */ new Map();
|
|
2346
2345
|
for (const f of userFiles) {
|
|
2347
2346
|
const set = new Set(f.tags);
|
|
@@ -2349,6 +2348,11 @@ function buildVaultData(index, options) {
|
|
|
2349
2348
|
for (const tm of f.content.matchAll(bodyTagRe)) set.add(tm[1]);
|
|
2350
2349
|
}
|
|
2351
2350
|
allTagsByFile.set(f.relativePath, [...set]);
|
|
2351
|
+
for (const tag of set) {
|
|
2352
|
+
const arr = tagsMap.get(tag) ?? [];
|
|
2353
|
+
arr.push(f);
|
|
2354
|
+
tagsMap.set(tag, arr);
|
|
2355
|
+
}
|
|
2352
2356
|
}
|
|
2353
2357
|
const tags = {};
|
|
2354
2358
|
for (const [tag, files] of tagsMap) {
|
|
@@ -2391,9 +2395,9 @@ function buildVaultData(index, options) {
|
|
|
2391
2395
|
function writeVaultData(index, options) {
|
|
2392
2396
|
const data = buildVaultData(index, options);
|
|
2393
2397
|
const json = JSON.stringify(data);
|
|
2394
|
-
const publicDir =
|
|
2398
|
+
const publicDir = import_node_path6.default.join(import_node_path6.default.resolve(options.srcDir), "public");
|
|
2395
2399
|
import_node_fs6.default.mkdirSync(publicDir, { recursive: true });
|
|
2396
|
-
const out =
|
|
2400
|
+
const out = import_node_path6.default.join(publicDir, options.views.dataFileName);
|
|
2397
2401
|
import_node_fs6.default.writeFileSync(out, json, "utf8");
|
|
2398
2402
|
return { path: out, bytes: json.length };
|
|
2399
2403
|
}
|
|
@@ -2458,7 +2462,7 @@ function viteAllYouNeed(userOptions = {}) {
|
|
|
2458
2462
|
config(_userViteConfig, _envCtx) {
|
|
2459
2463
|
const srcDirOpt = userOptions.srcDir;
|
|
2460
2464
|
if (!srcDirOpt) return void 0;
|
|
2461
|
-
const abs = toPosix(
|
|
2465
|
+
const abs = toPosix(import_node_path7.default.resolve(srcDirOpt));
|
|
2462
2466
|
return {
|
|
2463
2467
|
server: {
|
|
2464
2468
|
fs: {
|
|
@@ -2540,9 +2544,15 @@ function viteAllYouNeed(userOptions = {}) {
|
|
|
2540
2544
|
removeFile(index, ctx.file, resolved);
|
|
2541
2545
|
if (wasIndexed) structuralChange = "remove";
|
|
2542
2546
|
}
|
|
2543
|
-
} catch {
|
|
2544
|
-
|
|
2545
|
-
|
|
2547
|
+
} catch (err) {
|
|
2548
|
+
if (err.code === "ENOENT") {
|
|
2549
|
+
removeFile(index, ctx.file, resolved);
|
|
2550
|
+
if (wasIndexed) structuralChange = "remove";
|
|
2551
|
+
} else {
|
|
2552
|
+
console.warn(
|
|
2553
|
+
`vitepress-allyouneed: stat failed for ${ctx.file} (${err.code ?? "unknown"}); keeping existing index entry.`
|
|
2554
|
+
);
|
|
2555
|
+
}
|
|
2546
2556
|
}
|
|
2547
2557
|
const baseName = ctx.file.split(/[\\/]/).pop() ?? "";
|
|
2548
2558
|
const isSidebarFile = /^_sidebar\.(md|markdown)$/i.test(baseName);
|
|
@@ -3594,7 +3604,7 @@ function computeGroupText(dir, dirIndex, opts) {
|
|
|
3594
3604
|
|
|
3595
3605
|
// src/core/sidebar-auto/generate-sidebar-materialize.ts
|
|
3596
3606
|
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
3597
|
-
var
|
|
3607
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
3598
3608
|
var SIDEBAR_MATERIALIZE_SENTINEL = "<!-- generated by vitepress-allyouneed/sidebar-materialize (do not edit if you want auto-refresh; remove this comment to take ownership) -->";
|
|
3599
3609
|
var MD_RE = /\.(md|markdown)$/i;
|
|
3600
3610
|
var SIDEBAR_RE = /^_sidebar\.(md|markdown)$/i;
|
|
@@ -3602,12 +3612,12 @@ function generateSidebarMaterializations(options, matOpts = {}) {
|
|
|
3602
3612
|
const report = { written: [], skipped: [] };
|
|
3603
3613
|
const mode = matOpts.mode ?? "off";
|
|
3604
3614
|
if (mode === "off") return report;
|
|
3605
|
-
const srcDir =
|
|
3615
|
+
const srcDir = import_node_path8.default.resolve(options.srcDir);
|
|
3606
3616
|
const viewsPrefix = options.views.urlPrefix ? options.views.urlPrefix.replace(/^\/+|\/+$/g, "") : "";
|
|
3607
3617
|
const exclude = matOpts.exclude ?? [];
|
|
3608
3618
|
const dirs = [srcDir, ...collectDirs(srcDir, srcDir, viewsPrefix, exclude, mode)];
|
|
3609
3619
|
for (const dirAbs of dirs) {
|
|
3610
|
-
const target =
|
|
3620
|
+
const target = import_node_path8.default.join(dirAbs, "_sidebar.md");
|
|
3611
3621
|
if (import_node_fs8.default.existsSync(target)) {
|
|
3612
3622
|
let content;
|
|
3613
3623
|
try {
|
|
@@ -3680,8 +3690,8 @@ function collectDirs(root, cur, viewsPrefix, exclude, mode) {
|
|
|
3680
3690
|
if (!e.isDirectory()) continue;
|
|
3681
3691
|
if (e.name.startsWith(".") || e.name.startsWith("_")) continue;
|
|
3682
3692
|
if (e.name === "node_modules" || e.name === "public") continue;
|
|
3683
|
-
const full =
|
|
3684
|
-
const rel =
|
|
3693
|
+
const full = import_node_path8.default.join(dir, e.name);
|
|
3694
|
+
const rel = import_node_path8.default.relative(root, full).split(import_node_path8.default.sep).join("/");
|
|
3685
3695
|
if (viewsPrefix && (rel === viewsPrefix || rel.startsWith(viewsPrefix + "/"))) continue;
|
|
3686
3696
|
if (exclude.some((pat) => matchGlob(rel, pat))) continue;
|
|
3687
3697
|
out.push(full);
|
|
@@ -3695,7 +3705,7 @@ function hasAnyMd(dir) {
|
|
|
3695
3705
|
for (const e of entries) {
|
|
3696
3706
|
if (e.isFile() && MD_RE.test(e.name) && !SIDEBAR_RE.test(e.name)) return true;
|
|
3697
3707
|
if (e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")) {
|
|
3698
|
-
if (hasAnyMd(
|
|
3708
|
+
if (hasAnyMd(import_node_path8.default.join(dir, e.name))) return true;
|
|
3699
3709
|
}
|
|
3700
3710
|
}
|
|
3701
3711
|
} catch {
|
|
@@ -3713,9 +3723,47 @@ var WIKILINK_RE3 = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
|
3713
3723
|
function stripCodeForScan(src) {
|
|
3714
3724
|
let r = src.replace(/```[\s\S]*?```/g, (m) => " ".repeat(m.length));
|
|
3715
3725
|
r = r.replace(/~~~[\s\S]*?~~~/g, (m) => " ".repeat(m.length));
|
|
3716
|
-
r = r
|
|
3726
|
+
r = stripInlineCodeLinear(r);
|
|
3717
3727
|
return r;
|
|
3718
3728
|
}
|
|
3729
|
+
function stripInlineCodeLinear(src) {
|
|
3730
|
+
const out = src.split("");
|
|
3731
|
+
let i = 0;
|
|
3732
|
+
const n = src.length;
|
|
3733
|
+
while (i < n) {
|
|
3734
|
+
if (src.charCodeAt(i) !== 96) {
|
|
3735
|
+
i += 1;
|
|
3736
|
+
continue;
|
|
3737
|
+
}
|
|
3738
|
+
let openLen = 0;
|
|
3739
|
+
while (i + openLen < n && src.charCodeAt(i + openLen) === 96) openLen += 1;
|
|
3740
|
+
const contentStart = i + openLen;
|
|
3741
|
+
let j = contentStart;
|
|
3742
|
+
let closeAt = -1;
|
|
3743
|
+
while (j < n) {
|
|
3744
|
+
if (src.charCodeAt(j) === 96) {
|
|
3745
|
+
let runLen = 0;
|
|
3746
|
+
while (j + runLen < n && src.charCodeAt(j + runLen) === 96) runLen += 1;
|
|
3747
|
+
if (runLen === openLen) {
|
|
3748
|
+
closeAt = j;
|
|
3749
|
+
break;
|
|
3750
|
+
}
|
|
3751
|
+
j += runLen;
|
|
3752
|
+
} else {
|
|
3753
|
+
j += 1;
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
if (closeAt === -1) {
|
|
3757
|
+
i = contentStart;
|
|
3758
|
+
continue;
|
|
3759
|
+
}
|
|
3760
|
+
for (let k = i; k < closeAt + openLen; k++) {
|
|
3761
|
+
if (out[k] !== "\n") out[k] = " ";
|
|
3762
|
+
}
|
|
3763
|
+
i = closeAt + openLen;
|
|
3764
|
+
}
|
|
3765
|
+
return out.join("");
|
|
3766
|
+
}
|
|
3719
3767
|
function scanWikilinks(index, options) {
|
|
3720
3768
|
const dead = [];
|
|
3721
3769
|
const ambiguous = [];
|