Run LaTeXdiff from Git repository for separated LaTeX files
Language Select:
Introduction
You can easily get the difference of two LaTeX sources using LaTeXdiff.
Sometimes we manage LaTeX files with git, when we write articles. This program allows taking the difference of Git-managed LaTeX files and displaying the result.
What does it do?
- GitのコミットIDを2つ指定するとその2つのコミットの差分をLaTeXdiffで調べて出力
- 単一のLaTeXソースじゃなくて分割したファイルをincludeする場合にも対応
なお、今回は英語の場合しか試してません。
Overview of the program
Requirements
Naturally, TeX and latexdiff are required. If you installed TeX using MacTeX, you can use it. Python are required, too.
Original TeX source
まず今回使ったメインのTeXファイル。1.tex
、2.tex
などをincludeしています。
\documentclass[a4paper,12pt,fleqn]{jsarticle}
\begin{document}
\include{0}
\include{1}
\include{2}
\include{3}
\include{4}
\end{document}
今回は1.tex
、2.tex
、3.tex
、4.tex
の4つのファイルについて差分を取ることにします。
Extract files from Git repository
Gitリポジトリから任意のコミット時におけるファイルを開くには
git show a8ebb89:1.tex
のようにします。a8ebb89
はコミットIDです。
結果は標準出力に出力されますのでリダイレクトするなりパイプに渡して使うことが出来ます。
Processing Python program
1 #!/usr/bin/env python
2 #coding: utf-8
3 import sys
4 import shlex
5 import subprocess
6 FileList=['1.tex', '2.tex', '3.tex', '4.tex' ]
7
8 def write_source(input_file, output_file, commit_id):
9 print('{0} -> {1} [{2}]'.format(input_file, output_file, commit_id))
10 # Show source from Git
11 cmd=shlex.split('git show {0}:{1}'.format(commit_id, input_file))
12 with open(output_file, 'w') as f:
13 proc=subprocess.Popen(cmd, stdout=f, stderr=subprocess.PIPE)
14 stdout, stderr=proc.communicate()
15 # errchk
16 if stderr:
17 print("standard error of subprocess:")
18 print(stderr)
19 sys.exit()
20
21
22 def generate_diff(input_file, old, new):
23 # define names
24 old_file='{0}_{1}'.format(old, input_file)
25 new_file='{0}_{1}'.format(new, input_file)
26 output_file='diff_{0}'.format(input_file)
27 # latexdiff
28 cmd=shlex.split('latexdiff {0} {1}'.format(old_file, new_file))
29 with open(output_file, 'w') as f:
30 proc=subprocess.Popen(cmd, stdout=f, stderr=subprocess.PIPE)
31 stdout, stderr=proc.communicate()
32 # errchk
33 if stderr:
34 print("standard error of subprocess:")
35 print(stderr)
36
37
38 def clean(old, new):
39 import glob
40 import os
41 print('Removing intermediate files...')
42 for commit_id in [old, new]:
43 files=glob.glob('{0}_*'.format(commit_id))
44 for filename in files:
45 os.unlink(filename)
46
47
48 def main(old, new):
49 print('commit id(old): {0}'.format(old))
50 print('commit id(new): {0}'.format(new))
51 for input_file in FileList:
52 for commit_id in [old, new]:
53 output_file='{0}_{1}'.format(commit_id, input_file)
54 write_source(input_file, output_file, commit_id)
55 generate_diff(input_file, old, new)
56
57
58 if __name__ == '__main__':
59 # reading arguments
60 argvs=sys.argv
61 argc=len(argvs)
62 if argc != 3:
63 print('This program takes 2 arguments.')
64 print('Usage: python {0} commit id(old) commit id(new)'.format(argvs[0]))
65 sys.exit()
66 main(argvs[1], argvs[2])
67 #clean(argvs[1], argvs[2])
上のプログラムを適当な名前をつけて保存してください。以下ではlatexdiff.py
として保存したとして話を進めます。
How to use
6行目のFileListに差分を取りたいLaTeXのソースファイルを記入します。
あとは
python latexdiff.py CommitID(old) CommitID(new)
を実行してください。
中間ファイルを削除するためにclean関数も定義してありますが、上のプログラムではコメントアウトしてあります。必要であれば使ってください。
結果を表示するためのTeXソース
上のプログラムを実行すると、diff_1.tex
のようなファイルが出力されます。
あとは、これらをインクルードするTeXファイルを作ってください。先ほどのメインファイルを少し修正すればいいでしょう。
\documentclass[a4paper,12pt,fleqn]{jsarticle}
\begin{document}
\include{0}
\include{diff_1}
\include{diff_2}
\include{diff_3}
\include{diff_4}
\end{document}
あとはこちらをコンパイルすれば、2つのコミット間の差が見やすく表示されるはずです。
最後のコンパイルがうまくいかない場合
うまくコンパイルできない場合は以下をTeXソースのプリアンブルに記述するとうまくいくと思います。
\RequirePackage[normalem]{ulem}
\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1}
\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}}
\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}\providecommand{\DIFaddbegin}{}
\providecommand{\DIFaddend}{}
\providecommand{\DIFdelbegin}{}
\providecommand{\DIFdelend}{}
\providecommand{\DIFaddFL}[1]{\DIFadd{#1}}
\providecommand{\DIFdelFL}[1]{\DIFdel{#1}}
\providecommand{\DIFaddbeginFL}{}
\providecommand{\DIFaddendFL}{}
\providecommand{\DIFdelbeginFL}{}
\providecommand{\DIFdelendFL}{}
Lastly
以上です。すでに似たようなことをされてる方もおられるますし、やってることは大したことではありませんが、LaTeXソースを分割してGitでバージョン管理してる人にはそこそこ便利だと思います。
References
blog comments powered by Disqus