vitepress-allyouneed 0.3.4 → 0.3.6
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 +44 -0
- package/dist/index.cjs +97 -26
- 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 +97 -26
- package/dist/index.js.map +1 -1
- package/dist/markdown-it.cjs +41 -8
- 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 +41 -8
- package/dist/markdown-it.js.map +1 -1
- package/dist/{types-BLbN9Pg6.d.cts → types-CjyxPvQV.d.cts} +12 -0
- package/dist/{types-BLbN9Pg6.d.ts → types-CjyxPvQV.d.ts} +12 -0
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vitepress.cjs +97 -26
- 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 +97 -26
- package/dist/vitepress.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,50 @@
|
|
|
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.3.5] - 2026-05-20
|
|
6
|
+
|
|
7
|
+
零配置导航更顺手:不写 `index.md` 也能从导航 / sidebar / 用户手写 wikilink 进到一个文件夹;默认 index 模板换成"文件管理器风格"(子文件夹在上、文件在下)。
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`sidebarAuto.folderLinkFallback: 'first-file' | 'none'`(默认 `'first-file'`)**
|
|
12
|
+
控制"文件夹链接缺 index 时怎么办"。三处效果一致:
|
|
13
|
+
- 自动生成的 sidebar group:无 dirIndex 时,group title 链到该文件夹第一个文件;
|
|
14
|
+
- 自动生成的 nav tab:无 dirIndex 时,tab 链到第一个文件(不再 silently skip);
|
|
15
|
+
- 用户手写的 `[[folder/]]` wikilink:同样兜底到第一个文件,label 用文件夹名(不用 first file 的 basename)。
|
|
16
|
+
设为 `'none'` 退回老行为(无 link / 死链)。最常见用法:`autoFolderIndex: 'off'` + `folderLinkFallback: 'first-file'`,完全不在 vault 写 `index.md` 也能从导航走通。
|
|
17
|
+
> **注意 sidebar vs nav 的差异**:
|
|
18
|
+
> - **Sidebar group**:**空 frontmatter-only dirIndex** 是用户显式 opt-out 信号(读 frontmatter 中的 `sidebarTitle` / `sidebarCollapsed`,但 group **无 link**,只展开/折叠)。这种文件**不会**触发 first-file 兜底 —— 兜底只在**完全没有** dirIndex 文件时生效。
|
|
19
|
+
> - **Nav tab**:nav tab 没"展开/折叠"状态,空 dirIndex 不兜底就成了点不动的死 tab。所以 nav 一视同仁:空或无 dirIndex **都**走 first-file 兜底(若 `folderLinkFallback === 'first-file'`);兜底也找不到才 skip。
|
|
20
|
+
> - **`[[folder/]]` wikilink**:用户写 `[[folder/]]` 时本就期望"跳转",和 nav 同语义 —— 空 dirIndex 兜底到第一个文件。
|
|
21
|
+
- **`resolveWikilink` 加同名 dirIndex 路径变体** —— `[[Themen/]]` 现在会查 `Themen/Themen.md` 当作索引(对应 `pickDirIndexes` 同名优先策略)。
|
|
22
|
+
- **`[[folder/]]` 写法支持完整化**:之前 `[[Themen/]]` 由于 `target + '/index.md'` 拼出 `Themen//index.md` 双斜杠 bug,实际是死链。现在 normalize 时剥尾 `/` 并强制走 path-style 分支,变体查找正确。
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **默认 `autoFolderIndex` 模板 = "Folders 在上、Files 在下"**(像文件管理器 / Tags 视图)。
|
|
27
|
+
- 段标题改成 `## Folders` + `## Files`(原 `## Sections` + `## Pages`)。
|
|
28
|
+
- 子文件夹位置:**上面**(老模板在下面)。
|
|
29
|
+
- 子文件夹标题是否可点接 `sidebarAuto.groupLink`(等同 sidebar 配置语义):
|
|
30
|
+
- `'all'`(默认):所有子文件夹标题都用 wikilink 可点
|
|
31
|
+
- `'top-level'`:仅根 `index.md` 内可点;深层 `index.md` 内为纯文字
|
|
32
|
+
- `'off'`:全部纯文字
|
|
33
|
+
- 子文件夹的"可点目的地"再走 `folderLinkFallback` 兜底,所以即使子文件夹无 index,点了也能进。
|
|
34
|
+
- **`FolderIndexOptions` / `TemplateContext` 扩展**:新增 `groupLink` 字段;`TemplateContext` 新增 `isRoot` / `groupLink`。
|
|
35
|
+
- **`resolveWikilink` 的 `defaultLabel`**:wasFolderForm 时(`[[folder/]]`),label 用文件夹名,而不是兜底文件的 basename。
|
|
36
|
+
|
|
37
|
+
### Migration
|
|
38
|
+
|
|
39
|
+
老用户若觉得新默认行为"不对路":
|
|
40
|
+
```ts
|
|
41
|
+
sidebarAuto: {
|
|
42
|
+
folderLinkFallback: 'none', // 回到 v0.3.4 行为
|
|
43
|
+
autoFolderIndex: {
|
|
44
|
+
template: oldTemplate, // 自己写模板覆盖
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
5
49
|
## [0.3.4] - 2026-05-20
|
|
6
50
|
|
|
7
51
|
真实 Obsidian 物理笔记 vault 测试暴露的 9 个 bug + 3 个隐性问题的集中修复。
|
package/dist/index.cjs
CHANGED
|
@@ -661,12 +661,20 @@ function resolveWikilink(rawTarget, index, options, kind = "page", currentSource
|
|
|
661
661
|
headingPart = target.slice(hashIdx + 1).trim();
|
|
662
662
|
target = target.slice(0, hashIdx).trim();
|
|
663
663
|
}
|
|
664
|
+
const wasFolderForm = /\/$/.test(target);
|
|
665
|
+
if (wasFolderForm) target = target.replace(/\/+$/, "");
|
|
664
666
|
target = stripMarkdownExt(target);
|
|
665
|
-
const entry = lookupEntry(
|
|
667
|
+
const entry = lookupEntry(
|
|
668
|
+
target,
|
|
669
|
+
index,
|
|
670
|
+
options,
|
|
671
|
+
currentSourcePath,
|
|
672
|
+
wasFolderForm
|
|
673
|
+
);
|
|
666
674
|
if (!entry) {
|
|
667
675
|
return {
|
|
668
676
|
url: buildDeadUrl(rawTarget, options),
|
|
669
|
-
defaultLabel: defaultLabel(target, headingPart, void 0, options),
|
|
677
|
+
defaultLabel: defaultLabel(target, headingPart, void 0, options, wasFolderForm),
|
|
670
678
|
isDead: true,
|
|
671
679
|
hasUnmatchedAnchor: false,
|
|
672
680
|
kind
|
|
@@ -687,22 +695,25 @@ function resolveWikilink(rawTarget, index, options, kind = "page", currentSource
|
|
|
687
695
|
}
|
|
688
696
|
return {
|
|
689
697
|
url,
|
|
690
|
-
defaultLabel: defaultLabel(target, headingPart, entry, options),
|
|
698
|
+
defaultLabel: defaultLabel(target, headingPart, entry, options, wasFolderForm),
|
|
691
699
|
isDead: false,
|
|
692
700
|
hasUnmatchedAnchor,
|
|
693
701
|
target: entry,
|
|
694
702
|
kind
|
|
695
703
|
};
|
|
696
704
|
}
|
|
697
|
-
function lookupEntry(target, index, options, currentSourcePath) {
|
|
705
|
+
function lookupEntry(target, index, options, currentSourcePath, forcePathStyle = false) {
|
|
698
706
|
if (!target) return void 0;
|
|
699
|
-
if (target.includes("/")) {
|
|
707
|
+
if (target.includes("/") || forcePathStyle) {
|
|
708
|
+
const lastSeg = target.split("/").pop() ?? "";
|
|
700
709
|
const variants = [
|
|
701
710
|
target,
|
|
702
711
|
target + ".md",
|
|
703
712
|
target + ".markdown",
|
|
704
713
|
target + "/index.md",
|
|
705
|
-
target + "/index.markdown"
|
|
714
|
+
target + "/index.markdown",
|
|
715
|
+
// 同名文件夹索引(和 pickDirIndexes 优先级 1 对齐)
|
|
716
|
+
...lastSeg ? [target + "/" + lastSeg + ".md", target + "/" + lastSeg + ".markdown"] : []
|
|
706
717
|
];
|
|
707
718
|
for (const v of variants) {
|
|
708
719
|
const e = index.byRelativePath.get(v);
|
|
@@ -728,6 +739,11 @@ function lookupEntry(target, index, options, currentSourcePath) {
|
|
|
728
739
|
}
|
|
729
740
|
}
|
|
730
741
|
}
|
|
742
|
+
const folderFallback = options.sidebarAuto?.folderLinkFallback ?? "first-file";
|
|
743
|
+
if (folderFallback === "first-file") {
|
|
744
|
+
const first = findFirstFileInFolder(target, index);
|
|
745
|
+
if (first) return first;
|
|
746
|
+
}
|
|
731
747
|
return void 0;
|
|
732
748
|
}
|
|
733
749
|
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
@@ -749,14 +765,31 @@ function lookupEntry(target, index, options, currentSourcePath) {
|
|
|
749
765
|
return void 0;
|
|
750
766
|
}
|
|
751
767
|
}
|
|
768
|
+
function findFirstFileInFolder(folderPath, index) {
|
|
769
|
+
const prefix = folderPath + "/";
|
|
770
|
+
const candidates = [];
|
|
771
|
+
for (const f of index.files.values()) {
|
|
772
|
+
if (f.relativePath.startsWith(prefix)) candidates.push(f);
|
|
773
|
+
}
|
|
774
|
+
if (candidates.length === 0) return void 0;
|
|
775
|
+
candidates.sort((a, b) => {
|
|
776
|
+
const da = a.relativePath.split("/").length;
|
|
777
|
+
const db = b.relativePath.split("/").length;
|
|
778
|
+
if (da !== db) return da - db;
|
|
779
|
+
return a.relativePath.localeCompare(b.relativePath);
|
|
780
|
+
});
|
|
781
|
+
return candidates[0];
|
|
782
|
+
}
|
|
752
783
|
function buildDeadUrl(rawTarget, options) {
|
|
753
784
|
const safe = encodeURIComponent(stripMarkdownExt(rawTarget).split("#")[0]);
|
|
754
785
|
return options.base + safe;
|
|
755
786
|
}
|
|
756
|
-
function defaultLabel(target, headingPart, entry, options) {
|
|
787
|
+
function defaultLabel(target, headingPart, entry, options, wasFolderForm = false) {
|
|
757
788
|
const lt = options.wikilinks.linkText;
|
|
758
789
|
let base;
|
|
759
|
-
if (
|
|
790
|
+
if (wasFolderForm) {
|
|
791
|
+
base = basename(target) || target;
|
|
792
|
+
} else if (typeof lt === "function") {
|
|
760
793
|
if (entry) {
|
|
761
794
|
base = lt(entry, target);
|
|
762
795
|
} else {
|
|
@@ -2761,7 +2794,8 @@ function resolveSidebarAutoOptions(user = {}) {
|
|
|
2761
2794
|
groupLink: user.groupLink ?? "all",
|
|
2762
2795
|
includePrefix: user.includePrefix,
|
|
2763
2796
|
excludePrefixes: user.excludePrefixes ?? [],
|
|
2764
|
-
foldersFirst: user.foldersFirst ?? false
|
|
2797
|
+
foldersFirst: user.foldersFirst ?? false,
|
|
2798
|
+
folderLinkFallback: user.folderLinkFallback ?? "first-file"
|
|
2765
2799
|
};
|
|
2766
2800
|
}
|
|
2767
2801
|
function defaultItemTitle(entry, strip) {
|
|
@@ -2923,8 +2957,13 @@ function renderNode(node, opts, depth, isRoot, index, options) {
|
|
|
2923
2957
|
collapsed: resolveGroupCollapsed(child.dirIndex, opts),
|
|
2924
2958
|
items: childItems
|
|
2925
2959
|
};
|
|
2926
|
-
if (
|
|
2927
|
-
|
|
2960
|
+
if (shouldLinkGroup(opts, isRoot)) {
|
|
2961
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
2962
|
+
group.link = child.dirIndex.url;
|
|
2963
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
2964
|
+
const first = findFirstPageUrl(child, opts);
|
|
2965
|
+
if (first) group.link = first;
|
|
2966
|
+
}
|
|
2928
2967
|
}
|
|
2929
2968
|
folderItems.push(group);
|
|
2930
2969
|
}
|
|
@@ -3008,8 +3047,13 @@ function toFlatSidebar(root, opts) {
|
|
|
3008
3047
|
collapsed: resolveGroupCollapsed(d.dirIndex, opts),
|
|
3009
3048
|
items
|
|
3010
3049
|
};
|
|
3011
|
-
if (
|
|
3012
|
-
|
|
3050
|
+
if (shouldLinkGroup(opts, true)) {
|
|
3051
|
+
if (d.dirIndex && !d.dirIndexEmpty) {
|
|
3052
|
+
group.link = d.dirIndex.url;
|
|
3053
|
+
} else if (!d.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3054
|
+
const first = findFirstPageUrl(d, opts);
|
|
3055
|
+
if (first) group.link = first;
|
|
3056
|
+
}
|
|
3013
3057
|
}
|
|
3014
3058
|
out.push(group);
|
|
3015
3059
|
}
|
|
@@ -3042,7 +3086,12 @@ function toPerFolderSidebar(root, opts, options, index) {
|
|
|
3042
3086
|
/* isTopLevel */
|
|
3043
3087
|
true
|
|
3044
3088
|
)) {
|
|
3045
|
-
|
|
3089
|
+
let firstUrl = null;
|
|
3090
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3091
|
+
firstUrl = child.dirIndex.url;
|
|
3092
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3093
|
+
firstUrl = findFirstPageUrl(child, opts);
|
|
3094
|
+
}
|
|
3046
3095
|
if (firstUrl) {
|
|
3047
3096
|
rootItems.push({ text: labelText, link: firstUrl });
|
|
3048
3097
|
} else {
|
|
@@ -3067,16 +3116,23 @@ function toPerFolderSidebar(root, opts, options, index) {
|
|
|
3067
3116
|
);
|
|
3068
3117
|
if (items.length === 0 && !child.dirIndex) continue;
|
|
3069
3118
|
const sidebar = [];
|
|
3070
|
-
|
|
3119
|
+
if (shouldLinkGroup(
|
|
3071
3120
|
opts,
|
|
3072
3121
|
/* isTopLevel */
|
|
3073
3122
|
true
|
|
3074
|
-
)
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3123
|
+
)) {
|
|
3124
|
+
let selfUrl = null;
|
|
3125
|
+
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3126
|
+
selfUrl = child.dirIndex.url;
|
|
3127
|
+
} else if (!child.dirIndex && opts.folderLinkFallback === "first-file") {
|
|
3128
|
+
selfUrl = findFirstPageUrl(child, opts);
|
|
3129
|
+
}
|
|
3130
|
+
if (selfUrl) {
|
|
3131
|
+
sidebar.push({
|
|
3132
|
+
text: computeGroupText(child.path, child.dirIndex, opts),
|
|
3133
|
+
link: selfUrl
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3080
3136
|
}
|
|
3081
3137
|
sidebar.push(...items);
|
|
3082
3138
|
out[`/${key}/`] = sidebar;
|
|
@@ -3104,10 +3160,12 @@ function generateNav(index, options, autoOptions = {}) {
|
|
|
3104
3160
|
let link;
|
|
3105
3161
|
if (child.dirIndex && !child.dirIndexEmpty) {
|
|
3106
3162
|
link = stripBase(child.dirIndex.url, base);
|
|
3107
|
-
} else {
|
|
3163
|
+
} else if (opts.folderLinkFallback === "first-file") {
|
|
3108
3164
|
const first = findFirstPageUrl(child, opts);
|
|
3109
3165
|
if (!first) continue;
|
|
3110
3166
|
link = first;
|
|
3167
|
+
} else {
|
|
3168
|
+
continue;
|
|
3111
3169
|
}
|
|
3112
3170
|
const escapedPrefix = `/${key}/`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3113
3171
|
out.push({ text, link, activeMatch: "^" + escapedPrefix });
|
|
@@ -3277,7 +3335,9 @@ function generateFolderIndexes(options, folderOpts = {}) {
|
|
|
3277
3335
|
dirRelPath: dirRel,
|
|
3278
3336
|
title: humanize2(lastSeg, strip) || "Home",
|
|
3279
3337
|
files,
|
|
3280
|
-
subDirs
|
|
3338
|
+
subDirs,
|
|
3339
|
+
isRoot: dirRel === "",
|
|
3340
|
+
groupLink: folderOpts.groupLink ?? "all"
|
|
3281
3341
|
};
|
|
3282
3342
|
try {
|
|
3283
3343
|
import_node_fs8.default.writeFileSync(target, template(ctx), "utf8");
|
|
@@ -3358,6 +3418,7 @@ function humanize2(name, stripNumeric) {
|
|
|
3358
3418
|
}
|
|
3359
3419
|
function defaultTemplate(ctx) {
|
|
3360
3420
|
const prefix = ctx.dirRelPath === "" ? "" : `${ctx.dirRelPath}/`;
|
|
3421
|
+
const subDirLinkable = subFolderClickable(ctx.groupLink, ctx.isRoot);
|
|
3361
3422
|
const lines = [];
|
|
3362
3423
|
lines.push("---");
|
|
3363
3424
|
lines.push(`title: ${ctx.title}`);
|
|
@@ -3368,15 +3429,19 @@ function defaultTemplate(ctx) {
|
|
|
3368
3429
|
lines.push(`# ${ctx.title}`);
|
|
3369
3430
|
lines.push("");
|
|
3370
3431
|
if (ctx.subDirs.length > 0) {
|
|
3371
|
-
lines.push("##
|
|
3432
|
+
lines.push("## Folders");
|
|
3372
3433
|
lines.push("");
|
|
3373
3434
|
for (const d of ctx.subDirs) {
|
|
3374
|
-
|
|
3435
|
+
if (subDirLinkable) {
|
|
3436
|
+
lines.push(`- [[${prefix}${d.name}/|${d.title}]]`);
|
|
3437
|
+
} else {
|
|
3438
|
+
lines.push(`- ${d.title}`);
|
|
3439
|
+
}
|
|
3375
3440
|
}
|
|
3376
3441
|
lines.push("");
|
|
3377
3442
|
}
|
|
3378
3443
|
if (ctx.files.length > 0) {
|
|
3379
|
-
lines.push("##
|
|
3444
|
+
lines.push("## Files");
|
|
3380
3445
|
lines.push("");
|
|
3381
3446
|
for (const f of ctx.files) {
|
|
3382
3447
|
lines.push(`- [[${prefix}${f.relPath}|${f.title}]]`);
|
|
@@ -3385,6 +3450,11 @@ function defaultTemplate(ctx) {
|
|
|
3385
3450
|
}
|
|
3386
3451
|
return lines.join("\n");
|
|
3387
3452
|
}
|
|
3453
|
+
function subFolderClickable(groupLink, isRoot) {
|
|
3454
|
+
if (groupLink === "off") return false;
|
|
3455
|
+
if (groupLink === "top-level") return isRoot;
|
|
3456
|
+
return true;
|
|
3457
|
+
}
|
|
3388
3458
|
|
|
3389
3459
|
// src/core/scan-wikilinks.ts
|
|
3390
3460
|
var WIKILINK_RE3 = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
@@ -3534,6 +3604,7 @@ function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
|
3534
3604
|
sidebarAuto.autoFolderIndex,
|
|
3535
3605
|
sidebarAuto.stripNumericPrefix
|
|
3536
3606
|
);
|
|
3607
|
+
folderOpts.groupLink = sidebarAuto.groupLink ?? "all";
|
|
3537
3608
|
if (folderOpts.mode !== "off") {
|
|
3538
3609
|
try {
|
|
3539
3610
|
generateFolderIndexes(resolvedForWrapper, folderOpts);
|