如何在R vignette中对公式进行编号与交叉引用?
问题描述
我希望在R vignette中演示自己的matlib包中新函数生成LaTeX的功能。symbolicMatrix()和Eqn()可生成带标签的LaTeX公式代码,示例如下:
symbolicMatrix(lhs = "\\mathbf{X}") |> Eqn(label="eq:X")
生成的LaTeX代码:
\begin{equation} \label{eq:X} \mathbf{X} = \begin{pmatrix} x_{11} & x_{12} & \cdots & x_{1m} \\ x_{21} & x_{22} & \cdots & x_{2m} \\ \vdots & \vdots & & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{nm} \\ \end{pmatrix} \end{equation}
这段代码在PDF输出的.Rmd文档中可正常显示公式编号并实现交叉引用,但在HTML vignette中完全失效:既没有公式编号,也无法通过\ref{eq:X}完成交叉引用。
我使用的示例代码如下:
--- title: "Can I Number Equations in a Vignette?" author: An Author date: "`r Sys.Date()`" output: bookdown::html_document2: base_format: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Can I Number Equations in a Vignette?} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} ---
```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE)
library(matlib)
symbolicMatrix(lhs = "\\mathbf{X}") |> Eqn(label="eq:X")
Can I reference this as: See \ref{eq:X}
# 解决方法 要在HTML vignette中实现公式编号与交叉引用,需让生成的LaTeX公式被bookdown正确识别处理,以下是两种可行方案: ## 方案1:适配bookdown HTML的公式输出格式 bookdown的HTML输出支持用`$$`包裹公式并添加标签的语法(`$$\label{eq:X} ... $$`),而非原生LaTeX的`equation`环境。可以自定义一个适配的`Eqn`函数,转换输出格式: ```r # 自定义适配HTML的Eqn函数 Eqn_html <- function(x, label = NULL) { # 捕获原Eqn函数的输出 latex_output <- capture.output(Eqn(x, label = NULL)) # 移除equation环境首尾行,提取核心公式内容 formula_content <- gsub("^\\\\begin{equation}|^\\\\label.*|\\\\end{equation}$", "", latex_output) formula_content <- paste(formula_content, collapse = "\n") # 用bookdown兼容的格式输出 if (!is.null(label)) { cat(paste0("$$\\label{", label, "}\n", formula_content, "\n$$")) } else { cat(paste0("$$\n", formula_content, "\n$$")) } } # 使用示例 symbolicMatrix(lhs = "\\mathbf{X}") |> Eqn_html(label="eq:X")
同时,交叉引用需改用bookdown的\@ref(eq:X)语法,替换原生的\ref{eq:X}:
Can I reference this as: See \@ref(eq:X)
方案2:启用MathJax的公式自动编号
bookdown的html_document2依赖MathJax渲染公式,可通过配置MathJax开启自动编号,并确保标签被识别。首先修改vignette的YAML头部:
output: bookdown::html_document2: base_format: rmarkdown::html_vignette mathjax: "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" includes: in_header: mathjax_config.html
然后创建mathjax_config.html文件,添加以下配置:
<script> MathJax = { tex: { tags: 'ams', // 启用AMS风格公式编号 labels: { tag: (id) => '(' + id + ')' // 设置编号格式 } } }; </script>
此方案下,原Eqn()生成的equation环境LaTeX代码会被MathJax正确解析并添加编号,交叉引用同样需要使用\@ref(eq:X)语法。
关键注意点
- 必须使用
bookdown::html_document2作为输出格式,基础的rmarkdown::html_vignette不支持交叉引用功能。 - 交叉引用只能用bookdown的
\@ref(label)语法,原生LaTeX的\ref{}在HTML环境中无法生效。
内容的提问来源于stack exchange,提问作者user101089
相关产品推荐
相关产品推荐

