diff --git a/plug-api/app_event.ts b/plug-api/app_event.ts index 3767b057..e326f635 100644 --- a/plug-api/app_event.ts +++ b/plug-api/app_event.ts @@ -54,6 +54,7 @@ export type CompleteEvent = { export type WidgetContent = { html?: string; script?: string; + markdown?: string; url?: string; height?: number; width?: number; diff --git a/plug-api/types.ts b/plug-api/types.ts index b24044e5..36ab0d75 100644 --- a/plug-api/types.ts +++ b/plug-api/types.ts @@ -115,3 +115,14 @@ export type ObjectValue = { } & T; export type ObjectQuery = Omit; + +// Code widget stuff +export type CodeWidgetCallback = ( + bodyText: string, +) => Promise; + +export type CodeWidgetContent = { + html?: string; + markdown?: string; + script?: string; +}; diff --git a/plugs/query/assets/style.css b/plugs/markdown/assets/markdown_widget.css similarity index 100% rename from plugs/query/assets/style.css rename to plugs/markdown/assets/markdown_widget.css diff --git a/plugs/query/assets/common.js b/plugs/markdown/assets/markdown_widget.js similarity index 100% rename from plugs/query/assets/common.js rename to plugs/markdown/assets/markdown_widget.js diff --git a/plugs/markdown/assets/styles.css b/plugs/markdown/assets/preview.css similarity index 100% rename from plugs/markdown/assets/styles.css rename to plugs/markdown/assets/preview.css diff --git a/plugs/markdown/assets/handler.js b/plugs/markdown/assets/preview.js similarity index 100% rename from plugs/markdown/assets/handler.js rename to plugs/markdown/assets/preview.js diff --git a/plugs/markdown/markdown.plug.yaml b/plugs/markdown/markdown.plug.yaml index f24bf846..b7178963 100644 --- a/plugs/markdown/markdown.plug.yaml +++ b/plugs/markdown/markdown.plug.yaml @@ -2,6 +2,13 @@ name: markdown assets: - "assets/*" functions: + + # API + markdownContentWidget: + path: markdown_content_widget.ts:markdownContentWidget + + # User facing + toggle: path: "./markdown.ts:togglePreview" command: diff --git a/plugs/query/util.ts b/plugs/markdown/markdown_content_widget.ts similarity index 66% rename from plugs/query/util.ts rename to plugs/markdown/markdown_content_widget.ts index 0245dd10..df5b834e 100644 --- a/plugs/query/util.ts +++ b/plugs/markdown/markdown_content_widget.ts @@ -1,9 +1,25 @@ -import { asset } from "$sb/syscalls.ts"; +import { WidgetContent } from "$sb/app_event.ts"; +import { asset, markdown } from "$sb/syscalls.ts"; import { panelHtml } from "../../web/components/panel_html.ts"; +import { renderMarkdownToHtml } from "./markdown_render.ts"; + +export async function markdownContentWidget( + markdownText: string, +): Promise { + // Parse markdown to a ParseTree + const mdTree = await markdown.parseMarkdown(markdownText); + // And then render it to HTML + const html = renderMarkdownToHtml(mdTree, { smartHardBreak: true }); + return { + html: await wrapHTML(html), + script: await prepareJS(), + // And add back the markdown text so we can render it in a different way if desired + markdown: markdownText, + }; +} export async function prepareJS() { - const iframeJS = await asset.readAsset("assets/common.js"); - + const iframeJS = await asset.readAsset("assets/markdown_widget.js"); return ` const panelHtml = \`${panelHtml}\`; ${iframeJS} @@ -11,7 +27,7 @@ export async function prepareJS() { } export async function wrapHTML(html: string): Promise { - const css = await asset.readAsset("assets/style.css"); + const css = await asset.readAsset("assets/markdown_widget.css"); return ` diff --git a/plugs/markdown/preview.ts b/plugs/markdown/preview.ts index 778e86b9..7481f2b3 100644 --- a/plugs/markdown/preview.ts +++ b/plugs/markdown/preview.ts @@ -10,8 +10,8 @@ export async function updateMarkdownPreview() { const text = await editor.getText(); const mdTree = await markdown.parseMarkdown(text); // const cleanMd = await cleanMarkdown(text); - const css = await asset.readAsset("assets/styles.css"); - const js = await asset.readAsset("assets/handler.js"); + const css = await asset.readAsset("assets/preview.css"); + const js = await asset.readAsset("assets/preview.js"); const html = renderMarkdownToHtml(mdTree, { smartHardBreak: true, annotationPositions: true, diff --git a/plugs/query/query.plug.yaml b/plugs/query/query.plug.yaml index 9241e9dd..e36f15bc 100644 --- a/plugs/query/query.plug.yaml +++ b/plugs/query/query.plug.yaml @@ -1,6 +1,4 @@ name: query -assets: - - "assets/*" functions: queryWidget: path: query.ts:widget diff --git a/plugs/query/query.ts b/plugs/query/query.ts index 40593f39..1a1935ed 100644 --- a/plugs/query/query.ts +++ b/plugs/query/query.ts @@ -1,11 +1,9 @@ import type { WidgetContent } from "$sb/app_event.ts"; -import { editor, events, language, markdown, space } from "$sb/syscalls.ts"; +import { editor, events, language, space, system } from "$sb/syscalls.ts"; import { parseTreeToAST } from "$sb/lib/tree.ts"; import { astToKvQuery } from "$sb/lib/parse-query.ts"; import { jsonToMDTable, renderTemplate } from "../directive/util.ts"; -import { renderMarkdownToHtml } from "../markdown/markdown_render.ts"; import { replaceTemplateVars } from "../template/template.ts"; -import { prepareJS, wrapHTML } from "./util.ts"; export async function widget(bodyText: string): Promise { const pageMeta = await space.getPageMeta(await editor.getCurrentPage()); @@ -57,21 +55,14 @@ export async function widget(bodyText: string): Promise { } } - // Parse markdown to a ParseTree - const mdTree = await markdown.parseMarkdown(resultMarkdown); - // And then render it to HTML - const html = renderMarkdownToHtml(mdTree, { smartHardBreak: true }); - return { - html: await wrapHTML(` - ${parsedQuery.render ? "" : `
`} - ${html} - ${parsedQuery.render ? "" : `
`} - `), - script: await prepareJS(), - }; + return system.invokeFunction( + "markdown.markdownContentWidget", + resultMarkdown, + ); } catch (e: any) { - return { - html: await wrapHTML(`Error: ${e.message}`), - }; + return system.invokeFunction( + "markdown.markdownContentWidget", + `**Error:** ${e.message}`, + ); } } diff --git a/plugs/query/template.ts b/plugs/query/template.ts index 83da1aaa..dc85c24b 100644 --- a/plugs/query/template.ts +++ b/plugs/query/template.ts @@ -1,9 +1,15 @@ import { WidgetContent } from "$sb/app_event.ts"; -import { editor, handlebars, markdown, space, YAML } from "$sb/syscalls.ts"; +import { + editor, + handlebars, + markdown, + space, + system, + YAML, +} from "$sb/syscalls.ts"; import { rewritePageRefs } from "$sb/lib/resolve.ts"; -import { renderMarkdownToHtml } from "../markdown/markdown_render.ts"; -import { prepareJS, wrapHTML } from "./util.ts"; import { replaceTemplateVars } from "../template/template.ts"; +import { renderToText } from "$sb/lib/tree.ts"; type TemplateConfig = { // Pull the template from a page @@ -36,31 +42,28 @@ export async function widget(bodyText: string): Promise { ) : undefined; - const rendered = config.raw - ? templateText - : await handlebars.renderTemplate( - templateText, - value, - { - page: pageMeta, - }, - ); - const parsedMarkdown = await markdown.parseMarkdown(rendered); + let rendered = config.raw ? templateText : await handlebars.renderTemplate( + templateText, + value, + { + page: pageMeta, + }, + ); if (templatePage) { + const parsedMarkdown = await markdown.parseMarkdown(rendered); rewritePageRefs(parsedMarkdown, templatePage); + rendered = renderToText(parsedMarkdown); } - const html = renderMarkdownToHtml(parsedMarkdown, { - smartHardBreak: true, - }); - return { - html: await wrapHTML(html), - script: await prepareJS(), - }; + return system.invokeFunction( + "markdown.markdownContentWidget", + rendered, + ); } catch (e: any) { - return { - html: `Error: ${e.message}`, - }; + return system.invokeFunction( + "markdown.markdownContentWidget", + `**Error:** ${e.message}`, + ); } } diff --git a/web/cm_plugins/fenced_code.ts b/web/cm_plugins/fenced_code.ts index 27c99f98..1c3b2e55 100644 --- a/web/cm_plugins/fenced_code.ts +++ b/web/cm_plugins/fenced_code.ts @@ -1,13 +1,13 @@ import { WidgetContent } from "../../plug-api/app_event.ts"; import { Decoration, EditorState, syntaxTree, WidgetType } from "../deps.ts"; import type { Client } from "../client.ts"; -import { CodeWidgetCallback } from "../hooks/code_widget.ts"; import { decoratorStateField, invisibleDecoration, isCursorInRange, } from "./util.ts"; import { createWidgetSandboxIFrame } from "../components/widget_sandbox_iframe.ts"; +import type { CodeWidgetCallback } from "$sb/types.ts"; class IFrameWidget extends WidgetType { iframe?: HTMLIFrameElement; diff --git a/web/hooks/code_widget.ts b/web/hooks/code_widget.ts index 6c76ea80..6f9e17af 100644 --- a/web/hooks/code_widget.ts +++ b/web/hooks/code_widget.ts @@ -1,14 +1,11 @@ import { Hook, Manifest } from "../../plugos/types.ts"; import { System } from "../../plugos/system.ts"; +import { CodeWidgetCallback } from "$sb/types.ts"; export type CodeWidgetT = { codeWidget?: string; }; -export type CodeWidgetCallback = ( - bodyText: string, -) => Promise<{ html: string; script: string }>; - export class CodeWidgetHook implements Hook { codeWidgetCallbacks = new Map(); diff --git a/web/styles/colors.scss b/web/styles/colors.scss index 385f961c..063a7d6e 100644 --- a/web/styles/colors.scss +++ b/web/styles/colors.scss @@ -216,15 +216,13 @@ color: var(--editor-line-meta-color); } - .sb-table-widget { - thead tr { - background-color: var(--editor-table-head-background-color); - color: var(--editor-table-head-color); - } + thead tr { + background-color: var(--editor-table-head-background-color); + color: var(--editor-table-head-color); + } - tbody tr:nth-of-type(even) { - background-color: var(--editor-table-even-background-color); - } + tbody tr:nth-of-type(even) { + background-color: var(--editor-table-even-background-color); } .sb-line-blockquote { diff --git a/web/styles/editor.scss b/web/styles/editor.scss index 8e4df620..190c2928 100644 --- a/web/styles/editor.scss +++ b/web/styles/editor.scss @@ -393,22 +393,24 @@ margin-bottom: -3rem; overflow: auto; - table { - width: 100%; - border-spacing: 0; - } - - thead tr { - font-weight: bold; - } - - th, - td { - padding: 8px; - white-space: nowrap; - } } + table { + width: 100%; + border-spacing: 0; + } + + thead tr { + font-weight: bold; + } + + th, + td { + padding: 8px; + white-space: nowrap; + } + + // dont apply background color twice for (fenced) code blocks .sb-line-code .sb-code { background-color: transparent; diff --git a/web/syscalls/widget.ts b/web/syscalls/widget.ts index c6e8805f..badfbc4b 100644 --- a/web/syscalls/widget.ts +++ b/web/syscalls/widget.ts @@ -1,3 +1,4 @@ +import { CodeWidgetContent } from "$sb/types.ts"; import { SysCallMapping } from "../../plugos/system.ts"; import { Client } from "../client.ts"; @@ -9,7 +10,7 @@ export function widgetSyscalls( _ctx, lang: string, body: string, - ): Promise<{ html: string; script: string }> => { + ): Promise => { const langCallback = client.system.codeWidgetHook.codeWidgetCallbacks.get( lang, );