交叉引用

1 概述

每个可被交叉引用的元素都需要一个 label标签, 并且必须遵守 Quarto 规定的前缀, 例如 #fig-flower-light :

交叉引用标识符必须以类型为前缀(fig- 或 tbl- 等), 所以 #fig-elephant 是有效的,但 #elephant 和 #elephant-fig 是无效的

Warning前缀

下面是 Quarto 规范的交叉引用前缀 : fig, tbl, lst, tip, nte, wrn, imp, cau, thm, lem, cor, prp, cnj, def, exm, exr, sol, rem, alg, eq, sec, _

代码块的 #| label 和元素的ID都不要随便使用这些前缀

2 引用

下面都是引用一个对象合法的语法 :

还可以将多个引用分组在一起 :

一系列引用 [@fig-elephant; @fig-panther; @fig-rabbit].

3 浮动体

图表、表格 和 代码块 被称为 “浮动体” 。 浮动体渲染与定义的位置可以不同, 可以用 Markdown 和 围栏 两种方式定义浮动体

3.1 图表

下面是 Markdown 语法定义图表 :

![大象](elephant.png){#fig-elephant}

见 @fig-elephant 了解更详细的信息

还可以使用 div 语法 :

3.2 子图

用围栏包裹多张图片,给整体和每张图片分别加标签, 每个都可以被交叉引用 :

3.3 图形计算单元

Kinitr 构建的图表可以被交叉引用, 只需要在代码块上给图表增加 label 和 fig-cap :

Warning计算单元标题

动态图形, 不用前缀 fig-cap 或 tbl-cap 参考

一个代码块里面还可以创建多张子图, 并且可以对子图进行引用 :

3.4 表格

在表格下方添加标题, 接着在后面花括号中包含 #tbl- 标签, 就可以引用表格 :

还可以使用围栏语法的表格 :

3.5 子表格

下面范例的总表和子表都可以被交叉引用 :

3.6 表格计算单元

可以将代码块计算出来的表格加上 label 和 tbl-cap 来进行引用 :

一个代码块里面也可以创建多个表格, 并且每个都可以被引用 :

3.7 代码列表

要创建可引用的代码,需要添加 #lst- 标识符和 lst-cap 属性 :

也可以使用围栏创建代码的交叉引用,以 lst- 前缀给围栏设置标识符, 在围栏内包含标题 :

要交叉引用代码, 需要添加代码块的 lst-label 和 lst-cap 选项 :

如果既想引用源码, 又想引用图表可以采样下面的方法 :

4 提示框

要交叉引用一个提示框, 添加 #tip- 前缀 :

提示框的外观比较多, 下面是对应的前缀 :

提示框类型 前缀
tip #tip-
note #nte-
warning #wrn-
important #imp-
caution #cau-

下面是如何修改交叉引用的标题 :

5 定理与证明

定理在数学文章和书籍中经常用到。 需要创建一个 #thm- 围栏 :

Quarto 支持多种定理变体, 每种都有自己的标签前缀 :

Label Prefix Printed Name
#thm- Theorem 定理
#lem- Lemma 引理
#cor- Corollary 推论
#prp- Proposition 命题
#cnj- Conjecture 猜想
#def- Definition 定义
#exm- Example 示例
#exr- Exercise 习题
#sol- Solution 解答
#rem- Remark 备注
#alg- Algorithm 假设

还可以进入定理环境(通常指AMS定理环境), 用来进行证明 :

6 公式

公式后面加上 #eq- 标签就可以被交叉引用 :

7 章节

在章节的后面增加 #sec- 标签就可以被交叉引用 :

8 交叉引用选项

有大量选项自定义标题标签和引用。 这些选项全部在 YAML 元数据中的 crossref 键下 。下面是修改 xxx-title 的范例 :

8.1 引用前缀

引用一个对象的时候, 默认链接前缀是它的 title。 这个选项可以修改 :

8.2 本地化

上述 crossref: 键会覆盖当前文档的标题和引用前缀,并且与语言无关。 如需进行本地化相关的覆盖, 在 language: 下设置相应的 crossref-{type}-title 和 crossref-{type}-prefix 键。 可以针对每个目标语言进行作用域设置, 并且可以位于项目级别的 _language.yml 文件中 :

---
title: "cross references"
language:
  zh: 
    crossref-fig-title: "Fg"
    crossref-fig-prefix: "fg."
---

8.3 编号规则

交叉引用可使用多种编号规则, 默认使用数字 1、2、3... :

可以将编号和子编号进行分开设置规则 :

还可以单独为某一类型的子图设置编号规则 :

---
title: "cross references"
crossref:
  fig-labels: alpha a    # (default is arabic)
  tbl-labels: alpha a    # (default is arabic)
  subref-labels: roman i # (default is alpha a)
---

9 围栏语法

可交叉引用的 图表、表格 和 代码 统称为 浮动体。 浮动体渲染后的位置与其定义的位置可以不相同,浮动体都可以用围栏定义。下面是一个表格,被 当作图片 处理, 并且浮动到了侧边栏 :

A B
C D
Figure 1: 一个表格像一个图片, 通常图片的标题在图片下方, 表格的标题在上方
::: {#fig-table .column-margin}

| A | B |
|---|---|
| C | D |

一个表格像一个图片, 通常图片的标题在图片下方, 表格的标题在上方

:::

Table 1 是一个图片, 看起来像表格 :

Table 1

::: {#tbl-table .column-margin}

![](table.png)

一个图片看起来像表格, 标题在最上面

:::

Figure 2 一个代码块处理的像图表 :

library(tidyverse)
starwars |> 
  ggplot(aes(height, mass)) + 
  geom_point()
Figure 2: 一个代码块,处理的像图表
::: {#fig-code .column-margin}

```r
library(tidyverse)
starwars |> 
  ggplot(aes(height, mass)) + 
  geom_point()
```

一个代码块,处理的像图表

:::

9.1 图表

要使用围栏语法创建对图片的交叉引用,创建一个以 fig- 开头的标签, 并在该标签内包含图片及其标题 :

::: {#fig-elephant}

![](elephant.png)

An Elephant
:::

如果代码生成图片,也可以把代码放到图表围栏里面 :

::: {#fig-line-plot}

```{python}
import matplotlib.pyplot as plt
plt.plot([1,23,2,4])
plt.show()
```

A line plot
:::

上例中可以用 @fig-line-plot 引用这张图

9.2 表格

要使用围栏语法创建指向表的交叉引用,需创建一个以 tbl- 开头的围栏,并在围栏内依次放入表格和标题 :

::: {#tbl-letters}

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

My Caption

::: 

如果该表由可执行代码块生成, 可以把代码块作为内容放进去 :

Table 2: 天体对象
library(knitr)

table <- data.frame(
  `Astronomical object` = c("Sun", "Earth", "Moon", "Mars"),
  `R (km)`              = c("696,000", "6,371", "1,737", "3,390"),
  `mass (kg)`           = c(1.989e30, 5.972e24, 7.34e22, 6.39e23),
  check.names = FALSE
)

kable(table, format = "markdown")
Astronomical object R (km) mass (kg)
Sun 696,000 1.989e+30
Earth 6,371 5.972e+24
Moon 1,737 7.340e+22
Mars 3,390 6.390e+23
::: {#tbl-planets .column-margin}

```{r}
library(knitr)

table <- data.frame(
  `Astronomical object` = c("Sun", "Earth", "Moon", "Mars"),
  `R (km)`              = c("696,000", "6,371", "1,737", "3,390"),
  `mass (kg)`           = c(1.989e30, 5.972e24, 7.34e22, 6.39e23),
  check.names = FALSE
)

kable(table, format = "markdown")
```

天体对象

:::

9.3 源码列表

要使用围栏语法创建指向代码清单的交叉引用,需创建一个以 lst- 开头的围栏,并在围栏内放入代码和标题 :

Listing 1: 用户查询
SELECT * FROM Customers
::: {#lst-customers .column-margin}

```{.sql}
SELECT * FROM Customers
```

用户查询

:::

同样适用于不产生输出的可执行代码单元格 :

Listing 2: R 语言任务
x <- 1
::: {#lst-assign .column-margin}

```{r}
x <- 1
```

R 语言任务
:::

如果输出图表或者表格, 最好使用代码块选项来交叉引用

9.4 示意图

要使用围栏语法创建指向示意图的交叉引用,就把它当作图表来处理。例如 Figure 3 是用下面的代码创建的 :

A A B B A--B

Figure 3: 这是一个简单的用 graphviz 绘制的图
::: {#fig-simple}

```{dot}
graph {
  A -- B
}
```

这是一个简单的用 graphviz 绘制的图
:::

如果希望给示意图一个独立于 #fig- 的标签与计数器,可以考虑使用自定义交叉引用类型

9.5 子引用

围栏可以进行嵌套, 从而创建带有 子引用 的元素。 下面范例的外层定义了 fig-subrefs 这个引用以及主标题, 而内层的围栏则分别定义了 fig-first 和 fig-second 以及它们各自的子标题 :

结合 layout 属性, 可以创建由不同类型内容组成的复杂布局,并且每个元素都可以被引用 :

10 标题计算

如果在标题中包含计算得到的值, 可以使用围栏语法, 并结合内联表达式 :

11 条件内容

将交叉引用围栏语法与 条件内容 结合使用,可以让被引用的内容根据输出格式而变化。下面范例在输出格式为 HTML 时使用基于 JavaScript 的交互式图表,而在其他格式下生成静态图表 :

.content-visible 和 .content-hidden 用于控制内容是否显示在输出中,但不会阻止包裹的代码执行。如果需要完全跳过执行, 可以让代码块读取 QUARTO_EXECUTE_INFO 变量

11.1 content-visible

要让内容仅在特定格式下可见,可以创建一个带有 .content-visible 类的围栏。下面把内容标记为仅在 pdf 中可见 :

也可以对不执行的代码块设置条件 :

如果只想对文章中的一部分内容应用条件,可以使用 []{} 语法 :

也可以把内容标记为除指定格式外的所有格式都可见 :

when-format 和 unless-format 属性会匹配当前的 Pandoc 输出格式,并带有一些额外智能来对相关格式做别名处理(例如 html、html4、html5)

when-format 和 unless-format 也可以组合使用,构成更复杂的条件 :

::: {.content-visible when-format="html" unless-format="revealjs"}
  仅出现在 HTML 中,不出现在 Reveal.js 中
:::

::: {.content-visible when-format="revealjs"}
  仅出现在 Reveal.js 中,不出现在 HTML 或其他格式中
:::

11.2 content-hidden

为了防止内容在渲染为特定格式时显示,请使用 .content-hidden 。 这里将内容标记为在 HTML 中隐藏 :

也可以将内容标记为除指定格式外、对所有格式都隐藏 :

11.3 格式匹配

when-format 和 unless-format 子句会对相关格式做别名处理,让你定位目标格式时更直观。已实现的别名如下 :

别名 覆盖的格式
latex latex, pdf, beamer
pdf latex, pdf, beamer
epub epub*
html html, epub, revealjs, dashboard, email
html:js html*, revealjs, dashboard, email
markdown markdown, commonmark, gfm, markua, hugo-md, docusaurus-md
odt odt, opendocument
hugo hugo-md
docusaurus docusaurus-md
asciidoc asciidoc, asciidoctor
Warning注意

html:js 这个别名表示目标格式能够执行 JavaScript(映射到除 ePub 之外的所有 HTML 格式)

11.4 变量匹配

使用 unless-meta 和 when-meta 可以对布尔型变量进行匹配 :

还可以使用 配置文件 进行匹配

11.5 QUARTO_EXECUTE_INFO匹配

Quarto 在渲染文档前会构建一个 JSON 文件给变量 QUARTO_EXECUTE_INFO, 代码块可以读取变量 QUARTO_EXECUTE_INFO, 从中获得渲染的目标格式。下面代码在渲染 html 格式时输出交互图表,pdf 时输出图片 :

library(jsonlite)

info <- fromJSON(Sys.getenv("QUARTO_EXECUTE_INFO"))
fmt <- info$format$identifier$`target-format`

if (fmt == "html") {
  plotly::plot_ly(mtcars, x = ~wt, y = ~mpg, type = "scatter", mode = "markers")
} else if (fmt %in% c("pdf", "latex")) {
  plot(mtcars$wt, mtcars$mpg, xlab = "wt", ylab = "mpg", main = "mpg 与 wt 的关系")
}

12 链接