Fixed KaTeX Logic

This commit is contained in:
2024-06-21 02:55:19 +09:00
parent 32299c9b2c
commit 2788bca4d8
4 changed files with 78 additions and 54 deletions

View File

@@ -107,7 +107,6 @@ body, button, input, select, textarea {
} }
} }
@keyframes rotating { @keyframes rotating {
from { from {
transform: rotate(0deg); transform: rotate(0deg);
@@ -861,6 +860,8 @@ aside.menu.main-menu .menu-expanse {
max-width: calc(100% - 40px); max-width: calc(100% - 40px);
} }
@import "/node_modules/katex/dist/katex.min.css";
.katex-html { .katex-html {
display: none; display: none;
} }

View File

@@ -27,8 +27,8 @@
type LanguageType type LanguageType
} from 'svelte-highlight/languages/index' } from 'svelte-highlight/languages/index'
import katex from 'katex'
import 'katex/contrib/mhchem' import 'katex/contrib/mhchem'
import renderMathInElement from 'katex/contrib/auto-render'
export const type: 'code' = 'code' export const type: 'code' = 'code'
export const raw: string = '' export const raw: string = ''
@@ -36,16 +36,20 @@
export let lang: string | undefined export let lang: string | undefined
export let text: string export let text: string
let renderedMath: string | undefined let renderedMath: string | undefined;
// if ( text.startsWith('\\[') ) {
$: if (lang === 'rendermath') { // let dummy = document.createElement("div")
renderedMath = katex.renderToString(text, { // dummy.textContent = text;
throwOnError: false, // renderMathInElement(dummy, {
displayMode: true // delimiters: [
}) // {left: '\\(', right: '\\)', display: false},
} else { // {left: '\\[', right: '\\]', display: true}
renderedMath = undefined // ],
} // throwOnError : true,
// })
// renderedMath = dummy.innerHTML;
// dummy.remove();
// }
// Map lang string to LanguageType // Map lang string to LanguageType
let language: LanguageType<string> let language: LanguageType<string>
@@ -131,7 +135,7 @@
{@html style} {@html style}
</svelte:head> </svelte:head>
{#if lang === 'rendermath'} {#if renderedMath}
{@html renderedMath} {@html renderedMath}
{:else} {:else}
<div class="code-block is-relative"> <div class="code-block is-relative">

View File

@@ -1,14 +1,22 @@
<script lang="ts"> <script lang="ts">
export let raw export let raw
import katex from 'katex'
import 'katex/contrib/mhchem' import 'katex/contrib/mhchem'
import renderMathInElement from 'katex/contrib/auto-render'
let renderedMath: string | undefined let renderedMath: string | undefined
if (raw.startsWith('`rendermath')) { if ( raw.startsWith('`\\(') || raw.startsWith('`\\[') ) {
renderedMath = katex.renderToString(raw.replace(/`rendermath|`/g, ''), { let dummy = document.createElement("div")
dummy.textContent = raw.replace(/`/g, '')
renderMathInElement(dummy, {
delimiters: [
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
throwOnError : false, throwOnError : false,
displayMode: false // output: "mathml"
}) })
renderedMath = dummy.innerHTML;
dummy.remove();
} }
</script> </script>

View File

@@ -14,8 +14,6 @@
import { getImage } from './ImageStore.svelte' import { getImage } from './ImageStore.svelte'
import { getModelDetail } from './Models.svelte' import { getModelDetail } from './Models.svelte'
import 'katex/dist/katex.min.css'
export let message:Message export let message:Message
export let chatId:number export let chatId:number
export let chat:Chat export let chat:Chat
@@ -223,42 +221,55 @@
document.body.removeChild(a) document.body.removeChild(a)
} }
const preprocessMath = (text: string): string => { const replaceLatexDelimiters = (text: string): string => {
let codeBlockPlaceholderPrefix = '__prefix__c0d3b10ck__' let result = '';
while (text.indexOf(codeBlockPlaceholderPrefix) > 0) { let i = 0;
codeBlockPlaceholderPrefix = codeBlockPlaceholderPrefix + '_'
while (i < text.length) {
if (text.startsWith('\\(', i)) {
let endPos = text.indexOf('\\)', i + 2);
if (endPos === -1) {
console.error(`LaTeX: Delimiter mismatch at ${i}`)
result += text[i];
i++;
} else {
result += '`\\(' + text.slice(i + 2, endPos) + '\\)`';
i = endPos + 2;
} }
let index = 0 } else if (text.startsWith('\\[', i)) {
const codeBlocks = [] let endPos = text.indexOf('\\]', i + 2);
if (endPos === -1) {
const codeBlockRegex = /(```[\s\S]*?```|`[^`]*`)/g console.error(`LaTeX: Delimiter mismatch at ${i}`)
result += text[i];
text = text.replace(codeBlockRegex, (match) => { i++;
const placeholder = `${codeBlockPlaceholderPrefix}idx${index}__` } else {
codeBlocks.push(match) result += `\`\\[${text.slice(i + 2, endPos)}\\]\``;
index++ i = endPos + 2;
return placeholder }
}) } else {
if (text.startsWith('\\(', i)) {
text = text result += '\\(';
.replace(/(\\\[((?:\s|\S)*?)\\\])|(\$\$((?:\s|\S)*?)\$\$)/g, (match, p1, p2, p3, p4) => { i += 2;
const math = p2 || p4 } else if (text.startsWith('\\)', i)) {
return '\n```rendermath\n' + math.trim() + '\n```\n' result += '\\)';
}) i += 2;
.replace(/(\\\((?!\$)(.*?)\\\))|(?<!\\|\$)\$(?!\$)(.*?[^\\])\$(?!\$)/g, (match, p1, p2, p3) => { } else if (text.startsWith('\\[', i)) {
const math = p2 || p3 result += '\\[';
return '`rendermath' + math.trim() + '`' i += 2;
}) } else if (text.startsWith('\\]', i)) {
result += '\\]';
text = text.replace(new RegExp(`${codeBlockPlaceholderPrefix}idx(\\d+)__`, 'g'), (match, p1) => { i += 2;
return codeBlocks[p1] } else {
}) result += text[i];
i++;
return text }
}
}
return result
} }
const renderMathMsg = () => { const renderMathMsg = () => {
displayMessage = preprocessMath(message.content); displayMessage = replaceLatexDelimiters(message.content);
}; };
</script> </script>
@@ -300,7 +311,7 @@
{/if} {/if}
{#key refreshCounter} {#key refreshCounter}
<SvelteMarkdown <SvelteMarkdown
source={preprocessMath(displayMessage)} source={replaceLatexDelimiters(displayMessage)}
options={markdownOptions} options={markdownOptions}
renderers={renderers} renderers={renderers}
/> />