U
    :vhy_                     @   s   d Z dZdZdZ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 dd	lmZ d
d Zdd ZG dd dZG dd deZdS )z PDF Template Helpers for fpdf.pyz%Mariano Reingart <reingart@gmail.com>z#Copyright (C) 2010 Mariano ReingartzLGPL 3.0    N   )get_stack_level)FPDFException)FPDFc                 C   s   | d | d d | d fS )Ni       )colr   r   1/tmp/pip-unpacked-wheel-dvf6lv8i/fpdf/template.py_rgb   s    r
   c                 C   sf   t | \}}}|dkr&|dkr&|dks.|dkr>|d ddS |d dd|d dd|d ddS )Nr      z.3fz g z rg)r
   )r   rgbr   r   r	   _rgb_as_str   s     r   c                   @   s  e Zd ZdZd@ddZdd Zedd Zed	d
 ZdAe	j
edddZdBe	j
eeedddZdd ZeZdd Zdd Zdd Zdddddddd d!d!d!ddddd"d#d$d%Zdddddd dd&d'd(Zdddddd ddd)d*d+Zdddddd ddd)d,d-Zdddddd.d/d0Zdddddd1d2d dd3	d4d5Zddddd6d dddddd7d8d9Zdddddddd d!d!d!ddd:d;d<ZdCd>d?ZdS )DFlexTemplatez
    A flexible templating class.

    Allows to apply one or several template definitions to any page of
    a document in any combination.
    Nc              	   C   s^   t |tstd|| _d| _|r,| | | j| j| j| j	| j
| j| j| jd| _i | _dS )a=  
        Arguments: pdf (fpdf.FPDF() instance): All content will be added to this object.

            elements (list of dicts): A template definition in a list of dicts.
                If you omit this, then you need to call either load_elements()
                or parse_csv() before doing anything else.
        z('pdf' must be an instance of fpdf.FPDF()N)TLIBEBCC39W)
isinstancer   	TypeErrorpdfsplitting_pdfload_elements_text_line_image_rect_ellipse_barcode_code39_writehandlerstexts)selfr   elementsr   r   r	   __init__!   s     


zFlexTemplate.__init__c                 C   s$  t tdft tdfttfttfttfttft tdfttftttttt tdft tdftttdfttft tdfd}|| _g | _|D ]}d|krd|d< dD ]}||kr|d dkr&|dkrd	|kr|d	 |d< q|d
krd|kr|d |d
< q|dkr&d|kr&|d
 |d  |d< qtd| dqd|krb|d dkrZd|d< ntdd|kr|d dkrd|kr|d |d< |	 D ]p\}}||krt
|| |st
|tr|jnddd |D }td| d| dt|| j dq| j|d   qdS )z
        Load a template definition.

        Arguments:

            elements (list of dicts): A template definition in a list of dicts
        N)nametypex1y1x2y2fontsizebolditalic	underline
foreground
backgroundaligntextpriority	multilinerotatewrapmoder<   r   )r-   r.   r/   r0   r2   r.   r   r/   xr0   yr2   hzMandatory key 'z' missing in input datar1   r   r   z(Mandatory key 'x2' missing in input datar4   wz or c                 S   s   g | ]}d |j  d qS )')__name__.0r@   r   r   r	   
<listcomp>~   s     z.FlexTemplate.load_elements.<locals>.<listcomp>zValue of element item 'z
' must be z, not ''.r-   )strr.   intfloatobjectboolr+   keysKeyErroritemsr   rF   joinr   appendlower)r*   r+   
key_configektttyper   r   r	   r   ;   sn    












 zFlexTemplate.load_elementsc                 C   s8   | dd dkrt | dS | d dkr0t | dS t | S )z#Allow hex and oct values for colorsN   )0x0X   r   0   rL   )sr   r   r	   _parse_colorcode   s
    

zFlexTemplate._parse_colorcodec                 C   s$   t | }|dkrdS |dk r dS d S )Nr   TFra   )rb   ir   r   r	   _parse_multiline   s    zFlexTemplate._parse_multilineutf-8)infileencodingc              	   C   s   t ||d}t|}|D ]}|d}|rft|trf| dr^t|dd d|d< nt	d|d}|rt|tr| drt|dd d|d< qt	d	q| 
| W 5 Q R X dS )
a  
        Load the template definition from a JSON file.
        The data must be structured as an array of objects, with names and values exactly
        equivalent to what would get supplied to load_elements(),

        Arguments:

            infile (string or path-like object): The filepath of the JSON file.

            encoding (string): The character encoding of the file. Default is UTF-8.
        rh   r8   #r   Nr^   z;If foreground is a string, it must have the form '#rrggbb'.r9   z;If background is a string, it must have the form '#rrggbb'.)openjsonloadgetr   rK   rU   
startswithrL   
ValueErrorr   )r*   rg   rh   fdatadZfgvalZbgvalr   r   r	   
parse_json   s$    


zFlexTemplate.parse_json,.)rg   	delimiterdecimal_seprh   c                    s  d% fdd	}dt dfdt dfd|dfd|dfd	|dfd
|dfdt dfd|dfdtdfdtdfdtdfd| jdfd| jdfdt dfdt dfdtdfd| jdfd|dfdt dff}g | _|dkrt }t||d}tj	||dD ]}|
dgt|t|   i }	t||D ]\}
}|
 }|s||d rd|d d	krN|d d krNntd!|d  d"n|d dkrd|	d< n|d ||	|d < q| j|	 qW 5 Q R X d#d$ | jD | _dS )&a?  
        Load the template definition from a CSV file.

        Arguments:

            infile (string or path-like object): The filepath of the CSV file.

            delimiter (single character): The character that separates the fields in the CSV file:
                Usually a comma, semicolon, or tab.

            decimal_sep (single character): The decimal separator used in the file.
                Usually either a point or a comma.

            encoding (string): The character encoding of the file.
                Default is the system default encoding.
        r_   c                    s   t |  p| dS )z-Convert to float with given decimal separatorrv   )rM   stripreplace)rb   defaultrx   r   r	   _varsep_float   s    z-FlexTemplate.parse_csv.<locals>._varsep_floatr-   Tr.   r/   r0   r1   r2   r3   Fr4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   Nri   )rw    r[   r   r   rC   zMandatory value 'z' missing in csv datac                 S   s   g | ]}|d    qS )r-   rU   )rH   valr   r   r	   rI     s     z*FlexTemplate.parse_csv.<locals>.<listcomp>)r_   )rK   rL   rc   re   r+   localegetpreferredencodingrk   csvreaderextendlenzipry   r   rT   rP   )r*   rg   rw   rx   rh   r}   rV   rq   rowZkargsr   cfgvsr   r|   r	   	parse_csv   sT    




zFlexTemplate.parse_csvc                 C   sN   t |ts tdt|j d| | jkr<td| || j| < d S )N!name must be of type 'str', not 'rJ   z%Element not loaded, cannot set item: )	r   rK   AssertionErrorr.   rF   rU   rP   r   r)   )r*   r-   valuer   r   r	   __setitem__  s     zFlexTemplate.__setitem__c                 C   s.   t |ts tdt|j d| | jkS )Nr   rJ   )r   rK   r   r.   rF   rU   rP   r*   r-   r   r   r	   __contains__  s     zFlexTemplate.__contains__c                    sh   t |ts tdt|j d|| jkr2t||   | jkrN| j  S t	 fdd| j
D d S )Nr   rJ   c                 3   s&   | ]}|d     kr|d V  qdS )r-   r;   Nr   rG   keyr   r	   	<genexpr>%  s      z+FlexTemplate.__getitem__.<locals>.<genexpr>)r   rK   r   r.   rF   rP   rQ   rU   r)   nextr+   r   r   r   r	   __getitem__  s     


 zFlexTemplate.__getitem__c                    s   t  fdd| jD }| js0t | _| j  d}|drF|d7 }|drX|d7 }|drj|d	7 }| j|d
 ||d  | jj|d |d  |d |d  t||dddd|dddS )a  
        Split a string between words, for the parts to fit into a given element
        width. Additional splits will be made replacing any '\n' characters.

        Arguments:

            text (string): The input text string.

            element_name (string): The name of the template element to fit the text inside.

        Returns:
            A list of substrings, each of which will fit into the element width
            when rendered in the element font style and size.
        c                 3   s&   | ]}|d       kr|V  qdS )r-   Nr   )rH   elementelement_namer   r	   r   7  s   z/FlexTemplate.split_multicell.<locals>.<genexpr>r~   r5   r   r6   r   r7   Ur3   r4   r1   r/   r2   r0   r:   TLINESr?   WORD)rD   rB   r;   r:   dry_runoutputr?   )	r   r+   r   r   add_pagern   set_font
multi_cellrK   )r*   r;   r   r   styler   r   r	   split_multicell(  s.    





zFlexTemplate.split_multicellr   r~   	helvetica
         ?Fr   )r/   r0   r1   r2   r;   r3   r4   scaler5   r6   r7   r:   r8   r9   r=   r?   c             	   O   sv  |sd S | j }|jt|kr*|jt|  |d kr8d}n d}|jt|krX|jt|  |  }d}dD ]<}|	d| drl|
d| drl|dd	 }||7 }ql|	r|d
7 }|
r|d7 }|r|d7 }|||||  ||| || ||  }}|d kr |j|||d||d nR|r@|j|||d|||d n2|j|||||dddd }|j|||d||d d S )NFTr~   r   r   r   <></   r   r   r   r   )rD   rB   r;   borderr:   fill)rD   rB   r;   r   r:   r   r?   r   )rD   rB   r;   r:   r?   r   r   )r   
text_colorr   set_text_colorr
   
fill_colorset_fill_colorry   rU   ro   endswithr   set_xycellr   )r*   r/   r0   r1   r2   r;   r3   r4   r   r5   r6   r7   r:   r8   r9   r=   r?   ___r   r   r   tagwidthheightr   r   r	   r    Q  sb    $


	zFlexTemplate._text)r/   r0   r1   r2   r4   r   r8   c          
      O   sN   | j j  t|kr(| j jt|  | j ||  | j |||| d S )N)	r   
draw_color	serializerU   r   set_draw_colorr
   set_line_widthline)
r*   r/   r0   r1   r2   r4   r   r8   r   r   r   r   r	   r!     s    zFlexTemplate._line)r/   r0   r1   r2   r4   r   r8   r9   c                O   s   | j }|j  t|kr*|jt|  |d kr8d}n d}|jt|krX|jt|  |	||  |j
|||| || |d d S NDZFD)r   )r   r   r   rU   r   r   r
   r   r   r   Zrectr*   r/   r0   r1   r2   r4   r   r8   r9   r   r   r   r   r   r   r	   r#     s    zFlexTemplate._rectc                O   s   | j }|j  t|kr*|jt|  |d kr8d}n d}|jt|krX|jt|  |	||  |j
|||| || |d d S r   )r   r   r   rU   r   r   r
   r   r   r   Zellipser   r   r   r	   r$     s    zFlexTemplate._ellipse)r/   r0   r1   r2   r;   c                O   s(   |r$| j j||||| || dd d S )Nr~   )rD   rB   link)r   image)r*   r/   r0   r1   r2   r;   r   r   r   r   r	   r"     s    zFlexTemplate._imageinterleaved 2of5 ntr   )	r/   r0   r1   r2   r;   r3   r4   r   r8   c       	         O   s^   | j }|j  t|	kr*|jt|	  |  }|dkrZ|j||||| || d d S )Nr   )rD   rB   )	r   r   r   rU   r   r   r
   ry   Zinterleaved2of5)r*   r/   r0   r1   r2   r;   r3   r4   r   r8   r   r   r   r   r   r	   r%     s    zFlexTemplate._barcodeg      ?)r/   r0   r2   r;   r4   r   r8   r@   rA   rD   rB   c                O   s   |d k	s |	d k	s |
d k	s |d k	r2t jdtt d | j}|j  t|kr\|j	t
|  || }|dkrpd}|||||| | d S )NzVcode39 arguments x/y/w/h are deprecated since v2.4.4, please use x1/y1/y2/size instead
stacklevelr      )warningswarnDeprecationWarningr   r   r   r   rU   r   r   r
   Zcode39)r*   r/   r0   r2   r;   r4   r   r8   r@   rA   rD   rB   r   r   r   r   r   r	   r&     s     zFlexTemplate._code39)r/   r0   r1   r2   r;   r3   r4   r   r5   r6   r7   r   r8   c                O   s   |sd S | j }|jt|kr*|jt|  |  }d}dD ]<}|d| dr>|d| dr>|dd }||7 }q>|	r|d7 }|
r|d	7 }|r|d
7 }|	||||  |
|| |d|| d S )Nr~   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r
   ry   rU   ro   r   r   r   write)r*   r/   r0   r1   r2   r;   r3   r4   r   r5   r6   r7   r   r8   r   r   r   r   r   r   r   r	   r'     s(    $
zFlexTemplate._write        c           	      C   s  t | jdd d}| j  |D ]}| }| j|d  |dd|d< |dkr|d | |d< |d	 | |d	< |d |d
 |d  |  |d
< |d	 |d |d	  |  |d< |r|d | |d< |d
 | |d
< |r|d	 | |d	< |d | |d< ||d< |d  }|r| j	|||d d|kr|d r| j	|d |d |d	  | j
| f | W 5 Q R X n| j
| f | W 5 Q R X q$d|kr|d r| j	|d |d |d	  | j
| f | W 5 Q R X q$| j
| f | q$W 5 Q R X i | _dS )a`  
        Add the contents of the template to the PDF document.

        Arguments:

            offsetx, offsety (float): Place the template to move its origin to the given coordinates.

            rotate (float): Rotate the inserted template around its (offset) origin.

            scale (float): Scale the inserted template by this factor.
        c                 S   s   | d S )Nr<   r   )r@   r   r   r	   <lambda>M      z%FlexTemplate.render.<locals>.<lambda>r   r-   r;   r~   r   r/   r0   r1   r2   r   r.   r>   N)sortedr+   r   Zlocal_contextcopyr)   rn   rU   upperZrotationr(   )	r*   ZoffsetxZoffsetyr>   r   Zsorted_elementsr   ZeleZhandler_namer   r   r	   renderA  s:    
"  zFlexTemplate.render)N)rf   )ru   rv   N)r   r   r   r   )rF   
__module____qualname____doc__r,   r   staticmethodrc   re   osPathLikerK   rt   r   r   setr   r   r   r    r!   r#   r$   r"   r%   r&   r'   r   r   r   r   r	   r      s   
J

$   O
,K&(r   c                
       s8   e Zd ZdZd fdd	Zd	d
 Zd fdd	Z  ZS )Templatezr
    A simple templating class.

    Allows to apply a single template definition to all pages of a document.
    NA4portraitmmr~   c                    s   |rt jdtt d dD ]$}tt | tstd| dqt|||d}|	| |
| ||	 || ||
 t j||d dS )	a  
        Arguments:

            infile (str): [**DEPRECATED since 2.2.0**] unused, will be removed in a later version

            elements (list of dicts): A template definition in a list of dicts.
                If you omit this, then you need to call either load_elements()
                or parse_csv() before doing anything else.

            format (str): The page format of the document (eg. "A4" or "letter").

            orientation (str): The orientation of the document.
                Possible values are "portrait"/"P" or "landscape"/"L"

            unit (str): The units used in the template definition.
                One of "mm", "cm", "in", "pt", or a number for points per unit.

            title (str): The title of the document.

            author (str): The author of the document.

            subject (str): The subject matter of the document.

            creator (str): The creator of the document.
        zD"infile" is deprecated since v2.2.0, unused and will soon be removedr   )formatorientationunittitleauthorsubjectcreatorkeywordsz
Argument "z" must be of type str.)r   r   r   )r   r+   N)r   r   r   r   r   localsrK   r   r   	set_titleZ
set_authorZset_creatorset_subjectset_keywordssuperr,   )r*   rg   r+   r   r   r   r   r   r   r   r   argr   	__class__r   r	   r,   x  s     &




zTemplate.__init__c                 C   s   | j jr|   | j   dS )z5Finish the current page, and proceed to the next one.N)r   pager   r   )r*   r   r   r	   r     s    zTemplate.add_pagec                    sV   |rt jdtt d | jjdddd | jjddd	 t   |rR| j	| d
S )aa  
        Finish the document and process all pending data.

        Arguments:

            outfile (str): If given, the PDF file will be written to this file name.
                Alternatively, the `.pdf.output()` method can be manually called.

            dest (str): [**DEPRECATED since 2.2.0**] unused, will be removed in a later version.
        zB"dest" is deprecated since v2.2.0, unused and will soon be removedr   r   r   r^   )r   r4   Fr   )marginN)
r   r   r   r   r   r   Zset_auto_page_breakr   r   r   )r*   outfiledestr   r   r	   r     s    
zTemplate.render)
NNr   r   r   r~   r~   r~   r~   r~   )NN)rF   r   r   r   r,   r   r   __classcell__r   r   r   r	   r   o  s   
          Ar   )r   
__author____copyright____license__r   r   rl   r   r   deprecationr   errorsr   Zfpdfr   r
   r   r   r   r   r   r   r	   <module>   s   (    Z