diff --git a/ts/editable/BUILD.bazel b/ts/editable/BUILD.bazel index 0b8a417f4..c5eab62ef 100644 --- a/ts/editable/BUILD.bazel +++ b/ts/editable/BUILD.bazel @@ -3,7 +3,7 @@ load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check") load("//ts:prettier.bzl", "prettier_test") load("//ts:eslint.bzl", "eslint_test") load("//ts:esbuild.bzl", "esbuild") -load("//ts:vendor.bzl", "copy_bootstrap_icons", "copy_mdi_icons") +load("//ts:vendor.bzl", "copy_mdi_icons") load("//ts:compile_sass.bzl", "compile_sass") svelte_files = glob(["*.svelte"]) @@ -37,6 +37,14 @@ compile_sass( ], ) +copy_mdi_icons( + name = "mdi-icons", + icons = [ + "math-integral-box.svg", + ], + visibility = ["//visibility:public"], +) + ts_library( name = "editable", srcs = glob(["*.ts"]), @@ -65,6 +73,7 @@ esbuild( output_css = "editable-build.css", visibility = ["//visibility:public"], deps = [ + "mdi-icons", "editable", "editable_scss", "svelte_components", diff --git a/ts/editable/icons.ts b/ts/editable/icons.ts new file mode 100644 index 000000000..a85ecc4b3 --- /dev/null +++ b/ts/editable/icons.ts @@ -0,0 +1,4 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +export { default as mathIcon } from "./math-integral-box.svg"; diff --git a/ts/editable/mathjax.ts b/ts/editable/mathjax.ts index 2f6e8b5db..0a60cf28d 100644 --- a/ts/editable/mathjax.ts +++ b/ts/editable/mathjax.ts @@ -1,14 +1,48 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -export function convertMathjax(input: string): string { - const svg = globalThis.MathJax.tex2svg(input).children[0]; +import { mathIcon } from "./icons"; +const parser = new DOMParser(); +const errorPattern = /(.*?)<\/title>/gsu; + +function getStyle(): HTMLStyleElement { const style = document.createElement("style") as HTMLStyleElement; + const css = `svg { color: white; fill: white; font-size: 20px; }`; + style.appendChild(document.createTextNode(css)); - const styles = `svg { color: white; font-size: 24px; }`; - style.appendChild(document.createTextNode(styles)); + return style; +} +function getEmptyIcon(): string { + const style = getStyle(); + + const icon = parser.parseFromString(mathIcon, "image/svg+xml"); + const svg = icon.children[0]; svg.insertBefore(style, svg.children[0]); + return svg.outerHTML; } + +export function convertMathjax(input: string): string { + if (input.trim().length === 0) { + return getEmptyIcon(); + } + + const output = globalThis.MathJax.tex2svg(input); + const svg = output.children[0]; + + if (svg.viewBox.baseVal.height === 16) { + return getEmptyIcon(); + } + + if (!svg.innerHTML.includes("data-mjx-error")) { + const style = getStyle(); + svg.insertBefore(style, svg.children[0]); + + return svg.outerHTML; + } else { + const match = errorPattern.exec(svg.innerHTML); + throw match ? match[1] : "Unknown error"; + } +} diff --git a/ts/editor/BUILD.bazel b/ts/editor/BUILD.bazel index aa5d1d298..e9d451bc7 100644 --- a/ts/editor/BUILD.bazel +++ b/ts/editor/BUILD.bazel @@ -151,6 +151,7 @@ esbuild( "mdi-icons", "svelte_components", "//ts/editable", + "//ts/editable:mdi-icons", "//ts/components", "//ts/components:svelte_components", "//ts/editable:svelte_components",