skip to Main Content

Is there a way to include automatic incremental document versioning when working in markdown/rmarkdown/quarto? When I first render a file to pdf I want it to display version 1.0 and increment upwards from there every time the pdf is updated. Is this something that’s possible?

I tried including a custom function based on the presence of a cache file but it didn’t work. It seems that the YAML header option "version" is not accepted (I really convinced myself it did).

Here’s my YAML header:


title: "Project: Example"
date: "April 2024"
documentclass: report
version: 1.0

This is my function:

cache_dir <- "./cache"

# Function to increment and return version number
version_number <- function() {
  if (!file.exists(file.path(cache_dir, ".RData"))) {
    version <- 1.0
    save(version, file = file.path(cache_dir, ".RData"))
  } else {
    load(file = file.path(cache_dir, ".RData"))
    version <- get("version") + 1.0
    save(version, file = file.path(cache_dir, ".RData"))
  }
  return(paste0("v", version))
}

This also does not work:


title: "Project: Example"
date: "April 2024"
documentclass: report
version: 1.0

Does anyone know how I can implement such behavior? I’m not looking for version control like Git, and I’m using Visual Studio Code, if that helps. Thanks!

2

Answers


  1. One thing you could do is store the version number as a parameter in your R Markdown file and then use an external R Script to render the R Markdown file.

    Contents of R Markdown

    ---
    title: "Project: Example"
    output: pdf_document
    date: "April 2024"
    params:
      version: 1
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    ```
    
    ```{r}
    sprintf("The current version of this document is %i.", params$version)
    ```
    
    

    Contents of R Script

    get_version <- function(x) {
      src <- readLines(x)
      version_line <- grep("  version: \d+", src)
      as.numeric(sub("  version: ", "", src[version_line]))
    }
    
    set_version <- function(x, v) {
      src <- readLines(x)
      version_line <- grep("  version: \d+", src)
      src[version_line] <- sprintf("  version: %i", v)
      writeLines(src, x)
    }
    
    increment_version <- function(x) {
      version <- get_version(x)
      set_version(x, version + 1)
    }
    
    render <- function(input, ...) {
      increment_version(input)
      rmarkdown::render(input, ...)
    }
    
    render("C:/Users/the-mad-statter/Documents/my_r_markdown.Rmd")
    

    After editing the R Script to point to the desired R Markdown File, you could run it. The script will update the version number and then render the R Markdown file.

    Output

    enter image description here

    Login or Signup to reply.
  2. If you were using RStudio, you could store the version number as a parameter in your R Markdown file. You could then also include a rendering chunk in the R Markdown file. Running the rendering chunk would update the version and render the file.

    R Markdown File

    ---
    title: "Project: Example"
    output: pdf_document
    date: "April 2024"
    params:
      version: 1
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    ```
    
    ```{r render, eval=FALSE, include=FALSE}
    this_document <- function() {
      rstudioapi::getActiveDocumentContext()$path
    }
    
    get_version <- function() {
      src <- rstudioapi::getActiveDocumentContext()$contents
      version_line <- grep("^  version: \d+", src)
      as.numeric(sub("  version: ", "", src[version_line]))
    }
    
    set_version <- function(v) {
      src <- rstudioapi::getActiveDocumentContext()$contents
      version_line <- grep("^  version: \d+", src)
      version_line_length <- nchar(src[version_line]) + 1
      version_range <- rstudioapi::document_range(
        rstudioapi::document_position(version_line, 1),
        rstudioapi::document_position(version_line, version_line_length)
      )
      rstudioapi::modifyRange(version_range, sprintf("  version: %i", v))
    }
    
    increment_version <- function() {
      v <- get_version()
      set_version(v + 1)
    }
    
    render <- function(input, ...) {
      increment_version()
      rstudioapi::documentSave(rstudioapi::getActiveDocumentContext()$id)
      rmarkdown::render(input, ...)
    }
    
    render(this_document())
    ```
    
    ```{r}
    sprintf("The current version of this document is %i.", params$version)
    ```
    

    Output

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search