Rmarkdown和PDF输出:在Latex部分中评估Markdown

时间:2020-05-09 12:57:56

标签: r latex r-markdown knitr pandoc

如何使Latex代码中使用的降价代码得到评估? (带有PDF(Latex)输出的Rmarkdown)

非常简单的最小示例:

\begin{center}
**should be bold text**
\end{center}

使用knitr编译后的.tex文件中的当前输出:

\begin{center}
**should be bold text**
\end{center}

预期:

\begin{center}
\textbf{should be bold text}
\end{center}

我很乐于找到一种方法来使此工作正常进行,因为我试图找到一种方法,可以通过kable / kableExtra传递小节/数据帧。表格单元格已经可以包含Latex代码,但不能包含降价代码,因为kable会将所有内容转换为Latex结构。

在我看来,任何Latex代码块中的所有Markdown代码都不会得到评估。

我知道仅使用Latex代码也可以达到相同的结果,但是我更喜欢尽可能使用Markdown快捷方式。

编辑:

@duckmayr愿意提供另一个最小的示例,以查看如何自动更改R函数产生的Latex代码以使其起作用(连同建议的并接受的答案thx)。因此,我正在寻找一种无论我使用什么R函数都可以工作的包装器(这里:一个基本的R示例和一个简单的kable测试;也可以是Stargazer或其他东西)

---
title: "Untitled"
output: 
  pdf_document:
    keep_tex: true
    df_print: kable
header-includes:
    - \let\Begin\begin
    - \let\End\end
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, results='hide', message=FALSE, warning=FALSE)
library(kableExtra)
```


```{r test1, results='asis'}
test = function(x=1){
  cat('\\begin{center}\n**test**\n\\end{center}')
}
test()
```

```{r test2, results='asis'}
kable(data.frame(x=c("**bold text**")),"latex")
```

2 个答案:

答案 0 :(得分:3)

几年前有人打开an issue on the pandoc GitHub repo about this,并且we can find there a workaround:为\begin{}\end{}制作LaTeX同义词。因此,要在R Markdown中使用此功能,我们只需将它们放在header-includes中:

---
title: "Stack Overflow Answer"
author: "duckmayr"
date: "5/9/2020"
output:
    pdf_document:
        keep_tex: true
header-includes:
    - \let\Begin\begin
    - \let\End\end
---

\Begin{center}

**should be bold text**

\End{center}

LaTeX输出:

... Many initial lines skipped ...
\let\Begin\begin
\let\End\end

\title{Stack Overflow Answer}
\author{duckmayr}
\date{5/9/2020}

\begin{document}
\maketitle

\begin{center}

\textbf{should be bold text}

\end{center}

\end{document}

PDF输出:

enter image description here

更新:使用kable()之类的东西怎么办?

要处理kable()在R块中使用results='asis'之类的事情,我们需要修复kable()的输出;也就是说,我们需要将其\begin{}\end{}标记更改为\Begin{}\End{},并且还需要确保我们最终不会转换\\个序列到textbackslash{}个。这是我们的处理方式:

---
title: "Untitled"
output: 
  pdf_document:
    keep_tex: true
    df_print: kable
header-includes:
    - \let\Begin\begin
    - \let\End\end
    - \newcommand{\Newrow}{\\}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, results='hide', message=FALSE, warning=FALSE)
library(kableExtra)
allow_markdown <- function(tex) {
    tex <- gsub("begin", "Begin", tex) ## fix \begin{} tags
    tex <- gsub("\\\\end", "\n\\\\End", tex) ## fix \end{} tags
    tex <- gsub("\\\\\\\\", "\\\\Newrow\n", tex) ## fix new row \\
    return(tex)
}
```

```{r test2, results='asis'}
kable(data.frame(x=c("**bold text**")),"latex")
```

```{r test3, results='asis'}
allow_markdown(kable(data.frame(x=c("**bold text**")), "latex"))
```

我们在带有\newcommand{\Newrow}{\\}的标头中添加了一个新的LaTeX命令,以便我们可以安全地添加\\,而无需将其转换为\textbackslash{}。之所以有此必要,是因为我们如何诱使pandoc在\Begin\End之间的环境中处理降价。

我们还添加了一个R函数,用于修复kable()的LaTeX输出,该输出修复了开始和结束标签以及新行\\字符。

然后,我们将获得以下LaTeX和PDF输出:

[header omitted]
\begin{document}
\maketitle

\begin{tabular}{l}
\hline
x\\
\hline
**bold text**\\
\hline
\end{tabular}

\begin{tabular}{l}
\hline

x\\

\hline

\textbf{bold text}\\

\hline

\end{tabular}

\end{document}

enter image description here

答案 1 :(得分:1)

如果您只需要一个简单的LaTeX环境,建议您在Pandoc的Markdown中使用围栏的Div块(有关详细信息,请访问see this section in the R Markdown Cookbook),例如

::: {.center}
**should be bold text**

```{r}
knitr::kable(head(iris))
```
:::

在带围栏的Div块中,您可以编写任意Markdown内容。此外,这也适用于HTML输出。

请注意,此功能需要相对较新的Pandoc版本和开发版本的 rmarkdown 。您可以将RStudio Preview version(如果使用RStudio)与remotes::install_github('rstudio/rmarkdown')一起使用。