44
$\begingroup$

I was thinking about the best way to include Mathematica code in a $\LaTeX$ document with a nice syntax highlighting.

I have tried the packages listings and minted (with pygments), which both claim to include Mathematica syntax highlighting. There is also a separate Mathematica lexer for pygments on github.

Having looked at the output from these packages, I'm not entirely happy.

I was hoping to obtain a result resembling as closely as possible Mathematica's native syntax highlighting or the highlighting used here on mma.SE (is that halirutan's prettify extension?)

My question is: What are users' preferred ways to include Mathematica code in $\LaTeX$ files that preserve syntax highlighting?

$\endgroup$
10
  • 1
    $\begingroup$ possible duplicate of Saving a notebook as a $\LaTeX$ file, with syntax highlighting preserved $\endgroup$ Feb 23, 2014 at 21:27
  • 1
    $\begingroup$ Thanks for the link @belisarius: The answer in that thread concludes with "This code reduces your problem to implementing the syntax highlighter in Mathematica, or finding a LATEX package to do it for you" which is precisely what I'm asking for. I'm happy to manually copy and pasty Mathematica expressions into a LaTeX file, a process that the linked thread seems to automate. $\endgroup$
    – Eckhard
    Feb 23, 2014 at 21:34
  • 2
    $\begingroup$ @Eckhard The short answer is: there is no such thing, because the highlighting as done by Mathematica requires a lot of work which is not done by any of the listing, minted, etc packages. Even the highlighter on SE that I wrote is only faking, especially the highlighting for pattern variables will not work reliably. The best way I see is to use my IDEA plugin and write an action to export highlighted and indented code. In IDEA, I have everything at hand and the complex highlighting is real. $\endgroup$
    – halirutan
    Feb 24, 2014 at 4:35
  • 3
    $\begingroup$ @Eckhard This is because the IDEA plugin understand Mathematica syntax and semantic and can highlight and annotate very complex code constructs correctly. The hard part is: Even if I have all characters, their coloring and spaces, then this needs to be converted to colored LaTeX text where every character appears exactly as I want. I had already a look into the listing package and creating such output in TeX goes really beyond my user knowledge of TeX. $\endgroup$
    – halirutan
    Feb 24, 2014 at 4:39
  • 2
    $\begingroup$ If I had the knowledge how to convert annotated code text into TeX commands so that the output is correct, one could use IDEA to copy Mathematica code there, autoamtically indent it correctly and then with one key-press you would have the LaTeX code in your clipboard ready to paste it into your document. $\endgroup$
    – halirutan
    Feb 24, 2014 at 4:42

3 Answers 3

27
$\begingroup$

I too had a need for a better syntax highlighting engine for Mathematica that can be used in different formats (so the javascript plugin is ruled out), so I wrote a better lexer and highlighter for Pygments than the one that ships with pygments. From the README:

It can currently lex and highlight:

  • All builtin functions in the System` context including unicode symbols like π except those that use characters from the private unicode space (e.g. \[FormalA])
  • User defined symbols, including those in a context.
  • Comments, including multi line and nested.
  • Strings, including multi line and escaped quotes.
  • Patterns, slots (including named slots #name introduced in version 10) and slot sequences.
  • Message names (e.g. the ivar in General::ivar)
  • Numbers including base notation (e.g. 8 ^^ 23 == 19) and scientific notation (e.g. 1 *^ 3 == 1000).
  • Local variables in Block, With and Module.

Installing it is as simple as executing pip install pygments-mathematica.

Here's an example of using it in a $\LaTeX$ document:

\documentclass{article}
\usepackage[english]{babel}
\usepackage{fontspec}
\setmonofont{Menlo}

\usepackage{minted}
\usemintedstyle{mathematica}

\begin{document}
\begin{minted}[linenos=true]{wolfram}
(* An example highlighting the features of
   this Pygments plugin for Mathematica *)
lissajous::usage = "An example Lissajous curve.\n" <>
                   "Definition: f(t) = (sin(3t + Pi/2), sin(t))"
lissajous = {Sin[2^^11 # + 0.005`10 * 1*^2 * Pi], Sin[#]} &;

ParametricPlot[lissajous[t], {t, 0, 2 Pi}] /. x_Line :> {Dashed, x}
\end{minted}
\end{document}

Assuming the file is called mma.tex, run xelatex --shell-escape mma.tex to generate a pdf that looks like this:

mma latex screenshot

The style mathematica is shipped with this plugin and if you'd like to change the colors, you can just update them in mathematica/style.py and then (re)install the plugin.

If you like the default notebook colors, you can use the style mathematicanotebook.

$\endgroup$
18
  • $\begingroup$ Note that the displayed colors are not the default ones used in Mathematica. E.g., by default the entire definition of the usage message, except for the beginning lissajous::, is colored a gray shade; the numbers on the right-hand side of the definition of lissajous are by default black. Do you have a set of color definitions consistent with what Mathematica actually uses by default? $\endgroup$
    – murray
    Feb 15, 2016 at 15:36
  • $\begingroup$ @murray I'm aware and it was a conscious decision to not stick to the default Mathematica style too closely. I don't think primary colors do well in latex documents/HTML where you don't have the luxury of pressing F1 or Ctrl-W as in the notebook. Besides, using gray for ::bar, (* comment *) and "a string" is confusing as well. It is easy to change the colors though. If there is sufficient interest for it, I can even provide a theme mathematica-default that uses the exact default palette from the notebook. $\endgroup$
    – rm -rf
    Feb 15, 2016 at 15:46
  • 1
    $\begingroup$ You mention \[FormalA], and without having tried it, I think this will also mean \[Element] doesn't get displayed correctly, doesn't it? I had the same issue in the listings package but figured out how to fix it there (by escaping to $\LaTeX$). I wonder if one can fix this in your approach to get nicer display of such glyphs... it does improve readability a lot. (already upvoted without trying - I definitely will give it a shot soon). $\endgroup$
    – Jens
    Feb 15, 2016 at 17:58
  • 1
    $\begingroup$ @Jens It's coming soon... I'll make the release sometime tomorrow :) $\endgroup$
    – rm -rf
    Feb 16, 2016 at 6:23
  • 1
    $\begingroup$ @Jens Thanks for the feedback. I'll add the \[...] to unicode mapping in the next release :) $\endgroup$
    – rm -rf
    Feb 21, 2016 at 14:47
14
$\begingroup$

To get syntax highlighting for Mathematica in a latex code listing, try this:

\usepackage{listings}
\usepackage{color} 
\definecolor{listinggray}{gray}{0.9}
\definecolor{graphgray}{gray}{0.7}
\definecolor{blue}{rgb}{0,0,1}
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}

% define a custom mathematica language for syntax highlighting
\lstdefinelanguage{myMMA}{
keywords={SetDirectory, NotebookDirectory, Exp, IdentityMatrix, Eigenvalues, 
ListPlot, PlotRange, PlotStyle, Directive, PointSize, AspectRatio, Blue, Graphics, Line, 
Manipulate, Show, Sqrt, UniformDistribution, GammaDistribution, BetaDistribution, 
Nintegrate, For, DataRange, AxesLabel, PlotLabel, Transpose, Export, Plot, Append, Infinity},
keywordstyle=\color{black},
commentstyle=\color{gray}, 
stringstyle=\color{mymauve},
identifierstyle=\color{blue},
sensitive=false,
comment=[l]{(*},
morecomment=[s]{/*}{*/},
morestring=[b]',
morestring=[b]"
}

Keep in mind that the keywords I've listed here are far from exhaustive. I tried to find a list of Mathematica keywords but gave up. So I just used the keywords that I actually used in my code.

Edit

Here is a list of the keywords in a .txt file: https://www.dropbox.com/s/i3m8do7uof5uval/keywords.txt?dl=0

I found them by using

Names["System`*"]
$\endgroup$
5
  • 2
    $\begingroup$ Have a look at Names. BTW welcome here at Mathematica.SE! You might want to consider changing your user name as it coincides with one of the top users here and it may create some confusion. $\endgroup$ May 19, 2015 at 5:47
  • $\begingroup$ Thanks a ton, that was frustrating me. And I'll change the name as soon as SE lets me. $\endgroup$ May 19, 2015 at 6:02
  • $\begingroup$ Actually, you don't need to add all the keywords. The listings package already understands the option language=Mathematica! You just have to add the newest keywords that it doesn't know yet, using, e.g., otherkeywords={DiscretizeRegion}. $\endgroup$
    – Jens
    Feb 15, 2016 at 17:51
  • 1
    $\begingroup$ @Jens: Can you show a short but complete example of using the listings package for Mathematica that will produce syntax coloring. I tried it, being sure to load the color package, too, but I only get boldface and gray. $\endgroup$
    – murray
    Feb 21, 2016 at 18:22
  • $\begingroup$ @murray OK, let me try to make a complete but minimal $\LaTeX$ file. I'll probably post it as a separate answer for space reasons... I use this in bigger files so I have to eliminate some unnecessary customizations, but not too many... $\endgroup$
    – Jens
    Feb 21, 2016 at 18:28
12
$\begingroup$

The answer by @R.M. is what I would recommend to anyone who has the ability to install the required prerequisites. But as requested by @murray, here is an example of a complete $\LaTeX$ document that should have all the commands required for use with regular pdflatex (i.e., it doesn't require xelatex):

\documentclass[11pt,english]{scrartcl}
\usepackage{babel}
\usepackage{beramono}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{color}

\definecolor{identifiercolor}{rgb}{.4,.6,.56}
\definecolor{stringcolor}{gray}{0.5}
\definecolor{inactivecolor}{rgb}{0.15,0.15,0.5}
\usepackage{listings}
\lstset{basicstyle={\footnotesize\def\fvm@Scale{.85}\fontfamily{fvm}\selectfont},
  breaklines=true,
  escapeinside={\%*}{*)},
  keywordstyle={\bfseries\color{inactivecolor}},
  stringstyle={\bfseries\color{stringcolor}},
  identifierstyle={\bfseries\color{identifiercolor}},
  language=Mathematica,
  otherkeywords={DiscretizeRegion},
  showstringspaces=false}
\renewcommand{\lstlistingname}{Listing}

\begin{document}

Here I tell Mathematica to make a wave function plot:
\begin{lstlisting}[extendedchars=true,language=Mathematica]
Block[
 {region=DiscretizeRegion[Polygon[{{0,0},{-1/2,Sqrt[3]/2},{1/2,Sqrt[3]/2}}]]},
 ContourPlot[
  2 Cos[4 Pi x] Sin[(4 Pi y)/Sqrt[3]] - Sin[(8 Pi y)/Sqrt[3]],
  {x,y} %*$\in$*) region,
  PlotPoints ->70,
  Contours ->10,
  AspectRatio ->Automatic,
  FrameLabel ->{"x","y"},
  PlotLabel ->"Excited state of the equilateral triangle"
 ]
]
\end{lstlisting}

To get some characters such as \textbackslash{}[Element] in the output, 
I manually have to escpape from the listings environment and use the corresponding \LaTeX{} command.

\end{document}

Save this as listingsExample.tex and run pdflatex listingsExample. Make sure your editor doesn't automatically convert quotes " to $\LaTeX$ code (emacs does this by default). We want the code to be copied verbatim because it's supposed to be a source listing. The output should look like this:

PDF screen shot

I used the beramono font to get the arrows -> to come out in a form that allows the code to work directly when copied back to Mathematica. With the default font, the arrows look OK in the PDF but don't get translated back correctly inside Mathematica.

Also, I use the line basicstyle={\footnotesize\def\fvm@Scale{.85}\fontfamily{fvm}\selectfont}, to switch the font in the listing from serif to something closer to the Mathematica style. This font switching code comes from this answer on TeX.SE by Jubobs.

I also added a keyword not yet recognized by the package in its current version, using the line otherkeywords={DiscretizeRegion}.

For simplicity, the colors were chosen to look like the notebook display before any evaluation (i.e., keywords are blue). That way, I don't have to think about different colors for symbols that already have values.

The line escapeinside={\%*}{*)} defines two character sequences that are recognized as delimiters surrounding the escape to $\LaTeX$ code inside the listings environment.

$\endgroup$
6
  • $\begingroup$ @murray I hope this works for you - it's taken directly from a homework assignment I used last year... $\endgroup$
    – Jens
    Feb 21, 2016 at 18:59
  • $\begingroup$ Ok, that helps. Of course much of the $\text{\LaTeX}$ code you use is unnecessary, e.g., package scrartcl, use of babel ad `beramono, etc. $\endgroup$
    – murray
    Feb 21, 2016 at 20:40
  • $\begingroup$ The example as shown does not at all color such things as syntax errors (e.g., an unmatched parenthesis or missing bracket). How does one handle those? $\endgroup$
    – murray
    Feb 21, 2016 at 20:41
  • 1
    $\begingroup$ @murray As far as I know it's not possible, because listings is for syntactically correct code only... displaying an active notebook faithfully is probably a job for screen shots - anything else would be too much work. Of course it wouldn't be doable with Pygments, either. Actually - listings could do it if you finger-paint using `$\LaTeX$ escapes. But that's kind of silly. $\endgroup$
    – Jens
    Feb 21, 2016 at 20:43
  • $\begingroup$ The most useful reason I can think of for using Mathematica syntax coloring in a $\text{LaTeX}$ article is to show how the coloring tells you when something is wrong! $\endgroup$
    – murray
    Feb 21, 2016 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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