# Knitting, or Fusing {#chp:fuse}

R Markdown documents need to be knitted to Markdown before being rendered to a
target output format. The function `litedown::fuse()` plays a role similar to
`knitr::knit()`. It "fuses" program code with narratives, i.e., it executes all
code in the source document and interweaves results with narratives in the
output document. Similar to **knitr**, **litedown** supports code chunks and
inline code.

## Code chunks

A code chunk consists of the language name, chunk options (in the chunk header
or pipe comments), and the code:

```` md
```{lang}
#| chunk options

code
```
````

Currently, a subset of [**knitr** chunk options](https://yihui.org/knitr/) are
supported, which can be accessed in `litedown::reactor()`. To get an option
value, use `reactor("NAME")`, where `NAME` is the option name (e.g.,
`fig.width`). To set an option globally, use `reactor(NAME = VALUE)`.
Alternatively, you can manipulate the value returned by `reactor()` directly,
which is essentially an environment:

``` r
opts = litedown::reactor()
opts$fig.width  # get an option
opts$echo = FALSE  # set an option
```

Code chunks inside other code blocks are not parsed or evaluated, which provides
a way to write verbatim code chunks, e.g.,

````` md
````markdown
Some verbatim content.

```{r}
1 + 1
```
````
`````

Similarly, code in comments will not be recognized, either, e.g.,

```` html
<!--
Do not run this chunk:

```{r}
1 + 1
```

or the inline code `{r} pi`.
-->
````

If `N + 1` pairs of curly braces are used in the opening fence, the chunk fences
(with `N` pairs of curly braces) and chunk options will be shown in the output,
which can be useful for telling readers the full source of a chunk, e.g.,

```` md
```{{r}}
#| echo = TRUE, eval = FALSE

1 + 1
```
````

## Inline code

### The syntax {#sec:inline-syntax}

The syntax for inline code expressions is `` `{lang} code` ``, where `lang` is
the language name, e.g., `r`. Spaces are allowed after the opening backtick and
before the closing backtick. If the `code` happens to contain `N` backticks, you
will need to use at least `N + 1` backticks outside, e.g.,
``` ``{r} paste("`", rnorm(1), "`")`` ```. An inline code expression inside
another piece of inline code is not parsed or evaluated, which provides a way to
write verbatim inline code expressions, e.g., ``` `` `{lang} code` `` ```.

Comma-separated chunk options can also be provided to inline code expressions
after the language name, e.g., `` `{r, eval=FALSE} code` ``.

### Compatibility with knitr

For **knitr** users, please note that the syntax `` `r code` `` is not supported
by default. You have to wrap the language name `r` in curly braces. As a
temporary workaround, you may set `options(litedown.enable.knitr_inline = TRUE)`
in your `.Rprofile` to make **litedown** recognize `` `r code` ``, but we
recommend that you convert the document via `litedown:::convert_knitr()` instead
if you decide to stay with **litedown** in the long run.

### Numeric output

If the inline expression returns a single number, the number will be formatted.
To bypass the formatting, wrap the inline expression in `I()`. We denote the
number by $x$ for now.

-   First, $x$ will be rounded to $n$ significant digits, where $n$ is
    controlled by the global R option `litedown.inline.signif` and its default
    value is `3`. To change the default, set
    `options(litedown.inline.signif = N)` anywhere before the inline code is
    executed, where `N` is the desired number of significant digits.

-   Then $x$ will be formatted using the scientific notation $\pm m\times 10^n$
    if $|x| \geq 10^p$ or $|x| \leq 10^{-p}$, where $p$ is controlled by the
    global option `litedown.inline.power`, which defaults to `6`. If you want to
    avoid the scientific notation, you can set this option to `Inf`.

    When a number is formatted in the scientific notation, you need to wrap it
    in an inline LaTeX math expression. For example, `` $`{r} 1234567`$ `` will
    be rendered to $`{r} 1234567`$.

## R scripts

Besides R Markdown, you can also pass an R script to `fuse()`. You can write
Markdown content in `#'` comments, and group lines of code into chunks by `#|`
comments, e.g.,

``` r
#' ---
#' title: An R script
#' output:
#'   litedown::latex_format: null
#' ---
#' 
#' A _paragraph_.

#| eval=FALSE
1:10
1 + 1

#| fig.width=10, dev='pdf'
plot(cars)
```

Both `#'` and `#|` comments are optional.

## Language engines {#sec:engines}

Currently, the main computing language supported by **litedown** is R. You can
check all supported languages via:

```{r}
names(litedown::engines())
```

You can get a language engine definition via `litedown::engines('LANG')`, where
`LANG` is the language name, e.g.,

``` r
litedown::engines('md')
```

You can also set a new language engine via:

``` r
litedown::engines(LANG = function(x, inline = FALSE, ...) {

})
```

The function's argument `x` is an element in the list returned by
`litedown::crack()`.

### The Markdown engine

The `md` engine will output Markdown text both verbatim and as-is, which can be
useful for showing Markdown examples, e.g.,

```` md
```{md}
You can see both the _source_ and _output_ of
this `md` chunk.
```

You can also use `{md} the engine **inline**`.
````

### The CSS/JS engines

You can insert CSS/JS to the output via the `css`/`js` engines, e.g.,

```` md
```{css}
a {
  color: red;
}
```

```{js}
document.body.classList.add('dark');
```
````

### The Mermaid engine

The `mermaid` engine can be used to draw diagrams with
[mermaid.js](https://mermaid.js.org), e.g.,

```` md
```{mermaid, flow-abcd, echo=FALSE, fig.cap='A flowchart.'}
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
```
````

The JS library mermaid.js has to be loaded for the diagrams to be rendered. By
default, the latest version of mermaid.js will be added to the `js` variable
(@sec:the-js-variable) in the YAML metadata automatically. If you prefer using a
specific version, you can add it manually to the YAML metadata, e.g.,

```` md
---
title: "A mermaid diagram"
output:
  litedown::html_format:
    meta:
      js: ["@npm/mermaid@11.3.0/dist/mermaid.min.js"]
---

```{mermaid}

```
````

## Comparison to **knitr**

Major differences between **knitr** and **litedown** include:

| knitr | litedown |
|----|----|
| Supports multiple graphical devices for a chunk. | Only supports one device for a chunk (but there are multiple choices for this device). |
| Depending on certain chunk options, figure output could be both Markdown (`![]()`) and raw HTML (`<img>`) / LaTeX (`\includegraphics{}`). | Always use Markdown syntax for figures. |
| The document parser is based on regular expressions and not robust. Code chunks and inline expressions are not aware of their contexts (e.g., code blocks or comments). | The parser is based on **commonmark**, which is more robust and makes it straightforward to write verbatim code (in a parent code block) or comment out code (in `<!-- -->` comments). |
| Supports a large number of chunk options and language engines. | Supports a limited number of chunk options and engines. |
| Inline code does not support options or languages other than R. | Inline code supports options and other languages. |
| All code is executed in the linear order. | Code chunks and inline code can be executed in a custom non-linear order defined by the chunk option `order` (higher values indicate higher priority). |
| Supports chunk hooks and output hooks. | No hooks at the moment. |
| The package is more than 12 years old and quite mature. | The package is new and still experimental. |

If you feel any indispensable features are missing in **litedown**, please feel
free to suggest them in [Github issues](https://github.com/yihui/litedown).
However, please remember that the goal of **litedown** is not to fully
re-implement **rmarkdown**, **knitr** or Pandoc. Some features may never be
re-implemented, especially when the implementation is not simple enough.
