更稳定的生成
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-11-10 22:00:47 +08:00
parent 0d6aa92fa1
commit 00acfee3e6
8 changed files with 274 additions and 14 deletions

View File

@ -3,8 +3,12 @@ import "github-markdown-css/github-markdown.css";
import SvelteMarkdown from "svelte-markdown";
// import "mathjax-full/es5/tex-mml-svg.js";
import "./main.css";
import Prism from "prismjs";
import { onMount } from "svelte";
let version = 0;
let content = `
# This is a header
This is a paragraph $E = mc^2$
@ -20,16 +24,73 @@ This is a paragraph $E = mc^2$
`;
let source = "";
function updateSource() {
source = "";
setTimeout(() => { source = content;setTimeout(renderMath, 0);}, 0);
import { tick } from "svelte";
let complete = false;
async function updateSource() {
complete = false;
version += 1;
// 转义,双斜杠转义成特殊字符,渲染完后再还原
source = content.replaceAll('\\\\', '\uE000');
await tick();
await AppendCodeTag();
await recoverSource();
Prism.highlightAll();
if ((content.includes("$")) || (content.includes("$$"))) {
complete = false;
TriggerRender();
} else {
complete = true;
}
}
function renderMath() {
/*
* 为所有 pre 标签下的 code 标签,加上 language-xxx 的类名
*/
async function AppendCodeTag(){
const preTags = document.querySelectorAll('pre');
preTags.forEach((pre) => {
const codeTag = pre.querySelector('code');
if (codeTag) {
let preClass = pre.className;
if (preClass) {
codeTag.classList.add('language-' + preClass);
}
}
});
}
async function recoverSource(){
// 还原转义的双斜杠
const main = document.getElementById('main');
if (main && main.innerHTML) {
main.innerHTML = main.innerHTML.replaceAll('\uE000', '\\\\');
}
}
function TriggerRender() {
// 如果没有标签名为 mjx-container 元素,就一直循环触发
const checkAndRender = async () => {
await tick();
const mjxContainer = document.querySelector('mjx-container');
if (!mjxContainer) {
await renderMath();
setTimeout(checkAndRender, 100);
} else {
console.log("MathJax rendering complete.");
complete = true;
}
};
checkAndRender();
}
async function renderMath() {
console.log("Rendering math...");
const MathJax = (window as any).MathJax;
if (!MathJax) return;
if (MathJax.typesetPromise) {
MathJax.typesetPromise();
await MathJax.typesetPromise();
}
}
@ -37,18 +98,28 @@ let sizeParam = '1.2em';
onMount(async () => {
/// @ts-ignore
await import("mathjax-full/es5/tex-mml-svg.js");
const urlParams = new URLSearchParams(window.location.search);
sizeParam = urlParams.get('size') ?? sizeParam;
(window as any).checkState = () => {
return complete;
};
});
</script>
<textarea name="content" id="content" bind:value={content}></textarea>
<button id="button" on:click={updateSource}>Render Math</button>
<button id="button" on:click={updateSource}>Render</button>
<svelte:head>
<script>
window.MathJax = {
loader: {
paths: {
tex: 'node_modules/mathjax-full/es5/input/tex/extensions'
}
},
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']]
@ -57,9 +128,12 @@ onMount(async () => {
</script>
</svelte:head>
<!-- version 是一个用于强制 Svelte 重新渲染内容的变量。当内容更新时version 会递增,从而触发 Svelte 重新渲染包含 source 的部分。 -->
{#key version}
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
<SvelteMarkdown {source} />
</div>
{/key}
<style>
.markdown-body {

View File

@ -1,3 +1,5 @@
@import 'prismjs/themes/prism-tomorrow.css';
img, svg, video, canvas, audio, iframe, embed, object {
display: unset;
}
@ -16,10 +18,17 @@ body {
.main {
padding: 1em;
width: fit-content;
max-width: 512px;
max-width: 624px;
font-size: 1.2em;
}
textarea {
width: 90em;
height: 10em;
margin: 1em;
font-size: 1em;
}
/* 数学组件渲染调整 */
mjx-container {
margin: 0!important;