Highlighting Mathematica code in $\LaTeX$ document

42

21

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?

Eckhard

Posted 2014-02-23T21:13:06.707

Reputation: 1 325

1

possible duplicate of Saving a notebook as a $\LaTeX$ file, with syntax highlighting preserved

– Dr. belisarius – 2014-02-23T21:27:46.550

1Thanks 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. – Eckhard – 2014-02-23T21:34:11.703

2

@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.

– halirutan – 2014-02-24T04:35:27.230

3@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. – halirutan – 2014-02-24T04:39:27.507

2If 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. – halirutan – 2014-02-24T04:42:03.893

@Eckhard after a few moths, what´s your conclusion?. I´m very interested in the issue. – Mika Ike – 2014-06-21T06:15:59.130

@MikaIke Please see my answer below. – rm -rf – 2016-02-15T15:06:55.327

you can always save .nb file in pdf and use this

– egwene sedai – 2016-02-15T15:07:26.287

Related: How best to embed various cell groups into a latex project?

– jkuczm – 2016-03-08T14:26:56.420

1

Surprised there is no link to http://tex.stackexchange.com/questions/84748/fanciest-way-to-include-mathematica-code-in-latex/223898#223898 as a related question.

– SPPearce – 2017-03-14T09:52:54.597

Answers

24

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.

rm -rf

Posted 2014-02-23T21:13:06.707

Reputation: 85 395

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? – murray – 2016-02-15T15:36:30.840

@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. – rm -rf – 2016-02-15T15:46:16.720

1You 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). – Jens – 2016-02-15T17:58:37.943

Just to report back - it works as advertised, but the issue with \[Element] and similar characters does remain. – Jens – 2016-02-15T18:11:35.693

@Jens You're right. I plan to add that in soon. I didn't include in the first release because python 2.x doesn't always play well with unicode and it'll be a pain to support it across different versions of python (don't know if there are OS differences...). I will have some solution for this soon though, so you should be able to write and have it be recognized as an operator or write \[Element] or α or \[Alpha] and have it be recognized as a symbol. – rm -rf – 2016-02-15T22:04:24.897

Very cool - it's definitely a worthwhile effort, given that the other export methods from Mathematica are so flaky. – Jens – 2016-02-15T22:23:10.293

That looks excellent! I will give it a try as soon as I can. – Eckhard – 2016-02-15T22:32:07.190

1

@Jens It's coming soon... I'll make the release sometime tomorrow :)

– rm -rf – 2016-02-16T06:23:14.157

@Jens Please try the latest commit from master – rm -rf – 2016-02-17T03:58:18.853

@R.M. When I input it works, but with \[Element] it doesn't. So I still have to use the copy palette that I posted in this thread: How to “Copy as Unicode” from a Notebook, but then everything seems to be fine. Now I have to google a little to find out how to use minted in LyX.

– Jens – 2016-02-17T04:52:13.083

@Jens Ah, I didn't realize that you actually wanted \[Element] itself recognized as an operator. I thought it was a copy-paste result of :) Should be very easy to add, but I might wait on this one since I'm working on a couple of other additions. Also, it'll give me more time to collect other feedback/suggestions on it. BTW, it would also be easy for me to make modifications such as \[Element] -> on the fly, but I haven't been able to find a way to configure that as an option to only allow those who want it to use it... – rm -rf – 2016-02-17T06:12:19.333

I guess there are two separate design goals: (1) round-trip copying from MMA -> PDF -> MMA would be nice, and I think you already have that covered (if I turn off line numbers). (2) cosmetic issues such as display of unicode characters instead of FullForm code - and such issues are perhaps more open-ended, so it's understandable if you want to keep it the way it is for now. – Jens – 2016-02-17T06:41:49.810

@Jens If you don't mind me using you as a guinea pig... could you please try out version 0.3.0-rc-1 from here? It has support for highlighting local variables in Block, With and Module. I'm still working on adding support for highlighting patterns in := and :> so that's not going to look right. I'm mostly looking for some tests on real-world mathematica code to see if there are things I've overlooked (or things I might have to compromise on for practicality).

– rm -rf – 2016-02-20T03:44:56.070

It seems to work the same way as it does on the mathematica.SE web site, so that's good. But of course the more I try it, the more I notice how heavily I use things like \[Theta] etc... For the web site, we have the script by @halirutan, and I wonder if it can be leveraged here, too.

– Jens – 2016-02-20T22:59:18.147

@Jens It should do a little more than the website highlighting because the local variable x in x + Block[{x}, x] should be a different color than the one outside (this is only in the v0.3.0-rc-1 version). Regarding the \[Theta], I have all the ability to do that in the highlighter... the only problem is that I still haven't figured out whether that can be provided as an option via Pygments because not everyone might want to convert their \[...] characters into unicode. – rm -rf – 2016-02-21T01:58:37.407

@murray I added a new style that uses colors from the mathematica notebook. You can use it if you install the latest version from here and use \usemintedstyle{mathematicanotebook} in the above example.

– rm -rf – 2016-02-21T06:18:53.867

Yes, the scoped highlighting works, and the latest release pygments-mathematica-0.3.1 has the more greenish color for local variables. The mathematicanotebook colors and boldfacing make it very close to actual Mathematica output. The arrows (e.g. ->) don't bother me, but I think unicode for \[...] would be what most people would prefer, especially since you're using xetex anyway, and it doesn't interfere with round-trip copying. – Jens – 2016-02-21T07:13:14.450

1@Jens Thanks for the feedback. I'll add the \[...] to unicode mapping in the next release :) – rm -rf – 2016-02-21T14:47:23.883

13

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`*"]

Guilty Spark

Posted 2014-02-23T21:13:06.707

Reputation: 131

2

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.

– Sjoerd C. de Vries – 2015-05-19T05:47:57.993

Thanks a ton, that was frustrating me. And I'll change the name as soon as SE lets me. – Guilty Spark – 2015-05-19T06:02:51.713

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}. – Jens – 2016-02-15T17:51:19.290

1@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. – murray – 2016-02-21T18:22:39.607

@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... – Jens – 2016-02-21T18:28:29.720

9

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.

Jens

Posted 2014-02-23T21:13:06.707

Reputation: 93 191

@murray I hope this works for you - it's taken directly from a homework assignment I used last year... – Jens – 2016-02-21T18:59:10.537

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. – murray – 2016-02-21T20:40:39.947

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? – murray – 2016-02-21T20:41:54.607

1@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. – Jens – 2016-02-21T20:43:45.853

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! – murray – 2016-02-21T20:55:54.383

@murray I've never had a need for that, so I can't say anything else about it. – Jens – 2016-02-21T21:25:45.130