3
ƽh                @   s  d Z ddlmZ ddlZddlm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mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddl m!Z!m"Z#m$Z$ ddl%m&Z& dd	l'm(Z(m)Z)m*Z* dd
l+m,Z,m-Z-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3m4Z4 ej5  ej6e7Z8dddZ9G dd d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:ZAG dd  d ZBG d!d" d"eBZCG d#d$ d$eCZDG d%d& d&eCZEG d'd( d(eEZFG d)d* d*eFZGG d+d, d,eFZHG d-d. d.eEZIG d/d0 d0eIZJG d1d2 d2eBZKd3ZLd4eL ZMd5ZNG d6d7 d7ZOG d8d9 d9eOZPG d:d; d;eOZQG d<d= d=eOZRG d>d? d?eOZSG d@dA dAeOZTeTeTeSePePePePePePePeQeQeQeQeQeQeQeTeTdBZUdCdD ZVG dEdF dFeWZXG dGdH dHZYG dIdJ dJeYZZG dKdL dLeZZ[G dMdN dNeZZ\G dOdP dPeYZ]G dQdR dRe]Z^G dSdT dTeZZ_G dUdV dVe_Z`G dWdX dXe_ZaG dYdZ dZeZZbG d[d\ d\ebZcG d]d^ d^ebZded_d`Zeeedad4dbdadeedad4dcdadeedad4dddadeedadadd4dbeedadadd4dceedadadd4ddeedadaddadeedad4dbddbdeee_fG dfdg dgeYZge!jhdhG didj djZie!jj  dkdl eejfjk D ei_lW dQ R X e!jhdhdmdnG dodp dpegZme!jhdhdqdnG drds dsegZne!jhdhdtdnG dudv dvegZoe!jhdhdwdnG dxdy dyegZpe!jhdhdzdnG d{d| d|egZqe!jhdhd}dnG d~d degZre!jhdhddnG dd degZsG dd de`ZtG dd deaZuG dd deYZvG dd de`ZwG dd de`ZxG dd de`ZyG dd dZzez Z{dd Z|G dd dZ}G dd dZ~dddZdS )a0  
A module for parsing a subset of the TeX math syntax and rendering it to a
Matplotlib backend.

For a tutorial of its usage, see :doc:`/tutorials/text/mathtext`.  This
document is primarily concerned with implementation details.

The module uses pyparsing_ to parse the TeX expression.

.. _pyparsing: https://pypi.org/project/pyparsing/

The Bakoma distribution of the TeX Computer Modern fonts, and STIX
fonts are supported.  There is experimental support for using
arbitrary fonts, but results may vary without proper tweaking and
metrics for those fonts.
    )
namedtupleN)StringIO)Image)CombineEmpty
FollowedByForwardGroupLiteraloneOf	OneOrMoreOptionalParseBaseExceptionParseFatalExceptionParserElementQuotedStringRegex	StringEndSuppress
ZeroOrMore)cbookcolorsrcParams)AFM)FT2ImageKERNING_DEFAULTLOAD_NO_HINTING)findfontFontPropertiesget_font)latex_to_bakomalatex_to_standardtex2unilatex_to_cmexstix_virtual_fontsTc             C   s|   |st | S | dkrdS yt | S  tk
r4   Y nX yt| jd S  tk
rv } ztdj| |W Y dd}~X nX dS )aB  
    Return the integer index (from the Unicode table) of *symbol*.

    Parameters
    ----------
    symbol : str
        A single unicode character, a TeX command (e.g. r'\pi') or a Type1
        symbol name (e.g. 'phi').
    math : bool, default: True
        If False, always treat as a single unicode character.
    -i"  \z9'{}' is not a valid Unicode character or TeX/Type1 symbolN)ord	TypeErrorr"   stripKeyError
ValueErrorformat)symbolmatherr r0   9/tmp/pip-build-7iwl8md4/matplotlib/matplotlib/mathtext.pyget_unicode_index0   s    r2   c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )MathtextBackenda  
    The base class for the mathtext backend-specific code.  `MathtextBackend`
    subclasses interface between mathtext and specific Matplotlib graphics
    backends.

    Subclasses need to override the following:

    - :meth:`render_glyph`
    - :meth:`render_rect_filled`
    - :meth:`get_results`

    And optionally, if you need to use a FreeType hinting style:

    - :meth:`get_hinting_type`
    c             C   s   d| _ d| _d| _d S )Nr   )widthheightdepth)selfr0   r0   r1   __init__b   s    zMathtextBackend.__init__c             C   s   || _ || _|| _dS )z(Set the dimension of the drawing canvas.N)r4   r5   r6   )r7   whdr0   r0   r1   set_canvas_sizeg   s    zMathtextBackend.set_canvas_sizec             C   s
   t  dS )z_
        Draw a glyph described by *info* to the reference point (*ox*,
        *oy*).
        N)NotImplementedError)r7   oxoyinfor0   r0   r1   render_glyphm   s    zMathtextBackend.render_glyphc             C   s
   t  dS )zR
        Draw a filled black rectangle from (*x1*, *y1*) to (*x2*, *y2*).
        N)r=   )r7   x1y1x2y2r0   r0   r1   render_rect_filledt   s    z"MathtextBackend.render_rect_filledc             C   s
   t  dS )zp
        Return a backend-specific tuple to return to the backend after
        all processing is done.
        N)r=   )r7   boxr0   r0   r1   get_resultsz   s    zMathtextBackend.get_resultsc             C   s   t S )z\
        Get the FreeType hinting type to use with this particular
        backend.
        )r   )r7   r0   r0   r1   get_hinting_type   s    z MathtextBackend.get_hinting_typeN)
__name__
__module____qualname____doc__r8   r<   rA   rF   rH   rI   r0   r0   r0   r1   r3   R   s   r3   c               @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )MathtextBackendAggz
    Render glyphs and rectangles to an FTImage buffer, which is later
    transferred to the Agg image by the Agg backend.
    c             C   s4   d| _ d| _d | _d| _ddddg| _tj|  d S )Nr   bbox)r>   r?   imagemoderO   r3   r8   )r7   r0   r0   r1   r8      s    zMathtextBackendAgg.__init__c             C   sB   t | jd |t | jd |t| jd |t| jd |g| _d S )Nr            )minrO   max)r7   rB   rC   rD   rE   r0   r0   r1   _update_bbox   s    zMathtextBackendAgg._update_bboxc             C   s@   t j| ||| | jdkr<ttj|tj|t|d | _d S )NrO   r   )r3   r<   rQ   r   npceilrV   rP   )r7   r9   r:   r;   r0   r0   r1   r<      s    
z"MathtextBackendAgg.set_canvas_sizec             C   sf   | j dkr<| j||jj ||jj ||jj ||jj  n&|jj| j	|||jj
 |jtd d d S )NrO   ztext.antialiased)Zantialiased)rQ   rW   metricsxminymaxxmaxyminfontZdraw_glyph_to_bitmaprP   icebergglyphr   )r7   r>   r?   r@   r0   r0   r1   rA      s    


zMathtextBackendAgg.render_glyphc             C   s   | j dkr| j|||| nhtt|| d d}|dkr\|| d }t||d d  }nt|}| jjt||tj|||  d S )NrO   rR   r   g       @)rQ   rW   rV   intrP   Zdraw_rect_filledrX   rY   )r7   rB   rC   rD   rE   r5   centeryr0   r0   r1   rF      s    
z%MathtextBackendAgg.render_rect_filledc             C   s   d| _ |j}|j}tdd| | j}|d d |d d |d d |d d g}d| _ | j|d |d  |d |d  | |d |d  |  t|d  |d  | | j| j| j| j| j | j| j	|f}d | _	|S )NrO   r   rR   rS   rT   render)
rQ   r5   r6   shiprO   r<   r>   r?   r4   rP   )r7   rG   used_charactersZorig_heightZ
orig_depthrO   resultr0   r0   r1   rH      s*    ,
zMathtextBackendAgg.get_resultsc             C   s   ddl m} |j S )Nr   )backend_agg)matplotlib.backendsri   Zget_hinting_flag)r7   ri   r0   r0   r1   rI      s    z#MathtextBackendAgg.get_hinting_typeN)rJ   rK   rL   rM   r8   rW   r<   rA   rF   rH   rI   r0   r0   r0   r1   rN      s   rN   c               @   s   e Zd Zdd ZdS )MathtextBackendBitmapc       
      C   s$   t j| ||\}}}}}}}	||fS )N)rN   rH   )
r7   rG   rg   r>   r?   r4   r5   r6   rP   
charactersr0   r0   r1   rH      s    z!MathtextBackendBitmap.get_resultsN)rJ   rK   rL   rH   r0   r0   r0   r1   rk      s   rk   c               @   s:   e Zd ZdZeddZdd Zdd Zdd	 Zd
d Z	dS )MathtextBackendPszT
    Store information to write a mathtext rendering to the PostScript backend.
    	_PSResultz+width height depth pswriter used_charactersc             C   s   t  | _d | _d S )N)r   pswriterlastfont)r7   r0   r0   r1   r8      s    zMathtextBackendPs.__init__c             C   sv   | j | |j }|j}|j}||f| jkrN||f| _| jjd| d| d | jj|dd|dd|j d d S )N/z
 findfont
z scalefont
setfont
f z	 moveto
/z glyphshow
)r5   offsetpostscript_namefontsizerp   ro   writesymbol_name)r7   r>   r?   r@   ru   rv   r0   r0   r1   rA      s    
zMathtextBackendPs.render_glyphc             C   s.   d|| j | || || f }| jj| d S )Nz%f %f %f %f rectfill
)r5   ro   rw   )r7   rB   rC   rD   rE   psr0   r0   r1   rF      s    z$MathtextBackendPs.render_rect_filledc             C   s,   t dd| | j| j| j| j | j| j|S )Nr   )rf   rn   r4   r5   r6   ro   )r7   rG   rg   r0   r0   r1   rH      s    
zMathtextBackendPs.get_resultsN)
rJ   rK   rL   rM   r   rn   r8   rA   rF   rH   r0   r0   r0   r1   rm      s   rm   c               @   s:   e Zd ZdZeddZdd Zdd Zdd	 Zd
d Z	dS )MathtextBackendPdfzCStore information to write a mathtext rendering to the PDF backend.
_PDFResultz/width height depth glyphs rects used_charactersc             C   s   g | _ g | _d S )N)glyphsrects)r7   r0   r0   r1   r8     s    zMathtextBackendPdf.__init__c             C   s:   |j j}| j| |j }| jj||||j|j|jf d S )N)	r_   fnamer5   rt   r|   appendrv   numrx   )r7   r>   r?   r@   filenamer0   r0   r1   rA     s
    
zMathtextBackendPdf.render_glyphc             C   s&   | j j|| j| || || f d S )N)r}   r   r5   )r7   rB   rC   rD   rE   r0   r0   r1   rF     s    z%MathtextBackendPdf.render_rect_filledc             C   s0   t dd| | j| j| j| j | j| j| j|S )Nr   )rf   r{   r4   r5   r6   r|   r}   )r7   rG   rg   r0   r0   r1   rH     s    
zMathtextBackendPdf.get_resultsN)
rJ   rK   rL   rM   r   r{   r8   rA   rF   rH   r0   r0   r0   r1   rz     s   rz   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )MathtextBackendSvgzQ
    Store information to write a mathtext rendering to the SVG
    backend.
    c             C   s   g | _ g | _d S )N)
svg_glyphs	svg_rects)r7   r0   r0   r1   r8   (  s    zMathtextBackendSvg.__init__c             C   s4   | j | |j }| jj|j|j|j|||jf d S )N)r5   rt   r   r   r_   rv   r   rZ   )r7   r>   r?   r@   r0   r0   r1   rA   ,  s    zMathtextBackendSvg.render_glyphc             C   s*   | j j|| j| d || || f d S )NrR   )r   r   r5   )r7   rB   rC   rD   rE   r0   r0   r1   rF   2  s    z%MathtextBackendSvg.render_rect_filledc             C   s8   t dd| tj| j| jd}| j| j| j | j||fS )Nr   )r   r   )rf   typesSimpleNamespacer   r   r4   r5   r6   )r7   rG   rg   Zsvg_elementsr0   r0   r1   rH   6  s    

zMathtextBackendSvg.get_resultsN)rJ   rK   rL   rM   r8   rA   rF   rH   r0   r0   r0   r1   r   #  s
   r   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )MathtextBackendPathzY
    Store information to write a mathtext rendering to the text path
    machinery.
    c             C   s   g | _ g | _d S )N)r|   r}   )r7   r0   r0   r1   r8   G  s    zMathtextBackendPath.__init__c             C   s4   | j | |j }|j}| jj|j|j|||f d S )N)r5   rt   r   r|   r   r_   rv   )r7   r>   r?   r@   thetextr0   r0   r1   rA   K  s    z MathtextBackendPath.render_glyphc             C   s&   | j j|| j| || || f d S )N)r}   r   r5   )r7   rB   rC   rD   rE   r0   r0   r1   rF   Q  s    z&MathtextBackendPath.render_rect_filledc             C   s*   t dd| | j| j| j | j| j| jfS )Nr   )rf   r4   r5   r6   r|   r}   )r7   rG   rg   r0   r0   r1   rH   T  s    
zMathtextBackendPath.get_resultsN)rJ   rK   rL   rM   r8   rA   rF   rH   r0   r0   r0   r1   r   A  s
   r   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )MathtextBackendCairozS
    Store information to write a mathtext rendering to the Cairo
    backend.
    c             C   s   g | _ g | _d S )N)r|   r}   )r7   r0   r0   r1   r8   c  s    zMathtextBackendCairo.__init__c             C   s8   ||j  | j }t|j}| jj|j|j|||f d S )N)rt   r5   chrr   r|   r   r_   rv   )r7   r>   r?   r@   r   r0   r0   r1   rA   g  s    
z!MathtextBackendCairo.render_glyphc             C   s&   | j j||| j || || f d S )N)r}   r   r5   )r7   rB   rC   rD   rE   r0   r0   r1   rF   m  s    z'MathtextBackendCairo.render_rect_filledc             C   s*   t dd| | j| j| j | j| j| jfS )Nr   )rf   r4   r5   r6   r|   r}   )r7   rG   rg   r0   r0   r1   rH   q  s    
z MathtextBackendCairo.get_resultsN)rJ   rK   rL   rM   r8   rA   rF   rH   r0   r0   r0   r1   r   ]  s
   r   c               @   sr   e Zd ZdZdd Zdd Zdd Zdd	d
Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )Fontsz
    An abstract base class for a system of fonts to use for mathtext.

    The class must be able to take symbol keys and font file names and
    return the character metrics.  It also delegates to a backend class
    to do the actual drawing.
    c             C   s   || _ || _i | _dS )aG  
        Parameters
        ----------
        default_font_prop: `~.font_manager.FontProperties`
            The default non-math font, or the base font for Unicode (generic)
            font rendering.
        mathtext_backend: `MathtextBackend` subclass
            Backend to which rendering is actually delegated.
        N)default_font_propmathtext_backendrg   )r7   r   r   r0   r0   r1   r8     s    
zFonts.__init__c             C   s
   d| _ dS )za
        Fix any cyclical references before the object is about
        to be destroyed.
        N)rg   )r7   r0   r0   r1   destroy  s    zFonts.destroyc
       
      C   s   dS )av  
        Get the kerning distance for font between *sym1* and *sym2*.

        *fontX*: one of the TeX font names::

          tt, it, rm, cal, sf, bf or default/regular (non-math)

        *fontclassX*: TODO

        *symX*: a symbol in raw TeX form. e.g., '1', 'x' or '\sigma'

        *fontsizeX*: the fontsize in points

        *dpi*: the current dots-per-inch
        g        r0   )
r7   font1
fontclass1sym1	fontsize1font2
fontclass2sym2	fontsize2dpir0   r0   r1   get_kern  s    zFonts.get_kernTc             C   s   | j ||||||}|jS )a  
        *font*: one of the TeX font names::

          tt, it, rm, cal, sf, bf or default/regular (non-math)

        *font_class*: TODO

        *sym*:  a symbol in raw TeX form. e.g., '1', 'x' or '\sigma'

        *fontsize*: font size in points

        *dpi*: current dots-per-inch

        *math*: whether sym is a math character

        Returns an object with the following attributes:

        - *advance*: The advance distance (in points) of the glyph.

        - *height*: The height of the glyph in points.

        - *width*: The width of the glyph in points.

        - *xmin*, *xmax*, *ymin*, *ymax* - the ink rectangle of the glyph

        - *iceberg* - the distance from the baseline to the top of
          the glyph.  This corresponds to TeX's definition of "height".
        )	_get_inforZ   )r7   r_   
font_classsymrv   r   r.   r@   r0   r0   r1   get_metrics  s    zFonts.get_metricsc             C   s6   t j|||g\| _| _| _| jj| j| j| j dS )z
        Set the size of the buffer used to render the math expression.
        Only really necessary for the bitmap backends.
        N)rX   rY   r4   r5   r6   r   r<   )r7   r9   r:   r;   r0   r0   r1   r<     s    zFonts.set_canvas_sizec       	      C   sB   | j |||||}| jj|jjt j|j | jj	||| dS )a  
        Draw a glyph at

          - *ox*, *oy*: position

          - *facename*: One of the TeX face names

          - *font_class*:

          - *sym*: TeX symbol name or single character

          - *fontsize*: fontsize in points

          - *dpi*: The dpi to draw at.
        N)
r   rg   
setdefaultr_   r~   setaddr   r   rA   )	r7   r>   r?   Zfacenamer   r   rv   r   r@   r0   r0   r1   rA     s    zFonts.render_glyphc             C   s   | j j|||| dS )zL
        Draw a filled rectangle from (*x1*, *y1*) to (*x2*, *y2*).
        N)r   rF   )r7   rB   rC   rD   rE   r0   r0   r1   rF     s    zFonts.render_rect_filledc             C   s
   t  dS )zF
        Get the xheight for the given *font* and *fontsize*.
        N)r=   )r7   r_   rv   r   r0   r0   r1   get_xheight  s    zFonts.get_xheightc             C   s
   t  dS )z
        Get the line thickness that matches the given font.  Used as a
        base unit for drawing lines such as in a fraction or radical.
        N)r=   )r7   r_   rv   r   r0   r0   r1   get_underline_thickness  s    zFonts.get_underline_thicknessc             C   s   | j S )z
        Get the set of characters that were used in the math
        expression.  Used by backends that need to subset fonts so
        they know which glyphs to include.
        )rg   )r7   r0   r0   r1   get_used_characters  s    zFonts.get_used_charactersc             C   s   | j j|| j }| j  |S )z
        Get the data needed by the backend to render the math
        expression.  The return value is backend-specific.
        )r   rH   r   r   )r7   rG   rh   r0   r0   r1   rH     s    zFonts.get_resultsc             C   s
   ||fgS )a  
        Override if your font provides multiple sizes of the same
        symbol.  Should return a list of symbols matching *sym* in
        various sizes.  The expression renderer will select the most
        appropriate size for a given situation from this list.
        r0   )r7   fontnamer   r0   r0   r1   !get_sized_alternatives_for_symbol  s    z'Fonts.get_sized_alternatives_for_symbolN)T)rJ   rK   rL   rM   r8   r   r   r   r<   rA   rF   r   r   r   rH   r   r0   r0   r0   r1   r   z  s   
 	
r   c               @   sR   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdd Z	dd Z
dd ZdS )TruetypeFontsza
    A generic base class for all font setups that use Truetype fonts
    (through FT2Font).
    c             C   sB   t j| || i | _i | _t|}t|}|| jd< || jd< d S )Ndefaultregular)r   r8   glyphd_fontsr   r   )r7   r   r   r   default_fontr0   r0   r1   r8     s    
zTruetypeFonts.__init__c             C   s   d | _ tj|  d S )N)r   r   r   )r7   r0   r0   r1   r   &  s    zTruetypeFonts.destroyc             C   sl   || j kr| j | }n|}| jj|}|d krhtjj|rht|}|| j|< || j|j< || j|jj < |S )N)	fontmapr   getospathexistsr   ru   lower)r7   r_   basenamecached_fontr0   r0   r1   	_get_font*  s    

zTruetypeFonts._get_fontc             C   s,   |j dkr(|jd d |d | d  S dS )NZCmex10@   rS   rT   H   g        )ru   r5   )r7   r_   ra   rv   r   r0   r0   r1   _get_offset7  s    
zTruetypeFonts._get_offsetTc             C   s   |||||f}| j j|}|d k	r&|S | j|||||\}	}
}}}|	j|| |	j|
| jj d}dd |jD \}}}}| j|	|||}t	j
|jd |jd |jd |||| || |jd | |d	}t	j
|	||	j|||
||d }| j |< |S )N)flagsc             S   s   g | ]}|d  qS )g      P@r0   ).0valr0   r0   r1   
<listcomp>J  s    z+TruetypeFonts._get_info.<locals>.<listcomp>g      @g      P@)	advancer5   r4   r[   r]   r^   r\   r`   slanted)r_   rv   ru   rZ   rx   r   ra   rt   )r   r   
_get_glyphset_sizeZ	load_charr   rI   rO   r   r   r   ZlinearHoriAdvancer5   r4   ZhoriBearingYru   )r7   r   r   r   rv   r   r.   keyZbunchr_   r   rx   r   ra   r[   r^   r]   r\   rt   rZ   rh   r0   r0   r1   r   <  s>    zTruetypeFonts._get_infoc             C   sd   | j |}|j|| |jd}|d krD| j|td d||}|jS |d d |d  |d  }|S )Npcltzmathtext.defaultxxHeightg      P@g      (@g      Y@)r   r   Zget_sfnt_tabler   r   r`   )r7   r   rv   r   r_   r   rZ   r   r0   r0   r1   r   e  s    

zTruetypeFonts.get_xheightc             C   s   d| | d S )Ng      ?g      (@g      R@g      ?r0   )r7   r_   rv   r   r0   r0   r1   r   q  s    z%TruetypeFonts.get_underline_thicknessc
             C   sl   ||krP||krP| j |||||	}
| j |||||	}|
j}|j|
j|jtd S tj| |||||||||	
S )Nr   )r   r_   get_kerningr   r   r   r   )r7   r   r   r   r   r   r   r   r   r   info1info2r_   r0   r0   r1   r   w  s    zTruetypeFonts.get_kernN)T)rJ   rK   rL   rM   r8   r   r   r   r   r   r   r   r0   r0   r0   r1   r     s   

)r   c               @   s0  e Zd ZdZdddddddd	Zd
d Zedj ZdgddZ	dhdidjdkdlgdmdndodpdqgdrdsdtdudvgdwdxdydzd{gd|d}d~dgddddgddddgddddgddddgddddgddddgddddgddddgddddgdddddgddddgddddgddgddgdYZ
xdD ]\ZZe
e e
e< q
W ddde ZdfS )BakomaFontsz
    Use the Bakoma TrueType fonts for rendering.

    Symbols are strewn about a number of font files, each of which has
    its own proprietary 8-bit encoding.
    cmsy10cmr10cmtt10cmmi10cmb10cmss10cmex10)calrmttitbfsfexc             O   s\   t ||| _tj| f|| i | _x2| jj D ]$\}}t|}|| j|< || j|< q0W d S )N)	StixFonts_stix_fallbackr   r8   r   _fontmapitemsr   )r7   argskwargsr   r   fullpathr0   r0   r1   r8     s    
zBakomaFonts.__init__z
\int \ointTc             C   s   d }d }|| j krD|tkrDt| \}}	|dkp6|| jk}
| j|}n.t|dkrr|dk}
| j|}|d k	rrt|}	|d k	r|j|	}|dkr|j|}|d kr| jj	|||||S ||	|||
fS )Nr   rR   r   r   )
r   r    _slanted_symbolsr   lenr'   get_char_indexget_glyph_namer   r   )r7   r   r   r   rv   r.   rx   r_   r   r   r   gidr0   r0   r1   r     s&    


zBakomaFonts._get_glyphr   (r      ¡   ³   µ   Ã)   ¢   ´   ¶!r   {   ©n   ½}   ªo   ¾[   £r:   "]   ¤i#   ¥j   ¹$   ¦k   º%   §l   »&   ¨m   ¼'   ­D   ¿*   ®E   À+pqrs   ²rq      Âr%      ±.   Ë,^bcr;   ~err   g)r   r   r   r   r   r   z\lfloorz\rfloorz\lceilz\rceilz\langlez\ranglez	\__sqrt__z
\backslashrq   z\widehatz
\widetilde<>
\leftparen\rightparent
\leftbrace\rightbrace\leftbracket\rightbracket\{\}\[\]c             C   s   | j j|||fgS )N)_size_alternativesr   )r7   r   r   r0   r0   r1   r     s    z-BakomaFonts.get_sized_alternatives_for_symbolN)T)r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r:   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r   )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r	  )r   r
  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   rq   )r   r  )r   r%   )r   rq   )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r;   )r   r  )r   r   )r   rr   )r   r!  )r   r:   )r   r  )r   r   )r   r  r$  r   r%  r   r&  r   r'  r   r(  r   r)  r   r*  r   r+  r   r,  r   r-  r   )
r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  )rJ   rK   rL   rM   r   r8   r   splitr   r   r.  aliastargetr   r0   r0   r0   r1   r     sv   

        r   c               @   sB   e Zd ZdZdZdd Zedj Zdd Z	ddd	Z
d
d ZdS )UnicodeFontsaa  
    An abstract base class for handling Unicode fonts.

    While some reasonably complete Unicode fonts (such as DejaVu) may
    work in some situations, the only Unicode font I'm aware of with a
    complete set of math symbols is STIX.

    This class will "fallback" on the Bakoma fonts when a required
    symbol can not be found in the font.
    Tc             O   s   t d }t d d k	r$t d r dnd }tttdj|}|rD|||nd | _tj| f|| i | _x.dj	 D ]"}t d|  }t
|}|| j|< qlW td}t
|}|| jd< t| jtrd	d
ddddd}x0|j D ]$\}	}
t
|
}|| j|	< || j|
< qW d S )Nzmathtext.fallbackzmathtext.fallback_to_cmcm)stixstixsansr=  zcal rm tt it bf sfz	mathtext.r   r   STIXGeneralSTIXSizeOneSymSTIXSizeTwoSymSTIXSizeThreeSymSTIXSizeFourSymSTIXSizeFiveSym)r   rR   rS   rT         )r   r   StixSansFontsr   r   cm_fallbackr   r8   r   r9  r   r   
isinstancer   )r7   r   r   Zfallback_rcr   Ztexfontpropr_   Zstixsizedaltfontssizenamer   r0   r0   r1   r8      s:    

zUnicodeFonts.__init__z
\int \ointc             C   s   ||fS )Nr0   )r7   r   r   uniindexr0   r0   r1   _map_virtual_font(  s    zUnicodeFonts._map_virtual_fontc             C   s  d}| j r$tj|}|d k	r$d}d}|shyt||}d}W n, tk
rf   td}tjdj| Y nX | j	|||\}}|}|r|dkr|dk rt
|}	tj|	d d	kstj|	jd
rd}|dkp|| jk}
d}| j|}|d k	r|j|}|dkrd}|s| jrt|dkr.t| jtr.d}| jj||||}|d j}|ttjj krbd}tjd|| |S |dkrt| tr| jd|||S tjdj||| d}| j|}d}|j|}d}
|j|}|||||
fS )NFr   T?z#No TeX to unicode mapping for {!a}.r   i   r   LzGREEK CAPITALr   r   zComputer ModernzSubstituting symbol %s from %szTFont {!r} does not have a glyph for {!a} [U+{:x}], substituting with a dummy symbol.   )r   r   )r   r   )use_cmexr#   r   r2   r+   r'   _logwarningr,   rO  r   unicodedatacategoryrM  
startswithr   r   r   rI  rJ  r   r   family_namelistr   r   valuesr@   r   )r7   r   r   r   rv   r.   found_symbolrN  Znew_fontnamecharr   r_   
glyphindexr!  r~   rx   r0   r0   r1   r   +  sl    












zUnicodeFonts._get_glyphc             C   s   | j r| j j||S ||fgS )N)rI  r   )r7   r   r   r0   r0   r1   r   q  s    z.UnicodeFonts.get_sized_alternatives_for_symbolN)T)rJ   rK   rL   rM   rS  r8   r   r9  r   rO  r   r   r0   r0   r0   r1   r<    s   
&
Fr<  c                   s*   e Zd ZdZdd Zd fdd	Z  ZS )DejaVuFontsFc             O   s   t | trt||| _nt||| _t||| _tj| f|| i | _	| j
jdddddd x2| j
j D ]$\}}t|}|| j	|< || j	|< qlW d S )NrA  rB  rC  rD  rE  )rR   rS   rT   rF  rG  )rJ  DejaVuSerifFontsr   rI  rH  r   bakomar   r8   r   r   updater   r   )r7   r   r   r   rM  r   r0   r0   r1   r8   {  s     


zDejaVuFonts.__init__Tc       	         st   |dkr| j j|||||S t|}| jd}|d k	r\|j|}|dkr\t jd||||S t j|||||S d S )Nz\primer   r   )ra  r   r2   r   r   super)	r7   r   r   r   rv   r.   rN  r_   r^  )	__class__r0   r1   r     s    

zDejaVuFonts._get_glyph)T)rJ   rK   rL   rS  r8   r   __classcell__r0   r0   )rd  r1   r_  x  s   r_  c               @   s$   e Zd ZdZddddddddZd	S )
r`  zv
    A font handling class for the DejaVu Serif fonts

    If a glyph is not found it will fallback to Stix Serif
    zDejaVu SerifzDejaVu Serif:italiczDejaVu Serif:weight=boldzDejaVu SanszDejaVu Sans MonozDejaVu Serif Display)r   r   r   r   r   r   r   N)rJ   rK   rL   rM   r   r0   r0   r0   r1   r`    s   r`  c               @   s$   e Zd ZdZddddddddZdS )	DejaVuSansFontszt
    A font handling class for the DejaVu Sans fonts

    If a glyph is not found it will fallback to Stix Sans
    zDejaVu SanszDejaVu Sans:italiczDejaVu Sans:weight=boldzDejaVu Sans MonozDejaVu Sans Display)r   r   r   r   r   r   r   N)rJ   rK   rL   rM   r   r0   r0   r0   r1   rf    s   rf  c               @   sZ   e Zd ZdZddddddddd	d
dddZdZdZdZdd Zdd Z	e
j dd ZdS )r   aa  
    A font handling class for the STIX fonts.

    In addition to what UnicodeFonts provides, this class:

    - supports "virtual fonts" which are complete alpha numeric
      character sets with different font styles at special Unicode
      code points, such as "Blackboard".

    - handles sized alternative characters for the STIXSizeX fonts.
    r@  zSTIXGeneral:italiczSTIXGeneral:weight=boldSTIXNonUnicodezSTIXNonUnicode:italiczSTIXNonUnicode:weight=boldrA  rB  rC  rD  rE  )r   r   r   ZnonunirmZnonuniitZnonunibfr   rR   rS   rT   rF  rG  Fc             O   sP   t j| f|| i | _x2| jj D ]$\}}t|}|| j|< || j|< q$W d S )N)r   r8   r   r   r   r   )r7   r   r   r   rM  r   r0   r0   r1   r8     s    
zStixFonts.__init__c       
      C   sP  t j|}| jr.|d kr.|dkr.t d }d}nd}|d k	rt|trpy|| }W n tk
rn   |d }Y nX d}t|}xJ||k r|| d }|| }	||	d k r|}q~||	d	 krP q~|d	 }q~W |	d |  ko|	d	 kn  r||	d  |	d
  }|	d }n|sd	}td }|dkrHd|  ko8dkn  rHd| }||fS )Nr   r   r   TFr   r   rS   rR   rT   zmathtext.defaultr   r   i   i  Znonuni)r   r   )r   r   r   )r$   r   _sansrJ  dictr*   r   r   )
r7   r   r   rN  mappingZdoing_sans_conversionlohiZmidranger0   r0   r1   rO    s>    



"
&zStixFonts._map_virtual_fontc                sv   ddddddd}|j ||}yt|W n tk
rD   ||fgS X  fdd	td
D }|dkrr|d d }|S )Nr   r   r   r   u   ⟨u   ⟩)z\{z\}z\[z\]r"  r#  c                s,   g | ]$} j |jd kr|tfqS )r   )r   r   r   )r   r   )r7   rN  r0   r1   r   %  s    z?StixFonts.get_sized_alternatives_for_symbol.<locals>.<listcomp>   z	\__sqrt__rR   )r   r2   r+   rm  )r7   r   r   fixesalternativesr0   )r7   rN  r1   r     s    z+StixFonts.get_sized_alternatives_for_symbolN)rJ   rK   rL   rM   r   rS  rI  rh  r8   rO  	functools	lru_cacher   r0   r0   r0   r1   r     s&   -r   c               @   s   e Zd ZdZdZdS )rH  zd
    A font handling class for the STIX fonts (that uses sans-serif
    characters by default).
    TN)rJ   rK   rL   rM   rh  r0   r0   r0   r1   rH  .  s   rH  c               @   sd   e Zd ZdZeejdZddddddd	d
Zdd Z	dd Z
dddZdd Zdd Zdd ZdS )StandardPsFontsz
    Use the standard postscript fonts for rendering to backend_ps

    Unlike the other font classes, BakomaFont and UnicodeFont, this
    one requires the Ps backend.
    z	fonts/afmZpzcmi8aZpncr8aZpcrr8aZpncri8aZphvr8aZpncb8aZpsyr)r   r   r   r   r   r   Nc          
   C   s   t j| |t  i | _i | _t|d| jd}|d krDtdd| jd}t|d}t|}W d Q R X ||_	|| jd< || jd< t
 | _d S )NZafm)Zfontext	directoryZ	Helveticarbr   r   )r   r8   rm   r   fontsr   basepathopenr   r~   r   ro   )r7   r   r   fdr   r0   r0   r1   r8   I  s    



zStandardPsFonts.__init__c          
   C   s   || j kr| j | }n|}| jj|}|d kr~tjj| j|d }t|d}t|}W d Q R X ||_	|| j|< || j|j
 < |S )Nz.afmrv  )r   rw  r   r   r   joinrx  ry  r   r~   get_fontname)r7   r_   r   r   r~   rz  r0   r0   r1   r   [  s    

zStandardPsFonts._get_fontTc                s  ||||f}| j j|}|dk	r$|S |dkrNt|dksJtj|jd rNd}d}	|tkrtt| \}}
t|
}d}	n.t|dkr|}t|}
d}	nt	j
dj| |dk}| j|}|	ry|j|}W n. tk
r   t	j
d	j|j | d}	Y nX |	sd
}t|}
|j|}d}d|   fdd|j|D \}}}}tj|j|  |j|  |j|  |||| || || |d	}tj|||j |||
||d| j |< | j | S )z0Load the cmfont, metrics and glyph with caching.Nr   rR   rQ  r   FTz.No TeX to built-in Postscript mapping for {!r}z2No glyph in standard Postscript font {!r} for {!r}rP  r   gMbP?c                s   g | ]}|  qS r0   r0   )r   r   )scaler0   r1   r     s   z-StandardPsFonts._get_info.<locals>.<listcomp>)	r   r4   r5   r[   r]   r^   r\   r`   r   )r_   rv   ru   rZ   rx   r   ra   rt   )r   r   r   rV  rW  rX  r!   r   r'   rT  rU  r,   r   Zget_name_charr*   r|  Zget_bbox_charr   r   Zget_width_charZget_height_char)r7   r   r   r   rv   r   r.   r   tupr\  r   ra   r   r_   rx   rt   r[   r^   r]   r\   rZ   r0   )r}  r1   r   k  sr    



zStandardPsFonts._get_infoc
             C   sn   ||krR||krR| j |||||	}
| j |||||	}|
j}|j|
j|jd | S tj| |||||||||	
S )NgMbP?)r   r_   Zget_kern_distra   r   r   )r7   r   r   r   r   r   r   r   r   r   r   r   r_   r0   r0   r1   r     s    zStandardPsFonts.get_kernc             C   s   | j |}|j d | S )NgMbP?)r   r   )r7   r_   rv   r   r0   r0   r1   r     s    
zStandardPsFonts.get_xheightc             C   s   | j |}|j d | S )NgMbP?)r   r   )r7   r_   rv   r   r0   r0   r1   r     s    
z'StandardPsFonts.get_underline_thicknessN)T)rJ   rK   rL   rM   strr   Z_get_data_pathrx  r   r8   r   r   r   r   r   r0   r0   r0   r1   rt  6  s   
Nrt  gffffff?g      ?rn  c               @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )FontConstantsBasez
    A set of constants that controls how certain things, such as sub-
    and superscripts are laid out.  These are all metrics that can't
    be reliably retrieved from the font metrics in the font itself.
    g?g?gffffff?g333333?g      ?g?g?g?N)rJ   rK   rL   rM   script_spacesubdropsup1sub1sub2deltadelta_slanteddelta_integralr0   r0   r0   r1   r    s   r  c               @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
dS )ComputerModernFontConstantsg333333?g?g?g333333?N)rJ   rK   rL   r  r  r  r  r  r  r  r  r0   r0   r0   r1   r    s   r  c               @   s$   e Zd ZdZdZdZdZdZdZdS )STIXFontConstantsg?g?g333333?g?g333333?N)	rJ   rK   rL   r  r  r  r  r  r  r0   r0   r0   r1   r    s   r  c               @   s   e Zd ZdZdZdZdZdS )STIXSansFontConstantsg?g?g333333?g333333?N)rJ   rK   rL   r  r  r  r  r0   r0   r0   r1   r  &  s   r  c               @   s   e Zd ZdS )DejaVuSerifFontConstantsN)rJ   rK   rL   r0   r0   r0   r1   r  -  s   r  c               @   s   e Zd ZdS )DejaVuSansFontConstantsN)rJ   rK   rL   r0   r0   r0   r1   r  1  s   r  )zDejaVu SanszDejaVu Sans MonozDejaVu Serifr   r   r   r   r   r   r   r@  rg  rE  rD  rC  rB  rA  zBitstream Vera SanszBitstream Verac             C   s4   t j| jj| jjt}|tkr0t| jt	r0t
S |S )N)_font_constant_mappingr   font_outputr   r_   rY  r  r  rJ  rH  r  )state	constantsr0   r0   r1   _get_font_constant_setN  s    r  c               @   s   e Zd ZdS )MathTextWarningN)rJ   rK   rL   r0   r0   r0   r1   r  Z  s   r  c               @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )NodezA node in the TeX box model.c             C   s
   d| _ d S )Nr   )rL  )r7   r0   r0   r1   r8   a  s    zNode.__init__c             C   s   | j jS )N)rd  rJ   )r7   r0   r0   r1   __repr__d  s    zNode.__repr__c             C   s   dS )Ng        r0   )r7   nextr0   r0   r1   r   g  s    zNode.get_kerningc             C   s   |  j d7  _ dS )z
        Shrinks one level smaller.  There are only three levels of
        sizes, after which things will no longer get smaller.
        rR   N)rL  )r7   r0   r0   r1   shrinkj  s    zNode.shrinkc             C   s   |  j d8  _ dS )zb
        Grows one level larger.  There is no limit to how big
        something can get.
        rR   N)rL  )r7   r0   r0   r1   growq  s    z	Node.growc             C   s   d S )Nr0   )r7   r   rd   r0   r0   r1   re   x  s    zNode.renderN)
rJ   rK   rL   rM   r8   r  r   r  r  re   r0   r0   r0   r1   r  ^  s   r  c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )Boxz A node with a physical location.c             C   s    t j|  || _|| _|| _d S )N)r  r8   r4   r5   r6   )r7   r4   r5   r6   r0   r0   r1   r8     s    
zBox.__init__c             C   sB   t j|  | jtk r>|  jt9  _|  jt9  _|  jt9  _d S )N)r  r  rL  NUM_SIZE_LEVELSr4   SHRINK_FACTORr5   r6   )r7   r0   r0   r1   r    s
    

z
Box.shrinkc             C   s8   t j|  |  jt9  _|  jt9  _|  jt9  _d S )N)r  r  r4   GROW_FACTORr5   r6   )r7   r0   r0   r1   r    s    
zBox.growc             C   s   d S )Nr0   )r7   rB   rC   rD   rE   r0   r0   r1   re     s    z
Box.renderN)rJ   rK   rL   rM   r8   r  r  re   r0   r0   r0   r1   r  |  s
   r  c               @   s   e Zd ZdZdd ZdS )Vboxz$A box with only height (zero width).c             C   s   t j| d|| d S )Ng        )r  r8   )r7   r5   r6   r0   r0   r1   r8     s    zVbox.__init__N)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r    s   r  c               @   s   e Zd ZdZdd ZdS )Hboxz.A box with only width (zero height and depth).c             C   s   t j| |dd d S )Ng        )r  r8   )r7   r4   r0   r0   r1   r8     s    zHbox.__init__N)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r    s   r  c               @   sR   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )Chara  
    A single character.

    Unlike TeX, the font information and metrics are stored with each `Char`
    to make it easier to lookup the font metrics when needed.  Note that TeX
    boxes have a width, height, and depth, unlike Type1 and TrueType which use
    a full bounding box and an advance in the x-direction.  The metrics must
    be converted to the TeX model, and the advance (if different from width)
    must be converted into a `Kern` node when the `Char` is added to its parent
    `Hlist`.
    Tc             C   sJ   t j|  || _|j| _|j| _|j| _|j| _|j| _|| _| j	  d S )N)
r  r8   r  r  r_   r   rv   r   r.   _update_metrics)r7   r  r  r.   r0   r0   r1   r8     s    
zChar.__init__c             C   s
   d| j  S )Nz`%s`)r  )r7   r0   r0   r1   r    s    zChar.__repr__c             C   s`   | j j| j| j| j| j| j| j }| _| jdkr<|j	| _
n|j
| _
|j| _|j|j  | _d S )Nrs   )r  r   r_   r   r  rv   r   r.   _metricsr   r4   r`   r5   r6   )r7   rZ   r0   r0   r1   r    s    

zChar._update_metricsc             C   s   | j jS )N)r  r   )r7   r0   r0   r1   
is_slanted  s    zChar.is_slantedc          
   C   sR   | j j| j }d}t|trJ| jj| j| j| j	| j
|j|j|j	|j
| j	}|| S )z
        Return the amount of kerning between this and the given character.

        This method is called when characters are strung together into `Hlist`
        to create `Kern` nodes.
        g        )r  r   r4   rJ  r  r  r   r_   r   r  rv   r   )r7   r  r   kernr0   r0   r1   r     s    
zChar.get_kerningc             C   s&   | j j||| j| j| j| j| j dS )z4
        Render the character to the canvas
        N)r  rA   r_   r   r  rv   r   )r7   r   rd   r0   r0   r1   re     s    zChar.renderc             C   sP   t j|  | jtk rL|  jt9  _|  jt9  _|  jt9  _|  jt9  _d S )N)	r  r  rL  r  rv   r  r4   r5   r6   )r7   r0   r0   r1   r    s    

zChar.shrinkc             C   sF   t j|  |  jt9  _|  jt9  _|  jt9  _|  jt9  _d S )N)r  r  rv   r  r4   r5   r6   )r7   r0   r0   r1   r    s
    
z	Char.growN)T)rJ   rK   rL   rM   r8   r  r  r  r   re   r  r  r0   r0   r0   r1   r    s   
r  c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )Accentz
    The font metrics need to be dealt with differently for accents,
    since they are already offset correctly from the baseline in
    TrueType fonts.
    c             C   sJ   | j j| j| j| j| j| j }| _|j|j	 | _
|j|j | _d| _d S )Nr   )r  r   r_   r   r  rv   r   r  r]   r[   r4   r\   r^   r5   r6   )r7   rZ   r0   r0   r1   r    s
    zAccent._update_metricsc             C   s   t j|  | j  d S )N)r  r  r  )r7   r0   r0   r1   r    s    
zAccent.shrinkc             C   s   t j|  | j  d S )N)r  r  r  )r7   r0   r0   r1   r    s    
zAccent.growc             C   s6   | j j|| jj || jj | j| j| j| j| j	 dS )z5
        Render the character to the canvas.
        N)
r  rA   r  r[   r^   r_   r   r  rv   r   )r7   r   rd   r0   r0   r1   re     s    zAccent.renderN)rJ   rK   rL   rM   r  r  r  re   r0   r0   r0   r1   r    s
   r  c                   sL   e Zd ZdZdd Z fddZedd Zdd	 Zd
d Z	dd Z
  ZS )Listz0A list of nodes (either horizontal or vertical).c             C   s2   t j| ddd d| _|| _d| _d| _d| _d S )Ng        r   )r  r8   shift_amountchildrenglue_set	glue_sign
glue_order)r7   elementsr0   r0   r1   r8     s    zList.__init__c          	      s4   dt  j | j| j| j| jdjdd | jD f S )Nz![%s <%.02f %.02f %.02f %.02f> %s]rs   c             S   s   g | ]}t |qS r0   )repr)r   r   r0   r0   r1   r   &  s    z!List.__repr__.<locals>.<listcomp>)rc  r  r4   r5   r6   r  r{  r  )r7   )rd  r0   r1   r  !  s
    zList.__repr__c             C   s4   x.t t| ddd D ]}| | dkr|S qW dS )z
        Determine the highest order of glue used by the members of this list.

        Helper function used by vpack and hpack.
        NrR   r   ro  )rm  r   )totalsr   r0   r0   r1   _determine_order(  s    zList._determine_orderc             C   sh   | j |}|| _|| _|| dkr2|||  | _nd| _d| _|dkrdt| jrdtjd|| j	j
|  d S )Ng        r   z	%s %s: %r)r  r  r  r  
glue_ratior   r  rT  rU  rd  rJ   )r7   r   signr  Z
error_typer   r0   r0   r1   	_set_glue4  s    

zList._set_gluec             C   sL   x| j D ]}|j  qW tj|  | jtk rH|  jt9  _|  jt9  _d S )N)r  r  r  rL  r  r  r  r  )r7   childr0   r0   r1   r  B  s    

zList.shrinkc             C   sB   x| j D ]}|j  qW tj|  |  jt9  _|  jt9  _d S )N)r  r  r  r  r  r  )r7   r  r0   r0   r1   r  J  s
    
z	List.grow)rJ   rK   rL   rM   r8   r  staticmethodr  r  r  r  re  r0   r0   )rd  r1   r    s   	r  c               @   s,   e Zd ZdZdddZdd Zdd	d
ZdS )HlistzA horizontal list of boxes.        
additionalTc             C   s$   t j| | |r| j  | j  d S )N)r  r8   r  hpack)r7   r  r9   r  do_kernr0   r0   r1   r8   U  s    zHlist.__init__c             C   s   g }t | j}|rxht|D ]\}| j| }||d k rF| j|d  }nd}|j| |j|}|dkrt|}|j| qW || _dS )z
        Insert `Kern` nodes between `Char` nodes to set kerning.

        The `Char` nodes themselves determine the amount of kerning they need
        (in `~Char.get_kerning`), and this function just creates the correct
        linked list.
        rR   Ng        )r   r  rm  r   r   Kern)r7   new_childrenZnum_childrenr   elemr  Zkerning_distancer  r0   r0   r1   r  [  s    



z
Hlist.kernc             C   s  d}d}d}dgd }dgd }x| j D ]}t|trZ||j7 }t||j}t||j}q(t|tr||j7 }tj	|j rtj	|j rt
|dd}	t||j|	 }t||j|	 }q(t|tr|j}
||
j7 }||
j  |
j7  < ||
j  |
j7  < q(t|tr(||j7 }q(W || _|| _|dkr2||7 }|| _|| }|dkr`d| _d| _d| _dS |dkr|| j|d|d n| j|d
|d	 dS )a  
        Compute the dimensions of the resulting boxes, and adjust the glue if
        one of those dimensions is pre-specified.  The computed sizes normally
        enclose all of the material inside the new box; but some items may
        stick out if negative glue is used, if the box is overfull, or if a
        ``\vbox`` includes other boxes that have been shifted left.

        Parameters
        ----------
        w : float, default: 0
            A width.
        m : {'exactly', 'additional'}, default: 'additional'
            Whether to produce a box whose width is 'exactly' *w*; or a box
            with the natural width of the contents, plus *w* ('additional').

        Notes
        -----
        The defaults produce a box with the natural width of the contents.
        g        rF  r  r  r   NrR   Overfull	Underfullro  )r  rJ  r  r4   rV   r5   r6   r  rX   isinfgetattrGlue	glue_specstretch_orderstretchshrink_orderr  r  r  r  r  r  )r7   r9   r  r:   r;   r   total_stretchtotal_shrinkr  r  r  r0   r0   r1   r    sJ    











zHlist.hpackN)r  r  T)r  r  )rJ   rK   rL   rM   r8   r  r  r0   r0   r0   r1   r  R  s   
'r  c               @   s,   e Zd ZdZd	ddZddejfddZdS )
VlistzA vertical list of boxes.        r  c             C   s   t j| | | j  d S )N)r  r8   vpack)r7   r  r:   r  r0   r0   r1   r8     s    zVlist.__init__c             C   s  d}d}d}dgd }dgd }x| j D ]}	t|	trt|||	j 7 }|	j}tj|	jst|	dd}
t	||	j|
 }q(t|	t
r||7 }d}|	j}||j7 }||j  |j7  < ||j  |j7  < q(t|	tr|||	j 7 }d}q(t|	tr(tdq(W || _||kr||| 7 }|| _n|| _|dkr4||7 }|| _|| }|dkrbd| _d| _d| _dS |dkr~| j|d|d	 n| j|d|d
 dS )ak  
        Compute the dimensions of the resulting boxes, and to adjust the glue
        if one of those dimensions is pre-specified.

        Parameters
        ----------
        h : float, default: 0
            A height.
        m : {'exactly', 'additional'}, default: 'additional'
            Whether to produce a box whose height is 'exactly' *w*; or a box
            with the natural height of the contents, plus *w* ('additional').
        l : float, default: np.inf
            The maximum height.

        Notes
        -----
        The defaults produce a box with the natural height of the contents.
        g        rF  r  z1Internal mathtext error: Char node found in Vlistr  r   NrR   r  r  ro  )r  rJ  r  r5   r6   rX   r  r4   r  rV   r  r  r  r  r  r  r  r  RuntimeErrorr  r  r  r  )r7   r:   r  r  r9   r;   r   r  r  r  r  r  r0   r0   r1   r    sT    











zVlist.vpackN)r  r  )rJ   rK   rL   rM   r8   rX   infr  r0   r0   r0   r1   r    s   
r  c               @   s    e Zd ZdZdd Zdd ZdS )Rulea  
    A solid black rectangle.

    It has *width*, *depth*, and *height* fields just as in an `Hlist`.
    However, if any of these dimensions is inf, the actual value will be
    determined by running the rule up to the boundary of the innermost
    enclosing box.  This is called a "running dimension".  The width is never
    running in an `Hlist`; the height and depth are never running in a `Vlist`.
    c             C   s   t j| ||| |j| _d S )N)r  r8   r  )r7   r4   r5   r6   r  r0   r0   r1   r8     s    zRule.__init__c             C   s   | j j|||| ||  d S )N)r  rF   )r7   r   rd   r9   r:   r0   r0   r1   re   !  s    zRule.renderN)rJ   rK   rL   rM   r8   re   r0   r0   r0   r1   r    s   	r  c               @   s   e Zd ZdZdddZdS )Hrulez.Convenience class to create a horizontal rule.Nc             C   sB   |d kr|j j|j|j|j}|d  }}tj| tj||| d S )Ng      ?)	r  r   r_   rv   r   r  r8   rX   r  )r7   r  	thicknessr5   r6   r0   r0   r1   r8   (  s
    zHrule.__init__)N)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r  %  s   r  c               @   s   e Zd ZdZdd ZdS )Vrulez,Convenience class to create a vertical rule.c             C   s0   |j j|j|j|j}tj| |tjtj| d S )N)	r  r   r_   rv   r   r  r8   rX   r  )r7   r  r  r0   r0   r1   r8   3  s    zVrule.__init__N)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r  0  s   r  	_GlueSpecz/width stretch stretch_order shrink shrink_orderg        rR   rS   rT   )filfillfilllneg_filneg_fill	neg_filllemptyssc               @   sL   e Zd ZdZejdedd ZejdddddZ	d	d
 Z
dd ZdS )r  a  
    Most of the information in this object is stored in the underlying
    ``_GlueSpec`` class, which is shared between multiple glue objects.
    (This is a memory optimization which probably doesn't matter anymore, but
    it's easier to stick to what TeX does.)
    z3.3c             C   s   dS )NZnormalr0   )r7   r0   r0   r1   glue_subtypeO  s    zGlue.glue_subtypecopyFc             C   sB   t j|  t|tr tj| }nt|tr0|}ntd|| _d S )Nz.glue_type must be a glue spec name or instance)r  r8   rJ  r  r  _namedr+   r  )r7   	glue_typer  r  r0   r0   r1   r8   T  s    


zGlue.__init__c             C   s2   t j|  | jtk r.| j}|j|jt d| _d S )N)r4   )r  r  rL  r  r  _replacer4   r  )r7   r!  r0   r0   r1   r  _  s    

zGlue.shrinkc             C   s(   t j|  | j}|j|jt d| _d S )N)r4   )r  r  r  r  r4   r  )r7   r!  r0   r0   r1   r  e  s    
z	Glue.growN)F)rJ   rK   rL   rM   r   
deprecatedpropertyr  Z_delete_parameterr8   r  r  r0   r0   r0   r1   r  G  s   

r  z3.3c               @   s.   e Zd ZdZdddZdd Zedd	 Zd
S )GlueSpeczSee `Glue`.        r   c             C   s"   || _ || _|| _|| _|| _d S )N)r4   r  r  r  r  )r7   r4   r  r  r  r  r0   r0   r1   r8   o  s
    zGlueSpec.__init__c             C   s   t | j| j| j| j| jS )N)r  r4   r  r  r  r  )r7   r0   r0   r1   r  w  s    zGlueSpec.copyc             C   s
   | j | S )N)_types)clsr  r0   r0   r1   factory  s    zGlueSpec.factoryN)r  r  r   r  r   )rJ   rK   rL   rM   r8   r  classmethodr  r0   r0   r0   r1   r  k  s
    
r  c             C   s    i | ]\}}t f |j |qS r0   )r  _asdict)r   r   vr0   r0   r1   
<dictcomp>  s   r  zGlue('fil'))alternativec               @   s   e Zd Zdd ZdS )Filc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zFil.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  zGlue('fill')c               @   s   e Zd Zdd ZdS )Fillc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zFill.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  zGlue('filll')c               @   s   e Zd Zdd ZdS )Filllc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zFilll.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  zGlue('neg_fil')c               @   s   e Zd Zdd ZdS )NegFilc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zNegFil.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  zGlue('neg_fill')c               @   s   e Zd Zdd ZdS )NegFillc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zNegFill.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  zGlue('neg_filll')c               @   s   e Zd Zdd ZdS )NegFilllc             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zNegFilll.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  z
Glue('ss')c               @   s   e Zd Zdd ZdS )SsGluec             C   s   t j| d d S )Nr  )r  r8   )r7   r0   r0   r1   r8     s    zSsGlue.__init__N)rJ   rK   rL   r8   r0   r0   r0   r1   r    s   r  c                   s    e Zd ZdZ fddZ  ZS )	HCenteredzl
    A convenience class to create an `Hlist` whose contents are
    centered within its enclosing box.
    c                s&   t  jtdf|tdfdd d S )Nr  F)r  )rc  r8   r  )r7   r  )rd  r0   r1   r8     s    zHCentered.__init__)rJ   rK   rL   rM   r8   re  r0   r0   )rd  r1   r    s   r  c                   s    e Zd ZdZ fddZ  ZS )	VCenteredzk
    A convenience class to create a `Vlist` whose contents are
    centered within its enclosing box.
    c                s"   t  jtdf|tdf d S )Nr  )rc  r8   r  )r7   r  )rd  r0   r1   r8     s    zVCentered.__init__)rJ   rK   rL   rM   r8   re  r0   r0   )rd  r1   r    s   r  c               @   s8   e Zd ZdZdZdZdd Zdd Zdd Zd	d
 Z	dS )r  a  
    A `Kern` node has a width field to specify a (normally
    negative) amount of spacing. This spacing correction appears in
    horizontal lists between letters like A and V when the font
    designer said that it looks better to move them closer together or
    further apart. A kern node can also appear in a vertical list,
    when its *width* denotes additional spacing in the vertical
    direction.
    r   c             C   s   t j|  || _d S )N)r  r8   r4   )r7   r4   r0   r0   r1   r8     s    
zKern.__init__c             C   s
   d| j  S )Nzk%.02f)r4   )r7   r0   r0   r1   r    s    zKern.__repr__c             C   s&   t j|  | jtk r"|  jt9  _d S )N)r  r  rL  r  r4   r  )r7   r0   r0   r1   r    s    

zKern.shrinkc             C   s   t j|  |  jt9  _d S )N)r  r  r4   r  )r7   r0   r0   r1   r    s    
z	Kern.growN)
rJ   rK   rL   rM   r5   r6   r8   r  r  r  r0   r0   r0   r1   r    s   	r  c               @   s   e Zd ZdZdd ZdS )SubSuperClustera,  
    A hack to get around that fact that this code does a two-pass parse like
    TeX.  This lets us store enough information in the hlist itself, namely the
    nucleus, sub- and super-script, such that if another script follows that
    needs to be attached, it can be reconfigured on the fly.
    c             C   s"   d | _ d | _d | _tj| g  d S )N)nucleussubrc  r  r8   )r7   r0   r0   r1   r8     s    zSubSuperCluster.__init__N)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r    s   r  c               @   s   e Zd ZdZdddZdS )AutoHeightChara  
    A character as close to the given height and depth as possible.

    When using a font with multiple height versions of some characters (such as
    the BaKoMa fonts), the correct glyph will be selected, otherwise this will
    always just return a scaled version of the glyph.
    FNc             C   s   |j j|j|}|j j|j|j|j}|j }|| }	x:|D ]2\}
}|
|_t||}|j|j	 |	d|  kr<P q<W d}|jdkr|d kr|	|j|j	  }| j|9  _t||}||j	 }t
j| |g || _d S )Ng?r   )r  r   r_   r   rv   r   r  r  r5   r6   r  r8   r  )r7   r  r5   r6   r  alwaysfactorrq  r   Ztarget_totalr   r   r]  shiftr0   r0   r1   r8     s(    




zAutoHeightChar.__init__)FN)rJ   rK   rL   rM   r8   r0   r0   r0   r1   r    s   r  c               @   s   e Zd ZdZdefddZdS )AutoWidthChara  
    A character as close to the given width as possible.

    When using a font with multiple width versions of some characters (such as
    the BaKoMa fonts), the correct glyph will be selected, otherwise this will
    always just return a scaled version of the glyph.
    Fc             C   s   |j j|j|}|j }x,|D ]$\}}||_|||}	|	j|krP qW ||	j }
| j|
9  _|||}	tj| |	g |	j| _d S )N)r  r   r_   r  r4   rv   r  r8   )r7   r  r4   r  r  
char_classrq  r   r   r]  r  r0   r0   r1   r8   (  s    




zAutoWidthChar.__init__N)rJ   rK   rL   rM   r  r8   r0   r0   r0   r1   r    s   r  c               @   s4   e Zd ZdZdd Zedd Zdd Zdd	 Zd
S )Shipa  
    Ship boxes to output once they have been set up, this sends them to output.

    Since boxes can be inside of boxes inside of boxes, the main work of `Ship`
    is done by two mutually recursive routines, `hlist_out` and `vlist_out`,
    which traverse the `Hlist` nodes and `Vlist` nodes inside of horizontal
    and vertical boxes.  The global variables used in TeX to store state as it
    processes have become member variables here.
    c             C   s8   d| _ d| _d| _d| _|| _||j | _| j| d S )Nr   g        )max_pushcur_scur_vcur_hoff_hr5   off_v	hlist_out)r7   r>   r?   rG   r0   r0   r1   __call__F  s    zShip.__call__c             C   s   | dk rdS | dkrdS | S )Ng    eAg    eg    er0   )valuer0   r0   r1   clampO  s
    z
Ship.clampc             C   s^  d}d}|j }|j}| j}| j}|  jd7  _t| j| j| _| j}x|jD ]}	t	|	t
r|	j| j| j | j| j  |  j|	j7  _qNt	|	tr|  j|	j7  _qNt	|	trt|	jdkr|  j|	j7  _nF| j}
||	j | _t	|	t r| j|	 n
| j|	 |
|	j | _|| _qNt	|	tr|	j}|	j}|	j}tj|rL|j}tj|r^|j}|dkr|dkr|| | _|	j| j| j | j| j || || _|  j|7  _qNt	|	trN|	j}|j| }|dkr2|dkr
|j|kr2||j7 }t||j | }n(|j!|kr2||j"7 }t||j | }||7 }|  j|7  _qNW |  jd8  _d S )Nr   g        rR   )#r  r  r  r   r  rV   r  r  r  rJ  r  re   r  r  r4   r  r  r   r  r  r  	vlist_outr  r5   r6   rX   r  r  r  r  r  roundr  r  r  )r7   rG   cur_gcur_gluer  r  Z	base_line	left_edger  r  Zedgerule_height
rule_depth
rule_widthr  r0   r0   r1   r  W  sl    










zShip.hlist_outc             C   sN  d}d}|j }|j}|  jd7  _t| j| j| _| j}|  j|j8  _| j}| j}x|j	D ]}	t
|	tr|  j|	j7  _q^t
|	trt|	j	dkr|  j|	j|	j 7  _n\|  j|	j7  _||	j | _| j}
|j|	_t
|	tr| j|	 n
| j|	 |
|	j | _|| _q^t
|	tr|	j}|	j}|	j}tj|r@|j}||7 }|dkr8|dkr8|  j|7  _|	j| j| j | j| j || q^t
|	tr&|	j}|j| }|dkr|dkr|j|kr||j7 }t||j| }n(|j |kr||j!7 }t||j| }||7 }|  j|7  _q^t
|	t"r^t#dq^W |  jd8  _d S )Nr   g        rR   z1Internal mathtext error: Char node found in vlist)$r  r  r  rV   r  r   r  r5   r  r  rJ  r  r4   r  r   r6   r  r  r  r  r  rX   r  re   r  r  r  r  r  r  r  r  r  r  r  r  )r7   rG   r	  r
  r  r  r  Ztop_edger  r  Zsave_vr  r  r  r  r0   r0   r1   r    sl    











zShip.vlist_outN)	rJ   rK   rL   rM   r  r  r  r  r  r0   r0   r0   r1   r  ;  s
   		?r  c                s     fdd}t  }|j| |S )z$Helper class to raise parser errors.c                s   t | | d S )N)r   )r  loctoks)msgr0   r1   raise_error  s    zError.<locals>.raise_error)r   setParseAction)r  r  r  r0   )r  r1   Error  s    
r  c                   sj  e Zd ZdZedddddZedj Zedj Z	ed	j Z
ee	B e
B Zed
j Zedj Zedj Zedj Zedj Zedj Zedj Zedj Zedj Zdd Zdd ZG dd dZdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d)d)d*d*d+d,d,d-dddyd.Z d/d0 Z!d1d2 Z"d3d4 Z#e#Z$d5d6 Z%d7d|iZ&d>d? Z'd@dAdBdCdDdEdFdGdHdGdCdDdEdFd@dIdJd<dKZ(edLj Z)dMdN ee(Z*dOdP Z+dQdR Z,dSdT Z-dUdV Z.dWdX Z/e/ Z0Z1dYdZ Z2d[d\ Z3d]d^ Z4d_d` Z5dadb Z6dcdd Z7 fdedfZ8dgdh Z9didj Z:dkdl Z;dmdn Z<dodp Z=dqdr Z>dsdt Z?dudv Z@dwdx ZA  ZBS )}Parserz
    A pyparsing-based parser for strings containing math expressions.

    Raw text may also appear outside of pairs of ``$``.

    The grammar is based directly on that in TeX, though it cuts a few corners.
    r   rR   rS   rT   )displaystyle	textstyleZscriptstyleZscriptscriptstylea  
      + * -
      \pm             \sqcap                   \rhd
      \mp             \sqcup                   \unlhd
      \times          \vee                     \unrhd
      \div            \wedge                   \oplus
      \ast            \setminus                \ominus
      \star           \wr                      \otimes
      \circ           \diamond                 \oslash
      \bullet         \bigtriangleup           \odot
      \cdot           \bigtriangledown         \bigcirc
      \cap            \triangleleft            \dagger
      \cup            \triangleright           \ddagger
      \uplus          \lhd                     \amalga  
      = < > :
      \leq        \geq        \equiv   \models
      \prec       \succ       \sim     \perp
      \preceq     \succeq     \simeq   \mid
      \ll         \gg         \asymp   \parallel
      \subset     \supset     \approx  \bowtie
      \subseteq   \supseteq   \cong    \Join
      \sqsubset   \sqsupset   \neq     \smile
      \sqsubseteq \sqsupseteq \doteq   \frown
      \in         \ni         \propto  \vdash
      \dashv      \dots       \dotplus \doteqdota  
      \leftarrow              \longleftarrow           \uparrow
      \Leftarrow              \Longleftarrow           \Uparrow
      \rightarrow             \longrightarrow          \downarrow
      \Rightarrow             \Longrightarrow          \Downarrow
      \leftrightarrow         \longleftrightarrow      \updownarrow
      \Leftrightarrow         \Longleftrightarrow      \Updownarrow
      \mapsto                 \longmapsto              \nearrow
      \hookleftarrow          \hookrightarrow          \searrow
      \leftharpoonup          \rightharpoonup          \swarrow
      \leftharpoondown        \rightharpoondown        \nwarrow
      \rightleftharpoons      \leadstoz, ; . ! \ldotp \cdotpz}
       \sum \prod \coprod \bigcap \bigcup \bigsqcup \bigvee
       \bigwedge \bigodot \bigotimes \bigoplus \biguplus
       zlim liminf limsup sup max minz
\int \ointz.rm cal it tt sf bf default bb frak scr regularz
      arccos csc ker min arcsin deg lg Pr arctan det lim sec arg dim
      liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan
      coth inf max tanhzr
      | \| / \backslash \uparrow \downarrow \updownarrow \Uparrow
      \Downarrow \Updownarrow . \vert \Vert \\|z( [ \{ < \lfloor \langle \lceilz) ] \} > \rfloor \rangle \rceilc          
   C   s  t j }t |_t |_t |_t |_t |_t |_t |_	t |_
t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_t |_ t |_!t |_"t |_#t |_$t |_%t |_&t |_'t |_(t |_)t |_*t |_+t |_,t |_-t |_.t |_/t |_0x0t1|j2 D ] \}}|j3ds|j4| qW | jt5dK  _| jt5dK  _| jt6dj7 K  _| jt6dj7 K  _| jt6dj7 K  _| j t6dj7 K  _ | jt6dK  _| j(t8t9| j:K  _(| j
t;t6d	|j|j |j t<d
B  K  _
d}| j&t5d| K  _&| j't;|jt8| j= K  _'| j.t>|jt8t9t? t@t5djA tB B  K  _.| j-|j&|j.B jA K  _-| jt5dK  _| j	t;|jt8t9| jC K  _	| jtDt;|jt8| jE| jF |j K  _| jt;|jt8t9| jG K  _| j*tH|j|j K  _*| j|jjI K  _| j%tD|jtJ|j/ |j K  _%| j!tD|jtK|j/ |j K  _!| jtD|j*tJ|j/ |j K  _| jt;|jt8t9| jL K  _| jt;|jt8dd | jLD  K  _| jtDt;t6d|j!|j! t<dB  K  _| jtDt;t6d|j!|j! t<dB  K  _| jtDt;t6d|j!|j! t<dB  K  _| jt8t9| jMK  _| jt8t9| jNK  _| j"t8t9| jOK  _"| j#t8| jOdh d+K  _#| jtDt;t6d|jtH|j|jB dd |j |jtH|j|j#B dd |j  |j|j |j  |j% |j! |j! t<dB  K  _| j)tDt;t6dtH|j|j |j  d d|j! t<dB  K  _)| jtDt;t6d|j!t<dB  K  _| j0t>|jt5d  K  _0| jtDt;t6d!|jtJ|j$|j0B  |j t<d"B  K  _| j|j'|jB |j-B |j	B |jB |jB |jB |jB |jB |jB |j)B |jB |jB K  _| j$|j(|j
B |jB |j+B K  _$| j,t8dd#gK  _,| j+tDtH|jtK|j,|j  tH|j |jtH|j B |jB K  _+| j/|j$|jB |j0B K  _/| jt;t6d$|j|jB t<d%B  tDtJ|j$|jB  t;t6d& |j"|jB t<d%B  K  _| jtK|j/K  _| jtPd'dd(d)K  _| jt5d*jA K  _| j|jtJ|j|j  tB  K  _xBt1|j2 D ]2\}}|j3dsrtQ| |rr|jRtS| | qrW |j| _T|j| _Ud S ),N_z[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)z[-+]?[0-9]+r   r   r   r   r&   z\hspacezExpected \hspace{n}u   -🿿z;([a-zA-Z0-9 +\-*/<>=:,.;!\?&'@()\[\]|%s])|(\\[%%${}\[\]_|])z	[^A-Za-z]z'+c             S   s   g | ]}d | qS )r.   r0   )r   r   r0   r0   r1   r   	  s    z#Parser.__init__.<locals>.<listcomp>z\fraczExpected \frac{num}{den}z\dfraczExpected \dfrac{num}{den}z\binomzExpected \binom{num}{den}\}z\genfrac )r   z<Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}z\sqrtzExpected \sqrt{value}z	\overlinezExpected \overline{value}z	[A-Za-z]*z\operatornamezExpected \operatorname{value}r  z\leftzExpected a delimiterz\rightr   F)unquoteResultsz(?:(?:\\[$])|[^$])*)r  )Vr   r   r   accentZ
ambi_delimZ
apostrophe
auto_delimbinomZbslashc_over_ccustomspace	end_groupZfloat_literalr_   fracdfracfunctiongenfracgroupZint_literalZ	latexfontZlbracketZ
left_delimZlbracemainr.   math_stringnon_mathoperatornameoverlineZ	placeableZrbraceZrbracketrequired_groupZright_delimZright_delim_safesimplesimple_groupZsingle_symbolaccentprefixedspacesqrtstart_groupsubsuperZ
subsuperopr-   rx   tokenunknown_symbolvarsr   rX  setNamer   r
   suppressr   rZ  _space_widthsr   r  _accentprefixedr   r"   r   leaveWhitespacer   _char_over_charsr	   _accent_map_wide_accents_function_namesr   r  r   r   
_fontnames_ambi_delim_left_delim_right_delimr   hasattrr  r  _expression_math_expression)r7   r  r   r   Zunicode_ranger0   r0   r1   r8   5	  s$   
&$$"






b


R@H zParser.__init__c             C   s   | j |dd||g| _i | _y| jj|}W nN tk
rz } z2tdjd|jd|j	d  d t
|g|W Y dd}~X nX d| _i | _| jj  |d	 S )
z
        Parse expression *s* using the given *fonts_object* for
        output, at the given *fontsize* and *dpi*.

        Returns the parse tree of `Node` instances.
        r   r   
r  rs   rR   r  Nr   )State_state_stack_em_width_cacherE  parseStringr   r+   r{  linecolumnr  
resetCache)r7   r  Zfonts_objectrv   r   rh   r/   r0   r0   r1   parse&
  s    "
zParser.parsec               @   s:   e Zd ZdZdd Zdd Zedd Zejdd Zd	S )
zParser.Statez
        Stores the state of the parser.

        States are pushed and popped from a stack as necessary, and
        the "current" state is always at the top of the stack.
        c             C   s"   || _ || _|| _|| _|| _d S )N)r  _fontr   rv   r   )r7   r  r_   r   rv   r   r0   r0   r1   r8   G
  s
    zParser.State.__init__c             C   s   t j| j| j| j| j| jS )N)r  rH  r  r_   r   rv   r   )r7   r0   r0   r1   r  N
  s    zParser.State.copyc             C   s   | j S )N)rP  )r7   r0   r0   r1   r_   V
  s    zParser.State.fontc             C   s   |dkr|| _ || _d S )Nr   r   r   )r   r   r   )r   rP  )r7   rM  r0   r0   r1   r_   Z
  s    N)	rJ   rK   rL   rM   r8   r  r  r_   setterr0   r0   r0   r1   rH  @
  s
   rH  c             C   s
   | j d S )z&Get the current `State` of the parser.rR   ro  )rI  )r7   r0   r0   r1   	get_state`
  s    zParser.get_statec             C   s   | j j  dS )zPop a `State` off of the stack.N)rI  pop)r7   r0   r0   r1   	pop_stated
  s    zParser.pop_statec             C   s   | j j| j j  dS )z=Push a new `State` onto the stack, copying the current state.N)rI  r   rR  r  )r7   r0   r0   r1   
push_stateh
  s    zParser.push_statec             C   s
   t |gS )N)r  )r7   r  r  r  r0   r0   r1   r'  l
  s    zParser.mainc             C   s   | j j|d dd S )Nr   rR   ro  )rF  rK  )r7   r  r  r  r0   r0   r1   r(  o
  s    zParser.math_stringc             C   s   t |}| j  |gS )N)r  rT  )r7   r  r  r  hlistr0   r0   r1   r.   r
  s    zParser.mathc                sF   |d j dd} fdd|D }t|} j  td  j _|gS )Nr   z\$r   c                s   g | ]}t | j d dqS )F)r.   )r  rR  )r   r  )r7   r0   r1   r   y
  s    z#Parser.non_math.<locals>.<listcomp>zmathtext.default)replacer  rU  r   rR  r_   )r7   r  r  r  symbolsrV  r0   )r7   r1   r)  w
  s    zParser.non_mathc             C   sf   | j  }|j|j|jf}| jj|}|d krZ|jj|jtd d|j|j}|j	}|| j|< t
|| S )Nzmathtext.defaultr  )rR  r_   rv   r   rJ  r   r  r   r   r   r  )r7   
percentager  r   r4   rZ   r0   r0   r1   _make_space
  s    
zParser._make_spacegKqU?g0Bxq?g%?g1ZGU?      ?)z\,z
\thinspacez\/z\>z\:z\;z\ r  z\enspacez\quadz\qquadz\!c             C   s.   t |dkst| j|d  }| j|}|gS )NrR   r   )r   AssertionErrorr9  rZ  )r7   r  r  r  r   rG   r0   r0   r1   r0  
  s    
zParser.spacec             C   s   | j t|d gS )Nr   )rZ  float)r7   r  r  r  r0   r0   r1   r   
  s    zParser.customspacec       	      C   s  |d }yt || j }W n4 tk
rN } zt||d| |W Y d d }~X nX || jkrtdd |d | d d d D d}|| jkrt|d | j dks|dks|| j	kr|gS t
| jd|| jdgd	d
gS n|| jkr|dkrRtdd |d | d d d D d}tdd ||d d  D d}|dkrR|dkrR|gS |dkr||d  j r||d  j r|gS t
|| jdgd	d
gS |gS )Nr   zUnknown symbol: %sc             s   s   | ]}|d kr|V  qdS )rs   Nr0   )r   r  r0   r0   r1   	<genexpr>
  s    z Parser.symbol.<locals>.<genexpr>rR   r  r   g?T)r  r  c             s   s   | ]}|d kr|V  qdS )rs   Nr0   )r   r  r0   r0   r1   r^  
  s    c             s   s   | ]}|d kr|V  qdS )rs   Nr0   )r   r  r0   r0   r1   r^  
  s    r   r  ro  ro  )r  rR  r+   r   _spaced_symbolsr  _binary_operatorsr   r9  rB  r  rZ  _punctuation_symbolsisdigit)	r7   r  r  r  r  r]  r/   Z	prev_charZ	next_charr0   r0   r1   r-   
  s4    
&
 



& .zParser.symbolc             C   s   |d }t ||d| d S )Nr   zUnknown symbol: %s)r   )r7   r  r  r  r  r0   r0   r1   r5  
  s    zParser.unknown_symbolZAAr   A      ?N\circ        c             C   s  |d }| j  }|jj|j|j|j}| jj|d\}}}	|d krJtd|j	 }
|d d k	rh|d |
_|
 j|d 9  _t
|d |
}|j	 }|d d k	r|d |_| j|d 9  _t|d |}t|j|j}t|g}|j|d t|g}|j|d t|td||	 |gS )Nr           zError parsing symbolrS   rR   exactly)NNrg  )rR  r  r   r_   rv   r   r<  r   r   r  r  r  rV   r4   r  r  r  r  )r7   r  r  r  r   r  r  Z
under_descZ	over_descr0  Z
over_stateZoverZunder_stateZunderr4   Zover_centeredZunder_centeredr0   r0   r1   r  
  s4    



zParser.c_over_cz\circumflexaccentz\combiningbrevez\combiningoverlinez\combininggraveaccentz\combiningacuteaccentz\combiningtildez\combiningdotabovez\combiningdiaeresisz\combiningrightarrowabovez\rightarrowz
\leftarrow)ZhatZbrevebarZgraveacutetildedotZddotZvecr   `r	  r  r  r  ZoverrightarrowZoverleftarrowmathringzwidehat widetilde widebarc                s    fddt D S )Nc                s&   g | ] t  fd dD r qS )c             3   s    | ]} j |o| kV  qd S )N)rX  )r   a)r  r0   r1   r^    s    z-Parser.<lambda>.<locals>.<listcomp>.<genexpr>)any)r   )am)r  r1   r     s    z#Parser.<lambda>.<locals>.<listcomp>)r"   )rq  r0   )rq  r1   <lambda>  s    zParser.<lambda>c       
      C   s   t |dkst| j }|jj|j|j|j}t |d dkrFtd|d \}}|| j	krtt
d| |j|td}nt| j| |}|dkr|j  |j  tt|jd |g}	|	j|jd	 t|	td
|d t|ggS )NrR   r   rS   zError parsing accentr&   )r  rn  g      @rh  g        g       @)r   r\  rR  r  r   r_   rv   r   r   r>  r  r4   r  r=  r  r  r  r  r  r  r  )
r7   r  r  r  r  r  r  r   Z
accent_boxZcenteredr0   r0   r1   r    s(    
zParser.accentc                sF   | j   | j  d _t fdd|d D }| j  |d |_|S )Nr   c                s   g | ]}t | qS r0   )r  )r   r  )r  r0   r1   r   6  s    z#Parser.function.<locals>.<listcomp>r   )rU  rR  r_   r  rT  function_name)r7   r  r  r  rV  r0   )r  r1   r$  2  s    
zParser.functionc             C   sT   | j   | j }d|_x(|d D ]}t|tr d|_|j  q W | j  t|d S )Nr   r   )rU  rR  r_   rJ  r  r  rT  r  )r7   r  r  r  r  r  r0   r0   r1   r*  ;  s    
zParser.operatornamec             C   s*   | j   t|r&|d dd  | j _g S )Nr   rF  )rU  r   rR  r_   )r7   r  r  r  r0   r0   r1   r2  G  s    zParser.start_groupc             C   s   t |d }|gS )Nr   )r  )r7   r  r  r  grpr0   r0   r1   r&  N  s    zParser.groupc             C   s   | j   g S )N)rT  )r7   r  r  r  r0   r0   r1   r!  S  s    zParser.end_groupc             C   s&   t |dkst|d }|| j _g S )NrR   r   )r   r\  rR  r_   )r7   r  r  r  rM  r0   r0   r1   r_   W  s    
zParser.fontc             C   s:   t |tr|j| jkS t |tr6t|dr6|j| jkS dS )Nrs  F)rJ  r  r  _overunder_symbolsr  rD  rs  _overunder_functions)r7   r  r0   r0   r1   is_overunder]  s
    
zParser.is_overunderc             C   s   t |tr|j| jkS dS )NF)rJ  r  r  _dropsub_symbols)r7   r  r0   r0   r1   
is_dropsubd  s    
zParser.is_dropsubc             C   s   t |tr|j S dS )NF)rJ  r  r  )r7   r  r0   r0   r1   r  i  s    
zParser.is_slantedc             C   s   dS )NFr0   )r7   r  r  r0   r0   r1   is_between_bracketsn  s    zParser.is_between_bracketsc       %         s  t |dkstd }d }d }d}g }xX|d D ]L}	t|	trR|	dkrR|t |	7 }q.t|	trp|	jdkrp|d7 }q.|j|	 q.W |}t |dkr|sttd} nt |dkr|s|d S |d }nt |dkrt |dkr|d ntd}|dd  \}
}|
dkr|}n|}nt |dkrt |d
kr8|d ntd}|dd  \}}}}||krz|dkrrtdntd|dkr|}|}n|}|}ntd| j	 }|j
j|j|j|j}|j
j|j|j|j}|r(|d krtg }x*t|D ]}|jj| j||dg qW |j  |j  | j|r4g }d}|j}|d k	r`|j  t||j}|d k	r~|j  t||j}|d k	rt|g}|j|d |j|t|d g t|g}|j|d |j| |d k	rt|g}|j|d |jt|d |g |j}t|}||j |_ t|g}|gS |}t|tr|j}t |rt|d trt!|d dr|d d }|d }t!|dr|j"j#|_t|dd}n t|tr|j"j#|_t|g}t$|}|j}d}| j%|r|j}|j&| }|j&| }| j'|rr||j&| 7 }||j(||d d   7 }| j%|rnd|j& |j) | }d|j& |j) | }nd}|d krtt||g} | j  | j%|r||j*|  }!n
|j+| }!|!| _ ntt||g} | j  | j%|r||j*|  }"n
|j,| }"|d kr|" | _ ntt||g}#|#j  | j%|rH||j*|  }!n
|j-| }!d| |"| j |#j|!   }$|$dkr|"|$7 }"t| t|"| j |#j|!  |#g} |!| _ | j%|s|  j|j.| 7  _t|| g}|gS )NrR   r   r  r  r	  g        rS   rT   rF  rG  zDouble subscriptzDouble superscriptzOSubscript/superscript sequence is too long. Use braces { } to remove ambiguity.z\primerh  g      @r  F)r  g       @)r  r  )rS   rT   )rF  rG  ro  r{  ro  ro  )/r   r\  rJ  r  r  r  r   r  r   rR  r  r   r_   rv   r   r   r  rm  r  extendr-   r  r  rw  r4   r  rV   r  r  r5   r  r6   r  rD  r  r   r  ry  r  r  r  r  r  r  r  r  r  )%r7   r  r  r  r  r  rc  ZnapostrophesZnew_tokstokopr  Zop1Znext1Zop2Znext2r  Zrule_thicknessr   r   vlistr  r4   rV  rh   	last_charr  r  Z	lc_heightZlc_baselineZ	superkernZsubkernr   Z
shift_downZshift_uprd   Zclr)rd  r0   r1   r3  q  s   
















	












zParser.subsuperc             C   s<  | j  }|jj|j|j|j}t|}|| jd krD|j  |j  t	|g}	t	|g}
t
|j|j}|	j|d |
j|d t|	td|d t||td|d |
g}|jj|jtd d|j|j}|
j|j|j d |d   }||_t|t|d gg}|s|r8|d	krd
}|d	kr*d
}| j|||S |S )Nr  rh  r   g       @zmathtext.default=rS   g      @r  r  )rR  r  r   r_   rv   r   r]  _math_style_dictr  r  rV   r4   r  r  r  r  r   r   r5   r\   r^   r  r  r  _auto_sized_delimiter)r7   ZldelimZrdelimZrulestyler   denr  r  ZcnumZcdenr4   r  rZ   r  rh   r0   r0   r1   _genfrac/  s@    




zParser._genfracc             C   s6   t |dkstt |d dks$t| jt|d  S )NrR   r   rn  )r   r\  r  tuple)r7   r  r  r  r0   r0   r1   r%  Y  s    zParser.genfracc             C   sh   t |dkstt |d dks$t| j }|jj|j|j|j}|d \}}| jdd|| j	d ||S )NrR   r   rS   r  r  )
r   r\  rR  r  r   r_   rv   r   r  r  )r7   r  r  r  r  r  r   r  r0   r0   r1   r"  _  s    
zParser.fracc             C   sh   t |dkstt |d dks$t| j }|jj|j|j|j}|d \}}| jdd|| j	d ||S )NrR   r   rS   r  r  )
r   r\  rR  r  r   r_   rv   r   r  r  )r7   r  r  r  r  r  r   r  r0   r0   r1   r#  k  s    
zParser.dfracc             C   sJ   t |dkstt |d dks$t|d \}}| jddd| jd ||S )NrR   r   rS   r   r   g        r  )r   r\  r  r  )r7   r  r  r  r   r  r0   r0   r1   r  w  s
    
zParser.binomc                sF  |d \}}| j    jj j j j}|j|j |d  }|j|j }t	d|| dd}	|	j|	j }|	j|	j }t
td| |td| g}
tt td|
g}|j| j j d  d
| |d krt|	jd dd}n&t
 fdd|D }|j  |j  tt
|gg}| d |_t
|t|	j d |	|g}|gS )Nr   g      @z	\__sqrt__T)r  rS   r  g      Y@g      (@rh  g      ?g        c                s   g | ]}t | qS r0   )r  )r   r   )r  r0   r1   r     s    zParser.sqrt.<locals>.<listcomp>g333333?g     @)rR  r  r   r_   rv   r   r5   r  r6   r  r  r  r  r  r  r  r  r4   r  r  )r7   r  r  r  rootbodyr  r5   r6   checkZpadded_body	rightsideZ
root_vlistrV  r0   )r  r1   r1    s2    zParser.sqrtc             C   s   t |dkstt |d dks$t|d d }| j }|jj|j|j|j}|j|j	 |d  }|j
|j	 }tt|tdt|gg}	|	j||j|j d  d| t|	g}
|
gS )	NrR   r   g      @r  g      Y@g      (@rh  g     @)r   r\  rR  r  r   r_   rv   r   r5   r  r6   r  r  r  r  r  )r7   r  r  r  r  r  r  r5   r6   r  rV  r0   r0   r1   r+    s    
zParser.overlinec       
      C   s   | j  }t|r:tdd |D }tdd |D }d }nd}d}d}g }|dkrj|jt|||||d |j| |dkr|jt|||||d t|}	|	S )Nc             s   s   | ]}|j V  qd S )N)r5   )r   r   r0   r0   r1   r^    s    z/Parser._auto_sized_delimiter.<locals>.<genexpr>c             s   s   | ]}|j V  qd S )N)r6   )r   r   r0   r0   r1   r^    s    r   g      ?r  )r  )rR  r   rV   r   r  r}  r  )
r7   frontmiddlebackr  r5   r6   r  partsrV  r0   r0   r1   r    s$    
zParser._auto_sized_delimiterc             C   s   |\}}}| j ||j |S )N)r  asList)r7   r  r  r  r  r  r  r0   r0   r1   r    s    
zParser.auto_delimgKqUſr   rc  rd  Nre  r[  )r  r  rf  )CrJ   rK   rL   rM   ri  r  r   r9  r`  Z_relation_symbolsZ_arrow_symbolsr_  ra  ru  rv  rx  r@  r?  rA  rB  rC  r8   rO  rH  rR  rT  rU  r'  r(  r.   r)  rZ  r9  r0  r   r-   r/  r5  r<  r  r=  r>  r:  r  r$  r*  r2  r&  r,  r.  r!  r_   rw  ry  r  rz  r3  r  r%  r"  r#  r  r1  r+  r  r  re  r0   r0   )rd  r1   r    s   







 r 	&&
	 ?*(r  c            	   @   s   e Zd ZdZeeeeee	e
edZeeeeeedZdd ZdddZejd	d
d ZdddZdddZdddZdddZdS )MathTextParserN)bitmapZaggry   Zpdfsvgr   Zcairomacosx)r=  ZdejavuserifZ
dejavusansr>  r?  Zcustomc             C   s   |j  | _dS )z7Create a MathTextParser for the given backend *output*.N)r   _output)r7   outputr0   r0   r1   r8     s    zMathTextParser.__init__r   c             C   s   | j |||td td S )aZ  
        Parse the given math expression *s* at the given *dpi*.  If *prop* is
        provided, it is a `.FontProperties` object specifying the "default"
        font to use in the math expression, used for all non-math text.

        The results are cached, so multiple calls to `parse`
        with the same expression should be fast.
        z	ps.useafmzmathtext.fontset)_parse_cachedr   )r7   r  r   rK  r0   r0   r1   rO    s    zMathTextParser.parse2   c             C   s   |d krt  }| jdkr&|r&t|}n(| j| j  }tj| j|d}|||}|j }	| jd krjt	 | j
_| jj|||	|}
|j|
j|
j|
j |j|
S )Nry   )fontset)r   r  rt  _backend_mappingr   Z_check_getitem_font_type_mappingZget_size_in_points_parserr  rd  rO  r<   r4   r5   r6   rH   )r7   r  r   rK  Z	ps_useafmr  r  backendZfontset_classrv   rG   r0   r0   r1   r    s    



zMathTextParser._parse_cachedx      c             C   s:   | j dkstt|d}| j|||d\}}tj||fS )a  
        Parameters
        ----------
        texstr : str
            A valid mathtext string, e.g., r'IQ: $\sigma_i=15$'.
        dpi : float
            The dots-per-inch setting used to render the text.
        fontsize : int
            The font size in points

        Returns
        -------
        array : 2D uint8 alpha
            Mask array of rasterized tex.
        depth : int
            Offset of the baseline from the bottom of the image, in pixels.
        r  )rL  )r   rK  )r  r\  r   rO  rX   Zasarray)r7   texstrr   rv   rK  ftimager6   r0   r0   r1   to_mask   s    
zMathTextParser.to_maskblackc             C   s   | j |||d\}}tj|\}}}	}
tj|jd |jd dftjd}d| |dddddf< d| |dddddf< d|	 |dddddf< ||ddddd	f< ||fS )
a0  
        Parameters
        ----------
        texstr : str
            A valid mathtext string, e.g., r'IQ: $\sigma_i=15$'.
        color : color
            The text color.
        dpi : float
            The dots-per-inch setting used to render the text.
        fontsize : int
            The font size in points.

        Returns
        -------
        array : (M, N, 4) array
            RGBA color values of rasterized tex, colorized with *color*.
        depth : int
            Offset of the baseline from the bottom of the image, in pixels.
        )r   rv   r   rR   rF  )Zdtype   NrS   rT   )r  mcolorsto_rgbarX   zerosshapeZuint8)r7   r  colorr   rv   r   r6   r  r!  r  ro  ZRGBAr0   r0   r1   r  7  s    "zMathTextParser.to_rgbac             C   s.   | j ||||d\}}tj|j|dd |S )a/  
        Render a tex expression to a PNG file.

        Parameters
        ----------
        filename
            A writable filename or fileobject.
        texstr : str
            A valid mathtext string, e.g., r'IQ: $\sigma_i=15$'.
        color : color
            The text color.
        dpi : float
            The dots-per-inch setting used to render the text.
        fontsize : int
            The font size in points.

        Returns
        -------
        int
            Offset of the baseline from the bottom of the image, in pixels.
        )r  r   rv   Zpng)r,   )r  r   Z	fromarraysave)r7   r   r  r  r   rv   Zrgbar6   r0   r0   r1   to_pngU  s    zMathTextParser.to_pngc             C   s0   | j dkstt|d}| j|||d\}}|S )aQ  
        Parameters
        ----------
        texstr : str
            A valid mathtext string, e.g., r'IQ: $\sigma_i=15$'.
        dpi : float
            The dots-per-inch setting used to render the text.

        Returns
        -------
        int
            Offset of the baseline from the bottom of the image, in pixels.
        r  )rL  )r   rK  )r  r\  r   rO  )r7   r  r   rv   rK  r  r6   r0   r0   r1   	get_depthp  s    
zMathTextParser.get_depth)r   N)r  r  )r  r  r  )r  r  r  )r  r  )rJ   rK   rL   r  rk   rN   rm   rz   r   r   r   r  r   r`  rf  r   rH  r<  r  r8   rO  rr  rs  r  r  r  r  r  r0   r0   r0   r1   r    s,   



r  c             C   s   ddl m} ddlm} |dkr&t }td}|j| d|d\}}	}
}}|j|d |	d fd	}|jd|
|	 | |d
 |j	| |j
|||d |
S )a  
    Given a math expression, renders it in a closely-clipped bounding
    box to an image file.

    Parameters
    ----------
    s : str
        A math expression.  The math portion must be enclosed in dollar signs.
    filename_or_obj : str or path-like or file-like
        Where to write the image data.
    prop : `.FontProperties`, optional
        The size and style of the text.
    dpi : float, optional
        The output dpi.  If not set, the dpi is determined as for
        `.Figure.savefig`.
    format : str, optional
        The output format, e.g., 'svg', 'pdf', 'ps' or 'png'.  If not set, the
        format is determined as for `.Figure.savefig`.
    r   )figure)ri   Nr   r   )r   rK  g      R@)Zfigsize)Zfontproperties)r   r,   )
matplotlibr  rj   ri   r   r  rO  ZFiguretextZFigureCanvasAggZsavefig)r  Zfilename_or_objrK  r   r,   r  ri   parserr4   r5   r6   r  Zfigr0   r0   r1   math_to_image  s    
r  )Tg      )NNN)rM   collectionsr   rr  ior   loggingr   r   rV  numpyrX   ZPILr   	pyparsingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r  r   Zmatplotlib.afmr   Zmatplotlib.ft2fontr   r   r   Zmatplotlib.font_managerr   r   r   Zmatplotlib._mathtext_datar    r!   r"   r#   r$   enablePackrat	getLoggerrJ   rT  r2   r3   rN   rk   rm   rz   r   r   r   r   r   r   r<  r_  r`  rf  r   rH  rt  r  r  r  r  r  r  r  r  r  r  r  Warningr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  Z(_suppress_matplotlib_deprecation_warningr   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rf   r  r  r  r  r0   r0   r0   r1   <module>   s  L

"7K* kq ,h 2$	S=qO	$


' 
         '