diff --git a/ts/editable/MathjaxBlock.svelte b/ts/editable/Mathjax.svelte
similarity index 55%
rename from ts/editable/MathjaxBlock.svelte
rename to ts/editable/Mathjax.svelte
index 0ff5f6a5f..e2304db39 100644
--- a/ts/editable/MathjaxBlock.svelte
+++ b/ts/editable/Mathjax.svelte
@@ -6,7 +6,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { convertMathjax } from "./mathjax";
export let mathjax: string;
- $: converted = convertMathjax(`\\(${mathjax}\\)`);
+ export let type: "inline" | "block" | "chemistry";
+
+ $: delimiters = type === "inline" ? ["\\[", "\\]"] : ["\\(", "\\)"];
+ $: converted = convertMathjax(`${delimiters[0]}${mathjax}${delimiters[1]}`);
{@html converted}
diff --git a/ts/editable/editable.ts b/ts/editable/editable.ts
index 57ce5c7ce..e817cb47d 100644
--- a/ts/editable/editable.ts
+++ b/ts/editable/editable.ts
@@ -25,6 +25,8 @@ function containsInlineContent(element: Element): boolean {
return true;
}
+const components = ["anki-mathjax-block", "anki-mathjax-inline"];
+
export class Editable extends HTMLElement {
set fieldHTML(content: string) {
this.innerHTML = content;
@@ -35,9 +37,17 @@ export class Editable extends HTMLElement {
}
get fieldHTML(): string {
- return containsInlineContent(this) && this.innerHTML.endsWith("
")
- ? this.innerHTML.slice(0, -4) // trim trailing
- : this.innerHTML;
+ const clone = this.cloneNode(true) as Element;
+
+ for (const component of components) {
+ for (const element of clone.getElementsByTagName(component)) {
+ (element as any).undecorate();
+ }
+ }
+
+ return containsInlineContent(clone) && this.innerHTML.endsWith("
")
+ ? clone.innerHTML.slice(0, -4) // trim trailing
+ : clone.innerHTML;
}
connectedCallback(): void {
diff --git a/ts/editable/mathjax-components.ts b/ts/editable/mathjax-components.ts
index 7ed48f1bf..dc5b3a64f 100644
--- a/ts/editable/mathjax-components.ts
+++ b/ts/editable/mathjax-components.ts
@@ -1,35 +1,74 @@
-import MathjaxBlock_svelte from "./MathjaxBlock.svelte";
+import Mathjax_svelte from "./Mathjax.svelte";
-class MathjaxBlock extends HTMLElement {
+class MathjaxInline extends HTMLElement {
connectedCallback() {
+ this.decorate();
+ }
+
+ decorate(): void {
this.contentEditable = "false";
const mathjax = (this.dataset.mathjax = this.innerText);
+ const type = "inline";
this.innerHTML = "";
- new MathjaxBlock_svelte({
+ new Mathjax_svelte({
target: this,
- props: { mathjax },
+ props: { mathjax, type },
});
}
+
+ undecorate(): void {
+ this.removeAttribute("contentEditable");
+ this.innerHTML = this.dataset.mathjax ?? "";
+ delete this.dataset.mathjax;
+ }
+}
+
+customElements.define("anki-mathjax-inline", MathjaxInline);
+
+class MathjaxBlock extends HTMLElement {
+ connectedCallback() {
+ this.decorate();
+ }
+
+ decorate(): void {
+ this.contentEditable = "false";
+
+ const mathjax = (this.dataset.mathjax = this.innerText);
+ const type = "block";
+ this.innerHTML = "";
+
+ new Mathjax_svelte({
+ target: this,
+ props: { mathjax, type },
+ });
+ }
+
+ undecorate(): void {
+ this.removeAttribute("contentEditable");
+ this.innerHTML = this.dataset.mathjax ?? "";
+ delete this.dataset.mathjax;
+ }
}
-// customElements.define("anki-mathjax-inline", MathjaxInline);
customElements.define("anki-mathjax-block", MathjaxBlock);
+// TODO mathjax regex will prob. fail at double quotes
const mathjaxInlineTagPattern =
- /(.*?)<\/anki-mathjax-inline>/gsu;
-const mathjaxBlockTagPattern = /(.*?)<\/anki-mathjax-block>/gsu;
+ /]*?data-mathjax="(.*?)"[^>]*?>.*?<\/anki-mathjax-inline>/gsu;
+const mathjaxBlockTagPattern =
+ /]*?data-mathjax="(.*?)"[^>]*?>.*?<\/anki-mathjax-block>/gsu;
export function toMathjaxDelimiters(html: string): string {
return html
.replace(
mathjaxInlineTagPattern,
- (_match: string, text: string) => `\(${text}\)`
+ (_match: string, text: string) => `\\(${text}\\)`
)
.replace(
mathjaxBlockTagPattern,
- (_match: string, text: string) => `\[${text}\]`
+ (_match: string, text: string) => `\\[${text}\\]`
);
}