How can I set the Rmarkdown output template file dynamically in the YAML header as part of a package?

27 views Asked by At

I've got a package that saves data.frames as formatted tables in Word files, but I'm having trouble with using anything other than the default for the Word template. Inside my function, I call on rmarkdown::render with something like this:

rmarkdown::render(system.file("rmarkdown/templates/savemytable/skeleton/skeleton.Rmd",
                                package="mypackage")
                    quiet = TRUE)
  

Here's the YAML header for the skeleton.Rmd file that this calls on:

---
date: "Compiled on `r format(Sys.time(), '%B %d, %Y')`"
output: word_document
---

I would like to include a template Word file in my package that would allow people to save this in a landscape orientation, so I have saved a template Word file in the inst folder with a path like this:

 inst/Word/landscape_report_template.dotx

If I run this:

 system.file("Word/landscape_report_template.dotx",
                              package="mypackage")

that gets me the file path to landscape_report_template.dotx, so it seems like that part is working fine. However, I can't figure out how to adjust the output part of the YAML header to take anything but a hard-coded file path. This works:

 output: 
  word_document:
        reference_docx: "C:/Users/myname/mypackage/inst/Word/landscape_report_template.dotx"

But that obviously won't work for other users. I have tried the following, which all result in "Error: pandoc document conversion failed with error 99".

 output: 
  word_document:
        reference_docx: !r system.file("Word/landscape_report_template.dotx",
                          package="mypackage")


 output: 
  word_document:
        reference_docx: "`r system.file("Word/landscape_report_template.dotx",
                          package="mypackage")`"

and a few other variations on places to insert " or ` to try to get what I want. How can I dynamically specify the path of the reference_docx file?

UPDATE: This seems to be strangely difficult to do natively with rmarkdown. I've seen a few brief and not terribly illustrative examples using rmarkdown::yaml_front_matter to extract what the various YAML parameters are and then change the ones you want, but I don't get how you then put that information back into the skeleton.Rmd file in a package, e.g,.

 yaml_meta <- rmarkdown::yaml_front_matter(system.file("rmarkdown/templates/savemytable/skeleton/skeleton.Rmd", 
      package="mypackage"))

  # Modify YAML
  yaml_meta$output$word_document$reference_docx <- 
      system.file("Word/landscape_report_template.dotx",
                          package="mypackage")
  

But then what? Would you overwrite the package skeleton.Rmd file?!? That seems crazy to me.

2

There are 2 answers

2
user2554330 On BEST ANSWER

You could define your own function that wraps a call to rmarkdown::render with options specified to give your template. I think this might do it, though I haven't tested it:

with_landscape_template = function(input) {
  rmarkdown::render(input, 
    word_document(
            reference_docx = system.file("Word/landscape_report_template.dotx",
                                         package="mypackage")))
}
2
Eva On

As far as I know, this process needs a word document, not a word template. Please try to put a word document (docx) instead of a word template (dotx) as the reference document.

output: 
  word_document:
        reference_docx: "C:/Users/myname/mypackage/inst/Word/landscape_report_template.docx"

should work in your case.

But there are two requirements:

(A) You must generate this document through pandoc only. It means you have to first put some dummy content in one RMarkdown document, then render it as a word document. This document can be your reference_docx.

(B) You must use in-built styles in Microsoft Word. Once you render the document in the step above, you can change the in-built styles (e.g., heading1, heading2, etc.) in the rendered document.

If you still face any problem, ask a new question.