2

I use rmarkdown to generate a pdf file (which uses pandoc, which in turn uses pdflatex). By enabling keep_tex option, I noticed that code blocks without language type always become verbatim, e.g.:

```
my code block
```

becomes:

\begin{verbatim}
my code block
\end{verbatim}

Is it possible to change conversion rules (e.g. in case I want to change background color for those blocks)?

  • 1
    Welcome to TeX.se. I don't have time to give a full answer, you can tell knitr to use listings (see yihui.name/knitr/demo/listings) and you can tell get tcolorbox to put listings into boxes for you. See How to use lstlisting with tcolorbox? for an example. – Alan Munn Oct 8 at 13:35
  • @AlanMunn Thank you for replying. I've tried to experiment, and it seems to me that knitr hooks only work for R code chunks, is that correct? I'm wondering if it's possible to apply this to chunks without language specification. – Thunderbeef Oct 8 at 17:30
  • Yes, that may be true, I'm not sure. But pandoc can definitely use listings so it should still be possible in principle, if not directly through knitr. – Alan Munn Oct 8 at 17:48
  • 1
    I think I mainly pointed you in the right direction, so it might be better to post your test example and explanation as in answer yourself. :) – Alan Munn Oct 8 at 18:17
  • 1
    @AlanMunn I suspect of a XY problem but if Thunderbeef clarify the problem I will glad to try to answer. Nonetheless, maybe this example, or this example, are enough. – Fran Oct 8 at 22:14
1

Thanks to @AlanMunn, I found at least 2 solutions that work for code chunks with undefined language. Both are pandoc-specific, and don't actually require rmarkdown (examples for both can be found here):

1. Call pandoc with --listings option

In rmarkdown, it can be passed like this:

---
output:
  pdf_document:
    pandoc_args: [ "--listings" ]
---

This will make it so all code blocks (including ones without defined language) will instead be wrapped in lstlisting like this:

\begin{lstlisting}
my code block
\end{lstlisting}

With this, you have the option to customize appearance of those blocks by doing the following:

  1. Define your own language with \lstdefinelanguage to use in default style
  2. Define default style with \lstset to change appearance of chunks with unspecified language

2. Use pandoc filter

In rmarkdown, it can be passed like this:

---
output:
  pdf_document:
    pandoc_args: [ "--filter", "./my-cool-filter" ]
---

"Filter" is an executable written in any language that can process JSON. pandoc will convert the entire document into JSON dictionary, and pipe it through the filter, then work with the result. So, a filter can modify output in any arbitrary way.

In this particular case, you basically need to find all elements with "CodeBlock" type, and convert them into "RawBlock" with "tex" subtype, and wrap text value into any LaTeX macro of your liking.

UPD: It's even easier (and, apparently, faster, according to documentation), to use --lua-filter option. The whole code of the filter is just this:

function CodeBlock(elem)
  return pandoc.RawBlock('tex', '\\begin{my-cool-macro}\n' .. elem.text .. '\n\\end{my-cool-macro}')
end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.