Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to store embedded file (includes) in custom Rmarkdown #1212

Closed
Nicolabo opened this issue Dec 3, 2017 · 4 comments
Closed

how to store embedded file (includes) in custom Rmarkdown #1212

Nicolabo opened this issue Dec 3, 2017 · 4 comments
Labels
question general questions - not an issue

Comments

@Nicolabo
Copy link

Nicolabo commented Dec 3, 2017

This problem was previously posted on stackoverflow.com.

I created my own format in Rmarkdown based on this blogpost. I implemented it in my personal package and it works great. I also added custom files in includes argument of html_document.

My question is whether it's possible to store my custom files (included in includes argument) after I click Knit button. Similarly to self_contained = F option which allows storing all Rmarkdown dependencies.

I should give you some context first. Let’s say I used my html format to create a report two months ago. Two weeks later I decided to implement major changes in my html format and updated my package.

After next two weeks, my boss came to me asking for adding minor changes in old report. Then, by clicking Knit button, the report was not able to create, because there was a new version of my html format, which was significantly different.

I see three possibilities how to deal with this request. Either I can install old version of my package (suboptimal), create a new html format every time I implement major changes or I can store my dependencies (header, footer, css files) in a separate subdirectory (like a packrat). Then each report would be independent and immune to changes in my custom format.

Let me know if there is any better solution.

@cderv
Copy link
Collaborator

cderv commented Dec 3, 2017

Just for reference and to more easily follow, this question was also asked on RStudio community

@RLesur
Copy link
Contributor

RLesur commented Jan 27, 2018

Here's a basic example.
Assume that you have a myreport.Rmd file with the following header:

---
title: "Untitled"
author: "Romain Lesur"
date: "27 janvier 2018"
output: 
  html_document:
    includes:
      in_header: inheader.html
---

Using a hacky rmarkdown preprocessor, you can copy inheader.html file.
The following code is intended to be run in R console:

pre_processor <- function(metadata, 
                          input_file, 
                          runtime, 
                          knit_meta, 
                          files_dir, 
                          output_dir) {
  
  in_header <- metadata$output$html_document$includes$in_header
  if (!is.null(in_header)) file.copy(in_header, output_dir)
  
  invisible(NULL)
}

custom_output_format <- function() {
  rmarkdown::output_format(
    knitr = NULL,
    pandoc = NULL,
    pre_processor = pre_processor,
    base_format = rmarkdown::html_document()
  )
}

rmarkdown::render('myreport.Rmd', 
                   output_format = custom_output_format(), 
                   output_dir = 'output')

You get a output dir with the rendered report and inheader.html file inside.

In order to run a similar preprocessor on clicking Knit button, you have to include it in your personal package's output_format (see below).

Turning in a package
Here is an adaptation of the quarterly_report function of this blogpost:

quarterly_report <- function(toc = TRUE) {

  # get the locations of resource files located within the package
  css <- system.file("reports/styles.css", package = "mypackage")
  header <- system.file("reports/quarterly/header.html", package = "mypackage")

  # call the base html_document function
  base_format <-
    rmarkdown::html_document(toc = toc,
                             fig_width = 6.5,
                             fig_height = 4,
                             theme = NULL,
                             css = css,
                             includes = includes(before_body = header))

  pre_processor <- function(metadata,
                            input_file,
                            runtime,
                            knit_meta,
                            files_dir,
                            output_dir) {
    purrr::walk(c(css, header), file.copy, output_dir)

    invisible(NULL)
  }

  rmarkdown::output_format(
    knitr = NULL,
    pandoc = NULL,
    pre_processor = pre_processor,
    base_format = base_format
  )
}

This solution is not 100% satisfying because I don't think that rmarkdown pre_processor was created for having side-effects. But it works.

@rich-iannone rich-iannone added the question general questions - not an issue label Mar 15, 2018
@rich-iannone
Copy link
Member

Thanks @RLesur for answering the question here and in RStudio Community. Going to close this now.

@github-actions
Copy link

github-actions bot commented Nov 3, 2020

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question general questions - not an issue
Projects
None yet
Development

No branches or pull requests

4 participants