PDFTeX MetaPost – Text Processing in MetaPost During LaTeX Compilation

metapostpdftexworkflow

In a LaTeX document, I use a number of packages, many different commands created for the convenience of typing, non-standard fonts. I'd like to use it all inside MetaPost. The problem is that the text of the labels (including in btexetex) is rendered during the work of the mpos command, and not pdflatex. Is it possible to somehow postpone the rendering of text, formulas to the compilation stage of a LaTeX document? I know of a method using verbatimtexetex, but it requires duplicating the text from LaTeX to PostScript (this is not exactly deferred rendering, but it allow to have the necessary commands, fonts, etc. at the time of label rendering).

UPD: in a comment, Marijn wrote: Could you post a small example document and the necessary compile chain to illustrate your issue? What I would like to achieve looks something like this:

pic.mp:

outputtemplate := "%j-%3c.mps";

beginfig(1);
label(btex $x$ etex, (0, 0));
endfig;

end;

main.tex:

\documentclass{article}

% All kinds of usepackage, def, etc.
\usepackage{stix}

\begin{document}
\includegraphics{pic-001.mps}
\end{document}

And so that after calling the mpost pic and pdflatex main.tex commands, I get a file in which $x$ appears, typed in stix font. In addition, I want a solution in which the preamble text does not have to be duplicated in the MetaPost file, since it is almost impossible to maintain two identical pieces of text.

The ability to render text during the compilation of a LaTeX document, and not at the time of creating the image, I saw in this article.

Best Answer

Integrating Metapost figures into your LaTeX environment is simple, if you can switch to lualatex instead of pdflatex. For example:

\documentclass{article}
\usepackage{stix}
\usepackage{luamplib}
\mplibtextextlabel{enable}
\begin{document}
A document using Stix for maths:  $e=mc^2$.
\[
\begin{mplibcode}
beginfig(1);
    z0 = 42 dir 12;
    drawarrow origin -- z0 cutafter fullcircle scaled 6 shifted z0;
    dotlabel.rt("$x$", z0);
endfig;
\end{mplibcode}
\]
\end{document}

Compile this with lualatex to get this:

enter image description here

Documentation is here, and in Section 12 of my own Drawing with Metapost document.

...but lualatex is really slow!

Actually it really isn't any more. Even on my old 2011 Mac Mini, it only takes a few seconds to compile my benchmark document with 120 pages of complex graphics in-line. See pww-2.tex in this project.

... but my document is huge!

OK, my Drawing-with-Metapost document referenced above is also huge, and in that case I have a sort-of hybrid workflow.

  1. I use lualatex to compile the main document -- and it happily includes all of my old .mps graphics with no changes.

  2. And now I am gradually migrating my old .mp source to standalone luamplib graphics.

  3. This is the template I use:

     \documentclass[border=5mm]{standalone}
     \usepackage{luamplib}
     \begin{document}
     \mplibtextextlabel{enable}
     \begin{mplibcode}
     beginfig(1);
    
     endfig;
     \end{mplibcode}
     \end{document}
    
  4. Except that for DwM I vary that a bit, and I have the common code for the main document in a separate local style file called dwmcommon.sty. Just before \begin{document} in the main document and in these standalone graphics I have \usepackage{dwmcommon} to load all the common definitions, so that I only have to maintain them in one place.

  5. And of course I have to compile these updated MP files with lualatex instead of mpost. This produces .pdf output files directly instead of .mps or .eps, which saves one more process in the step.

The advantages of this hybrid approach are that:

  • it is a little bit quicker (but only a little)
  • it is a little easier to manage the syntax highlighting in the editor if you keep MP and TeX separate.

I did see a Vi syntax file for Context that attempted to define MP ranges and TeX ranges, but it was not a great success. So what I do (in Vim) is just switch between them manually, using set ft=mp or set ft=tex as needed.

Related Question