Search code examples
rr-markdownpdf-generation

Passing document YAML options to rmarkdown::render function to adjust page margins and font


I'd like to render a simple markdown file, that has been created by another process before, into a pdf file.

The command:

rmarkdown::render(input = "my_report.md", 
                  output_format = rmarkdown::pdf_document(latex_engine = "xelatex"))

just does this job.

However I would like to change the margins and the main font. With an .Rmd file one would define these settings in the Yaml header like this:

---
output: 
  pdf_document:
    latex_engine: xelatex
mainfont: LiberationSans
geometry: "left=5cm,right=3cm,top=2cm,bottom=2cm"
---

But the markdown files I'd like to convert don't have a Yaml header. Is there a way to pass these Yaml options to the render function as function parameters or in an indirect way?


Solution

  • Option 01

    geometry, mainfont are Pandoc variables and you can pass them to rmarkdown::pdf_document via pandoc_args argument.

    And for convenience, you can use rmarkdown::pandoc_variable_arg to specify name-value pair of pandoc arguments. And you need to use template=NULL so that rmarkdown default template is not used (otherwise whatever variable value passed to pandoc_arg get appended by geometry:margin=1in, so yours specified geometry value wiil be overwritten by rmarkdown defaults).

    library(rmarkdown)
    
    render(
      input = "input.md",
      output_format = rmarkdown::pdf_document(
        latex_engine = "xelatex",
        template = NULL,
        pandoc_args = c(
          pandoc_variable_arg("geometry", "left=5cm,right=3cm,top=2cm,bottom=2cm"),
          pandoc_variable_arg("mainfont", "LiberationSans")
        )
      )
    )
    

    And we can see that the variables are passed to pandoc correctly,

    /usr/lib/rstudio-server/bin/quarto/bin/tools/pandoc +RTS -K512m -RTS 
    input.md --to latex --from markdown+autolink_bare_uris+tex_math_single_backslash 
    --output input.tex --lua-filter /cloud/lib/x86_64-pc-linux-gnu-library/4.2/rmarkdown/rmarkdown/lua/pagebreak.lua 
    --lua-filter /cloud/lib/x86_64-pc-linux-gnu-library/4.2/rmarkdown/rmarkdown/lua/latex-div.lua 
    --embed-resources --standalone --highlight-style tango 
    --pdf-engine xelatex 
    --variable geometry=left=5cm,right=3cm,top=2cm,bottom=2cm 
    --variable mainfont=LiberationSans 
    

    Option 02

    Alternatively, you can pass those YAML options from a yaml file (located in the same directory as the input markdown file) via --metadata-file pandoc args.

    So specify the pandoc variables name and value in a yaml file like as following,

    main.yml

    author: Jphn Doe
    mainfont: LiberationSans
    geometry:
      - left=5cm
      - top=2cm
      - right=3cm
      - bottom=2cm
    linestretch: 1.5
    pagestyle: headings
    

    and then run the rmarkdown::render, (here you still need to use template=NULL, other wise the geometry you have specified in main.yml will be overwritten by rmardown default geometry:margin=1in)

    library(rmarkdown)
    
    render(
      input = "test_yaml.md",
      output_format = rmarkdown::pdf_document(
        latex_engine = "xelatex",
        template = NULL,
        pandoc_args = c("--metadata-file", "main.yml")
      )
    )
    

    input.md (markdown file used to test the code)

    # Rmarkdown
    
    Hello from rmarkdown.
    
    Lorem ipsum dolor sit amet, odio nec ornare tempor semper eget. Ligula lorem,
    torquent ante mauris torquent feugiat dis finibus vitae.
    

    Output for 1st option

    pdf output

    Output from 2nd option

    pdf output