50105fd044
* index plug: index paragraph nodes Includes attributes and tags in the paragraphs. Only considers top level paragraphs (right below Document node) * keep ref and pos consistent with other objects - most objects just store the starting position in the `pos` field. - ref is usually `${page}@${pos}` so that it works as a link. * cleanup and clarify comments * add paragraph to builtins index
52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import type { IndexTreeEvent } from "$sb/app_event.ts";
|
|
import { indexObjects } from "./api.ts";
|
|
import { renderToText, traverseTree, traverseTreeAsync } from "$sb/lib/tree.ts";
|
|
import { extractAttributes } from "$sb/lib/attribute.ts";
|
|
|
|
/** ParagraphObject An index object for the top level text nodes */
|
|
export type ParagraphObject = {
|
|
ref: string;
|
|
tags: string[];
|
|
text: string;
|
|
page: string;
|
|
pos: number;
|
|
} & Record<string, any>;
|
|
|
|
export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
|
|
const objects: ParagraphObject[] = [];
|
|
|
|
await traverseTreeAsync(tree, async (p) => {
|
|
// only search directly under document
|
|
// Paragraph nodes also appear under block elements
|
|
if (p.type == "Document") return false; // continue traversal if p is Document
|
|
if (p.type != "Paragraph") return true;
|
|
|
|
const tags = new Set<string>(["paragraph"]);
|
|
// tag the paragraph with any hashtags inside it
|
|
traverseTree(p, (e) => {
|
|
if (e.type == "Hashtag") {
|
|
tags.add(e.children![0].text!.substring(1));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
const attrs = await extractAttributes(p, false);
|
|
const pos = p.from!;
|
|
objects.push({
|
|
ref: `${page}@${pos}`,
|
|
text: renderToText(p),
|
|
tags: [...tags.values()],
|
|
page,
|
|
pos,
|
|
...attrs,
|
|
});
|
|
|
|
// stop on every element except document, including paragraphs
|
|
return true;
|
|
});
|
|
|
|
await indexObjects<ParagraphObject>(page, objects);
|
|
}
|