On Thu, Jan 30, 2003 at 09:09:14PM +0000, Raphael Clifford wrote:
> I have been given the kind offer (ahem) of reading a friend's thesis for
> them. Is there a "Track Changes" equivalent for lyx and/or latex so
> that we can easily work on each other's edits?
See http://www.devel.lyx.org/changetracking.php3
for a change tracking mode for LyX (it requires recompiling LyX).
If you want to compare between two lyx files, you can use the attached script
(which requires dvipost from http://efeu.cybertec.at/)
#!/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":
lyx = os.getenv("LYX")
if lyx == "":
lyx = "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"([^\\]|^)%(.*)"+'\\'+del_end, r"\1\2"+del_end, line)
line = re.sub(r"([^\\]|^)%(.*)", r"\1\2%", 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"\\(label|ref|cite)\{.*?\}", "", x[i])
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("dvipost %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)