用rmarkdown::render()把一个标记文件转换成pdf格式,并调整页边距和字体

3lxsmp7m  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(229)

我想呈现一个简单的降价文件,这是由另一个进程之前,到一个pdf文件。
命令:

rmarkdown::render(input = "my_report.md", 
                  output_format = rmarkdown::pdf_document(latex_engine = "xelatex"))

只是做这份工作。
但是我想修改页边距和主字体。对于.Rmd文件,可以在Yaml头文件中定义这些设置,如下所示:

---
output: 
  pdf_document:
    latex_engine: xelatex
mainfont: LiberationSans
geometry: "left=5cm,right=3cm,top=2cm,bottom=2cm"
---

但是我想转换的markdown文件没有Yaml头文件,有没有办法把这些Yaml选项作为函数参数或者间接地传递给render函数?

nimxete2

nimxete21#

这是可能的,但只是使用了一些技巧,它可能不会对所有可能的参数都有效,但似乎对mainfontgeometry有效。
这些设置传递给LaTeX的方式是作为Pandoc变量插入到模板中。问题是,如果你的YAML中没有边距,pdf_document驱动程序会硬编码1英寸的边距,这些边距会被添加到Pandoc命令行的最后。你甚至需要在以后覆盖这个设置。
有一种方法可以做到这一点:创建自己的输出格式,该格式基于pdf_document,但在最后添加自己的变量设置。

my_pdf_document <- function(geometry, mainfont, ...) {
  force(geometry)
  force(mainfont)
  result <- rmarkdown::pdf_document(...)
  oldpreproc <- result$pre_processor
  result$pre_processor <- function(...) {
    c(oldpreproc(...),
      "--variable",
      paste0("geometry:", geometry),
      "--variable",
      paste0("mainfont:", mainfont))
  }
  result
}

当你想用这个预处理器渲染时,给pdf_document给予你想给pdf_document的参数,以及用Pandoc变量设置的参数,例如。

rmarkdown::render("test.md",
              output_format = my_pdf_document(
                geometry = "left=5cm,right=3cm,top=2cm,bottom=2cm", 
                mainfont = "Helvetica", 
                latex_engine="xelatex")
             )

当我执行上面的调用时,我看到一个Pandoc命令,如下所示:

/Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/pandoc
  +RTS -K512m -RTS test.md --to latex --from
  markdown+autolink_bare_uris+tex_math_single_backslash 
  --output test.tex 
  --lua-filter /Library/Frameworks/R.framework/Versions/4.2/Resources/library/rmarkdown/rmarkdown/lua/pagebreak.lua 
  --lua-filter /Library/Frameworks/R.framework/Versions/4.2/Resources/library/rmarkdown/rmarkdown/lua/latex-div.lua 
  --embed-resources --standalone --highlight-style tango 
  --pdf-engine xelatex --variable graphics 
  --variable 'geometry:margin=1in' 
  --variable 'geometry:left=5cm,right=3cm,top=2cm,bottom=2cm' 
  --variable 'mainfont:Helvetica'

(虽然它都在一个很长的行上,没有 Package 得那么整齐)。倒数第三行是有问题的边距设置,最后两行是我们特殊输出格式的结果。
编辑以添加:
一个更简单、不那么笨拙的方法是读取整个Markdown文件,然后用YAML头文件再次写出它,然后你可以在头文件中放入任何你喜欢的东西,如果硬编码版本可以工作,它也可以工作。

5us2dqdw

5us2dqdw2#

选项01

geometrymainfontPandoc variables,您可以通过pandoc_args参数将它们传递给rmarkdown::pdf_document
为了方便起见,你可以使用rmarkdown::pandoc_variable_arg来指定pandoc参数的名称-值对,并且你需要使用template=NULL,这样rmarkdown默认模板就不会被使用(否则,无论传递到pandoc_arg的变量值是什么,都会被geometry:margin=1in附加,所以你指定的几何值将被rmarkdown默认值覆盖)。

library(rmarkdown)

render(
  input = "input.md",
  output_format = rmarkdown::pdf_document(
    latex_engine = "xelatex",
    template = NULL,
    pandoc_args = c(
      pandoc_variable_arg("geometry", "left=5cm,right=3cm,top=2cm,bottom=2cm"),
      pandoc_variable_arg("mainfont", "LiberationSans")
    )
  )
)

我们可以看到变量被正确地传递给了pandoc,

/usr/lib/rstudio-server/bin/quarto/bin/tools/pandoc +RTS -K512m -RTS 
input.md --to latex --from markdown+autolink_bare_uris+tex_math_single_backslash 
--output input.tex --lua-filter /cloud/lib/x86_64-pc-linux-gnu-library/4.2/rmarkdown/rmarkdown/lua/pagebreak.lua 
--lua-filter /cloud/lib/x86_64-pc-linux-gnu-library/4.2/rmarkdown/rmarkdown/lua/latex-div.lua 
--embed-resources --standalone --highlight-style tango 
--pdf-engine xelatex 
--variable geometry=left=5cm,right=3cm,top=2cm,bottom=2cm 
--variable mainfont=LiberationSans

选项02

或者,可以通过--metadata-file pandoc参数从yaml文件(与输入markdown文件位于同一目录中)传递这些YAML选项。
因此,在yaml文件中指定pandoc变量的名称和值,如下所示,

主文件.yml

author: Jphn Doe
mainfont: LiberationSans
geometry:
  - left=5cm
  - top=2cm
  - right=3cm
  - bottom=2cm
linestretch: 1.5
pagestyle: headings

然后运行rmarkdown::render,(此处您仍然需要使用template=NULL,否则您在main.yml中指定的几何图形将被rmardown默认值geometry:margin=1in覆盖)

library(rmarkdown)

render(
  input = "test_yaml.md",
  output_format = rmarkdown::pdf_document(
    latex_engine = "xelatex",
    template = NULL,
    pandoc_args = c("--metadata-file", "main.yml")
  )
)

input.md(用于测试代码的标记文件)

# Rmarkdown

Hello from rmarkdown.

Lorem ipsum dolor sit amet, odio nec ornare tempor semper eget. Ligula lorem,
torquent ante mauris torquent feugiat dis finibus vitae.

第一个选项的输出

第二个选项的输出

相关问题