R 在外部LaTeX文件中将YAML参数作为宏访问

R 在外部LaTeX文件中将YAML参数作为宏访问,r,r-markdown,knitr,pandoc,R,R Markdown,Knitr,Pandoc,我正在寻找将变量(或LaTeX宏)添加到YAML头中的方法,或在不久之后添加到YAML头中,以便它们可以用于作为我(模块化)报告一部分的外部.tex文件中 我的.rmd文件 --- output: pdf_document: latex_engine: xelatex includes: before_body: some.tex params: cat: "Felix" numb: 14 --- # chapter Oh my \textbf{`r p

我正在寻找将变量(或LaTeX宏)添加到YAML头中的方法,或在不久之后添加到YAML头中,以便它们可以用于作为我(模块化)报告一部分的外部
.tex
文件中

我的
.rmd
文件

---
output:
  pdf_document:
    latex_engine: xelatex
    includes:
      before_body: some.tex
params:
  cat: "Felix"
  numb: 14
---

# chapter
Oh my \textbf{`r params$cat`}. 
$x = `r 2*params$numb`^2$

<!-- Trying again to get the parameter -->
\input{some.tex}
输出

希望的产出


我希望能够以某种方式从YAML标题(甚至就在其下方)传递变量,以便LaTeX使用,以便可以在一个位置查看和更改所有重要的和定期更新的参数。

我相信您可以使用lua过滤器将一些内容编码在一起

首先提出您自己的包含机制(因为这需要在变量替换之前发生,所以您不能使用latex的
\input
),但例如:

功能段(elem)
如果#elem.content==1,elem.content[1].t==“Image”,那么
本地img=元素内容[1]
如果img.classes[1]=“降价”,则
本地f=io.open(img.src,'r')
本地块=pandoc.read(f:read('*a')).blocks
f:关闭()
返回块
结束
结束
结束
然后进行变量替换,例如:

localvars={}
函数get_vars(meta)
对于k,v成对(meta)do
如果v.t=='MetaInlines',则
vars[“$”.k..“$”]={table.unpack(v)}
结束
结束
结束
功能替换(el)
如果变量[el.text],则
返回pandoc.Span(变量[el.text])
其他的
返回el
结束
结束
返回{Meta=get_vars},{Str=replace}
这应该像这样工作:

---
output:
  pdf_document:
    latex_engine: xelatex
    pandoc_args:
      - '--lua-filter=include.lua'
      - '--lua-filter=substitution.lua'
name: Samuel
---

Look, I can include files:

![](include.md){.markdown}
include.md
中:

Look, I can use variables: \$name\$

这只是半途而废。仍然没有文件作为头输入

也许这个答案会给其他人一个想法

---
output:
  pdf_document:
    latex_engine: xelatex
params:
  cat: "Felix"
  numb: 14
header-includes:
- \usepackage{fancyhdr}
- \pagestyle{fancy}
- \fancyhead[CO,CE]{`r params$cat`}
---

# CHAPTER 1
Oh my \textbf{`r params$cat`}. 
$x = `r 2*params$numb`^2$

```{r child = 'some.tex'}
```
截图pdf


您可以在YAML头中创建TeX或LaTeX宏,并在
some.TeX
文件中使用该宏

例如,将其放在主文件中:

---
output:
  pdf_document:
    latex_engine: xelatex
      includes:
        before_body: some.tex
header-includes:
- \def\thecat{`r params$cat`}
params:
  cat: "Felix"
  numb: 14
---


# chapter
Oh my \textbf{`r params$cat`}. 
$x = `r 2*params$numb`^2$

\input{some.tex}
并将其放入
some.tex

\thecat
事情会以你想要的方式展现出来


如果您正在寻找最符合R Markdown工作流的东西,您可以定制用于构建LaTeX输出的模板,并将所有额外的LaTeX代码直接添加到此模板中

1。复制模板

---
output:
  pdf_document:
    latex_engine: xelatex
    includes:
      before_body: some.tex
params:
  cat: "Felix"
  numb: 14
---

# chapter
Oh my \textbf{`r params$cat`}. 
$x = `r 2*params$numb`^2$

<!-- Trying again to get the parameter -->
\input{some.tex}
首先,我们必须复印这份报告。以下代码将在当前工作目录中创建此文件:

file.copy(system.file("rmd/latex/default-1.17.0.2.tex",
          package = "rmarkdown"), "template.tex")
2。添加变量

使用我们的副本,我们可以定义自己的副本,该副本将插入到输出文档中。这允许我们在文档的YAML部分中指定参数,并以输出格式更新这些参数。正是这种机制允许我们添加
标题
作者
日期
,并将它们添加到输出格式中

我在文档的前面添加了一些代码。确切的位置并不重要,但我也倾向于将我的定制放在
\begin{document}
参数之前:

\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[LO, LE]{$params.value$}
\fancyhead[RO, RE]{$yourParam$}
3。从R降价调用模板

我们可以将自定义模板引用到我们的R降价文档。以下是我的最简单的例子:

---
output:
  pdf_document:
    template: template.tex
params:
  value: Text
yourParam: "`r Sys.Date()`"
---

`r params$value`
这两个参数将被添加到输出中,替换
$params.value$
$yourParam$
,并产生以下输出:

该示例强调了YAML参数如何不必嵌套在原始问题中指定的
params
参数中。如果您想构建一个

注意:使用pandoc符号替换变量的方法
$variable$
仅适用于在
模板
选项下定义的主模板文件。它不适用于任何
includes
参数或任何其他外部文件。有关更多详细信息,请参阅


让我重新表述一下这个问题:目标是编写一份参数化的报告。此报表使用
\input
嵌入TEX文件(例如
some.TEX
)。您正在寻找访问
some.tex
中YAML参数的方法

一种方法是根据YAML参数定义LaTeX宏,例如YAML参数
cat:“Felix”
变成
\newcommand{\cat}{Felix}
。这些TEX宏可以在整个文档中使用。(在主文件中,
r params$cat
也可以工作,但是由于
一些.tex
没有被编织,这里只有
\cat
工作。)

首先,对R码进行求值。它读取所有YAML参数,并通过
头文件includes
将相应的宏写入
myparams.tex
.1。生成的文件
myparams.tex
包含在中间tex文件中,该文件最终被编译为PDF

主RMD文件

---
output: pdf_document
header-includes: "\\input{myparams.tex}"
params:
  cat: "Felix"
  numb: 14
---

```{r, include = FALSE}
if (file.exists("myparams.tex")) {
  file.remove("myparams.tex") # CAUTION: this will DELETE any existing file "myparams.tex"
}
for (param in names(params)) {
  cat(sprintf("\\newcommand{\\%s}{%s}\n", param, params[param]), file = "myparams.tex", append = TRUE)
}
```

Oh my \cat. 
$x = 2 \cdot \numb^2$

Or alternatively: Oh my `r params$cat`. 

\input{some.tex}
Oh my \cat. % Here, `r params$cat` won't work.
some.tex

---
output: pdf_document
header-includes: "\\input{myparams.tex}"
params:
  cat: "Felix"
  numb: 14
---

```{r, include = FALSE}
if (file.exists("myparams.tex")) {
  file.remove("myparams.tex") # CAUTION: this will DELETE any existing file "myparams.tex"
}
for (param in names(params)) {
  cat(sprintf("\\newcommand{\\%s}{%s}\n", param, params[param]), file = "myparams.tex", append = TRUE)
}
```

Oh my \cat. 
$x = 2 \cdot \numb^2$

Or alternatively: Oh my `r params$cat`. 

\input{some.tex}
Oh my \cat. % Here, `r params$cat` won't work.
输出

---
output: pdf_document
header-includes: "\\input{myparams.tex}"
params:
  cat: "Felix"
  numb: 14
---

```{r, include = FALSE}
if (file.exists("myparams.tex")) {
  file.remove("myparams.tex") # CAUTION: this will DELETE any existing file "myparams.tex"
}
for (param in names(params)) {
  cat(sprintf("\\newcommand{\\%s}{%s}\n", param, params[param]), file = "myparams.tex", append = TRUE)
}
```

Oh my \cat. 
$x = 2 \cdot \numb^2$

Or alternatively: Oh my `r params$cat`. 

\input{some.tex}
Oh my \cat. % Here, `r params$cat` won't work.
哦,我的菲利克斯<代码>x=2·14²

或者:哦,我的菲利克斯

哦,我的菲利克斯,又来了

myparams.tex的内容(动态生成):



1为所有新LaTeX宏使用唯一前缀可能是一个好主意,以避免内置LaTeX命令和同名YAML参数之间的冲突。

在某些情况下,我可以使用将tex文件作为子文件而不是
\include
,但如果我想在序言(在标题中)中使用…我可以问一下您为什么要寻找外部LaTeX文件吗?如果您想从多个文件生成R标记文档,可以使用bookdown:@MichaelHarper感谢指针(将查看bookdown)。这是一种使事情(高度定制的报告)模块化和可管理的努力。如果将
include>的所有内容都放在原始标记的标题中(>100行代码),那会有点混乱