1
0
silverbullet/plugs/core/broken_links.ts
Zef Hemel 7c825348b2
Big refactors and fixes
* Query regen
* Fix anchor completion
* Dependency fixes
* Changelog update
2023-07-02 11:25:32 +02:00

67 lines
1.9 KiB
TypeScript

import { traverseTree } from "../../plug-api/lib/tree.ts";
import {
editor,
markdown,
space,
} from "../../plug-api/silverbullet-syscall/mod.ts";
export async function brokenLinksCommand() {
const pageName = "BROKEN LINKS";
await editor.flashNotification("Scanning your space...");
const allPages = await space.listPages();
const allPagesMap = new Map(allPages.map((p) => [p.name, true]));
const brokenLinks: { page: string; link: string; pos: number }[] = [];
for (const pageMeta of allPages) {
const text = await space.readPage(pageMeta.name);
const tree = await markdown.parseMarkdown(text);
traverseTree(tree, (tree) => {
if (tree.type === "WikiLinkPage") {
// Add the prefix in the link text
const [pageName] = tree.children![0].text!.split("@");
if (pageName.startsWith("💭 ")) {
return true;
}
if (
pageName && !pageName.startsWith("{{")
) {
if (!allPagesMap.has(pageName)) {
brokenLinks.push({
page: pageMeta.name,
link: pageName,
pos: tree.from!,
});
}
}
}
if (tree.type === "PageRef") {
const pageName = tree.children![0].text!.slice(2, -2);
if (pageName.startsWith("💭 ")) {
return true;
}
if (!allPagesMap.has(pageName)) {
brokenLinks.push({
page: pageMeta.name,
link: pageName,
pos: tree.from!,
});
}
}
if (tree.type === "DirectiveBody") {
// Don't look inside directive bodies
return true;
}
return false;
});
}
const lines: string[] = [];
for (const brokenLink of brokenLinks) {
lines.push(
`* [[${brokenLink.page}@${brokenLink.pos}]]: ${brokenLink.link}`,
);
}
await space.writePage(pageName, lines.join("\n"));
await editor.navigate(pageName);
}