1
0

Fixes #462 and adds richer backlink data

This commit is contained in:
Zef Hemel 2023-07-14 11:52:35 +02:00
parent 839a11bfd7
commit 430792834e

View File

@ -15,25 +15,32 @@ import { events } from "$sb/plugos-syscall/mod.ts";
import { import {
addParentPointers, addParentPointers,
collectNodesMatching, findNodeOfType,
ParseTree, ParseTree,
renderToText, renderToText,
replaceNodesMatching, replaceNodesMatching,
traverseTree,
} from "$sb/lib/tree.ts"; } from "$sb/lib/tree.ts";
import { applyQuery, removeQueries } from "$sb/lib/query.ts"; import { applyQuery } from "$sb/lib/query.ts";
import { extractFrontmatter } from "$sb/lib/frontmatter.ts"; import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
import { invokeFunction } from "$sb/silverbullet-syscall/system.ts"; import { invokeFunction } from "$sb/silverbullet-syscall/system.ts";
import { isValidPageName } from "$sb/lib/page.ts"; import { isValidPageName } from "$sb/lib/page.ts";
// Key space: // Key space:
// pl:toPage:pos => pageName // l:toPage:pos => {name: pageName, inDirective: true}
// meta => metaJson // meta: => metaJson
const backlinkPrefix = `l:`;
type BacklinkEntry = {
name: string;
alias?: string;
inDirective?: boolean;
};
export async function indexLinks({ name, tree }: IndexTreeEvent) { export async function indexLinks({ name, tree }: IndexTreeEvent) {
const backLinks: { key: string; value: string }[] = []; const backLinks: { key: string; value: BacklinkEntry }[] = [];
// [[Style Links]] // [[Style Links]]
// console.log("Now indexing links for", name); // console.log("Now indexing links for", name);
removeQueries(tree);
const pageMeta = await extractFrontmatter(tree); const pageMeta = await extractFrontmatter(tree);
if (Object.keys(pageMeta).length > 0) { if (Object.keys(pageMeta).length > 0) {
// console.log("Extracted page meta data", pageMeta); // console.log("Extracted page meta data", pageMeta);
@ -46,15 +53,38 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
await index.set(name, "meta:", pageMeta); await index.set(name, "meta:", pageMeta);
} }
collectNodesMatching(tree, (n) => n.type === "WikiLinkPage").forEach((n) => { let directiveDepth = 0;
let toPage = n.children![0].text!; traverseTree(tree, (n): boolean => {
if (toPage.includes("@")) { if (n.type === "DirectiveStart") {
toPage = toPage.split("@")[0]; directiveDepth++;
return true;
} }
backLinks.push({ if (n.type === "DirectiveStop") {
key: `pl:${toPage}:${n.from}`, directiveDepth--;
value: name, return true;
}); }
if (n.type === "WikiLink") {
const wikiLinkPage = findNodeOfType(n, "WikiLinkPage")!;
const wikiLinkAlias = findNodeOfType(n, "WikiLinkAlias");
let toPage = wikiLinkPage.children![0].text!;
if (toPage.includes("@")) {
toPage = toPage.split("@")[0];
}
const blEntry: BacklinkEntry = { name };
if (directiveDepth > 0) {
blEntry.inDirective = true;
}
if (wikiLinkAlias) {
blEntry.alias = wikiLinkAlias.children![0].text!;
}
backLinks.push({
key: `${backlinkPrefix}${toPage}:${wikiLinkPage.from}`,
value: blEntry,
});
return true;
}
return false;
}); });
// console.log("Found", backLinks.length, "wiki link(s)"); // console.log("Found", backLinks.length, "wiki link(s)");
await index.batchSet(name, backLinks); await index.batchSet(name, backLinks);
@ -72,10 +102,15 @@ export async function linkQueryProvider({
}: QueryProviderEvent): Promise<any[]> { }: QueryProviderEvent): Promise<any[]> {
const links: any[] = []; const links: any[] = [];
for ( for (
const { value: name, key } of await index.queryPrefix(`pl:${pageName}:`) const { value: blEntry, key } of await index.queryPrefix(
`${backlinkPrefix}${pageName}:`,
)
) { ) {
const [, , pos] = key.split(":"); // Key: pl:page:pos const [, , pos] = key.split(":"); // Key: l:page:pos
links.push({ name, pos }); if (!blEntry.inDirective) {
blEntry.inDirective = false;
}
links.push({ ...blEntry, pos });
} }
return applyQuery(query, links); return applyQuery(query, links);
} }
@ -254,12 +289,14 @@ type BackLink = {
}; };
async function getBackLinks(pageName: string): Promise<BackLink[]> { async function getBackLinks(pageName: string): Promise<BackLink[]> {
const allBackLinks = await index.queryPrefix(`pl:${pageName}:`); const allBackLinks = await index.queryPrefix(
`${backlinkPrefix}${pageName}:`,
);
const pagesToUpdate: BackLink[] = []; const pagesToUpdate: BackLink[] = [];
for (const { key, value } of allBackLinks) { for (const { key, value: { name } } of allBackLinks) {
const keyParts = key.split(":"); const keyParts = key.split(":");
pagesToUpdate.push({ pagesToUpdate.push({
page: value, page: name,
pos: +keyParts[keyParts.length - 1], pos: +keyParts[keyParts.length - 1],
}); });
} }