Pensieve header: This is the main notebook for the nb2tex project, containing both the documentation and the implementation.

To do

The phrase “∧FreeQ[c, _Cell, {1,∞}]” within the program seems unnecessary, and is presently commented out. Remove or justify!

Insert definitions for \nbpdfPrint and for \nbpdfText.

Experimentation

SetDirectory["C:\\drorbn\\AcademicPensieve\\Projects\\nb2tex"]

nb=NotebookGet[NotebookOpen@FileNameJoin[{Directory[],"nb2tex.nb"}]];
nb[[1,1]]

Cases[nb,c_Cell /; FreeQ[c, _Cell, {1,∞}],∞][[11]]

Table[
type=cell[[2]];
tag=CellTags /. Cases[cell,_Rule] /. CellTags->"";
{type,tag},
{cell,Cases[nb,c_Cell /; Length[c]≥2∧FreeQ[c, _Cell, {1,∞}],∞]}
]

PDFWidth=7.2;
PDFFolder="Sample";
If[FileType[PDFFolder]===None, CreateDirectory[PDFFolder]];
PDFCounter=0;
lines=Table[
type=cell[[2]];
tag=CellTags /. List@@cell[[3;;]] /. CellTags->"";
Which[
type=="Text"∧tag=="tex", cell[[1]],
StringMatchQ[tag,"pdf"~~___], (
pdfname=PDFFolder<>"/"<>ToString[++PDFCounter]<>".pdf";
Export[pdfname, Append[cell, PageWidth -> 108 PDFWidth]];
StringReplace[
"\\noindent\\nbpdfXXXType{pdfname}",
{"XXX"->StringDrop[tag,3], "Type"->type, "pdfname"->pdfname}
]
),
type=="Text"∧tag=="exec", ToExpression[cell[[1]]]; "",
True, ""
],
{cell,Cases[nb,c_Cell /; FreeQ[c, _Cell, {1,∞}],∞]}
];
StringJoin@@Riffle[DeleteCases[lines, ""], "\n\n"]

LATEX Prologue

\documentclass[12pt,reqno]{amsart}
\usepackage[export]{adjustbox} % This also includes graphicx.
\usepackage{needspace}
\usepackage[textwidth=6.5in,textheight=9in,headsep=0.15in,centering]{geometry}

\def\nbpdfInput#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfEcho#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfPrint#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfText#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfMessage#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfOutput#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfSubsection#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfgraphInput#1{\vskip 1mm\par\noindent\includegraphics{#1}}
\def\nbpdfgraphOutput#1{\vskip 1mm\par\noindent\includegraphics[width=1.5in]{#1}}

\begin{document}

Documentation

The nb2tex project aims to write a converter that takes Mathematica notebooks and converts them into latex files.

Text cells with tag ``tex’’ become verbatim tex output. They may include anything texish --- like formulas $1+1=2$, or anything else.

Untagged cells are ignored; for example, the following one should not appear in the latex result:

This cell must not appear in the latex output.

Cells with tag ``pdf’’ are converted into numbered pdf files in a pdf-subfolder (default name: same as the notebook’s name; in this case, ``Sample’’). The latex produced is \verb$\nbpdfType{Sample/nnn.pdf}$, where \verb$Type$ is the type of the current cell (\verb$Text$, \verb$Input$, \verb$Output$, \verb$Echo$, etc.), and \verb$nnn$ is the number of the current pdf file.

For example:

binom=Echo[(((a+b))^32)]//Expand

\verb$Series[1/(1+x),{x,0,128}]$

Series[1/(1+x),{x,0,128}]

\par If a tag is of the form ``pdf:Name’’, a pdf file by the name ``NameType.pdf’’ is created in the pdf folder (where Type is the type of the cell), yet nothing is added to the tex file. This allows to treat certain cells is a special manner. For example, using latex commands that will inline them or use them as side figure. As an example, if the Mathematica input is \includegraphics[valign=t]{Snips/FactorialInput}, the output is \includegraphics[valign=t]{Snips/FactorialOutput}.

20!

\par If a tag is of the form ``pdfXXX’’, with XXX a string not beginning with the character ``:’’, the string XXX gets added to the \verb$\nbpdf$ command, so it becomes \verb$\nbpdfXXXType$. This is useful for graphics inclusions, for example, where a useful tag would be ``pdfgraph’’:

plot=Plot3D[Cos[(x^2)+(y^2)],{x,-3,3},{y,-3,3}]

\par Invoking nb2tex (suffixes are automatically added and should not be included):

nb2tex[nb_String, opts___Rule];
nb2tex[nb_String,tex_String, opts___Rule];

\par Valid options include:
\begin{itemize}
\item \verb$”PDFFolder” -> foldername$ (a string).
\item \verb$”PDFWidth” -> width$ (in inches).
\end{itemize}

Input cells with tag ``exec’’ get executed using \verb$ToExpression$ at the time of their processing (even if they do not have the property ``Evaluatable), with no output produced. This is useful for setting / re-setting options within the notebook itself. For example, an input cell with tag exec and content \verb”nb2tex$PDFWidth=10” will allow very wide outputs:

nb2tex$PDFWidth=10

\needspace{25mm}

binom

nb2tex$PDFWidth=6.5

\par Similarly, changing  \verb”nb2tex$TeXFileName” will change the file where the latex output is written.

Implementation

As in http://drorbn.net/AcademicPensieve/Projects/nb2tex/.

SetOptions[$FrontEndSession,PrintingStyleEnvironment->"Working"];
nb2tex[nb_String,opts___Rule]:=nb2tex[nb,nb,opts];

nb2tex[nb_String,tex_String, opts___Rule]:=Module[
{notebook,PDFCounter=0,type,tag,pdfname,cells,cell,c,cl,texfiles={},TeXOut,
PDFFolder=PDFFolder/. {opts}/.PDFFolder->nb
},
nb2tex$TeXFileName=tex<>".tex";
nb2tex$PDFWidth = PDFWidth /. {opts} /. PDFWidth->6.5;
TeXOut[s_String]:=(texfiles=texfiles⋃{nb2tex$TeXFileName};
WriteString[nb2tex$TeXFileName,s]);
notebook=NotebookGet[NotebookOpen@FileNameJoin[{Directory[],nb<>".nb"}]];
If[FileType[PDFFolder]===None, CreateDirectory[PDFFolder]];
DeleteFile/@FileNames["*.pdf",PDFFolder];
cells=Cases[notebook,c_Cell /; Length[c]≥2,∞];
Do[
type=cell[[2]];
tag=CellTags /. Cases[cell,_Rule] /. CellTags->"";
Which[
type=="Text"∧tag=="tex", TeXOut[
StringReplace[cell[[1]],{"’"->"'", "”"->"\""}]<>"\n\n"],
StringMatchQ[tag,"pdf:"~~___], (
pdfname=PDFFolder<>"/"<>StringDrop[tag,4]<>type<>".pdf";
Export[pdfname, Join[cell, Cell[PageWidth -> 80nb2tex$PDFWidth/0.75]]];
cl="c:\\drorbn\\bin\\cpdf.exe -scale-page \"0.75 0.75\" "<>pdfname<>" -o "<>pdfname;
Close@OpenRead["!"<>cl];
),
StringMatchQ[tag,"pdf"~~___], (
pdfname=PDFFolder<>"/"<>ToString[++PDFCounter]<>".pdf";
Export[pdfname, Join[cell, Cell[PageWidth -> 80nb2tex$PDFWidth/0.75]]];
cl="c:\\drorbn\\bin\\cpdf.exe -scale-page \"0.75 0.75\" "<>pdfname<>" -o "<>pdfname;
Close@OpenRead["!"<>cl];
TeXOut[StringReplace[
"\\nbpdfXXXType{pdfname}\n",
{"XXX"->StringDrop[tag,3], "Type"->type, "pdfname"->pdfname}
]]
),
type=="Input"∧tag=="exec", ToExpression[cell[[1]]],
True, Null
],
{cell,cells}
];
Close/@texfiles;
]

Run

SetDirectory["C:\\drorbn\\AcademicPensieve\\Projects\\nb2tex"];
nb2tex["nb2tex", PDFFolder->"Snips"];
Run@"\"C:\\Users\\drorb\\AppData\\Local\\Programs\\MiKTeX\\miktex\\bin\\x64\\pdflatex.exe\" nb2tex.tex"

LATEX Epilogue

\end{document}