U
    e»{jµ(  ã                   @   sh   d Z ddlZddlZzddlmZ W n$ ek
rH   dd„ Zdd„ ZY nX ejZej	ZG d	d
„ d
ƒZ
dS )zZ
Contains a class that makes it simple to stream out well-formed and
nicely-indented XML.
é    Né   )Ú_iterparserc                 C   s(   |   dd¡} |   dd¡} |   dd¡} | S )z<
        Escapes &, < and > in an XML CDATA string.
        ú&ú&amp;ú<ú&lt;ú>ú&gt;©Úreplace©Ús© r   úW/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/utils/xml/writer.pyÚxml_escape_cdata   s    r   c                 C   s@   |   dd¡} |   dd¡} |   dd¡} |   dd¡} |   d	d
¡} | S )zE
        Escapes &, ', ", < and > in an XML attribute value.
        r   r   ú'z&apos;ú"z&quot;r   r   r   r	   r
   r   r   r   r   Ú
xml_escape   s    r   c                   @   s¨   e Zd ZdZdd„ Zd#dd„Zi fdd	„Zejd$dd„ƒZ	eji fdd„ƒZ
dd„ Zdd„ Zd%dd„Zdd„ Zddi fdd„Zdd„ Zdd„ Zd&dd „Zed!d"„ ƒZdS )'Ú	XMLWriteraN  
    A class to write well-formed and nicely indented XML.

    Use like this::

        w = XMLWriter(fh)
        with w.tag('html'):
            with w.tag('body'):
                w.data('This is the content')

    Which produces::

        <html>
         <body>
          This is the content
         </body>
        </html>
    c                 C   sB   |j | _ t|dƒr|j| _d| _g | _g | _d| _t| _t| _dS )zQ
        Parameters
        ----------
        file : writable file-like
        Úflushr   z@                                                                N)	ÚwriteÚhasattrr   Ú_openÚ_tagsÚ_dataÚ_indentationr   r   )ÚselfÚfiler   r   r   Ú__init__<   s    
zXMLWriter.__init__TFc                 C   s¤   | j r&|r|  d¡ n
|  d¡ d| _ | jr d | j¡}|rŠ|  d¡}tj|||d�}|  d¡ |  |  |¡¡ |  d¡ |  |  ¡ ¡ n|  |  |¡¡ g | _dS )	z)
        Flush internal buffers.
        ú>
r   r   Ú r   )Úinitial_indentÚsubsequent_indentÚ
N)r   r   r   ÚjoinÚget_indentation_spacesÚtextwrapÚfillr   )r   ÚindentÚwrapÚdatar   r   r   Ú_flushM   s(    

  ÿ

zXMLWriter._flushc                 K   s°   |   ¡  g | _| j |¡ |  |  d¡¡ |  d|› �¡ |sB|r | ¡ }| |¡ t| 	¡ ƒ}| 
¡  |D ]2\}}|dk	rl|  |¡}|  d|› d|› d�¡ qld| _t| jƒS )am  
        Opens a new element.  Attributes can be given as keyword
        arguments, or as a string/string dictionary.  The method
        returns an opaque identifier that can be passed to the
        :meth:`close` method, to close all open elements up to and
        including this one.

        Parameters
        ----------
        tag : str
            The element name

        attrib : dict of str -> str
            Attribute dictionary.  Alternatively, attributes can
            be given as keyword arguments.

        Returns
        -------
        id : int
            Returns an element identifier.
        éÿÿÿÿr   Nú z="r   r   )r+   r   r   Úappendr   r%   ÚcopyÚupdateÚlistÚitemsÚsortr   r   Úlen)r   ÚtagÚattribÚextraÚkÚvr   r   r   Ústartf   s     

zXMLWriter.startÚ
escape_xmlc                 +   sŠ   | j }|dkrVzddl‰ W n tk
r6   tdƒ‚Y nX ˆdkrDi ‰‡ ‡fdd„| _ n$|dkrjdd„ | _ n|d	krztd
ƒ‚dV  || _ dS )a[  Context manager to control how XML data tags are cleaned (escaped) to
        remove potentially unsafe characters or constructs.

        The default (``method='escape_xml'``) applies brute-force escaping of
        certain key XML characters like ``<``, ``>``, and ``&`` to ensure that
        the output is not valid XML.

        In order to explicitly allow certain XML tags (e.g. link reference or
        emphasis tags), use ``method='bleach_clean'``.  This sanitizes the data
        string using the ``clean`` function of the
        `bleach <https://bleach.readthedocs.io/en/latest/clean.html>`_ package.
        Any additional keyword arguments will be passed directly to the
        ``clean`` function.

        Finally, use ``method='none'`` to disable any sanitization. This should
        be used sparingly.

        Example::

          w = writer.XMLWriter(ListWriter(lines))
          with w.xml_cleaning_method('bleach_clean'):
              w.start('td')
              w.data('<a href="https://google.com">google.com</a>')
              w.end()

        Parameters
        ----------
        method : str
            Cleaning method.  Allowed values are "escape_xml",
            "bleach_clean", and "none".

        **clean_kwargs : keyword args
            Additional keyword args that are passed to the
            bleach.clean() function.
        Zbleach_cleanr   NzTbleach package is required when HTML escaping is disabled.
Use "pip install bleach".c                    s   ˆ j | fˆŽS ©N)Úclean©Úx©ÚbleachÚclean_kwargsr   r   Ú<lambda>Æ   ó    z/XMLWriter.xml_cleaning_method.<locals>.<lambda>Únonec                 S   s   | S r<   r   r>   r   r   r   rC   È   rD   r;   zEallowed values of method are "escape_xml", "bleach_clean", and "none")r   rA   ÚImportErrorÚ
ValueError)r   ÚmethodrB   Zcurrent_xml_escape_cdatar   r@   r   Úxml_cleaning_method’   s&    %ÿ
ÿzXMLWriter.xml_cleaning_methodc                 k   s$   | j ||f|Ž dV  |  |¡ dS )aU  
        A convenience method for creating wrapper elements using the
        ``with`` statement.

        Examples
        --------

        >>> with writer.tag('foo'):  # doctest: +SKIP
        ...     writer.element('bar')
        ... # </foo> is implicitly closed here
        ...

        Parameters are the same as to `start`.
        N)r:   Úend)r   r5   r6   r7   r   r   r   r5   Ò   s    zXMLWriter.tagc                 C   s2   |   ¡  |  |  ¡ ¡ |  d|  |¡› d�¡ dS )z¢
        Adds a comment to the output stream.

        Parameters
        ----------
        comment : str
            Comment text, as a Unicode string.
        z<!-- z -->
N)r+   r   r%   r   )r   Úcommentr   r   r   rK   æ   s    	zXMLWriter.commentc                 C   s   | j  |¡ dS )z¦
        Adds character data to the output stream.

        Parameters
        ----------
        text : str
            Character data, as a Unicode string.
        N)r   r.   )r   Útextr   r   r   r*   ó   s    	zXMLWriter.dataNc                 C   s²   |rD| j std|› d�ƒ‚|| j d krRtd| j d › d|› �ƒ‚n| j sRtdƒ‚| j  ¡ }| jrp|  ||¡ n| jrŠd| _|  d¡ d	S |rœ|  |  ¡ ¡ |  d
|› d�¡ d	S )a  
        Closes the current element (opened by the most recent call to
        `start`).

        Parameters
        ----------
        tag : str
            Element name.  If given, the tag must match the start tag.
            If omitted, the current element is closed.
        zunbalanced end(ú)r,   zexpected end(z), got zunbalanced end()r   z/>
Nz</r   )r   rG   Úpopr   r+   r   r   r%   )r   r5   r(   r)   r   r   r   rJ   þ   s"    

zXMLWriter.endc                 C   s   t | jƒ|kr|  ¡  q dS )zð
        Closes open elements, up to (and including) the element identified
        by the given identifier.

        Parameters
        ----------
        id : int
            Element identifier, as returned by the `start` method.
        N)r4   r   rJ   )r   Úidr   r   r   Úclose  s    
zXMLWriter.closec                 K   s0   | j ||f|Ž |r|  |¡ | jd|d� dS )z¤
        Adds an entire element.  This is the same as calling `start`,
        `data`, and `end` in sequence. The ``text`` argument
        can be omitted.
        F)r(   r)   N)r:   r*   rJ   )r   r5   rL   r)   r6   r7   r   r   r   Úelement)  s    
zXMLWriter.elementc                 C   s   d S r<   r   ©r   r   r   r   r   4  s    zXMLWriter.flushc                 C   s
   t | jƒS )z\
        Returns the number of indentation levels the file is currently
        in.
        )r4   r   rR   r   r   r   Úget_indentation7  s    zXMLWriter.get_indentationr   c                 C   s   | j dt| jƒ| … S )z`
        Returns a string of spaces that matches the current
        indentation level.
        N)r   r4   r   )r   Úoffsetr   r   r   r%   >  s    z XMLWriter.get_indentation_spacesc                 C   s:   i }|D ],}t | |ƒdk	rtt | |ƒƒ|| dd¡< q|S )a  
        Converts an object with a bunch of attributes on an object
        into a dictionary for use by the `XMLWriter`.

        Parameters
        ----------
        obj : object
            Any Python object

        attrs : sequence of str
            Attribute names to pull from the object

        Returns
        -------
        attrs : dict
            Maps attribute names to the values retrieved from
            ``obj.attr``.  If any of the attributes is `None`, it will
            not appear in the output dictionary.
        NÚ_ú-)ÚgetattrÚstrr   )ÚobjÚattrsÚdÚattrr   r   r   Úobject_attrsE  s
    zXMLWriter.object_attrs)TF)r;   )NTF)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r+   r:   Ú
contextlibÚcontextmanagerrI   r5   rK   r*   rJ   rP   rQ   r   rS   r%   Ústaticmethodr]   r   r   r   r   r   (   s$   
,?

r   )ra   rb   r&   r    r   rF   r   r   Zescape_xml_cdatar;   r   r   r   r   r   Ú<module>   s   	