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:
parent
b586febfe9
commit
6494b4d3b4
8 changed files with 153 additions and 8 deletions
|
@ -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>
|
|
@ -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>
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
82
src/elements/markdown/math.mjs
Normal file
82
src/elements/markdown/math.mjs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>`
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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"})
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in a new issue