On Fri, Jan 10, 2003 at 10:51:51AM +0100, Jean-Marc Lasgouttes wrote: > David> Does anyone know of a way of comparing two versions of a text > David> and producing an output to show which changes have been made. > > Some stupid tricks for finding difference (if you are lucky) can be > found at > http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg16018.html
A slightly less stupid solution is to use the attached script, which requires installing dvipost from http://efeu.cybertec.at/dist/dvipost-1.0.tar.gz
#!/usr/bin/env python # Copyright (C) 2002 Dekel Tsur <[EMAIL PROTECTED]> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. version = "0.1" import getopt,os,sys,re,string add_begin = "\\changestart" add_end = "\\changeend" del_begin = "\\overstrikeon" del_end = "\\overstrikeoff" math_rexp = r"\$|\\\[|\\\]|\\(?:begin|end)\{(?:equation|eqnarray|align)\*?\}" def preprocess(from_file, to_file): result = [] if from_file[-3:] == "lyx": os.system("lyx -e latex " + from_file) from_file2 = from_file[:-3]+"tex" else: from_file2 = from_file fh = open(from_file2) lines = fh.readlines() fh.close() if from_file[-3:] == "lyx": os.remove(from_file2) preamble = 1 text = "" for line in lines: if preamble: if re.search(r"\\begin{document}", line): preamble = 0 else: result.append(line) continue # Remove comments line = re.sub(r"([^\\]|^)%.*", r"\1%", line) # Put %\n before commands line = re.sub(r"(\\(\w+){)", "%\n\\1", line) # Put %\n after \emph{ line = re.sub(r"(\\(emph|textbf){)", "\\1%\n", line) text = text + line x = re.split("("+math_rexp+")", text) math_mode = 0 for i in xrange(len(x)): y = x[i] if i % 2: math_mode = not math_mode if math_mode: x[i] = x[i]+" " else: x[i] = " "+x[i] elif math_mode: x[i] = re.sub(r"([^\\_^])([=<>+-,()}])", r"\1 \2 ", x[i]) x[i] = re.sub(r"([^\\])(\\)", r"\1 \2", x[i]) text = string.join(x, "") fh = open(to_file, 'w') fh.write(text) fh.close() return result def usage(): print """Usage: ldiff [options] [<file1>] <file2> Show the differences between two latex/lyx files. ldiff <file1> <file2> to compare two files. tdiff <file> to compare <file> with the most recent version checked into CVS. ldiff -r<rev> <file> to compare <file> with revision <rev> of <file>. ldiff -r<rev1> -r<rev2> <file> to compare revision <rev1> with revision <rev2>. Options: -h, --help This information -v, --version Output version information -d, --deleted Show deleted text -b, --nocolor Do not colorize the changed text -l, --latex Produce only the latex file -s, --separation Separation between change bars and text (default value = -50)""" _options = ["help", "version", "deleted", "nocolor", "latex", "separation="] try: opts, args = getopt.getopt(sys.argv[1:], "hvdbkls:r:", _options) except getopt.error: usage() sys.exit(1) rev = "" deleted = 0 colorize = 1 onlylatex = 0 sep = "-50" for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() if o in ("-v", "--version"): print "ldiff, version "+version sys.exit() if o in ("-d", "--deleted"): deleted = 1 if o in ("-b", "--nocolor"): colorize = 0 if o in ("-l", "--latex"): onlylatex = 1 if o in ("-s", "--separation"): sep = a if o == "-r": rev = rev + " -r" + a if len(args) not in [1,2]: usage() sys.exit(1) file1 = "ldiff_tmp1.tex" file2 = "ldiff_tmp2.tex" if len(args) == 2: preprocess(args[0], file1) file = args[1] else: file0 = file1[:-3]+args[0][-3:] os.system("cvs diff %s -u %s | patch -R -o%s" % (rev, args[0], file0)) preprocess(file0, file1) if file0[-3:] == "lyx": os.remove(file0) file = args[0] preamble_lines = preprocess(file, file2) if deleted: wdiffopts = "-w'%s{}' -x'%s{}'" % (del_begin, del_end) else: wdiffopts = "-1" wdiffopts = wdiffopts + " -y'%s{}' -z'%s{}'" % (add_begin, add_end) fh = os.popen("wdiff %s %s %s" % (wdiffopts, file1, file2)) lines = fh.readlines() fh.close() os.remove(file1) os.remove(file2) filebase = file[:-4]+"-diff" filetex = filebase+".tex" fh = open(filetex, 'w') for line in preamble_lines: fh.write(line) color = "Gray" if deleted: color = "Blue" fh.write(r""" \usepackage{dvipost} \dvipost{cbexp=0pt} \dvipost{cbsep=%spt} """ % sep) if colorize: fh.write(r""" \dvipost{cbstart color push %s} \dvipost{cbend color pop} \dvipost{osstart color push Red} \dvipost{osend color pop} """ % color) text = "" for line in lines: line = re.sub(r"\\maketitle", "\\maketitle\\"+add_end, line) line = re.sub(r"%(.*)", r"\1%", line) text = text+line x = re.split("("+math_rexp+"|\\"+del_begin+"\\{\\}|\\"+del_end+"\\{\\})", text) math_mode = 0 math_mode_save = 0 os_mode = 0 for i in xrange(len(x)): y = x[i] if i % 2: if y == del_begin+"{}": os_mode = 1 math_mode_save = math_mode elif y == del_end+"{}": os_mode = 0 if math_mode_save != math_mode: x[i] = " $"+x[i] math_mode = math_mode_save else: math_mode = not math_mode elif os_mode: if math_mode: if string.count(x[i], '{') != string.count(x[i], '}'): x[i] = re.sub(r"\{|\}", "", x[i]) else: x[i] = re.sub(r"\\\w+|\{|\}", "", x[i]) text = string.join(x, "") fh.write(text) fh.close() if onlylatex: sys.exit() filedvi = filebase+".dvi" fileps = filebase+".ps" os.system("latex "+filetex) os.system("bibtex "+filebase) os.system("latex "+filetex) os.system("latex "+filetex) os.system("ltxpost %s %s" % (filedvi, filedvi)) os.system("dvips %s -o %s" % (filedvi, fileps)) os.rename(fileps, "__"+fileps) os.system("rm %s.*" % filebase) os.rename("__"+fileps, fileps)