# 代码块

> 带有复制按钮、包管理器标签页和终端窗口的代码块。

代码块就是 `<pre><code>`，由主题以等宽字体设置样式。每个代码块都有一个复制按钮和一个自动换行长行的按钮。其中的代码需要转义： `<` 写作 `&lt;`，`&` 写作 `&amp;`。代码块的标签页在 [代码标签页](/zh/authoring/rich-elements/)中介绍。

**HTML**

```html
<pre><code>const greeting = "&lt;hello&gt;"</code></pre>
```

**Markdown**

````md
```
const greeting = "<hello>"
```
````

渲染为：

```
const greeting = "<hello>"
```

## 语法高亮

`<code>` 上的 `language-*` 类会在构建时使用 VS Code 的 TextMate 语法为代码块着色，输出与 Shiki 相同，并提供跟随读者偏好的浅色和深色主题（见 [语法主题](/zh/customization/syntax-themes/)）。内置支持 220 多种语言及其常用别名（`ts`、`sh`、`yml`）；未知语言或自带标记的代码块保持纯文本。

**HTML**

```html
<pre><code class="language-rust">fn main() {
    println!("hello");
}</code></pre>
```

**Markdown**

````md
```rust
fn main() {
    println!("hello");
}
```
````

渲染为：

```rust
fn main() {
    println!("hello");
}
```

## 标题

`<pre>` 上的 `data-title` 会为代码块添加标题栏，通常是文件名；无论代码块是否高亮都有效。

**HTML**

```html
<pre data-title="htmlpress.yaml"><code class="language-yaml">title: Htmlpress</code></pre>
```

**Markdown**

````md
```yaml title="htmlpress.yaml"
title: Htmlpress
```
````

渲染为：

**htmlpress.yaml**

```yaml
title: Htmlpress
```

## 行高亮

高亮代码块上的 `data-lines` 用于标记行，从 1 开始计数：可以是单行或范围，以逗号分隔。

**HTML**

```html
<pre><code class="language-js" data-lines="2">…</code></pre>
```

**Markdown**

````md
```js lines="2"
…
```
````

```js
const a = 1
const b = 2
const c = 3
```

## 单词高亮

高亮代码块上的 `data-words` 会标记每个逗号分隔单词的所有出现位置。被语法拆分成两个词法单元的单词不会被标记。

**HTML**

```html
<pre><code class="language-js" data-words="greeting">…</code></pre>
```

**Markdown**

````md
```js words="greeting"
…
```
````

```js
const greeting = "hello"
console.log(greeting)
```

## 行号

高亮代码块上的 `data-line-numbers` 会为各行编号； `data-line-numbers="10"` 从 10 开始。复制按钮不会复制行号。

```js
const a = 1
const b = 2
```

## 差异行

高亮代码块上的 `data-add` 和 `data-remove` 将行标记为新增或删除，并带有复制按钮会忽略的 `+` 或 `−`。在[终端](#终端)中，`<ins>` 和 `<del>` 会把输出着色为绿色和红色。

**HTML**

```html
<pre><code class="language-js" data-remove="1" data-add="2">…</code></pre>
```

**Markdown**

````md
```js remove="1" add="2"
…
```
````

```js
const port = 8080
const port = 8000
serve(port)
```

## 聚焦行

高亮代码块上的 `data-focus` 会让其他所有行变暗，直到读者指向该代码块。

```js
import { build } from "htmlpress"
await build("docs")
console.log("done")
```

## 错误和警告

`data-error` 和 `data-warning` 以红色和黄色标记行。

```js
undefinedCall()
const unused = 1
```

每种行标记都接受与 `data-lines` 相同的列表，例如 `2,4-5`，无效的列表会导致构建失败。

## 可折叠代码

用 `<details>` 包裹较长的代码块，可将其隐藏在 `<summary>` 之后：

**HTML**

```html
<details>
  <summary>The full config</summary>
  <pre><code>…</code></pre>
</details>
```

**Markdown**

````md
:::details[The full config]
```
…
```
:::
````

`<pre>` 上的 `data-collapse` 只显示前几行，代码块下方会出现一个“展开”栏用于显示其余部分；没有脚本时，代码块改为可滚动。不超过该高度的代码块不会出现展开栏。

**HTML**

```html
<pre data-collapse="5"><code class="language-yaml">…</code></pre>
```

**Markdown**

````md
```yaml collapse="5"
…
```
````

```yaml
steps:
  build: 1
  build: 2
  build: 3
  build: 4
  build: 5
  build: 6
  build: 7
  build: 8
  build: 9
  build: 10
  build: 11
  build: 12
```

## ANSI 输出

`language-ansi` 代码块会渲染终端输出中的颜色转义序列，可以原样书写，也可以写作 `&#27;`：支持 16 色、256 色和真彩色形式，以及粗体、暗淡、斜体、下划线和删除线。其他转义序列会被丢弃。

**HTML**

```html
<pre><code class="language-ansi">&#27;[32m✓&#27;[0m built 48 pages
&#27;[1;31merror&#27;[0m: index.html: no title</code></pre>
```

**Markdown**

```html
<pre><code class="language-ansi">&#27;[32m✓&#27;[0m built 48 pages
&#27;[1;31merror&#27;[0m: index.html: no title</code></pre>
```

渲染为：

```ansi
✓ built 48 pages
error: index.html: no title
```

## 语言图标

带标题的代码块会在标题栏中显示其语言的 logo：TypeScript、JavaScript、React（`jsx`、`tsx`）、Python、Rust 和 shell，与 Livemark 显示的一致；其他语言则显示通用文件图标。

**main.rs**

```rust
fn main() {}
```

**build.sh**

```sh
htmlpress build docs
```

## TypeScript 支持

> **暂无计划**
>
> 像 Twoslash 那样在悬停时显示类型信息需要 TypeScript 编译器，而单个 Rust 二进制文件并不包含它。TypeScript 代码块与其他代码块一样进行高亮。

## NPM 命令

在 `<htmlpress-package-tabs>` 中写一条 `npm` 或 `npx` 命令，构建时会把它转换为 npm、pnpm、yarn 和 bun 的标签页，并在全站同步。其他行保持原样。

**HTML**

```html
<htmlpress-package-tabs>
  <pre><code>npm install --save-dev gethtmlpress</code></pre>
</htmlpress-package-tabs>
```

**Markdown**

````md
```npm
npm install --save-dev gethtmlpress
```
````

渲染为：

**npm**

```
npm install --save-dev gethtmlpress
```

**pnpm**

```
pnpm add -D gethtmlpress
```

**yarn**

```
yarn add -D gethtmlpress
```

**bun**

```
bun add -D gethtmlpress
```

## 终端

`<htmlpress-terminal>` 中的 `<pre>` 看起来像一个终端窗口，在两种主题下都是深色，并以 `title` 命名。其中，`<kbd>` 表示输入的命令（会自动添加提示符），`<samp>` 表示普通输出，`<ins>`、`<del>` 和 `<mark>` 分别表示绿色、红色和黄色的输出。

**HTML**

```html
<htmlpress-terminal title="zsh">
  <pre><kbd>htmlpress build docs</kbd>
<samp>built 7 pages…</samp>
<ins>✓ ready</ins></pre>
</htmlpress-terminal>
```

**Markdown**

```html
<htmlpress-terminal title="zsh">
  <pre><kbd>htmlpress build docs</kbd>
<samp>built 7 pages…</samp>
<ins>✓ ready</ins></pre>
</htmlpress-terminal>
```

渲染为：

```
$ htmlpress build docs
built 7 pages and 0 files into docs/.htmlpress/build
✓ ready
✗ 1 page failed
! 1 warning
```
