20080715

Автоматическая компиляция документов LaTeX (с помощью SCons)

Сколько нужно команд, чтобы скомпилировать PDF из документа LaTeX? Как минимум две: pdflatex mypaper.tex; pdflatex mypaper.tex. А если при этом используется библиография в формате BiBTeX? Уже как минимум четыре: pdflatex mypaper.tex; bibtex mypaper; pdflatex mypaper.tex; pdflatex mypaper.tex. А бывает, что документ нужно пропустить через LaTeX более, чем два раза? Бывает. А сколько раз нужно всё это проделывать во время редактирования документа? Много. Удобно всё это? Если честно, не очень. Но жизнь себе упростить можно.

Берём и устанавливаем SCons. В каталоге с файлом LaTeX создаём файл SConstruct вот такого содержания:
PDF(target='mypaper.pdf',source='mypaper.tex')
Вот и всё! Теперь достаточно одной команды:
$ scons
— и, если что-либо в документе или библиографии изменилось, то scons выполнит все нужные команды самостоятельно, запустит bibtex, если он используется, запустит несколько раз pdflatex (если необходимость этого указывается в логе)…

А если запустить scons повторно? А ничего не будет:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.
scons проверяет MD5-суммы исходных файлов и ничего не делает, если файлы не изменялись.

А если я хочу, чтобы файл перекомпилировался, когда меняется одна из иллюстраций? Проще простого. Поскольку я держу все картинки в подкаталоге imgs/ в формате PDF, то достаточно просто добавить их в список исходных файлов. Например так (содержимое файла SConstruct):
src = [ 'mypaper.tex', Glob('imgs/*.pdf') ]
PDF(target = 'mypaper.pdf', source = src)
— функция Glob создаст список всех файлов, удовлетворяющие шаблону.

А если нужен не PDF, а PS? Или DVI? Соответственно и в SConstruct достаточно написать
PostScript(target='mypaper.ps',source='mypaper.tex')
или
DVI(target='mypaper.dvi',source='mypaper.tex')


Вообще говоря, SCons — может управлять компиляцией не только документов LaTeX. Это универсальный и гибкий инструмент сборки программ, аналог комбинации Make и autoconf/automake. Я о нём узнал совсем недавно, увидев, что он используется в проекте FEniCS — почитал мануал — и понравилось. Файлы SConstruct (аналог Makefile) являются полноценными скриптами на Python (описать простые правила сборки просто, а сложные — возможно); scons умеет автоматически отслеживать зависимости в C, C++ и Java; «из коробки» поддерживаются C, C++, D, Java, Fortran (разных версий), ObjectiveC, Yacc, Lex, Qt, SWIK, и TeX/LaTeX (можно написать собственные «конструкторы» для других языков/инструментов); может отслеживать изменения по MD5-суммам, а не только по дате изменения; SCons умеет брать нужные файлы из других каталогов или систем управления версиями (CVS, Subversion); изначально спроектирован так, чтобы делать кросс-платформенные сборки было просто (в том числе проверки в стиле autoconf требуют на порядок меньшей настойчивости в изучении документации); поддерживаются параллельная сборка и кэш компилятора (как ccache, только не только для C/C++). А для работы самого SCons достаточно почти любого, самого замшелого Python. Ну и вообще, удобно, что «мэйкфайл» для компиляции документа LaTeX — всего одна строчка ;-)

Да, компилировать документы LaTeX можно, конечно, и с помощью старого проверенного make. Вот, кстати, и неплохой Makefile для этого дела.

См. также:

Эта заметка по-английски: Auto-building LaTeX documents with SCons