silverbullet/plugs/index/item.ts

89 lines
2.1 KiB
TypeScript
Raw Normal View History

2024-02-29 22:23:05 +08:00
import type { IndexTreeEvent } from "../../plug-api/types.ts";
2022-04-01 23:07:08 +08:00
2024-02-29 22:23:05 +08:00
import {
collectNodesOfType,
ParseTree,
renderToText,
} from "../../plug-api/lib/tree.ts";
2023-07-25 01:54:31 +08:00
import { extractAttributes } from "$sb/lib/attribute.ts";
import { rewritePageRefs } from "$sb/lib/resolve.ts";
2024-02-29 22:23:05 +08:00
import { ObjectValue } from "../../plug-api/types.ts";
import { indexObjects } from "./api.ts";
import { updateITags } from "$sb/lib/tags.ts";
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
2022-03-29 23:02:28 +08:00
export type ItemObject = ObjectValue<
{
name: string;
page: string;
pos: number;
} & Record<string, any>
>;
2022-03-29 23:02:28 +08:00
export async function indexItems({ name, tree }: IndexTreeEvent) {
const items: ObjectValue<ItemObject>[] = [];
2022-03-29 23:02:28 +08:00
const frontmatter = await extractFrontmatter(tree);
2022-04-04 17:51:41 +08:00
2022-10-14 21:11:33 +08:00
const coll = collectNodesOfType(tree, "ListItem");
2022-04-04 17:51:41 +08:00
for (let n of coll) {
2022-04-04 17:51:41 +08:00
if (!n.children) {
2023-07-26 23:12:56 +08:00
continue;
2022-04-04 17:51:41 +08:00
}
if (collectNodesOfType(n, "Task").length > 0) {
// This is a task item, skip it
2023-07-26 23:12:56 +08:00
continue;
}
const tags = new Set<string>();
const item: ItemObject = {
ref: `${name}@${n.from}`,
tag: "item",
2023-07-25 01:54:31 +08:00
name: "", // to be replaced
page: name,
pos: n.from!,
2023-07-25 01:54:31 +08:00
};
2022-10-14 21:11:33 +08:00
const textNodes: ParseTree[] = [];
collectNodesOfType(n, "Hashtag").forEach((h) => {
// Push tag to the list, removing the initial #
2023-10-13 22:33:37 +08:00
tags.add(h.children![0].text!.substring(1));
h.children = [];
});
// Extract attributes and remove from tree
const extractedAttributes = await extractAttributes(
["item", ...tags],
n,
true,
);
2022-10-14 21:11:33 +08:00
for (const child of n.children!.slice(1)) {
rewritePageRefs(child, name);
2022-04-04 17:51:41 +08:00
if (child.type === "OrderedList" || child.type === "BulletList") {
break;
}
textNodes.push(child);
}
2023-07-25 01:54:31 +08:00
item.name = textNodes.map(renderToText).join("").trim();
if (tags.size > 0) {
item.tags = [...tags];
}
for (
const [key, value] of Object.entries(extractedAttributes)
) {
item[key] = value;
}
updateITags(item, frontmatter);
2023-10-13 22:33:37 +08:00
items.push(item);
2023-07-26 23:12:56 +08:00
}
// console.log("Found", items, "item(s)");
await indexObjects(name, items);
}