U
    ;c$                     @   sj   d dl Zd dlZd dlZddd dD ZedeZedZG dd	 d	e	Z
G d
d de	ZdS )    N|c                 c   s   | ]}d  |V  qdS )z[{0}]N)format).0r r   2/tmp/pip-unpacked-wheel-c8awha23/dict2xml/logic.py	<genexpr>   s   r   )u   À-Öu   Ø-öu   ø-˿u   Ͱ-ͽu   Ϳ-῿u   ‌-‍u   ⁰-↏u   Ⰰ-⿯u   、-퟿u   豈-﷏u   ﷰ-�z(:|[A-Z]|_|[a-z]|{0})z2(\-|\.|[0-9]|\xB7|[\u0300-\u036F]|[\u203F-\u2040])c                   @   sH   e Zd ZdZdddgZddd	Zd
d Zdd Zdd Ze	dd Z
dS )Nodea  
    Represents each tag in the tree

    Each node has _either_ a single value or one or more children
    If it has a value:
        The serialized result is <%(tag)s>%(value)s</%(tag)s>

    If it has children:
        The serialized result is
            <%(wrap)s>
                %(children)s
            </%(wrap)s>

    Which one it is depends on the implementation of self.convert
    )&z&amp;)<z&lt;)>z&gt; NTc                 C   sn   |  || _|  || _|| _|  | _|| _|| _| jdkrjt| jt	rj| j
D ]\}}| j||| _qPd S )Nflat)sanitize_elementtagwrapdatadetermine_typetypeclosed_tags_foriterables_repeat_wrap
isinstancestrentitiesreplace)selfr   r   r   r   r   entityreplacementr   r   r   __init__2   s    
zNode.__init__c           
         s$  | j }d\}}|r&d|}d|}| jrD| j| jkrDd| j S |  \}}d}|r| jdkr~  fdd|D |}n| jrg }|D ]F}	|	 }|	jd	kr|| q |gd
}|d	|||f q |dS g }|D ]}	||	  qd	| |d
|gS d	||||fS )z,Returns the Node serialized as an xml string)r   r   z</{0}>z<{0}>z<{0}/>r   iterablec                 3   s   | ]}|  V  qd S )N)	serializer   cindenterr   r   r   U   s     z!Node.serialize.<locals>.<genexpr>r   TF)
r   r   r   r   convertr   r   r    appendjoin)
r   r$   r   endstartvaluechildrencontentresultr"   r   r#   r   r    A   s4    





zNode.serializec                 C   s@   | j }t|trdS t|tjjr&dS t|tjjr8dS dS dS )a  
        Return the type of the data on this node as an identifying string

        * Iterable : Supports "for item in data"
        * Mapping : Supports "for key in data: value = data[key]"
        * flat : A string or something that isn't iterable or a mapping
        r   mappingr   N)r   r   r   collectionsabcMappingIterable)r   r   r   r   r   r   q   s    
zNode.determine_typec              
   C   s   d}| j }| j}g }|dkrd|}t|tjs4t|}|D ](}|| }|t|d|| j| j	d q8nR|dkr|D ]"}|td| j
|| j| j	d qpn t|}| jrd| j|| j}||fS )a  
        Convert data on this node into a (value, children) tuple depending on the type of the data
        If the type is :
            * flat : Use self.tag to surround the value. <tag>value</tag>
            * mapping : Return a list of tags where the key for each child is the wrap for that node
            * iterable : Return a list of Nodes where self.wrap is the tag for that node
        r   r.   )r   r   r   z<{0}>{1}</{2}>)r   r   r   r/   OrderedDictsortedr&   r	   r   r   r   r   r   r   )r   valtypr   r+   Zsorted_datakeyitemr   r   r   r%      sD    
zNode.convertc                 C   sT   | rLt | trL|  dr$d|  } dt| s6dndgdd | D  S | S dS )a  
        Convert `wrap` into a valid tag name applying the XML Naming Rules.

            * Names can contain letters, numbers, and other characters
            * Names cannot start with a number or punctuation character
            * Names cannot start with the letters xml (or XML, or Xml, etc)
            * Names cannot contain spaces
            * Any name can be used, no words are reserved.

        :ref: http://www.w3.org/TR/REC-xml/#NT-NameChar
        xml_r   c                 S   s(   g | ] }t |s t|s d n|qS )r:   )NameStartCharmatchNameCharr!   r   r   r   
<listcomp>   s     z)Node.sanitize_element.<locals>.<listcomp>N)r   r   lower
startswithr'   r;   r<   )r   r   r   r   r      s    zNode.sanitize_element)r   r   NTN)__name__
__module____qualname____doc__r   r   r    r   r%   staticmethodr   r   r   r   r   r	      s   
         
01r	   c                   @   s,   e Zd ZdZdddZdd Zdd	d
ZdS )	ConverterzFLogic for creating a Node tree and serialising that tree into a stringN  Tc                 C   s   || _ || _|| _dS )aI  
        wrap: The tag that the everything else will be contained within
        indent: The string that is multiplied at the start of each new line, to represent each level of nesting
        newlines: A boolean specifying whether we want each tag on a new line.

        Note that indent only works if newlines is True
        N)r   indentnewlines)r   r   rH   rI   r   r   r   r      s    zConverter.__init__c                    s<   | j | j}|sdd }ns"ddd   fdd}|S )zdReturns a function that given a list of strings, will return that list as a single, indented, stringc                 S   s
   d | S )Nr   )r'   )nodeswrappedr   r   r   <lambda>       z*Converter._make_indenter.<locals>.<lambda>r   c                 s   s$   | D ]}| dD ]
}|V  qqdS )zYield each line in each node
N)split)rJ   nodeliner   r   r   eachline   s    z*Converter._make_indenter.<locals>.eachlinec                    s6   |rd }d }nd}d}| | | S )a"  
                Indent nodes depending on value of wrapped and indent
                If not wrapped, then don't indent
                Otherwise,
                    Seperate each child by a newline
                    and indent each line in the child by one indent unit
                z
{0}z

{0}{{0}}
rN   z{0})r   r'   )rJ   rK   Z	seperatorZsurroundingrR   rH   r   r   ret   s    
z%Converter._make_indenter.<locals>.ret)rH   rI   )r   rI   rT   r   rS   r   _make_indenter   s    
zConverter._make_indenterc                 C   s    |   }t| j|||d|S )zICreate a Node tree from the data and return it as a serialized xml string)r   r   r   r   )rU   r	   r   r    )r   r   r   r   r$   r   r   r   build  s    zConverter.build)NrG   T)TN)rA   rB   rC   rD   r   rU   rV   r   r   r   r   rF      s   
$rF   )collections.abcr/   rer'   Zstart_rangescompiler   r;   r=   objectr	   rF   r   r   r   r   <module>   s   

 4