15.6 Write the chunk content to a file via thecat engine

Sometimes it could be useful to write the content of a code chunk to an external file, and use this file later in other code chunks. Of course, you may do this via the R functions likewriteLines(), but the problem is that when the content is relatively long, or contains special characters, the character string that you would pass towriteLines() may look awkward. Below is an example of writing a long character string to a filemy-file.txt:

writeLines("This is a long character string.It has multiple lines. Remember to escapedouble quotes\"\", but 'single quotes' are OK.I hope you not to lose your sanity when thinkingabout how many backslashes you need, e.g., is it'\t' or '\\t' or '\\\\t'?",con ="my-file.txt")

This problem has been greatly alleviated since R 4.0.0, because R started to support raw strings inr"( )" (see the help page?Quotes), and you do not need to remember all the rules about special characters. Even with raw strings, it can still be a little distracting for readers to see a long string written to a file explicitly in a code chunk.

Thecat engine inknitr has provided a way for you to present text content in a code chunk and/or write it to an external file, without thinking about all the rules about R’s character strings (e.g., you need double backslashes when you need a literal backslash).

To write the chunk content to a file, specify the file path in the chunk optionengine.opts, e.g.,engine.opts = list(file = 'path/to/file'). Under the hood, the list of values specified inengine.opts will be passed to the functionbase::cat(), andfile is one of the arguments ofbase::cat().

Next we will present three examples to illustrate the use of thecat engine.

15.6.1 Write to a CSS file

As shown in Section7.3, you can embed acss code chunk in an Rmd document to style elements with CSS. An alternative way is to provide a custom CSS file to Pandoc via thecss option of some R Markdown output formats such ashtml_document. Thecat engine can be used to write this CSS file from Rmd.

This example below shows how to generate a filecustom.css from a chunk in thedocument, and pass the file path to thecss option of thehtml_document format:

---title: "Create a CSS file from a code chunk"output:  html_document:    css: custom.css---The chunk below will be written to`custom.css`, whichwill be used during the Pandoc conversion.```{cat, engine.opts = list(file = "custom.css")}h2 {  color: blue;}```## And this title will blue

The only difference between thecss code chunk approach and this approach is that the former approach writes the CSS code in place (i.e., in the place of the code chunk), which is inside the<body> tag of the output document, and the latter approach writes CSS to the<head> area of the output document. There will not be any practical visual differences in the output document.

15.6.2 Include LaTeX code in the preamble

In Section6.1, we introduced how to add LaTeX code to the preamble, which requires an external.tex file. This file can also be generated from Rmd, and here is an example:

---title: "Create a .tex file from a chunk"author: "Jane Doe"classoption: twosideoutput:  pdf_document:    includes:      in_header: preamble.tex---# How it worksWrite a code chunk to a file`preamble.tex` to definethe header and footer of the PDF output document:```{cat, engine.opts=list(file = 'preamble.tex')}\usepackage{fancyhdr}\usepackage{lipsum}\pagestyle{fancy}\fancyhead[CO,CE]{This is fancy header}\fancyfoot[CO,CE]{And this is a fancy footer}\fancyfoot[LE,RO]{\thepage}\fancypagestyle{plain}{\pagestyle{fancy}}```\lipsum[1-15]# More random content\lipsum[16-30]

In the LaTeX code in thecat code chunk above, we have defined the header and footer of the PDF document. If we also want to show the author name in the footer, we can append the author information topreamble.tex in anothercat code chunk with optionsengine.opts = list(file = 'preamble.tex', append = TRUE) andcode = sprintf('\\fancyfoot[LO,RE]{%s}', rmarkdown::metadata$author). To understand how this works, recall that we mentioned earlier in this section thatengine.opts is passed tobase::cat() (soappend = TRUE is passed tocat()), and you may understand the chunk optioncode by reading Section16.2.

15.6.3 Write YAML data to a file and also display it

By default, the content of thecat code chunk will not be displayed in the output document. If you also want to display it after writing it out, set the chunk optionclass.source to a language name. The language name is used for syntax highlighting. In the example below, we specify the language to beyaml:

```{cat, engine.opts=list(file='demo.yml'), class.source='yaml'}a:  aa: "something"  bb: 1b:  aa: "something else"  bb: 2```

Its output is displayed below, and it also generated a filedemo.yml.

a:aa:"something"bb:1b:aa:"something else"bb:2

To show the filedemo.yml is really generated, we can try to read it into R with theyaml package(Stephens and Simonov 2025):

xfun::tree(yaml::read_yaml("demo.yml"))
## List of 2##  |-a:List of 2##  |  |-aa: chr "something"##  |  |-bb: int 1##  |-b:List of 2##     |-aa: chr "something else"##     |-bb: int 2

References

Stephens, Jeremy, and Kirill Simonov. 2025.Yaml: Methods to Convert r Data to YAML and Back.https://github.com/vubiostat/r-yaml/.