o
    Ni8                     @   s  d Z ddlZddlm  mZ dZ	 G dd dej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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 d0d1 d1eZG d2d3 d3eZG d4d5 d5eZ G d6d7 d7eZ!G d8d9 d9e	Z"G d:d; d;e	Z#dS )<ah  MathML element classes based on `xml.etree`.

The module is intended for programmatic generation of MathML
and covers the part of `MathML Core`_ that is required by
Docutil's *TeX math to MathML* converter.

This module is PROVISIONAL:
the API is not settled and may change with any minor Docutils version.

.. _MathML Core: https://www.w3.org/TR/mathml-core/
    N)classdirdisplaystyleidnoncescriptlevelstyletabindexc                       s   e Zd ZdZdZ	 dZ	  fddZedd Zdd Z	d	d
 Z
 fddZ fddZdd Zdd Z fddZdd Zd$ddZdd Zd%ddZd d! Zd&d"d#Z  ZS )'MathElementzBase class for MathML elements.Nc                    s<    fdd|  D }t j jjfi |  | dS )a  Set up node with `children` and `attributes`.

        Attribute names are normalised to lowercase.
        You may use "CLASS" to set a "class" attribute.
        Attribute values are converted to strings
        (with True -> "true" and False -> "false").

        >>> math(CLASS='test', level=3, split=True)
        math(class='test', level='3', split='true')
        >>> math(CLASS='test', level=3, split=True).toxml()
        '<math class="test" level="3" split="true"></math>'

        c                    s    i | ]\}}|   |qS  )lowera_str.0kvselfr   W/home/ubuntu/.local/lib/python3.10/site-packages/docutils/utils/math/mathml_elements.py
<dictcomp>O   s     z(MathElement.__init__.<locals>.<dictcomp>N)itemssuper__init__	__class____name__extend)r   children
attributesattribr   r   r   r   A   s   zMathElement.__init__c                 C   s   t | trt|  S t| S N)
isinstanceboolstrr   )r   r   r   r   r   S   s   
zMathElement.a_strc                 C   s   dd | D }| j r|t| j  | j| jjkr"|d| j  t| ddr-|d |dd |  D 7 }| j dd	| d
S )z"Return full string representation.c                 S   s   g | ]}t |qS r   )reprr   childr   r   r   
<listcomp>\   s    z(MathElement.__repr__.<locals>.<listcomp>z
nchildren=switchNzswitch=Truec                 S   s&   g | ]\}}|d ur| d|qS )N=r   r   r   r   r   r'   c   s   & (, ))	textappendr$   	nchildrenr   getattrr   tagjoinr   argsr   r   r   __repr__Z   s   
zMathElement.__repr__c                 C   s8   | j r	t| j }n
ddd | D }| j d| dS )z/Return concise, informal string representation.r+   c                 s   s    | ]}| V  qd S r    r   r%   r   r   r   	<genexpr>k   s    z&MathElement.__str__.<locals>.<genexpr>r*   r,   )r-   r$   r2   r1   r3   r   r   r   __str__f   s   zMathElement.__str__c                    s   t  || | d S r    )r   setr   )r   keyvaluer   r   r   r8   n   s   zMathElement.setc                    s   | j dkrtd|  dt|tr| |_n"| j r0t| t| | j kr0td|  d| j  d|D ]}| |_q2t || d S )Nr   	Element "z" does not take children.z" takes only 	 children)r/   	TypeErrorr!   r
   parentlenr   __setitem__)r   r9   r:   er   r   r   r@   q   s   

zMathElement.__setitem__c                 C   s   | j duot| | j kS )z;Return boolean indicating whether children may be appended.N)r/   r?   r   r   r   r   is_full~   s   zMathElement.is_fullc                 C   s:   t | | _| j}|dur| r|j}|dur| s|S )z:Close element and return first non-full anchestor or None.N)r?   r/   r>   rB   )r   r>   r   r   r   close   s   
zMathElement.closec                    s^   |   r| jrd| j d}nd}td|  d| dt | | |_|   r-|  S | S )aL  Append `element` and return new "current node" (insertion point).

        Append as child element and set the internal `parent` attribute.

        If self is already full, raise TypeError.

        If self is full after appending, call `self.close()`
        (returns first non-full anchestor or None) else return `self`.
        ztakes only r<   zdoes not take childrenr;   z" .)rB   r/   r=   r   r.   r>   rC   )r   elementstatusr   r   r   r.      s   
zMathElement.appendc                 C   s   | }|D ]}|  |}q|S )ziSequentially append `elements`. Return new "current node".

        Raise TypeError if overfull.
        )r.   )r   elementscurrent_noderE   r   r   r   r      s   zMathElement.extendc                 C   s   | | }| |= |S r    r   )r   indexrE   r   r   r   pop   s   zMathElement.popc                 C   s>   |  ddu rz| j W S  ty   Y dS w |  ddkS )zReturn True, if `self` or an ancestor has ``display='block'``.

        Used to find out whether we are in inline vs. displayed maths.
        displayNFblock)getr>   in_blockAttributeErrorr   r   r   r   rO      s   zMathElement.in_block  r   c                 C   s   t | || dS )zFormat XML output with indents.

        Use with care:
          Formatting whitespace is permanently added to the
          `text` and `tail` attributes of `self` and anchestors!
        N)ETindent)r   spacelevelr   r   r   
indent_xml   s   zMathElement.indent_xmlc                 C   s@   |   D ]}t|ts|jr|j |_|jr|j |_qdS )zStrip whitespace at the end of `text` and `tail` attributes...

        to revert changes made by the `indent_xml()` method.
        Use with care, trailing whitespace from the original may be lost.
        N)iterr!   	MathTokenr-   rstriptail)r   rA   r   r   r   unindent_xml   s   zMathElement.unindent_xmlc                 C   sN   t j| |pddd}z	|dd}W |S  ty&   |d|d}Y |S w )a  Return an XML representation of the element.

        By default, the return value is a `str` instance. With an explicit
        `encoding` argument, the result is a `bytes` instance in the
        specified encoding. The XML default encoding is UTF-8, any other
        encoding must be specified in an XML document header.

        Name and encoding handling match `xml.dom.minidom.Node.toxml()`
        while `etree.Element.tostring()` returns `bytes` by default.
        unicodeF)short_empty_elementsu   ⁡z&ApplyFunction;s   &ApplyFunction;)rR   tostringreplacer=   encode)r   encodingxmlr   r   r   toxml   s   zMathElement.toxml)rI   )rQ   r   r    )r   
__module____qualname____doc__r/   r>   r   staticmethodr   r5   r7   r8   r@   rB   rC   r.   r   rK   rO   rV   r[   rc   __classcell__r   r   r   r   r
   8   s,    



	r
   c                   @      e Zd ZdZdS )MathRowz:Base class for elements treating content as a single mrow.Nr   rd   re   rf   r   r   r   r   rj          rj   c                       s0   e Zd ZdZdZ fddZ fddZ  ZS )
MathSchemazBase class for schemata expecting 2 or more children.

    The special attribute `switch` indicates that the last two child
    elements are in reversed order and must be switched before XML-export.
    See `msub` for an example.
       c                    s$   | dd| _t j|i | d S )Nr(   F)rK   r(   r   r   )r   r   kwargsr   r   r   r      s   zMathSchema.__init__c                    s>   t  |}| jr|  r| d | d | d< | d< d| _|S )z2Append element. Normalize order and close if full.rI   F)r   r.   r(   rB   )r   rE   rH   r   r   r   r.     s
   zMathSchema.append)r   rd   re   rf   r/   r   r.   rh   r   r   r   r   rm      s
    rm   c                       s$   e Zd ZdZdZ fddZ  ZS )rX   zgToken Element: contains textual data instead of children.

    Expect text data on initialisation.
    r   c                    s@   t  jdi | t|ttjfstd| dt|| _d S )Nz0MathToken element expects `str` or number, not "z".r   )r   r   r!   r#   numbersNumber
ValueErrorr-   )r   r-   r   r   r   r   r     s   
zMathToken.__init__)r   rd   re   rf   r/   r   rh   r   r   r   r   rX     s    rX   c                   @   ri   )mathz8Top-level MathML element, a single mathematical formula.Nrk   r   r   r   r   rt   !  rl   rt   c                   @   ri   )mtextz*Arbitrary text with no notational meaning.Nrk   r   r   r   r   ru   (  rl   ru   c                   @   ri   )mizCIdentifier, such as a function name, variable or symbolic constant.Nrk   r   r   r   r   rv   ,  rl   rv   c                   @   ri   )mnzNumeric literal.

    >>> mn(3.41).toxml()
    '<mn>3.41</mn>'

    Normally a sequence of digits with a possible separator (a dot or a comma).
    (Values with comma must be specified as `str`.)
    Nrk   r   r   r   r   rw   0  rl   rw   c                   @   ri   )moa  Operator, Fence, Separator, or Accent.

    >>> mo('<').toxml()
    '<mo>&lt;</mo>'

    Besides operators in strict mathematical meaning, this element also
    includes "operators" like parentheses, separators like comma and
    semicolon, or "absolute value" bars.
    Nrk   r   r   r   r   rx   ;  rl   rx   c                   @      e Zd ZdZdZdS )mspacezBlank space, whose size is set by its attributes.

    Takes additional attributes `depth`, `height`, `width`.
    Takes no children and no text.

    See also `mphantom`.
    r   Nr   rd   re   rf   r/   r   r   r   r   rz   G  s    rz   c                       s(   e Zd ZdZdd Z fddZ  ZS )mrowzyGeneric element to group children as a horizontal row.

    Removed on closing if not required (see `mrow.close()`).
    c                 C   sd   ddd}|   D ]&\}}|dv r)|r)||r)|| |||| |f}||| q	dS )zTransfer attributes from self to other.

        "List values" (class, style) are appended to existing values,
        other values replace existing values.
         z; )r   r   N)r   rN   r2   rY   r8   )r   other
delimitersr   r   r   r   r   transfer_attributes[  s   

zmrow.transfer_attributesc              	      sl   | j }|dur1t| dkr1| d }z||t|| < ||_ W n ttfy+   Y dS w | | t  S )z|Close element and return first non-full anchestor or None.

        Remove <mrow> if it has only one child element.
        N   r   )	r>   r?   listrJ   rP   rs   r   r   rC   )r   r>   r&   r   r   r   rC   i  s   


z
mrow.close)r   rd   re   rf   r   rC   rh   r   r   r   r   r|   U  s    r|   c                   @   ri   )mfraczAFractions or fraction-like objects such as binomial coefficients.Nrk   r   r   r   r   r   {  rl   r   c                   @   ry   )msqrtzSquare root. See also `mroot`.r   Nr{   r   r   r   r   r         r   c                   @   ri   )mrootz/Roots with an explicit index. See also `msqrt`.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )mstylezStyle Change.

    In modern browsers, <mstyle> is equivalent to an <mrow> element.
    However, <mstyle> may still be relevant for compatibility with
    MathML implementations outside browsers.
    Nrk   r   r   r   r   r     rl   r   c                   @   ri   )merrorz#Display contents as error messages.Nrk   r   r   r   r   r     rl   r   c                   @   ry   )menclosezRenders content inside an enclosing notation...

    ... specified by the notation attribute.

    Non-standard but still required by Firefox for boxed expressions.
    r   Nr{   r   r   r   r   r     s    r   c                   @   ri   )mpaddedzAdjust space around content.Nrk   r   r   r   r   r     rl   r   c                   @   ry   )mphantomz8Placeholder: Rendered invisibly but dimensions are kept.r   Nr{   r   r   r   r   r     r   r   c                   @   ri   )msubz$Attach a subscript to an expression.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )msupz&Attach a superscript to an expression.Nrk   r   r   r   r   r     rl   r   c                   @   ry   )msubsupz;Attach both a subscript and a superscript to an expression.   Nr{   r   r   r   r   r     r   r   c                   @   ri   )munderz0Attach an accent or a limit under an expression.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )moverz/Attach an accent or a limit over an expression.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )
munderoverz;Attach accents or limits both under and over an expression.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )mtablezTable or matrix element.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )mtrzRow in a table or a matrix.Nrk   r   r   r   r   r     rl   r   c                   @   ri   )mtdzCell in a table or a matrixNrk   r   r   r   r   r     rl   r   )$rf   rq   xml.etree.ElementTreeetreeElementTreerR   GLOBAL_ATTRIBUTESElementr
   rj   rm   rX   rt   ru   rv   rw   rx   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sD   	 9&	
