vitepress-allyouneed 0.5.3 → 0.5.5
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 +16 -0
- package/README.md +1 -1
- package/dist/index.cjs +89 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +89 -63
- package/dist/index.js.map +1 -1
- package/dist/markdown-it.cjs +44 -11
- package/dist/markdown-it.cjs.map +1 -1
- package/dist/markdown-it.d.cts +1 -1
- package/dist/markdown-it.d.ts +1 -1
- package/dist/markdown-it.js +44 -11
- package/dist/markdown-it.js.map +1 -1
- package/dist/{types-BmxLG9tx.d.cts → types-CtRev1Cc.d.cts} +3 -3
- package/dist/{types-BmxLG9tx.d.ts → types-CtRev1Cc.d.ts} +3 -3
- package/dist/vite.cjs +3 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +3 -2
- package/dist/vite.js.map +1 -1
- package/dist/vitepress.cjs +89 -63
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.d.cts +1 -1
- package/dist/vitepress.d.ts +1 -1
- package/dist/vitepress.js +89 -63
- package/dist/vitepress.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
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
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.5.5] - 2026-06-20
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **目录可由 dirIndex 排序**:`index.md`、`README.md` 或同名目录页现在是该文件夹 group 的排序锚点。默认 `sortBy: 'order-then-title'` 下,给目录页写 `order: 1` 即可控制目录位置;嵌套目录、`per-folder` 根侧栏和 `autoNav` 均一致生效,无需给文件夹名添加数字前缀。顶级 `groupOrder` 仍具有最高优先级。
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **嵌套 `index.md` 生成错误的无尾斜杠 URL**:`cleanUrls: true` 下目录页现在输出 `/guide/` 而不是 `/guide`;与 VitePress 的 `guide/index.html` 路由及 dead-link validator 保持一致。
|
|
17
|
+
- **`scanWikilinks` 把合法 `[[folder/]]` 误报为死链**:启动预扫不再维护遗漏 `folderLinkOrder` 的简化解析器,改为与渲染阶段共用 `resolveWikilink`;目录 index、相对路径、自引用锚点和冲突策略现在只有一套解析语义。
|
|
18
|
+
- **同名页面跨 locale / 区域解析错误**:`[[Gravitationsphysik]]` 这类 basename-only Wikilink 不再直接使用全局 `onConflict`。解析器现在先按源页面的同目录和最长共同路径前缀收窄候选(例如 `zh/themen/*` 优先于 `zh/selfcheck/*`,二者都优先于其它 locale),仍有歧义时才执行 `shortest` / `first` / `error`。
|
|
19
|
+
- 强化当前源页面定位:relativePath 精确匹配先于后缀兜底,且后缀存在多个 locale 命中时不再取扫描顺序中的第一个。
|
|
20
|
+
|
|
5
21
|
## [0.5.3] - 2026-06-20
|
|
6
22
|
|
|
7
23
|
0.5.2 的 **Bug 2 修复不完整**(已发到 npm,故 0.5.2 标记 deprecated;请升到 0.5.3)。本版把它彻底修对,并补齐 i18n 实战验证。
|
package/README.md
CHANGED
|
@@ -155,7 +155,7 @@ export default defineConfig({
|
|
|
155
155
|
| `cleanUrls` | `boolean` | 跟 VitePress `cleanUrls` 走 | URL 是否带 `.html` |
|
|
156
156
|
| `caseSensitive` | `boolean` | `false` | wikilink/asset 解析是否大小写敏感 |
|
|
157
157
|
| `deadLink` | `'silent' \| 'warn' \| 'error'` | `'warn'` | 死链处理 |
|
|
158
|
-
| `onConflict` | `'shortest' \| 'first' \| 'error'` | `'shortest'` |
|
|
158
|
+
| `onConflict` | `'shortest' \| 'first' \| 'error'` | `'shortest'` | 同名文件先按当前页面的同目录/共同路径前缀收窄,再执行冲突策略 |
|
|
159
159
|
| `onAliasConflict` | `'first' \| 'error'` | `'first'` | alias 冲突策略 |
|
|
160
160
|
| `slugify` | `(text: string) => string` | `@mdit-vue/shared` | 锚点 slugifier,必须与 VitePress `markdown.anchor.slugify` 一致 |
|
|
161
161
|
| `assets.preserveAssetPaths` | `boolean` | `false` | true 保留原 vault 路径(`/assets/foo.png`)、不哈希;false 走 `/_assets/<hash>-foo.png` |
|
package/dist/index.cjs
CHANGED
|
@@ -594,7 +594,8 @@ function computeUrl(rel, options) {
|
|
|
594
594
|
} else if (!options.cleanUrls) {
|
|
595
595
|
segments.push("index.html");
|
|
596
596
|
}
|
|
597
|
-
|
|
597
|
+
const url = buildUrl("/", segments);
|
|
598
|
+
return isIndex && options.cleanUrls ? url + "/" : url;
|
|
598
599
|
}
|
|
599
600
|
function pushToArrayMap(m, k, v) {
|
|
600
601
|
const arr = m.get(k);
|
|
@@ -721,22 +722,22 @@ function findSelfEntry(currentSourcePath, index) {
|
|
|
721
722
|
const norm = toPosix(currentSourcePath).replace(/^\.\//, "");
|
|
722
723
|
const byNorm = index.files.get(norm);
|
|
723
724
|
if (byNorm) return byNorm;
|
|
724
|
-
|
|
725
|
+
const srcDir = toPosix(index.srcDir).replace(/\/$/, "");
|
|
726
|
+
const relativeNorm = norm.startsWith(srcDir + "/") ? norm.slice(srcDir.length + 1) : norm;
|
|
727
|
+
const byRelative = index.byRelativePath.get(relativeNorm);
|
|
728
|
+
if (byRelative) return byRelative;
|
|
729
|
+
const suffixHits = [];
|
|
725
730
|
for (const e of index.files.values()) {
|
|
726
731
|
const abs = e.absolutePath;
|
|
727
732
|
if (abs === norm || abs.endsWith("/" + norm)) {
|
|
728
|
-
|
|
729
|
-
|
|
733
|
+
suffixHits.push(e);
|
|
734
|
+
continue;
|
|
730
735
|
}
|
|
731
736
|
if (e.relativePath && norm.endsWith("/" + e.relativePath)) {
|
|
732
|
-
|
|
733
|
-
break;
|
|
737
|
+
suffixHits.push(e);
|
|
734
738
|
}
|
|
735
739
|
}
|
|
736
|
-
if (
|
|
737
|
-
for (const e of index.files.values()) {
|
|
738
|
-
if (e.relativePath && e.relativePath.replace(/^\.\//, "") === norm) return e;
|
|
739
|
-
}
|
|
740
|
+
if (suffixHits.length === 1) return suffixHits[0];
|
|
740
741
|
const bn = basename(norm);
|
|
741
742
|
if (bn) {
|
|
742
743
|
const matches = [];
|
|
@@ -808,17 +809,50 @@ function lookupEntry(target, index, options, currentSourcePath, forcePathStyle =
|
|
|
808
809
|
const candidates = bnMap.get(bnKey);
|
|
809
810
|
if (!candidates || candidates.length === 0) return void 0;
|
|
810
811
|
if (candidates.length === 1) return candidates[0];
|
|
812
|
+
const contextualCandidates = narrowCandidatesBySource(
|
|
813
|
+
candidates,
|
|
814
|
+
currentSourcePath,
|
|
815
|
+
index
|
|
816
|
+
);
|
|
817
|
+
if (contextualCandidates.length === 1) return contextualCandidates[0];
|
|
811
818
|
switch (options.onConflict) {
|
|
812
819
|
case "shortest": {
|
|
813
|
-
const sorted = sortByShortestPath(
|
|
820
|
+
const sorted = sortByShortestPath(contextualCandidates);
|
|
814
821
|
return sorted[0];
|
|
815
822
|
}
|
|
816
823
|
case "first":
|
|
817
|
-
return
|
|
824
|
+
return contextualCandidates[0];
|
|
818
825
|
case "error":
|
|
819
826
|
return void 0;
|
|
820
827
|
}
|
|
821
828
|
}
|
|
829
|
+
function narrowCandidatesBySource(candidates, currentSourcePath, index) {
|
|
830
|
+
if (!currentSourcePath) return candidates;
|
|
831
|
+
const source = findSelfEntry(currentSourcePath, index);
|
|
832
|
+
if (!source) return candidates;
|
|
833
|
+
const sourceDir = directorySegments(source.relativePath);
|
|
834
|
+
let bestScore = 0;
|
|
835
|
+
const scored = candidates.map((candidate) => {
|
|
836
|
+
const candidateDir = directorySegments(candidate.relativePath);
|
|
837
|
+
const exactDirectory = sourceDir.length === candidateDir.length && sourceDir.every((segment, i) => segment === candidateDir[i]);
|
|
838
|
+
if (exactDirectory) {
|
|
839
|
+
return { candidate, score: sourceDir.length + 1 };
|
|
840
|
+
}
|
|
841
|
+
let commonPrefix = 0;
|
|
842
|
+
const limit = Math.min(sourceDir.length, candidateDir.length);
|
|
843
|
+
while (commonPrefix < limit && sourceDir[commonPrefix] === candidateDir[commonPrefix]) {
|
|
844
|
+
commonPrefix += 1;
|
|
845
|
+
}
|
|
846
|
+
return { candidate, score: commonPrefix };
|
|
847
|
+
});
|
|
848
|
+
for (const item of scored) bestScore = Math.max(bestScore, item.score);
|
|
849
|
+
if (bestScore === 0) return candidates;
|
|
850
|
+
return scored.filter((item) => item.score === bestScore).map((item) => item.candidate);
|
|
851
|
+
}
|
|
852
|
+
function directorySegments(relativePath) {
|
|
853
|
+
const parts = toPosix(relativePath).replace(/^\.\//, "").split("/");
|
|
854
|
+
return parts.slice(0, -1);
|
|
855
|
+
}
|
|
822
856
|
function matchHeading(entry, headingPart, slugify, mode) {
|
|
823
857
|
const exact = entry.headings.find(
|
|
824
858
|
(h) => h.text === headingPart || h.slug === headingPart || h.slug === slugify(headingPart)
|
|
@@ -2368,7 +2402,7 @@ function renderTemplate(v) {
|
|
|
2368
2402
|
// src/core/views/generate-data.ts
|
|
2369
2403
|
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
2370
2404
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
2371
|
-
var PLUGIN_VERSION = true ? "0.5.
|
|
2405
|
+
var PLUGIN_VERSION = true ? "0.5.5" : "0.0.0-dev";
|
|
2372
2406
|
var WIKILINK_RE = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
2373
2407
|
var DEFAULT_BODY_TAG_RE = /(?:^|[\s([{,;。,;])#([\p{L}_][\p{L}\p{N}_/-]*)/gu;
|
|
2374
2408
|
function buildBodyTagRe(userPattern) {
|
|
@@ -3420,8 +3454,27 @@ function shouldLinkGroup(opts, isTopLevel) {
|
|
|
3420
3454
|
}
|
|
3421
3455
|
function sortChildKeys(node, opts, isTopLevel) {
|
|
3422
3456
|
const keys = [...node.children.keys()];
|
|
3457
|
+
const collateOpts = { numeric: true, sensitivity: "base" };
|
|
3458
|
+
const compareFolderKeys = (a, b) => {
|
|
3459
|
+
const aNode = node.children.get(a);
|
|
3460
|
+
const bNode = node.children.get(b);
|
|
3461
|
+
const aAnchor = pickTitleSourceCandidate(aNode);
|
|
3462
|
+
const bAnchor = pickTitleSourceCandidate(bNode);
|
|
3463
|
+
if (opts.sortBy === "mtime-desc") {
|
|
3464
|
+
const am = aAnchor?.mtime ?? Number.NEGATIVE_INFINITY;
|
|
3465
|
+
const bm = bAnchor?.mtime ?? Number.NEGATIVE_INFINITY;
|
|
3466
|
+
if (am !== bm) return bm - am;
|
|
3467
|
+
} else if (opts.sortBy === "order-then-title") {
|
|
3468
|
+
const ao = aAnchor ? readOrder(aAnchor, opts.orderKey) : Number.POSITIVE_INFINITY;
|
|
3469
|
+
const bo = bAnchor ? readOrder(bAnchor, opts.orderKey) : Number.POSITIVE_INFINITY;
|
|
3470
|
+
if (ao !== bo) return ao - bo;
|
|
3471
|
+
}
|
|
3472
|
+
const at = computeGroupText(aNode.path, aAnchor, opts);
|
|
3473
|
+
const bt = computeGroupText(bNode.path, bAnchor, opts);
|
|
3474
|
+
return at.localeCompare(bt, void 0, collateOpts);
|
|
3475
|
+
};
|
|
3423
3476
|
if (!isTopLevel || opts.groupOrder.length === 0) {
|
|
3424
|
-
return keys.sort();
|
|
3477
|
+
return keys.sort(compareFolderKeys);
|
|
3425
3478
|
}
|
|
3426
3479
|
const orderMap = /* @__PURE__ */ new Map();
|
|
3427
3480
|
opts.groupOrder.forEach((name, i) => {
|
|
@@ -3457,7 +3510,7 @@ function sortChildKeys(node, opts, isTopLevel) {
|
|
|
3457
3510
|
const ob = orderMap.has(b) ? orderMap.get(b) : orderMap.get(tb);
|
|
3458
3511
|
return oa - ob;
|
|
3459
3512
|
});
|
|
3460
|
-
rest.sort();
|
|
3513
|
+
rest.sort(compareFolderKeys);
|
|
3461
3514
|
return [...indexed, ...rest];
|
|
3462
3515
|
}
|
|
3463
3516
|
function toFlatSidebar(root, opts) {
|
|
@@ -3507,7 +3560,12 @@ function toPerFolderSidebar(root, opts, options, index) {
|
|
|
3507
3560
|
for (const f of sortedRootFiles) {
|
|
3508
3561
|
rootItems.push({ text: opts.formatItemTitle(f), link: f.url });
|
|
3509
3562
|
}
|
|
3510
|
-
const topKeys =
|
|
3563
|
+
const topKeys = sortChildKeys(
|
|
3564
|
+
root,
|
|
3565
|
+
opts,
|
|
3566
|
+
/* isTopLevel */
|
|
3567
|
+
true
|
|
3568
|
+
);
|
|
3511
3569
|
for (const key of topKeys) {
|
|
3512
3570
|
const child = root.children.get(key);
|
|
3513
3571
|
const childWinner = resolveFolderLink(
|
|
@@ -3584,7 +3642,12 @@ function generateNav(index, options, autoOptions = {}) {
|
|
|
3584
3642
|
const root = buildTree2(visible);
|
|
3585
3643
|
const base = options.base.endsWith("/") ? options.base : options.base + "/";
|
|
3586
3644
|
const out = [{ text: opts.homeNavText, link: "/" }];
|
|
3587
|
-
const topKeys =
|
|
3645
|
+
const topKeys = sortChildKeys(
|
|
3646
|
+
root,
|
|
3647
|
+
opts,
|
|
3648
|
+
/* isTopLevel */
|
|
3649
|
+
true
|
|
3650
|
+
);
|
|
3588
3651
|
for (const key of topKeys) {
|
|
3589
3652
|
const child = root.children.get(key);
|
|
3590
3653
|
const winner = resolveFolderLink(
|
|
@@ -3876,9 +3939,14 @@ function scanWikilinks(index, options) {
|
|
|
3876
3939
|
if (isAsset) continue;
|
|
3877
3940
|
}
|
|
3878
3941
|
}
|
|
3879
|
-
const
|
|
3880
|
-
|
|
3881
|
-
|
|
3942
|
+
const resolved = resolveWikilink(
|
|
3943
|
+
rawTargetFull,
|
|
3944
|
+
index,
|
|
3945
|
+
options,
|
|
3946
|
+
isEmbed ? "transclusion" : "page",
|
|
3947
|
+
f.absolutePath
|
|
3948
|
+
);
|
|
3949
|
+
if (resolved.isDead) {
|
|
3882
3950
|
dead.push({
|
|
3883
3951
|
source: f.relativePath,
|
|
3884
3952
|
target: rawTarget,
|
|
@@ -3887,7 +3955,7 @@ function scanWikilinks(index, options) {
|
|
|
3887
3955
|
continue;
|
|
3888
3956
|
}
|
|
3889
3957
|
if (scanAmbig && headingPart) {
|
|
3890
|
-
const targetEntry =
|
|
3958
|
+
const targetEntry = resolved.target;
|
|
3891
3959
|
if (!targetEntry) continue;
|
|
3892
3960
|
const matches2 = findAmbiguousLeadingNumberMatches(targetEntry, headingPart);
|
|
3893
3961
|
if (matches2.length > 1) {
|
|
@@ -3909,27 +3977,6 @@ function scanWikilinks(index, options) {
|
|
|
3909
3977
|
}
|
|
3910
3978
|
return { total, dead, ambiguous };
|
|
3911
3979
|
}
|
|
3912
|
-
function resolveSimpleEntry(raw, index, options, currentSourceRel) {
|
|
3913
|
-
const target = stripMarkdownExt(toPosix(raw));
|
|
3914
|
-
if (!target) return void 0;
|
|
3915
|
-
if (target.includes("/")) {
|
|
3916
|
-
const e = index.byRelativePath.get(target) ?? index.byRelativePath.get(target + ".md") ?? index.byRelativePath.get(target + ".markdown");
|
|
3917
|
-
if (e) return e;
|
|
3918
|
-
if (currentSourceRel) {
|
|
3919
|
-
const curDir = currentSourceRel.split("/").slice(0, -1).join("/");
|
|
3920
|
-
if (curDir) {
|
|
3921
|
-
return index.byRelativePath.get(`${curDir}/${target}`) ?? index.byRelativePath.get(`${curDir}/${target}.md`) ?? index.byRelativePath.get(`${curDir}/${target}.markdown`);
|
|
3922
|
-
}
|
|
3923
|
-
}
|
|
3924
|
-
return void 0;
|
|
3925
|
-
}
|
|
3926
|
-
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
3927
|
-
const aliased = index.byAlias.get(aliasKey);
|
|
3928
|
-
if (aliased) return aliased;
|
|
3929
|
-
const map = options.caseSensitive ? index.byBasename : index.byBasenameLower;
|
|
3930
|
-
const key = options.caseSensitive ? target : target.toLowerCase();
|
|
3931
|
-
return map.get(key)?.[0];
|
|
3932
|
-
}
|
|
3933
3980
|
function logDeadLinks(report, deadLink) {
|
|
3934
3981
|
if (deadLink === "silent") return;
|
|
3935
3982
|
if (report.dead.length > 0) {
|
|
@@ -3978,27 +4025,6 @@ function extractExt3(target) {
|
|
|
3978
4025
|
if (dot <= 0) return "";
|
|
3979
4026
|
return cleaned.slice(dot + 1).toLowerCase();
|
|
3980
4027
|
}
|
|
3981
|
-
function resolveSimple(raw, index, options, currentSourceRel) {
|
|
3982
|
-
const target = stripMarkdownExt(toPosix(raw));
|
|
3983
|
-
if (!target) return false;
|
|
3984
|
-
if (target.includes("/")) {
|
|
3985
|
-
if (index.byRelativePath.has(target) || index.byRelativePath.has(target + ".md") || index.byRelativePath.has(target + ".markdown")) {
|
|
3986
|
-
return true;
|
|
3987
|
-
}
|
|
3988
|
-
if (currentSourceRel) {
|
|
3989
|
-
const curDir = currentSourceRel.split("/").slice(0, -1).join("/");
|
|
3990
|
-
if (curDir) {
|
|
3991
|
-
return index.byRelativePath.has(`${curDir}/${target}`) || index.byRelativePath.has(`${curDir}/${target}.md`) || index.byRelativePath.has(`${curDir}/${target}.markdown`);
|
|
3992
|
-
}
|
|
3993
|
-
}
|
|
3994
|
-
return false;
|
|
3995
|
-
}
|
|
3996
|
-
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
3997
|
-
if (index.byAlias.has(aliasKey)) return true;
|
|
3998
|
-
const map = options.caseSensitive ? index.byBasename : index.byBasenameLower;
|
|
3999
|
-
const key = options.caseSensitive ? target : target.toLowerCase();
|
|
4000
|
-
return (map.get(key)?.length ?? 0) > 0;
|
|
4001
|
-
}
|
|
4002
4028
|
|
|
4003
4029
|
// src/vitepress.ts
|
|
4004
4030
|
var autoFolderIndexWarned = false;
|