2022-10-14 13:11:33 +00:00
|
|
|
import { collectNodesOfType } from "$sb/lib/tree.ts";
|
2022-12-21 13:55:24 +00:00
|
|
|
import type { CompleteEvent, IndexTreeEvent } from "$sb/app_event.ts";
|
2023-11-02 15:19:33 +00:00
|
|
|
import { ObjectValue, QueryExpression } from "$sb/types.ts";
|
2023-10-03 12:16:33 +00:00
|
|
|
import { indexObjects, queryObjects } from "./api.ts";
|
2022-08-30 08:44:20 +00:00
|
|
|
|
2023-10-03 12:16:33 +00:00
|
|
|
type AnchorObject = ObjectValue<{
|
|
|
|
name: string;
|
|
|
|
page: string;
|
|
|
|
pos: number;
|
|
|
|
}>;
|
2022-08-30 08:44:20 +00:00
|
|
|
|
|
|
|
export async function indexAnchors({ name: pageName, tree }: IndexTreeEvent) {
|
2023-10-03 12:16:33 +00:00
|
|
|
const anchors: ObjectValue<AnchorObject>[] = [];
|
2022-08-30 08:44:20 +00:00
|
|
|
|
|
|
|
collectNodesOfType(tree, "NamedAnchor").forEach((n) => {
|
2022-10-24 17:40:52 +00:00
|
|
|
const aName = n.children![0].text!.substring(1);
|
2022-08-30 08:44:20 +00:00
|
|
|
anchors.push({
|
2023-11-03 11:01:33 +00:00
|
|
|
ref: `${pageName}$${aName}`,
|
2023-10-03 12:16:33 +00:00
|
|
|
tags: ["anchor"],
|
|
|
|
name: aName,
|
|
|
|
page: pageName,
|
|
|
|
pos: n.from!,
|
2022-08-30 08:44:20 +00:00
|
|
|
});
|
|
|
|
});
|
2022-10-21 08:00:43 +00:00
|
|
|
// console.log("Found", anchors.length, "anchors(s)");
|
2023-10-03 12:16:33 +00:00
|
|
|
await indexObjects(pageName, anchors);
|
2022-08-30 08:44:20 +00:00
|
|
|
}
|
|
|
|
|
2022-12-21 13:55:24 +00:00
|
|
|
export async function anchorComplete(completeEvent: CompleteEvent) {
|
2023-11-03 11:01:33 +00:00
|
|
|
const match = /\[\[([^\]@$:]*[@$][\w\.\-\/]*)$/.exec(
|
|
|
|
completeEvent.linePrefix,
|
|
|
|
);
|
2022-12-21 13:55:24 +00:00
|
|
|
if (!match) {
|
2022-08-30 08:44:20 +00:00
|
|
|
return null;
|
|
|
|
}
|
2022-12-21 13:55:24 +00:00
|
|
|
|
2023-11-03 11:01:33 +00:00
|
|
|
const pageRef = match[1].split(/[@$]/)[0];
|
2023-11-02 15:19:33 +00:00
|
|
|
let filter: QueryExpression | undefined = ["=", ["attr", "page"], [
|
|
|
|
"string",
|
|
|
|
pageRef,
|
|
|
|
]];
|
2022-08-30 08:44:20 +00:00
|
|
|
if (!pageRef) {
|
2023-11-02 15:19:33 +00:00
|
|
|
// "bare" anchor, match any page for completion purposes
|
|
|
|
filter = undefined;
|
2022-08-30 08:44:20 +00:00
|
|
|
}
|
2023-11-02 15:19:33 +00:00
|
|
|
const allAnchors = await queryObjects<AnchorObject>("anchor", { filter });
|
2022-08-30 08:44:20 +00:00
|
|
|
return {
|
2023-11-02 15:19:33 +00:00
|
|
|
from: completeEvent.pos - match[1].length,
|
2022-08-30 08:44:20 +00:00
|
|
|
options: allAnchors.map((a) => ({
|
2023-11-03 11:01:33 +00:00
|
|
|
label: a.page === completeEvent.pageName ? `\$${a.name}` : a.ref,
|
2022-08-30 08:44:20 +00:00
|
|
|
type: "anchor",
|
|
|
|
})),
|
|
|
|
};
|
|
|
|
}
|