Отслеживание версий документов LaTeX с помощью скрипта на Python

... и сверху ещё майонезом полить :-) На самом деле, задача вполне актуальная, а именно: есть документ LaTeX, с которым работает много людей - в документ вносятся правки. Большинство людей LaTeX не приемлют по личным причинам. По рукам ходит много распечаток документа разных версий, и нужно отслеживать, какая версия документа у каждого из них.

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

Для решения задачи нужно проделать несколько шагов. Во-первых, документ должен быть в репозитории системы контроля версий. Этим мы получаем номер ревизии, а стало быть, и всю информацию о том, какой документ обсуждается.

Далее нам нужно в текст LaTeX-документа добавить скрипт на Python. Для этого сначала нужно научиться вызывать Python внутри LaTeX, что довольно просто благодаря замечательной статье Python внутри LaTeX ув. тов. jetxee. Итак, требуется:

  • скачать файл python.sty и скопировать его в каталог с документом;
  • в документе в преамбуле включить \usepackage{python};
  • внутри документа фрагменты кода на Python помещать в окружение \begin{python} ... \end{python} - теперь всё, что они выведут, станет частью конечного документа;
  • запускать LaTeX теперь нужно с опцией -shell-escape для запуска встроенного кода из-под LaTeX
Ну и, естественно, нужно иметь рабочий Python на машине. Впрочем, если у вас десктоп с графической оболочкой и обвешан разными рюшками, Python у вас скорее всего уже есть.

Так, всё по отдельности у нас есть, и осталось запалить всё это вместе. Для этого в документ вставляем код (кусок реального документа, чтобы было понятно):

\documentclass[a4paper,10pt,oneside]{article}
\usepackage[T2A]{fontenc}
\usepackage[koi8-r]{inputenc}
\usepackage[russian,english]{babel}
\usepackage{amssymb,amsfonts,amsmath,mathtext}
\usepackage{cite,enumerate,float,indentfirst}
\usepackage{caption2,tabularx}
\usepackage[dvips]{graphicx}
\graphicspath{{pictures/}}

%<--------------Pythonated trick starts HERE!
\usepackage{fancybox,fancyhdr}
\usepackage{python}
\fancyhead[R]{}
\fancyhead[L]{}
\fancyhead[C]{}
\fancyfoot[R]{}
\fancyfoot[C]{\textit{\textbf{\input{svnstatus}}}}
\fancyfoot[L]{}
\begin{python}
#! /usr/bin/python
import os, string
cmd = 'svn status ИМЯФАЙЛАТУТ.tex -v'
fpipe = os.popen(cmd)
piperesult = fpipe.read()
fpipe.close()
results = piperesult.split()
if results[0] == 'M':
out = 'Subversion revision of this document is '+results[1]+', last modified by '+results[3]+', STATUS: '+results[0]
else:
out = 'Subversion revision of this document is '+results[1]+', last modified by '+results[2]
FileName='svnstatus.tex'
fout=open(FileName,'w')
fout.write(out)
fout.close()
\end{python}
%<--------------Pythonated trick ends HERE!


\makeatletter
\bibliographystyle{unsrt} %Стиль библиографических ссылок БибТеХа
% Заменяем библиографию с квадратных скобок на точку:
\renewcommand{\@biblabel}[1]{#1.}
\makeatother
% Рис.1. - как у нас принято.
\renewcommand{\captionlabeldelim}{.}

% Меняем поля страницы
\usepackage{geometry}
\geometry{left=2cm}
\geometry{right=2cm}
\geometry{top=2cm}
\geometry{bottom=3cm}

\begin{document}

\pagestyle{fancy}


\begin{abstract}
The registration of correlation signals....
\end{abstract}
Небольшие комментарии к коду. Я использовал возможности пакета fancyhdr для того, чтобы вставить упоминание о ревизии документа в колонтитуле - чтобы на каждой странице это было видно. Питонистый скрипт довольно прост, а если вы захотите его оптимизировать - напильник вам в руки.

Как сделать отслеживание версий для Mercurial [добавлено]
Для Mercurial код немного проще, приведу его кусок здесь:
%<--------------Pythonated trick starts HERE!
\usepackage{fancybox,fancyhdr}
\usepackage{python}
\begin{python}
#! /usr/bin/python
import os, string
cmd = 'hg id -n -i'
fpipe = os.popen(cmd)
piperesult = fpipe.read()
fpipe.close()
results = piperesult.split()
out = 'HG Mercurial revision hash of this document is '+results[0]+', revision number is '+results[1]
FileName='paperstatus.tex'
fout=open(FileName,'w')
fout.write(out)
fout.close()

\end{python}
\fancyhead[R]{}
\fancyhead[L]{}
\fancyhead[C]{Page \thepage}
\fancyfoot[R]{}
\fancyfoot[C]{\textit{\textbf{\input{paperstatus}}}}
\fancyfoot[L]{}

%<--------------Pythonated trick ends HERE!

После этого в ваш документ внизу страницы будет вставляться номер его ревизии в Subversion, что будет видно и при печати. Мне это сэкономило много нервов и седых волос.

18 комментариев: |высказаться!| RSS-лента дискуссии.|
Анонимный комментирует...

Спасибо за статью, думаю, пригодится. На днях переделывал отчет по нирс в latex, ваши статьи оказались очень даже кстати. Единственное, пришлось гуглить насчет пакета, который позволяет делать отступы во всех абзацев, начиная с первого.

\usepackage{indentfirst}

virens комментирует...

1 комментариев:

2 dpetroff.ru комментирует...
Спасибо за статью, думаю, пригодится.Пожалуйста. Мне вот уже пригодилась, и не раз :-)

Единственное, пришлось гуглить насчет пакета, который позволяет делать отступы во всех абзацев, начиная с первого. \usepackage{indentfirst}Очень странно: он должен быть в стандартной поставки, даже в tetex он есть. У вас какой дистрибутив латеха?
11.05.2009 8:39:00

Анонимный комментирует...

Очень странно: он должен быть в стандартной поставки, даже в tetex он есть.Товарищ, наверно, имел ввиду то, что про него ещё нужно узнать :-)

У меня вот какой вопрос: как бы поменять стиль оформления заголовков section в стандартных классах?
Читал про это у Львовского и в конце получилось вот это:
renewcommand{\section{\@startsection{section}{1}%
{0mm}{3.5ex plus 1ex minus .2ex}{15mm}%
{\normalfont\bfseries\Large\scshape\centering}}
LaTeX выдаёт ошибку:
You can't use `\spacefactor' in vertical mode.
\@->\spacefactor
\@m

Даже не знаю, что и думать...

Minoru комментирует...

Programmaster вежливо кашлянул, напоминая присутствующим, что он всё ещё здесьЗдрасте :)

К счастью, эта статья вернула блог в своё русло — а то я уж начал опасаться, что ты со своими примерами из диссертации совсем меня работы лишишь :) Я просто ту статью так до конца и не дочитал — не интересует эта ваша оптика, хоть убей :(

Хотя у меня завтра экзамен по физике, которую я, кстати, люблю :D

Ну-с, поехали!

возможность LaTeX выполнять налету и встраивать в текст результаты работы питонистого скрипта.
Ну, во-первых, «на лету» пишется раздельно :)
Во-вторых, как-то не очень читабельно эта фраза выглядит. Не лучше ли написать что-то вроде «возможность LaTeX выполнять Python-скрипт и встраивать результат его работы в документ»? Ну или что-то вроде того…

ув.тов.jetxee
А пробел перед ником не нужен?

скачать файл python.sty и скопировать этот файл
Тавтология получается. Лучше «скачать файл python.sty и скопировать его».

внутри документа фрагменты кода на Python … и теперь всё, что эти фрагменты кода будут печатать…
Аналогично. Может быть, покатит что-то вроде «внутри документа фрагменты кода на Python помещать в окружение \begin{python} ... \end{python} — всё, что они выведут, станет частью конечного документа;».

для запуска внешнего кода из-под LaTeX
Почему же код «внешний», когда он в документ встроен? В принципе, по логике больше подходит «внутренний», но так как я такое разделение кода на типы слышу впервые, лучше напиши просто «втроенного кода» :)

Однако если у вас десктоп с графической оболочкой и обвешан разными рюшками
«Однако» здесь несколько неуместно. Вот «впрочем» смотрелось бы значительно лучше :)

запалить всё это вместе.
Замечание не как редактора, но как читателя: у тебя в семье пожарники есть? :D Ты так любишь всё зажигать да запаливать…
Или это тебя гентушники на встречах заразили? Ты вроде в отчётах писал, что вы обычно им костёр доверяете — они же что угодно зажгут :D

Всё, после этого в ваш документ внизу страницы будет вставляться информация о том, что за версия Subversion этого документа
Опять тавтология. Что-то вроде «всё, после этого в ваш документ внизу страницы будет вставляться номер его ревизии в Subversion» может спасти ситуацию :)

That's all for today :)

Minoru комментирует...

Programmaster уже почти ушёл, но вдруг что-то вспомнил и вернулся
А вспомнил я вот что: вас не раздражает то, что после </b>, </i> и прочих убираются переносы строк? Причём сколько бы их (переносов) не было — все равно всё убирается и новая строка «прилепляется» к концу предыдущей.

Вчера поставил эксперимент в своём блоге (да простят меня читатели моего RSS фида). В результате подтвержил свои догадки: можно пользоваться HTML тегом <br>. То есть сразу после закрывающего тега ставишь <br> — и будет тебе счастье :) Как видите, в своём предыдущем комментарии я переносы расставил везде, кроме первой фразы (там где «Здрасте»). Работает ведь :)

Vaulter комментирует...

СТОП! svn (и др.) поддерживают т.н. keywords в теле документа, вида $Id$

\begin{abstract}
Ревизия $Revision$
..........

http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keywords.html

virens комментирует...

2 Анонимный комментирует...
У меня вот какой вопрос: как бы поменять стиль оформления заголовков section в стандартных классах?Честно говоря, я с такими вещами не сталкивался, так что увы, помочь не смогу.


2 Programmaster комментирует...

Programmaster вежливо кашлянул, напоминая присутствующим, что он всё ещё здесьДа ты заходи, не стесняйся, все свои... :-)

К счастью, эта статья вернула блог в своё руслоТак ведь не оффтопик, так что всё путём. В комментариях там интересных мыслей подбросили. За что я их, комментаторов, и ценю. Ну кроме спамеров, конечно :-)

Я просто ту статью так до конца и не дочитал — не интересует эта ваша оптика, хоть убейТак то не оптика, а регистрация изображений. Но не суть.

не очень читабельно эта фраза выглядит.Поправил - так лучше?

ув.тов.jetxee
А пробел перед ником не нужен?
Нужен. Глазаааааастый :-))


Тавтология получается. Лучше «скачать файл python.sty и скопировать его».Да, так лучше. Исправлено.

Может быть, покатит что-то вродеПокатило. :-)

Почему же код «внешний», когда он в документ встроен?Ммм...так дёргает-то он внешнюю программу? Хотя да, код-то внутри...

«Однако» здесь несколько неуместно. Вот «впрочем» смотрелось бы значительно лучше :)Так и есть. Пофиксено.

Замечание не как редактора, но как читателя: у тебя в семье пожарники есть?Неа, это последствия глобального потепления: раньше я мог что-то сморозить, теперь - только отжечь :-)

Опять тавтология.Да, писал не в ударе, согласен :-)
Исправил.

That's all for today :)Let me express my gratitude for your attention and fall down with adoration of your wisdom and greatness. :-)

2 Programmaster комментирует...
А вспомнил я вот что: вас не раздражает то, что после /b, /i и прочих убираются переносы строк?Да просто бесит, если честно. Это гугловцы, чтоб их так, опять что-то поломали (на тех.обслуживание вырубают блог уже второй раз за неделю). Надо им телегу накатать, что ли...


2 Vaulter комментирует...
СТОП! svn (и др.) поддерживают т.н. keywords в теле документа, вида $Id$Да, мне тут уже прислали вариант с keywords - думаю, надо будет писать ещё один пост (как разберусь). Большое спасибо за идею! И за ссылку тоже.

virens комментирует...

P.S> Про отсутствие BR в комментариях - оказывается, проблема известна, и давно (уже пару недель). Засабмитил блоггеровцам телегу, авось что придумают.

Анонимный комментирует...

Насчёт проблемы с заголовками, о которой я спрашивал выше:В очередной раз убеждаюсь, что google может решить все проблемы, а на CTAN уже всё написано :-)
http://www.tex.ac.uk/tex-archive/macros/latex/contrib/titlesec/
Вдруг кому-нибудь понадобится :)

Unknown комментирует...

А если VСS не поддерживает keywords, как до недавних пор bazaar, например, можно воспользоваться Makefile-ом и \input{}-ом. А то учить Python, хоть и по верхам похоже на «из пушки...» Вы не находите?

Minoru комментирует...

Так ведь не оффтопик, так что всё путём.
И то правда :)

В комментариях там интересных мыслей подбросили
Ну это как всегда :)

Ну кроме спамеров, конечно :-)
Армагеддон начнётся с появления человека, любящего спаммеров :D

Так то не оптика, а регистрация изображений. Но не суть.
Ну тебе виднее. ;)

Поправил - так лучше?
Агась :)

Нужен. Глазаааааастый :-))
^_^

Ммм...так дёргает-то он внешнюю программу? Хотя да, код-то внутри...
Вобщем-то да, вопрос скользкий. Код внутренний, но интерпретируется он внешней программой. Но это не очень-то и важно — понятно же, что ты имел в виду ;)

Неа, это последствия глобального потепления: раньше я мог что-то сморозить, теперь - только отжечь :-)
:D

>That's all for today :)
Let me express my gratitude for your attention and fall down with adoration of your wisdom and greatness. :-)

И кто меня за язык тянул… Пришлось полистать словарик. My pleasure and thanks, короче :)

Да просто бесит, если честно. Это гугловцы, чтоб их так, опять что-то поломали (на тех.обслуживание вырубают блог уже второй раз за неделю). Надо им телегу накатать, что ли...

Про отсутствие BR в комментариях - оказывается, проблема известна, и давно (уже пару недель). Засабмитил блоггеровцам телегу, авось что придумают.

Будем надеяться, они это быстренько починят
P.S. Кстати, твой коммент в Google Groups позволил мне реабилитироваться (в плане английского) — его я понял без словаря :D

Minoru комментирует...

С «my pleasure and thanks» я, наверное, таки лохонулся. Сейчас ещё раз (четвёртый уже :) перечитал свой коммент — ну не звучит оно :(

Unknown комментирует...

http://wiki.linuxformat.ru/index.php/LXF87-88:LaTeX -- раздел "LaTeX и контроль версий" и питон не нужен будет. По моему более элегантное решение.

jetxee комментирует...

Спасибо за ссылку. Приятно.

Только, может, лучше не тащить Python, а использовать svn:keywords ($Rev$, $LastChangedDate$, ...)? В исходнике документа будет номер версии.

Миша комментирует...

>У меня вот какой вопрос: как бы поменять стиль
>оформления заголовков section в стандартных
>классах?
>
>Читал про это у Львовского и в конце получилось
>вот это:
>renewcommand{\section{\@startsection{section}{1}%
>{0mm}{3.5ex plus 1ex minus .2ex}{15mm}%
>{\normalfont\bfseries\Large\scshape\centering}}
>LaTeX выдаёт ошибку:
>You can't use `\spacefactor' in vertical mode.
>\@->\spacefactor
>\@m

LaTeX использует "@" в своих целях. поэтому для корректной обработки содержащие его конструкции необходимо обрамлять командами \makeatletter и \makeatother:

\makeatletter
\renewcommand{\section{\@startsection{section}{1}%
{0mm}{3.5ex plus 1ex minus .2ex}{15mm}%
{\normalfont\bfseries\Large\scshape\centering}}
\makeatother

Анонимный комментирует...
Этот комментарий был удален автором.
Анонимный комментирует...

Ого...

Unknown комментирует...

а собственно почему для этого не использовать GIT. Кстати Линус Торвальдс недавно в GOOGLE провел конференцию по гиту, а добрые люди ее перевели.
http://www.youtube.com/watch?v=BtAlN4MaBr8

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

Подписаться на RSS-ленту комментариев к этому посту.