понедельник, 28 июня 2010 г.

Внедрение номера ревизии SVN в документ LaTeX

Допустим, мы разрабатываем с использованием LaTeX некоторый документ, исходники которого хранятся в системе контроля версий Subversion. Необходимо сделать так, чтобы по документу можно было определить, из какой ревизии он был собран. Для этого следует внедрить номер ревизии в текст документа, например, с помощью сноски:

Разведение слонопотамов%
\footnote{Собрано из ревизии \input{revision.tex}.}

Вместо команды \input{revision.tex} при трансляции документа подставляется содержимое указанного файла. Комментарий в конце первой строки убирает пробел, на который заменяется символ перевода строки. Файл revision.tex будет содержать номер ревизии, например 366. При каждой сборке документа необходимо просмотреть все рабочую копию, сравнить сохраненный номер ревизии с текущим и при наличии несоответствия обновить revision.tex и пересобрать документ.

Содержимое Makefile:

BUILD_DIR = build
MAIN_TEX = svnversion.tex
REVISION_TEX = revision.tex
TEX = $(MAIN_TEX) $(REVISION_TEX)
PDF = $(BUILD_DIR)/svnversion.pdf

Объявляются необходимые переменные. BUILD_DIR - директория для результатов сборки, MAIN_TEX - основной документ, имя которого будет передаваться транслятору LaTeX, REVISION_TEX - файл с номером ревизии, TEX - список файлов-зависимостей, PDF - файл-цель.

MKDIR = mkdir
RM = rm
SED = sed
SED_COMMAND = "s/\([0-9]\+:\)\?\([0-9]\+[A-Z]*\)/\2/"
REVISION_BAT = revision.bat
SVNVERSION = svnversion
SVNVERSION_OPTIONS = -n
LATEX = pdflatex
LATEX_OPTIONS = -output-directory=$(BUILD_DIR)

MKDIR, RM, SED, REVISION_BAT, SVNVERSION, LATEX - программы и команды, использующиеся в процессе сборки цели, SVNVERSION_OPTIONS - опции svnversion, LATEX_OPTIONS - опции интерпретатора LaTeX.

Номер версии рабочей копии будем определять с помощью утилиты svnversion, которая для Windows доступна в составе пакета CollabNet Subversion Command-Line Client. Утилита выдает номер версии в формате [ver1:]ver2[X], где ver1 - самая ранняя ревизия файла из рабочей копии, ver2 - самая поздняя, X - кратная характеристика рабочей копии (например, есть ли локальные изменения). Если рабочая копия не содержит файлов с разными номерами ревизий, то формат вывода ver[X]. В первом случае нас будет интересовать только часть строки после двоеточия, а во втором - вся строка. SED_COMMAND содержит команду потокового редактора sed, выделяющую необходимую часть строки.


WC_VERSION = $(shell $(SVNVERSION) $(SVNVERSION_OPTIONS) . | $(SED) $(SED_COMMAND))

В переменную WC_VERSION заносится необходимая информация о рабочей копии.

all: rev $(PDF)

rev:
  $(REVISION_BAT) $(WC_VERSION) $(REVISION_TEX)

$(PDF) : $(TEX)
  if not exist $(BUILD_DIR) $(MKDIR) $(BUILD_DIR)
  $(LATEX) $(LATEX_OPTIONS) $(MAIN_TEX)

Это цели и правила их сборки. all - главная цель. Цель rev обновляет файл с ревизией, цель $(PDF) запускает сборку. Вспомогательный файл revision.bat выглядит следующим образом:

@echo off

rem %1 is working copy resivion
rem %2 is name of file with revision

if not exist %2 goto update_file

set /p wc_rev_file= <%2
if not %1==%wc_rev_file% goto update_file

goto :EOF

:update_file
echo %1 > %2

Содержимое файла revision.txt сравнивается с переменной WC_VERSION, если будут обнаружены отличия, файл обновится.

Исходный код здесь.

Комментариев нет:

Отправить комментарий