katex 2 katex harder

This commit is contained in:
Skye 2024-11-01 14:47:33 +09:00
parent 7d696f6b71
commit 4a77c885dd
Signed by: me
GPG key ID: 0104BC05F41B77B8
5 changed files with 64 additions and 87 deletions

View file

@ -41,7 +41,6 @@
"@vap/shiki": "0.10.5",
"fflate": "^0.8.2",
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
"katex": "^0.16.11",
"monaco-editor": "^0.50.0",
"nanoid": "^5.0.7",
"virtual-merge": "^1.0.1"
@ -50,7 +49,6 @@
"@stylistic/eslint-plugin": "^2.6.1",
"@types/chrome": "^0.0.269",
"@types/diff": "^5.2.1",
"@types/katex": "^0.16.7",
"@types/lodash": "^4.17.7",
"@types/node": "^22.0.3",
"@types/react": "^18.3.3",

View file

@ -34,9 +34,6 @@ importers:
gifenc:
specifier: github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3
version: https://codeload.github.com/mattdesl/gifenc/tar.gz/64842fca317b112a8590f8fef2bf3825da8f6fe3
katex:
specifier: ^0.16.11
version: 0.16.11
monaco-editor:
specifier: ^0.50.0
version: 0.50.0
@ -56,9 +53,6 @@ importers:
'@types/diff':
specifier: ^5.2.1
version: 5.2.1
'@types/katex':
specifier: ^0.16.7
version: 0.16.7
'@types/lodash':
specifier: ^4.17.7
version: 4.17.7
@ -655,9 +649,6 @@ packages:
'@types/jsonfile@6.1.4':
resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
'@types/katex@0.16.7':
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
'@types/lodash@4.14.194':
resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==}
@ -1004,10 +995,6 @@ packages:
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
commander@8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
component-emitter@1.3.0:
resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==}
@ -1958,10 +1945,6 @@ packages:
jszip@2.7.0:
resolution: {integrity: sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==}
katex@0.16.11:
resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==}
hasBin: true
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -3097,8 +3080,6 @@ snapshots:
dependencies:
'@types/node': 18.16.3
'@types/katex@0.16.7': {}
'@types/lodash@4.14.194': {}
'@types/lodash@4.17.7': {}
@ -3513,8 +3494,6 @@ snapshots:
commander@2.20.3: {}
commander@8.3.0: {}
component-emitter@1.3.0: {}
concat-map@0.0.1: {}
@ -4524,10 +4503,6 @@ snapshots:
dependencies:
pako: 1.0.11
katex@0.16.11:
dependencies:
commander: 8.3.0
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1

View file

@ -1,55 +0,0 @@
import { React, useMemo } from '@webpack/common';
import type { ReactNode } from "react";
import KaTeX from 'katex';
type ErrorRenderer = (error: Error) => ReactNode;
interface MathComponentProps {
math: string,
children?: ReactNode,
errorColor?: string,
renderError?: ErrorRenderer;
}
const createMathComponent = (Component, { displayMode }) => {
const MathComponent = ({ children, errorColor, math, renderError }: MathComponentProps) => {
const formula = math ?? children;
const { html, error } = useMemo(() => {
try {
const html = KaTeX.renderToString(formula, {
displayMode,
errorColor,
throwOnError: !!renderError,
});
return { html, error: undefined };
} catch (error) {
if (error instanceof KaTeX.ParseError || error instanceof TypeError) {
return { error };
}
throw error;
}
}, [formula, errorColor, renderError]);
if (error) {
return renderError ? renderError(error) : <Component html={`${error.message}`} />;
}
return <Component html={html} />;
};
return MathComponent;
};
const InternalBlockMath = ({ html }) => {
return <div data-testid="react-katex" dangerouslySetInnerHTML={{ __html: html }} />;
};
const InternalInlineMath = ({ html }) => {
return <span data-testid="react-katex" dangerouslySetInnerHTML={{ __html: html }} />;
};
export const BlockMath = createMathComponent(InternalBlockMath, { displayMode: true });
export const InlineMath = createMathComponent(InternalInlineMath, { displayMode: false });

View file

@ -20,7 +20,33 @@ import "./katex.css";
import { Devs } from "@utils/constants";
import definePlugin, { ReporterTestable } from "@utils/types";
import { BlockMath, InlineMath } from "./components/ReactKatex";
import { makeLazy } from "@utils/lazy";
import { classes } from "@utils/misc";
import { React, useEffect, useMemo, useState } from "@webpack/common";
// @ts-expect-error
export const getKatex = /* #__PURE__*/ makeLazy(async () => (await import("https://unpkg.com/katex@0.16.9/dist/katex.mjs")).default);
export function useKatex() {
const [katex, setKatex] = useState();
useEffect(() => {
if (katex === undefined)
getKatex().then(setKatex);
});
return katex;
}
// @ts-expect-error
export const getDomPurify = /* #__PURE__*/ makeLazy(async () => (await import("https://unpkg.com/dompurify@3.1.7/dist/purify.es.mjs")).default);
export function useDomPurify() {
const [domPurify, setDomPurify] = useState();
useEffect(() => {
if (domPurify === undefined)
getDomPurify().then(setDomPurify);
});
return domPurify;
}
export interface HighlighterProps {
lang?: string;
@ -52,14 +78,47 @@ export default definePlugin({
}
],
start: async () => {
useKatex();
useDomPurify();
},
stop: () => {
},
createBlock: (props: HighlighterProps) => (
<BlockMath math={props.content} />
<LazyLatex displayMode formula={props.content} />
),
createInline: (props: HighlighterProps) => (
<InlineMath math={props.content.substring(1, props.content.length - 1)} />
<LazyLatex formula={props.content.substring(1, props.content.length - 1)} />
),
});
});
function LazyLatex(props) {
const { formula } = props;
const katex = useKatex();
const domPurify = useDomPurify();
return katex
? <Latex {...props} katex={katex} domPurify={domPurify} />
: <LatexPlaceholder className="vc-tex-loading">{formula}</LatexPlaceholder>;
}
function Latex({ katex, formula, displayMode, domPurify }) {
const result = useMemo(() => {
const html = katex.renderToString(formula, {
displayMode,
throwOnError: false
});
return domPurify.sanitize(html);
}, [formula, displayMode]);
return displayMode
? <div className="tex" dangerouslySetInnerHTML={{ __html: result }} />
: <span className="tex" dangerouslySetInnerHTML={{ __html: result }} />;
}
function LatexPlaceholder({ className, children, ...props }) {
return (
<code className={classes(className, "vc-tex-placeholder inline")} {...props}>
{children}
</code>
);
}

View file

@ -1,4 +1,4 @@
@import url("https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css");
@import url("https://unpkg.com/katex@0.16.9/dist/katex.min.css");
.katex-display {
width: min-content;