\write18
我喜欢在 PDF 文件完全写入并关闭后,在编译的最后使用 退出到 shell ,这样我就可以将其用作 shell 命令的一部分。这是否可行,或者 TeX 只是在最后关闭了 PDF?将其直接放在前面\end{document}
或里面\AtEndDocument
没有帮助(这并不奇怪)。据我所知,\write
s 实际上是那是什么对象,通常也是文档的一部分。所以我不抱太大希望。
背景
这是 的一项新功能,用于自动将 PDF 转换为 PNG standalone
。目前,我在第二次运行的序言中执行此操作,当时旧 PDF 尚未打开。这很好用,但我想避免编译两次独立图表。
答案1
您可以执行以下操作(基于 Ulrich Diez 的想法):
\documentclass{article}
\ifx\conditionmacro\undefined
\immediate\write18{%
pdfLaTeX --jobname="\jobname"
\gdef\string\conditionmacro{1}\string\input\space\jobname
}%
\immediate\write18{%
LaTeX --jobname="\jobname"
\gdef\string\conditionmacro{1}\string\input\space\jobname
}%
\immediate\write18{dvips \jobname}
\expandafter\stop
\fi
\begin{document}
abc
\end{document}
我不太确定在子进程中使用 \jobname 是否是个好主意,它似乎可行,但 \jobname1 或类似的名称可能更安全。
顺便说一句:我是使用窗户的不酷的孩子之一。
答案2
我认为这是不可能的;唯一可以挂钩的地方是\end
;让我们看一个 LaTeX 中的例子:
\makeatletter
\let\@@@@end\@@end
\def\@@end{\immediate\write18{ls -l \jobname.pdf}\@@@@end}
\makeatother
\documentclass{article}
\begin{document}
abc
\end{document}
编译后会给出标准输出
-rw-r--r-- 1 员工 159 7月 13 17:50 shellatend.pdf
但ls -l shellatend.pdf
编译结束后给出
-rw-r--r-- 1 员工 10200 7 月 13 日 17:50 shellatend.pdf
因此PDF文件还没有完全写出来。
\@@@@end
显然,将 shell 命令放在后面不执行任何操作。
答案3
一种不可移植的解决方案,似乎适用于 TeXLive 2011pdflatex --shell-escape
在 shell 中的运行sh
(因此很可能适用于任何基于 的 shell sh
),即在运行结束后分离要运行的进程pdflatex
。为了确保运行真正结束后事情能够发生,我使用了
sleep 3&&\
nohup cp \jobname.pdf \jobname.copy\
2>/dev/null
(没有换行符)。第一条指令等待 3 秒钟运行结束(该数字是任意的),并将&&
其分离(不确定它是如何工作的)。然后cp \jobname.pdf \jobname.copy
复制结果 pdf 文件;您可以用convert
实用程序或任何其他实际转换程序替换。我不太清楚为什么nohup
那需要 而sleep
命令不需要,但这可以防止cp
在父进程( )结束时调用 来中止pdflatex
。最后一步是将错误重定向到2>/dev/null
,因为由于某种原因nohup
会产生错误(这可能是一个不好的迹象,需要调查)。
当然,要将其用于一般用途的软件包中,我想您需要为 Windows 和 Mac 找到类似的解决方案,并确定这是否涵盖所有其他操作系统。
\documentclass{article}
\usepackage{lipsum}
\begin{document}
\section{Foo}
\lipsum[1-10]
\section{Bar}
\lipsum[11-20]
\immediate\write18{ls -la \jobname.*}
\immediate\write18
{sleep 3&&nohup cp "\jobname.pdf" "\jobname.copy" 2>/dev/null&}
\end{document}