knitr/Rmd:转换为MS Word时添加标题页和文本

crs*_*rsh 6 r ms-word pandoc knitr r-markdown

我正在尝试使用该rmarkdown软件包编写报告,但不幸的是,我的现场报告中的惯例通常作为MS Word文档提交.所以我不能总是依靠它的力量,LaTeX必须能够将我的.Rmd转换为MS Word.现在,因为我希望能够从同一个源文件创建PDF和MS Word文件,所以我试图找到一种通用的方法来实现这一点.我已经使用apa6LaTeX文档类工作了PDF .创建Word文件时.Rmd看起来像这样:

---
title: My title
abstract: This is the abstract.
author: John Doe
affiliation: Unknown
note: Nothing to say.

output:
  word_document:
    reference_docx: myreference.docx
---

Lorem ipsum.
Run Code Online (Sandbox Code Playgroud)

我可以从这里创建一个Word文档,但由于显而易见的原因,我的自定义yaml变量(例如抽象)将不会在文档中呈现.

基本上,我的问题如下:

在创建word文档时,如何在文档正文("Lorem ipsum")之前添加标题页(包括作者姓名,从属关系,作者注释等)和另一页仅包含摘要?这里的重点不是创建分页符(有关于此的其他开放性问题),而是**是否有一种方法可以pandoc使用自定义yaml变量将它们放在文档的开头并为它们分配样式?

该rmarkdown包提供了一个include()功能,但它只适用于HTML和PDF文档.

crs*_*rsh 2

我发现可以在rmarkdown提交之前使用预处理器自定义生成的 Markdown 文件的内容(例如添加和修改标题页)以pandoc进行转换。DOCX假设我们正在尝试在note摘要之前添加 YAML 参数中指定的一些信息(同时添加了对摘要的支持pandoc)。

为此,我们首先需要一个预处理器函数,用于读取输入文件并解析 YAML 前面的内容,并自定义输入文件:

my_pre_processor <- function(metadata, input_file, runtime, knit_meta, files_dir, output_dir, from) {

  # Identify YAML front matter delimiters
  input_text <- readLines(input_file, encoding = "UTF-8")
  yaml_delimiters <- grep("^(---|\\.\\.\\.)\\s*$", input_text)

  if(length(yaml_delimiters) >= 2 &&
     (yaml_delimiters[2] - yaml_delimiters[1] > 1) &&
     grepl("^---\\s*$", input_text[yaml_delimiters[1]])) {
    yaml_params <- yaml::yaml.load(paste(input_text[(yaml_delimiters[1] + 1):(yaml_delimiters[2] - 1)], collapse = "\n"))
  } else yaml_params <- NULL

  # Modify title page
  custom_lines <- c(
    "NOTE:"
    , metadata$note
    , "\n\n"
    , "# Abstract"
    , "\n"
    , metadata$abstract
    , "\n"
  )

  ## Add modified title page components after YAML front matter
  augmented_input_text <- c(custom_lines, input_text[(yaml_delimiters[2] + 1):length(input_text)])

  # Remove redundant default abstract
  yaml_params$abstract <- NULL

  # Add modifications to input file
  augmented_input_text <- c("---", yaml::as.yaml(yaml_params), "---", augmented_input_text)
  input_file_connection <- file(input_file, encoding = "UTF-8")
  writeLines(augmented_input_text, input_file_connection)
  close(input_file_connection)

  NULL
}
Run Code Online (Sandbox Code Playgroud)

现在我们需要定义一个利用预处理器的自定义格式:

my_word_document <- function(...) {
  config <- rmarkdown::word_document(...)

  # Preprocessor functions are adaptations from the RMarkdown package
  # (https://github.com/rstudio/rmarkdown/blob/master/R/pdf_document.R)
  pre_processor <- function(metadata, input_file, runtime, knit_meta, files_dir, output_dir, from = .from) {
    # save files dir (for generating intermediates)
    saved_files_dir <<- files_dir

    args <- my_pre_processor(metadata, input_file, runtime, knit_meta, files_dir, output_dir, from)
    args
  }

  config$pre_processor <- pre_processor
  config
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在渲染 R Markdown 文档时使用自定义格式,如下所示:

rmarkdown::render("./foo/bar.Rmd", output_format = my_word_document())
Run Code Online (Sandbox Code Playgroud)