![无需任何中间文件(stdin/stdout)即可生成 PDF](https://linux22.com/image/234803/%E6%97%A0%E9%9C%80%E4%BB%BB%E4%BD%95%E4%B8%AD%E9%97%B4%E6%96%87%E4%BB%B6%EF%BC%88stdin%2Fstdout%EF%BC%89%E5%8D%B3%E5%8F%AF%E7%94%9F%E6%88%90%20PDF.png)
我正在以编程方式从模板生成 PDF,并希望避免一直访问硬盘。这并非出于优化目的,而是因为我在所有核心上运行并行线程,如果文件不崩溃,我将不得不使用某种奇怪的命名系统。
我非常希望在不使用文件的情况下运行 pdflatex 或 xelatex。让它从字符串(或 stdin)读取 tex 文件,并让它将 pdf 的数据打印到 stdout。
pdflatex 中有一个 -ipc 选项可以实现我想要的功能,但我不知道如何使用它。
任何帮助都将非常感激。
答案1
(PDF|Xe)TeX 运行访问的文件远不止文档源和创建的 PDF。除了可执行文件(已包含格式)外,还有文档类、包、字体,并且程序会创建(除输出 PDF 外)至少一个日志文件,但通常还会创建 .aux 文件,有时还会创建其他一些文件(取决于包和用途),以供第二次或以后的运行使用。
所以我不认为这是真正可行的。
我的想法是将所有这些文件放在一个特殊的仅内存文件系统上(至少每个输出都有一个自己的目录以实现更好的缓存)。
如果所有文件都使用相同的模板,那么减少访问多个文件的另一种选择是创建一个包含所有文件所共有内容的新格式。
答案2
如果我们可以假设一个类 UNIX 系统正在运行编译,那么使用 mktemp 怎么样(带或不带 RAMdisk 类型的文件系统)?
#!/bin/sh
TDIR=`mktemp -d --tmpdir=/tmp`
cd /path/to/source
cp file.tex other.sty references.bib ${TDIR}
cd ${TDIR}
pdflatex file.tex
# plus any other commands required for bibtex,
# to display the pdf file,
# or move it to its final destination
cd ..
rm -r ${TDIR}
重新阅读您的帖子时,如果这是旨在通过 Web 服务器或类似服务器传输最终的 PDF,那么概念仍然可以相同,但您可能必须在 Perl、Python 或服务器的 CGI 语言中找到 mktemp 等效项。
答案3
我已经为自己做了这个(按照上面的建议):
#!/bin/bash -e
STATUS500="Status 500 internal server error"
STATUS404="Status 404 file not found"
function removeTempDirectory {
[ -d "$DIR" ] && rm -Rf $DIR
}
function die {
removeTempDirectory
printf "$*\n\n" 1>&2
trap - EXIT
exit 1
}
PDFLATEX=`which pdflatex`
PDFLATEX_OPTIONS="-halt-on-error"
[ -x "$PDFLATEX" ] || die $STATUS500
DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'cgilatex'`
[ -d "$DIR" ] || mkdir -p $DIR || die $STATUS500
[ -f $PATH_TRANSLATED ] || die $STATUS404
$PDFLATEX -halt-on-error \
-interaction=nonstopmode \
-output-directory=$DIR \
$PATH_TRANSLATED &> /dev/null || \
die $STATUS500
printf "Content-Type: application/pdf\n\n"
cat $DIR/*.pdf
removeTempDirectory
exit
以及httpd.conf
(对于 Apache):
Options +Indexes +ExecCGI
Action pdflate-action /cgilatex/cgilatex.cgi
AddHandler pdflate-action .tex
希望能帮助到你
答案4
这是使用临时目录的最小版本:
DIR=`mktemp -d`; pdflatex "--output-directory=$DIR" myfile.tex; mv "$DIR/"*pdf .
虽然我也希望这可以通过 stdin 和 stdout 来完成 - 这是创建 Unix 程序的正确方法。