o
    c@                     @   s6  d 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m	Z	m
Z
 ddlmZ ddlmZ ed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

    N)Color)	TA_CENTER
TA_JUSTIFYTA_LEFTTA_RIGHTstringWidth)FlowableZ	xhtml2pdfc                   @   s<   e Zd ZdZedddddeddddddddZ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.
    g        NzTimes-Romang      $@r   g      ?)	textAlign
textIndentwidthheightfontNamefontSizecolor
lineHeightZlineHeightAbsoluteZpdfLineSpacinglinkc                 K   s,   |  | j |  | d| _d| _d| _d S Nr   F)updateDEFAULTZspaceBeforeZ
spaceAfterZkeepWithNext)selfkw r   /xhtml2pdf/paragraph.py__init__E   s
   

zStyle.__init__)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r
   /   s    
r
   c                   @   s   e Zd ZdZdZ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

    boxc              	      s&      dd }|d u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                    s`   |r*| r,|d u r dtddd}|d ur. |  |  |||| d S d S d S d S )NZ	textColorr   )getr   setStrokeColorsetLineWidthline)Zbstyler   r   x1y1Zx2y2canvasr   r   r   _drawBorderLineo   s   

z$Box.drawBox.<locals>._drawBorderLineZborderLeftStyleZborderLeftWidthZborderLeftColorZborderRightStyleZborderRightWidthZborderRightColorZborderTopStyleZborderTopWidthZborderTopColorZborderBottomStyleZborderBottomWidthZborderBottomColor)	saveStater%   setFillColorrectrestoreState)r   r-   xywhbgr.   r   r,   r   drawBoxd   s6   








zBox.drawBoxN)r   r   r   r   namer8   r   r   r   r   r    M   s    r    c                   @   s(   e Zd ZdZdZdZdZdZdd ZdS )Fragmentz
    Fragment.

    text:       String containing text
    fontName:
    fontSize:
    width:      Width of string
    height:     Height of string
    fragmentFc                 C   s   d| d< d S )Nr   r   r   r   r   r   r   calc   s   zFragment.calcN)	r   r   r   r   r9   isSoftisTextisLFr=   r   r   r   r   r:      s    
r:   c                   @       e Zd ZdZdZdZdd ZdS )Wordz
    A single word.
    wordTc                 C   s    t | d | d | d | d< dS )z;
        XXX Cache stringWith if not accelerated?!
        textr   r   r   Nr   r<   r   r   r   r=      s    z	Word.calcN)r   r   r   r   r9   r?   r=   r   r   r   r   rB      
    rB   c                   @   rA   )SpacezN
    A space between fragments that is the usual place for line breaking.
    spaceTc                 C   s   t d| d | d | d< d S )N r   r   r   r   r<   r   r   r   r=      s   z
Space.calcN)r   r   r   r   r9   r>   r=   r   r   r   r   rF      rE   rF   c                   @   s   e Zd ZdZdZdZdZdS )	LineBreakz
    Line break.
    brTN)r   r   r   r   r9   r>   r@   r   r   r   r   rI      s    rI   c                   @   s    e Zd ZdZdd Zdd ZdS )BoxBeginbeginc                 C       |  dd|  dd | d< d S )N
marginLeftr   ZpaddingLeftr   r%   r<   r   r   r   r=          zBoxBegin.calcc                 C   sF   |  dd| d  }| d |  dd }| d }| ||||| d S )NrN   r   r3   lengthpaddingRightr   )r%   r8   )r   r-   r4   r3   r5   r6   r   r   r   draw   s   zBoxBegin.drawN)r   r   r   r9   r=   rS   r   r   r   r   rK      s    rK   c                   @   s   e Zd ZdZdd ZdS )BoxEndendc                 C   rM   )NZmarginRightr   rR   r   rO   r<   r   r   r   r=      rP   zBoxEnd.calcN)r   r   r   r9   r=   r   r   r   r   rT      s    rT   c                   @   s   e Zd ZdZdS )ImageZimageN)r   r   r   r9   r   r   r   r   rV      s    rV   c                   @   s4   e Zd ZdZdZdd Zdd Zdd Zd	d
 ZdS )Linez'
    Container for line fragments.
    g      ?c                 C   s,   d| _ d| _d| _|| _g | _t|  d S r   )r   r   isLaststyleboxStacklistr   )r   rY   r   r   r   r      s   zLine.__init__c           	      C   s0  |t krZ| d d | d d  }|| }|tkr%| D ]?}|d  |7  < q|tkr8| D ].}|d  |d 7  < q+|tkrZ| jsZ|t| d  }t| D ]\}}|d  || 7  < qK| D ]+}|d |d  }t|trr| j	
| q\t|tr| j	r| j	 }||d  |d< q\| j	D ]
}||d  |d< qd S )Nr3   r   g       @r"   rQ   )r   r   r   r   rX   len	enumerate
isinstancerK   rZ   appendrT   pop)	r   r   	alignmentZ	lineWidthZ
emptySpacefragdeltair3   r   r   r   doAlignment   s2   



zLine.doAlignmentc                    sf   | _ dgdd  D  }t| _t fdd|D   _ _ j j } D ]}||d< q) jS )z/
        Align words in previous line.
        r   c                 S   s   g | ]}| d dqS )r   r   rO   .0rc   r   r   r   
<listcomp>  s    z!Line.doLayout.<locals>.<listcomp>c                 3   s    | ]}| j  V  qd S N)
LINEHEIGHTrg   r<   r   r   	<genexpr>  s    z Line.doLayout.<locals>.<genexpr>r4   N)r   maxr   r   r   )r   r   Z
font_sizesr4   rc   r   r<   r   doLayout  s   

zLine.doLayoutc              	   C   s<   t d t d | D ]}t d|d|j  qd S )NrW   z(----------------------------------------z%srD   )loggerdebugr%   r9   upper)r   rc   r   r   r   dumpFragments%  s
   

zLine.dumpFragmentsN)	r   r   r   r   rk   r   rf   rn   rr   r   r   r   r   rW      s    rW   c                   @   s4   e Zd ZdZdddZdd Zddd	Zd
d ZdS )Textz
    Container for text fragments.

    Helper functions for splitting text into lines and calculating sizes
    and positions.
    Nc                 C   s@   |d u rg }g | _ d| _d| _d| _d| _|| _t| | d S )Nr   )linesr   r   maxWidth	maxHeightrY   r[   r   )r   datarY   r   r   r   r   4  s   zText.__init__c                 C   s   | D ]}|   qdS )z/
        Calculate sizes of fragments.
        N)r=   )r   rC   r   r   r   r=   A  s   
z	Text.calcFc                 C   s  g | _ d| _| | _| _|| _g }| j}d}|s|d }t| }d}||k r|}	t|}
t|D ]}d|d< |
	t
| q1||k r| | }|d }||d< |d7 }t|t
r^|	| n	t|trg|  |jry|jrs|
	| q|dkrxq?n|| |krq||7 }|
	| ||k sC|
r|
d jdv r|
  |
r|
d jdv s|
  |  j|
| j7  _| j 	|
 | j|kr|	S d}||k s&d| j d _| 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   r3   r   r"   r\   )rG   rJ   Tr   N)rt   r   ru   r   rv   rY   r]   rW   copyr`   rK   r_   rT   ra   r>   r@   r9   rr   rn   rX   rf   )r   ru   rv   splittedrZ   rY   r3   ZlenTextposZposBeginr(   r!   rc   Z	fragWidthr   r   r   splitIntoLinesH  sh   



!
=
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)r^   rt   ro   rp   rr   )r   re   r(   r   r   r   	dumpLines  s   zText.dumpLines)NN)F)r   r   r   r   r   r=   r{   r|   r   r   r   r   rs   ,  s    

Wrs   c                   @   s2   e Zd ZdZdddZdd Zdd Zd	d
 Zd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.)

    Fc                 K   s\   t |  || _| j  || _|| j_|| _|| _| D ]
\}}t| || qd | _	d S rj   )
r	   r   rD   r=   rY   rp   ry   itemssetattr
splitIndex)r   rD   rY   rp   ry   ZkwDictkvr   r   r   r     s   


zParagraph.__init__c                 C   sz   || _ || _td|| | jstddd dS |}| j||| _|| jj| _| _td| j| j| j | j| jfS )zF
        Determine the rectangle this paragraph really needs.
        z*** wrap (%f, %f)z*** wrap (%f, %f) neededr   )r   r   z'*** wrap (%f, %f) needed, splitIndex %rN)	ZavWidthZavHeightro   rp   rD   r{   r   r   r   )r   
availWidthavailHeightr   r   r   r   wrap  s   zParagraph.wrapc                 C   s   t d|| g }| jrB| 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 )z4
        Split ourselves in two paragraphs.
        z*** split (%f, %f)N)rp   T)rp   ry   z*** text1 %s / text %sz*** return %s)	ro   rp   r   rD   r}   rs   rY   r]   ry   )r   r   r   ry   Ztext1Ztext2p1p2r   r   r   split  s   zParagraph.splitc              	   C   sD  t d | js
dS | j}| j}|  | jrBd}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rc|	|||  |	d	d
r||	d |	d  |	|	d|d  ||	d || |	d  |	d	  |	dd}
|
rtd}|	d || |	d |	d f\}}}}||||f}t|
tr|
d}
|
dd}t|dkr|d  pd
}||r|dkr| dkrdpd}|dkr|d }
|j|
|d|d qT|
d dkr|
dd }
d
}|jd
|dkr|
p|d |dd qTqK|  dS )z6
        Render the content of the paragraph.
        z*** drawNg      ?r"   r   g?r#   rS   rD    r   r   r   r3   r4   r   z^[a-zA-Z][-+a-zA-Z0-9]+$r   utf8:   ZdocumentZpdfZGoToRURI)relativekind#)r   ) ro   rp   rD   canvrY   r/   r   r&   r'   r0   r1   Z
leftIndentr   r   rt   hasattrrS   r%   ZsetFontZ
drawStringrecompiler_   strencoder   r]   lowermatchZlinkURLZlinkRectr2   )r   r-   rY   ZbwZbcr7   r4   Zdyr(   rc   r   Z
_scheme_rer3   r5   r6   r1   partsschemer   r   r   r   rS     sj   





"
$

&"zParagraph.drawN)FF)r   r   r   r   r   r   r   rS   r   r   r   r   r}     s    
r}   c                   @   s   e Zd Zdd Zdd ZdS )PageNumberFlowablec                 C   s   t |  d | _d | _d S rj   )r	   r   page	pagecountr<   r   r   r   r   ?  s   

zPageNumberFlowable.__init__c                 C   s$   t | jjj| _t | jjj| _d S rj   )r   r   Z_doctemplater   Z_page_countr   r<   r   r   r   rS   D  s   zPageNumberFlowable.drawN)r   r   r   r   rS   r   r   r   r   r   >  s    r   ) r   rx   loggingr   Zreportlab.lib.colorsr   Zreportlab.lib.enumsr   r   r   r   Zreportlab.pdfbase.pdfmetricsr   Zreportlab.platypus.flowablesr	   	getLoggerro   dictr
   r    r:   rB   rF   rI   rK   rT   rV   r[   rW   rs   r}   r   r   r   r   r   <module>   s.   
AG| 