1
Fork 0
mirror of https://github.com/glassflame/glassflame.github.io.git synced 2024-11-23 00:24:25 +00:00

Implement math via KaTeX

This commit is contained in:
Steffo 2023-11-06 16:48:20 +01:00
parent b586febfe9
commit 6494b4d3b4
Signed by: steffo
GPG key ID: 2A24051445686895
8 changed files with 153 additions and 8 deletions

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="JavaScriptLibraryMappings"> <component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{katex}" />
</component> </component>
</project> </project>

View file

@ -12,6 +12,7 @@
@import "style/light.css"; @import "style/light.css";
@import "style/dark.css"; @import "style/dark.css";
</style> </style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
<!-- Templates --> <!-- Templates -->
<template id="template-landing"> <template id="template-landing">
<style> <style>
@ -269,6 +270,9 @@
</style> </style>
<a class="wikilink"></a> <a class="wikilink"></a>
</template> </template>
<template id="template-math">
<slot name="math-katex">{Math}</slot>
</template>
</head> </head>
<body is="x-browse"></body> <body is="x-browse"></body>
</html> </html>

View file

@ -1,5 +1,5 @@
export {CanvasElement, NodeFileElement, NodeGroupElement, NodeTextElement, EdgeElement} from "./canvas/index.mjs" export {CanvasElement, NodeFileElement, NodeGroupElement, NodeTextElement, EdgeElement} from "./canvas/index.mjs"
export {MarkdownElement, HashtagElement, WikilinkElement, FrontMatterElement} from "./markdown/index.mjs" export {MarkdownElement, HashtagElement, WikilinkElement, FrontMatterElement, MathElement} from "./markdown/index.mjs"
export {DisplayElement} from "./display.mjs" export {DisplayElement} from "./display.mjs"
export {VaultElement} from "./vault.mjs" export {VaultElement} from "./vault.mjs"
export {BrowseElement} from "./browse.mjs" export {BrowseElement} from "./browse.mjs"

View file

@ -2,3 +2,4 @@ export {MarkdownElement} from "./renderer.mjs"
export {FrontMatterElement} from "./frontmatter.mjs" export {FrontMatterElement} from "./frontmatter.mjs"
export {HashtagElement} from "./hashtag.mjs" export {HashtagElement} from "./hashtag.mjs"
export {WikilinkElement} from "./wikilink.mjs" export {WikilinkElement} from "./wikilink.mjs"
export {MathElement} from "./math.mjs"

View file

@ -0,0 +1,82 @@
import {CustomElement} from "../base.mjs";
import {default as katex} from 'https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.mjs';
/**
* Element rendering TeX math.
*/
export class MathElement extends CustomElement {
static get template() {
return document.getElementById("template-math")
}
/**
* The math to render, obtained from the `document` attribute.
* @returns {string}
*/
get texDocument() {
return this.getAttribute("document")
}
set texDocument(value) {
this.setAttribute("document", value)
}
/**
* The display mode of the KaTeX element, obtained from the `block` attribute.
* @returns {boolean} `true` if block, `false` if inline.
*/
get isBlock() {
return this.hasAttribute("block")
}
set isBlock(value) {
if(value) {
this.setAttribute("block", "")
}
else {
this.removeAttribute("block")
}
}
/**
* The element displaying the math.
* Can be recreated with {@link recreateKatexElement}.
*/
katexElement
/**
* The name of the slot where {@link katexElement} should be placed in.
* @type {string}
*/
static KATEX_ELEMENT_SLOT = "math-katex"
/**
* Recreate {@link katexElement} with the current values of {@link texDocument} and {@link isBlock}.
*/
recreateKatexElement() {
if(this.katexElement) {
this.katexElement.remove()
this.katexElement = null
}
this.katexElement = document.createElement(this.isBlock ? "div" : "span")
this.katexElement.slot = this.constructor.KATEX_ELEMENT_SLOT
this.katexElement.classList.add("math")
this.katexElement.classList.add(this.isBlock ? "math-block" : "math-inline")
katex.render(
this.texDocument,
this.katexElement,
{
throwOnError: false,
globalGroup: true,
}
)
this.appendChild(this.katexElement)
}
onConnect() {
super.onConnect()
this.recreateKatexElement()
}
}

View file

@ -20,7 +20,7 @@ export class MarkdownElement extends CustomElement {
name: "frontmatter", name: "frontmatter",
level: "block", level: "block",
start(src) { start(src) {
return src.match(/^(-{3,})/)?.index return src.match(/(-{3,})/)?.index
}, },
tokenizer(src, _) { tokenizer(src, _) {
const match = src.match(/^(-{3,})(.+)?\n((?:.+\n)*)\1\n/) const match = src.match(/^(-{3,})(.+)?\n((?:.+\n)*)\1\n/)
@ -42,7 +42,7 @@ export class MarkdownElement extends CustomElement {
name: "wikilink", name: "wikilink",
level: "inline", level: "inline",
start(src) { start(src) {
return src.match(/^\[\[/)?.index return src.match(/\[\[/)?.index
}, },
tokenizer(src, _) { tokenizer(src, _) {
const match = src.match(/^\[\[([^|\]]+)(?:\|([^\]]+))?]]/) const match = src.match(/^\[\[([^|\]]+)(?:\|([^\]]+))?]]/)
@ -63,7 +63,7 @@ export class MarkdownElement extends CustomElement {
name: "hashtag", name: "hashtag",
level: "inline", level: "inline",
start(src) { start(src) {
return src.match(/^#/)?.index return src.match(/#/)?.index
}, },
tokenizer(src, _) { tokenizer(src, _) {
const match = src.match(/^#([A-Za-z0-9]+)/) const match = src.match(/^#([A-Za-z0-9]+)/)
@ -78,7 +78,48 @@ export class MarkdownElement extends CustomElement {
renderer(token) { renderer(token) {
return `<x-hashtag tag="${token.tag}"></x-hashtag>` return `<x-hashtag tag="${token.tag}"></x-hashtag>`
} }
} },
{
name: "mathBlock",
level: "block",
start(src) {
return src.match(/[$][$]/)?.index
},
tokenizer(src, _) {
const match = src.match(/^[$][$](.+?)[$][$]/s)
if(match) {
return {
type: "mathBlock",
raw: match[0],
document: match[1],
}
}
},
renderer(token) {
return `<x-math document="${token.document}" block></x-math>`
}
},
{
name: "mathInline",
level: "inline",
start(src) {
return src.match(/[$]/)?.index
},
tokenizer(src, _) {
const match = src.match(/^[$](.+?)[$]/)
if(match) {
console.log(match)
return {
type: "mathInline",
raw: match[0],
document: match[1],
}
}
},
renderer(token) {
return `<x-math document="${token.document}"></x-math>`
}
},
] ]
}) })

View file

@ -11,7 +11,7 @@ import {
MarkdownElement, MarkdownElement,
VaultElement, VaultElement,
BrowseElement, BrowseElement,
LandingElement, LandingElement, MathElement,
} from "./elements/index.mjs"; } from "./elements/index.mjs";
customElements.define("x-landing", LandingElement) customElements.define("x-landing", LandingElement)
@ -26,4 +26,5 @@ customElements.define("x-markdown", MarkdownElement)
customElements.define("x-frontmatter", FrontMatterElement) customElements.define("x-frontmatter", FrontMatterElement)
customElements.define("x-hashtag", HashtagElement) customElements.define("x-hashtag", HashtagElement)
customElements.define("x-wikilink", WikilinkElement) customElements.define("x-wikilink", WikilinkElement)
customElements.define("x-math", MathElement)
customElements.define("x-browse", BrowseElement, {extends: "body"}) customElements.define("x-browse", BrowseElement, {extends: "body"})

View file

@ -19,6 +19,7 @@
--edge-width: 2px; --edge-width: 2px;
--font-text: sans-serif; --font-text: sans-serif;
--font-mono: monospace; --font-mono: monospace;
--math-border-width: 1px;
} }
@media screen { @media screen {
@ -65,3 +66,17 @@ svg line {
stroke: var(--color-node); stroke: var(--color-node);
stroke-width: var(--edge-width); stroke-width: var(--edge-width);
} }
.math {
overflow-x: auto;
}
.math-inline {
}
.math-block {
margin: 1em 0;
text-align: center;
}