import { codeWidget, editor, language, markdown, space, } from "$sb/silverbullet-syscall/mod.ts"; import { parseTreeToAST, renderToText } from "$sb/lib/tree.ts"; import { CodeWidgetContent } from "$sb/types.ts"; import { loadPageObject } from "../template/template.ts"; import { queryObjects } from "./api.ts"; import { TemplateObject } from "../template/types.ts"; import { expressionToKvQueryExpression } from "$sb/lib/parse-query.ts"; import { evalQueryExpression } from "$sb/lib/query.ts"; import { renderTemplate } from "../template/plug_api.ts"; import { extractFrontmatter } from "$sb/lib/frontmatter.ts"; import { rewritePageRefs } from "$sb/lib/resolve.ts"; export async function refreshWidgets() { await codeWidget.refreshAll(); } export async function renderTemplateWidgets(side: "top" | "bottom"): Promise< CodeWidgetContent | null > { const text = await editor.getText(); const pageMeta = await loadPageObject(await editor.getCurrentPage()); const parsedMd = await markdown.parseMarkdown(text); const frontmatter = await extractFrontmatter(parsedMd); const allFrontMatterTemplates = await queryObjects( "template", { filter: ["=", ["attr", "type"], ["string", `widget:${side}`]], orderBy: [{ expr: ["attr", "priority"], desc: false }], }, ); const templateBits: string[] = []; // Strategy: walk through all matching templates, evaluate the 'where' expression, and pick the first one that matches for (const template of allFrontMatterTemplates) { const exprAST = parseTreeToAST( await language.parseLanguage("expression", template.where!), ); const parsedExpression = expressionToKvQueryExpression(exprAST[1]); if (evalQueryExpression(parsedExpression, pageMeta)) { // Match! We're happy const templateText = await space.readPage(template.ref); // templateBits.push(await space.readPage(template.ref)); let renderedTemplate = (await renderTemplate( templateText, pageMeta, frontmatter, )).text; const parsedMarkdown = await markdown.parseMarkdown(renderedTemplate); rewritePageRefs(parsedMarkdown, template.ref); renderedTemplate = renderToText(parsedMarkdown); templateBits.push(renderedTemplate); } } const summaryText = templateBits.join(""); // console.log("Rendered", summaryText); return { markdown: summaryText, buttons: [ { description: "Reload", svg: ``, invokeFunction: "index.refreshWidgets", }, ], }; }