-
Notifications
You must be signed in to change notification settings - Fork 0
/
diff.py
93 lines (72 loc) · 2.5 KB
/
diff.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
Command line interface to difflib.py which wraps ndiff output in Critic Markup syntax.
"""
import sys
import difflib
import optparse
DELETED = '- ' # line unique to sequence 1
ADDED = '+ ' # line unique to sequence 2
COMMON = ' ' # line common to both sequences
NEITHER = '? ' # line not present in either input sequence
CM_ADD = '{++%s++}%s'
CM_DEL = '{--%s--}%s'
CM_HI = '{==%s==}{>>intraline differences<<}%s'
PLAIN = '%s%s'
LE_NL = '\n'
LE_CRNL = '\r\n'
def critic_markup(lines):
"wrap lines of ndiff output in critic markup"
while True:
line = next(lines)
try:
template, content, line_ending = parse_line(line)
yield template % (content, line_ending)
except IntralineDifferences:
pass # suppress intraline difference markers
class IntralineDifferences(Exception):
pass
def parse_line(line):
"""Parse line into diff marker, contents and line_ending (if applicable)"""
if line.startswith(ADDED):
template = CM_ADD
content = line[2:]
elif line.startswith(DELETED):
template = CM_DEL
content = line[2:]
elif line.startswith(NEITHER):
raise IntralineDifferences()
elif line.startswith(COMMON):
template = PLAIN
content = line[2:]
else:
raise Exception("NO MARKER::%s" % line)
if line.endswith(LE_NL):
line_ending = LE_NL
content = content[:-1]
elif line.endswith(LE_CRNL):
line_ending = LE_CRNL
content = content[:-2]
else:
line_ending = ''
return template, content, line_ending
def main():
# Configure the option parser
usage = "Output differences between two files as CriticMarkup. Output is a full file, works on full paragraphs only. \nusage: %prog [options] fromfile tofile"
parser = optparse.OptionParser(usage)
(options, args) = parser.parse_args()
if len(args) == 0:
parser.print_help()
sys.exit(1)
if len(args) != 2:
parser.error("need to specify both a fromfile and tofile")
fromfile, tofile = args # as specified in the usage string
# we're passing these as arguments to the diff function
# fromdate = time.ctime(os.stat(fromfile).st_mtime)
# todate = time.ctime(os.stat(tofile).st_mtime)
fromlines = open(fromfile, 'U').readlines()
tolines = open(tofile, 'U').readlines()
diff = difflib.ndiff(fromlines, tolines)
# diff is a generator
sys.stdout.writelines(critic_markup(diff))
if __name__ == '__main__':
main()