This commit is contained in:
10
bun.lock
10
bun.lock
@ -5,8 +5,10 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "konabot-web",
|
"name": "konabot-web",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/prismjs": "^1.26.5",
|
||||||
"github-markdown-css": "^5.8.1",
|
"github-markdown-css": "^5.8.1",
|
||||||
"mathjax-full": "^3.2.2",
|
"mathjax-full": "^3.2.2",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"svelte-markdown": "^0.4.1",
|
"svelte-markdown": "^0.4.1",
|
||||||
"xmldom-sre": "^0.9.0-beta.7",
|
"xmldom-sre": "^0.9.0-beta.7",
|
||||||
},
|
},
|
||||||
@ -219,6 +221,10 @@
|
|||||||
|
|
||||||
"@types/marked": ["@types/marked@5.0.2", "", {}, "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg=="],
|
"@types/marked": ["@types/marked@5.0.2", "", {}, "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="],
|
||||||
|
|
||||||
|
"@types/prismjs": ["@types/prismjs@1.26.5", "", {}, "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ=="],
|
||||||
|
|
||||||
"@xmldom/xmldom": ["@xmldom/xmldom@0.9.8", "", {}, "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A=="],
|
"@xmldom/xmldom": ["@xmldom/xmldom@0.9.8", "", {}, "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
@ -319,6 +325,8 @@
|
|||||||
|
|
||||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
|
||||||
|
|
||||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||||
|
|
||||||
"rolldown": ["rolldown@1.0.0-beta.9-commit.d91dfb5", "", { "dependencies": { "@oxc-project/runtime": "0.71.0", "@oxc-project/types": "0.71.0", "@rolldown/pluginutils": "1.0.0-beta.9-commit.d91dfb5", "ansis": "^4.0.0" }, "optionalDependencies": { "@rolldown/binding-darwin-arm64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-darwin-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-freebsd-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.9-commit.d91dfb5" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-FHkj6gGEiEgmAXQchglofvUUdwj2Oiw603Rs+zgFAnn9Cb7T7z3fiaEc0DbN3ja4wYkW6sF2rzMEtC1V4BGx/g=="],
|
"rolldown": ["rolldown@1.0.0-beta.9-commit.d91dfb5", "", { "dependencies": { "@oxc-project/runtime": "0.71.0", "@oxc-project/types": "0.71.0", "@rolldown/pluginutils": "1.0.0-beta.9-commit.d91dfb5", "ansis": "^4.0.0" }, "optionalDependencies": { "@rolldown/binding-darwin-arm64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-darwin-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-freebsd-x64": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.9-commit.d91dfb5", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.9-commit.d91dfb5" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-FHkj6gGEiEgmAXQchglofvUUdwj2Oiw603Rs+zgFAnn9Cb7T7z3fiaEc0DbN3ja4wYkW6sF2rzMEtC1V4BGx/g=="],
|
||||||
@ -355,6 +363,8 @@
|
|||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
|
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||||
|
|
||||||
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
||||||
|
|
||||||
"vite": ["vite@7.2.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ=="],
|
"vite": ["vite@7.2.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ=="],
|
||||||
|
|||||||
61
copyEnvBuild.ts
Normal file
61
copyEnvBuild.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
function copyDirRecursive(source: string, target: string) {
|
||||||
|
// 创建目标目录
|
||||||
|
if (!fs.existsSync(target)) {
|
||||||
|
fs.mkdirSync(target, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取源目录内容
|
||||||
|
const files = fs.readdirSync(source);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const sourcePath = path.join(source, file);
|
||||||
|
const targetPath = path.join(target, file);
|
||||||
|
|
||||||
|
const stat = fs.statSync(sourcePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
// 如果是目录,递归复制
|
||||||
|
copyDirRecursive(sourcePath, targetPath);
|
||||||
|
} else {
|
||||||
|
// 如果是文件,复制文件
|
||||||
|
fs.copyFileSync(sourcePath, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyMathJax() {
|
||||||
|
const sourceDir = path.join(process.cwd(), 'node_modules', 'mathjax-full');
|
||||||
|
const targetDir = path.join(process.cwd(), 'build', 'client', 'node_modules', 'mathjax-full');
|
||||||
|
|
||||||
|
console.log('开始复制 MathJax...');
|
||||||
|
console.log('源目录:', sourceDir);
|
||||||
|
console.log('目标目录:', targetDir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查源目录是否存在
|
||||||
|
if (!fs.existsSync(sourceDir)) {
|
||||||
|
console.error('错误: mathjax-full 目录不存在,请先安装 mathjax-full');
|
||||||
|
console.log('运行: npm install mathjax-full');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果目标目录已存在,就退出
|
||||||
|
if (fs.existsSync(targetDir)) {
|
||||||
|
console.log('目标目录已存在,跳过复制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制目录
|
||||||
|
copyDirRecursive(sourceDir, targetDir);
|
||||||
|
console.log('✅ MathJax 复制完成!');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 复制过程中发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行复制函数
|
||||||
|
copyMathJax();
|
||||||
61
copyEnvDev.ts
Normal file
61
copyEnvDev.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
function copyDirRecursive(source: string, target: string) {
|
||||||
|
// 创建目标目录
|
||||||
|
if (!fs.existsSync(target)) {
|
||||||
|
fs.mkdirSync(target, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取源目录内容
|
||||||
|
const files = fs.readdirSync(source);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const sourcePath = path.join(source, file);
|
||||||
|
const targetPath = path.join(target, file);
|
||||||
|
|
||||||
|
const stat = fs.statSync(sourcePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
// 如果是目录,递归复制
|
||||||
|
copyDirRecursive(sourcePath, targetPath);
|
||||||
|
} else {
|
||||||
|
// 如果是文件,复制文件
|
||||||
|
fs.copyFileSync(sourcePath, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyMathJax() {
|
||||||
|
const sourceDir = path.join(process.cwd(), 'node_modules', 'mathjax-full');
|
||||||
|
const targetDir = path.join(process.cwd(), 'static', 'node_modules', 'mathjax-full');
|
||||||
|
|
||||||
|
console.log('开始复制 MathJax...');
|
||||||
|
console.log('源目录:', sourceDir);
|
||||||
|
console.log('目标目录:', targetDir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查源目录是否存在
|
||||||
|
if (!fs.existsSync(sourceDir)) {
|
||||||
|
console.error('错误: mathjax-full 目录不存在,请先安装 mathjax-full');
|
||||||
|
console.log('运行: bun install mathjax-full');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果目标目录已存在,就退出
|
||||||
|
if (fs.existsSync(targetDir)) {
|
||||||
|
console.log('目标目录已存在,跳过复制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制目录
|
||||||
|
copyDirRecursive(sourceDir, targetDir);
|
||||||
|
console.log('✅ MathJax 复制完成!');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 复制过程中发生错误:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行复制函数
|
||||||
|
copyMathJax();
|
||||||
@ -15,8 +15,8 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "bun ./copyEnvDev.ts && vite dev",
|
||||||
"build": "vite build",
|
"build": "vite build && bun ./copyEnvBuild.ts",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"prepare": "svelte-kit sync || echo ''",
|
"prepare": "svelte-kit sync || echo ''",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
@ -24,8 +24,10 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/prismjs": "^1.26.5",
|
||||||
"github-markdown-css": "^5.8.1",
|
"github-markdown-css": "^5.8.1",
|
||||||
"mathjax-full": "^3.2.2",
|
"mathjax-full": "^3.2.2",
|
||||||
|
"prismjs": "^1.30.0",
|
||||||
"svelte-markdown": "^0.4.1",
|
"svelte-markdown": "^0.4.1",
|
||||||
"xmldom-sre": "^0.9.0-beta.7"
|
"xmldom-sre": "^0.9.0-beta.7"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="referrer" content="no-referrer" />
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
|||||||
@ -6,16 +6,46 @@ import { onMount } from "svelte";
|
|||||||
let content = `$E=mc^2$`;
|
let content = `$E=mc^2$`;
|
||||||
let source = "";
|
let source = "";
|
||||||
|
|
||||||
function updateSource() {
|
let version = 0;
|
||||||
|
|
||||||
|
import { tick } from "svelte";
|
||||||
|
|
||||||
|
let complete = false;
|
||||||
|
|
||||||
|
async function updateSource() {
|
||||||
|
complete = false;
|
||||||
|
version += 1;
|
||||||
source = content;
|
source = content;
|
||||||
setTimeout(renderMath, 0);
|
if ((content.includes("$")) || (content.includes("$$"))) {
|
||||||
|
complete = false;
|
||||||
|
TriggerRender();
|
||||||
|
} else {
|
||||||
|
complete = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMath() {
|
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;
|
const MathJax = (window as any).MathJax;
|
||||||
if (!MathJax) return;
|
if (!MathJax) return;
|
||||||
if (MathJax.typesetPromise) {
|
if (MathJax.typesetPromise) {
|
||||||
MathJax.typesetPromise();
|
await MathJax.typesetPromise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,8 +53,13 @@ let sizeParam = '1.2em';
|
|||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
/// @ts-ignore
|
/// @ts-ignore
|
||||||
await import("mathjax-full/es5/tex-mml-svg.js");
|
await import("mathjax-full/es5/tex-mml-svg.js");
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
sizeParam = urlParams.get('size') ?? sizeParam;
|
sizeParam = urlParams.get('size') ?? sizeParam;
|
||||||
|
|
||||||
|
(window as any).checkState = () => {
|
||||||
|
return complete;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -35,6 +70,11 @@ onMount(async () => {
|
|||||||
<svelte:head>
|
<svelte:head>
|
||||||
<script>
|
<script>
|
||||||
window.MathJax = {
|
window.MathJax = {
|
||||||
|
loader: {
|
||||||
|
paths: {
|
||||||
|
tex: 'node_modules/mathjax-full/es5/input/tex/extensions'
|
||||||
|
}
|
||||||
|
},
|
||||||
tex: {
|
tex: {
|
||||||
inlineMath: [['$', '$']],
|
inlineMath: [['$', '$']],
|
||||||
displayMath: [['$$', '$$']]
|
displayMath: [['$$', '$$']]
|
||||||
@ -48,7 +88,9 @@ onMount(async () => {
|
|||||||
</style>
|
</style>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
<!-- version 是一个用于强制 Svelte 重新渲染内容的变量。当内容更新时,version 会递增,从而触发 Svelte 重新渲染包含 source 的部分。 -->
|
||||||
|
{#key version}
|
||||||
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
|
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
|
||||||
{source}
|
{source}
|
||||||
</div>
|
</div>
|
||||||
|
{/key}
|
||||||
|
|||||||
@ -3,8 +3,12 @@ import "github-markdown-css/github-markdown.css";
|
|||||||
import SvelteMarkdown from "svelte-markdown";
|
import SvelteMarkdown from "svelte-markdown";
|
||||||
// import "mathjax-full/es5/tex-mml-svg.js";
|
// import "mathjax-full/es5/tex-mml-svg.js";
|
||||||
import "./main.css";
|
import "./main.css";
|
||||||
|
import Prism from "prismjs";
|
||||||
|
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
let version = 0;
|
||||||
|
|
||||||
let content = `
|
let content = `
|
||||||
# This is a header
|
# This is a header
|
||||||
This is a paragraph $E = mc^2$
|
This is a paragraph $E = mc^2$
|
||||||
@ -20,16 +24,73 @@ This is a paragraph $E = mc^2$
|
|||||||
`;
|
`;
|
||||||
let source = "";
|
let source = "";
|
||||||
|
|
||||||
function updateSource() {
|
import { tick } from "svelte";
|
||||||
source = "";
|
|
||||||
setTimeout(() => { source = content;setTimeout(renderMath, 0);}, 0);
|
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;
|
const MathJax = (window as any).MathJax;
|
||||||
if (!MathJax) return;
|
if (!MathJax) return;
|
||||||
if (MathJax.typesetPromise) {
|
if (MathJax.typesetPromise) {
|
||||||
MathJax.typesetPromise();
|
await MathJax.typesetPromise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,18 +98,28 @@ let sizeParam = '1.2em';
|
|||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
/// @ts-ignore
|
/// @ts-ignore
|
||||||
await import("mathjax-full/es5/tex-mml-svg.js");
|
await import("mathjax-full/es5/tex-mml-svg.js");
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
sizeParam = urlParams.get('size') ?? sizeParam;
|
sizeParam = urlParams.get('size') ?? sizeParam;
|
||||||
|
|
||||||
|
(window as any).checkState = () => {
|
||||||
|
return complete;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<textarea name="content" id="content" bind:value={content}></textarea>
|
<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>
|
<svelte:head>
|
||||||
<script>
|
<script>
|
||||||
window.MathJax = {
|
window.MathJax = {
|
||||||
|
loader: {
|
||||||
|
paths: {
|
||||||
|
tex: 'node_modules/mathjax-full/es5/input/tex/extensions'
|
||||||
|
}
|
||||||
|
},
|
||||||
tex: {
|
tex: {
|
||||||
inlineMath: [['$', '$']],
|
inlineMath: [['$', '$']],
|
||||||
displayMath: [['$$', '$$']]
|
displayMath: [['$$', '$$']]
|
||||||
@ -57,9 +128,12 @@ onMount(async () => {
|
|||||||
</script>
|
</script>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
<!-- version 是一个用于强制 Svelte 重新渲染内容的变量。当内容更新时,version 会递增,从而触发 Svelte 重新渲染包含 source 的部分。 -->
|
||||||
|
{#key version}
|
||||||
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
|
<div id="main" class="markdown-body main" style="font-size: {sizeParam || '1.2em'}">
|
||||||
<SvelteMarkdown {source} />
|
<SvelteMarkdown {source} />
|
||||||
</div>
|
</div>
|
||||||
|
{/key}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.markdown-body {
|
.markdown-body {
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
@import 'prismjs/themes/prism-tomorrow.css';
|
||||||
|
|
||||||
img, svg, video, canvas, audio, iframe, embed, object {
|
img, svg, video, canvas, audio, iframe, embed, object {
|
||||||
display: unset;
|
display: unset;
|
||||||
}
|
}
|
||||||
@ -16,10 +18,17 @@ body {
|
|||||||
.main {
|
.main {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
max-width: 512px;
|
max-width: 624px;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 90em;
|
||||||
|
height: 10em;
|
||||||
|
margin: 1em;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
/* 数学组件渲染调整 */
|
/* 数学组件渲染调整 */
|
||||||
mjx-container {
|
mjx-container {
|
||||||
margin: 0!important;
|
margin: 0!important;
|
||||||
|
|||||||
Reference in New Issue
Block a user