93 lines
2.2 KiB
TypeScript
93 lines
2.2 KiB
TypeScript
import {
|
|
cloneTree,
|
|
findParentMatching,
|
|
type ParseTree,
|
|
renderToText,
|
|
traverseTree,
|
|
} from "@silverbulletmd/silverbullet/lib/tree";
|
|
import { cleanTags, collectTags, updateITags } from "./tags.ts";
|
|
import type { FrontMatter } from "./frontmatter.ts";
|
|
import type {
|
|
ObjectValue,
|
|
PageMeta,
|
|
} from "@silverbulletmd/silverbullet/type/index";
|
|
import { system } from "@silverbulletmd/silverbullet/syscalls";
|
|
import { cleanAttributes, collectAttributes } from "./attribute.ts";
|
|
|
|
/** ParagraphObject An index object for the top level text nodes */
|
|
export type ParagraphObject = ObjectValue<
|
|
{
|
|
page: string;
|
|
pos: number;
|
|
text: string;
|
|
} & Record<string, any>
|
|
>;
|
|
|
|
export async function indexParagraphs(
|
|
pageMeta: PageMeta,
|
|
frontmatter: FrontMatter,
|
|
tree: ParseTree,
|
|
) {
|
|
const shouldIndexAll = await system.getConfig("index.paragraph.all", false);
|
|
|
|
const objects: ParagraphObject[] = [];
|
|
|
|
traverseTree(tree, (p) => {
|
|
if (p.type !== "Paragraph") {
|
|
return false;
|
|
}
|
|
|
|
if (findParentMatching(p, (n) => n.type === "ListItem")) {
|
|
// Not looking at paragraphs nested in a list
|
|
return true;
|
|
}
|
|
|
|
const fullText = renderToText(p);
|
|
|
|
// Collect tags
|
|
const tags = collectTags(p);
|
|
|
|
if (tags.length === 0 && !shouldIndexAll) {
|
|
// Don't index paragraphs without a hashtag
|
|
return true;
|
|
}
|
|
|
|
// Extract attributes
|
|
const attrs = collectAttributes(p);
|
|
|
|
// Clean tree, just to check if it's effectively empty or not
|
|
const pClone = cloneTree(p);
|
|
cleanTags(pClone);
|
|
cleanAttributes(pClone);
|
|
const text = renderToText(pClone);
|
|
|
|
if (!text.trim()) {
|
|
// Empty paragraph, just tags and attributes maybe
|
|
return true;
|
|
}
|
|
|
|
const pos = p.from!;
|
|
const paragraph: ParagraphObject = {
|
|
tag: "paragraph",
|
|
ref: `${pageMeta.name}@${pos}`,
|
|
text: fullText,
|
|
page: pageMeta.name,
|
|
pos,
|
|
range: [p.from!, p.to!],
|
|
...attrs,
|
|
};
|
|
if (tags.length > 0) {
|
|
paragraph.tags = [...tags];
|
|
paragraph.itags = [...tags];
|
|
}
|
|
|
|
updateITags(paragraph, frontmatter);
|
|
objects.push(paragraph);
|
|
|
|
// stop on every element except document, including paragraphs
|
|
return true;
|
|
});
|
|
|
|
return objects;
|
|
}
|