# Lua filters in R Markdown

## Pagebreaks

Adding a pagebreak in document was always possible using custom output specific syntax in a rmarkdown file but one drawback was the compatibility with several output format.

Since rmarkdown >= 1.15 and with RStudio >= 1.2 (or with pandoc >= 2.0), it is possible to add a `\newpage` or `\pagebreak` command in a new line to include a pagebreak in any of these formats: `pdf_document()`, `html_document()`, `word_document()` and `odt_document()`.

    # Header 1

    Some text

    \newpage

    # Header 2 on a new page

    Some other text

    \pagebreak

    # Header 3 on a third page

rmarkdown will convert those commands in the correct output format syntax using a lua filter during pandoc conversion.

### Using with PDF/ latex documents

As the commands are the ones already used in latex syntax, this works as expected in a tex output document, and thus with pdf. Adding a pagebreak was already possible with rmarkdown when output is `pdf_document()` or `latex_document()`, without any restriction about the version of pandoc.

### Using with HTML documents

A `\newpage` or `\pagebreak` command in a rmarkdown document with output as HTML will be converted by default in this html code with inline style using CSS rule `page-break-after`

    <div style="page-break-after: always;"></div>

This will always insert a pagebreak after this div.

To get more flexibility, you can use a HTML class and some custom CSS instead of an inline style. You need to add a metadata field `newpage_html_class` in your yaml header to set the class.

Then you can control the behavior using custom CSS as in this example

    ---
    output:
      html_document: default
    newpage_html_class: page-break
    ---

    ```{css, echo = FALSE}
    // display the pagebreak only when printing the html page
    @media all {
        .page-break { display: none; }
    }
    @media print {
        .page-break { display: block; break-after: page; }
    }
    ```

    # Header 1

    Some text

    \newpage

    # Header 2 on a new page

    Some other text

`\newpage` will be converted here to

    <div class="page-break"></div>

and the style will be applied to this class from the CSS included in the chunk.

This customisation can also be achieved by setting the environnement variable `PANDOC_NEWPAGE_HTML_CLASS` in the R session that will render the document (or in `.Renviron` file for example)

Let’s note that in this example we use `break-after` property instead of `page-break-after` as it is recommended now to use the former which is the replacement. The latter is kept around for compatibility reason with browsers.

### Using with Word documents

A `\newpage` or `\pagebreak` command in a rmarkdown document with output as Word document will be converted in a pagebreak for word document. Manually, this would mean adding this in your rmarkdown

    ```{=openxml}
    <w:p><w:r><w:br w:type="page"/></w:r></w:p>
    ```

For example, using the pagebreak feature, this will add the first header in the second page of the work document

    ---
    title: My main title
    output: word_document
    ---

    \newpage

    # First Header

### Using with ODT documents

To use the pagebreak feature with `odt_document()`, you need to provide a reference document that includes a paragraph style with, by default, the name Pagebreak. This named paragraph style should have no extra space before or after and have a pagebreak after it. (see libre office documentation on how to create a style).

The name of the named paragrah style could be customized using `newpage_odt_style` metadata in yaml header or `PANDOC_NEWPAGE_ODT_STYLE` environment variable (as in html document).

As the previous one, this example will lead to a two pages document, with first header on the second page.

    ---
    title: My main title
    output:
      odt_document:
        reference_odt: reference.odt
    ---

    \newpage

    # First Header

## About lua filters

Since pandoc 2.0, it is possible to use lua filters to add some extra functionality to pandoc document conversion. Adding a pagebreak command in markdown to be compatible with several output documents is one of them. You can find some more informations about lua filters in pandoc’s documentation and also some examples in a collection of lua filters for pandoc. These examples, and any other lua filters, can be use in your Rmarkdown document directly by adding a pandoc argument in yaml header

    ---
    output:
      html_document:
        pandoc_args: ["--lua-filter=filter.lua"]
    ---

The package rmdfiltr provides a collection of lua filters and helpers functions to use them.

Before pandoc 2.0, using filter with pandoc was already available through programs that modifies the AST. `pandoc-citeproc` is an example used to deal with citations. The package pandocfilter is useful to create filters using R.