1
0
silverbullet/plugs/index/paragraph.ts
Ian Shehadeh 50105fd044
Index plug: index paragraph nodes (#528)
* 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
2023-10-12 20:30:47 +02:00

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);
}