import { codeWidget, editor, language, markdown, space, } from "@silverbulletmd/silverbullet/syscalls"; import { parseTreeToAST, renderToText, } from "@silverbulletmd/silverbullet/lib/tree"; import type { CodeWidgetContent } from "../../plug-api/types.ts"; import { loadPageObject } from "../template/page.ts"; import { queryObjects } from "./api.ts"; import type { TemplateObject } from "../template/types.ts"; import { expressionToKvQueryExpression } from "../../plug-api/lib/parse_query.ts"; import { evalQueryExpression } from "@silverbulletmd/silverbullet/lib/query_expression"; import { renderTemplate } from "../template/plug_api.ts"; import { extractFrontmatter } from "@silverbulletmd/silverbullet/lib/frontmatter"; import { rewritePageRefs } from "@silverbulletmd/silverbullet/lib/resolve"; export async function refreshWidgets() { await codeWidget.refreshAll(); } export async function renderTemplateWidgets(side: "top" | "bottom"): Promise< CodeWidgetContent | null > { const text = await editor.getText(); let pageMeta = await loadPageObject(await editor.getCurrentPage()); const parsedMd = await markdown.parseMarkdown(text); const frontmatter = await extractFrontmatter(parsedMd); pageMeta = { ...pageMeta, ...frontmatter }; const blockTemplates = await queryObjects( "template", { // where hooks.top/bottom exists filter: ["attr", ["attr", "hooks"], side], orderBy: [{ // order by hooks.top/bottom.order asc expr: ["attr", ["attr", ["attr", "hooks"], side], "order"], desc: false, }], }, ); // console.log(`Found the following ${side} templates`, blockTemplates); const templateBits: string[] = []; // Strategy: walk through all matching templates, evaluate the 'where' expression, and pick the first one that matches for (const template of blockTemplates) { if (!template.hooks) { console.warn( "No hooks specified for template", template.ref, "this should never happen", ); continue; } const blockDef = template.hooks[side]!; const exprAST = parseTreeToAST( await language.parseLanguage("expression", blockDef.where!), ); const parsedExpression = expressionToKvQueryExpression(exprAST[1]); if (await evalQueryExpression(parsedExpression, pageMeta, {}, {})) { // Match! We're happy const templateText = await space.readPage(template.ref); let renderedTemplate = (await renderTemplate( templateText, frontmatter, { page: pageMeta }, )).text; const parsedMarkdown = await markdown.parseMarkdown(renderedTemplate); rewritePageRefs(parsedMarkdown, template.ref); renderedTemplate = renderToText(parsedMarkdown); templateBits.push(renderedTemplate.trim()); } } const summaryText = templateBits.join("\n"); // console.log("Summary:", summaryText); return { markdown: summaryText, buttons: [ { description: "Reload", svg: ``, invokeFunction: ["index.refreshWidgets"], }, ], }; }