o k`Q5@sddlZddlZddlmZmZddlmZgdZedej j Z ddZ dd Z  dd d Zdd dZddZ  dddZ dddZddZdS)N)Markupescape) expandtabs) diff_blocksget_change_extentget_diff_options unified_diffz\s+cCsdt|S)N )join_whitespace_split)textr :/usr/lib/python3/dist-packages/trac/versioncontrol/diff.py_norm_space_changessrcCsd}tt|t|}||kr'||||kr'|d7}||kr'||||ksd}||}| |krK||||krK|d8}| |krK||||ks:||dfS)a Determines the extent of differences between two strings. Returns a pair containing the offset at which the changes start, and the negative offset at which the changes end. If the two strings have neither a common prefix nor a common suffix, ``(0, 0)`` is returned. r)minlen)str1str2startlimitendr r rr!s  rFcCsh|rttt|}ttt|}|r dd|D}dd|D}t|||}|r2t|||||dd}|S)aTRetrieve differences in the form of `difflib.SequenceMatcher` opcodes, grouped according to the ``context`` and ``ignore_*`` parameters. :param fromlines: list of lines corresponding to the old content :param tolines: list of lines corresponding to the new content :param ignore_blank_lines: differences about empty lines only are ignored :param ignore_case: upper case / lower case only differences are ignored :param ignore_space_changes: differences in amount of spaces are ignored :param context: the number of "equal" lines kept for representing the context of the change :return: generator of grouped `difflib.SequenceMatcher` opcodes If none of the ``ignore_*`` parameters is `True`, there's nothing to filter out the results will come straight from the SequenceMatcher. cSg|]}|qSr lower.0lr r r Mz&get_filtered_hunks..cSrr rrr r rrNr F)listmapr get_hunksfilter_ignorable_lines) fromlinestolinescontextignore_blank_lines ignore_caseignore_space_changeshunksr r rget_filtered_hunks5s  r,cCs4td||}|durdd|fDS||S)z~Generator yielding grouped opcodes describing differences . See `get_filtered_hunks` for the parameter descriptions. Ncss|]}|VqdSNr )rhunkr r r ]szget_hunks..)difflibSequenceMatcher get_opcodesget_grouped_opcodes)r%r&r'matcherr r rr#Vs r#c #sfdd}t|}g}d} d} |D]_} | D]Z\} } }}}| dkr:| r2| | d|| d|f} q| | |||f} q|| || ||||r`d} | rXd| d|| d|f} nd| |||f} q| rg|| || | |||fd} qq| r||| | rB|dur|VdS|}||}gfd d }t|D]`\}\} } }}}|d kr| dkrt| ||t|||} }n5| dkr|| |kr| | t|| ||t|||f|s߈Vgt| ||t|||} }| | |||fqrd d dkr3d \} } }}}| | t|| ||t|||fd <|s@VdSdSdSdS|D]} | VqDdS) zDetect line changes that should be ignored and emits them as tagged as "equal", possibly joined with the preceding and/or following "equal" block. See `get_filtered_hunks` for the parameter descriptions. csr|dkr t| S|dkrt| SsrI|dkrGt|t|kr&dSfdd}tt|D]}||||||krDdSq3dSdSdS)NdeleteinsertreplaceFcsr|}r t|}|Sr-)rr)value)r)r*r rfts z7filter_ignorable_lines..is_ignorable..fT)anyrrange)tagr%r&r9i)r(r)r*r r is_ignorableks  z,filter_ignorable_lines..is_ignorableFNequalrTcstddDdS)Ncss|] }|ddkVqdS)rr?Nr )ropr r rr/sz.all_equal..)allr )groupr r all_equalsz)filter_ignorable_lines..all_equalrr)r!append enumeratemaxrr)r+r%r&r'r(r)r*r>opcodes ignored_linesprevr.r<i1i2j1j2nnnrDidxr )rCr(r)r*rr$bsn       &&  r$c sBddddd}tdddfd d }g} t||||D]} g} d } || D]\} }}}}| | krH| || |gd |gd d | dkr||D] }||}t|dd}| dddtt|qR||D] }||}t|dd}| dddtt|qyq,| dvrو||D]3}t||d}t|dd}d fdd| dD}| dd}| dddtt|q| dvr||D]3}t||d}t|dd}d fdd| dD}| dd }| dddtt|qq,| | q"| S)!zReturn an array that is adequate for adding to the data dictionary See `get_filtered_hunks` for the parameter descriptions. See also the diff_div.html template. modremaddunmod)r7r5r6r?z ( +)|^ cSs,tt|dd\}}t|d|dS)Nrz  z )divmodrrCr)matchdivrSr r rhtmlifyszdiff_blocks..htmlifyc 3s |D]\}}}}}|dkr{||||kr{t||D]^}||||}}t||\} } | dks:| dkrz| t|} |d| d|| | d|| d||<| t|} |d| d|| | d|| d||<q|||||fVqdS)Nr7r)r;rr) rHr<rKrLrMrNr=fromlinetolinerrlast)r%r&r rmarkup_intraline_changess0     z-diff_blocks..markup_intraline_changesN)offsetlines)typebasechangedr?F)quotesrrercrfr7r5zzc3|] }|VqdSr-subrsegr[space_rer rr/zdiff_blocks..r\r]zr7r6zc3rir-rjrlrnr rr/rpz) recompiler,rErrkrrstrr splitr7)r%r&r'tabwidthr(r)r*type_maprachangesrCblockslast_tagr<rKrLrMrNliner )r%r[ror&rrsl                 rc cst||||||D]z}|dd|dd|dd|ddf\}}} } |dkr2|dkr2d\}}d|d||| d| | fV|D]>\} }}} } | d kr_|||D]} d | VqVqE| d vrq|||D]} d | Vqi| d vr|| | D]} d| Vq{qEq dS)z}Generator producing lines corresponding to a textual diff. See `get_filtered_hunks` for the parameter descriptions. rrrrWr@)rrz@@ -%d,%d +%d,%d @@r?r rh-rq+N)r,) r%r&r'r(r)r*rCrKrLrMrNr<r{r r rr s.4"   rc s2i}d|i}dfdd }jdd}jd|}djvr,||kr,jd|d||d<jd d }jd |}djvrO||krOjd |d ||d <jd d}||d <d |rcdn|g}|d}|rr|d||d<|d}|r|d||d<|d}|r|d||d<|||fS)aRetrieve user preferences for diffs. :return: ``(style, options, data)`` triple. ``style`` can be ``'inline'`` or ``'sidebyside'``, ``options`` a sequence of "diff" flags, ``data`` the style and options information represented as key/value pairs in dictionaries, for example:: {'style': 'sidebyside', 'options': {'contextall': 1, 'contextlines': 2, 'ignorecase': 0, 'ignoreblanklines': 0, 'ignorewhitespace': 1}} optionsrcsRjd||}t|jv}djvr%||kr%jd||||S|}|S)Ndiff_update)sessionas_intintargsset)namedefaultprefargreqr rget_bool_option9sz)get_diff_options..get_bool_option diff_styleinlinestylerdiff_contextlinesrW contextlines contextallz-U%drignoreblanklinesz-B ignorecasez-iignorewhitespacez-bN)r)rgetrrrrE) r options_datadatarrrr'rrr rrr#s:     r)NFFFr-)NrRrrr)Nrrr)r0rrtrac.util.htmlrrtrac.util.textr__all__rsUNICODErur rrr,r#r$rrrr r r rs*  ! Z M