0

Does anyone know if it is possible to include parameters in the header and / or footer text of a Quarto or RMarkdown document rendered to a pdf?

This issue shows how to include general text in the header and footer. But what I want to do is include a parameter in the header or footer.

In the example below, the parameter name can be rendered in the main body, but I do not know if it is possible to include it in the header.

---
title: "Untitled"
format:
  pdf:
    include-in-header:
      text: |
        \usepackage{scrlayer-scrpage}
        \rohead{Header text}
        \lofoot{Footer text}
params:
  name: "John"
---

# Chapter ONE

My name is `r params$name`

\newpage

# Chapter TWO

Edit: The reason why I want to use a parameters is because I need to pass a parameter while rendering, e.g. using quarto::quarto_render() in R. I'm rendering multiple PDFs, and I'd like to insert a unique name in the header / footer of each one.

jhelvy
  • 542
  • 4
  • 8

3 Answers3

1

One possible solution could be using Latex Template Partials and pandoc variables.

Here I have used the title.tex template partial, because everything within it would be attached before the \begin{document} and moved the latex code for header and footer text in the title.tex.

Now to get the parameter value within the LateX code, I have done two things, at first used the parameter value in a YAML key name and then used the key inside the title.tex as a pandoc variable $name$ (the only purpose of using template partials is so that pandoc variables can be used).

---
title: Untitled
format: 
  pdf:
    keep-tex: true
    template-partials:
      - title.tex
params:
  name: John
name: "`r params$name`"
---

# Chapter ONE

My name is `r params$name`

\newpage

# Chapter TWO

title.tex

$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
\subtitle{$subtitle$}
$endif$
\author{$for(authors)$$it.name.literal$$sep$ \and $endfor$}
\date{$date$}

\usepackage{scrlayer-scrpage}
\rohead{Header text - $name$}
\lofoot{Footer text - $name$}
shafee
  • 15,566
  • 3
  • 19
  • 47
1

Brilliant solution presented here - have the header/footer refer to a macro, that you define later on in the document:

---
title: "Untitled"
format:
  pdf:
    keep-tex: true
    include-in-header:
      text: |
        \usepackage{scrlayer-scrpage}
        \rohead{\myname}
params:
  name: "John"

engine: knitr
---

# Chapter ONE

My name is `r params$name`

\newcommand{\myname}{`r params$name`}


\newpage

# Chapter TWO
jhelvy
  • 542
  • 4
  • 8
1

I've had this issue before and I was able to solve this by passing the variables I want to use in pandoc partials as metadata.

I solved it using rmardown::pandoc_metadata_arg() which takes a name argument and a value argument and returns a string vector that you can then pass to quarto::render() in the pandoc_args argument.

My use case was rendering a number of letters where I wanted to use the names/surnames in the latex template. I have a dataframe with the data in differents columns (name, surname, address and so on). Each row should be rendere to one output file. The name of the column in the dataframe is the name of the variable in the pandoc partial. Each column of the dataframe is one variable.

I've simplified it a bit with just two columns in the dataframe.

render_letter <- function(...) {
  my_variables <- list(...)
  
  my_variables |>
    purrr::imap(
      \(x, y) rmarkdown::pandoc_metadata_arg(y, x)
    ) |> unname() |> unlist() -> my_metadata
  
  quarto::quarto_render(
    input = "path/to/qmd/file.qmd",
    output_file = paste0(my_metadata$name, ".pdf"),
    pandoc_args = my_metadata
  )
}

letter_data <- tibble::tribble(
  ~name, ~surname,
  "John", "Doe",
  "Jane", "Doe"
)

letter_data |> 
  purrr::pwalk(render_letter)