2

I am creating diff files for legal documents with the python difflib and make_file(), which outputs HTML files containing a Table with the Diffs.

But the output tables are so wide that they are unreadable.

Is there any way to change the width of the table or add other css from my function call? I can't find anything related in the documentation.

In case it is not possible, what could be a solution to my "table width too wide" problem?

I already tried adding bootstrap and putting the table into a div that is responsive, but it didn't work.

1
  • see source code difflib - it uses hidden variable _styles and _template which you could use to assign own styles and own HTML template. Besides there is wrapcolumn in class HtmlDiff which could help to make it shorter. Commented Dec 22, 2020 at 22:49

1 Answer 1

6

You can use wrapcolumn= in HtmlDiff

import difflib
import webbrowser

d = difflib.HtmlDiff(wrapcolumn=10)

lines1 = ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa']
lines2 = ['XXXXXXXXXXXXXaaaaaaaaaYYYaaaaaaZZZZZZZZZZZaaaaZZZZZZZZ']

html = d.make_file(lines1, lines2)

with open('output.html', 'w') as fh: 
    fh.write(html)

webbrowser.open('output.html')

Without wrapcolumn=

enter image description here

With wrapcolumn=10

enter image description here


EDIT:

I didn't test it but in source code of diff you can see hidden variables _styles, _table_template, _file_template which you could replace in HtmlDiff to generate different HTML. This way you could add classes and styles to format it.

It may also need to change hidden _format_line to remove nowrap="nowrap"


EDIT:

I use HtmlDiff to create own class with new _format_line() without nowrap="nowrap" and now I can add styles with width and word-break

import difflib
import webbrowser

# --- classes ---

class MyHTML(difflib.HtmlDiff):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
   
        # append new styles inside new class 
        self._styles = self._styles + """
table.diff {width: 300px}
.diff_sub {display: inline-block; word-break: break-word;}
.diff_add {display: inline-block; word-break: break-word;}
"""

    # function from source code - I remove only `nowrap="nowrap"`
    def _format_line(self,side,flag,linenum,text):
        """Returns HTML markup of "from" / "to" text lines
        side -- 0 or 1 indicating "from" or "to" text
        flag -- indicates if difference on line
        linenum -- line number (used for line number column)
        text -- line text to be marked up
        """
        try:
            linenum = '%d' % linenum
            id = ' id="%s%s"' % (self._prefix[side],linenum)
        except TypeError:
            # handle blank lines where linenum is '>' or ''
            id = ''
        # replace those things that would get confused with HTML symbols
        text=text.replace("&","&amp;").replace(">","&gt;").replace("<","&lt;")

        # make space non-breakable so they don't get compressed or line wrapped
        text = text.replace(' ','&nbsp;').rstrip()

        return '<td class="diff_header"%s>%s</td><td>%s</td>' \
               % (id,linenum,text)

# --- main ---

d = MyHTML()

# >>> changing styles after creating `MyHTML` or in original `HtmlDiff <<<
#d._styles = d._styles + """
#table.diff {width: 300px}
#.diff_sub {display: inline-block; word-break: break-word;}
#.diff_add {display: inline-block; word-break: break-word;}
#"""

#d._file_template = """new template"""
    

lines1 = ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa']
lines2 = ['XXXXXXXXXXXXXaaaaaaaaaYYYaaaaaaZZZZZZZZZZZaaaaZZZZZZZZ']

html = d.make_file(lines1, lines2)

with open('output.html', 'w') as fh: 
    fh.write(html)

webbrowser.open('output.html')

Shorter version

import difflib
import webbrowser

d = HtmlDiff(wrapcolumn=10)

d._file_template = """new template with %(charset)s %(styles)s %(table)s %(legend)s"""         
#d._styles = """new styles"""         

lines1 = ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa']
lines2 = ['XXXXXXXXXXXXXaaaaaaaaaYYYaaaaaaZZZZZZZZZZZaaaaZZZZZZZZ']

html = d.make_file(lines1, lines2)

with open('output.html', 'w') as fh: 
    fh.write(html)

webbrowser.open('output.html')
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much! Wrapcolumn did the trick for the width. Can you give me an example for a call e.g. with a modified _file_template? I set a variable file='''<!DOCTYPE.... ''' and used _file_template=file in the function call, but it doesn't work
I made example which change _styles. If you don't need to modify functions in HtmlDiff then you can use d = HtmlDiff(wrapcolumn=10) and d._file_template = """new template"""

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.