突出显示代码中的更改

突出显示代码中的更改

我想打印代码,最好是语法高亮,然后将其与 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生成一个编译内容如下的文档:

在此处输入图片描述

相关内容