U
    =g7E                     @  sf  d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	 ddl
mZ ddlmZmZmZmZ ddlmZ ddlmZ erdd	lmZ eeZG d
d deZG dd deZG dd deZG dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd de$Z%G dd de$Z&G d d! d!eZ'G d"d# d#eZ(dS )$a  
A paragraph class to be used with ReportLab Platypus.

Todo:
----
- Bullets
- Weblinks and internal links
- Borders and margins (Box)
- Underline, Background, Strike
- Images
- Hyphenation
+ Alignment
+ Breakline, empty lines
+ TextIndent
- Sub and super

    )annotationsN)TYPE_CHECKINGAnyClassVar)Color)	TA_CENTER
TA_JUSTIFYTA_LEFTTA_RIGHTstringWidth)Flowable)Canvasc                   @  sL   e Zd ZU dZeddddddddddedddZd	ed
< ddddZdS )Stylez
    Style.

    Single place for style definitions: Paragraphs and Fragments. The
    naming follows the convention of CSS written in camelCase letters.
    r   zTimes-Romang      $@Ng      ?g        )colorfontNamefontSizeheight
lineHeightZlineHeightAbsolutelinkZpdfLineSpacing	textAlign
textIndentwidthzClassVar[dict[str, Any]]DEFAULTNonereturnc                 K  s2   |  | j |  | d| _d| _d| _d| _d S Nr   F)updater   ZspaceBeforeZ
spaceAfter
leftIndentZkeepWithNext)selfkwargs r"   7/tmp/pip-unpacked-wheel-d1lgvatt/xhtml2pdf/paragraph.py__init__H   s    
zStyle.__init__)	__name__
__module____qualname____doc__r   r	   r   __annotations__r$   r"   r"   r"   r#   r   2   s   

r   c                   @  s4   e Zd ZU dZdZded< dddddddd	Zd
S )Boxa%  
    Box.

    Handles the following styles:

        backgroundColor, backgroundImage
        paddingLeft, paddingRight, paddingTop, paddingBottom
        marginLeft, marginRight, marginTop, marginBottom
        borderLeftColor, borderLeftWidth, borderLeftStyle
        borderRightColor, borderRightWidth, borderRightStyle
        borderTopColor, borderTopWidth, borderTopStyle
        borderBottomColor, borderBottomWidth, borderBottomStyle

    Not used in inline Elements:

        paddingTop, paddingBottom
        marginTop, marginBottom

    boxstrnamer   int)canvasxywhc              	     s&      dd }|d k	r< |  j||||ddd  fdd}|dd dd d	d |||||  |d
d dd dd || ||| ||  |dd dd dd ||| || ||  |dd dd dd |||| |    d S )NZbackgroundColor   r   fillZstrokec                   sT   |rP| rP|d kr$ dtddd}|d k	rP |  |  |||| d S )NZ	textColorr   )getr   setStrokeColorsetLineWidthline)Zbstyler   r   x1y1x2y2r/   r    r"   r#   _drawBorderLines   s    

z$Box.drawBox.<locals>._drawBorderLineZborderLeftStyleZborderLeftWidthZborderLeftColorZborderRightStyleZborderRightWidthZborderRightColorZborderTopStyleZborderTopWidthZborderTopColorZborderBottomStyleZborderBottomWidthZborderBottomColor)	saveStater7   setFillColorrectrestoreState)r    r/   r0   r1   r2   r3   bgr@   r"   r?   r#   drawBoxh   sV    



	


	


	



zBox.drawBoxN)r%   r&   r'   r(   r-   r)   rF   r"   r"   r"   r#   r*   Q   s   
r*   c                   @  sP   e Zd ZU dZdZded< dZded< dZded< dZded	< d
dddZ	dS )Fragmentz
    Fragment.

    text:       String containing text
    fontName:
    fontSize:
    width:      Width of string
    height:     Height of string
    fragmentr,   r-   FboolisSoftisTextisLFr   r   c                 C  s   d| d< d S )Nr   r   r"   r    r"   r"   r#   calc   s    zFragment.calcN)
r%   r&   r'   r(   r-   r)   rJ   rK   rL   rN   r"   r"   r"   r#   rG      s   

rG   c                   @  s8   e Zd ZU dZdZded< dZded< dd	d
dZdS )WordzA single word.wordr,   r-   TrI   rK   r   r   c                 C  s    t | d | d | d | d< dS )z*XXX Cache stringWith if not accelerated?!.textr   r   r   Nr   rM   r"   r"   r#   rN      s    z	Word.calcN)r%   r&   r'   r(   r-   r)   rK   rN   r"   r"   r"   r#   rO      s   
rO   c                   @  s8   e Zd ZU dZdZded< dZded< dd	d
dZdS )SpacezDA space between fragments that is the usual place for line breaking.spacer,   r-   TrI   rJ   r   r   c                 C  s   t d| d | d | d< d S )N r   r   r   r   rM   r"   r"   r#   rN      s    z
Space.calcN)r%   r&   r'   r(   r-   r)   rJ   rN   r"   r"   r"   r#   rR      s   
rR   c                   @  s6   e Zd ZU dZdZded< dZded< dZded< d	S )
	LineBreakzLine break.brr,   r-   TrI   rJ   rL   N)r%   r&   r'   r(   r-   r)   rJ   rL   r"   r"   r"   r#   rU      s   
rU   c                   @  s0   e Zd ZU dZded< ddddZdd	 Zd
S )BoxBeginbeginr,   r-   r   r   c                 C  s    |  dd|  dd | d< d S )N
marginLeftr   ZpaddingLeftr   r7   rM   r"   r"   r#   rN      s     zBoxBegin.calcc                 C  sF   |  dd| d  }| d |  dd }| d }| ||||| d S )NrY   r   r0   lengthpaddingRightr   )r7   rF   )r    r/   r1   r0   r2   r3   r"   r"   r#   draw   s    zBoxBegin.drawN)r%   r&   r'   r-   r)   rN   r]   r"   r"   r"   r#   rW      s   
rW   c                   @  s(   e Zd ZU dZded< ddddZdS )	BoxEndendr,   r-   r   r   c                 C  s    |  dd|  dd | d< d S )NZmarginRightr   r\   r   rZ   rM   r"   r"   r#   rN      s     zBoxEnd.calcN)r%   r&   r'   r-   r)   rN   r"   r"   r"   r#   r^      s   
r^   c                   @  s   e Zd ZU dZded< dS )Imageimager,   r-   N)r%   r&   r'   r-   r)   r"   r"   r"   r#   r`      s   
r`   c                      sL   e Zd ZU dZdZded< dd fddZd	d
 Zdd Zdd Z	  Z
S )LinezContainer for line fragments.g      ?float
LINEHEIGHTr   r   c                   s,   d| _ d| _d| _|| _g | _t   d S r   )r   r   isLaststyleboxStacksuperr$   )r    rf   	__class__r"   r#   r$      s    zLine.__init__c           	      C  s6  |t kr| d d | d d  }|| }|tkrL| D ]}|d  |7  < q4nl|tkrt| D ]}|d  |d 7  < qXnD|tkr| js|t| d  }t| D ]\}}|d  || 7  < q| D ]V}|d |d  }t|tr| j	
| qt|tr| j	r| j	 }||d  |d< q| j	D ]}||d  |d< qd S )Nr0   r   g       @r4   r[   )r	   r
   r   r   re   len	enumerate
isinstancerW   rg   appendr^   pop)	r    r   	alignmentZ	lineWidthZ
emptySpacefragdeltair0   r"   r"   r#   doAlignment  s2    


zLine.doAlignmentc                   sf   | _ dgdd  D  }t| _t fdd|D   _ _ j j } D ]}||d< qR jS )zAlign words in previous line.r   c                 S  s   g | ]}| d dqS )r   r   rZ   .0rr   r"   r"   r#   
<listcomp>%  s     z!Line.doLayout.<locals>.<listcomp>c                 3  s   | ]}| j  V  qd S N)rd   rv   rM   r"   r#   	<genexpr>'  s    z Line.doLayout.<locals>.<genexpr>r1   )r   maxr   r   r   )r    r   Z
font_sizesr1   rr   r"   rM   r#   doLayout   s    

zLine.doLayoutc              	   C  s<   t d t d | D ]}t d|d|j  qd S )Nrb   z(----------------------------------------z%srQ   )loggerdebugr7   r-   upper)r    rr   r"   r"   r#   dumpFragments2  s    

zLine.dumpFragments)r%   r&   r'   r(   rd   r)   r$   ru   r|   r   __classcell__r"   r"   ri   r#   rb      s   
rb   c                      sh   e Zd ZdZddddd fddZdd	d
dZdddddddddZdd Z fddZ  Z	S )Textz
    Container for text fragments.

    Helper functions for splitting text into lines and calculating sizes
    and positions.
    Nzlist | NonezStyle | Noner   )datarf   r   c                   s@   |d krg }g | _ d| _d| _d| _d| _|| _t | d S )Nr   )linesr   r   maxWidth	maxHeightrf   rh   r$   )r    r   rf   ri   r"   r#   r$   A  s    zText.__init__r   c                 C  s   | D ]}|   qdS )zCalculate sizes of fragments.N)rN   )r    rP   r"   r"   r#   rN   N  s    z	Text.calcF)splittedr.   rI   z
int | None)r   r   r   r   c                C  s  g | _ d| _|| _|| _|| _g }| j}d}|s<|r<|d }t| }d}||k r|}	t|}
t|D ]}d|d< |
	t
| qh||k r"| | }|d }||d< |d7 }t|t
r|	| nt|tr|  |jr|jr|
	| q"|dkrqn|| |krq"||7 }|
	| q|
rD|
d jdkrD|
  q"|
  |  j|
| j7  _| j 	|
 | j|kr~|	S d}qHd| j d _|r| j D ]}
|
||d	  qd
S )z
        Split text into lines and calculate X positions. If we need more
        space in height than available we return the rest of the text.
        r   r   r0   r   r4   rk   >   rS   rV   Tr   N)r   r   r   r   r   rf   rl   rb   copyro   rW   rn   r^   rp   rJ   rL   r-   r   r|   re   ru   )r    r   r   r   rg   rf   r0   ZlenTextposZposBeginr:   r+   rr   Z	fragWidthr"   r"   r#   splitIntoLinesS  sd    





zText.splitIntoLinesc                 C  s2   t | jD ]"\}}td| t|  q
dS )z.For debugging dump all line and their content.zLine %d:N)rm   r   r}   r~   r   )r    rt   r:   r"   r"   r#   	dumpLines  s    zText.dumpLinesc                   s*   t |trt| t |S t |S )z6Make sure slices return also Text object and not lists)rn   slicetyperh   __getitem__)r    keyri   r"   r#   r     s    
zText.__getitem__)NN)
r%   r&   r'   r(   r$   rN   r   r   r   r   r"   r"   ri   r#   r   9  s   Yr   c                      sh   e Zd ZdZddddddddd fd	d
ZddddddZddddddZddddZ  ZS )	Paragrapha:  
    A simple Paragraph class respecting alignment.

    Does text without tags.

    Respects only the following global style attributes:
    fontName, fontSize, leading, firstLineIndent, leftIndent,
    rightIndent, textColor, alignment.
    (spaceBefore, spaceAfter are handled by the Platypus framework.)

    Fr~   r   r   r   rI   r   )rQ   rf   r~   r   r   c                  s\   t    || _| j  || _|| j_|| _|| _| D ]\}}t| || q<d | _	d S ry   )
rh   r$   rQ   rN   rf   r~   r   itemssetattr
splitIndex)r    rQ   rf   r~   r   ZkwDictkvri   r"   r#   r$     s    	

zParagraph.__init__r.   ztuple[int, int])
availWidthavailHeightr   c                 C  sx   || _ || _td|| | js2tddd dS |}| j||| _|| _| jj| _td| j| j| j | j| jfS )z4Determine the rectangle this paragraph really needs.z*** wrap (%f, %f)z*** wrap (%f, %f) neededr   )r   r   z'*** wrap (%f, %f) needed, splitIndex %r)	ZavWidthZavHeightr}   r~   rQ   r   r   r   r   )r    r   r   r   r"   r"   r#   wrap  s"    
zParagraph.wrapzlist[Paragraph]c                 C  s   t d|| g }| jr| jd| j }| j| jd }tt|| j| jd}tt|| j| jdd}||g}t dt|t| t d| j |S )z"Split ourselves in two paragraphs.z*** split (%f, %f)N)r~   Tr   z*** text1 %s / text %sz*** return %s)	r}   r~   r   rQ   r   r   rf   rl   r   )r    r   r   r   Ztext1Ztext2p1p2r"   r"   r#   split  s        zParagraph.splitr   c              	   C  sZ  t d | jsdS | j}| j}|  | jrd}tddd}tddd}|| || |	| |j
|jd| j| jddd d}| j}| jjD ]}||j7 }|D ]}	t|	dr|	|||  |	d	d
r$||	d |	d  |	|	d|d  ||	d || |	d  |	d	  |	dd}
|
rtd}|	d || |	d |	d f\}}}}||||f}t|
tr|
d}
|
jddd}t|dkr|d  pd
}||r|dkr| dkrdpd}|dkr|d }
|j|
|d|d q|
d dkr$|
dd }
d
}|jd
|dkr:|
p@|d |dd qq|  dS )z$Render the content of the paragraph.z*** drawNg      ?r4   r   g?r5   r]   rQ    r   r   r   r0   r1   r   z^[a-zA-Z][-+a-zA-Z0-9]+$r   utf8:)maxsplit   documentZpdfZGoToRURI)relativekind#)r   ) r}   r~   rQ   canvrf   rA   r   r8   r9   rB   rC   r   r   r   r   hasattrr]   r7   ZsetFontZ
drawStringrecompilern   bytesdecoder   rl   lowermatchZlinkURLZlinkRectrD   )r    r/   rf   ZbwZbcrE   r1   Zdyr:   rr   r   Z
_scheme_rer0   r2   r3   rC   partsschemer   r"   r"   r#   r]     sb    






"
$
 

zParagraph.draw)	r%   r&   r'   r(   r$   r   r   r]   r   r"   r"   ri   r#   r     s   r   c                      s0   e Zd Zdd fddZddddZ  ZS )PageNumberFlowabler   r   c                   s   t    d | _d | _d S ry   )rh   r$   page	pagecountrM   ri   r"   r#   r$   U  s    
zPageNumberFlowable.__init__c                 C  s$   t | jjj| _t | jjj| _d S ry   )r,   r   Z_doctemplater   Z_page_countr   rM   r"   r"   r#   r]   Z  s    zPageNumberFlowable.draw)r%   r&   r'   r$   r]   r   r"   r"   ri   r#   r   T  s   r   ))r(   
__future__r   r   loggingr   typingr   r   r   Zreportlab.lib.colorsr   Zreportlab.lib.enumsr   r   r	   r
   Zreportlab.pdfbase.pdfmetricsr   Zreportlab.platypus.flowablesr   Zreportlab.pdfgen.canvasr   	getLoggerr%   r}   dictr   r*   rG   rO   rR   rU   rW   r^   r`   listrb   r   r   r   r"   r"   r"   r#   <module>   s6   
U
	E  