silverbullet/plugs/core/item.ts

74 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-04-05 23:02:17 +08:00
import { IndexEvent } from "../../webapp/app_event";
2022-04-01 23:07:08 +08:00
import { batchSet, scanPrefixGlobal } from "plugos-silverbullet-syscall/index";
2022-04-05 23:02:17 +08:00
import { parseMarkdown } from "plugos-silverbullet-syscall/markdown";
import { collectNodesOfType, ParseTree, renderToText } from "../../common/tree";
import { whiteOutQueries } from "../query/util";
import { applyQuery, QueryProviderEvent } from "../query/engine";
2022-03-29 23:02:28 +08:00
export type Item = {
name: string;
2022-04-04 17:51:41 +08:00
nested?: string;
// Not stored in DB
page?: string;
pos?: number;
2022-03-29 23:02:28 +08:00
};
export async function indexItems({ name, text }: IndexEvent) {
let items: { key: string; value: Item }[] = [];
text = whiteOutQueries(text);
2022-04-04 17:51:41 +08:00
console.log("Indexing items", name);
let mdTree = await parseMarkdown(text);
let coll = collectNodesOfType(mdTree, "ListItem");
2022-04-04 17:51:41 +08:00
coll.forEach((n) => {
if (!n.children) {
return;
}
2022-04-12 02:34:09 +08:00
let textNodes: ParseTree[] = [];
2022-04-04 17:51:41 +08:00
let nested: string | undefined;
for (let child of n.children!.slice(1)) {
if (child.type === "OrderedList" || child.type === "BulletList") {
2022-04-12 02:34:09 +08:00
nested = renderToText(child);
2022-04-04 17:51:41 +08:00
break;
}
textNodes.push(child);
}
2022-04-12 02:34:09 +08:00
let item = textNodes.map(renderToText).join("").trim();
2022-03-29 23:02:28 +08:00
let value: Item = {
name: item,
2022-03-29 23:02:28 +08:00
};
2022-04-04 17:51:41 +08:00
if (nested) {
value.nested = nested;
2022-03-29 23:02:28 +08:00
}
items.push({
2022-04-04 17:51:41 +08:00
key: `it:${n.from}`,
2022-03-29 23:02:28 +08:00
value,
});
2022-04-04 17:51:41 +08:00
});
2022-03-29 23:02:28 +08:00
console.log("Found", items.length, "item(s)");
2022-04-01 23:07:08 +08:00
await batchSet(name, items);
2022-03-29 23:02:28 +08:00
}
export async function queryProvider({
query,
}: QueryProviderEvent): Promise<string> {
let allItems: Item[] = [];
for (let { key, page, value } of await scanPrefixGlobal("it:")) {
let [, pos] = key.split(":");
allItems.push({
...value,
page: page,
pos: +pos,
});
}
let markdownItems = applyQuery(query, allItems).map(
(item) =>
`* [[${item.page}@${item.pos}]] ${item.name}` +
(item.nested ? "\n " + item.nested : "")
);
return markdownItems.join("\n");
}