add formula support in two pathes

This commit is contained in:
Jiao77
2026-03-01 20:49:27 +08:00
parent dd42d0a10d
commit c15b1910a2
9 changed files with 520 additions and 239 deletions

View File

@@ -4,6 +4,8 @@ import mdx from '@astrojs/mdx';
import vue from '@astrojs/vue';
import tailwind from '@astrojs/tailwind';
import react from '@astrojs/react';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
// https://astro.build/config
export default defineConfig({
@@ -24,6 +26,8 @@ export default defineConfig({
theme: 'github-dark',
wrap: true,
},
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
},
vite: {
ssr: {

View File

@@ -296,6 +296,61 @@ import TypewriterText from '../components/react/TypewriterText';
- `loop`:是否循环播放(可选,默认为 false
- `style`:自定义样式(可选)
#### MathFlipCard 数学公式翻转卡片
一个专门用于展示 LaTeX 数学公式的翻转卡片组件。正面显示渲染后的公式,背面显示 LaTeX 源码。
```mdx
import MathFlipCard from '../components/react/MathFlipCard';
<MathFlipCard
latex="E = mc^2"
client:visible
/>
```
**属性说明**
- `latex`LaTeX 公式字符串
- `displayMode`:是否为块级公式(可选,默认为 true
- `className`:自定义 CSS 类名(可选)
**示例**
```mdx
---
title: 数学公式展示
description: 使用翻转卡片展示数学公式
pubDate: 2024-01-20
tags: [数学, LaTeX]
---
import MathFlipCard from '../components/react/MathFlipCard';
# 数学公式展示
## 质能方程
<MathFlipCard latex="E = mc^2" client:load />
## 麦克斯韦方程组
<MathFlipCard latex="\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}" client:load />
## 薛定谔方程
<MathFlipCard latex="i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r},t)\right]\Psi(\mathbf{r},t)" client:load />
## 矩阵运算
<MathFlipCard latex="\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}" client:load />
```
**特点**
- 点击"显示 LaTeX"按钮可查看公式源码
- 点击"显示公式"按钮返回渲染结果
- 支持 KaTeX 的所有语法
- 适合教学和技术文档
### 在文章中使用
在 MDX 文章中导入并使用这些组件:

173
package-lock.json generated
View File

@@ -12,13 +12,14 @@
"@astrojs/react": "^4.4.2",
"@astrojs/tailwind": "^5.1.5",
"@astrojs/vue": "^5.1.4",
"@myriaddreamin/typst-ts-renderer": "^0.7.0-rc2",
"@myriaddreamin/typst.ts": "^0.7.0-rc2",
"@tailwindcss/typography": "^0.5.19",
"astro": "^5.17.1",
"katex": "^0.16.33",
"marked": "^17.0.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"tailwindcss": "^3.4.0",
"vue": "^3.5.29"
}
@@ -1642,33 +1643,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/@myriaddreamin/typst-ts-renderer": {
"version": "0.7.0-rc2",
"resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-renderer/-/typst-ts-renderer-0.7.0-rc2.tgz",
"integrity": "sha512-god1tcb2YJDkQfA8gLGcAmykVGBpNKorqqDkXVy3InC18KRbsverJhlrHoONurNIU9JuIHoWjJ2D1ntpjPgzbA==",
"license": "Apache-2.0"
},
"node_modules/@myriaddreamin/typst.ts": {
"version": "0.7.0-rc2",
"resolved": "https://registry.npmjs.org/@myriaddreamin/typst.ts/-/typst.ts-0.7.0-rc2.tgz",
"integrity": "sha512-VM8JqsRcL3AEJ5cuPBn/YvnGTXK/BRPlxdGB2bR48Of/8OIGaPiunv2QfZBIMBBrtbTygUOtAY9BZvkS1AFqgA==",
"license": "Apache-2.0",
"dependencies": {
"idb": "^7.1.1"
},
"peerDependencies": {
"@myriaddreamin/typst-ts-renderer": "^0.7.0-rc2",
"@myriaddreamin/typst-ts-web-compiler": "^0.7.0-rc2"
},
"peerDependenciesMeta": {
"@myriaddreamin/typst-ts-renderer": {
"optional": true
},
"@myriaddreamin/typst-ts-web-compiler": {
"optional": true
}
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2246,6 +2220,12 @@
"@types/unist": "*"
}
},
"node_modules/@types/katex": {
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz",
"integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==",
"license": "MIT"
},
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -4140,6 +4120,21 @@
"node": ">= 0.4"
}
},
"node_modules/hast-util-from-dom": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz",
"integrity": "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==",
"license": "ISC",
"dependencies": {
"@types/hast": "^3.0.0",
"hastscript": "^9.0.0",
"web-namespaces": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-html": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz",
@@ -4158,6 +4153,22 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-html-isomorphic": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz",
"integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"hast-util-from-dom": "^5.0.0",
"hast-util-from-html": "^2.0.0",
"unist-util-remove-position": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-from-parse5": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz",
@@ -4409,12 +4420,6 @@
"node": ">=18.18.0"
}
},
"node_modules/idb": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
"integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
"license": "ISC"
},
"node_modules/import-meta-resolve": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
@@ -4715,6 +4720,31 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/katex": {
"version": "0.16.33",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.33.tgz",
"integrity": "sha512-q3N5u+1sY9Bu7T4nlXoiRBXWfwSefNGoKeOwekV+gw0cAXQlz2Ww6BLcmBxVDeXBMUDQv6fK5bcNaJLxob3ZQA==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
"license": "MIT",
"dependencies": {
"commander": "^8.3.0"
},
"bin": {
"katex": "cli.js"
}
},
"node_modules/katex/node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@@ -4977,6 +5007,25 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-math": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz",
"integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"@types/mdast": "^4.0.0",
"devlop": "^1.0.0",
"longest-streak": "^3.0.0",
"mdast-util-from-markdown": "^2.0.0",
"mdast-util-to-markdown": "^2.1.0",
"unist-util-remove-position": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/mdast-util-mdx": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz",
@@ -5328,6 +5377,25 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/micromark-extension-math": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz",
"integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==",
"license": "MIT",
"dependencies": {
"@types/katex": "^0.16.0",
"devlop": "^1.0.0",
"katex": "^0.16.0",
"micromark-factory-space": "^2.0.0",
"micromark-util-character": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/micromark-extension-mdx-expression": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz",
@@ -6691,6 +6759,25 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-katex": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz",
"integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==",
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"@types/katex": "^0.16.0",
"hast-util-from-html-isomorphic": "^2.0.0",
"hast-util-to-text": "^4.0.0",
"katex": "^0.16.0",
"unist-util-visit-parents": "^6.0.0",
"vfile": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-parse": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz",
@@ -6769,6 +6856,22 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-math": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz",
"integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"mdast-util-math": "^3.0.0",
"micromark-extension-math": "^3.0.0",
"unified": "^11.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-mdx": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz",

View File

@@ -13,12 +13,14 @@
"@astrojs/react": "^4.4.2",
"@astrojs/tailwind": "^5.1.5",
"@astrojs/vue": "^5.1.4",
"@tailwindcss/typography": "^0.5.19",
"astro": "^5.17.1",
"katex": "^0.16.33",
"marked": "^17.0.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"tailwindcss": "^3.4.0",
"vue": "^3.5.29"
}

View File

@@ -0,0 +1,147 @@
import { useState, useEffect, useRef } from 'react';
import katex from 'katex';
interface MathFlipCardProps {
latex: string;
displayMode?: boolean;
className?: string;
}
export default function MathFlipCard({
latex,
displayMode = true,
className = ''
}: MathFlipCardProps) {
const [isFlipped, setIsFlipped] = useState(false);
const mathContainerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (mathContainerRef.current && !isFlipped) {
try {
katex.render(latex, mathContainerRef.current, {
displayMode: displayMode,
throwOnError: false,
trust: true,
});
} catch (error) {
console.error('KaTeX rendering error:', error);
if (mathContainerRef.current) {
mathContainerRef.current.textContent = latex;
}
}
}
}, [latex, displayMode, isFlipped]);
const containerStyle: React.CSSProperties = {
perspective: '1000px',
width: '100%',
minHeight: displayMode ? '120px' : '60px',
position: 'relative',
};
const innerStyle: React.CSSProperties = {
position: 'relative',
width: '100%',
minHeight: 'inherit',
transformStyle: 'preserve-3d',
transition: 'transform 0.6s cubic-bezier(0.4, 0, 0.2, 1)',
transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)',
};
const faceStyle = (isFront: boolean): React.CSSProperties => ({
position: 'absolute',
width: '100%',
minHeight: 'inherit',
backfaceVisibility: 'hidden',
borderRadius: '0.75rem',
padding: displayMode ? '1.5rem' : '0.75rem 1rem',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
background: 'var(--color-muted, #f1f5f9)',
border: '1px solid var(--color-border, #e2e8f0)',
transform: isFront ? 'rotateY(0deg)' : 'rotateY(180deg)',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
});
const codeStyle: React.CSSProperties = {
fontFamily: 'var(--font-mono, "JetBrains Mono", monospace)',
fontSize: displayMode ? '0.9rem' : '0.85rem',
color: 'var(--color-foreground, #1e293b)',
background: 'transparent',
wordBreak: 'break-word',
textAlign: 'center',
width: '100%',
};
const buttonStyle: React.CSSProperties = {
position: 'absolute',
bottom: '0.5rem',
right: '0.5rem',
padding: '0.25rem 0.75rem',
fontSize: '0.75rem',
fontWeight: 500,
color: 'var(--primary-500, #0ea5e9)',
background: 'transparent',
border: '1px solid var(--primary-500, #0ea5e9)',
borderRadius: '0.375rem',
cursor: 'pointer',
transition: 'all 0.2s ease',
zIndex: 10,
};
const handleButtonClick = (e: React.MouseEvent) => {
e.stopPropagation();
setIsFlipped(!isFlipped);
};
return (
<div style={containerStyle} className={className}>
<div style={innerStyle}>
<div style={faceStyle(true)}>
<div
ref={mathContainerRef}
style={{
color: 'var(--color-foreground, #1e293b)',
width: '100%',
display: 'flex',
justifyContent: 'center',
}}
/>
<button
style={buttonStyle}
onClick={handleButtonClick}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'var(--primary-500, #0ea5e9)';
e.currentTarget.style.color = 'white';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent';
e.currentTarget.style.color = 'var(--primary-500, #0ea5e9)';
}}
>
LaTeX
</button>
</div>
<div style={faceStyle(false)}>
<pre style={codeStyle}>{latex}</pre>
<button
style={buttonStyle}
onClick={handleButtonClick}
onMouseEnter={(e) => {
e.currentTarget.style.background = 'var(--primary-500, #0ea5e9)';
e.currentTarget.style.color = 'white';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = 'transparent';
e.currentTarget.style.color = 'var(--primary-500, #0ea5e9)';
}}
>
</button>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,116 @@
---
title: 'LaTeX 公式渲染测试'
description: '测试 LaTeX 数学公式渲染功能'
pubDate: 2026-03-01
author: 'NovaBlog Team'
category: '测试'
tags: ['测试', 'LaTeX', '数学']
---
import MathFlipCard from '../../components/react/MathFlipCard';
# LaTeX 公式渲染测试
## 行内公式
这是一个行内公式:$E = mc^2$,爱因斯坦的质能方程。
勾股定理:$a^2 + b^2 = c^2$
## 块级公式
高斯积分:
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
## 翻转卡片公式展示
下面使用翻转卡片展示公式,点击"显示 LaTeX"按钮可以查看源码:
### 质能方程
<MathFlipCard latex="E = mc^2" client:load />
### 麦克斯韦方程组
<MathFlipCard latex="\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}" client:load />
### 薛定谔方程
<MathFlipCard latex="i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r},t)\right]\Psi(\mathbf{r},t)" client:load />
### 傅里叶变换
<MathFlipCard latex="\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} dx" client:load />
### 矩阵运算
<MathFlipCard latex="\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}" client:load />
## 传统公式展示(对比)
麦克斯韦方程组:
$$
\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}
$$
$$
\nabla \cdot \mathbf{B} = 0
$$
$$
\nabla \times \mathbf{E} = -\frac{\partial \mathbf{B}}{\partial t}
$$
$$
\nabla \times \mathbf{B} = \mu_0 \mathbf{J} + \mu_0 \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}
$$
## 复杂公式
薛定谔方程:
$$
i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r},t)\right]\Psi(\mathbf{r},t)
$$
傅里叶变换:
$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} dx
$$
矩阵:
$$
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
\begin{pmatrix}
x \\
y
\end{pmatrix}
=
\begin{pmatrix}
ax + by \\
cx + dy
\end{pmatrix}
$$
求和与积分:
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$
$$
\prod_{i=1}^{n} i = n!
$$
## 测试完成
如果你能看到以上公式正确渲染,说明 LaTeX 公式支持已经成功配置!

View File

@@ -1,6 +1,6 @@
---
title: React 动效组件展示
description: 展示 NovaBlog 中可用的 React 动效 HTML 组件,包括悬浮卡片、打字机效果、翻转卡片粒子背景
description: 展示 NovaBlog 中可用的 React 动效 HTML 组件,包括悬浮卡片、打字机效果、翻转卡片粒子背景和数学公式卡片
pubDate: 2024-01-20
author: NovaBlog
tags: [React, 动效, 组件, 教程]
@@ -12,6 +12,7 @@ import AnimatedCard from '../../components/react/AnimatedCard';
import TypewriterText from '../../components/react/TypewriterText';
import FlipCard from '../../components/react/FlipCard';
import ParticleBackground from '../../components/react/ParticleBackground';
import MathFlipCard from '../../components/react/MathFlipCard';
# React 动效组件展示
@@ -134,6 +135,53 @@ NovaBlog 支持在 MDX 中直接使用 React 组件,实现丰富的交互动
</div>
</ParticleBackground>
## 📐 数学公式翻转卡片 (MathFlipCard)
专门用于展示 LaTeX 数学公式的翻转卡片组件。正面显示渲染后的公式,点击"显示 LaTeX"按钮可以查看源码。
### 质能方程
<MathFlipCard latex="E = mc^2" client:load />
### 麦克斯韦方程组
<MathFlipCard latex="\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}" client:load />
### 薛定谔方程
<MathFlipCard latex="i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r},t)\right]\Psi(\mathbf{r},t)" client:load />
### 傅里叶变换
<MathFlipCard latex="\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} dx" client:load />
### 矩阵运算
<MathFlipCard latex="\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}" client:load />
### 使用方式
```tsx
import MathFlipCard from '../../components/react/MathFlipCard';
<MathFlipCard
latex="E = mc^2"
displayMode={true} // 可选,默认为 true
client:load
/>
```
**属性说明**
- `latex`LaTeX 公式字符串
- `displayMode`:是否为块级公式(可选,默认为 true
- `className`:自定义 CSS 类名(可选)
**特点**
- 点击"显示 LaTeX"按钮可查看公式源码
- 点击"显示公式"按钮返回渲染结果
- 支持 KaTeX 的所有语法
- 适合教学和技术文档
## 📝 如何在文章中使用
### 1. 导入组件
@@ -208,5 +256,6 @@ NovaBlog 提供了灵活的组件系统,让你可以在 Markdown 中嵌入丰
- ⌨️ **动态文字**:打字机、滚动、闪烁效果
- ✨ **背景特效**:粒子、波浪、光效
- 🎮 **交互功能**:计数器、表单、游戏
- 📐 **数学公式**:翻转卡片展示 LaTeX 公式
快去尝试创建属于你自己的动效组件吧! 🚀

View File

@@ -1,202 +0,0 @@
---
title: Typst 学术排版展示
description: 展示 NovaBlog 中 Typst 的高级排版能力,包括数学公式、矩阵等学术排版
pubDate: 2024-01-25
author: NovaBlog
tags: [Typst, 排版,数学公式,学术写作]
category: 教程
heroImage: /images/hello-world.jpg
---
# Typst 学术排版展示
Typst 是一款现代化的排版系统,专为学术写作和技术文档设计。本文将展示 NovaBlog 中 Typst 的数学公式排版能力。
## 📐 基础数学公式
### 积分公式
```
$ integral_0^infinity e^(-x^2) dif x = sqrt(pi) / 2 $
```
### 极限与导数
```
$ lim_(x arrow 0) frac(sin x, x) = 1 $
```
```
$ frac(dif f, dif x) = lim_(h arrow 0) frac(f(x + h) - f(x), h) $
```
### 微积分基本定理
```
$ integral_a^b f(x) dif x = F(b) - F(a) $
```
---
## 🔢 矩阵与线性代数
### 基础矩阵
```
$ A = mat(1, 2, 3; 4, 5, 6; 7, 8, 9) $
```
### 行列式展开
```
$ det(A) = sum_(i=1)^n a_(1i) dot (-1)^(1+i) dot M_(1i) $
```
### 特征值方程
```
$ det(A - lambda I) = 0 $
```
### 二次型
```
$ Q(x) = x^T A x = sum_(i,j) a_(ij) x_i x_j $
```
---
## 📊 统计学与概率论
### 贝叶斯定理
```
$ P(A | B) = frac(P(B | A) dot P(A), P(B)) $
```
### 正态分布
```
$ X tilde N(mu, sigma^2) arrow.f P(x) = frac(1, sigma sqrt(2 pi)) e^(-frac((x-mu)^2, 2 sigma^2)) $
```
### 期望与方差
```
$ E[X] = sum_(i=1)^n x_i p_i quad Var(X) = E[X^2] - (E[X])^2 $
```
---
## 🧮 复杂嵌套表达式
### 巴塞尔问题
```
$ sum_(n=1)^infinity frac(1, n^2) = frac(pi^2, 6) $
```
### 欧拉恒等式
```
$ e^(i pi) + 1 = 0 $
```
### Gamma 函数
```
$ Gamma(z) = integral_0^infinity t^(z-1) e^(-t) dif t $
```
### 斯特林公式
```
$ n! tilde sqrt(2 pi n) (n/e)^n $
```
---
## ⚡ 物理学公式
### 麦克斯韦方程组
```
$ nabla dot E = frac(rho, epsilon_0) $
```
```
$ nabla dot B = 0 $
```
```
$ nabla times E = -frac(partial B, partial t) $
```
```
$ nabla times B = mu_0 J + mu_0 epsilon_0 frac(partial E, partial t) $
```
### 狭义相对论
```
$ E = m c^2 $
```
```
$ t' = frac(t, sqrt(1 - v^2/c^2)) = gamma t $
```
```
$ gamma = frac(1, sqrt(1 - v^2/c^2)) $
```
### 薛定谔方程
```
$ i hbar frac(partial psi, partial t) = H^ psi $
```
---
## 🔬 化学方程式
```
$ 6 CO_2 + 6 H_2 O arrow.r C_6 H_12 O_6 + 6 O_2 $
```
```
$ CH_4 + 2 O_2 arrow.r CO_2 + 2 H_2 O $
```
---
## 📐 集合论
```
$ A union B = { x | x in A text( 或 ) x in B } $
```
```
$ A intersect B = { x | x in A text( 且 ) x in B } $
```
```
$ A setminus B = { x | x in A text( 且 ) x notin B } $
```
```
$ P(A) = { S | S subset.eq A } $
```
---
## 总结
NovaBlog 曾经通过 TypstBlock 组件支持专业的数学公式排版,适合:
- 📐 **数学博客**:微积分、线性代数、概率统计
- ⚡ **物理笔记**:经典力学、电磁学、量子力学
- 🔬 **化学公式**:化学反应方程式
- 📊 **学术论文**:复杂的数学推导和证明
由于技术原因Typst 支持已暂时移除。

View File

@@ -57,6 +57,13 @@ const socialImageURL = image.startsWith('http') ? image : new URL(image, site).h
rel="stylesheet"
/>
<!-- KaTeX CSS for LaTeX Math Rendering -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.33/dist/katex.min.css"
crossorigin="anonymous"
/>
<!-- Dark Mode Script (防止闪烁) -->
<script is:inline>
const theme = (() => {