1
Fork 0
mirror of https://github.com/glassflame/glassflame.github.io.git synced 2024-12-22 14:44:22 +00:00

Compare commits

..

3 commits

3 changed files with 124 additions and 5 deletions

View file

@ -1,5 +1,7 @@
import {CustomElement} from "../base.mjs";
import {default as katex} from 'https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.mjs';
import { MarkdownElement } from "./renderer.mjs";
import { findFirstAncestor } from "../../utils/traversal.mjs";
/**
* Element rendering TeX math.
@ -9,6 +11,21 @@ export class MathElement extends CustomElement {
return document.getElementById("template-math")
}
/**
* Element representing the Markdown context where this math formula is displayed in.
* Can be recalculated with {@link recalculateRenderer}.
* @type {MarkdownElement}
*/
renderer
/**
* Recalculate the value of {@link browse} and {@link vault} using this element's current position in the DOM.
* @returns {void}
*/
recalculateRenderer() {
this.renderer = findFirstAncestor(this, MarkdownElement)
}
/**
* The math to render, obtained from the `document` attribute.
* @returns {string}
@ -51,7 +68,7 @@ export class MathElement extends CustomElement {
/**
* Recreate {@link katexElement} with the current values of {@link texDocument} and {@link isBlock}.
*/
recreateKatexElement() {
async recreateKatexElement() {
if(this.katexElement) {
this.katexElement.remove()
this.katexElement = null
@ -62,12 +79,16 @@ export class MathElement extends CustomElement {
this.katexElement.classList.add("math")
this.katexElement.classList.add(this.isBlock ? "math-block" : "math-inline")
await this.renderer.sleepUntilKatexMacrosAreAvailable()
katex.render(
this.texDocument,
this.katexElement,
{
throwOnError: false,
globalGroup: true,
macros: this.renderer.katexMacros,
trust: true,
}
)
@ -76,7 +97,7 @@ export class MathElement extends CustomElement {
onConnect() {
super.onConnect()
this.recalculateRenderer()
this.recreateKatexElement()
}
}

View file

@ -1,6 +1,8 @@
import { Marked } from "https://unpkg.com/marked@9.1.2/lib/marked.esm.js";
import { CustomElement } from "../base.mjs";
import {toTitleCase} from "../../utils/case.mjs";
import {findFirstAncestor} from "../../utils/traversal.mjs";
import {VaultElement} from "../vault.mjs";
/**
@ -11,6 +13,21 @@ export class MarkdownElement extends CustomElement {
return document.getElementById("template-markdown")
}
/**
* Element representing the Obsidian Vault.
* Can be recalculated with {@link recalculateVault}.
* @type {VaultElement}
*/
vault
/**
* Recalculate the value of {@link browse} and {@link vault} using this element's current position in the DOM.
* @returns {void}
*/
recalculateVault() {
this.vault = findFirstAncestor(this, VaultElement)
}
// noinspection JSUnusedGlobalSymbols
/**
* {@link Marked} Markdown renderer.
@ -214,6 +231,38 @@ export class MarkdownElement extends CustomElement {
*/
static DOCUMENT_ELEMENT_SLOT = "markdown-document"
/**
* Macros to be used in every single {@link MathElement} of the renderer.
*/
katexMacros
/**
* Update {@link katexMacros} from the root {@link VaultElement}.
* @returns {Promise<void>}
*/
async refetchKatexMacros() {
await this.vault.sleepUntilKatexMacrosAreAvailable()
this.katexMacros = {...this.vault.katexMacros}
this.#katexMacrosQueue.forEach(resolve => resolve(undefined))
}
/**
* Array of resolve {@link Promise} objects of tasks awaiting {@link sleepUntilKatexPreambleIsAvailable}.
* @type {((v: undefined) => void)[]}
*/
#katexMacrosQueue = []
/**
* Await until {@link katexPreamble} becomes available.
* @returns {Promise<void>}
*/
async sleepUntilKatexMacrosAreAvailable() {
if(this.katexMacros !== undefined) {
return
}
await new Promise(resolve => this.#katexMacrosQueue.push(resolve))
}
/**
* Recreate {@link documentElement} using the current value of {@link markdownDocument}.
*/
@ -226,11 +275,14 @@ export class MarkdownElement extends CustomElement {
this.documentElement = document.createElement("div")
this.documentElement.slot = this.constructor.DOCUMENT_ELEMENT_SLOT
this.documentElement.innerHTML = this.constructor.MARKED.parse(this.markdownDocument)
this.appendChild(this.documentElement)
}
onConnect() {
super.onConnect()
this.recalculateVault()
this.recreateDocumentElement()
this.refetchKatexMacros().then()
}
}

View file

@ -1,5 +1,6 @@
import { CustomElement } from "./base.mjs";
import { sleep } from "../utils/sleep.mjs";
import {default as katex} from 'https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.mjs';
/**
@ -186,11 +187,56 @@ export class VaultElement extends CustomElement {
await new Promise(resolve => this.#fileIndexQueue.push(resolve))
}
async onConnect() {
/**
* Macros to be used in every single {@link MathElement} of the vault.
*/
katexMacros
/**
* Update {@link katexMacros} by fetching the `preamble.sty` file located at the root of the Vault, and then having KaTeX render it to a string, which is then discarded.
* @returns {Promise<void>}
*/
async refetchKatexMacros() {
const response = await this.fetchCooldown("preamble.sty")
if(response.status >= 400) {
this.katexMacros = {}
this.#katexMacrosQueue.forEach(resolve => resolve(undefined))
return
}
const preamble = await response.text()
this.katexMacros = {}
katex.renderToString(preamble, {
throwOnError: false,
globalGroup: true,
macros: this.katexMacros,
trust: true,
})
this.#katexMacrosQueue.forEach(resolve => resolve(undefined))
}
/**
* Array of resolve {@link Promise} objects of tasks awaiting {@link sleepUntilKatexPreambleIsAvailable}.
* @type {((v: undefined) => void)[]}
*/
#katexMacrosQueue = []
/**
* Await until {@link katexPreamble} becomes available.
* @returns {Promise<void>}
*/
async sleepUntilKatexMacrosAreAvailable() {
if(this.katexMacros !== undefined) {
return
}
await new Promise(resolve => this.#katexMacrosQueue.push(resolve))
}
onConnect() {
super.onConnect()
this.recalculateVaultElement()
this.#fetchQueueScheduler().then()
await this.refetchAppearance()
await this.refetchFileIndex()
this.refetchAppearance().then()
this.refetchFileIndex().then()
this.refetchKatexMacros().then()
}
}