# Running external pdflatex command and importing the generated PDF document

There have been a couple of questions about incorporating labels and equations that were typeset in $\LaTeX$ into a Mathematica notebook. Ideally, this requires running pdflatex (or latex) from within Mathematica and then importing the generated PDF document.

Unfortunately, importing of PDF is known to be buggy, as discussed in these questions (among others, probably):

The last two also mention ghostscript as the way to solve some of the issues, in particular using the pdfwrite device to re-generate a new PDF from existing ones.

This could be used in a $\LaTeX$ workflow like this (I am assuming Mac OS X here):

Export["words.tex", "\n\\nonstopmode
\\documentclass[12pt]{article}
\\begin{document}\n
\\end{document}\n
", "Text"];

Run["pdflatex words"]

(* ==> 0 *)

Import["words.pdf"]


Import::general: Expected cross reference table >>

Import::general: Expected cross reference table >>

Import::general: Could not find document trailer >>

General::stop:

As was to be expected, here we get error messages similar to what the second question referenced above saw. So now try the ghostscript workaround. Since this question aims at using $\LaTeX$, by assumption we have a working $\TeX$ installation which nowadays includes ghostscript, so the following will be able to execute:

Run["gs -sDEVICE=pdfwrite -dNOCACHE \
-sOutputFile=words-nofont.pdf -q -dBatch -dNOPAUSE words.pdf -c quit"]

(* ==> 0 *)

Import["words-nofont.pdf"]


But the imported PDF has incorrect spacings between the words. It should (as you can tell from the \\qquad in the source) look more like

$\text{Here}\qquad \text{we}\qquad \text{go}$

This is just a somewhat artificial example illustrating the general problem of incorrect lengths and fonts upon import of a PDF.

So the question is, how can one fix this, either by using $\TeX$ and its companion utilities differently, or by relying only on Mathematica's capabilities? If this can be done, then it will be possible to automate the generation of $\LaTeX$ labels etc. from within Mathematica.

I'll post my answer based on ghostscript below, hoping that eventually someone will come up with a fix for PDF import that doesn't require external software.

-

Only expected to work for Mac OS X and linux (Windows has ghostscript, but calls have different syntax):

The reason why the errors happen in the first place is that pdflatex generates one of the more recent versions of the PDF specification (1.5), whereas Mathematica expects an older version upon import (probably 1.3). Specifying the lower version by adding \pdfminorversion=3 as the first line of the source gets rid of the error messages but doesn't fix the spacings.

A possible work-around is to replace the ghostscript call in the question by a two-step process that first converts the $\LaTeX$ generated to Postscript and then passes it to the ps2pdf command which also comes with the $\TeX$ distribution. This seems to remove the features of the modern PDF that trip up Mathematica's import handling:

Run["gs -sDEVICE=pswrite -dNOCACHE -sOutputFile=- -q \
-dbatch -dNOPAUSE -dQUIET words.pdf -c quit | ps2pdf - wordNew.pdf"]

(* ==> 0 *)

Import["wordNew.pdf"]


To tie this together into a Mathematica function that typesets a given source string, I'll change the standard preamble of the test file above into something nicer:

latex[str_] := Module[
{p,
TeXsource = "\n\\nonstopmode
\\documentclass[border=1pt]{standalone}
\\usepackage[usenames]{color} %used for font color
\\usepackage{amssymb} %maths
\\usepackage{amsmath} %maths
\\usepackage[utf8]{inputenc} %useful to type directly diacritic \
characters\n
\\begin{document}\n
***BODY***
\\end{document}\n
",
sourceFile =
FileNameJoin[{$TemporaryDirectory, "MathematicaOutput" <> StringJoin[Map[ToString, DateList[]]]}]}, Export[sourceFile <> ".tex", StringReplace[TeXsource, "***BODY***" -> str], "Text"]; SetDirectory["/tmp"]; Run["pdflatex " <> sourceFile]; Run["gs -sDEVICE=pswrite -dNOCACHE -sOutputFile=- -q -dbatch \ -dNOPAUSE -dQUIET " <> sourceFile <> ".pdf -c quit | ps2pdf - " <> sourceFile <> "-nofont.pdf"]; p = First@Import[sourceFile <> "-nofont.pdf"]; DeleteFile[FileNames[sourceFile <> "*.*"]]; ResetDirectory[]; p ]  Now you can use this function as follows: latex[ "The answer is\\quad$\\displaystyle\\frac{\\alpha}{2}\\int_0^\\infty f(x)\\,dx$" ]  This allows transparent$\LaTeX\$ typesetting from within Mathematica, and the standalone class makes sure that the output PDF is nicely cropped.

As I said, this is a workaround that will become unnecessary as soon as someone finds a Mathematica-only route to import PDF properly.

-
If you only want PostScript, not PDF, you could also call latex and then dvips. –  Martin Schröder Dec 26 '12 at 12:49
Yes, that's true. But then to import it, I'd still need to convert to PDF again (using ps2dpf which I use above as well), so the total number of steps seems to be the same. –  Jens Dec 26 '12 at 16:59