使用 \write18 对 pdf 进行后处理

使用 \write18 对 pdf 进行后处理

我想在我的 pdf 上运行后处理脚本。为了与我的编辑器集成,它应该在 pdflatex 运行结束时自动执行 --理想情况下无需更改编译命令为了不破坏其他文件的行为。

我想我可以用这个atveryend包来做这件事,使用

%% 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}

但此操作失败。从日志条目中可以看出,即使在打印\AtVeryVeryEnd之前执行了一段时间Output written on document.pdf,即 PDF 文件的句柄当时仍处于打开状态。我无法说这在 unix 上会如何表现(独占文件锁不太常见),但在我的 Windows 机器上它会导致 pdfcrop 崩溃。

PDF 文件关闭后,是否有某种方法可以在 pdflatex 运行的“VeryVeryVery”末尾执行命令?

答案1

您可以执行以下操作:

\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}

这将编译您的文档两次(一次调用)。首先,\popCallStop未定义。因此,您的主文档被编译。之后,\popCallStop使用一些虚拟值进行定义。因此,编译的第二部分是运行您的后处理。但作为用户,您只需进行一次编译。

这是我在 stackexchange 上见过的一个技巧的变体。

相关内容