Skip to content

pandoc mintedcode

Benct Philip Jonsson edited this page Jul 6, 2015 · 3 revisions

This is the documentation for pandoc-mintedcode.pl.

DESCRIPTION

This is a quick and dirty pandoc filter which allows you to highlight code in LaTeX output with minted 2.0 rather than with Pandoc's builtin highlighting mechanism. This is useful because you get more sophisticated highlighting and formatting of code, and you can highlight different pieces of code differently, e.g. based on code language.

View the code and the documentation on GitHub.

USAGE

First of all read the minted documentation, and make sure that you have minted 2.0 or higher and its prerequisites installed.

The filter expects that you use minted's shortcut mechanism to define highlighting for the various code languages. Thus if you for example have Bash and Perl code in your document you should create a file called e.g. mint.ltx with the following contents:

\usepackage{minted}
\setminted{linenos,breakbytoken}
\setminted[bash]{bgcolor=LightCyan}
\setminted[perl]{style=perldoc,bgcolor=Cornsilk}
\newminted{bash}{}
\newmintinline{bash}{}
\newminted{perl}{}
\newmintinline{perl}{}

Note: As you know if you read the minted docs the last argument to \newminted and \newmintinline should really contain formatting/style options. However we have already set those with \setminted and use \newminted and \newmintinline only to get custom environment/command names, which makes the code which the filter must inject into the LaTeX output much simpler!

In your markdown file you tell the filter which of your defined minted shortcuts you want to use for a particular piece of code by providing the custom attribute mint=<value> with the name of your shortcut environment/command, minus the backslash and the code or inline ending as value. Thus since the name of a minted shortcut usually is of the form \begin{<language>code} and \<language>inline you usually give the language name as value:


for i in $( ls ); do
    echo item: $i
done
And some inline code `echo item: $i`{.bash mint=bash} too.

(Here .bash and .numberLines are classes which tell the builtin Pandoc highlighter how to highlight the code, in case you use it for other formats than LaTeX, while mint=bash tells the filter to use the \begin{bashcode} environment and \bashinline command respectively.

Now if you run pandoc like this

$ pandoc -F pandoc-mintedcode.pl -w latex --no-highlight -H mint.ltx doc.md -o doc.ltx

the Markdown above will have become

\begin{bashcode}
for i in $( ls ); do
    echo item: $i
done
\end{bashcode}

And some inline code \bashinline|echo item: $i| too.

There is one thing here which probably need explanation: the --no-highlight in the command line is to disable pandoc's builtin highlighter (supposing that you want to do that!)

Now you can process doc.ltx like this:

$ xelatex -shell-escape doc.ltx

Note that because minted needs *latex to be run with the -shell-escape option you can't use pandoc's direct-to-pdf mechanism; you have to first generate a standalone LaTeX document and run *latex on that!

Default environment/command

If your Markdown document contains code only in one language, or mainly in one language, you can tell the filter to use that language by default by putting the following metadata block in your Markdown file:

---
mint_block:  perl
mint_inline: perl
...

Having done this (of course substituting your default language for perl!) you don't need to use the mint=<language> attribute on code in your main language; it will be inferred automatically. You will still need to use \newminted{perl}{...} and \newmintinline{perl}{...} in your LaTeX preamble however! Now any code block or inline code without an explicit mint=<language> attribute will become \begin{perlcode}...\end{perlcode} and \perlinline|...| respectively!

Custom command/environment names and 'suffixes'

The minted shortcut commands allow you to specify a custom name for a shortcut through an optional argument, so that if you for example want to mark out erroneous perl code specially you can put this in your LaTeX preamble after \usepackage{minted}:

\newminted[badperlcode]{perl}{bgcolor=Gainsboro}
\newmintinline[badperlinline]{perl}{bgcolor=Gainsboro}

Then you can use this in your Markdown:


no strict;
no warnings;
Some more bad Perl: `open FH, '>file.txt';`{mint=badperl} -- old-fashioned!

This illustrates how the 'suffixes' for \minted and \mintinline shortcuts, viz. code in \begin{<language>code} and language in \<language>inline are always 'inferred by the filter, even when the <value> in the mint=<value> attribute isn't really the name of a code language, (or not only the name of a language). However these suffixes aren't hardcoded. You can use the metadata keys mint_bsfx (for code blocks) and mint_isfx (for inline code) to set them to other values, e.g.

---
mint_bsfx: pre
mint_isfx: 0
...

but then you have to name all your minted shortcuts accordingly:

\newminted[bashpre]{bash}{}
\newmintinline[bash]{bash}{}

Note here that setting the suffix to 0 (zero) or false disables automatic suffixing; you then have to type your environment/command names in their entirety in your markdown.

Don't repeat yourself!

Provided the first class, if any, of your code blocks/inlines always is the language name -- for the benefit of Pandoc's builtin highlighter -- you can set the metadata value mint_class to a true (to Perl!) value, and then you don't need to use the mint=<language> attribute at all, provided Pygments's and Pandoc's notion of the language name coincide. Note that an explicit mint=<language> overrides a class, and an explicit class overrides the value of mint_block: language and mint_inline: language in the metadata. Then you can write

`echo item: $i`{.bash}

and still use minted in LaTeX output!

Getting rid of mint=<language> in HTML output

When producing HTML you don't want mint=<language>, which is invalid HTML, around in your codes' attribute lists. Therefore that attribute will be stripped if you use this filter with other output formats than *latex and the metadata key mint_strip set to a true value:

$ pandoc -w html -F pandoc-mintedcode.pl -M mint_strip doc.md -o doc.html

WARNINGS

  • Since minted's \mintinline and shortcuts for it are based of fancyvrb's \Verb they need some (ASCII) punctuation character as delimiter for the code text. To find a suitable delimiter the filter greps through the list

    | ~ ` _ ^ @ ? ; : / . , + * ' & % $ # " ! - 

    picking the first which doesn't occur in the code. On rare occasions with some languages (Bash and Perl, I'm looking at you! :-) no such character may be found, resulting in the error message

    Found no verbatim delimiter for: `` <code> `` at pandoc-mintedcode.pl line 248, <> line 1.
    pandoc: Error running filter pandoc-mintedcode.pl

    The workaround is to rephrase so that the piece of code becomes a code block.

  • Because minted needs *latex to be run with the -shell-escape option you can't use pandoc's direct-to-pdf mechanism; you have to first generate a standalone LaTeX document and run *latex on that!

REQUIRED CPAN MODULES

Data::Rmap
JSON::MaybeXS
List::AllUtils

Installing modules

http://www.cpan.org/modules/INSTALL.html

Installing perl

http://learn.perl.org/installing/