[Tex/LaTex] How to use latekmk with feynmf/feynmp

build-systemfeynmflatexmkpdftex

Background

The latexmk tool can be used to automatically process your LaTeX files enough times to generate the output. As discussed here and here, latexmk now supports setting out_dir which passes the -output-directory to pdflatex and places build products in this alternate location. Unfortunately, this makes it difficult to use latexmk with feynmp.

Question

How can I configure latexmk to call mpost for processing Feynman diagrams generated by feynmp? Especially using the new out_dir configuration?

Partial Answer 1

One can try to add a custom rule to the latexmkrc file like

add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
    system("mpost $_[0]");
}

but this fails in three ways: 1) if there are multiple images, then the extensions .1 changes and it is not clear how to specify all the dependences. 2) I don't know how to tell latexmk that pdflatex needs to be run again after the figure is generated. 3) Even if out_dir is specified, latexmk still runs the mpost command in the source directory, thereby missing the generated .mp files.

Partial Answer 2

As suggested in this answer, one can use the -shell-escape option of pdflatex to allow the figures to be processed by the call to pdflatex. Unfortunately, the call to mpost still takes place in the top-level directory. Is there some way of using -output-directory to ensure that shell commands are executed in the appropriate place?

Here is a MWE demonstrating this second attempt:

latexmkrc

mkdir _build;
$out_dir = '_build';
$pdflatex="pdflatex -shell-escape -interaction=nonstopmode %O %S";

tst.tex

\documentclass{scrbook}
\usepackage{feynmp}
\usepackage{etoolbox}

\DeclareGraphicsRule{*}{mps}{*}{}
\makeatletter
\show\endfmffile
\preto{\endfmffile}{\let\the@fmffile\thefmffile}
\appto{\endfmffile}{
  \ifnum\pdfshellescape=\@ne
    \immediate\write18{mpost \the@fmffile}%
  \else
    \message{
      Run pdf(la)tex with -shell-escape to generate feynmp diagrams}
  \fi
  \let\the@fmffile\relax
}
\makeatother

\begin{document}
\begin{fmffile}{title}
  \begin{fmfgraph}(40,25) 
    \fmfleft{i1,i2} 
    \fmfright{o1,o2} 
    \fmf{fermion}{i1,v1,o1} 
    \fmf{fermion}{i2,v2,o2} 
    \fmf{photon}{v1,v2}
  \end{fmfgraph} 
\end{fmffile}
\end{document}

Best Answer

There's an update to latexmk, v. 4.30a, that solves some problems with using the -output-directory option. I'd recommend upgrading.

Here's a solution that works with v. 4.30a of latexmk:

$out_dir = 'output';
add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
    my $file = $_[0];
    my ($name, $path) =  fileparse( $file );
    pushd( $path );
    my $return = system "mpost $name" ;
    popd();
    return $return;
}
which is to be put in a latexmkrc file.

The above code solves the problem of persuading mpost to put its output files in the appropriate directory. The new version of latexmk solves the other problem that on a first run, when the .1 file does not exist, latexmk needed to detect the missing file condition and run mpost.

As far as I can tell, it does not cause a problem that if there are multiple images, mpost generates files with extensions like .NNN, where NNN is an integer. In this situation, there is still a file with extension .1, and this is sufficient to trigger the correct use of mpost.

Related Question