/usr/lib/python3/dist-packages/lxml/html/__pycache__
NameSizeModeActions
builder.cpython-310.pyc29170644editdlrm
clean.cpython-310.pyc176780644editdlrm
defs.cpython-310.pyc27910644editdlrm
diff.cpython-310.pyc240530644editdlrm
ElementSoup.cpython-310.pyc4900644editdlrm
formfill.cpython-310.pyc73630644editdlrm
html5parser.cpython-310.pyc63930644editdlrm
soupparser.cpython-310.pyc79930644editdlrm
usedoctest.cpython-310.pyc4160644editdlrm
_diffcommand.cpython-310.pyc22760644editdlrm
_html5builder.cpython-310.pyc35820644editdlrm
_setmixin.cpython-310.pyc20750644editdlrm
__init__.cpython-310.pyc564330644editdlrm
Edit: /usr/lib/python3/dist-packages/lxml/html/__pycache__/diff.cpython-310.pyc (24053B)
o ;/bYw@sddlmZddlZddlmZddlmZddlZddgZzddl m Z Wne y5ddl m Z YnwzeZWn eyEeZYnwzeWn eyUeZYnwdd Zefd dZd d Zd dZddZddZddZddZddZddZdiddZddZGdd d ZGd!d"d"Z Gd#d$d$e!Z"d%d&Z#d'd(Z$d)d*Z%d+d,Z&d-d.Z'd/d0Z(Gd1d2d2eZ)Gd3d4d4e)Z*Gd5d6d6e)Z+djd8d9Z,djd:d;Z-e.dej/ej0BZ3d?d@Z4e.dAZ5dBdCZ6dDdEZ7dFZ8dGZ9dHZ:didIdJZ;e.dKej<Z=dLdMZ>e.dNZ?dOdPZ@dQdRZAdSdTZBdUdVZCdWdXZDdYdZZEdid[d\ZFd]d^ZGd_d`ZHdadbZIdcddZJGdedfdfejKZLeMdgkrjddhlmNZNeNOdSdS)k)absolute_importN)etree)fragment_fromstring html_annotatehtmldiff)escapecCsdtt|d|fS)Nz%s) html_escape_unicode)textversionr 0/usr/lib/python3/dist-packages/lxml/html/diff.pydefault_markupsrcCsVdd|D}|d}|ddD] }t|||}qt|}t||}d|S)a doclist should be ordered from oldest to newest, like:: >>> version1 = 'Hello World' >>> version2 = 'Goodbye World' >>> print(html_annotate([(version1, 'version 1'), ... (version2, 'version 2')])) Goodbye World The documents must be *fragments* (str/UTF8 or unicode), not complete documents The markup argument is a function to markup the spans of words. This function is called like markup('Hello', 'version 2'), and returns HTML. The first argument is text and never includes any markup. The default uses a span with a title: >>> print(default_markup('Some Text', 'by Joe')) Some Text cSsg|] \}}t||qSr )tokenize_annotated).0docr r r r =sz!html_annotate..rrN)html_annotate_merge_annotationscompress_tokensmarkup_serialize_tokensjoinstrip)doclistmarkup tokenlist cur_tokenstokensresultr r rr#s  cCs t|dd}|D]}||_q|S)zFTokenize a document and add an annotation attribute to each token F include_hrefs)tokenize annotation)rr#rtokr r rrKs rc CsVt||d}|}|D]\}}}}}|dkr(|||} |||} t| | q dS)zMerge the annotations from tokens_old into tokens_new, when the tokens in the new document already existed in the old document. abequalN)InsensitiveSequenceMatcher get_opcodescopy_annotations) tokens_old tokens_newscommandscommandi1i2j1j2eq_oldeq_newr r rrSs    rcCs4t|t|ks Jt||D]\}}|j|_qdS)zN Copy annotations from the tokens listed in src to the tokens in dest N)lenzipr#)srcdestsrc_tokdest_tokr r rr+`s r+cCsV|dg}|ddD]}|djs#|js#|dj|jkr#t||q ||q |S)zm Combine adjacent tokens when there is no HTML between the tokens, and they share an annotation rrN) post_tagspre_tagsr#compress_merge_backappend)rrr$r r rrhs    rcCsx|d}t|tust|tur||dSt|}|jr#||j7}||7}t||j|j|jd}|j|_||d<dS)zY Merge tok into the last element of tokens (modifying the list of tokens in-place). r=r?r>trailing_whitespaceN)typetokenrAr rCr?r>r#)rr$lastr mergedr r rr@ws  r@ccs^|D])}|jD]}|Vq|}|||j}|jr ||j7}|V|jD]}|Vq&qdS)zz Serialize the list of tokens into a list of text chunks, calling markup_func around text to add annotations. N)r?htmlr#rCr>)r markup_funcrEprerHpostr r rrs    rcCs0t|}t|}t||}d|}t|S)a Do a diff of the old and new document. The documents are HTML *fragments* (str/UTF8 or unicode), they are not complete documents (i.e., no tag). Returns HTML with and tags added around the appropriate text. Markup is generally ignored, with the markup from new_html preserved, and possibly some markup from old_html (though it is considered acceptable to lose some of the old markup). Only the words in the HTML are diffed. The exception is tags, which are treated like words, and the href attribute of tags, which are noted inside the tag itself when there are changes. r)r"htmldiff_tokensrrfixup_ins_del_tags)old_htmlnew_htmlold_html_tokensnew_html_tokensrr r rrs  c Cst||d}|}g}|D]C\}}}}} |dkr'|t||| ddq|dks/|dkr)rr(rErJrKr r rrVs    rVcCst|\}}}|||r|dds|dd7<|d|r5|ddr5|ddd|d<|||d||dS)z| doc is the already-handled document (as a list of text chunks); here we add ins_chunks to the end of that. r= zNz )split_unbalancedrUendswithrA) ins_chunksrunbalanced_startbalancedunbalanced_endr r rrWs    rWc@ eZdZdS) DEL_STARTN__name__ __module__ __qualname__r r r rrgrgc@rf)DEL_ENDNrhr r r rrmrlrmc@seZdZdZdS) NoDeleteszY Raised when the document no longer contains any pending deletes (DEL_START/DEL_END) N)rirjrk__doc__r r r rrnsrncCs"|t|||tdS)z Adds the text chunks in del_chunks to the document doc (another list of text chunks) with marker to show it is a delete. cleanup_delete later resolves these markers into tags.N)rArgrUrm) del_chunksrr r rrX s  rXcCs z t|\}}}Wn tyY|Swt|\}}}t|||t||||}|r;|dds;|dd7<|d|rS|ddrS|ddd|d<|||d|||}q)a Cleans up any DEL_START/DEL_END markers in the document, replacing them with . To do this while keeping the document valid, it may need to drop some tags (either start or end tags). It may also move the del into adjacent tags to try to move it to a similar location where it was originally located (e.g., moving a delete into preceding
tag, if the del looks like (DEL_START, 'Text
', DEL_END)rr=r_zNz ) split_deleternr`locate_unbalanced_startlocate_unbalanced_endrarArU)chunks pre_deleterT post_deletercrdrerr r rrYs*        rYc Csg}g}g}g}|D]l}|ds||q |ddk}|dd}|tvr0||q |rg|rM|dd|krM|||\}}} | ||<q |ra|dd|Dg}||q ||q ||t||f|d q |d d|Dd d|D}|||fS) a]Return (unbalanced_start, balanced, unbalanced_end), where each is a list of text and tag chunks. unbalanced_start is a list of all the tags that are opened, but not closed in this span. Similarly, unbalanced_end is a list of tags that are closed but were not opened. Extracting these might mean some reordering of the chunks./r=cSg|]\}}}|qSr r )rnamepostagr r rrTz$split_unbalanced..NcSrzr r )rr{r|chunkr r rr]r~cSsg|]}|dur|qSNr )rrr r rr^s) startswithrAsplitr empty_tagspoprUr7) rtstartend tag_stackrdrendtagr{r|r}r r rr`9s<           r`cCsVz|t}Wn tytw|t}|d|||d|||ddfS)z Returns (stuff_before_DEL_START, stuff_inside_DEL_START_END, stuff_after_DEL_END). Returns the first case found (there may be more DEL_STARTs in stuff_after_DEL_END). Raises NoDeletes if there's no DEL_START found. Nr)indexrg ValueErrorrnrm)rtr|pos2r r rrqas  *rqcCs |sd S|d}|dd}|sd S|d}|tus#|ds%d S|ddkr-d S|dd}|dkr>> unbalanced_start = ['
'] >>> doc = ['

', 'Text', '

', '
', 'More Text', '
'] >>> pre, post = doc[:3], doc[3:] >>> pre, post (['

', 'Text', '

'], ['
', 'More Text', '
']) >>> locate_unbalanced_start(unbalanced_start, pre, post) >>> pre, post (['

', 'Text', '

', '
'], ['More Text', '
']) As you can see, we moved the point so that the dangling
that we found will be effectively replaced by the div in the original document. If this doesn't work out, we just throw away unbalanced_start without doing anything. rrz<>rwrxinsdelzUnexpected delete tag: %rN)rrrgrrrA)rcrurvfinding finding_namenextr{r r rrrms.   rrcCs |sdS|d}|dd}|sdS|d}|tus#|ds%dS|dd}|dks6|dkr8dS||krI||d|ndSq) zt like locate_unbalanced_start, except handling end tags and possibly moving the point earlier in the document. rr=rryrC)clsr r?r>rCobjr r rrs z token.__new__cCsdt||j|j|jfS)Nztoken(%s, %r, %r, %r))r __repr__r?r>rCselfr r rrsztoken.__repr__cCst|Sr)r rr r rrHz token.htmlNNr)rirjrkror^rrrHr r r rrEs   rEc@s.eZdZdZ  d ddZddZdd ZdS) tag_tokenz Represents a token that is actually a tag. Currently this is just the tag, which takes up visible space just like a word but is only represented in a document by a tag. NrcCs2tj|dt|f|||d}||_||_||_|S)Nz%s: %srB)rErrDr}data html_repr)rr}rrr?r>rCrr r rrsztag_token.__new__cCs d|j|j|j|j|j|jfS)NzRtag_token(%s, %s, html_repr=%s, post_tags=%r, pre_tags=%r, trailing_whitespace=%r))r}rrr?r>rCrr r rrsztag_token.__repr__cCs|jSr)rrr r rrHsztag_token.htmlr)rirjrkrorrrHr r r rrs  rc@eZdZdZdZddZdS) href_tokenzh Represents the href in an anchor tag. Unlike other words, we only show the href when it changes. TcCsd|S)Nz Link: %sr rr r rrHrzhref_token.htmlN)rirjrkror^rHr r r rrs rTcCs2t|r|}nt|dd}t|d|d}t|S)ak Parse the given HTML and returns token objects (words with attached tags). This parses only the content of a page; anything in the head is ignored, and the and elements are themselves optional. The content is then parsed by lxml, which ensures the validity of the resulting parsed document (though lxml may make incorrect guesses when the markup is particular bad). and tags are also eliminated from the document, as that gets confusing. If include_hrefs is true, then the href attribute of tags is included as a special kind of diffable token.Tcleanup)skip_tagr!)r iselement parse_html flatten_el fixup_chunks)rHr!body_elrtr r rr"s  r"cCs|rt|}t|ddS)a Parses an HTML fragment, returning an lxml element. Note that the HTML will be wrapped in a
tag that was not in the original document. If cleanup is true, make sure there's no or , and get rid of any and tags. T) create_parent) cleanup_htmlr)rHrr r rr s rz z zcCsLt|}|r||d}t|}|r|d|}td|}|S)z This 'cleans' the HTML, meaning that any page structure is removed (only the contents of are used, if there is any and tags are removed. Nr)_body_researchr _end_body_rer _ins_del_resub)rHmatchr r rr1s   rz [ \t\n\r]$cCs$t|}|d|||dfS)zP This function takes a word, such as 'test ' and returns ('test',' ') rN)r7rstrip)wordstripped_lengthr r rsplit_trailing_whitespaceAs rc CsDg}d}g}|D]}t|trK|ddkr2|d}t|d\}}td||||d}g}||n|ddkrJ|d}t||dd }g}||qt|rdt|\}}t|||d }g}||qt|rn||qt |r|rz||q|sJd ||||f|j |qJ|std |d gS|dj ||S)zM This function takes a list of chunks and produces a list of tokens. Nrimgr)rr?rChrefr_)r?rCz4Weird state, cur_word=%r, result=%r, chunks=%r of %rFr)r?r=) isinstancetuplerrrAris_wordrE is_start_tag is_end_tagr>rU) rt tag_accumcur_wordrrr9r}rCrr r rrIsR          r) paramrareabrbasefontinputbasemetalinkcol)address blockquotecenterdirdivdlfieldsetformh1h2h3h4h5h6hrisindexmenunoframesnoscriptolprJtableul) dddtframesetlitbodytdtfootththeadtrccs|s|jdkrd|dt|fVnt|V|jtvr*|js*t|s*|js*dSt|j}|D]}t|Vq1|D]}t ||dD]}|VqCq;|jdkr^|dr^|r^d|dfV|stt |Vt|j}|D] }t|VqldSdS)a Takes an lxml element el, and generates all the text chunks for that tag. Each start tag is a chunk, each word is a chunk, and each end tag is a chunk. If skip_tag is true, then the outermost container tag is not returned (just its contents).rr9Nr r&r) r}get start_tagrr r7tail split_wordsr rend_tag)elr!r start_wordsrchilditem end_wordsr r rrs.       rz \S+(?:\s+|$)cCs|r|sgSt|}|S)z_ Splits some text into words. Includes trailing whitespace on each word when appropriate. )rsplit_words_refindall)r wordsr r rrs  rz ^[ \t\n\r]cCs$d|jddd|jDfS)z= The text representation of the start tag for a tag. z<%s%s>rcSs"g|] \}}d|t|dfqS)z %s="%s"T)r )rr{valuer r rrszstart_tag..)r}rattribitems)rr r rrs rcCs*|jr t|jr d}nd}d|j|fS)zg The text representation of an end tag for a tag. Includes trailing whitespace when appropriate. r_rz%s)rstart_whitespace_rerr})rextrar r rrsrcCs |d S)Nrwrr$r r rrs rcCs |dS)Nrrrr r rrs rcCs|do |d S)Nrwrrrr r rrsrcCs$t|dd}t|t|dd}|S)z Given an html string, move any or tags inside of any block-level elements, e.g. transform

word

to

word

FrT) skip_outer)r_fixup_ins_del_tagsserialize_html_fragment)rHrr r rrMs  rMcCs^t|tr Jd|tj|dtd}|r-||ddd}|d|d}|S|S)z Serialize a single lxml element as HTML. The serialized form includes the elements tail. If skip_outer is true, then don't serialize the outermost tag z3You should pass in an element, not a string like %rrH)methodencoding>rNrw)r basestringrtostringr findrfindr)rrrHr r rrs rcCs@dD]}|d|D]}t|sq t||d|q qdS)z?fixup_ins_del_tags that works on an lxml document in-place )rrzdescendant-or-self::%s)r}N)xpath_contains_block_level_tag_move_el_inside_blockdrop_tag)rr}rr r rr s  rcCs4|jtvs |jtvr dS|D] }t|rdSqdS)zPTrue if the element contains any block-level elements, like

, , etc. TF)r}block_level_tagsblock_level_container_tagsr)rrr r rrsrcCs|D]}t|r nqt|}|j|_d|_|t||g|dd<dSt|D]6}t|rQt|||jrPt|}|j|_d|_|| |d|q+t|}| ||| |q+|jryt|}|j|_d|_|d|dSdS)zt helper for _fixup_ins_del_tags; actually takes the etc tags and moves them inside any block-level tags. Nrr) rrElementr rUlistrrrRrrSrA)rr}r children_tagtail_tag child_tagtext_tagr r rrs8        rcCs|}|jpd}|jr,t|s||j7}n|djr&|dj|j7_n|j|d_||}|ra|dkr:d}n||d}|durS|jrO|j|7_n||_n|jr^|j|7_n||_||||d<dS)z Removes an element, but merges its contents into its place, e.g., given

Hi there!

, if you remove the element you get

Hi there!

rr=rNr) getparentr rr7r getchildren)rparentr rpreviousr r r_merge_element_contents?s*      rc@r)r)zt Acts like SequenceMatcher, but tries not to find very small equal blocks amidst large spans of changes rcsDtt|jt|j}t|j|dtj|}fdd|DS)Ncs$g|]}|dks|ds|qS)rr )rr thresholdr rrms  zBInsensitiveSequenceMatcher.get_matching_blocks..)minr7r'rdifflibSequenceMatcherget_matching_blocks)rsizeactualr rrris z.InsensitiveSequenceMatcher.get_matching_blocksN)rirjrkrorrr r r rr)as r)__main__) _diffcommand)F)T)P __future__rrlxmlr lxml.htmlrre__all__rHrr ImportErrorcgiunicoder NameErrorstrrrrrrr+rr@rrrLrVrWrgrm ExceptionrnrXrYr`rqrrrsrErrr"rcompileISrrrrend_whitespace_rerrrr r rUrrrrrrrrrMrrrrrrr)rir mainr r r rs       (  &'( 2)   6       "