o
    e¨n  ã                   @   s˜  d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZmZmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZmZ g d	¢ZG d
d„ deƒZG dd„ deƒZG dd„ deƒZdd„ Zdd„ Z eƒ d(dd„ƒZ!eƒ dd„ ƒZ"dd„ Z#e $d¡Z%e $dej&¡Z'e $dej(ej)B ¡Z*e $d¡Z+e $dej,¡Z-g d ¢Z.G d!d"„ d"e/ƒZ0d)d$d%„Z1e2d&krÊd'Ze0eƒZ3e4e3 1¡ ƒ dS dS )*é    N)ÚOrderedDict)ÚescapeÚunescape)ÚurljoinÚurlparseÚunquote)Úetree©ÚCSSSelector)Úfunction_cache)Úcsstext_to_pairsÚmerge_styles)ÚPremailerErrorÚ	PremailerÚ	transformc                   @   ó   e Zd ZdS )r   N©Ú__name__Ú
__module__Ú__qualname__© r   r   úCD:\Projects\ConvertPro\env\Lib\site-packages\premailer/premailer.pyr      ó    r   c                   @   r   )ÚExternalNotFoundErrorNr   r   r   r   r   r      r   r   c                   @   r   )ÚExternalFileLoadingErrorNr   r   r   r   r   r      r   r   c                 C   s   d  dd„ |  d¡D ƒ¡S )z,makes every property in a string !important.ú;c                 s   s&    | ]}|  d ¡sd| n|V  qdS )ú
!importantz%s !importantN)Úendswith)Ú.0Úpr   r   r   Ú	<genexpr>$   s
   € ÿ
ÿz!make_important.<locals>.<genexpr>)ÚjoinÚsplit)Úbulkr   r   r   Úmake_important"   s   
þr$   c                 C   sF   t dƒ| ƒ}|st d¡}t dƒ| ƒd }| ¡  d|¡ |S |d S )z=Ensures that `root` contains a <head> element and returns it.ÚheadÚbodyr   )Ú_create_cssselectorr   ÚElementÚ	getparentÚinsert)Úrootr%   r&   r   r   r   Úget_or_create_head*   s   
r,   Tc                 C   s   t j| |dS )aÆ  
    This function will cache the result from cssutils
    It is a big gain when number of rules is big
    Maximum cache entries are 1000. This is mainly for
    protecting memory leak in case something gone wild.
    Be aware that you can turn the cache off in Premailer

    Args:
        css_body(str): css rules in string format
        validate(bool): if cssutils should validate

    Returns:
        cssutils.css.cssstylesheet.CSSStyleSheet

    ©Úvalidate)ÚcssutilsÚparseString)Úcss_bodyr.   r   r   r   Ú_cache_parse_css_string6   s   r2   c                 C   s   t | ƒS ©Nr	   )Úselectorr   r   r   r'   J   s   r'   c                 C   s   dd„ }t  || ¡S )z.Capitalize float and margin CSS property namesc                 S   s$   d  |  d¡ ¡ |  d¡|  d¡¡S )Nz
{0}:{1}{2}ÚpropertyÚvalueÚ
terminator)ÚformatÚgroupÚ
capitalize©Úmatchr   r   r   Ú_capitalize_propertyR   s
   ýz5capitalize_float_margin.<locals>._capitalize_property)Ú_lowercase_margin_float_ruleÚsub)r1   r=   r   r   r   Úcapitalize_float_marginO   s   r@   z(^|\s)\wz\<\!\[CDATA\[(.*?)\]\]\>zr(?P<property>margin(-(top|bottom|left|right))?|float)
        :
        (?P<value>.*?)
        (?P<terminator>$|;)z\s*!importantz!^#([0-9a-f])([0-9a-f])([0-9a-f])$)z:last-childz:first-childú
:nth-childc                   @   s¤   e Zd ZdZ																												ddd„Zddd	„Zd
d„ Zddd„Zdd„ Zdd„ Z	e
dd„ ƒZddd„Zdd„ Zdd„ ZdS )r   zdata-premailerNFTÚhtmlc                 C   sô   || _ || _|| _|| _|| _|| _|| _|| _|
| _|| _	|	| _
t|tƒr)|g}|| _t|tƒr4|g}|| _|| _|| _|| _|d u rFg }|| _|| _|| _|| _|| _|| _|| _|| _|| _|pdt| _|rntj |¡ |rxtj  |¡ d S d S r3   )!rB   Úbase_urlÚdisable_link_rewritesÚpreserve_internal_linksÚpreserve_inline_attachmentsÚpreserve_handlebar_syntaxÚexclude_pseudoclassesÚkeep_style_tagsÚremove_classesr@   Úinclude_star_selectorsÚ
isinstanceÚstrÚexternal_stylesÚcss_textÚstrip_importantÚmethodÚ	base_pathÚdisable_basic_attributesÚdisable_validationÚcache_css_parsingÚdisable_leftover_cssÚalign_floating_imagesÚremove_unset_propertiesÚallow_networkÚallow_insecure_sslÚallow_loading_external_filesÚrequestsÚsessionr/   ÚlogÚ
addHandlerÚsetLevel)ÚselfrB   rC   rD   rE   rF   rG   rH   rI   rK   rJ   r@   rP   rN   rO   rQ   rR   rS   rT   rU   Zcssutils_logging_handlerZcssutils_logging_levelrV   rW   rX   rY   rZ   r[   r]   r   r   r   Ú__init__r   sJ   


ÿzPremailer.__init__c                 C   s    | j r	t||dS tj||dS )Nr-   )rU   r2   r/   r0   )ra   r1   r.   r   r   r   Ú_parse_css_stringÄ   s   zPremailer._parse_css_stringc              
      s’  ‡fdd„‰ ‡ fdd„}g }g }|s||fS ˆj |ˆj d}|D ]£}|j|jkr/| |¡ q!|j|jkr6q!dd„ |j ¡ D ƒ}dd„ |j ¡ D ƒ}	||ƒ}
||	ƒ}|||	 ƒ}d	d
„ |j 	d¡D ƒ}|D ]^}d|v r‚ˆj
r‚d| 	dd¡d  tvr‚| ||f¡ qed|v rŠˆjsŠqe| d¡rqe| d¡}| d¡}tt |¡ƒ}d|fd|
ffD ]\}}|s°q©|||||t|ƒf}| |||f¡ q©qeq!||fS )aA  Returns a list of rules to apply to this doc and a list of rules
        that won't be used because e.g. they are pseudoclasses. Rules
        look like: (specificity, selector, bulk)
        for example: ((0, 1, 0, 0, 0), u'.makeblue', u'color:blue').
        The bulk of the rule should not end in a semicolon.
        c                    s0   ˆ j s| jdkrd | j| j¡S d | j| j¡S )NÚ	importantz{0}:{1}z{0}:{1} !important)rP   Úpriorityr8   Únamer6   )Úprop)ra   r   r   Úformat_css_propertyÒ   s   z9Premailer._parse_style_rules.<locals>.format_css_propertyc                    s   d  ‡ fdd„| D ƒ¡S )z‘Accepts a list of cssutils Property objects and returns
            a semicolon delimitted string like 'color: red; font-size: 12px'
            r   c                 3   s    | ]}ˆ |ƒV  qd S r3   r   ©r   rg   ©rh   r   r   r    Ü   s   € zLPremailer._parse_style_rules.<locals>.join_css_properties.<locals>.<genexpr>)r!   )Ú
propertiesrj   r   r   Újoin_css_propertiesØ   s   z9Premailer._parse_style_rules.<locals>.join_css_propertiesr-   c                 S   s   g | ]	}|j d kr|‘qS ©rd   ©re   ri   r   r   r   Ú
<listcomp>î   ó
    
þz0Premailer._parse_style_rules.<locals>.<listcomp>c                 S   s   g | ]	}|j d kr|‘qS rm   rn   ri   r   r   r   ro   ó   rp   c                 s   s.    | ]}|  ¡ r|  ¡  d ¡s|  ¡ V  qdS )ú@N)ÚstripÚ
startswith©r   Úxr   r   r   r    ÿ   s   € ýý
ÿz/Premailer._parse_style_rules.<locals>.<genexpr>ú,ú:é   Ú*ú#Ú.r   )rc   rT   ÚtypeZ
MEDIA_RULEÚappendZ
STYLE_RULEÚstyleZgetPropertiesZselectorTextr"   rH   ÚFILTER_PSEUDOSELECTORSrK   rs   ÚcountÚlenÚ_element_selector_regexÚfindall)ra   r1   Zruleset_indexrl   ÚleftoverÚrulesZsheetÚruleZnormal_propertiesZimportant_propertiesZbulk_normalZbulk_importantZbulk_allÚ	selectorsr4   Zid_countZclass_countZelement_countZis_importantr#   Zspecificityr   )rh   ra   r   Ú_parse_style_rulesÊ   sj   
þþ
þÿ


úôé%zPremailer._parse_style_rulesc           )      K   sP  |dur| j durtdƒ‚|du r| j du rtdƒ‚|du r!| j }t|dƒr/| ¡ }|}|}n8| jdkr<tjddd}nt ¡ }| ¡ }| j	rPt
 dd	d
„ |¡}t ||¡ ¡ }| ¡ }| |jj¡re|n|}|dusmJ ‚| jrsd}	nt|ƒ}	g }
d}dg}| jr†| d¡ td |¡ƒ|ƒD ]­}|j d¡}|rž|dvržq|j | j¡}|r»|dkr±|j| j= qt d| j|f ¡ |jdk}|rÆ|j}n|j d¡}|  |¡}|  ||¡\}}|d7 }|
  |¡ | !¡ }|sì| j"r0|rñ|}n
t #d¡}d|jd< | j"r||_n|  $|¡|_| j%rt& d|j¡|_| jdkr"t '|j¡|_|s/| (|¡ | )|¡ q| j"r7|s<| )|¡ q| j*r]| jr]| j*D ]}|  |¡}|  +|||
|	¡ |d7 }qH| j,rt| j,D ]}|  +|||
|	¡ |d7 }qd|
j-t. /d¡d i }|
D ]o\}}}|}d}d|v rœt
 0d|d¡\}}d| }|t1v s§| d¡rªd}n|}|s±J ‚t|ƒ}||ƒ}t2|ƒrït3|| j4 d}|D ]&} t5| ƒ}!|!|vrÛ| g g dœ||!< ||! d  |¡ ||! d  |¡ qÈq| 6¡ D ]-\}}t7|d j dd¡|d |d | j8d }"|"r|"|d jd< | j9|d |"d!d" qõ| j:r8| ;d#¡D ]} |  !¡ }#|#jd$= q,| j<rP| ;d%¡D ]} t<| ƒ}$|$|  !¡ jd< qA| j=r}| ;d&¡D ]#} t> ?| jd ¡}%|%j@d'krpd'| jd(< qY|%j@d)kr{d)| jd(< qY| jArâ| jBsâtC| jAƒjDstEd*ƒ‚d+D ]O}&| ;d,|& ¡D ]D} |  !¡ }#|#j|& }'|&dkr·| jFr·|' d-¡r·q›|&d.krÈ| jGrÈ|' d/¡rÈq›|&dkrÕ|' d0¡rÕq›tH| jA|'ƒ|#j|&< q›q’t|dƒrê|S | Id1| j¡ | Id2|¡ | Id3d4¡ tjJ|fi |¤Ž K|d3 ¡}(| jdkrtL d5d
„ |(¡}(| j	r&t
 d6d7d
„ |(¡}(|(S )8zUchange the html and return it with CSS turned into style
        attributes.
        NzCan't pass html argument twicez must pass html as first argumentÚgetroottreeÚxmlF)Zns_cleanZresolve_entitiesz="{{(.*?)}}"c                 S   s   dt |  ¡ d ƒ d S ©Nz="{{r   z}}")r   Úgroupsr;   r   r   r   Ú<lambda>]  s    z%Premailer.transform.<locals>.<lambda>r   r~   zlink[rel~=stylesheet]rv   Úmedia)ÚallÚscreenÚignorezUnrecognized %s attribute (%r)Úhrefrx   útext/cssr|   Ú )Úkeyrw   z:%srA   r-   )ÚitemÚclassesr~   r—   r–   )rX   T)Úforcez//@classÚclassz//@stylez//img[@style]ÚrightÚalignÚleftzBase URL must have a scheme)r’   Úsrcz//@%srz   r   zcid:ztel:rQ   Úpretty_printÚencodingúutf-8c                 S   s   d|   d¡ S )Nz/*<![CDATA[*/%s/*]]>*/rx   )r9   )Úmr   r   r   r   0  s    z="%7B%7B(.+?)%7D%7D"c                 S   s   dt t|  ¡ d ƒƒ d S r‹   )r   r   rŒ   r;   r   r   r   r   7  s    )MrB   Ú	TypeErrorÚhasattrr‰   rQ   r   Z	XMLParserÚ
HTMLParserrr   rG   Úrer?   Z
fromstringZgetrootrs   ZdocinfoÚdoctyperV   r,   rY   r}   r'   r!   ÚattribÚgetÚattribute_nameÚwarningsÚwarnÚtagÚtextÚ_load_externalrˆ   Úextendr)   rI   r(   Ú_css_rules_to_stringrP   Ú_importantsZCDATAZaddpreviousÚremoverN   Ú_process_css_textrO   ÚsortÚoperatorÚ
itemgetterr"   r   r   r   rT   ÚidÚitemsr   rX   Ú_style_to_basic_html_attributesrJ   Zxpathr@   rW   r/   Z
parseStyleÚfloatrC   rD   r   ÚschemeÚ
ValueErrorrE   rF   r   Ú
setdefaultZtostringÚdecodeÚ_cdata_regex))ra   rB   rž   Úkwargsr+   ÚpageÚtreeÚparserÚstrippedr%   r…   ÚindexZcssselectorÚelementrŽ   Zdata_attributeZis_styler1   r’   Úthese_rulesÚthese_leftoverZparent_of_elementr~   Ú	stylefileÚelementsÚ_r4   Znew_selectorÚclass_Úselr¸   Zprocessed_styler–   Zitem_idZfinal_styleÚparentZmangledZ	image_cssÚattrÚurlÚoutr   r   r   r   +  s`  

ý

ÿÿ






€
€





ÿ
€ü

ÿ
€

ÿþ
ÿþïÿýzPremailer.transformc                 C   s"   | j j|| j d}| ¡  |jS )N)Úverify)r]   r¨   rZ   Úraise_for_statusr­   )ra   rÐ   Úresponser   r   r   Ú_load_external_url<  s   zPremailer._load_external_urlc                 C   s  |  d¡r| jrd| jv rd| }nd| }|  d¡s |  d¡r'|  |¡}|S | js1td |¡ƒ‚|}tj | j	p;tj
¡}tj |¡sNtj tj ||¡¡}tj |¡rrtj|dd}| ¡ }W d	  ƒ |S 1 skw   Y  |S | jr€t| j|ƒ}|  |¡S t|ƒ‚)
z<loads an external stylesheet from a remote url or local pathz//zhttps://zhttps:zhttp:zhttp://zEUnable to load external file {!r} because it's explicitly not allowedr    )rŸ   N)rs   rC   rÕ   r[   r   r8   ÚosÚpathÚabspathrR   ÚcurdirÚisabsr!   ÚexistsÚcodecsÚopenÚreadr   r®   r   )ra   rÐ   r1   rÉ   rR   Úfr   r   r   r®   A  s6   


íþ

ÿøú
zPremailer._load_externalc                 C   s   t  d| ¡}|S )z°Fix background colors for Lotus Notes

        Notes which fails to handle three character ``bgcolor`` codes well.
        see <https://github.com/peterbe/premailer/issues/114>z#\1\1\2\2\3\3)Ú_short_color_codesr?   )Zcolor_valueÚretvalr   r   r   Ú	six_colora  s   zPremailer.six_colorc                 C   s$  |  d¡r|  d¡|  d¡kr| d¡d dd… }tƒ }dd„ | d¡D ƒD ]M\}}| ¡ }|d	kr:| ¡ |d
< q'|dkrE| ¡ |d< q'|dkrYd| ¡ vrY|  | ¡ ¡|d< q'|dksa|dkrt| ¡ }| d¡rp|dd… }|||< q'| ¡ D ]\}}||jv r„|r‰|| j	v rŠqy||j|< qydS )a0  given an element and styles like
        'background-color:red; font-family:Arial' turn some of that into HTML
        attributes. like 'bgcolor', etc.

        Note, the style_content can contain pseudoclasses like:
        '{color:red; border:1px solid green} :visited{border:1px solid green}'
        Ú}Ú{r   rx   Nc                 S   s(   g | ]}t | d ¡ƒdkr| d ¡‘qS )rw   é   )r   r"   rt   r   r   r   ro   z  s    "z=Premailer._style_to_basic_html_attributes.<locals>.<listcomp>r   z
text-alignr›   zvertical-alignZvalignzbackground-colorÚtransparentÚbgcolorÚwidthÚheightZpxéþÿÿÿ)
r€   r"   r   rr   Úlowerrâ   r   r¸   r§   rS   )ra   rÆ   Zstyle_contentr˜   Ú
attributesr•   r6   r   r   r   r¹   l  s:   ÿÿ
€
ÿ
øz)Premailer._style_to_basic_html_attributesc                 C   sž   g }|D ]E}t |tƒr|\}}| d|t|ƒf ¡ q|jD ]$}t |tjjjtjj	j
fƒr.q|j ¡ D ]}|j |d¡df|j|< q3q| |j¡ qd |¡S )z.given a list of css rules returns a css stringz%s {%s}Fr   Ú
)rL   Útupler}   r$   ZcssRulesr/   ÚcssZ
csscommentZ
CSSCommentZcssunknownruleZCSSUnknownRuler~   ÚkeysZgetPropertyValueZcssTextr!   )ra   r…   Úlinesr–   ÚkÚvr†   r•   r   r   r   r°   ™  s(   

þþþÿ
zPremailer._css_rules_to_stringc                 C   sp   |   ||¡\}}| |¡ |dur4|s| jr6t d¡}d|jd< | jr'||_n|  |¡|_| |¡ dS dS dS )z¸processes the given css_text by adding rules that can be
        in-lined to the given rules list and adding any that cannot
        be in-lined to the given `<head>` element.
        Nr~   r“   r|   )	rˆ   r¯   rI   r   r(   r§   r­   r°   r}   )ra   rO   rÅ   r…   r%   rÇ   rÈ   r~   r   r   r   r³   ³  s   


ùzPremailer._process_css_text)NNFFTFTFFFFTNNrB   NNFTNNFTTTFFN©T)NT©F)r   r   r   r©   rb   rc   rˆ   r   rÕ   r®   Ústaticmethodrâ   r¹   r°   r³   r   r   r   r   r   n   sV    
ã
R
a   


-r   Fc                 K   s   t di |¤Žj| |dS )N)rž   r   )r   r   )rB   rž   rÀ   r   r   r   r   Ä  s   r   Ú__main__a  <html>
        <head>
        <title>Test</title>
        <style>
        h1, h2 { color:red; }
        strong {
          text-decoration:none
          }
        p { font-size:2px }
        p.footer { font-size: 1px}
        </style>
        </head>
        <body>
        <h1>Hi!</h1>
        <p><strong>Yes!</strong></p>
        <p class="footer" style="color:red">Feetnuts</p>
        </body>
        </html>rô   rõ   )5rÜ   rµ   rÖ   r¥   rª   Úcollectionsr   rB   r   r   Úurllib.parser   r   r   r/   r\   Zlxmlr   Zlxml.cssselectr
   Zpremailer.cacher   Zpremailer.merge_styler   r   Ú__all__Ú	Exceptionr   r¼   r   r   r$   r,   r2   r'   r@   Úcompiler‚   ÚDOTALLr¿   Ú
IGNORECASEÚVERBOSEr>   r±   ÚIrà   r   Úobjectr   r   r   r   Úprintr   r   r   r   Ú<module>   sZ    


û
    
Zì