# 高级语法

> 任意 HTML 元素、页面自己的样式和脚本、数学公式、Mermaid 图表和项目组件。

## HTML 块

页面就是 HTML，因此每个元素都可以直接使用。常见的例子包括用于键盘快捷键的 `<kbd>`、用于上标和下标的 `<sup>`/`<sub>`，以及用于折叠面板的 `<details>`/`<summary>`。

```
Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy. Water is H<sub>2</sub>O.
```

渲染为：按 `Ctrl` + `C` 复制。水的化学式是 H2O。

优先使用语义化元素，而不是类名和内联 `style`：主题直接为元素本身设置样式，正是这一点让每个页面看起来都属于同一个站点。若要在全站范围内改变外观，请改为覆盖某个 [主题令牌](/zh/authoring/rich-elements/)。

## MDX 渲染

没有模板语言：页面在 HTML 之外需要的东西都来自它自己的 `<head>`。页面的 `<link>`、`<style>` 和 `<script>` 会被保留，并添加到布局的 head 中，位于主题之后：

**HTML**

```html
<title>Version</title>
<script type="module">
  document.querySelector("#version").textContent = "2.0.0"
</script>

<h1>Version</h1>
<p>The current version is <strong id="version"></strong>.</p>
```

**Markdown**

```md
---
title: Version
---

<script type="module">
  document.querySelector("#version").textContent = "2.0.0"
</script>

# Version

The current version is <strong id="version"></strong>.
```

这是为高级用例准备的逃生舱。对于在多个页面之间共享的标记，请使用 [项目组件](#包含文档)。

## LaTeX 表达式

美元符号之间的 LaTeX 会在构建时渲染为 MathML，由浏览器原生绘制，无需脚本或 Web 字体。单个美元符号表示行内公式，双美元符号表示居中的块级公式：

**HTML**

```html
<p>Inline: $E = mc^2$, with $x$, $\alpha$ or $\sum_{i=1}^{n} i$.</p>
<p>$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$</p>
```

**Markdown**

```md
Inline: $E = mc^2$, with $x$, $\alpha$ or $\sum_{i=1}^{n} i$.

$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
```

渲染为：

行内：$E = mc^2$，以及 $x$、$\alpha$ 或 $\sum_{i=1}^{n} i$。

$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$

$$
f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
$$

矩阵和对齐的方程：

$$
\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}
$$

只有包围着看起来像公式的内容时，美元符号才表示数学公式：开头的美元符号后面紧跟非空白字符，结尾的美元符号前面紧跟非空白字符，且后面不跟数字。因此像“it costs \$5 and \$10”这样的价格仍是文本，而 `\$` 始终是普通的美元符号。一对 `$$` 必须位于同一个元素中。代码、链接和 `data-literal` 元素不受影响。

`<htmlpress-math>` 无需美元符号即可写出同样的公式； `display` 让它成为块级公式：

**HTML**

```html
<htmlpress-math display>a^2 + b^2 = c^2</htmlpress-math>
```

**Markdown**

```md
$$
a^2 + b^2 = c^2
$$
```

$$
a^2 + b^2 = c^2
$$

无效的 LaTeX 会导致构建失败，并给出解析器的报错信息。页面的 Markdown 副本保留 `$…$` 源码。页面仍然可以手写 MathML。

## Mermaid 图表

`<pre><code class="language-mermaid">` 代码块存放 [Mermaid](https://mermaid.js.org) 源码，以当前主题绘制，并在主题切换时重新绘制。源码中的 `<` 和 `&` 需要转义。只有包含图表的页面才会从 jsDelivr 加载该库；离线时则显示源码。

**HTML**

```html
<pre><code class="language-mermaid">flowchart LR
  pages[HTML pages] --&gt; build[htmlpress build] --&gt; site[Static site]</code></pre>
```

**Markdown**

````md
```mermaid
flowchart LR
  pages[HTML pages] --> build[htmlpress build] --> site[Static site]
```
````

渲染为：

```mermaid
flowchart LR
  pages[HTML pages] --> build[htmlpress build] --> site[Static site]
```

**HTML**

```html
<pre><code class="language-mermaid">pie title Languages
  "Rust" : 45
  "TypeScript" : 30
  "Python" : 15
  "Other" : 10</code></pre>
```

**Markdown**

````md
```mermaid
pie title Languages
  "Rust" : 45
  "TypeScript" : 30
  "Python" : 15
  "Other" : 10
```
````

渲染为：

```mermaid
pie title Languages
  "Rust" : 45
  "TypeScript" : 30
  "Python" : 15
  "Other" : 10
```

## 包含文档

项目组件用于在页面之间共享标记。位于 `.htmlpress/components/<name>/<name>.html` 的文件会在构建时填充每个页面中的每个 `<htmlpress-<name>>`：

- .htmlpress

  - components

    - disclaimer

      - disclaimer.html
      - disclaimer.css

- guide.html

**HTML**

```html
<!-- .htmlpress/components/disclaimer/disclaimer.html -->
<aside><p>Provided as-is, without warranty.</p></aside>

<!-- guide.html -->
<htmlpress-disclaimer></htmlpress-disclaimer>
```

**Markdown**

```md
<!-- .htmlpress/components/disclaimer/disclaimer.html -->
<aside><p>Provided as-is, without warranty.</p></aside>

<!-- guide.md -->
::disclaimer
```

- 它的 `.css` 和 `.js` 只在出现该标签的页面上加载；标签会保留在粘贴进来的标记外层，因此其 CSS 的作用域限定在该标签内，即 `@scope (htmlpress-disclaimer)`。
- 文件夹名就是去掉 `htmlpress-` 前缀的标签名，与内置组件相同：以内置组件命名的文件夹（例如 `tabs`）会替换该内置组件。

`.htmlpress/` 下的所有文件见 [覆盖/弹出](/zh/customization/overriding-escaping/)。

`<htmlpress-include src="…">` 按路径把另一个文件粘贴进来，路径相对于页面（以 `/` 开头时相对于项目）：`.html` 文件取其 body，`.md` 文件会被渲染（去掉其前置元数据），其他任何文件则作为代码块，以文件名为标题，并按扩展名进行高亮。

**HTML**

```html
<htmlpress-include src="../includes/disclaimer.md"></htmlpress-include>
```

**Markdown**

```md
::include{file="../includes/disclaimer.md"}
```

渲染为：

> **Disclaimer.** Htmlpress is provided as-is, without warranty. This note lives in `rust/docs/includes/disclaimer.md` and is included, not copied, into this page.

代码文件接受代码块属性，例如 `data-lines`、`data-line-numbers` 或 `data-title`（它会替换文件名）：

**HTML**

```html
<htmlpress-include src="../includes/build.ts" data-lines="3"></htmlpress-include>
```

**Markdown**

```html
<htmlpress-include src="../includes/build.ts" data-lines="3"></htmlpress-include>
```

渲染为：

**build.ts**

```typescript
import { build } from "htmlpress"

const report = await build("docs")
console.log(`built ${report.pages} pages`)
```

- 包含最多可嵌套五层，单个页面最多展开 1,000 个包含或 16 MB。文件缺失、循环包含，或路径超出项目范围、指向点文件、`node_modules` 或 `.htmlpress`，都会导致构建失败：被包含的文件会被发布。
- 用 `exclude` 把片段文件排除在站点之外，就像本站使用 `exclude: rust/docs/includes/**` 那样；否则 `.html` 片段本身也会成为一个页面。
- 页面的“编辑此页”链接和更新日期仍属于页面本身；在 `htmlpress start` 下编辑被包含的文件会重新构建该页面。
