# Postprocess pdf with \write18

I want to run a postprocessing script on my pdf. For integration with my editor it should be executed at the end of the pdflatex run, automatically -- ideally without having to change the compilation command in order not to break the behaviour for other documents.

I thought that I could do this with the atveryend package, using

%% minimal example file where \write18 is used for cropping.
\documentclass[]{article}

\title{}
\author{}
\usepackage{lipsum}
\usepackage{atveryend}
\AtVeryVeryEnd{
\message{^^J=== STARTING POSTPROCESSING ===^^J}
\immediate\write18{pdfcrop \jobname.pdf \jobname.pdf}
}

\begin{document}

\maketitle

\begin{abstract}
\lipsum[1]
\end{abstract}

\section{A section}

\lipsum[2-3]

\end{document}


But this fails. One can see from the log entries that even \AtVeryVeryEnd is executed a while before Output written on document.pdf is printed, i.e. the PDF file's handle is still open at that time. I can't say how this would behave on unix (where exclusive file locks are less common), but on my Windows machine it makes pdfcrop crash.

Is there some method to execute the command at the "VeryVeryVery" end of the pdflatex run, after the PDF file has been closed?

• No. There's no macro-level access to processes at or after the end of the PDF creation process. – Joseph Wright Jul 16 '15 at 9:32
• The output PDF file is finalized only after (the primitive) \end has been executed, so nothing can be read from the input at that time. What about pdflatex file && pdfcrop file? – egreg Jul 16 '15 at 9:32
• only thing you could do is launch a shell command that waits for the pdf to appear before editing it, that seems rather fragile though, compared to just configuring the editor to run the commands in sequence, all editor configs will allow that, so they can do latex bibtex latex, etc. – David Carlisle Jul 16 '15 at 9:35

You can do the following:

\newcommand{\postProcessDocument}[1]{%
\ifx\popCallStop\undefined%
\immediate\write18{pdfLaTeX
-synctex=1
-interaction=nonstopmode
-jobname=\jobname\space
\gdef\string\popCallStop{x}%
\string\input{\string\"\jobname\string\"}}%
#1%
\expandafter\stop%
\fi}
\postProcessDocument{%  post procesing commands
\message{^^J=== STARTING POSTPROCESSING ===^^J}
\immediate\write18{pdfcrop \jobname.pdf \jobname.pdf}
}

\documentclass[]{article}

\title{}
\author{}
\usepackage{lipsum}

\begin{document}

\maketitle

\begin{abstract}
\lipsum[1]
\end{abstract}

\section{A section}

\lipsum[2-3]

\end{document}


This will compile your document twice (with one call). First, \popCallStop is undefinded. Therefore, your main document is compiled. Afterwards, \popCallStop is defined with some dummy value. So, the second part of the compilation is running your post-processing. But as a user, you only do a single compilation.

This is some variation of a trick I saw once on stackexchange.

• I submitted a change suggestion to your code to also support documents, where the root file has spaces in its name. I also added -interaction=nonstopmode to prevent the process from hanging, which is problematic when running pdflatex from an editor interface. – kdb Jul 16 '15 at 11:44
• I just noticed that this breaks synctex in weird ways (different behaviour for different files) on my machine, regardless whether the file has spaces in the name or not. I assume that pdfcrop is what breaks it though. – kdb Jul 16 '15 at 12:01