
    IR-e(                         d Z ddlZddlZ	 ddlmZ ej        Zej        Zn# e	$ r	 d Zd ZY nw xY w G d d          Z
dS )	zZ
Contains a class that makes it simple to stream out well-formed and
nicely-indented XML.
    N   )_iterparserc                     |                      dd          } |                      dd          } |                      dd          } | S )z<
        Escapes &, < and > in an XML CDATA string.
        &&amp;<&lt;>&gt;replacess    8lib/python3.11/site-packages/astropy/utils/xml/writer.pyxml_escape_cdatar      sB     IIc7##IIc6""IIc6""    c                     |                      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   s    r   
xml_escaper      sh     IIc7##IIc8$$IIc8$$IIc6""IIc6""r   c                       e Zd ZdZd ZddZi fdZej        dd            Z	ej        i fd	            Z
d
 Zd ZddZd Zddi fdZd Zd ZddZe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                     |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files     r   __init__zXMLWriter.__init__<   sX     Z
4!! 	$DJ


$ 0$r   TFc                 p   | j         r4|r|                     d           n|                     d           d| _         | j        rd                    | j                  }|r|                     d          }t          j        |||          }|                     d           |                     |                     |                     |                     d           |                     |                                            n(|                     |                     |                     g | _        dS 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datas       r   _flushzXMLWriter._flushM   s2    : 	  

5!!!!

3DJ: 	774:&&D 
844Q77}6   

4   

40066777

4   

466889999

40066777DJJJ	 	r   c                 \   |                                   g | _        | j                            |           |                     |                     d                     |                     d|            |s|r|                                }|                    |           t          |	                                          }|
                                 |D ]8\  }}|1|                     |          }|                     d| d| d           9d| _        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   )r1   r   r   appendr   r+   copyupdatelistitemssortr   r   len)r!   tagattribextrakvs         r   startzXMLWriter.startf   s   , 	 

#

4..r22333

9s99 
	.U 
	.[[]]FMM%   &,,..))FKKMMM . .1= **AJJ}1}}}}}---
4:r   
escape_xmlc              +      K   | j         }|dk    r3	 ddln# t          $ r t          d          w xY wi fd| _         n$|dk    r	d | _         n|dk    rt          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.
        bleach_cleanr   NzTbleach package is required when HTML escaping is disabled.
Use "pip install bleach".c                       j         | fi S N)clean)xbleachclean_kwargss    r   <lambda>z/XMLWriter.xml_cleaning_method.<locals>.<lambda>   s    lfl1.M.M.M.M r   nonec                     | S rF    )rH   s    r   rK   z/XMLWriter.xml_cleaning_method.<locals>.<lambda>   s    a r   rB   zEallowed values of method are "escape_xml", "bleach_clean", and "none")r   rI   ImportError
ValueError)r!   methodrJ   current_xml_escape_cdatarI   s     ` @r   xml_cleaning_methodzXMLWriter.xml_cleaning_method   s      J $(#8 ^##    0   #!$M$M$M$M$MD!!v$/KD!!|##W   	 8s    2c              +   Z   K    | j         ||fi | dV  |                     |           dS )aT  
        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)rA   end)r!   r<   r=   r>   s       r   r<   zXMLWriter.tag   s@       	
3((%(((r   c                     |                                   |                     |                                            |                     d|                     |           d           dS )z
        Adds a comment to the output stream.

        Parameters
        ----------
        comment : str
            Comment text, as a Unicode string.
        z<!-- z -->
N)r1   r   r+   r   )r!   comments     r   rW   zXMLWriter.comment   sa     	

4..00111

A40099AAABBBBBr   c                 :    | j                             |           dS )z
        Adds character data to the output stream.

        Parameters
        ----------
        text : str
            Character data, as a Unicode string.
        N)r   r5   )r!   texts     r   r0   zXMLWriter.data   s      	
$r   Nc                 
   |rL| j         st          d| d          || j         d         k    r t          d| j         d          d|           n| j         st          d          | j                                         }| j        r|                     ||           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()r3   zexpected end(z), got zunbalanced end()r   z/>
Nz</r%   )r   rP   popr   r1   r   r   r+   )r!   r<   r.   r/   s       r   rU   zXMLWriter.end   s&     	5: ; !93!9!9!9:::djn$$ !MB!M!M!M!MNNN % : 5 !3444jnn: 	KK%%%%Z 	DJJJvF 	6JJt2244555

====!!!!!r   c                     t          | j                  |k    r.|                                  t          | j                  |k    ,dS 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)r;   r   rU   )r!   ids     r   closezXMLWriter.close  sE     $*oo""HHJJJ $*oo""""""r   c                      | j         ||fi | |r|                     |           |                     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)rA   r0   rU   )r!   r<   rY   r/   r=   r>   s         r   elementzXMLWriter.element(  sS     	
3((%((( 	IIdOOOD)))))r   c                     d S rF   rN   r!   s    r   r   zXMLWriter.flush3  s    r   c                 *    t          | j                  S )z\
        Returns the number of indentation levels the file is currently
        in.
        )r;   r   rc   s    r   get_indentationzXMLWriter.get_indentation6  s    
 4:r   r   c                 J    | j         dt          | j                  |z            S )z`
        Returns a string of spaces that matches the current
        indentation level.
        N)r    r;   r   )r!   offsets     r   r+   z XMLWriter.get_indentation_spaces=  s%    
  !;3tz??V#;!;<<r   c                     i }|D ]F}t          | |          4t          t          | |                    ||                    dd          <   G|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attrs       r   object_attrszXMLWriter.object_attrsD  sZ    *  	D 	DDsD!!-,/T0B0B,C,C$,,sC(()r   )TF)rB   )NTF)r   )__name__
__module____qualname____doc__r#   r1   rA   
contextlibcontextmanagerrS   r<   rW   r0   rU   r_   ra   r   re   r+   staticmethodrq   rN   r   r   r   r   (   sU        &% % %"   2 !# * * * *X =9 =9 =9 =9~      $C C C	  	  	 " " " "<   !%5 	* 	* 	* 	*    = = = =   \  r   r   )ru   rv   r,   r&   r   escape_xml_cdatar   rB   r   rO   r   rN   r   r   <module>rz      s         (0 #3'JJ1      	 	 	 	 	6u u u u u u u u u us   ! //