15.1 Register a custom language engine (*)
You can register a custom language engine via the method
knitr::knit_engines$set(). It accepts a function as its input, e.g.,
This registers the
foo engine, and you will be able to use a code chunk that starts with
The engine function has one argument,
options, which is a list of chunk options of the code chunk. You can access the source code of the chunk as a character vector in
options$code. For example, for the code chunk:
code element of
options would be a character vector
c('1 + 1', '2 + 2').
Language engines do not really have to deal with computer languages, but can process any text in a code chunk. First, we show a simple example of an engine that converts the content of a code chunk to uppercase:
The key is that we apply the function
toupper to the “code,” and return the result as a single character string (by concatenating all lines of code by
\n). Note that
toupper() is applied only when the chunk option
eval = TRUE, otherwise the original string is returned. This shows you how to make use of chunk options like
eval inside the engine function. Similarly, you may consider adding
if (options$results == 'hide') return() to the function body to hide the output when the chunk option
results = 'hide'. Below is an example chunk that uses the
upper engine, with its output:
HELLO, KNITR ENGINES!
Next we show an example of an alternative Python engine18 named
py. This engine is implemented by simply calling the
python command via the R function
To fully understand the above engine function, you need to know the following:
Given Python code as a character string (
codein the above function), we can execute the code via a command-line call
python -c 'code'. That is what
system2()does. We collect the (text) output by specifying
stdout = TRUEin
You can pass the chunk options, source code, and text output to the function
knitr::engine_output()to generate the final output. This function deals with common chunk options like
echo = FALSEand
results = 'hide', so you do not need to take care of these cases.
A lot of language engines in knitr are defined in this way (i.e., using
system2() to execute commands corresponding to languages). If you are curious about the technical details, you may check out the source code of most language engines in the R source code here: https://github.com/yihui/knitr/blob/master/R/engine.R.
Now we can use the new engine
You can even override existing language engines in knitr via
knitr::knit_engines$set(), if you are sure that your versions are necessary or better than the existing ones. Usually we do not recommend that you do this because it may surprise users who are familiar with existing engines, but we want to make you aware of this possibility anyway.