如何让 \bm{} 在 R 降价(到 HTML)文件中工作?

How to get \bm{} to work in an R markdown (to HTML) file?

我的 R Markdown (.Rmd) 文件如下所示:

---
title: Foo
author: Marius Hofert
header-includes:
    - \usepackage{bm}
output:
    pdf_document
vignette: >
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteIndexEntry{Foo}
---
\[
\begin{align}
   \bm{U}=a\bm{X}\quad\boldmath{U}=a\boldmath{X}\quad\mathbf{U}=a\mathbf{X}.
\end{align}
\]

输出(通过 R CMD build./inst/doc/*.html 中的查找获得)是这样的:

为了获得斜体粗体矢量,我想在我的 .Rmd 文档中使用 \bm{X},但它失败了(尽管我加载了包 bm)。为什么?没有 output: pdf_document 部分也会发生同样的情况。

更新

如果我是运行

---
title: Foo
author: Marius Hofert
header-includes:
    - \usepackage{bm}
output:
    pdf_document
vignette: >
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteIndexEntry{Foo}
---
\[
\begin{align}
   \bm{U}=a\bm{X}\quad\boldmath{U}=a\boldmath{X}\quad\mathbf{U}=a\mathbf{X}.
\end{align}
\]

\[
   \bm{U}=a\bm{X}\quad\boldmath{U}=a\boldmath{X}\quad\mathbf{U}=a\mathbf{X}.
\]

\begin{align}
   \bm{U}=a\bm{X}\quad\boldmath{U}=a\boldmath{X}\quad\mathbf{U}=a\mathbf{X}.
\end{align}

我得到(没有错误)

我认为您的 \[ \]\begin{align} ... \end{align} 是多余的。当我 运行 如上所述时,我得到

! Package amsmath Error: Erroneous nesting of equation structures; (amsmath) trying to recover with `aligned'.

See the amsmath package documentation for explanation. Type H for immediate help. ...

l.84 \end{align}

当我删除 \begin{align} ... \end{align} 时对我来说工作正常 ...

(看来也出现了类似的问题...)

(也许您遇到了您没有注意到的错误并且不小心查看了以前编译的版本?)


至于为什么你没有得到正确的 HTML 输出:我很确定 MathJax(用于渲染嵌入 Rmarkdown 的 LaTeX 的引擎 HTML)doesn't know about \boldmath; adding the package to your LaTeX input won't help, you'll have to use \mathbf and \boldsymbol instead. You can play around here 查看哪些有效,哪些无效:输入

$\bm X \boldmath X \boldsymbol X \mathbf X$

在那个网页上给出

最重要的是,如果您想要正确呈现精美的数学,您最好坚持使用 PDF 输出。

我认为 Mathjax(这是 Pandoc 在 HTML 输出中使用的)可以 \usepackage{}。我通过有 2 个文件来解决这个问题:一个叫做 preamble-mathjax.tex,一个叫做 preamble-latex.tex 我的 YAML 元数据是这样设置的(对于 rmarkdown):

output:
    html_document:
       includes:
         before_body: preamble-mathjax.tex
    pdf_document:
       includes:
         in_header: preamble-latex.tex

并且 preamble-mathjax.tex 有(注意围绕 \( \) 以便 mathjax 解析为数学块)

\(
\newcommand{\bm}[1]{\boldsymbol{\mathbf{#1}}}
\)

preamble-latex.tex 有:

\usepackage{bm}

因此,每当我在我的文档中使用 \bm{..} 时,无论我编译为 HTML 还是 PDF,它都有效。 (将 boldsymbolmathbf 堆叠在一起,使希腊字母和普通字母都变成粗体,并且粗体字母保持直立,就像使用 \bm 时一样)。


你的问题的外围: 最终您可能希望拥有第三个文件 preamble-both.tex,其中包含非特定于包的宏(假设相关的 preamble-* 已经包含在内)例如

\newcommand{\bX}{\bm{X}} % bold X
\newcommand{\R}{\mathbb{R}} % real numbers

然后您将其包含在两种输出格式中。这使您无需将所有宏都编写两次,一次用于 html_document,一次用于 pdf_document。但是,MathJax 要求宏被 \(\) 包围,而如果是这种情况,LaTeX 会出错。

我发现解决这个问题的唯一方法是有一个只包含 \( 的文件 bracket-start.txt 和一个只包含 \) 的文件 bracket-end.txt,所以我的 YAML 是:

output:
    html_document:
       includes:
         before_body: [preamble-mathjax.tex, bracket-start.txt, preamble-both.tex, bracket-end.txt]
    pdf_document:
       includes:
         in_header: preamble-latex.tex
         before_body: preamble-both.tex

这很笨拙,但它有效(有 Pandoc latex_macros 扩展,但它对我来说从来没有用过)

另一个解决方案是使用子块参数。缺点是主要的是它只适用于被 $ $ 或 $$ $$ 包围的数学。它在方程式环境中不起作用。好的一面是,您暂时不会在 html 页面的顶部看到您的定义 "flashing",我使用上述解决方案时遇到了这种情况。

demo.Rmd

---
title: Foo
output:
  pdf_document: default
  html_document: default
---

```{r child = 'defs.tex'}
```

My math definitions are in defs.tex.  Now I can use the defs in equations
but they need to be in math mode for html output.  This works for both
pdf and html:
$\AA^\top\BB$ and 
$$\AA^\top\BB$$

But using your new commands in the equation environment
only works for pdf output because pandoc will not expand the
definitions if the newcommands are not in $ $ or $$ $$.    

\begin{equation}
\AA^\top\BB
\end{equation}

defs.tex

\newcommand{\BB}{\mathbf{B}}
\newcommand{\CC}{\mathbf{C}}
\renewcommand{\AA}{\mathbf{A}}

如果您使用 Mathjax 在 html 文档中呈现方程式,则第三种解决方案效果很好。 Mathjax 在 RStudio 的 pandoc 中默认开启。这具有无闪烁的优点,并且适用于 $$ $$ 和方程式环境。这样做的最大缺点是 pandoc 从 html 中删除了 \ref{},因此您必须添加一个编织钩子才能更改为 \ref{}。当然有办法告诉 pandoc 不要这样做,但我找不到。我尝试了许多不同的 pandoc args 但没有成功。

此示例假设您需要方程式编号并且希望在文本中交叉引用这些编号。它还假定您是从 RStudio 编织的。可能其他情况下有效,但这就是我测试的内容。

mathjax.js --- 在这里定义宏并告诉 Mathjax 添加 eqn #s

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config"> 
  MathJax.Hub.Config({ 
    TeX: { 
      equationNumbers: {autoNumber: "all"},
      Macros: {
        AA: "{\bf A}",
        BB: "{\bf B}"
      }
    } 
  });
</script>

defs.tex --- 这是 pdf_document

\def\AA{\bf A}
\def\BB{\bf B}

test.Rmd --- 现在我们可以制作适用于 html 和 pdf 的 Rmd 文档。我不知道如何告诉 pandoc 不要从 html 中删除 LaTeX 命令。所以传入一个编织钩子来加倍 \ref{} 调用。

---
title: "Test"
knit: ( function(inputFile, encoding) { if(rmarkdown::all_output_formats(inputFile)[1]=="html_document"){ f <- inputFile; x <- readLines(f); y <- gsub("[\]ref[{]","\\\\ref{", x); cat(y,file="tmp.Rmd", sep="\n"); rmarkdown::render("tmp.Rmd", encoding = encoding ) }else{ rmarkdown::render(inputFile, encoding = encoding ) } })
output: 
  html_document:
    includes:
      before_body: [../tex/mathjax.html]
  pdf_document: 
    includes: 
      before_body: ../tex/defs2.tex
---

```{r mss-setup, include=FALSE, purl=FALSE}
knitr::opts_knit$set(unnamed.chunk.label = "tvarss-")
```

In the pdf, this will not have a number but in the html it will.

$$
\AA^\top\BB
$$
You can use nonumber if you need the equation numbering to be the same in html and pdf.

$$
\AA^\top\BB\nonumber
$$

If we want to crossref an equation, use equation environment.  
\begin{equation}
\AA^\top\BB
\label{eqn1}\end{equation}
This is Equation \ref{eqn1}.

这里是编织函数:

( function(inputFile, encoding) { if(rmarkdown::all_output_formats(inputFile)[1]=="html_document"){ f <- inputFile; x <- readLines(f) ; y <- gsub("[\]ref[{]","\\\\ref{", x); cat(y,file="tmp.Rmd", sep="\n"); rmarkdown::render("tmp.Rmd", encoding = encoding ) }else{ rmarkdown::render(inputFile, encoding = encoding ) } })