我想打印代码,最好是语法高亮,然后将其与 diff 相结合,其中包含的代码是代码的较新版本。我希望已添加或更改的行能够高亮显示或正常显示,而未修改的行则淡化。
目前,我正在将代码包含在 lstlisting 包中,但这并不能让我结合差异来突出显示更改。
这样的事情就太棒了。
原始文件
富
吧
修改的文件(包含在 LaTeX 文档中)
foo
bar2
baz
文档中的结果将是
富
酒吧2
巴兹
(除了理想情况下,正常文本将褪色,而粗体文本将保持正常)
答案1
这是一个可以进行差异处理的 Python 脚本。它适用于 Python 2.x,但只需稍加调整(codecs.open() -> open() 等)即可在 Python 3 下使用。您需要自定义添加/修改和删除行的处理方式以满足您的偏好。我将为此添加一个宏到我的 PythonTeX 包中,但至少要过几天我才能将其合并并发布新版本。
# -*- coding: utf-8 -*-
'''
Read in two code files, compute diff, and output a highlighted version in TeX
format. Usage: diff2tex.py old_file new_file
'''
# Imports
from __future__ import unicode_literals
import sys
import codecs
import difflib
import re
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import LatexFormatter
file_encoding = 'utf=8'
lexer = 'python'
formatter = LatexFormatter(style='default', texcomments=False, mathescape=False, linenos=True)
def pygmentize(expr):
s = highlight(expr, get_lexer_by_name(lexer), formatter)
# Strip Verbatim environment
s = re.sub(r'\\begin{Verbatim}\[.+\]\n', '', s)
s = re.sub(r'\\end{Verbatim}\n', '', s)
return s
def same_wrapper(expr):
return r'\colorbox{white}{\parbox{\linewidth}{' + expr.rstrip('\r\n') + '\\vphantom{fg}}}\n'
def new_wrapper(expr):
return r'\colorbox{PaleGreen}{\parbox{\linewidth}{' + expr.rstrip('\r\n') + '\\vphantom{fg}}}\n'
def del_wrapper(expr):
return r'\colorbox{LightPink}{\parbox{\linewidth}{' + expr.rstrip('\r\n') + '\\vphantom{fg}}}\n'
old_file = codecs.open(sys.argv[1], 'r', encoding=file_encoding)
new_file = codecs.open(sys.argv[2], 'r', encoding=file_encoding)
differ = difflib.Differ()
diff = differ.compare(old_file.readlines(), new_file.readlines())
result = []
for line in diff:
if line.startswith(' '):
line = re.sub('^ ', '', line)
result.append(same_wrapper(pygmentize(line)))
elif line.startswith('+ '):
line = re.sub('\+ ', '', line)
result.append(new_wrapper(pygmentize(line)))
elif line.startswith('- '):
line = re.sub('- ', '', line)
result.append(del_wrapper(pygmentize(line)))
elif line.startswith('\? '):
pass
# Create a header and footer for a sample .tex document
header = '''\\documentclass[11pt]{article}
\\usepackage[T1]{fontenc}
\\usepackage{lmodern}
\\usepackage[utf8]{inputenc}
\\usepackage{fancyvrb}
\\usepackage[svgnames]{xcolor}
\\usepackage{upquote}
\\begin{document}
'''
footer = '''
\\end{document}
'''
# Get the correct command to start the Verbatim environment
begin_verbatim = highlight(' ', get_lexer_by_name(lexer), formatter).split('\n',1)[0] + '\n'
out_file = codecs.open('diff.tex', 'w', encoding=file_encoding)
out_file.write(header)
# Need to get and write the Pygments macros
out_file.write(formatter.get_style_defs())
out_file.write('\n\n')
out_file.write(begin_verbatim)
out_file.write(''.join(result))
out_file.write('\\end{Verbatim}\n')
out_file.write(footer)
out_file.close()
我们可以给出这两个文件。旧版本:
#!/usr/bin/env python
'''
A docstring
'''
def f(x): #Will edit this
x = x + 1
x = x**2 #Will delete this
return x**2
f(x)
print('Done!')
新的、编辑过的文件:
#!/usr/bin/env python
'''
A docstring
'''
def f_new(x):
#Add a comment
x = x + 1
return x**2
f_new(x)
print('Done!')
运行后将python diff2tex.py old.py new.py
生成一个编译内容如下的文档: