Search code examples
r-markdownpandocbookdown

How to extend Pandoc


I am using bookdown for a documentation which is outputted with bookdown::gitbook and bookdown::pdf_book.

In my Rmd files, I am using a div to wrap around notes and warnings styled with a css file. For example:

<div class="note">
This is a note.
</div>

Obviously, HTML and CSS is ignored when generating the PDF file. I was wondering if there is a way to "inject" a small script that would replace the div with, for example, a simple prefix text.

Or, is there another way to have it formatted in HTML and in the PDF without littering my file by adding something lengthy every time like:

if (knitr::is_html_output(excludes='epub')) {
  cat('
<div class="note">
This is a note.
</div>
  ')
} else {
  cat('Note: This is a note.')
}

I could also style blockquotes as described here but it is not an option as I still need blockquotes.


Solution

  • The appropriate way to do this is to use a fenced div rather than inserting HTML directly into your markdown and trying to parse it later with LUA. Pandoc already allows you to insert custom styles and process them to both file types. In other words, it will take care of creating the appropriate HTML and LaTeX for you, and then you just need to style each of them. The Bookdown documentation references this here, but it simply points to further documentation here, and here.

    This method will create both your custom classed div in html and apply the same style name in the LaTeX code.

    So, for your example, it would look like this:

    ::: {.note data-latex=""}
    This is a note.
    :::
    

    The output in HTML will be identical to yours:

    <div class="note">
    <p>This is a note.</p>
    </div>
    

    And you've already got the CSS you want to style that.

    The LaTeX code will be as follows:

    \begin{note}
    This is a note.
    \end{note}
    

    To style that you'll need to add some code to your preamble.tex file, which you've already figured out as well. Here's a very simple example of some LaTeX that would simply indent the text from both the left and right sides:

    \newenvironment{note}[0]{\par\leftskip=2em\rightskip=2em}{\par\medskip}