vitepress-allyouneed 0.3.3 → 0.3.4
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 +23 -0
- package/dist/index.cjs +169 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +169 -54
- package/dist/index.js.map +1 -1
- package/dist/markdown-it.cjs +79 -20
- package/dist/markdown-it.cjs.map +1 -1
- package/dist/markdown-it.js +79 -20
- package/dist/markdown-it.js.map +1 -1
- package/dist/vite.cjs +39 -6
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +39 -6
- package/dist/vite.js.map +1 -1
- package/dist/vitepress.cjs +171 -54
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.js +171 -54
- package/dist/vitepress.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
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.4] - 2026-05-20
|
|
6
|
+
|
|
7
|
+
真实 Obsidian 物理笔记 vault 测试暴露的 9 个 bug + 3 个隐性问题的集中修复。
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **图片找不到**:`resolveAsset` 之前只查 vault 绝对相对路径(`assetsByRelativePath`),Obsidian "相对当前文件" 路径模式下写 `![[media/image4.png]]` 在 `Themen/X.md` 里时找不到 → 退化为 basename + base → `/image4.png` → Vite 当 public 根 → 404。现接 `currentSourcePath`,**先**查 vault 绝对路径、**再**查相对源文件 dir、**最后**走 basename fallback;`image.ts` / `media.ts` / `transclusion.ts` 三个调用方都已传 `env.currentPath`。
|
|
11
|
+
- **`![[ ]]` transclusion 同样问题**:`renderTransclusionHtml` 和降级版 `handleTransclusion` 调 `resolveWikilink` 时漏传 `currentSourcePath`,现已补。
|
|
12
|
+
- **`autoFolderIndex` 根目录生成 `[[/foo/]]` 死链**:`defaultTemplate` 拼路径时 `dirRelPath===''` 没特判,产出带前导 `/` 的 wikilink,resolver 不识别"绝对 wikilink"全死。改成根用空 prefix(`[[foo/]]`)。
|
|
13
|
+
- **Obsidian 表格内 `\|` 转义被当成路径字符**:`[[Foo\|Bar]]` 是 Obsidian 在表格 cell 里转义 pipe 的标准写法。原 5 处 `inner.split('|')` 把 target 解析成 `Foo\`(带尾巴反斜杠)→ 找不到。统一抽 `utils/wikilink.ts:splitWikilinkInner`,5 处(`wikilinks/rule.ts`、`embeds/block-rule.ts`、`sidebar-auto/parse-sidebar-md.ts`、`views/generate-data.ts`、`core/scan-wikilinks.ts`)替换。
|
|
14
|
+
- **`stripNumericPrefix` 把版本号吃掉**:`/^\d+[-_.\s]+/` 把 `1.2.3-formula.md` 误剥成 `2.3-formula`。`.` 不再算分隔符,只剩 `-` / `_` / 空白。
|
|
15
|
+
- **行内 `#tag` 在 `cleanUrls: false` 下 404**:`<a class="ayn-tag" href>` 直接拼 `/_perspectives_/tags#xxx`,没考虑 `cleanUrls`。现走 `applyCleanUrls`,需要 `.html` 时自动加。
|
|
16
|
+
- **`%% block comment %%` 包了 ``` fence 时提前结束**:扫描闭合 `%%` 没跟踪 fence 状态,fence 内的 `%%` 字面行会把注释关掉,导致 fence 残留。改成同时跟踪 ``` / ~~~ 配对状态,只在 fence 外才允许关闭。
|
|
17
|
+
- **`views.urlPrefix` 自定义后 sidebar fallback 失效**:`buildPerspectivesFallbackSidebar` 硬编码 `_perspectives_/`,用户改 `views.urlPrefix: 'extras'` 后过滤失效,会在视图页 sidebar 看到一个指向自己的"前往 Extras"项。现接 `viewsPrefix` 参数。
|
|
18
|
+
- **i18n locale Perspectives 注入不对称**:(a) per-locale sidebar 生成后没过 `injectViewsSidebar`,EN locale 等丢 Perspectives 组;(b) nav 注入老逻辑要求 `lc.themeConfig.nav !== undefined`,没自定义 nav 的 locale 拿不到下拉。两边都修。
|
|
19
|
+
- **graph 视图丢相对路径 wikilink 边**:`resolveTargetSimple` 不接 `currentSourceRel`,与 `resolver.ts:117` 行为不一致,从而 sibling 笔记的相对链接在 Graph 上看不见。补齐相对路径 fallback。
|
|
20
|
+
- **`_sidebar.md` fence 检测同 `%%` 同症**:`/^```|^~~~/` 任一 marker 都切状态,`~~~` 在 ``` 块里会提前结束。改成 marker 配对跟踪。
|
|
21
|
+
- **`callout` 标题不解析 inline markdown**:`[!info] **Newton**` 之前显示字面 `**Newton**`。Obsidian 实际会渲染。现走 `md.renderInline`(用户传了自定义标题时)。
|
|
22
|
+
- **`webm` 同时在 audio/video 列表**:`classifyMediaExt` video-first,所有 `.webm` 一律渲染为 `<video>`。从 `AUDIO_EXTS` 删掉。
|
|
23
|
+
- **静默 `catch{}` 加日志**:`writeVaultData` 失败、`scanWikilinks` 失败之前都吞错,debug "Graph 不更新"非常难找。改成 `console.warn`。
|
|
24
|
+
|
|
25
|
+
### Tests
|
|
26
|
+
- 新增 `tests/v034-bugfixes.test.ts`,每个 RED bug 一条回归用例。
|
|
27
|
+
|
|
5
28
|
## [0.3.3] - 2026-05-20
|
|
6
29
|
|
|
7
30
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -772,13 +772,47 @@ function defaultLabel(target, headingPart, entry, options) {
|
|
|
772
772
|
}
|
|
773
773
|
return base;
|
|
774
774
|
}
|
|
775
|
-
function resolveAsset(rawTarget, index, options) {
|
|
775
|
+
function resolveAsset(rawTarget, index, options, currentSourcePath) {
|
|
776
776
|
const target = toPosix(rawTarget).trim();
|
|
777
777
|
if (target.includes("/")) {
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
rawBasename: basename(target)
|
|
781
|
-
}
|
|
778
|
+
const direct = index.assetsByRelativePath.get(target);
|
|
779
|
+
if (direct) {
|
|
780
|
+
return { asset: direct, rawBasename: basename(target) };
|
|
781
|
+
}
|
|
782
|
+
if (currentSourcePath) {
|
|
783
|
+
const srcDirAbs = index.srcDir;
|
|
784
|
+
const cur = toPosix(currentSourcePath);
|
|
785
|
+
const rel = cur.startsWith(srcDirAbs + "/") ? cur.slice(srcDirAbs.length + 1) : "";
|
|
786
|
+
if (rel) {
|
|
787
|
+
const curDir = rel.split("/").slice(0, -1).join("/");
|
|
788
|
+
if (curDir) {
|
|
789
|
+
const relAsset = index.assetsByRelativePath.get(`${curDir}/${target}`);
|
|
790
|
+
if (relAsset) {
|
|
791
|
+
return { asset: relAsset, rawBasename: basename(target) };
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
const bn0 = options.caseSensitive ? basename(target) : basename(target).toLowerCase();
|
|
797
|
+
const map0 = options.caseSensitive ? index.assetsByBasename : index.assetsByBasenameLower;
|
|
798
|
+
const fallback = map0.get(bn0);
|
|
799
|
+
if (fallback && fallback.length === 1) {
|
|
800
|
+
return { asset: fallback[0], rawBasename: basename(target) };
|
|
801
|
+
}
|
|
802
|
+
if (fallback && fallback.length > 1) {
|
|
803
|
+
switch (options.onConflict) {
|
|
804
|
+
case "shortest":
|
|
805
|
+
return {
|
|
806
|
+
asset: sortByShortestPath(fallback)[0],
|
|
807
|
+
rawBasename: basename(target)
|
|
808
|
+
};
|
|
809
|
+
case "first":
|
|
810
|
+
return { asset: fallback[0], rawBasename: basename(target) };
|
|
811
|
+
case "error":
|
|
812
|
+
return { asset: void 0, rawBasename: basename(target) };
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
return { asset: void 0, rawBasename: basename(target) };
|
|
782
816
|
}
|
|
783
817
|
const bn = options.caseSensitive ? target : target.toLowerCase();
|
|
784
818
|
const map = options.caseSensitive ? index.assetsByBasename : index.assetsByBasenameLower;
|
|
@@ -903,7 +937,7 @@ function renderImageHtml(rawTarget, aliasParts, env) {
|
|
|
903
937
|
const { index, options } = env;
|
|
904
938
|
const { altText, dim } = parseAltAndDim(aliasParts);
|
|
905
939
|
const processedTarget = options.embeds.postProcessImageTarget(rawTarget);
|
|
906
|
-
const { asset } = resolveAsset(processedTarget, index, options);
|
|
940
|
+
const { asset } = resolveAsset(processedTarget, index, options, env.currentPath);
|
|
907
941
|
let src;
|
|
908
942
|
if (asset) {
|
|
909
943
|
asset.referencedBy.add(env.currentPath ?? "<unknown>");
|
|
@@ -997,7 +1031,13 @@ function escapeAttrName(k) {
|
|
|
997
1031
|
// src/modules/embeds/transclusion.ts
|
|
998
1032
|
function renderTransclusionHtml(md, rawTarget, aliasParts, env) {
|
|
999
1033
|
const { index, options } = env;
|
|
1000
|
-
const result = resolveWikilink(
|
|
1034
|
+
const result = resolveWikilink(
|
|
1035
|
+
rawTarget,
|
|
1036
|
+
index,
|
|
1037
|
+
options,
|
|
1038
|
+
"transclusion",
|
|
1039
|
+
env.currentPath
|
|
1040
|
+
);
|
|
1001
1041
|
if (result.isDead || !result.target) {
|
|
1002
1042
|
return `<div class="transclusion transclusion--dead" data-target="${escapeHtml(
|
|
1003
1043
|
rawTarget
|
|
@@ -1070,7 +1110,7 @@ function handleTransclusion(state, rawTarget, aliasParts, env) {
|
|
|
1070
1110
|
);
|
|
1071
1111
|
}
|
|
1072
1112
|
const { index, options } = env;
|
|
1073
|
-
const result = resolveWikilink(rawTarget, index, options, "page");
|
|
1113
|
+
const result = resolveWikilink(rawTarget, index, options, "page", env.currentPath);
|
|
1074
1114
|
const url = result.url;
|
|
1075
1115
|
const label = aliasParts.length ? aliasParts.join("|").trim() : result.defaultLabel;
|
|
1076
1116
|
const html = `<a class="wikilink wikilink--inline-transclusion-degraded" href="${escapeHtml(url)}" data-wikilink-target="${escapeHtml(rawTarget)}" title="\u884C\u5185 transclusion \u5DF2\u964D\u7EA7,\u89C1\u63A7\u5236\u53F0">${escapeHtml(label)}</a>`;
|
|
@@ -1108,7 +1148,7 @@ function getCache(env) {
|
|
|
1108
1148
|
}
|
|
1109
1149
|
|
|
1110
1150
|
// src/modules/embeds/media.ts
|
|
1111
|
-
var AUDIO_EXTS = ["mp3", "wav", "ogg", "m4a", "flac", "aac"
|
|
1151
|
+
var AUDIO_EXTS = ["mp3", "wav", "ogg", "m4a", "flac", "aac"];
|
|
1112
1152
|
var VIDEO_EXTS = ["mp4", "webm", "mov", "m4v", "avi", "mkv"];
|
|
1113
1153
|
var PDF_EXTS = ["pdf"];
|
|
1114
1154
|
function isAudioExt(ext) {
|
|
@@ -1146,7 +1186,7 @@ function parseAliasDim(parts) {
|
|
|
1146
1186
|
function resolveSrc(rawTarget, env) {
|
|
1147
1187
|
const { index, options } = env;
|
|
1148
1188
|
const processedTarget = options.embeds.postProcessImageTarget(rawTarget);
|
|
1149
|
-
const { asset } = resolveAsset(processedTarget, index, options);
|
|
1189
|
+
const { asset } = resolveAsset(processedTarget, index, options, env.currentPath);
|
|
1150
1190
|
if (asset) {
|
|
1151
1191
|
asset.referencedBy.add(env.currentPath ?? "<unknown>");
|
|
1152
1192
|
env.referencedAssets?.add(asset);
|
|
@@ -1188,6 +1228,11 @@ function handleMediaEmbed(state, kind, rawTarget, aliasParts, env) {
|
|
|
1188
1228
|
return true;
|
|
1189
1229
|
}
|
|
1190
1230
|
|
|
1231
|
+
// src/utils/wikilink.ts
|
|
1232
|
+
function splitWikilinkInner(inner) {
|
|
1233
|
+
return inner.split(/\\?\|/).map((p) => p.trim());
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1191
1236
|
// src/modules/wikilinks/rule.ts
|
|
1192
1237
|
function makeWikilinkRule(scope) {
|
|
1193
1238
|
return function wikilinkRule(state, silent) {
|
|
@@ -1216,7 +1261,7 @@ function makeWikilinkRule(scope) {
|
|
|
1216
1261
|
return false;
|
|
1217
1262
|
}
|
|
1218
1263
|
state.pos = closeIdx + 2;
|
|
1219
|
-
const parts = inner
|
|
1264
|
+
const parts = splitWikilinkInner(inner);
|
|
1220
1265
|
const rawTarget = parts[0];
|
|
1221
1266
|
const aliasParts = parts.slice(1);
|
|
1222
1267
|
if (isEmbed) {
|
|
@@ -1310,7 +1355,7 @@ function makeRule(md) {
|
|
|
1310
1355
|
const env = state.env;
|
|
1311
1356
|
if (!env || !env.index || !env.options) return false;
|
|
1312
1357
|
const inner = m[1];
|
|
1313
|
-
const parts = inner
|
|
1358
|
+
const parts = splitWikilinkInner(inner);
|
|
1314
1359
|
const rawTarget = parts[0];
|
|
1315
1360
|
const aliasParts = parts.slice(1);
|
|
1316
1361
|
const ext = extractExt2(rawTarget);
|
|
@@ -1445,7 +1490,7 @@ function registerCalloutsCore(md) {
|
|
|
1445
1490
|
const header = extractHeader(inner);
|
|
1446
1491
|
if (!header) continue;
|
|
1447
1492
|
const bodyHtml = renderBody(inner, header.firstLineRest, md, state.env);
|
|
1448
|
-
const html = renderCallout(header.parsed, bodyHtml);
|
|
1493
|
+
const html = renderCallout(header.parsed, bodyHtml, md, state.env);
|
|
1449
1494
|
const newToken = new state.Token("html_block", "", 0);
|
|
1450
1495
|
newToken.content = html + "\n";
|
|
1451
1496
|
newToken.map = t.map;
|
|
@@ -1502,16 +1547,17 @@ function renderBody(inner, firstLineRest, md, env) {
|
|
|
1502
1547
|
}
|
|
1503
1548
|
return md.renderer.render(cloned, md.options, env);
|
|
1504
1549
|
}
|
|
1505
|
-
function renderCallout(header, bodyHtml) {
|
|
1550
|
+
function renderCallout(header, bodyHtml, md, env) {
|
|
1506
1551
|
const { type, foldable, title } = header;
|
|
1507
|
-
const
|
|
1552
|
+
const rawTitle = title || DEFAULT_TITLES[type];
|
|
1553
|
+
const titleHtml = title ? md.renderInline(rawTitle, env) : escapeHtml(rawTitle);
|
|
1508
1554
|
const iconSvg = `<svg class="callout-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">` + CALLOUT_ICONS[type] + `</svg>`;
|
|
1509
1555
|
const cls = `callout callout--${type}` + (foldable ? " callout--foldable" : "");
|
|
1510
1556
|
if (foldable) {
|
|
1511
1557
|
const isOpen = foldable === "open";
|
|
1512
|
-
return `<details class="${cls}" data-callout="${type}"${isOpen ? " open" : ""}><summary class="callout-title">${iconSvg}<span class="callout-title-text">${
|
|
1558
|
+
return `<details class="${cls}" data-callout="${type}"${isOpen ? " open" : ""}><summary class="callout-title">${iconSvg}<span class="callout-title-text">${titleHtml}</span></summary><div class="callout-content">${bodyHtml}</div></details>`;
|
|
1513
1559
|
}
|
|
1514
|
-
return `<div class="${cls}" data-callout="${type}"><div class="callout-title">${iconSvg}<span class="callout-title-text">${
|
|
1560
|
+
return `<div class="${cls}" data-callout="${type}"><div class="callout-title">${iconSvg}<span class="callout-title-text">${titleHtml}</span></div><div class="callout-content">${bodyHtml}</div></div>`;
|
|
1515
1561
|
}
|
|
1516
1562
|
|
|
1517
1563
|
// src/modules/callouts/index.ts
|
|
@@ -1666,12 +1712,25 @@ function makeCommentBlockRule() {
|
|
|
1666
1712
|
if (silent) return true;
|
|
1667
1713
|
let next = startLine + 1;
|
|
1668
1714
|
let closed = false;
|
|
1715
|
+
let fenceMarker = null;
|
|
1669
1716
|
while (next < endLine) {
|
|
1670
1717
|
const lpos = state.bMarks[next] + state.tShift[next];
|
|
1671
1718
|
const lmax = state.eMarks[next];
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1719
|
+
const lineText = state.src.slice(lpos, lmax);
|
|
1720
|
+
const trimmed = lineText.trim();
|
|
1721
|
+
const fm = /^(`{3,}|~{3,})/.exec(trimmed);
|
|
1722
|
+
if (fm) {
|
|
1723
|
+
const ch = fm[1][0];
|
|
1724
|
+
if (fenceMarker === null) fenceMarker = ch;
|
|
1725
|
+
else if (fenceMarker === ch) fenceMarker = null;
|
|
1726
|
+
next += 1;
|
|
1727
|
+
continue;
|
|
1728
|
+
}
|
|
1729
|
+
if (fenceMarker === null) {
|
|
1730
|
+
if (lpos + 2 <= lmax && state.src.charCodeAt(lpos) === PCT && state.src.charCodeAt(lpos + 1) === PCT && state.src.slice(lpos + 2, lmax).trim() === "") {
|
|
1731
|
+
closed = true;
|
|
1732
|
+
break;
|
|
1733
|
+
}
|
|
1675
1734
|
}
|
|
1676
1735
|
next += 1;
|
|
1677
1736
|
}
|
|
@@ -2085,7 +2144,7 @@ function renderTemplate(v) {
|
|
|
2085
2144
|
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
2086
2145
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
2087
2146
|
var PLUGIN_VERSION = "0.2.0-beta.0";
|
|
2088
|
-
var WIKILINK_RE = /(!?)\[\[([^\]\n
|
|
2147
|
+
var WIKILINK_RE = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
2089
2148
|
var BODY_TAG_RE = /(?:^|[\s([{,;。,;])#([\p{L}_][\p{L}\p{N}_/-]*)/gu;
|
|
2090
2149
|
function buildVaultData(index, options) {
|
|
2091
2150
|
const viewsPrefix = options.views.urlPrefix ? options.views.urlPrefix.replace(/^\/+|\/+$/g, "") + "/" : "";
|
|
@@ -2112,8 +2171,13 @@ function buildVaultData(index, options) {
|
|
|
2112
2171
|
const matches = f.content.matchAll(WIKILINK_RE);
|
|
2113
2172
|
for (const m of matches) {
|
|
2114
2173
|
const isEmbed = m[1] === "!";
|
|
2115
|
-
const
|
|
2116
|
-
|
|
2174
|
+
const inner = m[2];
|
|
2175
|
+
let rawTarget = splitWikilinkInner(inner)[0] ?? "";
|
|
2176
|
+
const hashIdx = rawTarget.indexOf("#");
|
|
2177
|
+
if (hashIdx >= 0) rawTarget = rawTarget.slice(0, hashIdx);
|
|
2178
|
+
rawTarget = rawTarget.trim();
|
|
2179
|
+
if (!rawTarget) continue;
|
|
2180
|
+
const target = resolveTargetSimple(rawTarget, index, options, f.relativePath);
|
|
2117
2181
|
if (!target) continue;
|
|
2118
2182
|
if (isPerspective(target)) continue;
|
|
2119
2183
|
if (target.relativePath === f.relativePath) continue;
|
|
@@ -2204,11 +2268,28 @@ function pickTitle(f) {
|
|
|
2204
2268
|
}
|
|
2205
2269
|
return f.basename;
|
|
2206
2270
|
}
|
|
2207
|
-
function resolveTargetSimple(rawTarget, index, options) {
|
|
2271
|
+
function resolveTargetSimple(rawTarget, index, options, currentSourceRel) {
|
|
2208
2272
|
const target = stripMarkdownExt(toPosix(rawTarget));
|
|
2209
2273
|
if (!target) return void 0;
|
|
2210
2274
|
if (target.includes("/")) {
|
|
2211
|
-
|
|
2275
|
+
const direct = index.byRelativePath.get(target) ?? index.byRelativePath.get(target + ".md") ?? index.byRelativePath.get(target + ".markdown") ?? index.byRelativePath.get(target + "/index.md") ?? index.byRelativePath.get(target + "/index.markdown");
|
|
2276
|
+
if (direct) return direct;
|
|
2277
|
+
if (currentSourceRel) {
|
|
2278
|
+
const curDir = currentSourceRel.split("/").slice(0, -1).join("/");
|
|
2279
|
+
if (curDir) {
|
|
2280
|
+
for (const v of [
|
|
2281
|
+
`${curDir}/${target}`,
|
|
2282
|
+
`${curDir}/${target}.md`,
|
|
2283
|
+
`${curDir}/${target}.markdown`,
|
|
2284
|
+
`${curDir}/${target}/index.md`,
|
|
2285
|
+
`${curDir}/${target}/index.markdown`
|
|
2286
|
+
]) {
|
|
2287
|
+
const e = index.byRelativePath.get(v);
|
|
2288
|
+
if (e) return e;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
return void 0;
|
|
2212
2293
|
}
|
|
2213
2294
|
const aliasKey = options.caseSensitive ? target : target.toLowerCase();
|
|
2214
2295
|
const aliased = index.byAlias.get(aliasKey);
|
|
@@ -2323,7 +2404,11 @@ function viteAllYouNeed(userOptions = {}) {
|
|
|
2323
2404
|
if (resolved.modules.views) {
|
|
2324
2405
|
try {
|
|
2325
2406
|
writeVaultData(index, resolved);
|
|
2326
|
-
} catch {
|
|
2407
|
+
} catch (e) {
|
|
2408
|
+
console.warn(
|
|
2409
|
+
"vitepress-allyouneed: \u91CD\u65B0\u5199 vault-data.json \u5931\u8D25,Graph/Stats/Tags \u53EF\u80FD\u4E0D\u66F4\u65B0\u3002",
|
|
2410
|
+
e instanceof Error ? e.message : String(e)
|
|
2411
|
+
);
|
|
2327
2412
|
}
|
|
2328
2413
|
}
|
|
2329
2414
|
},
|
|
@@ -2392,8 +2477,10 @@ function makeTagRule() {
|
|
|
2392
2477
|
const tagsViewName = env.options?.views?.names?.tags ?? "tags";
|
|
2393
2478
|
const urlPrefix = env.options?.views?.urlPrefix ?? "_perspectives_";
|
|
2394
2479
|
const base = env.options?.base ?? "/";
|
|
2480
|
+
const cleanUrls = env.options?.cleanUrls ?? true;
|
|
2395
2481
|
const prefixSeg = urlPrefix ? `${urlPrefix}/` : "";
|
|
2396
|
-
const
|
|
2482
|
+
const pagePath = applyCleanUrls(`${prefixSeg}${tagsViewName}`, cleanUrls);
|
|
2483
|
+
const href = `${base}${pagePath}#${encodeURIComponent(tag)}`;
|
|
2397
2484
|
const html = `<a class="ayn-tag" data-tag="${escapeHtml(tag)}" href="${escapeHtml(href)}">#${escapeHtml(tag)}</a>`;
|
|
2398
2485
|
const token = state.push("html_inline", "", 0);
|
|
2399
2486
|
token.content = html;
|
|
@@ -2434,7 +2521,8 @@ function injectViewsSidebar(sidebar, options) {
|
|
|
2434
2521
|
sidebar[persPath] = buildPerspectivesFallbackSidebar(
|
|
2435
2522
|
sidebar,
|
|
2436
2523
|
group,
|
|
2437
|
-
options.base.endsWith("/") ? options.base : options.base + "/"
|
|
2524
|
+
options.base.endsWith("/") ? options.base : options.base + "/",
|
|
2525
|
+
prefix
|
|
2438
2526
|
);
|
|
2439
2527
|
}
|
|
2440
2528
|
}
|
|
@@ -2442,10 +2530,11 @@ function injectViewsSidebar(sidebar, options) {
|
|
|
2442
2530
|
}
|
|
2443
2531
|
return [group];
|
|
2444
2532
|
}
|
|
2445
|
-
function buildPerspectivesFallbackSidebar(allSidebars, group, base) {
|
|
2533
|
+
function buildPerspectivesFallbackSidebar(allSidebars, group, base, viewsPrefix) {
|
|
2446
2534
|
const out = [{ text: "Home", link: "/" }];
|
|
2535
|
+
const persSuffix = `/${viewsPrefix}/`;
|
|
2447
2536
|
const topPaths = Object.keys(allSidebars).filter(
|
|
2448
|
-
(p) => p !== base && !p.endsWith(
|
|
2537
|
+
(p) => p !== base && !p.endsWith(persSuffix)
|
|
2449
2538
|
);
|
|
2450
2539
|
for (const p of topPaths) {
|
|
2451
2540
|
const seg = p.replace(/^\/|\/$/g, "").split("/").filter(Boolean).pop() ?? p;
|
|
@@ -2522,18 +2611,22 @@ function normalizeItems(items) {
|
|
|
2522
2611
|
});
|
|
2523
2612
|
}
|
|
2524
2613
|
var LINE_RE2 = /^(\s*)-\s+(.*)$/;
|
|
2525
|
-
var WIKILINK_RE2 = /^\[\[([^\]\n
|
|
2614
|
+
var WIKILINK_RE2 = /^\[\[([^\]\n]+)\]\]/;
|
|
2526
2615
|
var MD_LINK_RE = /^\[([^\]]+)\]\(([^)]+)\)/;
|
|
2527
2616
|
function parseList(src, entry, index, options) {
|
|
2528
2617
|
const lines = src.split(/\r?\n/);
|
|
2529
2618
|
const parsed = [];
|
|
2530
|
-
let
|
|
2619
|
+
let fenceMarker = null;
|
|
2531
2620
|
for (const raw of lines) {
|
|
2532
|
-
|
|
2533
|
-
|
|
2621
|
+
const trimmed = raw.trim();
|
|
2622
|
+
const fenceMatch = /^(`{3,}|~{3,})/.exec(trimmed);
|
|
2623
|
+
if (fenceMatch) {
|
|
2624
|
+
const ch = fenceMatch[1][0];
|
|
2625
|
+
if (fenceMarker === null) fenceMarker = ch;
|
|
2626
|
+
else if (fenceMarker === ch) fenceMarker = null;
|
|
2534
2627
|
continue;
|
|
2535
2628
|
}
|
|
2536
|
-
if (
|
|
2629
|
+
if (fenceMarker !== null) continue;
|
|
2537
2630
|
const m = LINE_RE2.exec(raw);
|
|
2538
2631
|
if (!m) continue;
|
|
2539
2632
|
const indent = m[1].replace(/\t/g, " ").length;
|
|
@@ -2545,12 +2638,16 @@ function parseList(src, entry, index, options) {
|
|
|
2545
2638
|
function parseLineBody(indent, body, entry, index, options) {
|
|
2546
2639
|
const wl = WIKILINK_RE2.exec(body);
|
|
2547
2640
|
if (wl) {
|
|
2548
|
-
const
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2641
|
+
const inner = wl[1];
|
|
2642
|
+
const parts = splitWikilinkInner(inner);
|
|
2643
|
+
let rawTarget = parts[0];
|
|
2644
|
+
const customText = parts[1] ?? void 0;
|
|
2645
|
+
const hashIdx = rawTarget.indexOf("#");
|
|
2646
|
+
if (hashIdx >= 0) rawTarget = rawTarget.slice(0, hashIdx);
|
|
2647
|
+
const resolved = resolveTarget(rawTarget, index, options, entry);
|
|
2551
2648
|
return {
|
|
2552
2649
|
indent,
|
|
2553
|
-
text: customText ?? defaultTextForTarget(
|
|
2650
|
+
text: customText ?? defaultTextForTarget(rawTarget, resolved),
|
|
2554
2651
|
link: resolved?.url ?? null
|
|
2555
2652
|
};
|
|
2556
2653
|
}
|
|
@@ -2679,7 +2776,7 @@ function defaultItemTitle(entry, strip) {
|
|
|
2679
2776
|
}
|
|
2680
2777
|
function humanize(name, strip) {
|
|
2681
2778
|
let s = name;
|
|
2682
|
-
if (strip) s = s.replace(/^\d+[-_
|
|
2779
|
+
if (strip) s = s.replace(/^\d+[-_\s]+/, "");
|
|
2683
2780
|
return s.replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim().replace(/\b\w/g, (m) => m.toUpperCase());
|
|
2684
2781
|
}
|
|
2685
2782
|
function newNode(path) {
|
|
@@ -3255,11 +3352,12 @@ function matchGlob(path, pat) {
|
|
|
3255
3352
|
function humanize2(name, stripNumeric) {
|
|
3256
3353
|
let s = name;
|
|
3257
3354
|
if (stripNumeric) {
|
|
3258
|
-
s = s.replace(/^\d+[-_
|
|
3355
|
+
s = s.replace(/^\d+[-_\s]+/, "");
|
|
3259
3356
|
}
|
|
3260
3357
|
return s.replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim().replace(/\b\w/g, (m) => m.toUpperCase());
|
|
3261
3358
|
}
|
|
3262
3359
|
function defaultTemplate(ctx) {
|
|
3360
|
+
const prefix = ctx.dirRelPath === "" ? "" : `${ctx.dirRelPath}/`;
|
|
3263
3361
|
const lines = [];
|
|
3264
3362
|
lines.push("---");
|
|
3265
3363
|
lines.push(`title: ${ctx.title}`);
|
|
@@ -3273,7 +3371,7 @@ function defaultTemplate(ctx) {
|
|
|
3273
3371
|
lines.push("## Sections");
|
|
3274
3372
|
lines.push("");
|
|
3275
3373
|
for (const d of ctx.subDirs) {
|
|
3276
|
-
lines.push(`- [[${
|
|
3374
|
+
lines.push(`- [[${prefix}${d.name}/|${d.title}]]`);
|
|
3277
3375
|
}
|
|
3278
3376
|
lines.push("");
|
|
3279
3377
|
}
|
|
@@ -3281,7 +3379,7 @@ function defaultTemplate(ctx) {
|
|
|
3281
3379
|
lines.push("## Pages");
|
|
3282
3380
|
lines.push("");
|
|
3283
3381
|
for (const f of ctx.files) {
|
|
3284
|
-
lines.push(`- [[${
|
|
3382
|
+
lines.push(`- [[${prefix}${f.relPath}|${f.title}]]`);
|
|
3285
3383
|
}
|
|
3286
3384
|
lines.push("");
|
|
3287
3385
|
}
|
|
@@ -3289,7 +3387,7 @@ function defaultTemplate(ctx) {
|
|
|
3289
3387
|
}
|
|
3290
3388
|
|
|
3291
3389
|
// src/core/scan-wikilinks.ts
|
|
3292
|
-
var WIKILINK_RE3 = /(!?)\[\[([^\]\n
|
|
3390
|
+
var WIKILINK_RE3 = /(!?)\[\[([^\]\n]+)\]\]/g;
|
|
3293
3391
|
function stripCodeForScan(src) {
|
|
3294
3392
|
let r = src.replace(/```[\s\S]*?```/g, (m) => " ".repeat(m.length));
|
|
3295
3393
|
r = r.replace(/~~~[\s\S]*?~~~/g, (m) => " ".repeat(m.length));
|
|
@@ -3305,7 +3403,12 @@ function scanWikilinks(index, options) {
|
|
|
3305
3403
|
for (const m of matches) {
|
|
3306
3404
|
total += 1;
|
|
3307
3405
|
const isEmbed = m[1] === "!";
|
|
3308
|
-
const
|
|
3406
|
+
const inner = m[2];
|
|
3407
|
+
let rawTarget = splitWikilinkInner(inner)[0] ?? "";
|
|
3408
|
+
const hashIdx = rawTarget.indexOf("#");
|
|
3409
|
+
if (hashIdx >= 0) rawTarget = rawTarget.slice(0, hashIdx);
|
|
3410
|
+
rawTarget = rawTarget.trim();
|
|
3411
|
+
if (!rawTarget) continue;
|
|
3309
3412
|
if (isEmbed) {
|
|
3310
3413
|
const ext = extractExt3(rawTarget);
|
|
3311
3414
|
if (ext) {
|
|
@@ -3445,7 +3548,11 @@ function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
|
3445
3548
|
try {
|
|
3446
3549
|
const report = scanWikilinks(index, resolvedForWrapper);
|
|
3447
3550
|
logDeadLinks(report, resolvedForWrapper.deadLink);
|
|
3448
|
-
} catch {
|
|
3551
|
+
} catch (e) {
|
|
3552
|
+
console.warn(
|
|
3553
|
+
"vitepress-allyouneed: scanWikilinks \u5931\u8D25,\u8DF3\u8FC7\u6B7B\u94FE\u6C47\u603B\u3002",
|
|
3554
|
+
e instanceof Error ? e.message : String(e)
|
|
3555
|
+
);
|
|
3449
3556
|
}
|
|
3450
3557
|
const localesObj = config.locales;
|
|
3451
3558
|
const localeKeys = localesObj ? Object.keys(localesObj).filter((k) => k !== "root") : [];
|
|
@@ -3494,17 +3601,25 @@ function defineConfigWithAllYouNeed(config, pluginOptions = {}) {
|
|
|
3494
3601
|
themeConfig.nav,
|
|
3495
3602
|
resolvedForWrapper
|
|
3496
3603
|
);
|
|
3497
|
-
const
|
|
3498
|
-
if (
|
|
3499
|
-
for (const lang of Object.keys(
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
if (lc.themeConfig.
|
|
3503
|
-
|
|
3504
|
-
|
|
3604
|
+
const localesForViews = config.locales;
|
|
3605
|
+
if (localesForViews) {
|
|
3606
|
+
for (const lang of Object.keys(localesForViews)) {
|
|
3607
|
+
if (lang === "root") continue;
|
|
3608
|
+
const lc = localesForViews[lang];
|
|
3609
|
+
if (!lc.themeConfig) lc.themeConfig = {};
|
|
3610
|
+
if (lc.themeConfig.sidebar !== void 0) {
|
|
3611
|
+
lc.themeConfig.sidebar = injectViewsSidebar(
|
|
3612
|
+
lc.themeConfig.sidebar,
|
|
3505
3613
|
resolvedForWrapper
|
|
3506
3614
|
);
|
|
3507
3615
|
}
|
|
3616
|
+
const navInjected = injectViewsNav(
|
|
3617
|
+
lc.themeConfig.nav,
|
|
3618
|
+
resolvedForWrapper
|
|
3619
|
+
);
|
|
3620
|
+
if (navInjected !== void 0) {
|
|
3621
|
+
lc.themeConfig.nav = navInjected;
|
|
3622
|
+
}
|
|
3508
3623
|
}
|
|
3509
3624
|
}
|
|
3510
3625
|
}
|