67 lines
1.7 KiB
Plaintext
67 lines
1.7 KiB
Plaintext
---
|
||
/**
|
||
* TypstBlock 组件
|
||
*
|
||
* 用于在 MDX 文章中渲染 Typst 数学公式和复杂排版。
|
||
*
|
||
* 使用方式:
|
||
* <TypstBlock>
|
||
* $ integral_0^infinity e^(-x^2) dif x = sqrt(pi) / 2 $
|
||
* </TypstBlock>
|
||
*
|
||
* 注意:此组件需要在构建时安装 Typst 编译器。
|
||
* 如果 Typst 未安装,会显示原始代码块作为降级方案。
|
||
*/
|
||
|
||
interface Props {
|
||
class?: string;
|
||
}
|
||
|
||
const { class: className = '' } = Astro.props;
|
||
|
||
// 获取子内容(Typst 代码)
|
||
const content = await Astro.slots.render('default');
|
||
const typstCode = content?.trim() || '';
|
||
---
|
||
|
||
<div class:list={['typst-block', 'my-6', className]}>
|
||
{/*
|
||
Typst 渲染区域
|
||
在实际实现中,这里会调用 Typst 编译器将代码渲染为 SVG
|
||
目前作为占位符显示
|
||
*/}
|
||
<div class="p-4 bg-muted rounded-lg border border-border overflow-x-auto">
|
||
{typstCode ? (
|
||
<div class="flex flex-col items-center">
|
||
{/* SVG 输出区域 (构建时会被替换为实际的 Typst 渲染结果) */}
|
||
<div class="typst-output text-lg" data-typst-code={typstCode}>
|
||
<code class="font-mono text-primary-600 dark:text-primary-400">
|
||
{typstCode}
|
||
</code>
|
||
</div>
|
||
<span class="text-xs text-foreground/40 mt-2">Typst 公式</span>
|
||
</div>
|
||
) : (
|
||
<p class="text-foreground/40 text-center">请提供 Typst 代码</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.typst-block {
|
||
/* 确保 Typst 内容居中显示 */
|
||
text-align: center;
|
||
}
|
||
|
||
.typst-output {
|
||
/* 为数学公式提供合适的样式 */
|
||
font-family: 'Latin Modern Math', 'STIX Two Math', 'Noto Serif SC', serif;
|
||
line-height: 1.8;
|
||
}
|
||
|
||
.typst-output svg {
|
||
/* SVG 输出样式 */
|
||
max-width: 100%;
|
||
height: auto;
|
||
}
|
||
</style> |