2024-02-29 22:23:05 +08:00
|
|
|
import type { IndexTreeEvent } from "../../plug-api/types.ts";
|
2023-10-13 02:30:47 +08:00
|
|
|
import { indexObjects } from "./api.ts";
|
2023-10-13 21:37:25 +08:00
|
|
|
import {
|
|
|
|
collectNodesOfType,
|
|
|
|
findParentMatching,
|
|
|
|
renderToText,
|
|
|
|
traverseTreeAsync,
|
2024-02-29 22:23:05 +08:00
|
|
|
} from "../../plug-api/lib/tree.ts";
|
2024-08-07 02:11:38 +08:00
|
|
|
import { extractAttributes } from "@silverbulletmd/silverbullet/lib/attribute";
|
2024-07-30 23:33:33 +08:00
|
|
|
import type { ObjectValue } from "../../plug-api/types.ts";
|
2024-08-07 02:11:38 +08:00
|
|
|
import { updateITags } from "@silverbulletmd/silverbullet/lib/tags";
|
|
|
|
import { extractFrontmatter } from "@silverbulletmd/silverbullet/lib/frontmatter";
|
2024-10-20 18:39:58 +08:00
|
|
|
import { extractHashtag } from "../../plug-api/lib/tags.ts";
|
2023-10-13 02:30:47 +08:00
|
|
|
|
|
|
|
/** ParagraphObject An index object for the top level text nodes */
|
2023-10-13 22:33:37 +08:00
|
|
|
export type ParagraphObject = ObjectValue<
|
|
|
|
{
|
|
|
|
page: string;
|
|
|
|
pos: number;
|
2024-07-07 02:52:27 +08:00
|
|
|
text: string;
|
2023-10-13 22:33:37 +08:00
|
|
|
} & Record<string, any>
|
|
|
|
>;
|
2023-10-13 02:30:47 +08:00
|
|
|
|
|
|
|
export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
|
|
|
|
const objects: ParagraphObject[] = [];
|
2024-01-11 20:20:50 +08:00
|
|
|
|
|
|
|
const frontmatter = await extractFrontmatter(tree);
|
2023-10-13 02:30:47 +08:00
|
|
|
|
|
|
|
await traverseTreeAsync(tree, async (p) => {
|
2023-10-13 21:37:25 +08:00
|
|
|
if (p.type !== "Paragraph") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (findParentMatching(p, (n) => n.type === "ListItem")) {
|
|
|
|
// Not looking at paragraphs nested in a list
|
|
|
|
return false;
|
|
|
|
}
|
2023-10-13 02:30:47 +08:00
|
|
|
|
2024-07-07 02:52:27 +08:00
|
|
|
const fullText = renderToText(p);
|
|
|
|
|
|
|
|
// Collect tags and remove from the tree
|
2024-02-28 03:05:12 +08:00
|
|
|
const tags = new Set<string>();
|
2024-01-11 20:20:50 +08:00
|
|
|
collectNodesOfType(p, "Hashtag").forEach((tagNode) => {
|
2024-10-20 18:39:58 +08:00
|
|
|
tags.add(extractHashtag(tagNode.children![0].text!));
|
2024-01-11 20:20:50 +08:00
|
|
|
// Hacky way to remove the hashtag
|
|
|
|
tagNode.children = [];
|
|
|
|
});
|
|
|
|
|
2024-02-28 03:05:12 +08:00
|
|
|
// Extract attributes and remove from tree
|
2024-08-22 02:13:40 +08:00
|
|
|
const attrs = await extractAttributes(["paragraph", ...tags], p);
|
2024-02-28 03:05:12 +08:00
|
|
|
const text = renderToText(p);
|
2023-10-13 23:32:31 +08:00
|
|
|
|
2024-02-28 03:05:12 +08:00
|
|
|
if (!text.trim()) {
|
2024-01-11 20:20:50 +08:00
|
|
|
// Empty paragraph, just tags and attributes maybe
|
|
|
|
return true;
|
2023-10-13 23:32:31 +08:00
|
|
|
}
|
2023-10-13 02:30:47 +08:00
|
|
|
|
|
|
|
const pos = p.from!;
|
2024-01-11 20:20:50 +08:00
|
|
|
const paragraph: ParagraphObject = {
|
|
|
|
tag: "paragraph",
|
2024-07-07 02:52:27 +08:00
|
|
|
ref: `${page}@${pos}`,
|
|
|
|
text: fullText,
|
2023-10-13 02:30:47 +08:00
|
|
|
page,
|
|
|
|
pos,
|
|
|
|
...attrs,
|
2024-01-11 20:20:50 +08:00
|
|
|
};
|
|
|
|
if (tags.size > 0) {
|
|
|
|
paragraph.tags = [...tags];
|
|
|
|
paragraph.itags = [...tags];
|
|
|
|
}
|
|
|
|
|
|
|
|
updateITags(paragraph, frontmatter);
|
|
|
|
objects.push(paragraph);
|
2023-10-13 02:30:47 +08:00
|
|
|
|
|
|
|
// stop on every element except document, including paragraphs
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2023-10-13 21:37:25 +08:00
|
|
|
// console.log("Paragraph objects", objects);
|
|
|
|
|
2023-10-13 02:30:47 +08:00
|
|
|
await indexObjects<ParagraphObject>(page, objects);
|
|
|
|
}
|