Minted
Minted
Geoffrey M. Poore
[email protected]
github.com/gpoore/minted
Abstract
minted is a package that facilitates expressive syntax highlighting using the
powerful Pygments library. The package also provides options to customize
the highlighted source code output.
License
1
Contents
1 Introduction 4
2 Installation 4
2.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Required packages . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Installing minted . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Basic usage 6
3.1 Preliminary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 A minimal complete example . . . . . . . . . . . . . . . . . . . . . 6
3.3 Formatting source code . . . . . . . . . . . . . . . . . . . . . . . . 7
3.4 Using different styles . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.5 Supported languages . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4 Floating listings 9
5 Options 11
5.1 Package options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.2 Macro option usage . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.3 Available options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6 Defining shortcuts 29
Version History 34
8 Implementation 42
8.1 Required packages . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
8.2 Package options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
8.3 Input, caching, and temp files . . . . . . . . . . . . . . . . . . . . . 46
8.4 OS interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
8.5 Option processing . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
2
8.6 Internal helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.7 Public API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.8 Command shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.9 Float support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
8.10 Epilogue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
8.11 Final cleanup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3
1 Introduction
minted is a package that allows formatting source code in LATEX. For example:
\begin{minted}{<language>}
<code>
\end{minted}
class Foo
def init
pi = Math::PI
@var = "Pi is approx. #{pi}"
end
end
Here we have four different colors for identifiers (five, if you count keywords) and
escapes from inside strings, none of which pose a problem for Pygments.
Additionally, installing Pygments is actually incredibly easy (see the next section).
2 Installation
2.1 Prerequisites
Pygments is written in Python, so make sure that you have Python 2.6 or later
installed on your system. This may be easily checked from the command line:
4
$ python --version
Python 2.7.5
If you dont have Python installed, you can download it from the Python website
or use your operating systems package manager.
Some Python distributions include Pygments (see some of the options under
Alternative Implementations on the Python site). Otherwise, you will need
to install Pygments manually. This may be done by installing setuptools, which
facilitates the distribution of Python applications. You can then install Pygments
using the following command:
Under Windows, you will not need the sudo, but may need to run the command
prompt as administrator. Pygments may also be installed with pip:
If you already have Pygments installed, be aware that the latest version is recom-
mended (at least 1.4 or later). Some features, such as escapeinside, will only
work with 2.0+. minted may work with versions as early as 1.2, but there are no
guarantees.
minted requires that the following packages be available and reasonably up to date
on your system. All of these ship with recent TEX distributions.
upquote etoolbox
shellesc (for
float xstring luatex 0.87+)
You can probably install minted with your TEX distributions package manager.
Otherwise, or if you want the absolute latest version, you can install it manually
by following the directions below.
5
You may download minted.sty from the projects homepage. We have to install
the file so that TEX is able to find it. In order to do that, please refer to the TEX
FAQ. If you just want to experiment with the latest version, you could locate your
current minted.sty in your TEX installation and replace it with the latest version.
Or you could just put the latest minted.sty in the same directory as the file you
wish to use it with.
3 Basic usage
3.1 Preliminary
Since minted makes calls to the outside world (that is, Pygments), you need to tell
the LATEX processor about this by passing it the -shell-escape option or it wont
allow such calls. In effect, instead of calling the processor like this:
$ latex input
Working with OS X
If you are using minted with some versions/configurations of OS X, and are using
caching with a large number of code blocks (> 256), you may receive an error like
This is due to the way files are handled by the operating system, combined with
the way that caching works. To resolve this, you may use the OS X commands
launchctl limit maxfiles or ulimit -n to increase the number of files that
may be used.
6
\documentclass{article}
\usepackage{minted}
\begin{document}
\begin{minted}{c}
int main() {
printf("hello, world");
return 0;
}
\end{minted}
\end{document}
int main() {
printf("hello, world");
return 0;
}
minted Using minted is straightforward. For example, to highlight some Python source
code we might use the following code snippet (result on the right):
\begin{minted}{python}
def boring(args = None): def boring(args = None):
pass pass
\end{minted}
Optionally, the environment accepts a number of options in key=value notation,
which are described in more detail below.
\mint For a single line of source code, you can alternatively use a shorthand notation:
This typesets a single line of code using a command rather than an environment,
so it saves a little typing, but its output is equivalent to that of the minted
environment.
7
The code is delimited by a pair of identical characters, similar to how \verb works.
The complete syntax is \mint[hoptionsi]{hlanguagei}hdelimihcodeihdelimi, where
the code delimiter can be almost any punctuation character. The hcodei may also
be delimited with matched curly braces {}, so long as hcodei itself does not contain
unmatched curly braces. Again, this command supports a number of options
described below.
Note that the \mint command is not for inline use. Rather, it is a shortcut for
minted when only a single line of code is present. The \mintinline command is
provided for inline use.
\mintinline Code can be typeset inline:
X\mintinline{python}{print(x**2)}X Xprint(x**2)X
\usemintedstyle Instead of using the default style you may choose another stylesheet provided by
Pygments. This may be done via the following:
\usemintedstyle{name}
$ pygmentize -L styles
1 For example, \mintinline works in footnotes! The main exception is when the code contains
8
Creating your own styles is also easy. Just follow the instructions provided on the
Pygments website.
$ pygmentize -L lexers
4 Floating listings
listing minted provides the listing environment to wrap around a source code block.
This puts the code into a floating box, with the default placement tbp like figures
and tables. You can also provide a \caption and a \label for such a listing in
the usual way (that is, as for the figure and table environments):
\begin{listing}[H]
\mint{cl}/(car (cons 1 '(2)))/
\caption{Example of a listing.}
\label{lst:example}
\end{listing}
will yield:
The default listing placement can be modified easily. When the package option
newfloat=false (default), the float package is used to create the listing envi-
ronment. Placement can be modified by redefining \fps@listing. For example,
\makeatletter
\renewcommand{\fps@listing}{htp}
\makeatother
9
When newfloat=true, the more powerful newfloat package is used to create the
listing environment. In that case, newfloat commands are available to customize
listing:
\SetupFloatingEnvironment{listing}{placement=htp}
\listoflistings The \listoflistings macro will insert a list of all (floated) listings in the docu-
ment:
List of Listings
\listoflistings
1 Example of a listing. 9
By default, the listing environment is created using the float package. In that case,
the \listingscaption and \listoflistingscaption macros described below
may be used to customize the caption and list of listings. If minted is loaded with
the newfloat option, then the listing environment will be created with the more
powerful newfloat package instead. newfloat is part of caption, which provides many
options for customizing captions.
When newfloat is used to create the listing environment, customization should be
achieved using newfloats \SetupFloatingEnvironment command. For example,
the string Listing in the caption could be changed to Program code using
\SetupFloatingEnvironment{listing}{name=Program code}
\renewcommand{\listingscaption}{Program code}
\listoflistingscaption (Only applies when package option newfloat is not used.) Likewise, the
caption of the listings list, List of Listings, can be changed by redefining
\listoflistingscaption:
10
\renewcommand{\listoflistingscaption}{List of Program Code}
5 Options
chapter To control how LATEX counts the listing floats, you can pass either the section
or chapter option when loading the minted package. For example, the following
will cause listings to be counted by chapter:
\usepackage[chapter]{minted}
cache=hboolean i minted works by saving code to a temporary file, highlighting the code via Pygments
(default: true) and saving the output to another temporary file, and inputting the output into the
LATEX document. This process can become quite slow if there are several chunks of
code to highlight. To avoid this, the package provides a cache option. This is on
by default.
The cache option creates a directory _minted-hjobnamei in the documents root
directory (this may be customized with the cachedir option).3 Files of highlighted
code are stored in this directory, so that the code will not have to be highlighted
again in the future. In most cases, caching will significantly speed up document
compilation.
Cached files that are no longer in use are automatically deleted.4
cachedir=hdirectory i This allows the directory in which cached files are stored to be specified. Paths
(def: _minted-hjobname i) should use forward slashes, even under Windows.
Special characters must be escaped. For example, cachedir=~/mintedcache
would not work because the tilde ~ would be converted into the LATEX com-
mands for a non-breaking space, rather than being treated literally. Instead, use
\string~/mintedcache, \detokenize{~/mintedcache}, or an equivalent solu-
tion.
Paths may contain spaces, but only if the entire hdirectoryi is wrapped in curly
braces {}, and only if the spaces are quoted. For example,
3 The directory is actually named using a sanitized copy of hjobnamei, in which spaces and
asterisks have been replaced by underscores, and double quotation marks have been stripped. If
the file name contains spaces, \jobname will contain a quote-wrapped name, except under older
versions of MiKTeX which used the name with spaces replaced by asterisks. Using a sanitized
hjobnamei is simpler than accomodating the various escaping conventions.
4 This depends on the main auxiliary file not being deleted or becoming corrupted. If that
happens, you could simply delete the cache directory and start over.
11
cachedir = {\detokenize{~/"minted cache"/"with spaces"}}
draft=hboolean i This uses fancyvrb alone for all typesetting; Pygments is not used. This trades syntax
(default: false) 5 Ordinarily, cache files are named using an MD5 hash of highlighting settings and highlighted
text. finalizecache renames cache files using a listing<number>.pygtex scheme. This makes
it simpler to match up document content and cache files, and is also necessary for the XeTeX
engine since prior to TeX Live 2016 it lacked the built-in MD5 capabilities that pdfTeX and
LuaTeX have.
12
highlighting and some other minted features for faster compiling. Performance
should be essentially the same as using fancyvrb directly; no external temporary
files are used. Note that if you are not changing much code between compiles, the
difference in performance between caching and draft mode may be minimal. Also
note that draft settings are typically inherited from the document class.
Draft mode does not support autogobble. Regular gobble, linenos, and most
other options not related to syntax highlighting will still function in draft mode.
Documents can usually be compiled without shell escape in draft mode. The
ifplatform package may issue a warning about limited functionality due to shell
escape being disabled, but this may be ignored in almost all cases. (Shell escape
is only really required if you have an unusual system configuration such that the
\ifwindows macro must fall back to using shell escape to determine the system.
See the ifplatform documentation for more details: http://www.ctan.org/pkg/
ifplatform.)
If the cache option is set, then all existing cache files will be kept while draft
mode is on. This allows caching to be used intermitently with draft mode without
requiring that the cache be completely recreated each time. Automatic cleanup of
cached files will resume as soon as draft mode is turned off. (This assumes that the
auxiliary file has not been deleted in the meantime; it contains the cache history
and allows automatic cleanup of unused files.)
final=hboolean i This is the opposite of draft; it is equivalent to draft=false. Again, note that
(default: true) draft and final settings are typically inherited from the document class.
kpsewhich=hboolean i This option uses kpsewhich to locate files that are to be highlighted. Some build
(default: false) tools such as texi2pdf function by modifying TEXINPUTS; in some cases, users
may customize TEXINPUTS as well. The kpsewhich option allows minted to work
with such configurations.
This option may add a noticeable amount of overhead on some systems, or with
some system configurations.
This option does not make minted work with the -output-directory and
-aux-directory command-line options for LATEX. For those, see the outputdir
package option.
langlinenos=hboolean i minted uses the fancyvrb package behind the scenes for the code typesetting.
(default: false) fancyvrb provides an option firstnumber that allows the starting line number of an
environment to be specified. For convenience, there is an option firstnumber=last
that allows line numbering to pick up where it left off. The langlinenos option
makes firstnumber work for each language individually with all minted and \mint
usages. For example, consider the code and output below.
\begin{minted}[linenos]{python}
def f(x):
return x**2
13
\end{minted}
\begin{minted}[linenos]{ruby}
def func
puts "message"
end
\end{minted}
\begin{minted}[linenos, firstnumber=last]{python}
def g(x):
return 2*x
\end{minted}
1 def f(x):
2 return x**2
1 def func
2 puts "message"
3 end
3 def g(x):
4 return 2*x
Without the langlinenos option, the line numbering in the second Python envi-
ronment would not pick up where the first Python environment left off. Rather, it
would pick up with the Ruby line numbering.
newfloat=hboolean i By default, the listing environment is created using the float package. The
(default: false) newfloat option creates the environment using newfloat instead. This provides
better integration with the caption package.
outputdir=hdirectory i The -output-directory and -aux-directory (MiKTeX) command-line options
(default: hnone i) for LATEX cause problems for minted, because the minted temporary files are saved
in <outputdir>, but minted still looks for them in the document root directory.
There is no way to access the value of the command-line option so that minted
can automatically look in the right place. But it is possible to allow the output
directory to be specified manually as a package option.
The output directory should be specified using an absolute path or a path relative
to the document root directory. Paths should use forward slashes, even under
Windows. Special characters must be escaped, while spaces require quoting and
need the entire hdirectoryi to be wrapped in curly braces {}. See cachedir above
for examples of escaping and quoting.
section To control how LATEX counts the listing floats, you can pass either the section
or chapter option when loading the minted package.
14
5.2 Macro option usage
All minted highlighting commands accept the same set of options. Options are
specified as a comma-separated list of key=value pairs. For example, we can
specify that the lines should be numbered:
\begin{minted}[linenos=true]{c++}
#include <iostream> 1 #include <iostream>
int main() { 2 int main() {
std::cout << "Hello " 3 std::cout << "Hello "
<< "world" 4 << "world"
<< std::endl; 5 << std::endl;
} 6 }
\end{minted}
An option value of true may also be omitted entirely (including the =). To
customize the display of the line numbers further, override the \theFancyVerbLine
command. Consult the fancyvrb documentation for details.
\mint accepts the same options:
\mint[linenos]{perl}|$x=~/foo/| 1 $x=~/foo/
Heres another example: we want to use the LATEX math mode inside comments:
\begin{minted}[mathescape]{python}
# Returns $\sum_{i=1}^{n}i$
Pn
# Returns i=1 i
def sum_from_one_to(n): def sum_from_one_to(n):
r = range(1, n + 1) r = range(1, n + 1)
return sum(r) return sum(r)
\end{minted}
To make your LATEX code more readable you might want to indent the code inside
a minted environment. The option gobble removes these unnecessary whitespace
characters from the output. There is also an autogobble option that detects the
length of this whitespace automatically.
15
\begin{minted}[gobble=2,
showspaces]{python}
def boring(args = None):
pass defboring(args=None):
\end{minted} pass
versus
versus
defboring(args=None):
\begin{minted}[showspaces]{python} pass
def boring(args = None):
pass
\end{minted}
\setminted You may wish to set options for the document as a whole, or for an entire language.
This is possible via \setminted[hlanguagei]{hkey=value,...i}. Language-specific
options override document-wide options. Individual command and environment
options override language-specific options.
\setmintedinline You may wish to set separate options for \mintinline, either for the document
as a whole or for a specific language. This is possible via \setmintedinline.
The syntax is \setmintedinline[hlanguagei]{hkey=value,...i}. Language-specific
options override document-wide options. Individual command options override
language-specific options. All settings specified with \setmintedinline override
those set with \setminted. That is, inline settings always have a higher precedence
than general settings.
Following is a full list of available options. For more detailed option descriptions
please refer to the fancyvrb and Pygments documentation.
...text.
\begin{minted}[autogobble]{python} ...text.
def f(x): def f(x):
return x**2 return x**2
\end{minted}
16
beameroverlays (boolean) (default: false)
Give the < and > characters their normal text meanings when used with
escapeinside and texcomments, so that beamer overlays of the form \only<1>{...}
will work.
\begin{minted}[breaklines, breakafter=d]{python}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
\end{minted}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCould c
, NeverFitOnOneLine'
17
\begin{minted}[breaklines, breakanywhere]{python}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
\end{minted}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeve c
, rFitOnOneLine'
\begin{minted}[breaklines, breakbefore=A]{python}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
\end{minted}
some_string = 'SomeTextThatGoesOn c
, AndOnForSoLongThatItCouldNeverFitOnOneLine'
18
both have the same setting.
19
use escapeinside=, and then insert \\ at the appropriate point. (Note that
escapeinside does not work within strings.)
...text. ...text.
\begin{minted}[breaklines]{python}
def f(x): def f(x):
return 'Some text ' + str(x) return 'Some text ' +
\end{minted} , str(x)
Breaking in minted and \mint may be customized in several ways. To customize the
indentation of broken lines, see breakindent and breakautoindent. To customize
the line continuation symbols, use breaksymbolleft and breaksymbolright.
To customize the separation between the continuation symbols and the code,
use breaksymbolsepleft and breaksymbolsepright. To customize the ex-
tra indentation that is supplied to make room for the break symbols, use
breaksymbolindentleft and breaksymbolindentright. Since only the left-
hand symbol is used by default, it may also be modified using the alias options
breaksymbol, breaksymbolsep, and breaksymbolindent. Note than none of
these options applies to \mintinline, since they are not relevant in the inline
context.
An example using these options to customize the minted environment is shown
below. This uses the \carriagereturn symbol from the dingbat package.
\begin{minted}[breaklines,
breakautoindent=false,
breaksymbolleft=\raisebox{0.8ex}{
\small\reflectbox{\carriagereturn}},
breaksymbolindentleft=0pt,
breaksymbolsepleft=0pt,
breaksymbolright=\small\carriagereturn,
breaksymbolindentright=0pt,
breaksymbolsepright=0pt]{python}
def f(x):
return 'Some text ' + str(x) + ' some more text ' +
, str(x) + ' even more text that goes on for a
, while'
\end{minted}
def f(x):
return 'Some text ' + str(x) + ' some more text ' + C
C str(x) + ' even more text that goes on for a while'
Automatic line breaks are limited with Pygments styles that use a colored back-
ground behind large chunks of text. This coloring is accomplished with \colorbox,
20
which cannot break across lines. It may be possible to create an alternative to
\colorbox that supports line breaks, perhaps with TikZ, but the author is unaware
of a satisfactory solution. The only current alternative is to redefine \colorbox so
that it does nothing. For example,
\AtBeginEnvironment{minted}{\renewcommand{\colorbox}[3][]{#3}}
uses the etoolbox package to redefine \colorbox within all minted environments.
Automatic line breaks will not work with showspaces=true unless you use
breakanywhere or breakafter=\space.
21
breaksymbolindentright (dimension) (default: hbreaksymbolindentrightnchars i)
The extra right indentation that is provided to make room for breaksymbolright.
This indentation is only applied when there is a breaksymbolright.
22
\definecolor{bg}{rgb}{0.95,0.95,0.95}
\begin{minted}[bgcolor=bg]{php}
<?php
<?php
echo "Hello, $x";
echo "Hello, $x";
?>
?>
\end{minted}
This option puts minted environments and \mint commands in a snugshade*
environment from the framed package, which supports breaks across pages. (Prior
to minted 2.2, a minipage was used, which prevented page breaks and gave
undesirable spacing from surrounding text.) Be aware that if bgcolor is used with
breaklines=true, and a line break occurs just before a page break, then text may
extend below the colored background in some instances. It is best to use a more
advanced framing package in those cases; see Framing alternatives below.
This option puts \mintinline inside a \colorbox, which does not allow line
breaks. If you want to use \setminted to set background colors, and only want
background colors on minted and \mint, you may use \setmintedinline{bgcolor={}}
to turn off the coloring for inline commands.
Framing alternatives
If you want more reliable and advanced options for background colors and framing,
you should consider a more advanced framing package such as mdframed or tcolorbox.
It is easy to add framing to minted commands and environments using the etoolbox
package, which is automatically loaded by minted. For example, using mdframed:
\BeforeBeginEnvironment{minted}{\begin{mdframed}}
\AfterEndEnvironment{minted}{\end{mdframed}}
Some framing packages also provide built-in commands for such purposes. For
example, mdframed provides a \surroundwithmdframed command, which could
be used to add a frame to all minted environments:
\surroundwithmdframed{minted}
tcolorbox even provides a built-in framing environment with minted support. Sim-
ply use \tcbuselibrary{minted} in the preamble, and then put code within a
tcblisting environment:
\begin{tcblisting}{<tcb options>,
minted language=<language>,
minted style=<style>,
minted options={<option list>} }
<code>
\end{tcblisting}
23
tcolorbox provides other commands and environments for fine-tuning listing ap-
pearance and for working with external code files.
codetagify (list of strings) (default: highlight XXX, TODO, BUG, and NOTE)
Highlight special code tags in comments and docstrings.
\begin{minted}[escapeinside=||]{py}
def f(x): def f(x):
y = x|\colorbox{green}{**}|2 y = x ** 2
return y return y
\end{minted}
Note that when math is used inside escapes, any active characters be-
yond those that are normally active in verbatim can cause problems.
Any package that relies on special active characters in math mode (for exam-
ple, icomma) will produce errors along the lines of TeX capacity exceeded and
\leavevmode\kern\z@. This may be fixed by modifying \@noligs, as described
at http://tex.stackexchange.com/questions/223876.
24
firstnumber (auto | last | integer) (default: auto = 1)
Line number of the first line.
fontseries (series name) (default: auto the same as the current font)
The font series to use.
fontsize (font size) (default: auto the same as the current font)
The size of the font to use, as a size command, e.g. \footnotesize.
fontshape (font shape) (default: auto the same as the current font)
The font shape to use.
25
keywordcase (string) (default: lower)
Changes capitalization of keywords. Takes lower, upper, or capitalize.
\renewcommand{\theFancyVerbLine}{\sffamily
\textcolor[rgb]{0.5,0.5,1.0}{\scriptsize
\oldstylenums{\arabic{FancyVerbLine}}}}
11 def all(iterable):
\begin{minted}[linenos,
12 for i in iterable:
firstnumber=11]{python}
13 if not i:
def all(iterable):
14 return False
for i in iterable:
15 return True
if not i:
return False
return True
\end{minted}
26
numberblanklines (boolean) (default: true)
Enables or disables numbering of blank lines.
27
omitted.
28
texcl (boolean) (default: false)
Enables LATEX code inside comments. Usage as in package listings. See the note
under escapeinside regarding math and ligatures.
6 Defining shortcuts
Large documents with a lot of listings will nonetheless use the same source language
and the same set of options for most listings. Always specifying all options is
redundant, a lot to type and makes performing changes hard.
One option is to use \setminted, but even then you must still specify the language
each time.
minted therefore defines a set of commands that lets you define shortcuts for the
highlighting commands. Each shortcut is specific for one programming language.
\newminted \newminted defines a new alias for the minted environment:
\newminted{cpp}{gobble=2,linenos}
If you want to provide extra options on the fly, or override existing default options,
you can do that, too:
29
\newminted{cpp}{gobble=2,linenos}
\begin{cppcode*}{linenos=false,
int const answer = 42;
frame=single}
int const answer = 42;
\end{cppcode*}
\newminted{cpp}{gobble=2,linenos}
\newenvironment{env}{\VerbatimEnvironment\begin{cppcode}}{\end{cppcode}}
\newmint The above macro only defines shortcuts for the minted environment. The main
reason is that the short command form \mint often needs different optionsat
the very least, it will generally not use the gobble option. A shortcut for \mint is
defined using \newmint[hmacro namei]{hlanguagei}{hoptionsi}. The arguments
and usage are identical to \newminted. If no hmacro namei is specified, hlanguagei
is used.
\newmint{perl}{showspaces}
my$foo=$bar;
\perl/my $foo = $bar;/
\newmintinline This creates custom versions of \mintinline. The syntax is the same as that
for \newmint: \newmintinline[hmacro namei]{hlanguagei}{hoptionsi}. If a
hmacro namei is not specified, then the created macro is called \hlanguageiinline.
\newmintinline{perl}{showspaces}
Xmy$foo=$bar;X
X\perlinline/my $foo = $bar;/X
\newmintedfile[hmacro namei]{hlanguagei}{hoptionsi}
30
If no hmacro namei is given, then the macro is called \hlanguageifile.
31
Im getting errors with math, something like TeX capacity exceeded
and \leavevmode\kern\z@. This is due to ligatures being disabled within
verbatim content. See the note under escapeinside.
With mathescape and the breqn package (or another special math
package), the document never finishes compiling or there are other
unexpected results. Some math packages like breqn give certain characters
like the comma special meanings in math mode. These can conflict with
minted. In the breqn and comma case, this can be fixed by redefining the
comma within minted environments:
\AtBeginEnvironment{minted}{\catcode\,=12\mathcode\,="613B}
\def\args{linenos,frame=single,fontsize=\footnotesize,style=bw}
\newcommand{\makenewmintedfiles}[1]{%
\newmintedfile[inputlatex]{latex}{#1}%
\newmintedfile[inputc]{c}{#1}%
}
\expandafter\makenewmintedfiles\expandafter{\args}
32
I want to use \mintinline in a context that normally doesnt allow
verbatim content. The \mintinline command will already work in many
places that do not allow normal verbatim commands like \verb, so make
sure to try it first. If it doesnt work, one of the simplest alternatives is to
save your code in a box, and then use it later. For example,
\newsavebox\mybox
\begin{lrbox}{\mybox}
\mintinline{cpp}{std::cout}
\end{lrbox}
\commandthatdoesnotlikeverbatim{Text \usebox{\mybox}}
\usepackage{etoolbox}
\BeforeBeginEnvironment{minted}{\begin{english}}
\AfterEndEnvironment{minted}{\end{english}}
Tabs are being turned into the character sequence ^^I. This
happens when you use XeLaTeX. You need to use the -8bit
command-line option so that tabs may be written correctly to tem-
porary files. See http://tex.stackexchange.com/questions/58732/
how-to-output-a-tabulation-into-a-file for more on XeLaTeXs han-
dling of tab characters.
The caption package produces an error when \captionof and other
commands are used in combination with minted. Load the caption
package with the option compatibility=false. Or better yet, use minteds
newfloat package option, which provides better caption compatibility.
\usepackage{caption}
\newenvironment{longlisting}{\captionsetup{type=listing}}{}
33
With the caption package, it is best to use minteds newfloat package option.
See http://tex.stackexchange.com/a/53540/10742 for more on listing
environments with page breaks.
I want to use a custom script/executable to access Pygments,
rather than pygmentize. Redefine \MintedPygmentize:
\renewcommand{\MintedPygmentize}{...}
Acknowledgements
Konrad Rudolph: Special thanks to Philipp Stephani and the rest of the guys from
comp.text.tex and tex.stackexchange.com.
Geoffrey Poore: Thanks to Marco Daniel for the code on tex.stackexchange.com
that inspired automatic line breaking. Thanks to Patrick Vogt for improving TikZ
externalization compatibility.
Version History
v2.5 (2017/07/19)
The default placement for the listing float is now tbp instead of h, to
parallel figure and table and also avoid warnings caused by h (#165).
34
The documentation now contains information about changing default
placement. The float package is no longer loaded when the newfloat
package option is used.
Added support for *nchars options from fvextra v1.3 that allow setting
breaklines-related indentation in terms of a number of characters,
rather than as a fixed dimension.
Fixed incompatibility with babel magyar (#158).
Added support for beamer overlays with beameroverlays option
(#155).
Comments in the Pygments LATEX style files no longer appear as literal
text when minted is used in .dtx files (#161).
autogobble now works with package option kpsewhich (#151). Under
Windows, the kpsewhich option no longer requires PowerShell.
Fixed a bug that prevented finalizecache from working with
outputdir (#149).
Fixed a bug with firstline and lastline that prevented them from
working with the minted environment (#145).
Added note on breqn conflicts to FAQ (#163).
v2.4.1 (2016/10/31)
Single quotation marks in \jobname are now replaced with underscores
in \minted@jobname to prevent quoting errors (#137).
The autogobble option now takes firstline and lastline into ac-
count (#130).
Fixed numberblanklines, which had been lost in the transition to v2.0+
(#135).
v2.4 (2016/07/20)
Line breaking and all associated options are now completely delegated
to fvextra.
Fixed a bug from v2.2 that could cause the first command or environment
to vanish when cache=false (related to work on \MintedPygmentize).
v2.3 (2016/07/14)
The fvextra package is now required. fvextra extends and patches
fancyvrb, and includes improved versions of fancyvrb extensions that
were formerly in minted.
As part of fvextra, the upquote package is always loaded. fvextra
brings the new option curlyquotes, which allows curly single quotation
marks instead of the literal backtick and typewriter single quotation
mark produced by upquote. This allows the default upquote behavior
to be disabled when desired.
35
Thanks to fvextra, the options breakbefore, breakafter, and
breakanywhere are now compatible with non-ASCII characters under
pdfTeX (#123).
Thanks to fvextra, obeytabs no longer causes lines in multi-line
comments or strings to vanish (#88), and is now compatible with
breaklines (#99). obeytabs will now always give correct results with
tabs used for indentation. However, tab stops are not guaranteed to be
correct for tabs in the midst of text.
fvextra brings the new options space, spacecolor, tab, and tabcolor
that allow these characters and their colors to be redefined (#98).
The tab may now be redefined to a flexible-width character such as
\rightarrowfill. The visible tab will now always be black by default,
instead of changing colors depending on whether it is part of indentation
for a multiline string or comment.
fvextra brings the new options highlightcolor and highlightlines,
which allow single lines or ranges of lines to be highlighted based on
line number (#124).
fvextra brings the new options numberfirstline, stepnumberfromfirst,
and stepnumberoffsetvalues that provide better control over line
numbering when stepnumber is not 1.
Fixed a bug from v2.2.2 that prevented upquote from working.
v2.2.2 (2016/06/21)
Fixed a bug introduced in v2.2 that prevented setting the Pygments
style in the preamble. Style definitions are now more compatible with
using \MintedPygmentize to call a custom pygmentize.
v2.2.1 (2016/06/15)
v2.2 (2016/06/08)
All uses of \ShellEscape (\write18) no longer wrap file names and
paths with double quotes. This allows a cache directory to be speci-
fied relative to a users home directory, for example, ~/minted_cache.
cachedir and outputdir paths containing spaces will now require ex-
plicit quoting of the parts of the paths that contain spaces, since minted
no longer supplies quoting. See the updated documentation for examples
(#89).
36
Added breakbefore, breakbeforegroup, breakbeforesymbolpre, and
breakbeforesymbolpost. These parallel breakafter*. It is possible
to use breakbefore and breakafter for the same character, so long
as breakbeforegroup and breakaftergroup have the same setting
(#117).
Added package options finalizecache and frozencache. These al-
low the cache to be prepared for (finalizecache) and then used
(frozencache) in an environment in which -shell-escape, Python,
and/or Pygments are not available. Note that this only works if minted
content does not need to be modified, and if no settings that depend on
Pygments or Python need to be changed (#113).
Style names containing hyphens and underscores (paraiso-light,
paraiso-dark, algol_nu) now work (#111).
The shellesc package is now loaded, when available, for compatibility
with LuaTeX 0.87+ (TeX Live 2016+, etc.). \ShellEscape is now
used everywhere instead of \immediate\write18. If shellesc is not
available, then a \ShellEscape macro is created. When shellesc is
loaded, there is a check for versions before v0.01c to patch a bug in
v0.01b (present in TeX Live 2015) (#112).
The bgcolor option now uses the snugshade* environment from the
framed package, so bgcolor is now compatible with page breaks. When
bgcolor is in use, immediately preceding text will no longer push the
minted environment into the margin, and there is now adequate spacing
from surrounding text (#121).
Added missing support for fancyvrbs labelposition (#102).
Improved fix for TikZ externalization, thanks to Patrick Vogt (#73).
Fixed breakautoindent; it was disabled in version 2.1 due to a bug in
breakanywhere.
Properly fixed handling of \MintedPygmentize (#62).
Added note on incompatibility of breaklines and obeytabs options.
Trying to use these together will now result in a package error (#99).
Added note on issues with obeytabs and multiline comments (#88).
Due to the various obeytabs issues, the docs now discourage using
obeytabs.
Added note to FAQ on fancybox and fancyvrb conflict (#87).
Added note to docs on the need for \VerbatimEnvironment in environ-
ment definitions based on minted environments.
v2.1 (2015/09/09)
Changing the highlighting style now no longer involves re-highlighing
code. Style may be changed with almost no overhead.
37
Improved control of automatic line breaks. New option breakanywhere
allows line breaks anywhere when breaklines=true. The pre-
break and post-break symbols for these types of breaks may be set
with breakanywheresymbolpre and breakanywheresymbolpost (#79).
New option breakafter allows specifying characters after which line
breaks are allowed. Breaks between adjacent, identical characters may
be controlled with breakaftergroup. The pre-break and post-break
symbols for these types of breaks may be set with breakaftersymbolpre
and breakaftersymbolpost.
breakbytoken now only breaks lines between tokens that are sep-
arated by spaces, matching the documentation. The new option
breakbytokenanywhere allows for breaking between tokens that are
immediately adjacent. Fixed a bug in \mintinline that produced a
following linebreak when \mintinline was the first thing in a paragraph
and breakbytoken was true (#77).
Fixed a bug in draft mode option handling for \inputminted (#75).
Fixed a bug with \MintedPygmentize when a custom pygmentize was
specified and there was no pygmentize on the default path (#62).
Added note to docs on caching large numbers of code blocks under OS X
(#78).
Added discussion of current limitations of texcomments (#66) and
escapeinside (#70).
PGF/TikZ externalization is automatically detected and supported
(#73).
The package is now compatible with LATEX files whose names contain
spaces (#85).
v2.0 (2015/01/31)
Added the compatibility package minted1, which provides the minted
1.7 code. This may be loaded when 1.7 compatibility is required. This
package works with other packages that \RequirePackage{minted}, so
long as it is loaded first.
Moved all old \changes into changelog.
Development releases for 2.0 (2014January 2015)
Caching is now on by default.
Fixed a bug that prevented compiling under Windows when file names
contained commas.
Added breaksymbolleft, breaksymbolsepleft, breaksymbolindentleft,
breaksymbolright, breaksymbolsepright, and breaksymbolindentright
options. breaksymbol, breaksymbolsep, and breaksymbolindent are
now aliases for the correspondent *left options.
38
Added kpsewhich package option. This uses kpsewhich to locate the
files that are to be highlighted. This provides compatibility with build
tools like texi2pdf that function by modifying TEXINPUTS (#25).
Fixed a bug that prevented \inputminted from working with outputdir.
Added informative error messages when Pygments output is missing.
Added final package option (opposite of draft).
Renamed the default cache directory to _minted-<jobname> (replaced
leading period with underscore). The leading period caused the cache
directory to be hidden on many systems, which was a potential source
of confusion.
breaklines and breakbytoken now work with \mintinline (#31).
bgcolor may now be set through \setminted and \setmintedinline.
When math is enabled via texcomments, mathescape, or escapeinside,
space characters now behave as in normal math by vanishing, instead of
appearing as literal spaces. Math need no longer be specially formatted
to avoid undesired spaces.
In default value of \listoflistingscaption, capitalized Listings so
that capitalization is consistent with default values for other lists (figures,
tables, algorithms, etc.).
Added newfloat package option that creates the listing environment
using newfloat rather than float, thus providing better compatibility
with the caption package (#12).
Added support for Pygments option stripall.
Added breakbytoken option that prevents breaklines from breaking
lines within Pygments tokens.
\mintinline uses a \colorbox when bgcolor is set, to give more
reasonable behavior (#57).
For PHP, \mintinline automatically begins with startinline=true
(#23).
Fixed a bug that threw off line numbering in minted when langlinenos=false
and firstnumber=last. Fixed a bug in \mintinline that threw off sub-
sequent line numbering when langlinenos=false and firstnumber=last.
Improved behavior of \mint and \mintinline in draft mode.
The \mint command now has the additional capability to take code
delimited by paired curly braces {}.
It is now possible to set options only for \mintinline using the new
\setmintedinline command. Inline options override options specified
via \setminted.
Completely rewrote option handling. fancyvrb options are now handled
on the LATEX side directly, rather than being passed to Pygments and
then returned. This makes caching more efficient, since code is no longer
rehighlighted just because fancyvrb options changed.
39
Fixed buffer size error caused by using cache with a very large number
of files (#61).
Fixed autogobble bug that caused failure under some operating systems.
Added support for escapeinside (requires Pygments 2.0+; #38).
Fixed issues with XeTeX and caching (#40).
The upquote package now works correctly with single quotes when
using Pygments 1.6+ (#34).
Fixed caching incompatibility with Linux and OS X under xelatex (#18
and #42).
Fixed autogobble incompatibility with Linux and OS X.
\mintinline and derived commands are now robust, via \newrobustcmd
from etoolbox.
Unused styles are now cleaned up when caching.
Fixed a bug that could interfere with caching (#24).
Added draft package option (#39). This typesets all code using
fancyvrb; Pygments is not used. This trades syntax highlighting for
maximum speed in compiling.
Added automatic line breaking with breaklines and related options
(#1).
Fixed a bug with boolean options that needed a False argument to
cooperate with \setminted (#48).
v2.0-alpha3 (2013/12/21)
Added autogobble option. This sends code through Pythons
textwrap.dedent() to remove common leading whitespace.
Added package option cachedir. This allows the directory in which
cached content is saved to be specified.
Added package option outputdir. This allows an output directory
for temporary files to be specified, so that the package can work with
LaTeXs -output-directory command-line option.
The kvoptions package is now required. It is needed to process key-
value package options, such as the new cachedir option.
Many small improvements, including better handling of paths under
Windows and improved key system.
v2.0-alpha2 (2013/08/21)
\DeleteFile now only deletes files if they do indeed exist. This elimi-
nates warning messages due to missing files.
Fixed a bug in the definition of \DeleteFile for non-Windows systems.
40
Added support for Pygments option stripnl.
Settings macros that were previously defined globally are now defined lo-
cally, so that \setminted may be confined by \begingroup...\endgroup
as expected.
Macro definitions for a given style are now loaded only once per docu-
ment, rather than once per command/environment. This works even
without caching.
A custom script/executable may now be substituted for pygmentize by
redefining \MintedPygmentize.
v2.0alpha (2013/07/30)
1.7 (2011/09/17)
Options for float placement added [2011/09/12]
Fixed tabsize option [2011/08/30]
More robust detection of the -shell-escape option [2011/01/21]
Added the label option [2011/01/04]
Installation instructions added [2010/03/16]
Minimal working example added [2010/03/16]
41
Added PHP-specific options [2010/03/14]
Removed unportable flag from Unix shell command [2010/02/16]
1.6 (2010/01/31)
Added font-related options [2010/01/27]
Windows support added [2010/01/27]
Added command shortcuts [2010/01/22]
Simpler versioning scheme [2010/01/22]
0.1.5 (2010/01/13)
0.0.4 (2010/01/08)
Initial version [2010/01/08]
8 Implementation
Load required packages. For compatibility reasons, most old functionality should
be supported with the original set of packages. More recently added packages, such
as etoolbox and xstring, should only be used for new features when possible.
shellesc must be loaded before any packages that invoke \write18, since it is
possible that they havent yet been patched to work with LuaTeX 0.87+.
1 \RequirePackage{keyval}
2 \RequirePackage{kvoptions}
3 \RequirePackage{fvextra}
4 \RequirePackage{ifthen}
5 \RequirePackage{calc}
6 \IfFileExists{shellesc.sty}
7 {\RequirePackage{shellesc}
8 \@ifpackagelater{shellesc}{2016/04/29}
9 {}
10 {\protected\def\ShellEscape{\immediate\write18 }}}
11 {\protected\def\ShellEscape{\immediate\write18 }}
12 \RequirePackage{ifplatform}
13 \RequirePackage{pdftexcmds}
14 \RequirePackage{etoolbox}
42
15 \RequirePackage{xstring}
16 \RequirePackage{lineno}
17 \RequirePackage{framed}
Make sure that either color or xcolor is loaded by the beginning of the document.
18 \AtEndPreamble{%
19 \@ifpackageloaded{color}{}{%
20 \@ifpackageloaded{xcolor}{}{\RequirePackage{xcolor}}}%
21 }
\minted@float@within Define an option that controls the section numbering of the listing float.
22 \DeclareVoidOption{chapter}{\def\minted@float@within{chapter}}
23 \DeclareVoidOption{section}{\def\minted@float@within{section}}
newfloat Define an option to use newfloat rather than float to create a floated listing
environment.
24 \DeclareBoolOption{newfloat}
cache Define an option that determines whether highlighted content is cached. We use a
boolean to keep track of its state.
25 \DeclareBoolOption[true]{cache}
\minted@jobname At various points, temporary files and directories will need to be named after
the main .tex file. The typical way to do this is to use \jobname. However,
if the file name contains spaces, then \jobname will contain the name wrapped
in quotes (older versions of MiKTeX replace spaces with asterisks instead, and
XeTeX apparently allows double quotes within file names, in which case names are
wrapped in single quotes). While that is perfectly fine for working with LATEX
internally, it causes problems with \write18, since quotes will end up in unwanted
locations in shell commands. It would be possible to strip the wrapping quotation
marks when they are present, and maintain any spaces in the file name. But it is
simplest to create a sanitized version of \jobname in which spaces and asterisks
are replaced by underscores, and double quotes are stripped. Single quotes are also
replaced, since they can cause quoted string errors, or become double quotes in
the process of being passed to the system through \write18.
26 \StrSubstitute{\jobname}{ }{_}[\minted@jobname]
27 \StrSubstitute{\minted@jobname}{*}{_}[\minted@jobname]
28 \StrSubstitute{\minted@jobname}{"}{}[\minted@jobname]
29 \StrSubstitute{\minted@jobname}{}{_}[\minted@jobname]
43
\minted@cachedir Set the directory in which cached content is saved. The default uses a minted-
prefix followed by the sanitized \minted@jobname.
30 \newcommand{\minted@cachedir}{\detokenize{_}minted-\minted@jobname}
31 \let\minted@cachedir@windows\minted@cachedir
32 \define@key{minted}{cachedir}{%
33 \@namedef{minted@cachedir}{#1}%
34 \StrSubstitute{\minted@cachedir}{/}{\@backslashchar}[\minted@cachedir@windows]}
finalizecache Define an option that switches the naming of cache files from an MD5-based system
to a listing<number> scheme. Compiling with this option is a prerequisite to
turning on frozencache.
35 \DeclareBoolOption{finalizecache}
frozencache Define an option that uses a fixed set of cache files, using listing<number> file
naming with \write18 disabled. This is convenient for working with a document
in an environment in which \write18 support is disabled and minted content does
not need to be modified.
36 \DeclareBoolOption{frozencache}
\minted@outputdir The -output-directory command-line option for LATEX causes problems for
minted, because the minted temporary files are saved in the output directory,
but minted still looks for them in the document root directory. There is no way
to access the value of the command-line option. But it is possible to allow the
output directory to be specified manually as a package option. A trailing slash
is automatically appended to the outputdir, so that it may be directly joined to
cachedir. This may be redundant if the user-supplied value already ends with
a slash, but doubled slashes are ignored under *nix and Windows, so it isnt a
problem.
37 \let\minted@outputdir\@empty
38 \let\minted@outputdir@windows\@empty
39 \define@key{minted}{outputdir}{%
40 \@namedef{minted@outputdir}{#1/}%
41 \StrSubstitute{\minted@outputdir}{/}%
42 {\@backslashchar}[\minted@outputdir@windows]}
kpsewhich Define an option that invokes kpsewhich to locate the files that are to be
pygmentized. This isnt done by default to avoid the extra overhead, but can be
useful with some build tools such as texi2pdf that rely on modifying TEXINPUTS.
43 \DeclareBoolOption{kpsewhich}
langlinenos Define an option that makes all minted environments and \mint commands for a
given language share cumulative line numbering (if firstnumber=last).
44
44 \DeclareBoolOption{langlinenos}
draft Define an option that allows fancyvrb to do all typesetting directly, without using
Pygments. This trades syntax highlighting for speed. Note that in many cases, the
difference in performance between caching and draft mode will be minimal. Also
note that draft settings may be inherited from the document class.
45 \DeclareBoolOption{draft}
final Define a final option that is the opposite of draft, since many packages do this.
46 \DeclareComplementaryOption{final}{draft}
Process package options. Proceed with everything that immediately relies upon
them. If PGF/TikZ externalization is in use, switch on draft mode and turn off
cache. Externalization involves compiling the entire document; all parts not related
to the current image are silently thrown away. minted needs to cooperate with that
by not writing any temp files or creating any directories. Two checks are done for
externalization. The first, using \tikzifexternalizing, works if externalization
is set before minted is loaded. The second, using \tikzexternalrealjob, works if
externalization is set after minted is loaded.
47 \ProcessKeyvalOptions*
48 \ifthenelse{\boolean{minted@newfloat}}{\RequirePackage{newfloat}}{\RequirePackage{float}}
49 \ifcsname tikzifexternalizing\endcsname
50 \tikzifexternalizing{\minted@drafttrue\minted@cachefalse}{}
51 \else
52 \ifcsname tikzexternalrealjob\endcsname
53 \minted@drafttrue
54 \minted@cachefalse
55 \else
56 \fi
57 \fi
58 \ifthenelse{\boolean{minted@finalizecache}}%
59 {\ifthenelse{\boolean{minted@frozencache}}%
60 {\PackageError{minted}%
61 {Options "finalizecache" and "frozencache" are not compatible}%
62 {Options "finalizecache" and "frozencache" are not compatible}}%
63 {}}%
64 {}
65 \ifthenelse{\boolean{minted@cache}}%
66 {\ifthenelse{\boolean{minted@frozencache}}%
67 {}%
68 {\AtEndOfPackage{\ProvideDirectory{\minted@outputdir\minted@cachedir}}}}%
69 {}
45
8.3 Input, caching, and temp files
\minted@input We need a wrapper for \input. In most cases, \input failure will be due to
attempts to use \inputminted with files that dont exist, but we also want to give
informative error messages when outputdir is needed or incompatible build tools
are used.
70 \newcommand{\minted@input}[1]{%
71 \IfFileExists{#1}%
72 {\input{#1}}%
73 {\PackageError{minted}{Missing Pygments output; \string\inputminted\space
74 was^^Jprobably given a file that does not exist--otherwise, you may need
75 ^^Jthe outputdir package option, or may be using an incompatible build
76 tool,^^Jor may be using frozencache with a missing file}%
77 {This could be caused by using -output-directory or -aux-directory
78 ^^Jwithout setting minteds outputdir, or by using a build tool that
79 ^^Jchanges paths in ways minted cannot detect,
80 ^^Jor using frozencache with a missing file.}}%
81 }
\minted@infile Define a default name for files of highlighted content that are brought it. Caching
will redefine this. We start out with the default, non-caching value.
82 \newcommand{\minted@infile}{\[email protected]}
We need a way to track the cache files that are created, and delete those that
are not in use. This is accomplished by creating a comma-delimited list of cache
files and saving this list to the .aux file so that it may be accessed on subsequent
runs. During subsequent runs, this list is compared against the cache files that
are actually used, and unused files are deleted. Cache file names are created with
MD5 hashes of highlighting settings and file contents, with a .pygtex extension, so
they never contain commas. Thus comma-delimiting the list of file names doesnt
introduce a potential for errors.
83 \newcommand{\minted@cachelist}{}
\minted@addcachefile This adds a file to the list of cache files. It also creates a macro involving the hash,
so that the current usage of the hash can be easily checked by seeing if the macro
exists. The list of cache files must be created with built-in linebreaks, so that when
it is written to the .aux file, it wont all be on one line and thereby risk buffer
errors.
84 \newcommand{\minted@addcachefile}[1]{%
85 \expandafter\long\expandafter\gdef\expandafter\minted@cachelist\expandafter{%
86 \minted@cachelist,^^J%
46
87 \space\space#1}%
88 \expandafter\gdef\csname minted@cached@#1\endcsname{}%
89 }
\minted@savecachelist We need to be able to save the list of cache files to the .aux file, so that we can
reload it on the next run.
90 \newcommand{\minted@savecachelist}{%
91 \ifdefempty{\minted@cachelist}{}{%
92 \immediate\write\@mainaux{%
93 \string\gdef\string\minted@oldcachelist\string{%
94 \minted@cachelist\string}}%
95 }%
96 }
At the end of the document, save the list of cache files and clean the cache. If
in draft mode, dont clean up the cache and save the old cache file list for next
time. This allows draft mode to be switched on and off without requiring that all
highlighted content be regenerated. The saving and cleaning operations may be
called without conditionals, since their definitions already contain all necessary
checks for their correct operation.
110 \ifthenelse{\boolean{minted@draft}}%
111 {\AtEndDocument{%
112 \ifcsname minted@oldcachelist\endcsname
113 \StrSubstitute{\minted@oldcachelist}{,}{,^^J }[\minted@cachelist]
114 \minted@savecachelist
115 \fi}}%
116 {\ifthenelse{\boolean{minted@frozencache}}%
117 {\AtEndDocument{%
118 \ifcsname minted@oldcachelist\endcsname
119 \StrSubstitute{\minted@oldcachelist}{,}{,^^J }[\minted@cachelist]
120 \minted@savecachelist
47
121 \fi}}%
122 {\AtEndDocument{%
123 \minted@savecachelist
124 \minted@cleancache}}}%
8.4 OS interaction
\DeleteFile Delete a file. Define conditionally in case an equivalent macro has already been
defined.
125 \ifwindows
126 \providecommand{\DeleteFile}[2][]{%
127 \ifthenelse{\equal{#1}{}}%
128 {\IfFileExists{#2}{\ShellEscape{del #2}}{}}%
129 {\IfFileExists{#1/#2}{%
130 \StrSubstitute{#1}{/}{\@backslashchar}[\minted@windir]
131 \ShellEscape{del \minted@windir\@backslashchar #2}}{}}}
132 \else
133 \providecommand{\DeleteFile}[2][]{%
134 \ifthenelse{\equal{#1}{}}%
135 {\IfFileExists{#2}{\ShellEscape{rm #2}}{}}%
136 {\IfFileExists{#1/#2}{\ShellEscape{rm #1/#2}}{}}}
137 \fi
\ProvideDirectory We need to be able to create a directory, if it doesnt already exist. This is primarily
for storing cached highlighted content.
138 \ifwindows
139 \newcommand{\ProvideDirectory}[1]{%
140 \StrSubstitute{#1}{/}{\@backslashchar}[\minted@windir]
141 \ShellEscape{if not exist \minted@windir\space mkdir \minted@windir}}
142 \else
143 \newcommand{\ProvideDirectory}[1]{%
144 \ShellEscape{mkdir -p #1}}
145 \fi
48
\TestAppExists{appname}
\ifthenelse{\boolean{AppExists}}{app exists}{app doesn't exist}
146 \newboolean{AppExists}
147 \newread\minted@appexistsfile
148 \newcommand{\TestAppExists}[1]{
149 \ifwindows
On Windows, we need to use path expansion and write the result to a file. If the
application doesnt exist, the file will be empty (except for a newline); otherwise,
it will contain the full path of the application.
150 \DeleteFile{\[email protected]}
151 \ShellEscape{for \string^\@percentchar i in (#1.exe #1.bat #1.cmd)
152 do set > \[email protected] <nul: /p
153 x=\string^\@percentchar \string~$PATH:i>> \[email protected]}
154 %$ <- balance syntax highlighting
155 \immediate\openin\minted@appexistsfile\[email protected]
156 \expandafter\def\expandafter\@tmp@cr\expandafter{\the\endlinechar}
157 \endlinechar=-1\relax
158 \readline\minted@appexistsfile to \minted@apppathifexists
159 \endlinechar=\@tmp@cr
160 \ifthenelse{\equal{\minted@apppathifexists}{}}
161 {\AppExistsfalse}
162 {\AppExiststrue}
163 \immediate\closein\minted@appexistsfile
164 \DeleteFile{\[email protected]}
165 \else
49
some need to be sent to fancyvrb, and some need to be processed within minted
itself.
To begin with, we need macros for storing lists of options that will later be passed
via the command line to Pygments (optlistcl). These are defined at the global
(cl@g), language (cl@lang), and command or environment (cl@cmd) levels, so that
settings can be specified at various levels of hierarchy. The language macro is
actually a placeholder. The current language will be tracked using \minted@lang.
Each individual language will create a \minted@optlistcl@langhlanguagei macro.
\minted@optlistcl@lang may be \let to this macro as convenient; otherwise,
the general language macro merely serves as a placeholder.
The global- and language-level lists also have an inline (i) variant. This allows
different settings to be applied in inline settings. An inline variant is not needed at
the command/environment level, since at that level settings would not be present
unless they were supposed to be applied.
\minted@optlistcl@g
173 \newcommand{\minted@optlistcl@g}{}
\minted@optlistcl@g@i
174 \newcommand{\minted@optlistcl@g@i}{}
\minted@lang
175 \let\minted@lang\@empty
\minted@optlistcl@lang
176 \newcommand{\minted@optlistcl@lang}{}
\minted@optlistcl@lang@i
177 \newcommand{\minted@optlistcl@lang@i}{}
\minted@optlistcl@cmd
178 \newcommand{\minted@optlistcl@cmd}{}
We also need macros for storing lists of options that will later be passed to fancyvrb
(optlistfv). As before, these exist at the global (fv@g), language (fv@lang), and
command or environment (fv@cmd) levels. Pygments accepts fancyvrb options,
but in almost all cases, these options may be applied via \fvset rather than via
running Pygments. This is significantly more efficient when caching is turned on,
since it allows formatting changes to be applied without having to re-highlight the
code.
50
\minted@optlistfv@g
179 \newcommand{\minted@optlistfv@g}{}
\minted@optlistfv@g@i
180 \newcommand{\minted@optlistfv@g@i}{}
\minted@optlistfv@lang
181 \newcommand{\minted@optlistfv@lang}{}
\minted@optlistfv@lang@i
182 \newcommand{\minted@optlistfv@lang@i}{}
\minted@optlistfv@cmd
183 \newcommand{\minted@optlistfv@cmd}{}
\minted@configlang We need a way to check whether a language has had all its option list macros
created. This generally occurs in a context where \minted@lang needs to be set.
So we create a macro that does both at once. If the language list macros do not
exist, we create them globally to simplify future operations.
184 \newcommand{\minted@configlang}[1]{%
185 \def\minted@lang{#1}%
186 \ifcsname minted@optlistcl@lang\minted@lang\endcsname\else
187 \expandafter\gdef\csname minted@optlistcl@lang\minted@lang\endcsname{}%
188 \fi
189 \ifcsname minted@optlistcl@lang\minted@lang @i\endcsname\else
190 \expandafter\gdef\csname minted@optlistcl@lang\minted@lang @i\endcsname{}%
191 \fi
192 \ifcsname minted@optlistfv@lang\minted@lang\endcsname\else
193 \expandafter\gdef\csname minted@optlistfv@lang\minted@lang\endcsname{}%
194 \fi
195 \ifcsname minted@optlistfv@lang\minted@lang @i\endcsname\else
196 \expandafter\gdef\csname minted@optlistfv@lang\minted@lang @i\endcsname{}%
197 \fi
198 }
We need a way to define options in bulk at the global, language, and command
levels. How this is done will depend on the type of option. The keys created are
grouped by level: minted@opt@g, minted@opt@lang, and minted@opt@cmd, plus
inline variants. The language-level key groupings use \minted@lang internally, so
we dont need to duplicate the internals for different languages. The key groupings
are independent of whether a given option relates to Pygments, fancyvrb, etc.
Organization by level is the only thing that is important here, since keys are
51
applied in a hierarchical fashion. Key values are stored in macros of the form
\minted@opt@hleveli:hkeyi, so that they may be retrieved later. In practice, these
key macros will generally not be used directly (hence the colon in the name).
Rather, the hierarchy of macros will be traversed until an existing macro is found.
\minted@def@optcl Define a generic option that will be passed to the command line. Options are given
in a {key}{value} format that is transformed into key=value and then passed to
pygmentize. This allows value to be easily stored in a separate macro for later
access. This is useful, for example, in separately accessing the value of encoding
for performing autogobble.
If a key option is specified without =value, the default is assumed. Options are
automatically created at all levels.
Options are added to the option lists in such a way that they will be detokenized.
This is necessary since they will ultimately be used in \write18.
199 \newcommand{\minted@addto@optlistcl}[2]{%
200 \expandafter\def\expandafter#1\expandafter{#1%
201 \detokenize{#2}\space}}
202 \newcommand{\minted@addto@optlistcl@lang}[2]{%
203 \expandafter\let\expandafter\minted@tmp\csname #1\endcsname
204 \expandafter\def\expandafter\minted@tmp\expandafter{\minted@tmp%
205 \detokenize{#2}\space}%
206 \expandafter\let\csname #1\endcsname\minted@tmp}
207 \newcommand{\minted@def@optcl}[4][]{%
208 \ifthenelse{\equal{#1}{}}%
209 {\define@key{minted@opt@g}{#2}{%
210 \minted@addto@optlistcl{\minted@optlistcl@g}{#3=#4}%
211 \@namedef{minted@opt@g:#2}{#4}}%
212 \define@key{minted@opt@g@i}{#2}{%
213 \minted@addto@optlistcl{\minted@optlistcl@g@i}{#3=#4}%
214 \@namedef{minted@opt@g@i:#2}{#4}}%
215 \define@key{minted@opt@lang}{#2}{%
216 \minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang}{#3=#4}%
217 \@namedef{minted@opt@lang\minted@lang:#2}{#4}}%
218 \define@key{minted@opt@lang@i}{#2}{%
219 \minted@addto@optlistcl@lang{%
220 minted@optlistcl@lang\minted@lang @i}{#3=#4}%
221 \@namedef{minted@opt@lang\minted@lang @i:#2}{#4}}%
222 \define@key{minted@opt@cmd}{#2}{%
223 \minted@addto@optlistcl{\minted@optlistcl@cmd}{#3=#4}%
224 \@namedef{minted@opt@cmd:#2}{#4}}}%
225 {\define@key{minted@opt@g}{#2}[#1]{%
226 \minted@addto@optlistcl{\minted@optlistcl@g}{#3=#4}%
227 \@namedef{minted@opt@g:#2}{#4}}%
228 \define@key{minted@opt@g@i}{#2}[#1]{%
229 \minted@addto@optlistcl{\minted@optlistcl@g@i}{#3=#4}%
230 \@namedef{minted@opt@g@i:#2}{#4}}%
231 \define@key{minted@opt@lang}{#2}[#1]{%
52
232 \minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang}{#3=#4}%
233 \@namedef{minted@opt@lang\minted@lang:#2}{#4}}%
234 \define@key{minted@opt@lang@i}{#2}[#1]{%
235 \minted@addto@optlistcl@lang{%
236 minted@optlistcl@lang\minted@lang @i}{#3=#4}%
237 \@namedef{minted@opt@lang\minted@lang @i:#2}{#4}}%
238 \define@key{minted@opt@cmd}{#2}[#1]{%
239 \minted@addto@optlistcl{\minted@optlistcl@cmd}{#3=#4}%
240 \@namedef{minted@opt@cmd:#2}{#4}}}%
241 }
This covers the typical options that must be passed to Pygments. But some,
particularly escapeinside, need more work. Since their arguments may contain
escaped characters, expansion rather than detokenization is needed. Getting
expansion to work as desired in a \write18 context requires the redefinition of
some characters.
\minted@escchars We need to define versions of common escaped characters that will work correctly
under expansion for use in \write18.
242 \edef\minted@hashchar{\string#}
243 \edef\minted@dollarchar{\string$}
244 \edef\minted@ampchar{\string&}
245 \edef\minted@underscorechar{\string_}
246 \edef\minted@tildechar{\string~}
247 \edef\minted@leftsquarebracket{\string[}
248 \edef\minted@rightsquarebracket{\string]}
249 \newcommand{\minted@escchars}{%
250 \let\#\minted@hashchar
251 \let\%\@percentchar
252 \let\{\@charlb
253 \let\}\@charrb
254 \let\$\minted@dollarchar
255 \let\&\minted@ampchar
256 \let\_\minted@underscorechar
257 \let\\\@backslashchar
258 \let~\minted@tildechar
259 \let\~\minted@tildechar
260 \let\[\minted@leftsquarebracket
261 \let\]\minted@rightsquarebracket
262 } %$ <- highlighting
53
268 \expandafter\minted@addto@optlistcl@e@i\expandafter{\minted@xtmp}{#1}}
269 \def\minted@addto@optlistcl@e@i#1#2{%
270 \expandafter\def\expandafter#2\expandafter{#2#1\space}}
271 \newcommand{\minted@addto@optlistcl@lang@e}[2]{%
272 \begingroup
273 \minted@escchars
274 \xdef\minted@xtmp{#2}%
275 \endgroup
276 \expandafter\minted@addto@optlistcl@lang@e@i\expandafter{\minted@xtmp}{#1}}
277 \def\minted@addto@optlistcl@lang@e@i#1#2{%
278 \expandafter\let\expandafter\minted@tmp\csname #2\endcsname
279 \expandafter\def\expandafter\minted@tmp\expandafter{\minted@tmp#1\space}%
280 \expandafter\let\csname #2\endcsname\minted@tmp}
281 \newcommand{\minted@def@optcl@e}[4][]{%
282 \ifthenelse{\equal{#1}{}}%
283 {\define@key{minted@opt@g}{#2}{%
284 \minted@addto@optlistcl@e{\minted@optlistcl@g}{#3=#4}%
285 \@namedef{minted@opt@g:#2}{#4}}%
286 \define@key{minted@opt@g@i}{#2}{%
287 \minted@addto@optlistcl@e{\minted@optlistcl@g@i}{#3=#4}%
288 \@namedef{minted@opt@g@i:#2}{#4}}%
289 \define@key{minted@opt@lang}{#2}{%
290 \minted@addto@optlistcl@lang@e{minted@optlistcl@lang\minted@lang}{#3=#4}%
291 \@namedef{minted@opt@lang\minted@lang:#2}{#4}}%
292 \define@key{minted@opt@lang@i}{#2}{%
293 \minted@addto@optlistcl@lang@e{%
294 minted@optlistcl@lang\minted@lang @i}{#3=#4}%
295 \@namedef{minted@opt@lang\minted@lang @i:#2}{#4}}%
296 \define@key{minted@opt@cmd}{#2}{%
297 \minted@addto@optlistcl@e{\minted@optlistcl@cmd}{#3=#4}%
298 \@namedef{minted@opt@cmd:#2}{#4}}}%
299 {\define@key{minted@opt@g}{#2}[#1]{%
300 \minted@addto@optlistcl@e{\minted@optlistcl@g}{#3=#4}%
301 \@namedef{minted@opt@g:#2}{#4}}%
302 \define@key{minted@opt@g@i}{#2}[#1]{%
303 \minted@addto@optlistcl@e{\minted@optlistcl@g@i}{#3=#4}%
304 \@namedef{minted@opt@g@i:#2}{#4}}%
305 \define@key{minted@opt@lang}{#2}[#1]{%
306 \minted@addto@optlistcl@lang@e{minted@optlistcl@lang\minted@lang}{#3=#4}%
307 \@namedef{minted@opt@lang\minted@lang:#2}{#4}}%
308 \define@key{minted@opt@lang@i}{#2}[#1]{%
309 \minted@addto@optlistcl@lang@e{%
310 minted@optlistcl@lang\minted@lang @i}{#3=#4}%
311 \@namedef{minted@opt@lang\minted@lang @i:#2}{#4}}%
312 \define@key{minted@opt@cmd}{#2}[#1]{%
313 \minted@addto@optlistcl@e{\minted@optlistcl@cmd}{#3=#4}%
314 \@namedef{minted@opt@cmd:#2}{#4}}}%
315 }
54
\minted@def@optcl@switch Define a switch or boolean option that is passed to Pygments, which is true when
no value is specified.
316 \newcommand{\minted@def@optcl@switch}[2]{%
317 \define@booleankey{minted@opt@g}{#1}%
318 {\minted@addto@optlistcl{\minted@optlistcl@g}{#2=True}%
319 \@namedef{minted@opt@g:#1}{true}}
320 {\minted@addto@optlistcl{\minted@optlistcl@g}{#2=False}%
321 \@namedef{minted@opt@g:#1}{false}}
322 \define@booleankey{minted@opt@g@i}{#1}%
323 {\minted@addto@optlistcl{\minted@optlistcl@g@i}{#2=True}%
324 \@namedef{minted@opt@g@i:#1}{true}}
325 {\minted@addto@optlistcl{\minted@optlistcl@g@i}{#2=False}%
326 \@namedef{minted@opt@g@i:#1}{false}}
327 \define@booleankey{minted@opt@lang}{#1}%
328 {\minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang}{#2=True}%
329 \@namedef{minted@opt@lang\minted@lang:#1}{true}}
330 {\minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang}{#2=False}%
331 \@namedef{minted@opt@lang\minted@lang:#1}{false}}
332 \define@booleankey{minted@opt@lang@i}{#1}%
333 {\minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang @i}{#2=True}%
334 \@namedef{minted@opt@lang\minted@lang @i:#1}{true}}
335 {\minted@addto@optlistcl@lang{minted@optlistcl@lang\minted@lang @i}{#2=False}%
336 \@namedef{minted@opt@lang\minted@lang @i:#1}{false}}
337 \define@booleankey{minted@opt@cmd}{#1}%
338 {\minted@addto@optlistcl{\minted@optlistcl@cmd}{#2=True}%
339 \@namedef{minted@opt@cmd:#1}{true}}
340 {\minted@addto@optlistcl{\minted@optlistcl@cmd}{#2=False}%
341 \@namedef{minted@opt@cmd:#1}{false}}
342 }
Now that all the machinery for Pygments options is in place, we can move on to
fancyvrb options.
\minted@def@optfv Define fancyvrb options. The #1={##1} is needed because any braces enclosing the
argument (##1) will be stripped during the initial capture, and they need to be
reinserted before fancyvrb gets the argument and sends it through another keyval
processing step. If there were no braces initially, adding them here doesnt hurt,
since they are just stripped off again during processing.
343 \newcommand{\minted@def@optfv}[1]{%
344 \define@key{minted@opt@g}{#1}{%
345 \expandafter\def\expandafter\minted@optlistfv@g\expandafter{%
346 \minted@optlistfv@g#1={##1},}%
347 \@namedef{minted@opt@g:#1}{##1}}
348 \define@key{minted@opt@g@i}{#1}{%
349 \expandafter\def\expandafter\minted@optlistfv@g@i\expandafter{%
350 \minted@optlistfv@g@i#1={##1},}%
351 \@namedef{minted@opt@g@i:#1}{##1}}
55
352 \define@key{minted@opt@lang}{#1}{%
353 \expandafter\let\expandafter\minted@tmp%
354 \csname minted@optlistfv@lang\minted@lang\endcsname
355 \expandafter\def\expandafter\minted@tmp\expandafter{%
356 \minted@tmp#1={##1},}%
357 \expandafter\let\csname minted@optlistfv@lang\minted@lang\endcsname%
358 \minted@tmp
359 \@namedef{minted@opt@lang\minted@lang:#1}{##1}}
360 \define@key{minted@opt@lang@i}{#1}{%
361 \expandafter\let\expandafter\minted@tmp%
362 \csname minted@optlistfv@lang\minted@lang @i\endcsname
363 \expandafter\def\expandafter\minted@tmp\expandafter{%
364 \minted@tmp#1={##1},}%
365 \expandafter\let\csname minted@optlistfv@lang\minted@lang @i\endcsname%
366 \minted@tmp
367 \@namedef{minted@opt@lang\minted@lang @i:#1}{##1}}
368 \define@key{minted@opt@cmd}{#1}{%
369 \expandafter\def\expandafter\minted@optlistfv@cmd\expandafter{%
370 \minted@optlistfv@cmd#1={##1},}%
371 \@namedef{minted@opt@cmd:#1}{##1}}
372 }
56
399 \minted@tmp#1=false,}%
400 \expandafter\let\csname minted@optlistfv@lang\minted@lang\endcsname%
401 \minted@tmp
402 \@namedef{minted@opt@lang\minted@lang:#1}{false}}%
403 \define@booleankey{minted@opt@lang@i}{#1}%
404 {\expandafter\let\expandafter\minted@tmp%
405 \csname minted@optlistfv@lang\minted@lang @i\endcsname
406 \expandafter\def\expandafter\minted@tmp\expandafter{%
407 \minted@tmp#1=true,}%
408 \expandafter\let\csname minted@optlistfv@lang\minted@lang @i\endcsname%
409 \minted@tmp
410 \@namedef{minted@opt@lang\minted@lang @i:#1}{true}}%
411 {\expandafter\let\expandafter\minted@tmp%
412 \csname minted@optlistfv@lang\minted@lang @i\endcsname
413 \expandafter\def\expandafter\minted@tmp\expandafter{%
414 \minted@tmp#1=false,}%
415 \expandafter\let\csname minted@optlistfv@lang\minted@lang @i\endcsname%
416 \minted@tmp
417 \@namedef{minted@opt@lang\minted@lang @i:#1}{false}}%
418 \define@booleankey{minted@opt@cmd}{#1}%
419 {\expandafter\def\expandafter\minted@optlistfv@cmd\expandafter{%
420 \minted@optlistfv@cmd#1=true,}%
421 \@namedef{minted@opt@cmd:#1}{true}}%
422 {\expandafter\def\expandafter\minted@optlistfv@cmd\expandafter{%
423 \minted@optlistfv@cmd#1=false,}%
424 \@namedef{minted@opt@cmd:#1}{false}}%
425 }
minted@isinline In resolving value precedence when actually using values, we need a way to
determine whether we are in an inline context. This is accomplished via a boolean
that is set at the beginning of inline commands.
426 \newboolean{minted@isinline}
\minted@fvset We will need a way to actually use the lists of stored fancyvrb options later on.
427 \newcommand{\minted@fvset}{%
428 \expandafter\fvset\expandafter{\minted@optlistfv@g}%
429 \expandafter\let\expandafter\minted@tmp%
430 \csname minted@optlistfv@lang\minted@lang\endcsname
431 \expandafter\fvset\expandafter{\minted@tmp}%
432 \ifthenelse{\boolean{minted@isinline}}%
433 {\expandafter\fvset\expandafter{\minted@optlistfv@g@i}%
434 \expandafter\let\expandafter\minted@tmp%
435 \csname minted@optlistfv@lang\minted@lang @i\endcsname
436 \expandafter\fvset\expandafter{\minted@tmp}}%
437 {}%
438 \expandafter\fvset\expandafter{\minted@optlistfv@cmd}%
439 }
57
We need a way to define minted-specific options at multiple levels of hierarchy, as
well as a way to retrieve these options. As with previous types of options, values
are stored in macros of the form \minted@opt@hleveli:hkeyi, since they are not
meant to be accessed directly.
The order of precedence is cmd, lang@i, g@i, lang, g. A value specified at the
command or environment level should override other settings. In its absence, a
value specified for an inline command should override other settings, if we are
indeed in an inline context. Otherwise, language settings take precedence over
global settings.
Before actually creating the option-definition macro, we need a few helper macros.
58
so that it uses \PYG. Then \PYG is \let to \PYG<style> as appropriate. This
way, code need not be highlighted again when the style is changed. This has
the disadvantage that none of the \PYG<symbol> macros will be defined; rather,
only \PYG<style><symbol> macros will be defined. It would be possible to \let
\PYG<symbol> to \PYG<style><symbol>, but it is simpler to define a complete set
of symbol macros using the PYG prefix, so that all symbol macros will be defined
by default.6
Whenever \minted@checkstyle is invoked with a named style and style macros
need to be created, there is a check to see if the PYG prefix macros have been
created, and they are generated if they do not yet exist. This is important when
\MintedPygmentize is used to call a custom pygmentize; we want to wait as late
as possible to use pygmentize, so we dont want to generate the \PYG macros until
the last possible moment. When the \PYG macros are actually created, the single
quote macro is patched after loading.
It isnt necessary to set the initial style to default, because the current style is
always obtained via \minted@get@opt{style}{default}, so default is always
the fallback value and need not be set explicitly. \minted@checkstyle is used in
each command/environment, so that using pygmentize can be delayed as long as
possible.
453 \newcommand{\minted@checkstyle}[1]{%
454 \ifcsname minted@styleloaded@\ifstrempty{#1}{default-pyg-prefix}{#1}\endcsname\else
455 \ifstrempty{#1}{}{\ifcsname PYG\endcsname\else\minted@checkstyle{}\fi}%
456 \expandafter\gdef%
457 \csname minted@styleloaded@\ifstrempty{#1}{default-pyg-prefix}{#1}\endcsname{}%
458 \ifthenelse{\boolean{minted@cache}}%
459 {\IfFileExists
460 {\minted@outputdir\minted@cachedir/\ifstrempty{#1}{default-pyg-prefix}{#1}.pygstyle}%
461 {}%
462 {%
463 \ifthenelse{\boolean{minted@frozencache}}%
464 {\PackageError{minted}%
465 {Missing style definition for #1 with frozencache}%
466 {Missing style definition for #1 with frozencache}}%
467 {\ifwindows
468 \ShellEscape{%
469 \MintedPygmentize\space -S \ifstrempty{#1}{default}{#1} -f latex
470 -P commandprefix=PYG#1
471 > \minted@outputdir@windows\minted@cachedir@windows\@backslashchar%
472 \ifstrempty{#1}{default-pyg-prefix}{#1}.pygstyle}%
473 \else
474 \ShellEscape{%
6 It would be possible to hard-code the symbol macros in minted itself, but that would have
the disadvantage of tying minted more closely to a particular version of Pygments. Similarly,
\leting symbol macros assumes a complete, fixed list of symbol macros. The current approach is
harder to break than these alternatives; the worst-case scenario should be needing to purge the
cache, rather than dealing with an undefined macro.
59
475 \MintedPygmentize\space -S \ifstrempty{#1}{default}{#1} -f latex
476 -P commandprefix=PYG#1
477 > \minted@outputdir\minted@cachedir/%
478 \ifstrempty{#1}{default-pyg-prefix}{#1}.pygstyle}%
479 \fi}%
480 }%
481 \begingroup
482 \let\def\gdef
483 \catcode\string=12
484 \catcode\_=11
485 \catcode\-=11
486 \catcode\%=14
487 \endlinechar=-1\relax
488 \minted@input{%
489 \minted@outputdir\minted@cachedir/\ifstrempty{#1}{default-pyg-prefix}{#1}.pygstyle}%
490 \endgroup
491 \minted@addcachefile{\ifstrempty{#1}{default-pyg-prefix}{#1}.pygstyle}}%
492 {%
493 \ifwindows
494 \ShellEscape{%
495 \MintedPygmentize\space -S \ifstrempty{#1}{default}{#1} -f latex
496 -P commandprefix=PYG#1 > \minted@outputdir@windows\[email protected]}%
497 \else
498 \ShellEscape{%
499 \MintedPygmentize\space -S \ifstrempty{#1}{default}{#1} -f latex
500 -P commandprefix=PYG#1 > \minted@outputdir\[email protected]}%
501 \fi
502 \begingroup
503 \let\def\gdef
504 \catcode\string=12
505 \catcode\_=11
506 \catcode\-=11
507 \catcode\%=14
508 \endlinechar=-1\relax
509 \minted@input{\minted@outputdir\[email protected]}%
510 \endgroup}%
511 \ifstrempty{#1}{\minted@patch@PYGZsq}{}%
512 \fi
513 }
514 \ifthenelse{\boolean{minted@draft}}{\renewcommand{\minted@checkstyle}[1]{}}{}
\minted@patch@PYGZsq The single quote macro from Pygments 1.6+ needs to be patched if the upquote
package is in use. Patching is done when the default style is created. Patching is
only attempted if the macro exists, so that there is a graceful fallback in the event
of a custom Pygments stylesheet.
515 \newcommand{\minted@patch@PYGZsq}{%
516 \ifcsname PYGZsq\endcsname
517 \expandafter\ifdefstring\expandafter{\csname PYGZsq\endcsname}{\char\}%
60
518 {\minted@patch@PYGZsq@i}%
519 {}%
520 \fi
521 }
522 \begingroup
523 \catcode\=\active
524 \gdef\minted@patch@PYGZsq@i{\gdef\PYGZsq{}}
525 \endgroup
526 \ifthenelse{\boolean{minted@draft}}{}{\AtBeginDocument{\minted@patch@PYGZsq}}
\minted@get@opt We need a way to traverse the hierarchy of values for a given key and return the
current value that has precedence. In doing this, we need to specify a default value
to use if no value is found. When working with minted-specific values, there should
generally be a default value; in those cases, an empty default may be supplied. But
the macro should also work with Pygments settings, which are stored in macros of
the same form and will sometimes need to be accessed (for example, encoding).
In the Pygments case, there may very well be no default values on the LATEX side,
61
because we are falling back on Pygments own built-in defaults. There is no need
to duplicate those when very few Pygments values are ever needed; it is simpler to
specify the default fallback when accessing the macro value.
From a programming perspective, the default argument value needs to be manda-
tory, so that \minted@get@opt can be fully expandable. This significantly simplifies
accessing options.
545 \def\minted@get@opt#1#2{%
546 \ifcsname minted@opt@cmd:#1\endcsname
547 \csname minted@opt@cmd:#1\endcsname
548 \else
549 \ifminted@isinline
550 \ifcsname minted@opt@lang\minted@lang @i:#1\endcsname
551 \csname minted@opt@lang\minted@lang @i:#1\endcsname
552 \else
553 \ifcsname minted@opt@g@i:#1\endcsname
554 \csname minted@opt@g@i:#1\endcsname
555 \else
556 \ifcsname minted@opt@lang\minted@lang:#1\endcsname
557 \csname minted@opt@lang\minted@lang:#1\endcsname
558 \else
559 \ifcsname minted@opt@g:#1\endcsname
560 \csname minted@opt@g:#1\endcsname
561 \else
562 #2%
563 \fi
564 \fi
565 \fi
566 \fi
567 \else
568 \ifcsname minted@opt@lang\minted@lang:#1\endcsname
569 \csname minted@opt@lang\minted@lang:#1\endcsname
570 \else
571 \ifcsname minted@opt@g:#1\endcsname
572 \csname minted@opt@g:#1\endcsname
573 \else
574 #2%
575 \fi
576 \fi
577 \fi
578 \fi
579 }%
62
Lexers.
580 \minted@def@optcl{encoding}{-P encoding}{#1}
581 \minted@def@optcl{outencoding}{-P outencoding}{#1}
582 \minted@def@optcl@e{escapeinside}{-P "escapeinside}{#1"}
583 \minted@def@optcl@switch{stripnl}{-P stripnl}
584 \minted@def@optcl@switch{stripall}{-P stripall}
585 % Python console
586 \minted@def@optcl@switch{python3}{-P python3}
587 % PHP
588 \minted@def@optcl@switch{funcnamehighlighting}{-P funcnamehighlighting}
589 \minted@def@optcl@switch{startinline}{-P startinline}
Filters.
590 \ifthenelse{\boolean{minted@draft}}%
591 {\minted@def@optfv{gobble}}%
592 {\minted@def@optcl{gobble}{-F gobble:n}{#1}}
593 \minted@def@optcl{codetagify}{-F codetagify:codetags}{#1}
594 \minted@def@optcl{keywordcase}{-F keywordcase:case}{#1}
LATEX formatter.
595 \minted@def@optcl@switch{texcl}{-P texcomments}
596 \minted@def@optcl@switch{texcomments}{-P texcomments}
597 \minted@def@optcl@switch{mathescape}{-P mathescape}
598 \minted@def@optfv@switch{linenos}
599 \minted@def@opt{style}
600 \minted@def@optfv{frame}
601 \minted@def@optfv{framesep}
602 \minted@def@optfv{framerule}
603 \minted@def@optfv{rulecolor}
604 \minted@def@optfv{numbersep}
605 \minted@def@optfv{numbers}
606 \minted@def@optfv{firstnumber}
607 \minted@def@optfv{stepnumber}
608 \minted@def@optfv{firstline}
609 \minted@def@optfv{lastline}
610 \minted@def@optfv{baselinestretch}
611 \minted@def@optfv{xleftmargin}
612 \minted@def@optfv{xrightmargin}
613 \minted@def@optfv{fillcolor}
614 \minted@def@optfv{tabsize}
615 \minted@def@optfv{fontfamily}
616 \minted@def@optfv{fontsize}
617 \minted@def@optfv{fontshape}
618 \minted@def@optfv{fontseries}
619 \minted@def@optfv{formatcom}
63
620 \minted@def@optfv{label}
621 \minted@def@optfv{labelposition}
622 \minted@def@optfv{highlightlines}
623 \minted@def@optfv{highlightcolor}
624 \minted@def@optfv{space}
625 \minted@def@optfv{spacecolor}
626 \minted@def@optfv{tab}
627 \minted@def@optfv{tabcolor}
628 \minted@def@optfv{highlightcolor}
629 \minted@def@optfv@switch{beameroverlays}
630 \minted@def@optfv@switch{curlyquotes}
631 \minted@def@optfv@switch{numberfirstline}
632 \minted@def@optfv@switch{numberblanklines}
633 \minted@def@optfv@switch{stepnumberfromfirst}
634 \minted@def@optfv@switch{stepnumberoffsetvalues}
635 \minted@def@optfv@switch{showspaces}
636 \minted@def@optfv@switch{resetmargins}
637 \minted@def@optfv@switch{samepage}
638 \minted@def@optfv@switch{showtabs}
639 \minted@def@optfv@switch{obeytabs}
640 \minted@def@optfv@switch{breaklines}
641 \minted@def@optfv@switch{breakbytoken}
642 \minted@def@optfv@switch{breakbytokenanywhere}
643 \minted@def@optfv{breakindent}
644 \minted@def@optfv{breakindentnchars}
645 \minted@def@optfv@switch{breakautoindent}
646 \minted@def@optfv{breaksymbol}
647 \minted@def@optfv{breaksymbolsep}
648 \minted@def@optfv{breaksymbolsepnchars}
649 \minted@def@optfv{breaksymbolindent}
650 \minted@def@optfv{breaksymbolindentnchars}
651 \minted@def@optfv{breaksymbolleft}
652 \minted@def@optfv{breaksymbolsepleft}
653 \minted@def@optfv{breaksymbolsepleftnchars}
654 \minted@def@optfv{breaksymbolindentleft}
655 \minted@def@optfv{breaksymbolindentleftnchars}
656 \minted@def@optfv{breaksymbolright}
657 \minted@def@optfv{breaksymbolsepright}
658 \minted@def@optfv{breaksymbolseprightnchars}
659 \minted@def@optfv{breaksymbolindentright}
660 \minted@def@optfv{breaksymbolindentrightnchars}
661 \minted@def@optfv{breakbefore}
662 \minted@def@optfv{breakbeforesymbolpre}
663 \minted@def@optfv{breakbeforesymbolpost}
664 \minted@def@optfv@switch{breakbeforegroup}
665 \minted@def@optfv{breakafter}
666 \minted@def@optfv@switch{breakaftergroup}
667 \minted@def@optfv{breakaftersymbolpre}
668 \minted@def@optfv{breakaftersymbolpost}
669 \minted@def@optfv@switch{breakanywhere}
64
670 \minted@def@optfv{breakanywheresymbolpre}
671 \minted@def@optfv{breakanywheresymbolpost}
\minted@encoding When working with encoding, we will need access to the current encoding. That
may be done via \minted@get@opt, but it is more convenient to go ahead and
define a shortcut with an appropriate default
674 \newcommand{\minted@encoding}{\minted@get@opt{encoding}{UTF8}}
675 \newsavebox{\minted@bgbox}
Now we can define the environment that applies a background color. Prior to
minted 2.2, this involved a minipage. However, that approach was problematic
because it did not allow linebreaks, would be pushed into the margin by immediately
preceding text, and had very different whitespace separation from preceding and
following text compared to no background color. In version 2.2, this was replaced
with an approach based on framed. \FV@NumberSep is adjusted by \fboxsep to
ensure that line numbers remain in the same location in the margin regardless of
whether bgcolor is used.
676 \newenvironment{minted@colorbg}[1]{%
677 \setlength{\OuterFrameSep}{0pt}%
678 \colorlet{shadecolor}{#1}%
679 \let\minted@tmp\FV@NumberSep
680 \edef\FV@NumberSep{%
681 \the\numexpr\dimexpr\minted@tmp+\number\fboxsep\relax sp\relax}%
65
682 \medskip
683 \begin{snugshade*}}
684 {\end{snugshade*}%
685 \medskip\noindent}
\minted@code Create a file handle for saving code (and anything else that must be written to
temp files).
686 \newwrite\minted@code
minted@FancyVerbLineTemp At various points, we will need a temporary counter for storing and then restoring
the value of FancyVerbLine. When using the langlinenos option, we need to store
the current value of FancyVerbLine, then set FancyVerbLine to the current value
of a language-specific counter, and finally restore FancyVerbLine to its initial value
after the current chunk of code has been typeset. In patching VerbatimOut, we
need to prevent FancyVerbLine from being incremented during the write process.
691 \newcounter{minted@FancyVerbLineTemp}
66
707 \newcommand{\minted@FVE@VerbatimOut}{%
708 \immediate\closeout\FV@OutFile\endgroup\@esphack
709 \setcounter{FancyVerbLine}{\value{minted@FancyVerbLineTemp}}}%
minted@pygmentizecounter We need a counter to keep track of how many files have been pygmentized.
This is primarily used with finalizecache for naming cache files sequentially in
listing<number>.pygtex form.
713 \newcounter{minted@pygmentizecounter}
soon as the code is used multiple times with different options. While that may seem unlikely in
practice, it occurs in this documentation and may be expected to occur in other docs.
67
At the very beginning, a check is performed to make sure that style macros exist.
This must be done before the highlighted content is generated, so that temp file
names can be shared without accidental overwriting. Styles are generated here,
rather than when a style is set, so that creating the style macros is done as late as
possible in case a custom pygmentize is in use via \MintedPygmentize.
714 \newcommand{\minted@pygmentize}[2][\minted@outputdir\[email protected]]{%
715 \minted@checkstyle{\minted@get@opt{style}{default}}%
716 \stepcounter{minted@pygmentizecounter}%
717 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}%
718 {\def\minted@codefile{\minted@outputdir\[email protected]}}%
719 {\def\minted@codefile{#1}}%
720 \ifthenelse{\boolean{minted@isinline}}%
721 {\def\minted@optlistcl@inlines{%
722 \minted@optlistcl@g@i
723 \csname minted@optlistcl@lang\minted@lang @i\endcsname}}%
724 {\let\minted@optlistcl@inlines\@empty}%
725 \def\minted@cmd{%
726 \ifminted@kpsewhich
727 \ifwindows
728 \detokenize{for /f "usebackq tokens=*"}\space\@percentchar\detokenize{a in (kpsewhich}\
729 \fi
730 \fi
731 \MintedPygmentize\space -l #2
732 -f latex -P commandprefix=PYG -F tokenmerge
733 \minted@optlistcl@g \csname minted@optlistcl@lang\minted@lang\endcsname
734 \minted@optlistcl@inlines
735 \minted@optlistcl@cmd -o \minted@outputdir\minted@infile\space
736 \ifminted@kpsewhich
737 \ifwindows
738 \@percentchar\detokenize{a}%
739 \else
740 \detokenize{}kpsewhich \minted@codefile\space
741 \detokenize{||} \minted@codefile\detokenize{}%
742 \fi
743 \else
744 \minted@codefile
745 \fi}%
746 % For debugging, uncomment: %%%%
747 % \immediate\typeout{\minted@cmd}%
748 % %%%%
749 \ifthenelse{\boolean{minted@cache}}%
750 {%
751 \ifminted@frozencache
752 \else
753 \ifx\XeTeXinterchartoks\minted@undefined
754 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}%
755 {\edef\minted@hash{\pdf@filemdfivesum{#1}%
756 \pdf@mdfivesum{\minted@cmd autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbSt
68
757 {\edef\minted@hash{\pdf@filemdfivesum{#1}%
758 \pdf@mdfivesum{\minted@cmd}}}%
759 \else
760 \ifx\mdfivesum\minted@undefined
761 \immediate\openout\minted@code\[email protected]\relax
762 \immediate\write\minted@code{\minted@cmd}%
763 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}%
764 {\immediate\write\minted@code{autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVer
765 \immediate\closeout\minted@code
766 \edef\minted@argone@esc{#1}%
767 \StrSubstitute{\minted@argone@esc}{\@backslashchar}{\@backslashchar\@backslashchar}[
768 \StrSubstitute{\minted@argone@esc}{"}{\@backslashchar"}[\minted@argone@esc]%
769 \edef\minted@tmpfname@esc{\minted@outputdir\minted@jobname}%
770 \StrSubstitute{\minted@tmpfname@esc}{\@backslashchar}{\@backslashchar\@backslashchar
771 \StrSubstitute{\minted@tmpfname@esc}{"}{\@backslashchar"}[\minted@tmpfname@esc]%
772 %Cheating a little here by using ASCII codes to write { and }
773 %in the Python code
774 \def\minted@hashcmd{%
775 \detokenize{python -c "import hashlib; import os;
776 hasher = hashlib.sha1();
777 f = open(os.path.expanduser(os.path.expandvars(\"}\minted@[email protected]
778 hasher.update(f.read());
779 f.close();
780 f = open(os.path.expanduser(os.path.expandvars(\"}\minted@argone@esc\detokenize{
781 hasher.update(f.read());
782 f.close();
783 f = open(os.path.expanduser(os.path.expandvars(\"}\minted@[email protected]
784 macro = \"\\edef\\minted@hash\" + chr(123) + hasher.hexdigest() + chr(125) + \"\
785 f.write(\"\\makeatletter\" + macro + \"\\makeatother\\endinput\n\");
786 f.close();"}}%
787 \ShellEscape{\minted@hashcmd}%
788 \minted@input{\minted@outputdir\[email protected]}%
789 \else
790 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}%
791 {\edef\minted@hash{\mdfivesum file {#1}%
792 \mdfivesum{\minted@cmd autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbStar
793 {\edef\minted@hash{\mdfivesum file {#1}%
794 \mdfivesum{\minted@cmd}}}%
795 \fi
796 \fi
797 \edef\minted@infile{\minted@cachedir/\[email protected]}%
798 \IfFileExists{\minted@infile}{}{%
799 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}{%
800 \minted@autogobble{#1}}{}%
801 \ShellEscape{\minted@cmd}}%
802 \fi
803 \ifthenelse{\boolean{minted@finalizecache}}%
804 {%
805 \edef\minted@cachefilename{listing\arabic{minted@pygmentizecounter}.pygtex}%
806 \edef\minted@actualinfile{\minted@cachedir/\minted@cachefilename}%
69
807 \ifwindows
808 \StrSubstitute{\minted@infile}{/}{\@backslashchar}[\minted@infile@windows]
809 \StrSubstitute{\minted@actualinfile}{/}{\@backslashchar}[\minted@actualinfile@window
810 \ShellEscape{move /y \minted@outputdir\minted@infile@windows\space\minted@outputdir\
811 \else
812 \ShellEscape{mv -f \minted@outputdir\minted@infile\space\minted@outputdir\minted@act
813 \fi
814 \let\minted@infile\minted@actualinfile
815 \expandafter\minted@addcachefile\expandafter{\minted@cachefilename}%
816 }%
817 {\ifthenelse{\boolean{minted@frozencache}}%
818 {%
819 \edef\minted@cachefilename{listing\arabic{minted@pygmentizecounter}.pygtex}%
820 \edef\minted@infile{\minted@cachedir/\minted@cachefilename}%
821 \expandafter\minted@addcachefile\expandafter{\minted@cachefilename}}%
822 {\expandafter\minted@addcachefile\expandafter{\[email protected]}}%
823 }%
824 \minted@inputpyg}%
825 {%
826 \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}{%
827 \minted@autogobble{#1}}{}%
828 \ShellEscape{\minted@cmd}%
829 \minted@inputpyg}%
830 }
70
854 \detokenize{f = open(fname, \"r\", encoding=\"}\minted@encoding\detokenize{\") if os.path.is
855 t = f.readlines() if f is not None else None;
856 t_opt = t if t is not None else [];
857 f.close() if f is not None else None;
858 tmpfname = os.path.expanduser(os.path.expandvars(\"}\minted@[email protected]\detokenize{\"))
859 f = open(tmpfname, \"w\", encoding=\"}\minted@encoding\detokenize{\") if t is not None else
860 fvstartnum = }\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbStartNum\fi\detokenize{;
861 fvstopnum = }\ifx\FancyVerbStopNum\z@ 0\else\FancyVerbStopNum\fi\detokenize{;
862 s = fvstartnum-1 if fvstartnum != 0 else 0;
863 e = fvstopnum if fvstopnum != 0 else len(t_opt);
864 [f.write(textwrap.dedent(\"\".join(x))) for x in (t_opt[0:s], t_opt[s:e], t_opt[e:]) if x an
865 f.close() if t is not None else os.remove(tmpfname);"}%
866 \ifminted@kpsewhich
867 \ifwindows
868 \space\@percentchar\detokenize{a}%
869 \else
870 \space\detokenize{}kpsewhich #1\space\detokenize{||} #1\detokenize{}%
871 \fi
872 \fi
873 }%
874 \ShellEscape{\minted@autogobblecmd}%
875 }
\minted@inputpyg For increased clarity, the actual \input process is separated out into its own macro.
At the last possible moment, \PYG is \let to \PYGhstylei and redefined to used
appropriate line breaking via \VerbatimPygments from fvextra.
The bgcolor option needs to be dealt with in different ways depending on whether
we are using \mintinline. It is simplest to apply this option here, so that the
macro redefinitions may be local and thus do not need to be manually reset later.
876 \newcommand{\minted@inputpyg}{%
877 \expandafter\let\expandafter\minted@PYGstyle%
878 \csname PYG\minted@get@opt{style}{default}\endcsname
879 \VerbatimPygments{\PYG}{\minted@PYGstyle}%
880 \ifthenelse{\boolean{minted@isinline}}%
881 {\ifthenelse{\equal{\minted@get@opt{breaklines}{false}}{true}}%
882 {\let\FV@BeginVBox\relax
883 \let\FV@EndVBox\relax
884 \def\FV@BProcessLine##1{\FancyVerbFormatLine{##1}}%
885 \minted@inputpyg@inline}%
886 {\minted@inputpyg@inline}}%
887 {\minted@inputpyg@block}%
888 }
889 \def\minted@inputpyg@inline{%
890 \ifthenelse{\equal{\minted@get@opt{bgcolor}{}}{}}%
891 {\minted@input{\minted@outputdir\minted@infile}}%
892 {\colorbox{\minted@get@opt{bgcolor}{}}{%
893 \minted@input{\minted@outputdir\minted@infile}}}%
71
894 }
895 \def\minted@inputpyg@block{%
896 \ifthenelse{\equal{\minted@get@opt{bgcolor}{}}{}}%
897 {\minted@input{\minted@outputdir\minted@infile}}%
898 {\begin{minted@colorbg}{\minted@get@opt{bgcolor}{}}%
899 \minted@input{\minted@outputdir\minted@infile}%
900 \end{minted@colorbg}}}
\minted@langlinenoson
901 \newcommand{\minted@langlinenoson}{%
902 \ifcsname c@minted@lang\minted@lang\endcsname\else
903 \newcounter{minted@lang\minted@lang}%
904 \fi
905 \setcounter{minted@FancyVerbLineTemp}{\value{FancyVerbLine}}%
906 \setcounter{FancyVerbLine}{\value{minted@lang\minted@lang}}%
907 }
\minted@langlinenosoff
908 \newcommand{\minted@langlinenosoff}{%
909 \setcounter{minted@lang\minted@lang}{\value{FancyVerbLine}}%
910 \setcounter{FancyVerbLine}{\value{minted@FancyVerbLineTemp}}%
911 }
\setmintedinline Set global or language-level options, but only for inline (\mintinline) content.
These settings will override the corresponding \setminted settings.
72
921 \newcommand{\setmintedinline}[2][]{%
922 \ifthenelse{\equal{#1}{}}%
923 {\setkeys{minted@opt@g@i}{#2}}%
924 {\minted@configlang{#1}%
925 \setkeys{minted@opt@lang@i}{#2}}}
Now that the settings macros exist, we go ahead and create any needed defaults.
PHP should use startinline for \mintinline. Visible tabs should have a specified
color so that they dont change colors when used to indent multiline strings or
comments.
926 \setmintedinline[php]{startinline=true}
927 \setminted{tabcolor=black}
\usemintedstyle Set style. This is a holdover from version 1, since \setminted can now accomplish
this, and a hierarchy of style settings are now possible.
928 \newcommand{\usemintedstyle}[2][]{\setminted[#1]{style=#2}}
\minted@defwhitespace@retok The \mint and \mintinline commands need to be able to retokenize the code they
collect, particularly in draft mode. Retokenizeation involves expansion combined
with \scantokens, with active space and tab characters. The active characters
need to expand to the appropriate fancyvrb macros, but the macros themselves
should not be expanded. We need a macro that will accomplish the appropriate
definitions.
929 \begingroup
930 \catcode\ =\active
931 \catcode\^^I=\active
932 \gdef\minted@defwhitespace@retok{\def {\noexpand\FV@Space}\def^^I{\noexpand\FV@Tab}}%
933 \endgroup
\minted@writecmdcode The \mintinline and \mint commands will need to write the code they capture
to a temporary file for highlighting. It will be convenient to be able to accomplish
this via a simple macro, since that makes it simpler to deal with any expansion of
what is to be written. This isnt needed for the minted environment, because the
(patched) VerbatimOut is used.
934 \newcommand{\minted@writecmdcode}[1]{%
935 \immediate\openout\minted@code\[email protected]\relax
936 \immediate\write\minted@code{\detokenize{#1}}%
937 \immediate\closeout\minted@code}
\mintinline Define an inline command. This requires some catcode acrobatics. The typical
verbatim methods are not used. Rather, a different approach is taken that is
generally more robust when used within other commands (for example, when used
in footnotes).
73
Pygments saves code wrapped in a Verbatim environment. Getting the inline com-
mand to work correctly require redefining Verbatim to be BVerbatim temporarily.
This approach would break if BVerbatim were ever redefined elsewhere.
Everything needs to be within a \begingroup...\endgroup to prevent settings
from escaping.
In the case of draft mode, the code is captured and retokenized. Then the internals
of fancyvrb are used to emulate SaveVerbatim, so that \BUseVerbatim may be
employed.
The FancyVerbLine counter is altered somehow within \minted@pygmentize, so
we protect against this.
938 \newrobustcmd{\mintinline}[2][]{%
939 \begingroup
940 \setboolean{minted@isinline}{true}%
941 \minted@configlang{#2}%
942 \setkeys{minted@opt@cmd}{#1}%
943 \minted@fvset
944 \begingroup
945 \let\do\@makeother\dospecials
946 \catcode\{=1
947 \catcode\}=2
948 \catcode\^^I=\active
949 \@ifnextchar\bgroup
950 {\minted@inline@iii}%
951 {\catcode\{=12\catcode\}=12
952 \minted@inline@i}}
953 \def\minted@inline@i#1{%
954 \endgroup
955 \def\minted@inline@ii##1#1{%
956 \minted@inline@iii{##1}}%
957 \begingroup
958 \let\do\@makeother\dospecials
959 \catcode\^^I=\active
960 \minted@inline@ii}
961 \ifthenelse{\boolean{minted@draft}}%
962 {\newcommand{\minted@inline@iii}[1]{%
963 \endgroup
964 \begingroup
965 \minted@defwhitespace@retok
966 \everyeof{\noexpand}%
967 \endlinechar-1\relax
968 \let\do\@makeother\dospecials
969 \catcode\ =\active
970 \catcode\^^I=\active
971 \xdef\minted@tmp{\scantokens{#1}}%
972 \endgroup
973 \let\FV@Line\minted@tmp
74
974 \def\FV@SV@minted@tmp{%
975 \FV@Gobble
976 \expandafter\FV@ProcessLine\expandafter{\FV@Line}}%
977 \ifthenelse{\equal{\minted@get@opt{breaklines}{false}}{true}}%
978 {\let\FV@BeginVBox\relax
979 \let\FV@EndVBox\relax
980 \def\FV@BProcessLine##1{\FancyVerbFormatLine{##1}}%
981 \BUseVerbatim{minted@tmp}}%
982 {\BUseVerbatim{minted@tmp}}%
983 \endgroup}}%
984 {\newcommand{\minted@inline@iii}[1]{%
985 \endgroup
986 \minted@writecmdcode{#1}%
987 \RecustomVerbatimEnvironment{Verbatim}{BVerbatim}{}%
988 \setcounter{minted@FancyVerbLineTemp}{\value{FancyVerbLine}}%
989 \minted@pygmentize{\minted@lang}%
990 \setcounter{FancyVerbLine}{\value{minted@FancyVerbLineTemp}}%
991 \endgroup}}
75
1016 \endgroup
1017 \begingroup
1018 \minted@defwhitespace@retok
1019 \everyeof{\noexpand}%
1020 \endlinechar-1\relax
1021 \let\do\@makeother\dospecials
1022 \catcode\ =\active
1023 \catcode\^^I=\active
1024 \xdef\minted@tmp{\scantokens{#1}}%
1025 \endgroup
1026 \let\FV@Line\minted@tmp
1027 \def\FV@SV@minted@tmp{%
1028 \FV@CodeLineNo=1\FV@StepLineNo
1029 \FV@Gobble
1030 \expandafter\FV@ProcessLine\expandafter{\FV@Line}}%
1031 \minted@langlinenoson
1032 \UseVerbatim{minted@tmp}%
1033 \minted@langlinenosoff
1034 \endgroup}}%
1035 {\newcommand{\mint@iii}[1]{%
1036 \endgroup
1037 \minted@writecmdcode{#1}%
1038 \minted@langlinenoson
1039 \minted@pygmentize{\minted@lang}%
1040 \minted@langlinenosoff
1041 \endgroup}}
76
1063 \minted@langlinenosoff}}
1079 \newcommand{\newminted}[3][]{
First, we look whether a custom environment name was given as the first optional
argument. If thats not the case, construct it from the language name (append
code).
1080 \ifthenelse{\equal{#1}{}}
1081 {\def\minted@envname{#2code}}
1082 {\def\minted@envname{#1}}
Now, we define two environments. The first takes no further arguments. The
second, starred version, takes an extra argument that specifies option overrides.
1083 \newenvironment{\minted@envname}
1084 {\VerbatimEnvironment
1085 \begin{minted}[#3]{#2}}
1086 {\end{minted}}
1087 \newenvironment{\minted@envname *}[1]
1088 {\VerbatimEnvironment\begin{minted}[#3,##1]{#2}}
1089 {\end{minted}}}
77
\newmint Define a new language-specific alias for the \mint short form.
1090 \newcommand{\newmint}[3][]{
Same as with \newminted, look whether an explicit name is provided. If not, take
the language name as command name.
1091 \ifthenelse{\equal{#1}{}}
1092 {\def\minted@shortname{#2}}
1093 {\def\minted@shortname{#1}}
1094 \expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
1095 \mint[#3,##1]{#2}##2}}
Here, the default macro name (if none is provided) appends file to the language
name.
1097 \ifthenelse{\equal{#1}{}}
1098 {\def\minted@shortname{#2file}}
1099 {\def\minted@shortname{#1}}
1100 \expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
1101 \inputminted[#3,##1]{#2}{##2}}}
78
8.9 Float support
listing Define a new floating environment to use for floated listings. This is defined
conditionally based on the newfloat package option.
1115 \ifthenelse{\boolean{minted@newfloat}}%
1116 {\@ifundefined{minted@float@within}%
1117 {\DeclareFloatingEnvironment[fileext=lol,placement=tbp]{listing}}%
1118 {\def\minted@tmp#1{%
1119 \DeclareFloatingEnvironment[fileext=lol,placement=tbp, within=#1]{listing}}%
1120 \expandafter\minted@tmp\expandafter{\minted@float@within}}}%
1121 {\@ifundefined{minted@float@within}%
1122 {\newfloat{listing}{tbp}{lol}}%
1123 {\newfloat{listing}{tbp}{lol}[\minted@float@within]}}
The following macros only apply when listing is created with the float package.
When listing is created with newfloat, its properties should be modified using
newfloats \SetupFloatingEnvironment.
1124 \ifminted@newfloat\else
\listingcaption The name that is displayed before each individual listings caption and its number.
The macro \listingscaption can be redefined by the user.
1125 \newcommand{\listingscaption}{Listing}
1126 \floatname{listing}{\listingscaption}
\listoflistings Used to produce a list of listings (like \listoffigures etc.). This may well clash
with other packages (for example, listings) but we choose to ignore this since these
two packages shouldnt be used together in the first place.
1128 \providecommand{\listoflistings}{\listof{listing}{\listoflistingscaption}}
Again, the preceding macros only apply when float is used to create listings, so we
need to end the conditional.
1129 \fi
79
8.10 Epilogue
Check whether LaTeX was invoked with -shell-escape option, set the default
style, and make sure pygmentize exists. Checking for pygmentize must wait until
the end of the preamble, in case it is specified via \MintedPygmentize (which
would typically be after the package is loaded).
1130 \AtEndOfPackage{%
1131 \ifthenelse{\boolean{minted@draft}}%
1132 {}%
1133 {%
1134 \ifthenelse{\boolean{minted@frozencache}}{}{%
1135 \ifnum\pdf@shellescape=1\relax\else
1136 \PackageError{minted}%
1137 {You must invoke LaTeX with the
1138 -shell-escape flag}%
1139 {Pass the -shell-escape flag to LaTeX. Refer to the minted.sty
1140 documentation for more information.}%
1141 \fi}%
1142 }%
1143 }
1144 \AtEndPreamble{%
1145 \ifthenelse{\boolean{minted@draft}}%
1146 {}%
1147 {%
1148 \ifthenelse{\boolean{minted@frozencache}}{}{%
1149 \TestAppExists{\MintedPygmentize}%
1150 \ifAppExists\else
1151 \PackageError{minted}%
1152 {You must have pygmentize installed
1153 to use this package}%
1154 {Refer to the installation instructions in the minted
1155 documentation for more information.}%
1156 \fi}%
1157 }%
1158 }
Clean up temp files. What actually needs to be done depends on caching and
engine.
1159 \AfterEndDocument{%
1160 \ifthenelse{\boolean{minted@draft}}%
1161 {}%
1162 {\ifthenelse{\boolean{minted@frozencache}}%
1163 {}
1164 {\ifx\XeTeXinterchartoks\minted@undefined
80
1165 \else
1166 \DeleteFile[\minted@outputdir]{\[email protected]}%
1167 \DeleteFile[\minted@outputdir]{\[email protected]}%
1168 \fi
1169 \DeleteFile[\minted@outputdir]{\[email protected]}%
1170 \DeleteFile[\minted@outputdir]{\[email protected]}%
1171 }%
1172 }%
1173 }
1 \NeedsTeXFormat{LaTeX2e}
2 %%%% Begin minted1 modification
3 %%\ProvidesPackage{minted}[2011/09/17 v1.7 Yet another Pygments shim for LaTeX]
4 \ProvidesPackage{minted1}[2015/01/31 v1.0 minted 1.7 compatibility package]
5 %%%% End minted1 modification
6 \RequirePackage{keyval}
7 \RequirePackage{fancyvrb}
8 \RequirePackage{xcolor}
9 \RequirePackage{float}
10 \RequirePackage{ifthen}
8 The approach used for doing this is described at http://tex.stackexchange.com/a/39418/
10742.
81
11 %%%% Begin minted1 modification
12 \newboolean{mintedone@mintedloaded}
13 \@ifpackageloaded{minted}%
14 {\setboolean{mintedone@mintedloaded}{true}%
15 \PackageError{minted1}{The package "minted1" may not be loaded after
16 ^^J"minted" has already been loaded--load "minted1" only for "minted"
17 ^^Jversion 1.7 compatibility}%
18 {Load "minted1" only when "minted" version 1.7 compatibility is required}}%
19 {}
20 \ifmintedone@mintedloaded\else
21 \@namedef{[email protected]}{2011/09/17 v1.7 Yet another Pygments shim for LaTeX}
22 \expandafter\let\expandafter\minted@tmp\csname [email protected]\endcsname
23 \expandafter\let\csname [email protected]\endcsname\minted@tmp
24 \let\minted@tmp\relax
25 %%%% End minted1 modification
26 \RequirePackage{calc}
27 \RequirePackage{ifplatform}
28 \DeclareOption{chapter}{\def\minted@float@within{chapter}}
29 \DeclareOption{section}{\def\minted@float@within{section}}
30 \ProcessOptions\relax
31 \ifwindows
32 \providecommand\DeleteFile[1]{\immediate\write18{del #1}}
33 \else
34 \providecommand\DeleteFile[1]{\immediate\write18{rm #1}}
35 \fi
36 \newboolean{AppExists}
37 \newcommand\TestAppExists[1]{
38 \ifwindows
39 \DeleteFile{\jobname.aex}
40 \immediate\write18{for \string^\@percentchar i in (#1.exe #1.bat #1.cmd)
41 do set >\jobname.aex <nul: /p x=\string^\@percentchar \string~$PATH:i>>\jobname.aex} %$
42 \newread\@appexistsfile
43 \immediate\openin\@appexistsfile\jobname.aex
44 \expandafter\def\expandafter\@tmp@cr\expandafter{\the\endlinechar}
45 \endlinechar=-1\relax
46 \readline\@appexistsfile to \@apppathifexists
47 \endlinechar=\@tmp@cr
48 \ifthenelse{\equal{\@apppathifexists}{}}
49 {\AppExistsfalse}
50 {\AppExiststrue}
51 \immediate\closein\@appexistsfile
52 \DeleteFile{\jobname.aex}
53 \immediate\typeout{file deleted}
54 \else
55 \immediate\write18{which #1 && touch \jobname.aex}
56 \IfFileExists{\jobname.aex}
57 {\AppExiststrue
58 \DeleteFile{\jobname.aex}}
59 {\AppExistsfalse}
60 \fi}
82
61 \newcommand\minted@resetoptions{}
62 \newcommand\minted@defopt[1]{
63 \expandafter\def\expandafter\minted@resetoptions\expandafter{%
64 \minted@resetoptions
65 \@namedef{minted@opt@#1}{}}}
66 \newcommand\minted@opt[1]{
67 \expandafter\detokenize%
68 \expandafter\expandafter\expandafter{\csname minted@opt@#1\endcsname}}
69 \newcommand\minted@define@opt[3][]{
70 \minted@defopt{#2}
71 \ifthenelse{\equal{#1}{}}{
72 \define@key{minted@opt}{#2}{\@namedef{minted@opt@#2}{#3}}}
73 {\define@key{minted@opt}{#2}[#1]{\@namedef{minted@opt@#2}{#3}}}}
74 \newcommand\minted@define@switch[3][]{
75 \minted@defopt{#2}
76 \define@booleankey{minted@opt}{#2}
77 {\@namedef{minted@opt@#2}{#3}}
78 {\@namedef{minted@opt@#2}{#1}}}
79 \minted@defopt{extra}
80 \newcommand\minted@define@extra[1]{
81 \define@key{minted@opt}{#1}{
82 \expandafter\def\expandafter\minted@opt@extra\expandafter{%
83 \minted@opt@extra,#1=##1}}}
84 \newcommand\minted@define@extra@switch[1]{
85 \define@booleankey{minted@opt}{#1}
86 {\expandafter\def\expandafter\minted@opt@extra\expandafter{%
87 \minted@opt@extra,#1}}
88 {\expandafter\def\expandafter\minted@opt@extra\expandafter{%
89 \minted@opt@extra,#1=false}}}
90 \minted@define@switch{texcl}{-P texcomments}
91 \minted@define@switch{mathescape}{-P mathescape}
92 \minted@define@switch{linenos}{-P linenos}
93 \minted@define@switch{startinline}{-P startinline}
94 \minted@define@switch[-P funcnamehighlighting=False]%
95 {funcnamehighlighting}{-P funcnamehighlighting}
96 \minted@define@opt{gobble}{-F gobble:n=#1}
97 \minted@define@opt{bgcolor}{#1}
98 \minted@define@extra{frame}
99 \minted@define@extra{framesep}
100 \minted@define@extra{framerule}
101 \minted@define@extra{rulecolor}
102 \minted@define@extra{numbersep}
103 \minted@define@extra{firstnumber}
104 \minted@define@extra{stepnumber}
105 \minted@define@extra{firstline}
106 \minted@define@extra{lastline}
107 \minted@define@extra{baselinestretch}
108 \minted@define@extra{xleftmargin}
109 \minted@define@extra{xrightmargin}
110 \minted@define@extra{fillcolor}
83
111 \minted@define@extra{tabsize}
112 \minted@define@extra{fontfamily}
113 \minted@define@extra{fontsize}
114 \minted@define@extra{fontshape}
115 \minted@define@extra{fontseries}
116 \minted@define@extra{formatcom}
117 \minted@define@extra{label}
118 \minted@define@extra@switch{numberblanklines}
119 \minted@define@extra@switch{showspaces}
120 \minted@define@extra@switch{resetmargins}
121 \minted@define@extra@switch{samepage}
122 \minted@define@extra@switch{showtabs}
123 \minted@define@extra@switch{obeytabs}
124 \newsavebox{\minted@bgbox}
125 \newenvironment{minted@colorbg}[1]{
126 \def\minted@bgcol{#1}
127 \noindent
128 \begin{lrbox}{\minted@bgbox}
129 \begin{minipage}{\linewidth-2\fboxsep}}
130 {\end{minipage}
131 \end{lrbox}%
132 \colorbox{\minted@bgcol}{\usebox{\minted@bgbox}}}
133 \newwrite\minted@code
134 \newcommand\minted@savecode[1]{
135 \immediate\openout\minted@code\jobname.pyg
136 \immediate\write\minted@code{#1}
137 \immediate\closeout\minted@code}
138 \newcommand\minted@pygmentize[2][\jobname.pyg]{
139 \def\minted@cmd{pygmentize -l #2 -f latex -F tokenmerge
140 \minted@opt{gobble} \minted@opt{texcl} \minted@opt{mathescape}
141 \minted@opt{startinline} \minted@opt{funcnamehighlighting}
142 \minted@opt{linenos} -P "verboptions=\minted@opt{extra}"
143 -o \jobname.out.pyg #1}
144 \immediate\write18{\minted@cmd}
145 % For debugging, uncomment:
146 %\immediate\typeout{\minted@cmd}
147 \ifthenelse{\equal{\minted@opt@bgcolor}{}}
148 {}
149 {\begin{minted@colorbg}{\minted@opt@bgcolor}}
150 \input{\jobname.out.pyg}
151 \ifthenelse{\equal{\minted@opt@bgcolor}{}}
152 {}
153 {\end{minted@colorbg}}
154 \DeleteFile{\jobname.out.pyg}}
155 \newcommand\minted@usedefaultstyle{\usemintedstyle{default}}
156 \newcommand\usemintedstyle[1]{
157 \renewcommand\minted@usedefaultstyle{}
158 \immediate\write18{pygmentize -S #1 -f latex > \jobname.pyg}
159 \input{\jobname.pyg}}
160 \newcommand\mint[3][]{
84
161 \DefineShortVerb{#3}
162 \minted@resetoptions
163 \setkeys{minted@opt}{#1}
164 \SaveVerb[aftersave={
165 \UndefineShortVerb{#3}
166 \minted@savecode{\FV@SV@minted@verb}
167 \minted@pygmentize{#2}
168 \DeleteFile{\jobname.pyg}}]{minted@verb}#3}
169 \newcommand\minted@proglang[1]{}
170 \newenvironment{minted}[2][]
171 {\VerbatimEnvironment
172 \renewcommand{\minted@proglang}[1]{#2}
173 \minted@resetoptions
174 \setkeys{minted@opt}{#1}
175 \begin{VerbatimOut}[codes={\catcode\^^I=12}]{\jobname.pyg}}%
176 {\end{VerbatimOut}
177 \minted@pygmentize{\minted@proglang{}}
178 \DeleteFile{\jobname.pyg}}
179 \newcommand\inputminted[3][]{
180 \minted@resetoptions
181 \setkeys{minted@opt}{#1}
182 \minted@pygmentize[#3]{#2}}
183 \newcommand\newminted[3][]{
184 \ifthenelse{\equal{#1}{}}
185 {\def\minted@envname{#2code}}
186 {\def\minted@envname{#1}}
187 \newenvironment{\minted@envname}
188 {\VerbatimEnvironment\begin{minted}[#3]{#2}}
189 {\end{minted}}
190 \newenvironment{\minted@envname *}[1]
191 {\VerbatimEnvironment\begin{minted}[#3,##1]{#2}}
192 {\end{minted}}}
193 \newcommand\newmint[3][]{
194 \ifthenelse{\equal{#1}{}}
195 {\def\minted@shortname{#2}}
196 {\def\minted@shortname{#1}}
197 \expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
198 \mint[#3,##1]{#2}##2}}
199 \newcommand\newmintedfile[3][]{
200 \ifthenelse{\equal{#1}{}}
201 {\def\minted@shortname{#2file}}
202 {\def\minted@shortname{#1}}
203 \expandafter\newcommand\csname\minted@shortname\endcsname[2][]{
204 \inputminted[#3,##1]{#2}{##2}}}
205 \@ifundefined{minted@float@within}
206 {\newfloat{listing}{h}{lol}}
207 {\newfloat{listing}{h}{lol}[\minted@float@within]}
208 \newcommand\listingscaption{Listing}
209 \floatname{listing}{\listingscaption}
210 \newcommand\listoflistingscaption{List of listings}
85
211 \providecommand\listoflistings{\listof{listing}{\listoflistingscaption}}
212 \AtBeginDocument{
213 \minted@usedefaultstyle}
214 \AtEndOfPackage{
215 \ifnum\pdf@shellescape=1\relax\else
216 \PackageError{minted}
217 {You must invoke LaTeX with the
218 -shell-escape flag}
219 {Pass the -shell-escape flag to LaTeX. Refer to the minted.sty
220 documentation for more information.}\fi
221 \TestAppExists{pygmentize}
222 \ifAppExists\else
223 \PackageError{minted}
224 {You must have pygmentize installed
225 to use this package}
226 {Refer to the installation instructions in the minted
227 documentation for more information.}
228 \fi}
229 %%%% Begin minted1 modification
230 \fi
231 %%%% End minted1 modification
86