(See Update at the end, to get proper colors)
By default pandoc uses its own highlighting engine, but it can be changed to use package listings
instead. Simply add --listings
option to your pandoc command line.
However, the format used by listings does not break long lines either, but you can prepare all the required options in a separate tex file, for example:
% Contents of listings-setup.tex
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily,
numbers=left,
numberstyle=\footnotesize,
stepnumber=2,
numbersep=5pt,
backgroundcolor=\color{black!10},
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2,
captionpos=b,
breaklines=true,
breakatwhitespace=true,
breakautoindent=true,
linewidth=\textwidth
}
And then compile with the line:
pandoc test.md --listings -H listings-setup.tex -o output.pdf
Unfortunately, this solution cannot use the --highlight-style
option too. If you want to get the tango
colorscheme, you have to code it yourself as options for the listing packages, and include them in the \lstset
above.
Given the file test.md
as follows:
% Title
% Author
# First section
Some code with long lines:
```java
public class Test {
static Set<Thread> updateThreads = new HashSet<Thread>();
public static void main(String[] args) {
ConcurrentMap<Integer, String> concurrentMap = new ConcurrentHashMap<Integer, String>();
for (int i = 0; i < 1000; i++) {
startUpdateThread(i, concurrentMap);
}
for (Map.Entry<Integer, String> entry : concurrentMap.entrySet()) {
System.out.println("Key :" + entry.getKey() + " Value:" + entry.getValue());
}
for (Thread thread : updateThreads) {
thread.interrupt();
}
}
}
```
That's it.
The result generated by the previous pandoc command line is:
Update
In order to mimic closely the result obtained with --highlight-style tango
option (and no listings
package), I ran pandoc asking for the intermediate .tex
file to discover how the colors were defined for that case.
I wrote the following setup using listings
options, which use the same colors (only where applicable, for example listings
has no mean to set a specific color for numeric constants or other syntactic elements). In addition I reduced the spacing among chars, which were too far apart with default setup. This is the new setup:
% Contents of listings-setup.tex
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily,
numbers=left,
keywordstyle=\color[rgb]{0.13,0.29,0.53}\bfseries,
stringstyle=\color[rgb]{0.31,0.60,0.02},
commentstyle=\color[rgb]{0.56,0.35,0.01}\itshape,
numberstyle=\footnotesize,
stepnumber=1,
numbersep=5pt,
backgroundcolor=\color[RGB]{248,248,248},
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2,
captionpos=b,
breaklines=true,
breakatwhitespace=true,
breakautoindent=true,
escapeinside={\%*}{*)},
linewidth=\textwidth,
basewidth=0.5em,
}
Using those settings, i.e. running pandoc
with options:
pandoc test.md --listings -H listings-setup.tex -o output.pdf
the following result is obtained:
For reference, compare it with the result without --listings
but with --highlight-syntax tango
instead:
As you can see, the style is very close (except for numeric constants, which are blue using tango
, but black using listings
). Note also how the lines were wrapped with listings
. I also added line numbers which refer to the original lines (before wrapping).
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:
- Define your own language with
\lstdefinelanguage
to use in default style
- 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
Best Answer
You're almost there and the answer you link has the solution.
First create a new file in your preferred editor and add the lines:
Then save this file as
listings-setup.tex
. It is all there is to do. Now compile your file with:And your code block might wrap appropriately.