Back to index

moin  1.9.0~rc2
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
MoinMoin.support.difflib.HtmlDiff Class Reference

List of all members.

Public Member Functions

def __init__
def make_file
def make_table

Private Member Functions

def _tab_newline_replace
def _split_line
def _line_wrapper
def _collect_lines
def _format_line
def _make_prefix
def _convert_flags

Private Attributes

 _tabsize
 _wrapcolumn
 _linejunk
 _charjunk
 _prefix

Static Private Attributes

 _file_template = _file_template
 _styles = _styles
 _table_template = _table_template
 _legend = _legend
int _default_prefix = 0

Detailed Description

For producing HTML side by side comparison with change highlights.

This class can be used to create an HTML table (or a complete HTML file
containing the table) showing a side by side, line by line comparison
of text with inter-line and intra-line change highlights.  The table can
be generated in either full or contextual difference mode.

The following methods are provided for HTML generation:

make_table -- generates HTML for a single side by side table
make_file -- generates complete HTML file with a single side by side table

See tools/scripts/diff.py for an example usage of this class.

Definition at line 1642 of file difflib.py.


Constructor & Destructor Documentation

def MoinMoin.support.difflib.HtmlDiff.__init__ (   self,
  tabsize = 8,
  wrapcolumn = None,
  linejunk = None,
  charjunk = IS_CHARACTER_JUNK 
)
HtmlDiff instance initializer

Arguments:
tabsize -- tab stop spacing, defaults to 8.
wrapcolumn -- column number where lines are broken and wrapped,
    defaults to None where lines are not wrapped.
linejunk,charjunk -- keyword arguments passed into ndiff() (used to by
    HtmlDiff() to generate the side by side HTML differences).  See
    ndiff() documentation for argument default values and descriptions.

Definition at line 1665 of file difflib.py.

01665 
01666                  charjunk=IS_CHARACTER_JUNK):
01667         """HtmlDiff instance initializer
01668 
01669         Arguments:
01670         tabsize -- tab stop spacing, defaults to 8.
01671         wrapcolumn -- column number where lines are broken and wrapped,
01672             defaults to None where lines are not wrapped.
01673         linejunk,charjunk -- keyword arguments passed into ndiff() (used to by
01674             HtmlDiff() to generate the side by side HTML differences).  See
01675             ndiff() documentation for argument default values and descriptions.
01676         """
01677         self._tabsize = tabsize
01678         self._wrapcolumn = wrapcolumn
01679         self._linejunk = linejunk
01680         self._charjunk = charjunk


Member Function Documentation

def MoinMoin.support.difflib.HtmlDiff._collect_lines (   self,
  diffs 
) [private]
Collects mdiff output into separate lists

Before storing the mdiff from/to data into a list, it is converted
into a single line of text with HTML markup.

Definition at line 1811 of file difflib.py.

01811 
01812     def _collect_lines(self,diffs):
01813         """Collects mdiff output into separate lists
01814 
01815         Before storing the mdiff from/to data into a list, it is converted
01816         into a single line of text with HTML markup.
01817         """
01818 
01819         fromlist,tolist,flaglist = [],[],[]
01820         # pull from/to data and flags from mdiff style iterator
01821         for fromdata,todata,flag in diffs:
01822             try:
01823                 # store HTML markup of the lines into the lists
01824                 fromlist.append(self._format_line(0,flag,*fromdata))
01825                 tolist.append(self._format_line(1,flag,*todata))
01826             except TypeError:
01827                 # exceptions occur for lines where context separators go
01828                 fromlist.append(None)
01829                 tolist.append(None)
01830             flaglist.append(flag)
01831         return fromlist,tolist,flaglist

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff._convert_flags (   self,
  fromlist,
  tolist,
  flaglist,
  context,
  numlines 
) [private]
Makes list of "next" links

Definition at line 1866 of file difflib.py.

01866 
01867     def _convert_flags(self,fromlist,tolist,flaglist,context,numlines):
01868         """Makes list of "next" links"""
01869 
01870         # all anchor names will be generated using the unique "to" prefix
01871         toprefix = self._prefix[1]
01872 
01873         # process change flags, generating middle column of next anchors/links
01874         next_id = ['']*len(flaglist)
01875         next_href = ['']*len(flaglist)
01876         num_chg, in_change = 0, False
01877         last = 0
01878         for i,flag in enumerate(flaglist):
01879             if flag:
01880                 if not in_change:
01881                     in_change = True
01882                     last = i
01883                     # at the beginning of a change, drop an anchor a few lines
01884                     # (the context lines) before the change for the previous
01885                     # link
01886                     i = max([0,i-numlines])
01887                     next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg)
01888                     # at the beginning of a change, drop a link to the next
01889                     # change
01890                     num_chg += 1
01891                     next_href[last] = '<a href="#difflib_chg_%s_%d">n</a>' % (
01892                          toprefix,num_chg)
01893             else:
01894                 in_change = False
01895         # check for cases where there is no content to avoid exceptions
01896         if not flaglist:
01897             flaglist = [False]
01898             next_id = ['']
01899             next_href = ['']
01900             last = 0
01901             if context:
01902                 fromlist = ['<td></td><td>&nbsp;No Differences Found&nbsp;</td>']
01903                 tolist = fromlist
01904             else:
01905                 fromlist = tolist = ['<td></td><td>&nbsp;Empty File&nbsp;</td>']
01906         # if not a change on first line, drop a link
01907         if not flaglist[0]:
01908             next_href[0] = '<a href="#difflib_chg_%s_0">f</a>' % toprefix
01909         # redo the last link to link to the top
01910         next_href[last] = '<a href="#difflib_chg_%s_top">t</a>' % (toprefix)
01911 
01912         return fromlist,tolist,flaglist,next_href,next_id

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff._format_line (   self,
  side,
  flag,
  linenum,
  text 
) [private]
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

Definition at line 1832 of file difflib.py.

01832 
01833     def _format_line(self,side,flag,linenum,text):
01834         """Returns HTML markup of "from" / "to" text lines
01835 
01836         side -- 0 or 1 indicating "from" or "to" text
01837         flag -- indicates if difference on line
01838         linenum -- line number (used for line number column)
01839         text -- line text to be marked up
01840         """
01841         try:
01842             linenum = '%d' % linenum
01843             id = ' id="%s%s"' % (self._prefix[side],linenum)
01844         except TypeError:
01845             # handle blank lines where linenum is '>' or ''
01846             id = ''
01847         # replace those things that would get confused with HTML symbols
01848         text=text.replace("&","&amp;").replace(">","&gt;").replace("<","&lt;")
01849 
01850         # make space non-breakable so they don't get compressed or line wrapped
01851         text = text.replace(' ','&nbsp;').rstrip()
01852 
01853         return '<td class="diff_header"%s>%s</td><td nowrap="nowrap">%s</td>' \
01854                % (id,linenum,text)

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff._line_wrapper (   self,
  diffs 
) [private]
Returns iterator that splits (wraps) mdiff text lines

Definition at line 1783 of file difflib.py.

01783 
01784     def _line_wrapper(self,diffs):
01785         """Returns iterator that splits (wraps) mdiff text lines"""
01786 
01787         # pull from/to data and flags from mdiff iterator
01788         for fromdata,todata,flag in diffs:
01789             # check for context separators and pass them through
01790             if flag is None:
01791                 yield fromdata,todata,flag
01792                 continue
01793             (fromline,fromtext),(toline,totext) = fromdata,todata
01794             # for each from/to line split it at the wrap column to form
01795             # list of text lines.
01796             fromlist,tolist = [],[]
01797             self._split_line(fromlist,fromline,fromtext)
01798             self._split_line(tolist,toline,totext)
01799             # yield from/to line in pairs inserting blank lines as
01800             # necessary when one side has more wrapped lines
01801             while fromlist or tolist:
01802                 if fromlist:
01803                     fromdata = fromlist.pop(0)
01804                 else:
01805                     fromdata = ('',' ')
01806                 if tolist:
01807                     todata = tolist.pop(0)
01808                 else:
01809                     todata = ('',' ')
01810                 yield fromdata,todata,flag

Here is the call graph for this function:

Here is the caller graph for this function:

Create unique anchor prefixes

Definition at line 1855 of file difflib.py.

01855 
01856     def _make_prefix(self):
01857         """Create unique anchor prefixes"""
01858 
01859         # Generate a unique anchor prefix so multiple tables
01860         # can exist on the same HTML page without conflicts.
01861         fromprefix = "from%d_" % HtmlDiff._default_prefix
01862         toprefix = "to%d_" % HtmlDiff._default_prefix
01863         HtmlDiff._default_prefix += 1
01864         # store prefixes so line format method has access
01865         self._prefix = [fromprefix,toprefix]

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff._split_line (   self,
  data_list,
  line_num,
  text 
) [private]
Builds list of text lines by splitting text lines at wrap point

This function will determine if the input text line needs to be
wrapped (split) into separate lines.  If so, the first wrap point
will be determined and the first line appended to the output
text line list.  This function is used recursively to handle
the second part of the split line to further split it.

Definition at line 1728 of file difflib.py.

01728 
01729     def _split_line(self,data_list,line_num,text):
01730         """Builds list of text lines by splitting text lines at wrap point
01731 
01732         This function will determine if the input text line needs to be
01733         wrapped (split) into separate lines.  If so, the first wrap point
01734         will be determined and the first line appended to the output
01735         text line list.  This function is used recursively to handle
01736         the second part of the split line to further split it.
01737         """
01738         # if blank line or context separator, just add it to the output list
01739         if not line_num:
01740             data_list.append((line_num,text))
01741             return
01742 
01743         # if line text doesn't need wrapping, just add it to the output list
01744         size = len(text)
01745         max = self._wrapcolumn
01746         if (size <= max) or ((size -(text.count('\0')*3)) <= max):
01747             data_list.append((line_num,text))
01748             return
01749 
01750         # scan text looking for the wrap point, keeping track if the wrap
01751         # point is inside markers
01752         i = 0
01753         n = 0
01754         mark = ''
01755         while n < max and i < size:
01756             if text[i] == '\0':
01757                 i += 1
01758                 mark = text[i]
01759                 i += 1
01760             elif text[i] == '\1':
01761                 i += 1
01762                 mark = ''
01763             else:
01764                 i += 1
01765                 n += 1
01766 
01767         # wrap point is inside text, break it up into separate lines
01768         line1 = text[:i]
01769         line2 = text[i:]
01770 
01771         # if wrap point is inside markers, place end marker at end of first
01772         # line and start marker at beginning of second line because each
01773         # line will have its own table tag markup around it.
01774         if mark:
01775             line1 = line1 + '\1'
01776             line2 = '\0' + mark + line2
01777 
01778         # tack on first line onto the output list
01779         data_list.append((line_num,line1))
01780 
01781         # use this routine again to wrap the remaining text
01782         self._split_line(data_list,'>',line2)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff._tab_newline_replace (   self,
  fromlines,
  tolines 
) [private]
Returns from/to line lists with tabs expanded and newlines removed.

Instead of tab characters being replaced by the number of spaces
needed to fill in to the next tab stop, this function will fill
the space with tab characters.  This is done so that the difference
algorithms can identify changes in a file when tabs are replaced by
spaces and vice versa.  At the end of the HTML generation, the tab
characters will be replaced with a nonbreakable space.

Definition at line 1705 of file difflib.py.

01705 
01706     def _tab_newline_replace(self,fromlines,tolines):
01707         """Returns from/to line lists with tabs expanded and newlines removed.
01708 
01709         Instead of tab characters being replaced by the number of spaces
01710         needed to fill in to the next tab stop, this function will fill
01711         the space with tab characters.  This is done so that the difference
01712         algorithms can identify changes in a file when tabs are replaced by
01713         spaces and vice versa.  At the end of the HTML generation, the tab
01714         characters will be replaced with a nonbreakable space.
01715         """
01716         def expand_tabs(line):
01717             # hide real spaces
01718             line = line.replace(' ','\0')
01719             # expand tabs into spaces
01720             line = line.expandtabs(self._tabsize)
01721             # relace spaces from expanded tabs back into tab characters
01722             # (we'll replace them with markup after we do differencing)
01723             line = line.replace(' ','\t')
01724             return line.replace('\0',' ').rstrip('\n')
01725         fromlines = [expand_tabs(line) for line in fromlines]
01726         tolines = [expand_tabs(line) for line in tolines]
01727         return fromlines,tolines

Here is the caller graph for this function:

def MoinMoin.support.difflib.HtmlDiff.make_file (   self,
  fromlines,
  tolines,
  fromdesc = '',
  todesc = '',
  context = False,
  numlines = 5 
)
Returns HTML file of side by side comparison with change highlights

Arguments:
fromlines -- list of "from" lines
tolines -- list of "to" lines
fromdesc -- "from" file column header string
todesc -- "to" file column header string
context -- set to True for contextual differences (defaults to False
    which shows full differences).
numlines -- number of context lines.  When context is set True,
    controls number of lines displayed before and after the change.
    When context is False, controls the number of lines to place
    the "next" link anchors before the next change (so click of
    "next" link jumps to just before the change).

Definition at line 1682 of file difflib.py.

01682 
01683                   numlines=5):
01684         """Returns HTML file of side by side comparison with change highlights
01685 
01686         Arguments:
01687         fromlines -- list of "from" lines
01688         tolines -- list of "to" lines
01689         fromdesc -- "from" file column header string
01690         todesc -- "to" file column header string
01691         context -- set to True for contextual differences (defaults to False
01692             which shows full differences).
01693         numlines -- number of context lines.  When context is set True,
01694             controls number of lines displayed before and after the change.
01695             When context is False, controls the number of lines to place
01696             the "next" link anchors before the next change (so click of
01697             "next" link jumps to just before the change).
01698         """
01699 
01700         return self._file_template % dict(
01701             styles = self._styles,
01702             legend = self._legend,
01703             table = self.make_table(fromlines,tolines,fromdesc,todesc,
01704                                     context=context,numlines=numlines))

Here is the call graph for this function:

def MoinMoin.support.difflib.HtmlDiff.make_table (   self,
  fromlines,
  tolines,
  fromdesc = '',
  todesc = '',
  context = False,
  numlines = 5 
)
Returns HTML table of side by side comparison with change highlights

Arguments:
fromlines -- list of "from" lines
tolines -- list of "to" lines
fromdesc -- "from" file column header string
todesc -- "to" file column header string
context -- set to True for contextual differences (defaults to False
    which shows full differences).
numlines -- number of context lines.  When context is set True,
    controls number of lines displayed before and after the change.
    When context is False, controls the number of lines to place
    the "next" link anchors before the next change (so click of
    "next" link jumps to just before the change).

Definition at line 1914 of file difflib.py.

01914 
01915                    numlines=5):
01916         """Returns HTML table of side by side comparison with change highlights
01917 
01918         Arguments:
01919         fromlines -- list of "from" lines
01920         tolines -- list of "to" lines
01921         fromdesc -- "from" file column header string
01922         todesc -- "to" file column header string
01923         context -- set to True for contextual differences (defaults to False
01924             which shows full differences).
01925         numlines -- number of context lines.  When context is set True,
01926             controls number of lines displayed before and after the change.
01927             When context is False, controls the number of lines to place
01928             the "next" link anchors before the next change (so click of
01929             "next" link jumps to just before the change).
01930         """
01931 
01932         # make unique anchor prefixes so that multiple tables may exist
01933         # on the same page without conflict.
01934         self._make_prefix()
01935 
01936         # change tabs to spaces before it gets more difficult after we insert
01937         # markkup
01938         fromlines,tolines = self._tab_newline_replace(fromlines,tolines)
01939 
01940         # create diffs iterator which generates side by side from/to data
01941         if context:
01942             context_lines = numlines
01943         else:
01944             context_lines = None
01945         diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk,
01946                       charjunk=self._charjunk)
01947 
01948         # set up iterator to wrap lines that exceed desired width
01949         if self._wrapcolumn:
01950             diffs = self._line_wrapper(diffs)
01951 
01952         # collect up from/to lines and flags into lists (also format the lines)
01953         fromlist,tolist,flaglist = self._collect_lines(diffs)
01954 
01955         # process change flags, generating middle column of next anchors/links
01956         fromlist,tolist,flaglist,next_href,next_id = self._convert_flags(
01957             fromlist,tolist,flaglist,context,numlines)
01958 
01959         s = []
01960         fmt = '            <tr><td class="diff_next"%s>%s</td>%s' + \
01961               '<td class="diff_next">%s</td>%s</tr>\n'
01962         for i in range(len(flaglist)):
01963             if flaglist[i] is None:
01964                 # mdiff yields None on separator lines skip the bogus ones
01965                 # generated for the first line
01966                 if i > 0:
01967                     s.append('        </tbody>        \n        <tbody>\n')
01968             else:
01969                 s.append( fmt % (next_id[i],next_href[i],fromlist[i],
01970                                            next_href[i],tolist[i]))
01971         if fromdesc or todesc:
01972             header_row = '<thead><tr>%s%s%s%s</tr></thead>' % (
01973                 '<th class="diff_next"><br /></th>',
01974                 '<th colspan="2" class="diff_header">%s</th>' % fromdesc,
01975                 '<th class="diff_next"><br /></th>',
01976                 '<th colspan="2" class="diff_header">%s</th>' % todesc)
01977         else:
01978             header_row = ''
01979 
01980         table = self._table_template % dict(
01981             data_rows=''.join(s),
01982             header_row=header_row,
01983             prefix=self._prefix[1])
01984 
01985         return table.replace('\0+','<span class="diff_add">'). \
01986                      replace('\0-','<span class="diff_sub">'). \
01987                      replace('\0^','<span class="diff_chg">'). \
01988                      replace('\1','</span>'). \
01989                      replace('\t','&nbsp;')

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 1679 of file difflib.py.

Definition at line 1662 of file difflib.py.

Definition at line 1658 of file difflib.py.

Definition at line 1661 of file difflib.py.

Definition at line 1678 of file difflib.py.

Definition at line 1864 of file difflib.py.

Definition at line 1659 of file difflib.py.

Definition at line 1660 of file difflib.py.

Definition at line 1676 of file difflib.py.

Definition at line 1677 of file difflib.py.


The documentation for this class was generated from the following file: