
    -Ph                     	   d dl Z d dlZd dlZd dlmZ dZ G d d          Z G d d          Z G d d	          Z G d
 d          Z	 G d d          Z
 G d d          Z G d d          Z G d d          Z G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d  d!e          Z G d" d#          Z G d$ d%e          Z G d& d'e          Z G d( d)e          Z G d* d+e          Z G d, d-e          Z G d. d/e          Z G d0 d1          Z G d2 d3          Z G d4 d5          Z G d6 d7e          Z G d8 d9e          Z  G d: d;          Z! G d< d=e!          Z" G d> d?e!          Z# G d@ dAe#          Z$ G dB dC          Z% G dD dEe          Z& G dF dGe!          Z' G dH dIe'          Z( G dJ dKe$          Z) G dL dMe'          Z* G dN dOe'          Z+ G dP dQe'          Z, G dR dSe'          Z- G dT dUe'          Z. G dV dWe'          Z/ G dX dYe/          Z0 G dZ d[          Z1 G d\ d]          Z2 G d^ d_e!          Z3 G d` dae'          Z4 G db dc          Z5 G dd dee'          Z6 G df dge6          Z7 G dh die7          Z8 G dj dke7          Z9 G dl dme8          Z: G dn doe7          Z; G dp dqe7          Z< G dr dse7          Z= G dt due;          Z>e5xj?        e6e<gz  c_?        e:e8e;e>e=e9ge6_?         G dv dw          Z@ G dx dye7          ZA G dz d{e6          ZB G d| d}e6          ZC G d~ de7          ZD G d deD          ZE G d deD          ZF G d deD          ZG G d deD          ZH G d de7          ZIe6xj?        eIgz  c_?         G d de;          ZJ G d de;          ZK G d de;          ZL G d de8          ZM G d deM          ZN G d de1          ZO G d de;          ZP G d de1          ZQe6xj?        eKeLeJeMePgz  c_?        e2xjR         eO             eQ            gz  c_R         G d d          ZS G d de7          ZT G d deT          ZU G d d          ZVe6xj?        eUgz  c_?        d ZWd ZXeYdk    r eX             dS dS )    N)tex2unicharz1.3 (2021-06-02)c                       e Zd ZdZdZdZdZdZd Zd Z	d Z
d Z ee          Z ee	          Z	 ee
          Z
 ee          ZdS )TracezA tracing classFNc                     t           j        rt           j        rdS t                               |t          j                   dS )zShow a debug messageN)r   	debugmode	quietmodeshowsysstdoutclsmessages     ]/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/docutils/utils/math/math2html.pydebugzTrace.debug+   s6     	%/ 	F

7CJ'''''    c                     t           j        rdS t           j        rt           j        rt           j        |z   }t                               |t
          j                   dS )zShow a trace messageN)r   r   prefixshowlinesmoder	   r
   r   r   s     r   r   zTrace.message1   sM    ? 	F< 	-E/ 	-lW,G

7CJ'''''r   c                     d|z   }t           j        rt           j        rt           j        |z   }t                               |t          j                   dS )zShow an error messagez* N)r   r   r   r	   r
   stderrr   s     r   errorzTrace.error9   sG    .< 	-E/ 	-lW,G

7CJ'''''r   c                 6    |                     |dz              dS )zShow a message out of a channel
N)write)r   r   channels      r   r	   z
Trace.show@   s    gn%%%%%r   )__name__
__module____qualname____doc__r   r   r   r   r   r   r   r	   classmethod r   r   r   r   "   s        IIMF( ( (( ( (( ( (& & & KEk'""GKE;tDDDr   r   c                   "    e Zd ZdZdgg ddZdS )ContainerConfig+Configuration class from elyxer.config fileFormulaConstant)AlphaCommandBracketBracketCommandCombiningFunctionEmptyCommandFontFunctionFormulaFormulaNumberFormulaSymbolOneParamFunctionOversetFunctionRawTextSpacedCommandSymbolFunctionTextFunctionUndersetFunctionallowed	extractedN)r   r   r   r   extracttextr!   r   r   r#   r#   J   s7        11 &&   KKKr   r#   c                   *    e Zd ZdZddddZdddd	Zd
S )EscapeConfigr$       ’u   ‘)r   '`z&amp;z&lt;z&gt;)&<>N)r   r   r   r   charsentitiesr!   r   r   r;   r;   c   sB        11  E  HHHr   r;   c                      e Zd ZdZi dddddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&Zej                                        D ]\  ZZ	e	ed'ez   <   d(d)d*d+d,Z
g d-g d.g d/g d0g d1g d2d3gd4gd5Zd6d7d6d6d8d9Zd:d;d<d=d>d?d@dAdBdCdDdEZej                                        D ]\  ZZ	e	ed'ez   <   i d+dFdGdHdIdHdJdKdLdMdNdOdPdQdRdSdTdUdVdSdWdUdXdUdYdSdZd[d\d]d^d_d`d4i dad4dbd3dcdFdddedfdgdhdgdidjdkd4dld3dmdndodpdqd'drdOdsdtdudSdvdwdxdwi dyd[dzd{d|d}d~dddddddddddddddddddddHddddddi dddddddddddddddddddddddddddddddddddddddddddddddddȜZi Ze                    ej                   e                    ej                   e                    ej                   e                    ej                   e                    ej                   e                    ej                   e                    ej                   e                    dɄ e                                D                        dddddddnddќZddddҜZddddddלZddgg dڢddgddgdܜZi ddޓddddddddddddddddddddddddddddddddi dd ddddddddd	dޓd
dddddddddddddddddddddi d d!d"d#d$d%d&d'd(d)d*d+d,dd-d.d/dd0d1d2d3d4d5d6d7d8d9d:dd;dd<ddddddd=d>d7d?Zi d@g dAdBg dCdDg dEdFg dGdHg dIdJg dKdLg dMdNg dOdPg dQdRg dSdTg dUdVg dWdXg dWdYg dZd[g d\d]g d\d^g d_i d`g dadbg dcddg dEdeg dfdgg dhdig djdkg dldmg dndog dpdqdrdggdsg dtdug dvdwg dxdyg dzd{g d|d}g dQd~g dg dMg dg d\g dg dg dg dg ddZdddddddZddiZ i ddddddddddddddddddddddddddddddddddi dddddddddddddddddddddddÐdēdŐdƓdǐdȓdɐdʓdːdd̐d͓dΐdϐdАdѐdҐdϐdӜZ!dgdgdgdddՐd֐dאdؐdِdڐdېddgdedݜZ"i dސdߓddߓddߓdddddddddddddddddddddddddddddddddgddZ#i ddddd ddddddddd	d
dddddddddddddddddZ$ej%                                        D ]\  ZZ	e	e$d'ez   <   dӐddd'ddd d!d"d#	Z&dd$d%Z'd&d'd(d)d*d+d,d-d.d/d0d1Z(d2g d3iZ)d4S (5  FormulaConfigr$   z\AmSz<span class="textsc">AmS</span>z\AA   Åz\AE   Æz\DH   Ðz\Lu   Łz\O   Øz\OEu   Œz\TH   Þz\aa   åz\ae   æz\dh   ðz\iu   ız\ju   ȷz\lu   łz\o   øz\oeu   œz\ss   ß   þu   ħ)z\thz\hbar\z\beginr@   z\endz\\)begincellseparatorendrowseparator)u   ⎛u   ⎜u   ⎝)u   ⎞u   ⎟u   ⎠)u   ⎡u   ⎢u   ⎣)u   ⎤u   ⎥u   ⎦)u   ⎧   ⎪u   ⎨u   ⎩)u   ⎫rW   u   ⎬u   ⎭|   ‖)()[]{}rX   rY   span class="stretchy"z<span class="leftdot"></span>z<span class="rightdot"></span>)\leftz\left.z\middle\rightz\right.u   ́u   ̈u   ̂u   ̀u   ̃u   ̧u   ̊u   ̩u   ⃝u   ̥u   ̌)z\'z\"z\^z\`z\~z\cz\rz\sz\textcircledz\textsubringz\vz<br/>z\
 z\	z
\centerdotu   ⬝z\colon: z
\copyright   ©z	\dotminusu   ∸z\dotsu   …z\dotsbu   ⋯z\dotscz\dotsiz\dotsmz\dotsoz\euro   €z\guillemotleft   «z\guillemotright   »z\lVertz
\Arrowvertz\lvertz\newlinez\nobreakspace    z	\nolimitsr<   z	\nonumberz\qquadu     z\rVertz\rvertz\textasciicircum^z\textasciitilde~z\textbackslashz\textcopyrightz\textdegree   °z\textellipsisz\textemdashu   —z\textendashz	\texteuroz\textgreaterrB   z	\textlessrA   z\textordfeminine   ªz\textordmasculine   ºz\textquotedblleftu   “z\textquotedblrightu   ”z\textquoterightr=   z\textregistered   ®z\textrightarrowu   →z\textsection   §z\texttrademarku   ™z\texttwosuperior   ²z\textvisiblespacez\thickspacez!<span class="thickspace"> </span>z\;z	\triangleu   △z\triangledownu   ▽z\varnothingu   ⌀z\PrPrz\arccosarccosz\arcsinarcsinz\arctanarctanz\argargz\coscosz\coshcoshz\cotcotz\cothcothz\csccscz\degdegz\detdetz\dimdimz\expexpz\gcdgcdhomu	   inj limkerlgu	   lim infu	   lim suplnlogu
   proj limsecsinsinhtantanh)z\homz\injlimz\kerz\lgz\liminfz\limsupz\lnz\logz\projlimz\secz\sinz\sinhz\tanz\tanhc              #   *   K   | ]\  }}d |z   |fV  dS )rR   Nr!   ).0keyvalues      r   	<genexpr>zFormulaConfig.<genexpr>  s/      JJJCTCZ'JJJJJJr   u   ‒u$   <span class="smallsymbol">⋯</span>u$   <span class="smallsymbol">→</span>u   ⟵u   ⟷u   ⟶u   ～)z\barz\dddotz\vecz\overleftarrowz\overleftrightarrowz\overrightarrowz\widehatz
\widetilde)z\underleftarrowz\underleftrightarrowz\underrightarrowr_   \]z\end{r]   )bracketcomplexendafter	endbeforesquarebracketrl)r   cr   r   )aligneqnarraygatheredsmallmatrixz\boldsymbolbz\mathbbzspan class="blackboard"z
\mathbb{A}u   𝔸z
\mathbb{B}u   𝔹z
\mathbb{C}u   ℂz
\mathbb{D}u   𝔻z
\mathbb{E}u   𝔼z
\mathbb{F}u   𝔽z
\mathbb{G}u   𝔾z
\mathbb{H}u   ℍz
\mathbb{J}u   𝕁z
\mathbb{K}u   𝕂z
\mathbb{L}u   𝕃z
\mathbb{N}u   ℕz
\mathbb{O}u   𝕆z
\mathbb{P}u   ℙz
\mathbb{Q}u   ℚz
\mathbb{R}u   ℝz
\mathbb{S}u   𝕊z
\mathbb{T}u   𝕋z
\mathbb{W}u   𝕎z
\mathbb{Z}u   ℤz\mathbfz\mathcalzspan class="scriptfont"z\mathcal{B}u   ℬz\mathcal{E}u   ℰz\mathcal{F}u   ℱz\mathcal{H}u   ℋz\mathcal{I}u   ℐz\mathcal{L}u   ℒz\mathcal{M}u   ℳz\mathcal{R}u   ℛz	\mathfrakzspan class="fraktur"z\mathfrak{C}u   ℭz\mathfrak{F}u   𝔉z\mathfrak{H}u   ℌz\mathfrak{I}u   ℑz\mathfrak{R}u   ℜz\mathfrak{Z}u   ℨz\mathitiz\mathring{A}z\mathring{U}u   Ůz\mathring{a}z\mathring{u}u   ůz\mathring{w}u   ẘz\mathring{y}u   ẙz\mathrmzspan class="mathrm"z\mathscrzspan class="mathscr"z\mathscr{B}z\mathscr{E}z\mathscr{F}zspan class="mathsf"zspan class="mathtt")z\mathscr{H}z\mathscr{I}z\mathscr{L}z\mathscr{M}z\mathscr{R}z\mathsfz\mathttz\operatornamez\addcontentsline)z{$p!}{$q!}{$r!}f0{}ignoredz\addtocontents)z
{$p!}{$q!}r   r   z\backmatter)r<   r   r   \binom){$1}{$2}zf2{(}f0{f1{$1}f1{$2}}f2{)}zspan class="binom"zspan class="binomstack"span class="bigdelimiter size2"z\boxed){$1}f0{$1}zspan class="boxed"\cfrac)z[$p!]{$1}{$2}!f0{f3{(}f1{$1}f3{)/(}f2{$2}f3{)}}span class="fullfraction"zspan class="numerator align-$p"span class="denominator"span class="ignored"z\color)	{$p!}{$1}r   zspan style="color: $p;"z	\colorbox)r   r   z-span class="colorbox" style="background: $p;"\dbinom)r   u%   (f0{f1{f2{$1}}f1{f2{ }}f1{f2{$2}}})zspan class="binomial"zspan class="binomrow"zspan class="binomcell"\dfrac)r   r   r   span class="numerator"r   r   z\displaystyle)r   r   zspan class="displaystyle"z
\fancyfoot)z
[$p!]{$q!}r   r   z
\fancyheadz\fbox)r   r   zspan class="fbox"z	\fboxrule){$p!}r   r   z\fboxsepz
\fcolorbox)z{$p!}{$q!}{$1}r   z<span class="boxed" style="border-color: $p; background: $q;"\frac)r   r   span class="fraction"r   r   r   z	\framebox)z[$p!][$q!]{$1}r   z1span class="framebox align-$q" style="width: $p;"z\frontmatterz\href)z[$o]{$u!}{$t!}zf0{$t}a href="$u"z\hspace)r   f0{ }z&span class="hspace" style="width: $p;"z	\leftroot)r   r   z*span class="leftroot" style="width: $p;px"z	\nicefrac)r   u   f0{f1{$1}⁄f2{$2}}r   zsup class="numerator"zsub class="denominator"r   z\parbox)z[$p!]{$w!}{$1}zf0{1}z$div class="Boxed" style="width: $w;"z	\raisebox)r   zf0{$1.font}z1span class="raisebox" style="vertical-align: $p;"z\renewenvironmentz{$1!}{$2!}{$3!}z\rule)z[$v!]{$w!}{$h!}zf0/z.hr class="line" style="width: $w; height: $h;"z\scriptscriptstyle)r   r   zspan class="scriptscriptstyle"z\scriptstyle)r   r   zspan class="scriptstyle"z\sqrt)[$0]{$1}u!   f0{f1{$0}f2{√}f4{(}f3{$1}f4{)}}zspan class="sqrt"zsup class="root"zspan class="radical"zspan class="root"r   z	\stackrel)r   zf0{f1{$1}f2{$2}}zspan class="stackrel"zspan class="upstackrel"zspan class="downstackrel"\tbinomz\tfrac)r   r   zspan class="textfraction"r   r   r   )r   r   zspan class="textstyle")r   z$0f0{$1.font}zspan class="unit")z[$0]{$1}{$2}u   $0f0{f1{$1.font}⁄f2{$2.font}}r   zsup class="unit"zsub class="unit")r   r   z(span class="uproot" style="width: $p;px")z{$u!}zf0{$u}r   )r   r   z'span class="vspace" style="height: $p;")z
\textcolorz
\textstylez\thispagestylez\unitz	\unitfracz\uprootz\urlz\vspacez$1+$2z$1+$2+1)r   r   r   r   r   r   z\labelz
a name="#"z\biginterleaveu   ⫼z\infinfz\limlimz\maxmaxz\minminz\supsupz\ointopu-   <span class="bigoperator integral">∮</span>z\bigcapu$   <span class="bigoperator">⋂</span>z\bigcupu$   <span class="bigoperator">⋃</span>z\bigodotu$   <span class="bigoperator">⨀</span>z	\bigoplusu$   <span class="bigoperator">⨁</span>z
\bigotimesu$   <span class="bigoperator">⨂</span>z	\bigsqcapu$   <span class="bigoperator">⨅</span>z	\bigsqcupu$   <span class="bigoperator">⨆</span>z	\biguplusu$   <span class="bigoperator">⨄</span>z\bigveeu$   <span class="bigoperator">⋁</span>z	\bigwedgeu$   <span class="bigoperator">⋀</span>z\coprodu$   <span class="bigoperator">∐</span>z\intopu-   <span class="bigoperator integral">∫</span>z\produ$   <span class="bigoperator">∏</span>z\sumu$   <span class="bigoperator">∑</span>z\varprodu$   <span class="bigoperator">⨉</span>z\zcmpu   ⨟z\zhideu   ⧹z\zpipeu   ⨠z	\zprojectu   ⨡z\intz\iintu-   <span class="bigoperator integral">∬</span>z\iiintu-   <span class="bigoperator integral">∭</span>z\iiiintu-   <span class="bigoperator integral">⨌</span>z\fintu-   <span class="bigoperator integral">⨏</span>z	\idotsintu3   <span class="bigoperator integral">∫⋯∫</span>z\ointz\oiintu-   <span class="bigoperator integral">∯</span>u-   <span class="bigoperator integral">∰</span>u-   <span class="bigoperator integral">∲</span>u-   <span class="bigoperator integral">∳</span>u-   <span class="smallsymbol integral">∫</span>u-   <span class="bigoperator integral">⨖</span>)z\oiiintz\ointclockwisez\ointctrclockwisez	\smallintz\sqintz\varointclockwise	u    + u   , u	    − u	    ⁄ z : u
    &lt; u    = u
    &gt; )r   rc   $r@   r>   +,-/:rA   =rB   @rk   z\bigzspan class="bigdelimiter size1"z\biglz\bigrz\Bigr   z\Biglz\Bigrz\biggzspan class="bigdelimiter size3"z\bigglz\biggrz\Biggzspan class="bigdelimiter size4"z\Bigglz\Biggrz\begin{array}zspan class="arraydef"z
\centeringzspan class="align-center"z\ensuremathzspan class="ensuremath"z	\hphantomzspan class="phantom"z	\noindentzspan class="noindent"zspan class="overbrace"zspan class="overline"zspan class="underbrace")z
\overbracez	\overlinez\phantomz\underbracez
\underlinez	\vphantomz\nleqqu   ≦̸z\ngeqqu   ≧̸z
\nleqslantu   ⩽̸z
\ngeqslantu   ⩾̸z\nsubseteqqu   ⫅̸z\nsupseteqqu   ⫆̸z
\nsqsubsetu   ≶⊏z	\shortmidu$   <span class="smallsymbol">∣</span>z\shortparallelu$   <span class="smallsymbol">∥</span>z
\nshortmidu$   <span class="smallsymbol">∤</span>z\nshortparallelu$   <span class="smallsymbol">∦</span>z\smallfrownu$   <span class="smallsymbol">⌢</span>z\smallsmileu$   <span class="smallsymbol">⌣</span>z\thickapproxu#   <span class="boldsymbol">≈</span>z	\thicksimu#   <span class="boldsymbol">∼</span>z
\varproptou   <span class="mathsf">∝</span>z\begin{r^   %\[r   r\   *)	
beginafterbeginbeforer   commandcommentr   simpler   
unnumberedsub)rj   _zspan class="mbox"zspan class="text"zspan class="textbf"zspan class="textit"zspan class="textnormal"zspan class="textrm"zspan class="textsc"zspan class="textsf"zspan class="textsl"zspan class="texttt"zspan class="normal")z\mboxz\textz\textbfz\textitz\textnormalz\textrmz\textscz\textsfz\textslz\textttz\textup
characters).r   rf   rZ   r[   r\   r]      ·!;rX   rp   "?N)*r   r   r   r   alphacommandsr   	mathalphaitemsr   r   arraybigbracketsbracketcommandscombiningfunctions
mathaccentcommandscmddictupdatemathbinmathopen	mathclose	mathfencemathord	mathpunctspaceoversetfunctionsundersetfunctionsendingsenvironmentsfontfunctionshybridfunctionshybridsizeslabelfunctionslimitcommandsmodifiedonefunctionsspacedcommandsmathrelstartssymbolfunctionstextfunctions
unmodifiedr!   r   r   rF   rF   s   sf       112t 	t 	t	
 	t 	t 	t 	t 	t 	t 	t 	t 	t 	t 	t  	t!" 	t#$ '  M* "+1133 ( (
U"'d3h 	 E .-----------444444 !' K *2+*4 O "!!!!!!!!!!  ",2244 - -
U',48$$TTT 	T 	x	T
 	4T 	tT 	eT 	%T 	5T 	5T 	5T 	5T 	5T 	%T 	4T  	D!T" 	5#T T$ 	%T& 	3'T( 	W)T* 	$+T, 	b-T. 	b/T0 	81T2 	53T4 	35T6 	S7T8 	C9T: 	4;T< 	4=T> 	?T@ 	%ATB 	CTD 	ET T TF 	eGTH 	ITJ 	cKTL 	TMTN 	dOTP 	eQTR 	uSTT 	EUTV 	DWTX 	EYTZ 	[T\ 	5]T^ 	T_T` 	caTb 	;cTd 	2eTf 	hgT T Th 	(iTj 	kTn 	oTp 	HqTr 	HsTt 	HuTv 	wTx 	yTz 	&{T| 	}T~ 	&T@ 	ATB 	CTD 	ETF 	GTH 	ITJ 	KT TL !gT T THj GNN;&'''NN;'(((NN;()))NN;()))NN;&'''NN;()))NN;$%%%OOJJ'--//JJJJJJ
  = =  %!' . "!&"   G s#OO#JSz	 L')Bv,f6CU 	v  -f 7DV 	v	  -e	 6CF	
 	v
  -f
 7DU 	v  -e 6CE  	u ,V 6CF 	v  -e 6@ 	. 	  .u 7E u '5e 	  .u 7Ee 	, 	   !0 :I% 	 !0 9H  	C!" 	#"  /#$ 	%$  /%$ 7Fu%& 	'( 	))* 	++, 	-,  .u-, 7Ee- . ueu))/7  M<.CCC.<<<. 	///. 	  R  R  R	.
 	;;;. 	  ~  ~  ~. 	EEE. 	^^^. 	  V  V  V. 	  p  p  p. 	III. 	888. 	888. 	999. 	222.  	111!." 	sss#. .$ 	  k  k  k%.& 	ggg'.( 	000).* 	===+., 	PPP-.. 	VVV/.4 	  _  _  _5.6 	WWW7.8 	ggg9.: 	0"5;.< 	^^^=.> 	SSS?.@ 	GGGA.D 	  r  r  rE.F 	  H  H  HG.H 	  V  V  VI.J 	  q  q  qK. .L JIICCC777DDD K  K  KRRR333QQQ[. . .Ob wIg9 K 	<N(5(( 	( 		(
 	( 	( 	F( 	=( 	=( 	=( 	=( 	=( 	=( 	=( 	=(  	=!(" 	=#( ($ 	=%(& 	F'(( 	=)(* 	=+(, 	=-(. 	%/(. #E/(. ,5e/(. >J5/(4 	@5(6 	A7(8 	B9(: 	C;(< 	A=(> 	K?(@ 	AA(B 	BC( (D DJMEBMO( ( (MV rE.5FUYk#5BX H23 	3 	2	
 	3 	3 	3 	4 	4 	3 	4 	4 	1 	2  	1!" 	,#$ 	-%& 0-+1,1  L8 	 		
 	 	 	 	 	< 	A 	= 	B 	> 	>  	>!" 	;#$ 	;%N( ")//11 ) )
U#(tCx  *CESC F  O
 &%))1)))))) M 	 < < <
JJJr   rF   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )CommandLineParserzA parser for runtime optionsc                     || _         d S N)options)selfr   s     r   __init__zCommandLineParser.__init__  s    r   c                 l   t          |          dk    rdS t          |          dk    r|d                             d          rp|                     |          \  }}|sd|z   dz   S |sd|z   dz   S t          | j        ||           t          |          dk    r|d                             d          pdS )Parse command line optionsr   N--zOption z not recognizedz needs a value)len
startswith
readoptionsetattrr   )r   argsr   r   s       r   parseoptionszCommandLineParser.parseoptions"  s    t99>>4$ii!mmQ 2 24 8 8m..JC = 5(+<<< : 3)999DL#u--- $ii!mmQ 2 24 8 8m tr   c                 b   |d         dd         }|d= d|v r|                      ||          }n|                    dd          }t          | j        |          sd|fS t	          | j        |          }t          |t                    r|dfS t          |          dk    r|dfS |d                             d          r#|d         }|d= || 	                    ||          fS |d         
                    d	          }|d= t          |t                    r|                    |           ||fS ||fS )
z$Read the key and value for an optionr      Nr   r   r<   Tr   zutf-8)readequalskeyreplacehasattrr   getattr
isinstanceboolr  r  
readquoteddecodelistappend)r   r  rv   r   currentinitialr   s          r   r  zCommandLineParser.readoption/  sH   1gabbkG#::$$S$//CC++c2&&Ct|S)) 	9$,,,gt$$ 	9t99>>97c"" 	71gGQg6666Qw''Ggt$$ 	 NN5!!!<Ezr   c                 Z   t                               d           |dd         }t          |          dk    r|d                             d          s|d                             d          s}t                               d|d         z              |d|d         z   z  }|d= t          |          dk    r6|d                             d          s|d                             d          }t          |          dk    s|d                             d          rdS |d|dd	         z   z  }|S )
zRead a value between quotesOops   Nr   r   r  z
Appending rc   )r   r   r  endswithr  )r   r  r  r   s       r   r  zCommandLineParser.readquotedJ  s   F$ii!mmDG$4$4S$9$9m$q'BTBTUYBZBZmKKtAw.///S47]"EQ $ii!mmDG$4$4S$9$9m$q'BTBTUYBZBZm t99>>T!W//55>4tAbDz!!r   c                 ~    |                     dd          }|d         }|d         }|                    d|           |S )zRead a key using equalsr   r  r   )splitinsert)r   rv   r  r  r   r   s         r   r  zCommandLineParser.readequalskeyW  s@    		#q!!AhaAu
r   N)	r   r   r   r   r   r  r  r  r  r!   r   r   r   r     se        ""      6      r   r   c                   P    e Zd ZdZdZdZdZdZdZdZ	dZ
i Zd Zd Zd Zd Zd	 ZdS )
OptionszA set of runtime optionsNFTc                 
   |d         t           _        |d= t          t                     }|                    |          }|r.t                              |           |                                  |                                  dS )r  r   N)r   locationr   r  r   r   usageprocessoptions)r   r  parserresults       r   r  zOptions.parseoptionsn  st    7G"7++$$T** 	KKJJLLLr   c                 6   t           j        r|                                  t           j        r|                                  t          t                    D ]C}|                    d          r,t          t          |t          | |dd                              DdS )zProcess all options parsed.modeN)
r   helpr#  versionshowversiondirr   r  r  r  )r   params     r   r$  zOptions.processoptionsy  s    < 	JJLLL? 	ZZ 	A 	AE~~f%% AugdE#2#J&?&?@@@	A 	Ar   c                     t                               dt          j        t          j                  j         d           t                               d           |                                  dS )zShow correct usagezUsage: z [options] "input string"z.Convert input string with LaTeX math to MathMLN)r   r   pathlibPathr   r"  parentshowoptionsr   s    r   r#  zOptions.usage  si     0gl7+;<<C 0 0 0 	1 	1 	1DEEEr   c                 0   t                               d           t                               d           t                               d           t                               d           t                               d           t          j                     dS )zShow all possible optionsz1    --help:                 show this online helpz9    --quiet:                disables all runtime messageszF    --debug:                enable debugging messages (for developers)z@    --version:              show version number and release datezD    --simplemath:           do not generate fancy math constructionsN)r   r   r
   exitr4  s    r   r3  zOptions.showoptions  sp    GHHHOPPP\]]]VWWWZ[[[




r   c                 p    t                               dt          z              t          j                     dS )z(Return the current eLyXer version stringz
math2html N)r   r   __version__r
   r6  r4  s    r   r,  zOptions.showversion  s(    L,---




r   )r   r   r   r   r"  r   quietr+  r*  
simplemath	showlinesbranchesr  r$  r#  r3  r,  r!   r   r   r   r   `  s        HEEGDJIH	 	 		A 	A 	A        r   r   c                   J    e Zd ZdZd Zd Z ee          Z ee          ZdS )Clonerz&An object used to clone other objects.c                 8    	 |                      |j                  S )z"Return an exact copy of an object.)create	__class__)r   originals     r   clonezCloner.clone  s    =zz(,---r   c                 X    |                     |          }|                                 |S )z"Create an object of a given class.)__new__r   )r   typerC  s      r   r@  zCloner.create  s(    T""r   N)r   r   r   r   rC  r@  r    r!   r   r   r>  r>    sR        ,,. . .
   KE[  FFFr   r>  c                   *    e Zd ZdZd Zd Zd Zd ZdS )ContainerExtractora  A class to extract certain containers.

    The config parameter is a map containing three lists:
    allowed, copied and extracted.
    Each of the three is a list of class names for containers.
    Allowed containers are included as is into the result.
    Cloned containers are cloned and placed into the result.
    Extracted containers are looked into.
    All other containers are silently ignored.
    c                 :    |d         | _         |d         | _        d S )Nr7   r8   r6   )r   configs     r   r   zContainerExtractor.__init__  s    i(,r   c                 \     g  fd} fd} fd}|                     |||           S )z8Extract a group of selected containers from a container.c                 *    | j         j        j        v S r   )rA  r   r7   r   r   s    r   <lambda>z,ContainerExtractor.extract.<locals>.<lambda>  s    1;/4<? r   c                 *    | j         j        j        v S r   )rA  r   r8   rM  s    r   rN  z,ContainerExtractor.extract.<locals>.<lambda>  s    ak2dnD r   c                 0                         |           S r   )process)r   r  r   s    r   rN  z,ContainerExtractor.extract.<locals>.<lambda>  s    DLLD11 r   )recursivesearch)r   	containerlocate	recursiverQ  r  s   `    @r   extractzContainerExtractor.extract  sS    ????DDDD	11111!!&)W===r   c                     |j         j        }|| j        v r|                    |           dS t                              d|z              dS )zAdd allowed containers.zUnknown container class N)rA  r   r7   r  r   r   )r   rS  r  names       r   rQ  zContainerExtractor.process  sP    "+4<KK	"""""KK2T9:::::r   c                     t                               |          }|j        |_        |                     |          |_        |S )zFReturn a new container with contents only in a safe list, recursively.)r>  rC  outputrV  contents)r   rS  rC  s      r   	safeclonezContainerExtractor.safeclone  s5    Y'' 'i00r   N)r   r   r   r   r   rV  rQ  r\  r!   r   r   rH  rH    sZ        	 	- - -  ; ; ;    r   rH  c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	ParserzA generic parserc                 "    d| _         i | _        d S )Nr   )rS   
parametersr4  s    r   r   zParser.__init__  s    
r   c                     |                                                                 }|                                 |j        | _        |S )zParse the header)currentliner  nextline
linenumberrS   )r   readerheaders      r   parseheaderzParser.parseheader  s>    ##%%++--&
r   c                    |                                                                                     dd          }|                                 t	          |          dk    rdS |d         }t	          |          dk    rd| j        |<   dS d|d         vr$|d                                         | j        |<   dS |d                             d          }|d         | j        |<   dS )zParse a parameterrc   r  r   NTr   )rb  stripr  rc  r  r`  )r   re  r  r   doublesplits        r   parseparameterzParser.parseparameter  s    ""$$**,,223::u::??FAhu::??#'DOC FeAh#(8>>#3#3DOC FAhnnS))*1~r   c                 4   | j         s,t                              dt          |           z              dS |                                                    | j                   s8 |             |                                                    | j                   6dS dS )z'Parse until the current ending is foundzNo ending for N)endingr   r   strrb  r  )r   re  rQ  s      r   parseendingzParser.parseending  s    { 	KK(3t994555F$$&&11$+>> 	GIII $$&&11$+>> 	 	 	 	 	r   c                     | j                             |          }|r#| j        |_        |                    |           d S d S r   )factorycreatecontainerr2  r  )r   re  r[  rS  s       r   parsecontainerzParser.parsecontainer  sK    L0088	 	'#{IOOI&&&&&	' 	'r   c                 P    | j         j        dz   t          | j                  z   dz   S )zReturn a description (r[   )rA  r   rn  rS   r4  s    r   __str__zParser.__str__  s$    ~&-DJ?#EEr   N)
r   r   r   r   r   rg  rk  ro  rs  rv  r!   r   r   r^  r^    sy            . . .   ' ' 'F F F F Fr   r^  c                       e Zd ZdZd ZdS )LoneCommandz"A parser for just one command linec                     g S )zRead nothingr!   r   re  s     r   parsezLoneCommand.parse	      	r   Nr   r   r   r   r{  r!   r   r   rx  rx    s)        ((    r   rx  c                   (    e Zd ZdZg Zd Zd Zd ZdS )
TextParserz(A parser for a command and a bit of textc                     t                               |            d | _        |j        j        t
          j        v r!t
          j        |j        j                 | _        g | _        d S r   )r^  r   rm  rA  r   r#   r   r   rS  s     r   r   zTextParser.__init__  sO    '?+BBB)1)2E2NODKr   c                 J   t           j                            | j                   t           j        t          j        d         t          j        d         | j        gz   | _        g }|                     |          s+|                     ||           |                     |          +|S )z$Parse lines as long as they are textLayoutInset)r  stackr  rm  r#   r   isendingrs  r   re  r[  s      r   r{  zTextParser.parse  s    ,,,!'?+B8+L+:+B7+K+/;+8 8 --'' 	2111 --'' 	2r   c                 *   |                                                                 }t          |          dk    rdS |d         | j        v rH|d         t          j        v r&t          j                            |d                    ng t          _        dS dS )zCheck if text is endingr   FT)rb  r  r  r   r  r  remove)r   re  r  s      r   r  zTextParser.isending%  s    $$&&,,..w<<151:%%qzZ--- ''
3333#%
 4ur   N)r   r   r   r   r  r   r{  r  r!   r   r   r  r    sL        ..E  	 	 	    r   r  c                       e Zd ZdZd ZdS )ExcludingParserz%A parser that excludes the final linec                 F     g                        fd           S )z5Parse everything up to (and excluding) the final linec                  0                                    S r   )rs  )r[  re  r   s   r   rN  z'ExcludingParser.parse.<locals>.<lambda>9  s    )<)<VX)N)N r   )ro  r  s   ``@r   r{  zExcludingParser.parse6  s5    !N!N!N!N!N!NOOOr   Nr}  r!   r   r   r  r  3  s)        ++    r   r  c                       e Zd ZdZd ZdS )BoundedParserzA parser bound by a final linec                 d    t                               | |          }|                                 |S )z*Parse everything, including the final line)r  r{  rc  r  s      r   r{  zBoundedParser.parse@  s,    "((v66r   Nr}  r!   r   r   r  r  =  s)        $$    r   r  c                       e Zd ZdZd ZdS )BoundedDummyz&A bound parser that ignores everythingc                 b    |                      fd                                            g S )z#Parse the contents of the containerc                  ,                                      S r   )rc  )re  s   r   rN  z$BoundedDummy.parse.<locals>.<lambda>M  s    ):): r   )ro  rc  rz  s    `r   r{  zBoundedDummy.parseK  s8    !:!:!:!:;;;	r   Nr}  r!   r   r   r  r  H  s)        ,,    r   r  c                       e Zd ZdZd Zd ZdS )StringParserzParses just a stringc                 $    |j         dz   | _        g S )zDo nothing, just take noter  )rd  rS   rz  s     r   rg  zStringParser.parseheaderV  s    &*
	r   c                 V    |                                 }|                                 |S )zParse a single line)rb  rc  r  s      r   r{  zStringParser.parse[  s(    %%''r   N)r   r   r   r   rg  r{  r!   r   r   r  r  S  s8          
    r   r  c                       e Zd ZdZd Zd ZdS )ContainerOutputz(The generic HTML output for a container.c                 Z    t                               dt          |           z              dS )zShow an error.zgethtml() not implemented for Nr   r   rn  r  s     r   gethtmlzContainerOutput.gethtmle  s&    4s4yy@AAAAAr   c                     dS )z5Decide if the output is empty: by default, not empty.Fr!   r4  s    r   isemptyzContainerOutput.isemptyi  s    ur   N)r   r   r   r   r  r  r!   r   r   r  r  b  s;        ..B B B    r   r  c                       e Zd Zd Zd ZdS )EmptyOutputc                     g S )zReturn empty HTML code.r!   r  s     r   r  zEmptyOutput.gethtmlp  r|  r   c                     dS )z"This output is particularly empty.Tr!   r4  s    r   r  zEmptyOutput.isemptyt  s    tr   N)r   r   r   r  r  r!   r   r   r  r  n  s2              r   r  c                       e Zd ZdZd ZdS )FixedOutputzFixed outputc                     |j         S )zReturn constant HTML code)htmlr  s     r   r  zFixedOutput.gethtml|  s
    ~r   Nr   r   r   r   r  r!   r   r   r  r  y  s(        N    r   r  c                       e Zd ZdZd ZdS )ContentsOutputz&Outputs the contents converted to HTMLc                     g }|j         |S |j         D ]g}t          |d          s>t                              d|j        j        z   dz   t          |          z              |c S ||                                z  }h|S )Return the HTML codeNr  zNo html in rd   )r[  r  r   r   rA  r   rn  r  )r   rS  r  elements       r   r  zContentsOutput.gethtml  s    %K ) 	& 	&G7I.. MG,=,FFMPST[P\P\\]]]GOO%%%DDr   Nr  r!   r   r   r  r    s)        ,,
 
 
 
 
r   r  c                   J    e Zd ZdZdZdZdZddZd Zd Z	d Z
d Zd	 Zd
 ZdS )TaggedOutputz-Outputs an HTML tag surrounding the contents.NFc                 8    || _         |r|| _        |r|| _        | S )z/Set the value for the tag and other attributes.)tag
breaklinesempty)r   r  r  r  s       r   settagzTaggedOutput.settag  s,     	)(DO 	DJr   c                     || _         | S )zSet the value for breaklines.)r  )r   r  s     r   setbreaklineszTaggedOutput.setbreaklines  s    $r   c                     | j         r|                     |          gS |                     |          g}|t                              | |          z  }|                    |                     |                     |S )zReturn the HTML code.)r  selfclosingopenr  r  r  close)r   rS  r  s      r   r  zTaggedOutput.gethtml  st    : 	1$$Y//00		)$$%&&tY777DJJy))***r   c                 f    |                      |          sdS d| j        z   dz   }| j        r|dz   S |S )zGet opening line.r<   rA   rB   r   checktagr  r  )r   rS  r  s      r   r  zTaggedOutput.open  sD    }}Y'' 	2TX~#? 	$;r   c                     |                      |          sdS d| j                                        d         z   dz   }| j        rd|z   dz   S |S )zGet closing line.r<   z</r   rB   r   )r  r  r  r  )r   rS  r  s      r   r  zTaggedOutput.close  sY    }}Y'' 	2tx~~''**S0? 	'%<$&&r   c                 f    |                      |          sdS d| j        z   dz   }| j        r|dz   S |S )zGet self-closing line.r<   rA   z/>r   r  )r   rS  r  s      r   r  zTaggedOutput.selfclosing  sF    }}Y'' 	2DHnt+? 	&%%r   c                     | j         s,t                              dt          |          z              dS | j         dk    rdS dS )zCheck that the tag is valid.z
No tag in Fr<   T)r  r   r   rn  r  s     r   r  zTaggedOutput.checktag  sC    x 	KKs9~~566658r>>5tr   )FF)r   r   r   r   r  r  r  r  r  r  r  r  r  r  r!   r   r   r  r    s        33
CJE     
            r   r  c                   ,    e Zd ZdZ	 d Zd Zd Zd ZdS )FilteredOutputz1Returns the output in the contents, but filtered:c                     g | _         dS )zInitialize the filters.N)filtersr4  s    r   r   zFilteredOutput.__init__  s    r   c                 >    | j                             ||f           dS )z:Add a new filter: replace the original by the replacement.N)r  r  )r   rB  replacements      r   	addfilterzFilteredOutput.addfilter  s#    X{344444r   c                     g }t                               | |          }|D ]*}|                    |                     |                     +|S )r  )r  r  r  filter)r   rS  r&  r  lines        r   r  zFilteredOutput.gethtml  sQ    %%dI66 	- 	-DMM$++d++,,,,r   c                 T    | j         D ]\  }}||v r|                    ||          } |S )z0Filter a single line with all available filters.)r  r  )r   r  rB  r  s       r   r  zFilteredOutput.filter  s<    %)\ 	; 	;!Hk4||Hk::r   N)r   r   r   r   r   r  r  r  r!   r   r   r  r    sY        77*  5 5 5      r   r  c                       e Zd ZdZd ZdS )StringOutputzReturns a bare string as outputc                     |j         gS )zReturn a bare stringstringr  s     r   r  zStringOutput.gethtml  s     !!r   Nr  r!   r   r   r  r    s)        %%" " " " "r   r  c                       e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZddZd ZdS )GlobablezA bit of text which can be globbed (lumped together in bits).
    Methods current(), skipcurrent(), checkfor() and isout() have to be
    implemented by subclasses.Fc                 ,    t                      | _        d S r   )
EndingList
endinglistr4  s    r   r   zGlobable.__init__  s    $,,r   c                     |                                  rdS t          |                                           dk    r|                                  dS dS )z*Check for a Unicode byte mark and skip it.Ni  )finishedordr  skipcurrentr4  s    r   checkbytemarkzGlobable.checkbytemark  sR    ==?? 	Ft||~~&(( )(r   c                 :    t                               d           dS )z+Find out if we are out of the position yet.zUnimplemented isout()Tr   r   r4  s    r   isoutzGlobable.isout	  s    +,,,tr   c                 :    t                               d           dS )zReturn the current character.zUnimplemented current()r<   r  r4  s    r   r  zGlobable.current  s    -...rr   c                 :    t                               d           dS )z3Check for the given string in the current position.zUnimplemented checkfor()Fr  r   r  s     r   checkforzGlobable.checkfor  s    .///ur   c                     |                                  r"| j        s| j                                         dS | j                            |           S )z*Find out if the current text has finished.T)r  leavependingr  checkpendingcheckinr4  s    r   r  zGlobable.finished  sL    ::<< 	$ /,,...4&&t,,,r   c                 :    t                               d           dS ))Return the current character and skip it.zUnimplemented skipcurrent()r<   r  r4  s    r   r  zGlobable.skipcurrent   s    1222rr   c                     d}|                                  s? |            r5||                                 z  }|                                  s
 |            5|S )z>Glob a bit of text that satisfies a check on the current char.r<   )r  r  )r   currentcheckglobs      r   r  zGlobable.glob%  s^    --// 	'llnn 	'D$$&&&D --// 	'llnn 	'r   c                 4                            fd          S )zGlob a bit of alpha textc                  P                                                                      S r   r  isalphar4  s   r   rN  z$Globable.globalpha.<locals>.<lambda>.      !7!7!9!9 r   r  r4  s   `r   	globalphazGlobable.globalpha,      yy9999:::r   c                 4                            fd          S )zGlob a row of digits.c                  P                                                                      S r   r  isdigitr4  s   r   rN  z%Globable.globnumber.<locals>.<lambda>2  r  r   r  r4  s   `r   
globnumberzGlobable.globnumber0  r  r   c                     |                                                                  s|                                  dk    rdS dS )z5Return if the current character is alphanumeric or _.r   TF)r  isalnumr4  s    r   isidentifierzGlobable.isidentifier4  s:    <<>>!!## 	t||~~'<'<4ur   c                 6    |                      | j                  S )z Glob alphanumeric and _ symbols.)r  r  r4  s    r   globidentifierzGlobable.globidentifier:  s    yy*+++r   c                     	 |                                                                  rdS |                                  dv rdS dS )z5Return if the current character is a value character:Fz{}()Tr  isspacer4  s    r   isvaluezGlobable.isvalue>  sC    #<<>>!!## 	5<<>>V##5tr   c                 6    |                      | j                  S )z'Glob a value: any symbols but brackets.)r  r   r4  s    r   	globvaluezGlobable.globvalueG  s    yy&&&r   c                 4                            fd          S )z(Skip all whitespace at current position.c                  P                                                                      S r   r  r4  s   r   rN  z$Globable.skipspace.<locals>.<lambda>M  r  r   r  r4  s   `r   	skipspacezGlobable.skipspaceK  r  r   c                 l                            fd          z   }                                |S )z4Glob a bit of text up to (including) the magic char.c                  4                                      k    S r   r  )	magiccharr   s   r   rN  z(Globable.globincluding.<locals>.<lambda>Q  s    9!< r   )r  skip)r   r	  r  s   `` r   globincludingzGlobable.globincludingO  s>    yy<<<<<==	I		)r   c                 8                            fd          S )z?Glob a bit of text up until (excluding) any excluded character.c                  0                                      vS r   r  )excludedr   s   r   rN  z(Globable.globexcluding.<locals>.<lambda>W  s    x!? r   r  )r   r  s   ``r   globexcludingzGlobable.globexcludingU  s#    yy?????@@@r   c                 <    | j                             ||           dS )zPush a new ending to the bottomN)r  addr   rm  optionals      r   
pushendingzGlobable.pushendingY  s     FH-----r   Nc                     |                                  r	| j        r|S | j                            |           }|r)||k    r#t                              d|z   dz   |z              |                     |           |S )z,Pop the ending found at the current positionzExpected ending z, got )r  r  r  popr   r   r
  )r   expectedrm  s      r   	popendingzGlobable.popending]  s    ::<< 	D- 	O$$T** 	KF**KK*X5@6IJJJ		&r   c                 L    | j                             |           }|sdS |j        S )z$Return the next ending in the queue.N)r  
findendingrm  )r   
nextendings     r   r  zGlobable.nextendingg  s-    _//55
 	4  r   Fr   )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    s^       " " L' ' '    
  
  
- - -  
  ; ; ;; ; ;  , , ,  ' ' '; ; ;  A A A. . . .   ! ! ! ! !r   r  c                   D    e Zd ZdZd ZddZd Zd Zd Zd Z	d	 Z
d
 ZdS )r  zA list of position endingsc                     g | _         d S r   )r   r4  s    r   r   zEndingList.__init__r  s    r   Fc                 V    | j                             t          ||                     dS )zAdd a new ending to the listN)r   r  PositionEndingr  s      r   r  zEndingList.addu  s(    N68<<=====r   c                 :    | xj         |j        j         z  c_         dS )z/Pick any pending endings from a parse position.N)r   r  r   poss     r   pickpendingzEndingList.pickpendingy  s    ..r   c                 4    |                      |          rdS dS )zSearch for an endingTF)r  r"  s     r   r  zEndingList.checkin}  s     ??3 	4ur   c                    |                                 rt                              d           dS |                     |          }|s1t                              d|                                z              dS t          | j                  D ]O}| j                            |           ||k    r	|j        c S |j	        st                              d|z              Pt                              d           dS )z)Remove the ending at the current positionzNo ending out of boundsr<   zNo ending at zRemoved non-optional ending zNo endings left)
r  r   r   r  r  reversedr   r  rm  r  )r   r#  rm  eachs       r   r  zEndingList.pop  s    99;; 	KK12222%% 	KK#++--78882T\** 	C 	CDL%%%v~~{"""] C:TABBB%&&&rr   c                     t          | j                  dk    rdS t          t          | j                            D ](\  }}|                    |          r|c S |j        s dS )dS )z'Find the ending at the current positionr   N)r  r   	enumerater'  r  r  )r   r#  indexrm  s       r   r  zEndingList.findending  sy    t|!!4&x'='=>> 	 	ME6~~c"" ? tttr   c                     t          | j                  dk    r/t                              dt	          |           z   dz              dS dS )z&Check if there are any pending endingsr   zPending z
 left openN)r  r   r   r   rn  r4  s    r   r  zEndingList.checkpending  sG    t|!!KK
SYY.=>>>>> "!r   c                     d}| j         D ]}|t          |          dz   z  }t          | j                   dk    r
|dd         }|dz   S )Printable representationz	endings [r   r   Nr  r]   )r   rn  r  )r   r  rm  s      r   rv  zEndingList.__str__  s[    l 	( 	(Fc&kkC''FFt|q  CRC[F|r   Nr  )r   r   r   r   r   r  r$  r  r  r  r  rv  r!   r   r   r  r  o  s            > > > >/ / /    $	 	 	? ? ?
    r   r  c                   $    e Zd ZdZd Zd Zd ZdS )r   z An ending for a parsing positionc                 "    || _         || _        d S r   rm  r  r  s      r   r   zPositionEnding.__init__  s     r   c                 6    |                     | j                  S )zCheck for the ending)r  rm  r"  s     r   r  zPositionEnding.checkin  s    ||DK(((r   c                 2    d| j         z   }| j        r|dz  }|S )r.  zEnding z (optional)r1  r  s     r   rv  zPositionEnding.__str__  s'    T[(= 	$m#Fr   N)r   r   r   r   r   r  rv  r!   r   r   r   r     sG        &&! ! !) ) )    r   r   c                   N    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd ZdS )PositionzA position in a text to parse.
    Including those in Globable, functions to implement by subclasses are:
    skip(), identifier(), extract(), isout() and current().c                 :    t                               |            d S r   )r  r   r4  s    r   r   zPosition.__init__  s    $r   c                 :    t                               d           dS )zSkip a stringzUnimplemented skip()Nr  r  s     r   r
  zPosition.skip  s    *+++++r   c                 :    t                               d           dS )z.Return an identifier for the current position.zUnimplemented identifier()Errorr  r4  s    r   
identifierzPosition.identifier  s    0111wr   c                 <    	 t                               d           dS )zHExtract the next string of the given length, or None if not enough text,zUnimplemented extract()Nr  r   lengths     r   rV  zPosition.extract  s    /-...tr   c                 N    ||                      t          |                    k    S )z)Check for a string at the given position.)rV  r  r  s     r   r  zPosition.checkfor  s    c&kk2222r   c                     |                      t          |                    }|sdS |                                |                      t          |                                                    k    S )z!Check for a string in lower case.F)rV  r  lower)r   r  r8   s      r   checkforlowerzPosition.checkforlower  sW    LLV--	 	5||~~c&kk!:!:!@!@!B!BBBr   c                 X    |                                  }|                     |           |S )r  )r  r
  r   r  s     r   r  zPosition.skipcurrent  s&    ,,..		'r   c                 R    |                                   |                                 S )z3Advance the position and return the next character.)r  r  r4  s    r   __next__zPosition.__next__  s"    ||~~r   c                 ^    |                      |          sdS |                     |           dS )z;Check for a string at the given position; if there, skip itFT)r  r
  r  s     r   	checkskipzPosition.checkskip  s2    }}V$$ 	5		&tr   c                 j    t                               |dz   |                                 z              dS )z2Show an error message and the position identifier.rd   N)r   r   r:  )r   r   s     r   r   zPosition.error  s-    GdNT__%6%6677777r   N)r   r   r   r   r   r
  r:  rV  r  rA  r  rE  rG  r   r!   r   r   r5  r5    s        ? ?     , , ,  
  3 3 3C C C    
  8 8 8 8 8r   r5  c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	TextPositionz%A parse position based on a raw text.c                 ~    t                               |            d| _        || _        |                                  dS )z#Create the position from some text.r   N)r5  r   r#  textr  r   rL  s     r   r   zTextPosition.__init__  s<    $	r   c                 @    | xj         t          |          z  c_         dS )zSkip a string of characters.N)r#  r  r  s     r   r
  zTextPosition.skip  s    CKKr   c                     d}| j         |z   t          | j                  k    rt          | j                  | j         z
  }d| j        | j         | j         |z            z   dz   S )z&Return a sample of the remaining text.   r   r#  r  rL  r<  s     r   r:  zTextPosition.identifier	  sZ    8fs49~~--^^dh.FTYtx6(99::S@@r   c                 <    | j         t          | j                  k    S )z'Find out if we are out of the text yet.rQ  r4  s    r   r  zTextPosition.isout  s    x3ty>>))r   c                 &    | j         | j                 S )z6Return the current character, assuming we are not out.)rL  r#  r4  s    r   r  zTextPosition.current  s    y""r   c                 ~    | j         |z   t          | j                  k    rdS | j        | j         | j         |z            S )zHExtract the next string of the given length, or None if not enough text.NrQ  r<  s     r   rV  zTextPosition.extract  s<    8fs49~~--4yDHv$5566r   N)
r   r   r   r   r   r
  r:  r  r  rV  r!   r   r   rJ  rJ    sw        ++       A A A* * *# # #7 7 7 7 7r   rJ  c                       e Zd ZdZdZdZdZd Zd Zd Z	e
j        fdZd Zd Zd	 Zd
 Zd Zd Zd Zd Zd ZddZd Zd Zd Zd ZdS )	Containerz.A container for text and objects in a lyx fileNc                 ,    t                      | _        d S r   )r  r[  r4  s    r   r   zContainer.__init__&  s    r   c                     dS )zProcess contentsNr!   r4  s    r   rQ  zContainer.process)  s    r   c                     | j                             |           }t          |t                    r t                              d|z              |g}|S )zGet the resulting HTMLzRaw string )rZ  r  r  rn  r   r   )r   r  s     r   r  zContainer.gethtml-  sL    {""4((dC   	KK,---6Dr   c                     t          |                                          }|D ]"}||v r|                    |||                   }#|S )z*Escape a line with replacements from a map)sortedkeysr  )r   r  replacementspiecespieces        r   escapezContainer.escape5  sS    ))++,, 	@ 	@E}}||E<+>??r   c                     d}t          |          }|                                st          |                                          dk    rtt	          t          |                                                    }|dk    r,t	          t          t          |                    dz             }|d|dd         z   dz   z  }n||                                z  }|                                 |                                |S )	z/Escape all Unicode characters to HTML entities.r<      0xd835i   z&#r  Nr   )rJ  r  r  r  hexnextr  )r   r  r&  r#  	codepoints        r   escapeentitieszContainer.escapeentities>  s    4  ,,.. 	3;;==!!C''CKKMM 2 233	(( #CS		NNV$; < <I$122.44#++--'OO ,,.. 	 r   c                 >    g |                      |fd           S )z2Search for all embedded containers of a given typec                 .                         |           S r   )r  )rS  r  s    r   rN  z%Container.searchall.<locals>.<lambda>P  s    4;;y3I3I r   )searchprocess)r   rF  r  s     @r   	searchallzContainer.searchallM  s-    4!I!I!I!IJJJr   c                 x    |                      |          }|D ]!}|j        j                            |           "|S )z3Search for all containers of a type and remove them)rk  r2  r[  r  )r   rF  r  rS  s       r   searchremovezContainer.searchremoveS  sD    ~~d## 	8 	8I%,,Y7777r   c                 :    |                      fd|           dS )z4Search for elements of a given type and process themc                 $    t          |           S r   )r  )rS  rF  s    r   rN  z)Container.searchprocess.<locals>.<lambda>\  s    Z	4-H-H r   N)locateprocess)r   rF  rQ  s    ` r   rj  zContainer.searchprocessZ  s)    HHHH'RRRRRr   c                 r    | j         D ].}|                    ||            ||          r ||           /dS )z3Search for all embedded containers and process themN)r[  rp  )r   rT  rQ  rS  s       r   rp  zContainer.locateprocess^  sV     	# 	#I##FG444vi   #	"""	# 	#r   c                     | j         D ]:} ||          r|                    |||            ||          r ||           ;dS )z,Perform a recursive search in the container.N)r[  rR  )r   rT  rU  rQ  rS  s        r   rR  zContainer.recursivesearche  sk     	# 	#Iy## F))&)WEEEvi   #	"""		# 	#r   c                     t          t          j                                      |           }d                    d |D                       S )z)Extract all text from allowed containers.r<   c              3   $   K   | ]}|j         V  d S r   r  )r   constants     r   r   z(Container.extracttext.<locals>.<genexpr>p  s$      AA8xAAAAAAr   )rH  r#   r9   rV  join)r   	constantss     r   r9   zContainer.extracttextm  sA    &'BCCKKDQQ	wwAAyAAAAAAr   c                    |t          | j                  k    rdS t          | j        |         d          rdS |t          | j                  k     r || j        |                   rd| j        |         _        |j                            | j        |                    | j                            |           |t          | j                  k     r || j        |                   | j                            ||           dS )z*Group some adjoining elements into a groupNgroupedT)r  r[  r  ry  r  r  r  )r   r+  group	isingroups       r   rz  zContainer.groupr  s    C&&&&F4='33 	Fc$-((((YYt}U7K-L-L(+/DM% (N!!$-"6777Me$$$ c$-((((YYt}U7K-L-L( 	UE*****r   c                    | j         |         }| j                             |           t          |j                   dk    rL| j                             ||j                                                    t          |j                   dk    JdS dS )z)Remove a container but leave its contentsr   N)r[  r  r  r  )r   r+  rS  s      r   r  zContainer.remove~  s    M%(	%   )$%%))M  	(:(>(>(@(@AAA )$%%))))))r   r   c                     t                               d|z  t          |           z              | j        D ]}|                    |dz              dS )zShow in a treez  r  N)r   r   rn  r[  tree)r   levelrS  s      r   r~  zContainer.tree  sW    D5L3t99,--- 	& 	&INN519%%%%	& 	&r   c                 2    || j         vrdS | j         |         S )z)Get the value of a parameter, if present.N)r`  r   rX  s     r   getparameterzContainer.getparameter  s!    t&&4t$$r   c                 ^    |                      |          }|sg S |                    d          S )z7Get the value of a comma-separated parameter as a list.r   )r  r  )r   rX  	paramtexts      r   getparameterlistzContainer.getparameterlist  s4    %%d++	 	Is###r   c                 `    | j         }|r$|j                                        rdS |j         }|$dS )z&Check if the parent's output is empty.TF)r2  rZ  r  rC  s     r   hasemptyoutputzContainer.hasemptyoutput  sD    + 	%~%%'' tnG  	% ur   c                 p    | j         s| j        j        S | j        j        dz   t          | j                   z   S )zGet a descriptionr   )rS   rA  r   rn  r4  s    r   rv  zContainer.__str__  s4    z 	+>**~&,s4:>>r   )r   )r   r   r   r   partkeyr2  rS   r   rQ  r  r;   rD   r`  rg  rk  rm  rj  rp  rR  r9   rz  r  r~  r  r  r  rv  r!   r   r   rV  rV    sR       44GFE       )5(=          S S S# # ## # #B B B

+ 
+ 
+B B B& & & &% % %$ $ $  ? ? ? ? ?r   rV  c                       e Zd ZdZd ZdS )BlackBoxz)A container that does not output anythingc                 `    t                      | _        t                      | _        g | _        d S r   )rx  r%  r  rZ  r[  r4  s    r   r   zBlackBox.__init__  s#    !mm!mmr   N)r   r   r   r   r   r!   r   r   r  r    s)        //    r   r  c                   :    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
dS )	StringContainerzA container for a single stringNc                 `    t                      | _        t                      | _        d| _        d S )Nr<   )r  r%  r  rZ  r  r4  s    r   r   zStringContainer.__init__  s#    "nn"nnr   c                 d    | j         r(|                     | j                   | _        d| _         dS dS )z(Replace special chars from the contents.N)parsedreplacespecialr  r4  s    r   rQ  zStringContainer.process  s8    ; 	--dk::DKDKKK	 	r   c                 d   |                      |t          j                  }|                     |          }t          j        d         |v rft          |          dk    rS| j        rdt          | j                  z   dz   }nd}t          
                    ||                                z              |S )z%Replace all special chars from a linestartcommandr  zUnknown command at rd   zUnknown command: )r`  r;   rD   
changeliner#   r  r  rS   rn  r   r   ri  )r   r  replacedr   s       r   r  zStringContainer.replacespecial  s    ;;t\%:;;??8,,!.1X==#h--RSBSBSz ./#dj//ADH-KK(.."2"22333r   c                 B    |                      |t          j                  S r   )r`  r;   rC   )r   r  s     r   r  zStringContainer.changeline  s    {{4!3444r   c                     | j         S )zReturn all text.r  r4  s    r   r9   zStringContainer.extracttext  s
    {r   c                     d}| j         r|dt          | j                   z   z  }d}t          | j                                                  dk    rd}|dz   | j                                        dd         z   |z   dz   S )	"Return a printable representation.r  r   z...   r<   ru  Nr[   )rS   rn  r  r  ri  )r   r&  ellipsiss      r   rv  zStringContainer.__str__  s    ": 	,cC
OO++Ft{  ""##r))H}t{00223B377(BSHHr   )r   r   r   r   r  r   rQ  r  r  r9   rv  r!   r   r   r  r    s~        %%F  
    5 5 5  I I I I Ir   r  c                       e Zd ZdZd Zd ZdS )ConstantzA constant stringc                 H    g | _         || _        t                      | _        d S r   )r[  r  r  rZ  rM  s     r   r   zConstant.__init__  s    "nnr   c                     d| j         z   S )Nz
Constant: r  r4  s    r   rv  zConstant.__str__  s    dk))r   N)r   r   r   r   r   rv  r!   r   r   r  r    s8        % % %
* * * * *r   r  c                       e Zd ZdZdZdS )DocumentParametersz#Global parameters for the document.FN)r   r   r   r   displaymoder!   r   r   r  r    s        ))KKKr   r  c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	FormulaParserzParses a formulac                 2   |j         dz   | _        |                     |          }|so|                                 |                     |          }|sDt                              d|                                                                z              dgS |gS )zSee if the formula is inlinedr  zUnknown formula type in unknown)rd  rS   	parsetyperc  r   r   rb  ri  )r   re  rF  s      r   rg  zFormulaParser.parseheader  s    &*
~~f%% 	#OO>>&))D #69K9K9M9M9S9S9U9UUVVV!{"vr   c                    |                                                     t          j        d                   dk    rdS |                                                     t          j        d                   dk    rdS |                                                     t          j        d                   dk    rdS |                                                     t          j        d                   dk    rdS d	S )
z)Get the formula type from the first line.r   r   inliner   blockr   r   numberedN)rb  findrF   r   rz  s     r   r  zFormulaParser.parsetype  s    $$]%9(%CDDII8$$]%9)%DEEJJ7$$]%9,%GHHAMM7$$]%9-%HIIQNN:tr   c                    |                      |          }|                                                    | j                  s|                                                                }t          |          dk    rt                              d|z              |                                 |                                                    | j                  |                                 |S )zParse the formula until the endr   zUnparsed formula line )	parseformularb  r  rm  ri  r  r   r   rc  )r   re  formulastrippeds       r   r{  zFormulaParser.parse  s    ##F++$$&&11$+>> 	))++1133H8}}q  4x?@@@OO	 $$&&11$+>> 	
 	r   c                    t           j        d         }||                                v r`|                                                    |d          d         }||v r|                     |||          S |                     |||          S t           j        d         |                                v r7|                     |t           j        d         t           j        d                   S t           j        d         }t           j        d         }||                                v r!|                                                                                    |          r|                                                                }|                    |          d                             |          }||d         z   |z   }t           j        d         }	t           j        d         }
|	|d         z   |
z   }||                     |||          z   |z   S t          
                    d	|z   d
z   |                                z              dS t           j        d         }t           j        d         }||                                v r?||                                v r)t           j        d         }|                     |||          S t          
                    d|                                z   dz              dS )zParse the formula contentsr   r  r   r   r   r   r   r   zMissing z in r<   r   r   zFormula beginning z is unknown)rF   r   rb  r  parsesinglelinerparsemultilinerr   ri  r  r   r   )r   re  r   restr   r   r  endsplit
startpiecer   r   endpiecebegincommandbeginbracket
endbrackets                  r   r  zFormulaParser.parseformula  s   %h/V''))))%%''--fa88;D~~,,VVVDDD''???	*f.@.@.B.BBB''0DY0O(5(=i(HJ J J#*=9"),7
&,,....!!##))++44Z@@ b ,,..4466"==55a8>>zJJ(8A;6C
)1+>	(0<$x{2X=!D$8$8X$V$VVYaaaKK
Z/&86;M;M;O;OOPPP2$+I6$+I66--////LFDVDVDXDX4X4X&.y9J''jIII(6+=+=+?+??-OPPPrr   c                    |                                                                 }||vr%t                              d|z   dz   |z              dS |                    |          s%t                              d|z   dz   |z              dS |                    |          }||t          |          z   t          |                    }|                                 |S )zParse a formula in one lineLine   does not contain formula start r<   zFormula z does not end with )rb  ri  r   r   r  r+  r  rc  )r   re  startrm  r  r+  r  s          r   r  zFormulaParser.parsesingleliner;  s    !!##))++KK$)KKeSTTT2}}V$$ 	KK
T),AAFJKKK2

5!!ECJJ&F|34r   c                 <   d}|                                 }||vr7t                              d|                                z   dz   |z              dS |                    |          }||t          |          z   d                                         }|                    |          sE||dz   z  }|                                 |                                 }|                    |          E||dt          |                    z  }|                                 |S )z!Parse a formula in multiple linesr<   r  r  Nr   )rb  r   r   ri  r+  r  r  rc  )r   re  r  rm  r  r  r+  s          r   r  zFormulaParser.parsemultilinerI  s   !!##KK$**,,.1SSV[[\\\2

5!!ECJJ&''(..00--'' 	(td{"GOO%%''D --'' 	( 	4#f++&&r   N)
r   r   r   r   rg  r  r{  r  r  r  r!   r   r   r  r    su        
 
 

 
 
	 	 	! ! !F      r   r  c                   H    e Zd ZdZdZdZdZd Zd Zd Z	d Z
d	 Zd
 Zd ZdS )
FormulaBitzA bit of a formulaNr  r<   c                 :    g | _         t                      | _        dS )z6The formula bit type can be 'alpha', 'number', 'font'.N)r[  r  rZ  r4  s    r   r   zFormulaBit.__init__b  s    $&&r   c                     || _         | S )z!Set the internal formula factory.)rq  )r   rq  s     r   
setfactoryzFormulaBit.setfactoryg  s    r   c                 r    | j                             |           | xj        |j        z  c_        | |_        dS )z-Add any kind of formula bit already processedN)r[  r  rB  r2  r   bits     r   r  zFormulaBit.addl  s5    S!!!%


r   c                     | xj         |z  c_         |                    |          s7t                              d|z   dz   |                                z              dS dS )z0Skip a string and add it to the original formulazString z not at N)rB  rG  r   r   r:  )r   r  r#  s      r   skiporiginalzFormulaBit.skiporiginalr  sd    }}V$$ 	LKK	F*Z7#..:J:JJKKKKK	L 	Lr   c                     t          | j                  dk    rdS t          d | j        D                       | _        | j        S )zDCompute the size of the bit as the max of the sizes of all contents.r   r  c              3   $   K   | ]}|j         V  d S r   sizer   r  s     r   r   z)FormulaBit.computesize.<locals>.<genexpr>|  s$      BBBBBBBBr   )r  r[  r   r  r4  s    r   computesizezFormulaBit.computesizex  sD    t}""1BBDMBBBBB	yr   c                 @    | j                             | j                  S zReturn a copy of itself.)rq  r  rB  r4  s    r   rC  zFormulaBit.clone  s    |((777r   c                 0    | j         j        dz   | j        z   S )zGet a string representationz	 read in )rA  r   rB  r4  s    r   rv  zFormulaBit.__str__  s    ~&4t}DDr   )r   r   r   r   rF  r  rB  r   r  r  r  r  rC  rv  r!   r   r   r  r  [  s        DDH' ' '
  
  L L L  8 8 8E E E E Er   r  c                   &    e Zd ZdZd ZddZd ZdS )	TaggedBitzA tagged string in a formulac                     t                                          |          | _        |                     t	          |                     | S zSet the constant and the tag)r  r  rZ  r  r%   )r   ru  r  s      r   ru  zTaggedBit.constant  s:    "nn++C00**+++r   Fc                 b    || _         t                                          ||          | _        | S r  )r[  r  r  rZ  )r   r[  r  r  s       r   completezTaggedBit.complete  s)     "nn++C<<r   c                 V    t                                          |d          | _        | S )z4Set the self-closing tag, no contents (as in <hr/>).T)r  )r  r  rZ  )r   r  s     r   selfcompletezTaggedBit.selfcomplete  s%    "nn++Ct+<<r   Nr  )r   r   r   r   ru  r  r  r!   r   r   r  r    sL        ""         r   r  c                   *    e Zd ZdZd Zd Zd Zd ZdS )r%   zA constant string in a formulac                 f    t                               | |           || _        d| _        d| _        dS )zSet the constant stringr  N)r  r   rB  r  rF  r  s     r   r   zFormulaConstant.__init__  s1    $'''				r   c                     | j         S )z+Compute the size of the constant: always 1.r  r4  s    r   r  zFormulaConstant.computesize  s
    yr   c                 *    t          | j                  S r  )r%   rB  r4  s    r   rC  zFormulaConstant.clone  s    t}---r   c                     d| j         z   S )r  zFormula constant: r  r4  s    r   rv  zFormulaConstant.__str__  s    #dk11r   N)r   r   r   r   r   r  rC  rv  r!   r   r   r%   r%     sV        $$    . . .2 2 2 2 2r   r%   c                       e Zd ZdZd Zd ZdS )r1   zA bit of text inside a formulac                 N    |                                                                 S )zDetect a bit of raw textr  r"  s     r   detectzRawText.detect      {{}}$$&&&r   c                     |                                 }|                     t          |                     d| _        dS )zParse alphabetic textalphaN)r  r  r%   rF  )r   r#  r  s      r   parsebitzRawText.parsebit  s4    ''(((			r   Nr   r   r   r   r  r  r!   r   r   r1   r1     s8        $$' ' '    r   r1   c                   L    e Zd ZdZej        Zej        d         Zd Zd Zd Z	dS )r.   zA symbol inside a formular   c                     |                                 t          j        v rdS |                                 t          j        v rdS dS )zDetect a symbolTF)r  r.   r   r   r"  s     r   r  zFormulaSymbol.detect  s=    ;;==M4444;;==M2224ur   c                    |                                 t          j        v r*|                     |                                 |           dS |                                 t          j        v r:|                     t          j        |                                          |           dS t
                              d|                                 z   dz              dS )Parse the symbolNzSymbol z
 not found)r  r.   r   	addsymbolr   r   r   r"  s     r   r  zFormulaSymbol.parsebit  s    ;;==M444NN3;;==#...F;;==M222NN=1#++--@#FFFFI-<=====r   c                     |                      |                                |           | j                            t	          |                     dS )zAdd a symbolN)r  r  r[  r  r%   )r   symbolr#  s      r   r  zFormulaSymbol.addsymbol  sD    #++-----_V4455555r   N)
r   r   r   r   rF   r   r   r  r  r  r!   r   r   r.   r.     s\        %H),7J  > > >6 6 6 6 6r   r.   c                       e Zd ZdZd Zd ZdS )r-   zA string of digits in a formulac                 N    |                                                                 S )zDetect a digitr  r"  s     r   r  zFormulaNumber.detect  r  r   c                                          fd          }|                     t          |                     d| _        dS )zParse a bunch of digitsc                  P                                                                      S r   r  )r#  s   r   rN  z(FormulaNumber.parsebit.<locals>.<lambda>  s    #++--"7"7"9"9 r   numberN)r  r  r%   rF  )r   r#  digitss    ` r   r  zFormulaNumber.parsebit  sC    9999::(()))			r   Nr  r!   r   r   r-   r-     s8        %%' ' '    r   r-   c                   8    e Zd ZdZej        d         Zd Zd ZdS )Commentz*A LaTeX comment: % to the end of the line.r   c                 <    |                                 | j        k    S )zDetect the %.)r  r  r"  s     r   r  zComment.detect  s    {{}}
**r   c                 L    | xj         |                    d          z  c_         dS )zParse to the end of the line.r   N)rB  r  r"  s     r   r  zComment.parsebit  s$    **4000r   N)	r   r   r   r   rF   r   r  r  r  r!   r   r   r  r    sE        00 +E+ + +1 1 1 1 1r   r  c                   $    e Zd ZdZd Zd Zd ZdS )
WhiteSpacez"Some white space inside a formula.c                 N    |                                                                 S )zDetect the white space.r  r"  s     r   r  zWhiteSpace.detect  r  r   c                 J    | xj         |                                z  c_         dS )zParse all whitespace.N)rB  r  r"  s     r   r  zWhiteSpace.parsebit  s    (r   c                     d| j         z   dz   S )r  zWhitespace: *r   )rB  r4  s    r   rv  zWhiteSpace.__str__  s    .44r   N)r   r   r   r   r  r  rv  r!   r   r   r  r    sG        ((' ' ') ) )5 5 5 5 5r   r  c                   |    e Zd ZdZej        d         Zej        d         Zd Z	d Z
d Zd Zd Zd Zd	 Zd
 Zd ZdS )r'   zA {} bracket inside a formular   c                 H    t                               |            d| _        dS )z'Create a (possibly literal) new bracketN)r  r   innerr4  s    r   r   zBracket.__init__  s!    D!!!


r   c                 6    |                     | j                  S )zDetect the start of a bracket)r  r  r"  s     r   r  zBracket.detect  s    ||DJ'''r   c                 <    |                      || j                   | S )zParse the bracket)parsecompleteinnerformular"  s     r   r  zBracket.parsebit       3 1222r   c                 <    |                      || j                   | S )zParse a text bracket)r  	innertextr"  s     r   	parsetextzBracket.parsetext   s    3///r   c                 <    |                      || j                   | S )zParse a literal bracket)r  innerliteralr"  s     r   parseliteralzBracket.parseliteral%  r  r   c                    |                     | j                  s<t                              d| j        z   dz   |                                z              dS |                     | j        |           |                    | j                    ||           | xj        |	                    | j                  z  c_        | 
                                 dS )zParse the start and end markszBracket should start with z at N)r  r  r   r   r:  r  r  rm  rB  r  r  )r   r#  innerparsers      r   r  zBracket.parsecomplete*  s    ||DJ'' 	KK4tzAFJS^^M]M]]^^^4$*c***t{###Ct{333r   c                     |                                 sC|                     | j                            |                     |                                 AdS dS )z(Parse a whole formula inside the bracketNr  r  rq  parseanyr"  s     r   r  zBracket.innerformula5  Z    ,,.. 	1HHT\**3//000 ,,.. 	1 	1 	1 	1 	1r   c                    t          t          j                                                  }|                    t          j        d                    |                    t          j        d                    |                    t          j                   |                                s|	                                |v rS| 
                    | j                            |                     |                    d          r| xj        dz  c_        n4| 
                    t          |                                                     |                                dS dS )z<Parse some text inside the bracket, following textual rules.r   r   rc   N)r  rF   r   r\  r  r   r  r  r  r  r  rq  r  rG  rB  r%   r  )r   r#  specialcharss      r   r  zBracket.innertext:  s    M9>>@@AAM0;<<<M0;<<<GM***,,.. 	={{}},,..s33444==%% )MMS(MM):):;;<<< ,,.. 	= 	= 	= 	= 	=r   c                    d| _         |                                s|                                | j        k    s|                                | j        k    r|                     |           n"| xj         |                                z  c_         |                                s|                                | j        k    | xj        | j         z  c_        dS )zAParse a literal inside the bracket, which does not generate HTML.r<   N)literalr  r  rm  r  r  r  rB  r"  s     r   r  zBracket.innerliteralH  s    ,,.. 	2$+)E)E{{}}
**!!#&&&& 1 11	 ,,.. 	2$+)E)E
 	%r   N)r   r   r   r   rF   r   r  r   rm  r   r  r  r	  r  r  r  r  r  r!   r   r   r'   r'     s        ## +E"9-F  
( ( (  
  
  
	 	 	1 1 1
= = =& & & & &r   r'   c                   L    e Zd ZdZej        d         Zej        d         Zd Z	dS )SquareBracketzA [] bracket inside a formular   c                 :    t                      }| j        |_        |S )z3Return a new square bracket with the same contents.)r  r[  )r   r   s     r   rC  zSquareBracket.cloneY  s    //=r   N)
r   r   r   r   rF   r   r  r   rm  rC  r!   r   r   r  r  S  sC        ## 1E"?3F    r   r  c                       e Zd ZdZd Zd ZdS )MathsProcessorzAA processor for a maths construction inside the FormulaProcessor.c                 Z    t                               dt          |           z              dS )z$Process an element inside a formula.zUnimplemented process() in Nr  r   r[  r+  s      r   rQ  zMathsProcessor.processc  s&    1CII=>>>>>r   c                      d| j         j        z   S )zReturn a printable description.zMaths processor )rA  r   r4  s    r   rv  zMathsProcessor.__str__g  s    !DN$;;;r   N)r   r   r   r   rQ  rv  r!   r   r   r  r  `  s8        GG? ? ?< < < < <r   r  c                   :    e Zd ZdZg Zd Zd Zd Zd Zd Z	d Z
dS )	FormulaProcessorz&A processor specifically for formulas.c                     |                      |           |                     |           |                     |           dS )z7Process the contents of every formula bit, recursively.N)processcontentsprocessinsidestraversewholer  s     r   rQ  zFormulaProcessor.processq  sD    S!!!C   3r   c                     t          |t                    sdS |                                 |j        D ]}|                     |           dS )z&Process the contents of a formula bit.N)r  r  rQ  r[  r"  r   r  r  s      r   r"  z FormulaProcessor.processcontentsw  sX    #z** 	F| 	* 	*G  ))))	* 	*r   c                     t          |t                    sdS t          |j                  D ]?\  }}| j        D ]}|                    |j        |           |                     |           @dS )z8Process the insides (limits, brackets) in a formula bit.N)r  r  r*  r[  
processorsrQ  r#  )r   r  r+  r  	processors        r   r#  zFormulaProcessor.processinsides  s    #z** 	F'55 	) 	)NE7!_ 7 7	!!#,6666((((		) 	)r   c                    d}|                      |          D ]i\  }}|j        dk    r|                     ||           n@|j        dk    r5|r3|j        dk    r(|j                            dt          d                     |}jdS )z>Traverse over the contents to alter variables and space units.Nr  fontr  r       )traverserF  	italicizer[  r  r%   )r   r  lastr  r[  s        r   r$  zFormulaProcessor.traversewhole  s    !]]733 	 	MCx7""sH----V###h1F1F##Ax'@'@AAADD	 	r   c              #      K   |j         D ]U}t          |d          r|j        r||j         fV  %t          |t                    r|                     |          E d{V  VdS )zHTraverse a formula and yield a flattened structure of (bit, list) pairs.rF  N)r[  r  rF  r  r  r-  r&  s      r   r-  zFormulaProcessor.traverse  s      | 	2 	2Gw'' 2GL 2s|+++++GZ00 2==111111111		2 	2r   c                 |    |                     |          }t                                          |gd          ||<   dS )z Italicize the given bit of text.r   N)r+  r  r  )r   r  r[  r+  s       r   r.  zFormulaProcessor.italicize  s6    s###++..uc::r   N)r   r   r   r   r(  rQ  r"  r#  r$  r-  r.  r!   r   r   r   r   l  sy        ,,J     * * *) ) )  2 2 2; ; ; ; ;r   r   c                   T    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZdS )r,   zA LaTeX formulac                 x    t                      | _        t                                          d          | _        d S )Nzspan class="formula")r  r%  r  r  rZ  r4  s    r   r   zFormula.__init__  s+    #oo"nn++,BCCr   c                     | j         d         dk    rdt          _        n'dt          _        | j                            dd           |                                  dS )zConvert the formula to tagsr   r  FTzdiv class="formula"N)rf  r  r  rZ  r  classicr4  s    r   rQ  zFormula.process  sR    ;q>X%%-2**-1*K4d;;;r   c                     t                                          | j                  }t                                          |           | |_        |g| _        dS )zEMake the contents using classic output generation with XHTML and CSS.N)FormulaFactoryr  r  r   rQ  r2  r[  )r   wholes     r   r5  zFormula.classic  sK      --dk::""5)))r   c                    |                     d          r|                     |           n|                     d          r|                     |           nm|                     d          r|                     |d           nA|                     d          r|                     |d           n|                    d           |                                  | S )z4Parse using a parse position instead of self.parser.z$$r   z\(z\)r   r   zUnparseable formula)rG  parsedollarblockparsedollarinlineparseinlinetoparseblocktor   rQ  r"  s     r   r{  zFormula.parse  s    == 		-!!#&&&&]]3 	-""3'''']]5!! 	-sE****]]5!! 	-c5))))II+,,,r   c                 @    dg| _         |                     |           dS )zParse a $...$ formula.r  N)rf  parsedollarr"  s     r   r;  zFormula.parsedollarinline  s%    jr   c                     dg| _         |                     |           |                    d          s|                    d           dS dS )zParse a $$...$$ formula.r  r   z1Formula should be $$...$$, but last $ is missing.N)rf  r?  rG  r   r"  s     r   r:  zFormula.parsedollarblock  sY    i}}S!! 	KIIIJJJJJ	K 	Kr   c                     |                     d           |                    d          | _        |                    d           dS )zParse to the next $.r   N)r  r  r  r  r"  s     r   r?  zFormula.parsedollar  sA    s'',,cr   c                 B    dg| _         |                     ||           dS )zParse a \(...\) formula.r  Nrf  	parseuptor   r#  limits      r   r<  zFormula.parseinlineto  s%    jsE"""""r   c                 B    dg| _         |                     ||           dS )zParse a \[...\] formula.r  NrC  rE  s      r   r=  zFormula.parseblockto  s%    isE"""""r   c                     |                     |           |                    d           | _        |                    |           dS )z1Parse a formula that ends with the given command.c                      dS )NTr!   r!   r   r   rN  z#Formula.parseupto.<locals>.<lambda>  s    t r   N)r  r  r  r  rE  s      r   rD  zFormula.parseupto  sA    uhh||,,er   c                 P    | j         r| j         j        rd| j         j        z   dz   S dS )r  z	Formula (r[   zUnnumbered formula)r  r  r4  s    r   rv  zFormula.__str__  s3    < 	;DL/ 	;!44s::##r   N)r   r   r   r   r   rQ  r5  r{  r;  r:  r?  r<  r=  rD  rv  r!   r   r   r,   r,     s        D D D           
K K K  # # #
# # #
  $ $ $ $ $r   r,   c                       e Zd ZdZd Zd ZdS )WholeFormulazParse a whole formulac                 ,    |                                  S )z"Not outside the formula is enough.)r  r"  s     r   r  zWholeFormula.detect  s    <<>>!!r   c                     |                                 sC|                     | j                            |                     |                                 AdS dS )zParse with any formula bitNr  r"  s     r   r  zWholeFormula.parsebit  r  r   Nr  r!   r   r   rL  rL    s8        " " "1 1 1 1 1r   rL  c                   d    e Zd ZdZeeeeee	gZ
ee	gZdZd Zd Zd Zd Zd Zd Zd	 Zd
 Zd ZdS )r7  zConstruct bits of formulaFc                     i | _         dS )z Initialize the map of instances.N)	instancesr4  s    r   r   zFormulaFactory.__init__  s    r   c                 ~    |                                 rdS |                     |                              |          S )zDetect a bit of a given type.F)r  instancer  )r   rF  r#  s      r   
detecttypezFormulaFactory.detecttype	  s7    <<>> 	5}}T""))#...r   c                     || j         vs| j         |         s|                     |          | j         |<   | j         |         S )z"Get an instance of the given type.)rQ  r@  r   rF  s     r   rS  zFormulaFactory.instance  s@    t~%%T^D-A%#';;t#4#4DN4 ~d##r   c                 \    t                               |                              |           S )z+Create a new formula bit of the given type.)r>  r@  r  rV  s     r   r@  zFormulaFactory.create  s"    }}T""--d333r   c                     |                                 s+|                     |          sdS |                                 +dS )zClear any skipped types.N)r  skipanyr"  s     r   clearskippedzFormulaFactory.clearskipped  sD    ,,.. 	<<$$  ,,.. 	 	r   c                     | j         D ]B}|                     |                              |          r|                     ||          c S CdS )zSkip any skipped types.N)skippedtypesrS  r  r  r   r#  rF  s      r   rY  zFormulaFactory.skipany   sZ    % 	1 	1D}}T""))#.. 1~~dC000001tr   c                 "   | j         | j        z   D ]0}|                     ||          r|                     ||          c S 1t                              d|                                z              t          |                                          S )z.Parse any formula bit at the current location.zUnrecognized formula at )	typesr\  rT  r  r   r   r:  r%   r  r]  s      r   r  zFormulaFactory.parseany'  s    J!22 	1 	1DtS)) 1~~dC000001.1A1AABBBs00111r   c                     |                      |          }d| j        |<   |                    |          }|r|                    |           S |S )z#Parse the given type and return it.N)rS  rQ  r  r  )r   rF  r#  r  returnedbits        r   r  zFormulaFactory.parsetype/  sQ    mmD!!#tll3'' 	0))$///
r   c                    t          |          }|                     t                    }|                    |          r|                    |           |S |                                sdt                              d|                                z              |	                    t                                          |d                     |S )z5Parse a string of text that contains a whole formula.zUnknown formula at: span class="unknown")rJ  r@  rL  r  r  r  r   r   r:  r  r  ru  )r   r  r#  r8  s       r   r  zFormulaFactory.parseformula8  s    7##L))<< 	NN3L||~~ 	MKK.1A1AABBBIIikk**74JKKLLLr   N)r   r   r   r   r.   r1   r-   r'   r  r  r_  r\  definingr   rT  rS  r@  rZ  rY  r  r  r  r!   r   r   r7  r7    s         G]GWjQEZ(LH  / / /$ $ $4 4 4    2 2 2      r   r7  c                   ^    e Zd ZdZg Zej        d         ZdZd Z	d Z
d Zd Zd Zd	 Zd
 ZdS )FormulaCommandz A LaTeX command inside a formular   Nc                 @    |                     t          j                  S )zFind the current command.)r  rf  r  r"  s     r   r  zFormulaCommand.detectM  s    ||N0111r   c                    |                      |          }|                     ||          }|r|S |                    d          s|                    d          r|                     ||          }|r|S | j        j        st                              d|z              t                      	                    d          | _
        |                     t          |                     dS )zParse the command.\up\UpzUnknown command rc  N)extractcommandparsewithcommandr  parseupgreekrq  rd  r   r   r  r  rZ  r  r%   )r   r#  r   r  upgreeks        r   r  zFormulaCommand.parsebitQ  s    %%c**##GS11 	Jf%% 	););F)C)C 	''55G |$ 	6KK*W4555"nn++,BCC))***tr   c                 h    t           j        D ]$}||j        v r|                     |||          c S %dS )z0Parse the command type once we have the command.N)rf  r_  
commandmapparsecommandtype)r   r   r#  rF  s       r   rl  zFormulaCommand.parsewithcommanda  sK    "( 	A 	AD$/)),,WdC@@@@@ *tr   c                     | j                             |          }|                    |           |                    |          }|r|S |S )zParse a given command type.)rq  r@  
setcommandr  )r   r   rF  r#  r  returneds         r   rq  zFormulaCommand.parsecommandtypeh  sL    l!!$''w<<$$ 	O
r   c                    |                     t          j                  s$|                    dt          j        z              dS |                                r|                     |          S |                                                                r8t          j        |                                z   }|                     d           |S t          j        |	                                z   S )z.Extract the command from the current position.zMissing command start Nr   )
rG  rf  r  r   r  emptycommandr  r  r  r  )r   r#  r   s      r   rk  zFormulaCommand.extractcommandq  s    }}^122 	II.1EEFFFF<<>> 	*$$S)));;==  "" 	$*S]]__<GMM#N#coo&7&777r   c                     d}|                                 s-|                                }|r|                    |          r|}t          j        |z   S )zuCheck for an empty command: look for command disguised as ending.
        Special case against '{ \{ \} }' situation.r<   )r  r  rG  rf  r  )r   r#  r   rm  s       r   rv  zFormulaCommand.emptycommand  sV     yy{{ 	!^^%%F !#--// ! #g--r   c                 r   t          |          dk     rdS |                    d          rd|dd         z   }n_|                    d          r+d|dd                                         z   |dd         z   }nt                              d|z              dS |                     ||          }|rd|_        |S )	zParse the Greek \up command..   Nri  rR      rj  zImpossible upgreek command: r+  )r  r  rG  upperr   r   rl  rF  )r   r   r#  	upcommandrn  s        r   rm  zFormulaCommand.parseupgreek  s    w<<!4f%% 	wqrr{*II]]6"" 	wqs|11333gabbkAIIKK6@AAAF''	377 	"!GLr   )r   r   r   r   r_  rF   r   r  rp  r  r  rl  rq  rk  rv  rm  r!   r   r   rf  rf  F  s        &&E +EJ2 2 2       8 8 8 . . .    r   rf  c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	
CommandBitz%A formula bit that includes a commandc                 t    || _         | j        r)| xj        |z  c_        | j        | j                  | _        dS dS )zSet the command in the bitN)r   rp  rB  
translated)r   r   s     r   rs  zCommandBit.setcommand  sA    ? 	<MMW$MM"odl;DOOO	< 	<r   c                     | j                             |           |                                rdS | j                             |          }|                     |           |S )z)Parse a parameter at the current positionN)rq  rZ  r  r  r  )r   r#  	parameters      r   rk  zCommandBit.parseparameter  sZ    !!#&&&<<>> 	4L))#..	r   c                     | j                             |           | j                             t          |          sdS | j                             t          |          }|                     |           |S )zParse a square bracketN)rq  rZ  rT  r  r  r  r   r#  r   s      r   parsesquarezCommandBit.parsesquare  se    !!#&&&|&&}c:: 	4,((<<r   c                    | j                             |           | j                             t          |          sY|                                s1t
                              d|                                z              dS |                                S t                      	                    | j                   }| 
                    |                    |                     |j        S )zParse a literal bracket.zNo literal parameter found at: N)rq  rZ  rT  r'   r   r   r   r:  r  r  r  r  r  r  s      r   r  zCommandBit.parseliteral  s    !!#&&&|&&w44 	#;;== =@P@PPQQQt==??"))&&t|44%%c**+++r   c                 $   | j                             |           | j                             t          |          sdS t                                          | j                   }|                     |                    |                     |j        S )z!Parse a square bracket literally.N)rq  rZ  rT  r  r  r  r  r  r  s      r   parsesquareliteralzCommandBit.parsesquareliteral  sx    !!#&&&|&&}c:: 	4//,,T\::%%c**+++r   c                 ^   | j                             |           | j                             t          |          s$t                              d| j        z              dS t                                          | j                                       |          }| 	                    |           |S )zParse a text parameter.zNo text parameter for N)
rq  rZ  rT  r'   r   r   r   r  r	  r  r  s      r   r	  zCommandBit.parsetext  s    !!#&&&|&&w44 	KK04<?@@@4))&&t|44>>sCCr   N)
r   r   r   r   rs  rk  r  r  r  r	  r!   r   r   r~  r~    st        ++< < <    
 
 
      r   r~  c                   &    e Zd ZdZej        Zd ZdS )r*   z%An empty command (without parameters)c                 :    t          | j                  g| _        dS )z"Parse a command without parametersNr%   r  r[  r"  s     r   r  zEmptyCommand.parsebit  s    (99:r   N)r   r   r   r   rF   r   rp  r  r!   r   r   r*   r*     s1        ++'J; ; ; ; ;r   r*   c                   &    e Zd ZdZej        Zd ZdS )r2   z<An empty command which should have math spacing in formulas.c                 F    t          d| j        z   dz             g| _        dS )z4Place as contents the command translated and spaced.r,  Nr  r"  s     r   r  zSpacedCommand.parsebit  s&    
 )DO)Ch)NOOPr   N)r   r   r   r   rF   r   rp  r  r!   r   r   r2   r2     s6        FF-JQ Q Q Q Qr   r2   c                   *    e Zd ZdZej        ZdZd ZdS )r&   z:A command without parameters whose result is alphabetical.)z\Xiz\Thetaz\Piz\Sigmaz\Gammaz\Lambdaz\Phiz\Psiz\Deltaz\Upsilonz\Omegac                 j    t                               | |           | j        | j        vr	d| _        dS dS )z'Parse the command and set type to alphar  N)r*   r  r   greek_capitalsrF  r"  s     r   r  zAlphaCommand.parsebit  s=    dC(((<t222  DIII 32r   N)	r   r   r   r   rF   r   rp  r  r  r!   r   r   r&   r&     s8        DD,J.N         r   r&   c                   0    e Zd ZdZej        ZdZd Zd Z	dS )r/   zA function of one parameterFc                     t                                          | j                  | _        |                     |           |                                  dS )z#Parse a function with one parameterN)r  r  r  rZ  rk  simplifyifpossibler"  s     r   r  zOneParamFunction.parsebit	  sI    "nn++DO<<C   !!!!!r   c                     | j         | j        v r4t                      | _        | j        | j                  g| _        d| _        dS dS )z&Try to simplify to a single character.TN)rB  rp  r  rZ  r  
simplifiedr4  s    r   r  z#OneParamFunction.simplifyifpossible	  sB    =DO++%--DK78DI"DOOO ,+r   N)
r   r   r   r   rF   r   rp  r  r  r  r!   r   r   r/   r/    	  sE        !!+JJ" " "# # # # #r   r/   c                   ,    e Zd ZdZej        Zd Zd ZdS )r3   z>Find a function which is represented by a symbol (like _ or ^)c                 B    |                                 t          j        v S )zFind the symbol)r  r3   rp  r"  s     r   r  zSymbolFunction.detect	  s    {{}} 999r   c                    |                      |                                           |                    | j                   t	                                          | j                  | _        |                     |           dS )r  N)	rs  r  r
  r   r  r  r  rZ  rk  r"  s     r   r  zSymbolFunction.parsebit	  se    &&&"nn++DO<<C     r   N)	r   r   r   r   rF   r   rp  r  r  r!   r   r   r3   r3   	  s@        DD.J: : :! ! ! ! !r   r3   c                   ,    e Zd ZdZej        Zd Zd ZdS )r4   z-A function where parameters are read as text.c                     t                                          | j                  | _        |                     |           dS )zParse a text parameterN)r  r  r  rZ  r	  r"  s     r   r  zTextFunction.parsebit*	  s5    "nn++DO<<sr   c                     d| _         dS )zSet the type to fontr+  N)rF  r4  s    r   rQ  zTextFunction.process/	  s    			r   N)	r   r   r   r   rF   r   rp  r  rQ  r!   r   r   r4   r4   %	  s@        33,J  
    r   r4   c                   &    e Zd ZdZej        Zd ZdS )r+   z2A function of one parameter that changes the font.c                 <    d| _         |                                  dS )z.Simplify if possible using a single character.r+  N)rF  r  r4  s    r   rQ  zFontFunction.process:	  s!    	!!!!!r   N)r   r   r   r   rF   r   rp  rQ  r!   r   r   r+   r+   4	  s3        << ,J" " " " "r   r+   c                   D    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 ZdS )
BigBracketzA big bracket generator.r   c                     || _         || _        || _        d| _        |t          j        v rt          j        |         | _        dS dS )z(Set the size and symbol for the bracket.N)r  rB  	alignmentr^  rF   r   )r   r  r   r  s       r   r   zBigBracket.__init__I	  sG    	"m///'3G<DKKK 0/r   c           	      |    t          | dt          t          | j                            z             } ||          S )z%Return the nth piece for the bracket.getpiece)r  rn  r  r^  )r   r+  functions      r   r  zBigBracket.getpieceR	  s6    4c#dk2B2B.C.C!CDDxr   c                     | j         d         S )z1Return the only piece for a single-piece bracket.r   )r^  r   r+  s     r   	getpiece1zBigBracket.getpiece1W	  s    {1~r   c                 x    |dk    r| j         d         S || j        dz
  k    r| j         d         S | j         d         S )zGGet the nth piece for a 3-piece bracket: parenthesis or square bracket.r   r  r  r^  r  r  s     r   	getpiece3zBigBracket.getpiece3[	  s@    A::;q>!DIM!!;r?"{1~r   c                     |dk    r| j         d         S || j        dz
  k    r| j         d         S || j        dz
  dz  k    r| j         d         S | j         d         S )z7Get the nth piece for a 4-piece bracket: curly bracket.r   r  rz  r
  r  r  s     r   	getpiece4zBigBracket.getpiece4c	  sb    A::;q>!DIM!!;q>!TY]A%%%;q>!{1~r   c                     |                      |          }d| j        z   dz   }t                                          ||          S )z'Get the bracket piece as an array cell.zspan class="bracket align-r   )r  r  r  ru  )r   r+  r_  spans       r   getcellzBigBracket.getcellm	  s>    e$$+dn<sB{{##E4000r   c                 \   | j         dk    s| j        s|                                 S g }t          | j                   D ]M}|                     |          }|                    t                                          |gd                     Nt                                          |d          gS )z3Get the bracket as an array or as a single bracket.r  span class="arrayrow"span class="array")r  r^  getsinglebracketranger  r  r  r  )r   rowsr+  cells       r   getcontentszBigBracket.getcontentss	  s    9>>>((***49%% 	O 	OE<<&&DKK	,,dV5LMMNNNN$$T+?@@AAr   c                     | j         dk    r#t                                          dd          gS t                                          | j         d          gS )z$Return the bracket as a single sign.r   r<   zspan class="emptydot"r`   )rB  r  ru  r4  s    r   r  zBigBracket.getsinglebracket}	  sM    =CKK((-DEEFF$$T]4KLLMMr   N)r   )r   r   r   r   r   r  r  r  r  r  r  r  r!   r   r   r  r  F	  s        = = = =  
      1 1 1B B BN N N N Nr   r  c                       e Zd ZdZdZd ZdS )FormulaEquationzA simple numbered equation.equationc                     t                      | _        |                     | j                            t
          |                     dS )Parse the arrayN)r  rZ  r  rq  r  rL  r"  s     r   r  zFormulaEquation.parsebit	  s9    $&&''c::;;;;;r   Nr   r   r   r   r_  r  r!   r   r   r  r  	  s.        !!E< < < < <r   r  c                       e Zd ZdZd Zd ZdS )FormulaCellzAn array cell inside a rowc                 n    || _         t                                          d|z   dz   d          | _        | S )Nzspan class="arraycell align-r   T)r  r  r  rZ  )r   r  s     r   setalignmentzFormulaCell.setalignment	  sA    ""nn++,J.7-8:=->?CE Er   c                     | j                             |           |                                rd S |                     | j                             t
          |                     d S r   )rq  rZ  r  r  r  rL  r"  s     r   r  zFormulaCell.parsebit	  sW    !!#&&&<<>> 	F''c::;;;;;r   N)r   r   r   r   r  r  r!   r   r   r  r  	  s8            < < < < <r   r  c                   >    e Zd ZdZej        d         Zd Zd Zd Z	dS )
FormulaRowzAn array row inside an arrayrT   c                 b    || _         t                                          dd          | _        | S )Nr  T)
alignmentsr  r  rZ  )r   r  s     r   setalignmentszFormulaRow.setalignments	  s*    $"nn++,CTJJr   c                    d}|                     | j        d           |                                sr|                     |          }|                    |           |                     |           |dz  }|                    | j                   |                                rt          | j                  dk    rt                      | _
        dS dS )zParse a whole rowr   T)r  r  N)r  rT   r  
createcellr  r  rG  r  r[  r  rZ  )r   r#  r+  r  s       r   r  zFormulaRow.parsebit	  s    t)D999,,.. 	.??5))DMM#HHTNNNQJEMM$,--- ,,.. 	. t}""%--DKKK #"r   c                     | j         |t          | j                   z           }| j                            t                                        |          S )z4Create the cell that corresponds to the given index.)r  r  rq  r@  r  r  )r   r+  r  s      r   r  zFormulaRow.createcell	  sA    OEC,@,@$@A	|"";//<<YGGGr   N)
r   r   r   r   rF   r   rT   r  r  r  r!   r   r   r  r  	  sY        ""!'8M  
( ( (H H H H Hr   r  c                   *    e Zd ZdZd Zd Zd Zd ZdS )MultiRowFormulazA formula with multiple rows.c                     g | _         d}|                     |          D ]E}|rd}n|                                  |                    |           |                     |           Ft          | j                   | _        dS )z,Parse all rows, finish when no more row endsTFN)r  iteraterowsaddemptyr  addrowr  r  )r   r#  firstrows       r   	parserowszMultiRowFormula.parserows	  s    	##C(( 	 	C   LLKK	NN			r   c              #   F  K   t           j        d         }	 |                    |d           | j                            t
                    }|                    | j                  V  |                    |          r$| xj	        |
                    |          z  c_	        ndS )z0Iterate over all rows, end when no more row endsrV   TN)rF   r   r  rq  r@  r  r  r  r  rB  r  )r   r#  rV   r  s       r   r  zMultiRowFormula.iteraterows	  s      $*>:	NN<...,%%j11C##DO44444||L)) |!<!<<	r   c                    | j                             t                                        | j                  }t          | j        d         j                  D ]Q\  }}|                    |          }|	                    t          d                     |	                    |           R|                     |           dS )zAdd an empty row.r  u    N)rq  r@  r  r  r  r*  r  r[  r  r  r%   r  )r   r  r+  originalcellr  s        r   r  zMultiRowFormula.addempty	  s    l!!*--;;DOLL#,TYr]-C#D#D 	 	E<>>%((DHH_U++,,,GGDMMMMCr   c                 d    | j                             |           |                     |           dS )z2Add a row to the contents and to the list of rows.N)r  r  r  )r   r  s     r   r  zMultiRowFormula.addrow	  s+    	r   N)r   r   r   r   r  r  r  r  r!   r   r   r  r  	  sV        ### # #
 
 
      r   r  c                   "    e Zd ZdZdZd Zd ZdS )FormulaArrayzAn array within a formular   c                     t                                          dd          | _        |                     |           |                     |           dS )r  r  FN)r  r  rZ  parsealignmentsr  r"  s     r   r  zFormulaArray.parsebit	  sJ    "nn++,@%HHS!!!sr   c                     d| _         |                     |          }|r|| _         |                     |          }g | _        |D ]}| j                            |           dS )zParse the different alignmentsr   N)valignr  r  r  r  )r   r#  r  ss       r   r  zFormulaArray.parsealignments	  sy     ))#.. 	"!DK##C(( 	& 	&AO""1%%%%	& 	&r   N)r   r   r   r   r_  r  r  r!   r   r   r  r  	  s=        E  & & & & &r   r  c                       e Zd ZdZdZd ZdS )FormulaMatrixz'A matrix (array with center alignment).matrixc                     t                                          dd          | _        d| _        dg| _        |                     |           dS )z(Parse the matrix, set alignments to 'c'.r  Fr   N)r  r  rZ  r  r  r  r"  s     r   r  zFormulaMatrix.parsebit
  sF    "nn++,@%HH%sr   Nr  r!   r   r   r  r  
  s.        --E    r   r  c                       e Zd ZdZdZd ZdS )FormulaCaseszA cases statementcasesc                    t                      | _        ddg| _        |                     |           | j        D ]N}|j        D ]D}|j                            dd           |j                            t          d                     EOt                      	                    | j        dd          }t          t          | j                  dd          }|                                |gz   | _        dS )zParse the casesr   zspan class="case align-l"Tu    zspan class="bracketcases"r^   N)r  rZ  r  r  r[  r  r  r%   r  r  r  r  r  )r   r#  r  r  r   braces         r   r  zFormulaCases.parsebit
  s    $&&*s= 	= 	=C = =""#>EEE$$_U%;%;<<<<= $$T]4OQUVV3t}--sC88))++ug5r   Nr  r!   r   r   r  r  
  s.        E6 6 6 6 6r   r  c                       e Zd ZdZd ZdS )EquationEnvironmentz;A \begin{}...\end equation environment with rows and cells.c                    | j                             dd          }t                                          d|z  d          | _        |t
          j        v rt
          j        |         | _        nut          	                    d| j         z              t                                          d          | _        | 
                    t          d|z                       dg| _        |                     |           d	S )
zParse the whole environment.r   r<   zspan class="environment %s"FzUnknown equation environment rc  z\begin{%s} r   N)r_  r  r  r  rZ  rF   r   r  r   r   r  r%   r  )r   r#  environments      r   r  zEquationEnvironment.parsebit$
  s    j((b11"nn++5kA5J J-444+8EDOOKK7$*DEEE&..//0FGGDKHH_^K%?@@AAA"eDOsr   N)r   r   r   r   r  r!   r   r   r  r  !
  s)        CC    r   r  c                   H    e Zd ZdZej        d         diZeee	e
gZd Zd ZdS )BeginCommandzEA \begin{}...\end command and what it entails (array, cases, aligned)rS   r<   c                 l   |                      |          }|                     |          }t          j        d         dz   |z   dz   }|                    |           |                    |           |                     |           | xj        |                    |          z  c_        |j	        | _	        dS )zParse the begin commandrU   r^   r_   N)
r  findbitrF   r   r  r  r  rB  r  r  )r   r#  r   r  rm  s        r   r  zBeginCommand.parsebit<
  s    ##C((ll7##$U+c1G;cAvSv...H			r   c                     t           j        D ]=}|                    dd          |j        k    r| j                            |          c S >| j                            t                    }||_        |S )z7Find the command bit corresponding to the \begin{piece}r   r<   )r  r_  r  r_  rq  r@  r  )r   r_  rF  r  s       r   r  zBeginCommand.findbitG
  sr     & 	1 	1D}}S"%%33|**400000 4l!!"566	
r   N)r   r   r   r   rF   r   rp  r  r  r  r  r_  r  r  r!   r   r   r  r  5
  sX        MM%g.3JlL-HE	 	 	    r   r  c                   (    e Zd Zej        Zd Zd ZdS )r)   c                 P   | j         }|                     |          }|s$t                              d| j        z              dS t          |t                    si	 t          t          j	                  }|
                    |          d         }n3# t          $ r& t                              d| j        z             Y dS w xY w|j                            d          rd}nd}|j        d|         |z   |j        |d         z   |_        t          j        d|j                  |_        dS )	zParse a combining function.z)Missing parameter for combining function Nr   z!No base character found for "%s".r,  r
  r  NFC)r  parsesingleparameterr   r   r   r  r%   rH  r#   r9   rV  
IndexErrorr  r  unicodedata	normalize)r   r#  	combiningr  	extractorr   s         r   r  zCombiningFunction.parsebitX
  s1   O	--c22	 	KKCdlRSSSF )_55 	./JKK	%--i88;		   ?$,NOOO
 &&x00 	AAA$+BQB/);i>Nqrr>RR	&0	8HII	s   4B ,B>=B>c                     | j                             |           |                                rdS |                     |          S )z&Parse a parameter, or a single letter.N)rq  rZ  r  rk  r"  s     r   r  z&CombiningFunction.parsesingleparameterr
  sA    !!#&&&<<>> 	4""3'''r   N)r   r   r   rF   r   rp  r  r  r!   r   r   r)   r)   T
  s=        1JJ J J4( ( ( ( (r   r)   c                   &    e Zd ZdZej        Zd ZdS )r0   z;A function that decorates some bit of text with an overset.c                    | j         }t                                          |d          | _        |                     |          | _        t                                          d          | _        | j	        
                    d| j                   t                                          d          | j        _        |                                  dS )zParse an overset-functionr   span class="embellished"r   span class="base"Nr  r  ru  r  rk  r  r  r  rZ  r[  r  r  r   r#  r  s      r   r  zOversetFunction.parsebit
      kk**6599,,S11"nn++,FGGQ,,, , 5 56I J J!!!!!r   N)r   r   r   r   rF   r   rp  r  r!   r   r   r0   r0   z
  s1        AA/J" " " " "r   r0   c                   &    e Zd ZdZej        Zd ZdS )r5   z<A function that decorates some bit of text with an underset.c                    | j         }t                                          |d          | _        |                     |          | _        t                                          d          | _        | j	        
                    d| j                   t                                          d          | j        _        |                                  dS )zParse an underset-functionr   r  r   r   Nr  r  s      r   r  zUndersetFunction.parsebit
  r  r   N)r   r   r   r   rF   r   rp  r  r!   r   r   r5   r5   
  s1        BB0J" " " " "r   r5   c                   &    e Zd ZdZej        Zd ZdS )LimitCommandz@A command which accepts limits above and below, in display mode.c                     t                                          d          | _        | j        }| j                            t                                          |d                     dS )zParse a limit command.span class="limits"zspan class="limit"N)r  r  rZ  r  r[  r  r  ru  r  s      r   r  zLimitCommand.parsebit
  sT    "nn++,ABBY[[11&:NOOPPPPPr   N)r   r   r   r   rF   r   rp  r  r!   r   r   r  r  
  s6        FF,JQ Q Q Q Qr   r  c                   "    e Zd ZdZdZd Zd ZdS )LimitPreviousCommandz(A command to limit the previous command.Nc                     t                                          d          | _        | j                            |           dS )zDo nothing.r	  N)r  r  rZ  rq  rZ  r"  s     r   r  zLimitPreviousCommand.parsebit
  s8    "nn++,ABB!!#&&&&&r   c                     dS )r  zLimit previous commandr!   r4  s    r   rv  zLimitPreviousCommand.__str__
  s    ''r   )r   r   r   r   rp  r  rv  r!   r   r   r  r  
  s=        ..J' ' '
( ( ( ( (r   r  c                   H    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZdS )LimitsProcessorz)A processor for limits inside an element.c                    t           j        rdS |                     ||          r|                     ||           |                     ||          r1|                     ||dz             r|                     ||           dS dS dS )z"Process the limits for an element.Nr  )r   r:  checklimitsmodifylimitscheckscriptmodifyscriptsr  s      r   rQ  zLimitsProcessor.process
  s     	FHe,, 	/h...He,, 	01A1A(ETUI1V1V 	0x/////	0 	0 	0 	0r   c                     t           j        sdS |                     ||dz   t                    r|                     ||           dS t          ||         t                    sdS |                     ||dz             S )z3Check if the current position has a limits command.Fr  )r  r  checkcommandr  limitsaheadr  r  r  r  s      r   r  zLimitsProcessor.checklimits
  s     "- 	5Xuqy2FGG 	Xu---5(5/<88 	5%!)444r   c                     ||dz                                 ||                                                    t                      ||         _        dS )z,Limit the current element based on the next.r  N)r  rC  r  rZ  r  s      r   r  zLimitsProcessor.limitsahead
  sE     5 5 7 7888!,r   c                 z   ||         }|                      ||dz             }|                     ||dz             r|                      ||dz             }n"t                                          dd          }|j        dk    r||}}|j                            |           |j                            d|           dS )zCModify a limits commands so that the limits appear above and below.r  r,  zsup class="limit"rj   r   N)getlimitr  r  ru  r   r[  r  r  )r   r[  r+  limited	subscriptsuperscripts         r   r  zLimitsProcessor.modifylimits
  s    5/MM(EAI66	Heai00 	N--%!)<<KK#++..x9LMMK##%.K	***;/////r   c                     |                      ||          }|j        j                            dd          |j        _        |S )z#Get the limit for a limits command.scriptrF  )	getscriptrZ  r  r  )r   r[  r+  rF  s       r   r  zLimitsProcessor.getlimit
  s9    x// <+33HgFFr   c                     |                      ||          }|                      ||          }|j        dk    r||}}t                                          ||gd          }|                    ||           dS )z=Modify the super- and subscript to appear vertically aligned.rj   zspan class="scripts"N)r   r   r  r  r  )r   r[  r+  r  r  scriptss         r   r  zLimitsProcessor.modifyscripts
  sx    NN8U33	nnXu55##%.K++&&Y'?AWXXw'''''r   c                 :    |                      ||t                    S )z6Check if the current element is a sub- or superscript.)r  r3   r  s      r   r  zLimitsProcessor.checkscript
  s      5.AAAr   c                 X    t          |          |k    rdS t          ||         |          S )z0Check for the given type as the current element.F)r  r  )r   r[  r+  rF  s       r   r  zLimitsProcessor.checkcommand
  s,    x==E!!5(5/4000r   c                 F    ||         }|j         xj        dz  c_        ||= |S )zGet the sub- or superscript.z class="script")rZ  r  )r   r[  r+  r  s       r   r   zLimitsProcessor.getscript
  s*    uo
++UO
r   N)r   r   r   r   rQ  r  r  r  r  r  r  r  r   r!   r   r   r  r  
  s        //0 0 0
5 
5 
5/ / /
0 0 0  	( 	( 	(B B B1 1 1    r   r  c                   ,    e Zd ZdZej        Zd Zd ZdS )r(   z"A command which defines a bracket.c                 <    t                               | |           dS )zParse the bracket.N)r/   r  r"  s     r   r  zBracketCommand.parsebit  s    !!$,,,,,r   c                 R    || _         d|z   | _        t          |          g| _        | S )z+Create the bracket for the given character.rR   )rB  r   r%   r[  r   	direction	characters      r   r@  zBracketCommand.create  s,    !i'(334r   N)	r   r   r   r   rF   r   rp  r  r@  r!   r   r   r(   r(     s@        ((.J- - -    r   r(   c                   B    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
S )BracketProcessorz!A processor for bracket commands.c                 z    t           j        rdS |                     ||          r|                     ||          S dS )z6Convert the bracket using Unicode pieces, if possible.N)r   r:  	checkleftprocessleftr  s      r   rQ  zBracketProcessor.process  sH     	F>>(E** 	5##He444	5 	5r   c                     |                      ||dz             }|sdS |                     |||          }|                     ||         |           |                     ||         |           dS )zProcess a left bracket.r  N)	findrightfindmaxresize)r   r[  r+  
rightindexr  s        r   r0  zBracketProcessor.processleft  sr    ^^Heai88
 	F||HeZ88HUOT***HZ($/////r   c                 :    |                      ||         d          S )z0Check if the command at the given index is left.ra   checkdirectionr  s      r   r/  zBracketProcessor.checkleft'  s    ""8E?H===r   c                 :    |                      ||         d          S )z1Check if the command at the given index is right.rb   r7  r  s      r   
checkrightzBracketProcessor.checkright+  s    ""8E?I>>>r   c                 F    t          |t                    sdS |j        |k    S )z6Check if the given bit is the desired bracket command.F)r  r(   r   )r   r  r   s      r   r8  zBracketProcessor.checkdirection/  s&    #~.. 	5{g%%r   c                     d}|t          |          k     rV|                     ||          r|dz  }|                     ||          r|dz  }|dk    r|S |dz  }|t          |          k     VdS )z9Find the right bracket starting at the given index, or 0.r  r   N)r  r/  r:  )r   r[  r+  depths       r   r2  zBracketProcessor.findright5  s    c(mm##~~h.. 
x// 
zzQJE c(mm## tr   c                 H    |||         }t          d |D                       S )z@Find the max size of the contents between the two given indices.c              3   $   K   | ]}|j         V  d S r   r  r  s     r   r   z+BracketProcessor.findmax.<locals>.<genexpr>E  s$      66G7<666666r   )r   )r   r[  	leftindexr5  sliceds        r   r3  zBracketProcessor.findmaxB  s.    )J./66v666666r   c                     |                                 }|j                            dd          }t          |||          }t	                      |_        |                                |_        dS )z+Resize a bracket command to the given size.rR   r<   N)r9   r   r  r  r  rZ  r  r[  )r   r   r  r+  r  r   s         r   r4  zBracketProcessor.resizeG  sb    ''))	O++D"55	T9i88'))"..00r   N)r   r   r   r   rQ  r0  r/  r:  r8  r2  r3  r4  r!   r   r   r-  r-    s        ''5 5 50 0 0> > >? ? ?& & &  7 7 7
1 1 1 1 1r   r-  c                   :    e Zd ZdZ	 	 	 	 ddgZd Zd Zd Zd ZdS )	ParameterDefinitionz3The definition of a parameter in a hybrid function.)r\   r]   )r^   r_   c                 L    d | _         d| _        d| _        d | _        d | _        d S )NF)rX  r  r  r   literalvaluer4  s    r   r   zParameterDefinition.__init__a  s,    	
 r   c                 `   t           j        D ]\  }}|                    |          r|dk    rd| _        |                    d          s5t                              d|                                z   dz               dS |                                | _        |                    d          rd| _	        |                    |          s2t                              d|                                z               dS | c S t                              d	|                                z              dS )
z2Parse a parameter definition: [$0], {$x}, {$1!}...r\   Tr   z$Wrong parameter name, did you mean $r   Nr   zWrong parameter closing z'Wrong character in parameter template: )
rD  parambracketsrG  r  r   r   r  r  rX  r  )r   r#  openingclosings       r   r{  zParameterDefinition.parseh  s   "5"C 	 	Wg}}W%% c>>$(DM}}S))  KK F VY\ \]]]44OO--	==%% (#'DL}}W--  KK :S__=N=N NOOO44 	=@Q@QQRRRtr   c                 N   | j         r`| j        r|                    |          | _        n|                    |          | _        | j        rt          | j                  | _        dS dS | j        r|                    |          | _        dS |                    |          | _        dS )z/Read the parameter itself using the definition.N)	r  r  r  rF  r  r%   r   r  rk  )r   r#  r  s      r   readzParameterDefinition.read{  s    < 
	6} ?$,$?$?$D$D!!$,$9$9#$>$>!  @,T->??


@ @] 	6!--c22DJJJ!0055DJJJr   c                 h    d| j         z   }| j        r|dt          | j                  z   z  }n|dz  }|S )r  zparam rd   z (empty))rX  r   rn  )r   r&  s     r   rv  zParameterDefinition.__str__  s@    DI%: 	!dS__,,FFj Fr   N)	r   r   r   r   rH  r   r{  rL  rv  r!   r   r   rD  rD  X  sl        99>A9\,M! ! !  &6 6 6    r   rD  c                   2    e Zd ZdZ	 d Zd Zd Zd Zd ZdS )ParameterFunctionzFA function with a variable number of parameters defined in a template.c                     i | _         |                     |          D ]*}|                    ||            || j         d|j        z   <   +dS )z*Read the params according to the template.r   N)params	paramdefsrL  rX  r   readtemplater#  paramdefs       r   
readparamszParameterFunction.readparams  sX    |44 	8 	8HMM#t$$$/7DKhm+,,	8 	8r   c              #      K   t          |          }|                                s=t                                          |          }|r|V  |                                ;dS dS )z*Read each param definition in the templateN)rJ  r  rD  r{  rS  s       r   rR  zParameterFunction.paramdefs  ss      <((,,.. 	*,,22377H  ,,.. 	 	 	 	 	r   c                 2    || j         vrdS | j         |         S )zGet a parameter as parsed.N)rQ  r  s     r   getparamzParameterFunction.getparam  s!    t{""4{4  r   c                 6    |                      |          j        S )zGet the value of a parameter.)rY  r   r  s     r   getvaluezParameterFunction.getvalue  s    }}T""((r   c                 P    |                      |          }|r|j        sdS |j        S )z%Get the literal value of a parameter.N)rY  rF  )r   rX  r.  s      r   getliteralvaluez!ParameterFunction.getliteralvalue  s3    d## 	E. 	4!!r   N)	r   r   r   r   rV  rR  rY  r[  r]  r!   r   r   rO  rO    sh        LL;8 8 8  ! ! !) ) )" " " " "r   rO  c                   P    e Zd ZdZej        Zd Zd Zd Z	d Z
d Zd Zd Zd	 Zd
S )HybridFunctiona  
    A parameter function where the output is also defined using a template.
    The template can use a number of functions; each function has an associated
    tag.
    Example: [f0{$1},span class="fbox"] defines a function f0 which corresponds
    to a span of class fbox, yielding <span class="fbox">$1</span>.
    Literal parameters can be used in tags definitions:
      [f0{$1},span style="color: $p;"]
    yields <span style="color: $p;">$1</span>, where $p is a literal parameter.
    Sizes can be specified in hybridsizes, e.g. adding parameter sizes. By
    default the resulting size is the max of all arguments. Sizes are used
    to generate the right parameters.
    A function followed by a single / is output as a self-closing XHTML tag:
      [f0/,hr]
    will generate <hr/>.
    c                     | j         d         }| j         d         }|                     ||           |                     |          | _        |                                  dS )z*Parse a function with [] and {} parametersr   r  N)r  rV  writeparamsr[  computehybridsize)r   r#  rT  writetemplates       r   r  zHybridFunction.parsebit  s[    q)*c***((77     r   c                 F    |                      t          |                    S )z*Write all params according to the template)writeposrJ  )r   rc  s     r   ra  zHybridFunction.writeparams  s    }}\-88999r   c                    g }|                                 sR|                    d          r-|                     |          }|r|                    |           n|                    d          r4|                     |          }|rd|_        |                    |           n|                    d          r*|                    |                     dd                     ns|                    d          r*|                    |                     dd                     n4|                    t          |                                                     |                                 R|S )z/Write all params as read in the parse position.r   fNrZ   leftr[   right)	r  rG  
writeparamr  writefunctionrF  writebracketr%   r  )r   r#  r&  r.  r  s        r   re  zHybridFunction.writepos  sU   ,,.. 	B}}S!! B,, )MM%(((s## 
B--c22 ,$(HMMM(+++s## Bd//<<====s## Bd//==>>>>ocoo.?.?@@AAA ,,.. 	B  r   c                 >   d|                                 z   }|| j        vrt                              d|z              dS | j        |         sdS |                    d          r)|                                | j        |         j        _        | j        |         j        S )z*Write a single param of the form $0, $x...r   zUnknown parameter Nr   )r  rQ  r   r   rG  r  r   rF  )r   r#  rX  s      r   rj  zHybridFunction.writeparam  s    S__&&&t{""KK,t34444{4  	4== 	;+.==??DK#({4 &&r   c                    |                      |          }|sdS |                    d          r!t                                          |          S |                    d          st                              d           dS |                    d           |                     |          }|                                 t          |          dk    rdS t                      
                    ||          S )z"Write a single function f0,...,fn.Nr   r^   z Function should be defined in {}r_   r   )readtagrG  r  r  r   r   r  re  r  r  r  )r   r#  r  r[  s       r   rk  zHybridFunction.writefunction  s    ll3 	4== 	1;;++C000}}S!! 	KK:;;;4s==%%x==A4{{##Hc222r   c                    |                                                                 s1t                              d|                                 z              dS t	          |                                          }d|z   t          | j                  k    r/t                              dt          |          z   dz              dS | j        d|z            }d|vr|S | j	        D ]h}||v rb| j	        |         }|j
        s't                              d|z   dz   |z   d	z              A|j        r|j        }nd
}|                    ||          }i|S )zJGet the tag corresponding to the given index. Does parameter substitution.zFunction should be f0,...,f9: fNr
  z
Function fz is not definedr   zParameters in tag z should be literal: {z!}r<   )r  r  r   r   intr  r  r  rn  rQ  r  rF  r  )r   r#  r+  r  variabler.  r   s          r   ro  zHybridFunction.readtag  sI   {{}}$$&& 	KK9CKKMMIJJJ4COO%%&&u9s4?++++KKs5zz14EEFFF4oa%i(c>>J 
	3 
	3H3H-} KK 4s :=T TW_ _bf fggg% !.EEEkk(E22
r   c                 h    | j                             t                                        ||          S )z4Return a new bracket looking at the given direction.)rq  r@  r(   r)  s      r   rl  zHybridFunction.writebracket$  s(    |"">2299)YOOOr   c                     | j         t          j        vr|                                  dS t                                          |           | _        | j        D ]}| j        |_        dS )z(Compute the size of the hybrid function.N)r   
HybridSizeconfigsizesr  getsizer  r[  )r   r  s     r   rb  z HybridFunction.computehybridsize(  sh    <z555FLL((..	} 	% 	%G9GLL	% 	%r   N)r   r   r   r   rF   r   rp  r  ra  re  rj  rk  ro  rl  rb  r!   r   r   r_  r_    s         " .J! ! !: : :  *
' 
' 
'3 3 3$  2P P P% % % % %r   r_  c                   &    e Zd ZdZej        Zd ZdS )ru  z+The size associated with a hybrid function.c                 4   | j         |j                 }|j        D ]M}||v rG|j        |         j                                        }|                    |t          |                    }Nd|v rt                              d|z              dS t          |          S )z*Read the size for a function and parse it.r   z%Unconverted variable in hybrid size: r  )
rv  r   rQ  r   r  r  rn  r   r   eval)r   r  
sizestringrX  r  s        r   rw  zHybridSize.getsize8  s    %h&67
O 	A 	ADz!!t,2>>@@'//c$ii@@
*KK?*LMMM1Jr   N)r   r   r   r   rF   r   rv  rw  r!   r   r   ru  ru  3  s1        11+K
  
  
  
  
 r   ru  c                     t                      }|                    |           }t                                          |           |                                 d                    |                                          S )zConvert some TeX math to HTML.r<   )r7  r  r   rQ  rv  r  )r  rq  r8  s      r   	math2htmlr}  H  sa    G  ))Eu%%%	MMOOO775==??###r   c                  4   t           j        } t                                          |            t	          |           dk    r(t
                              d           t                       t          | d                   }t
          	                    |           dS )z6Main function, called if invoked from the command liner  z"Usage: math2html.py escaped_stringr   N)
r
   argvr   r  r  r   r   r6  r}  r   )r  r&  s     r   mainr  Q  su    8DII4   
4yyA~~8999tAwF	MM&r   __main__)Zr0  r
   r  docutils.utils.mathr   r8  r   r#   r;   rF   r   r   r>  rH  r^  rx  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r5  rJ  rV  r  r  r  r  r  r  r  r%   r1   r.   r-   r  r  r'   r  r  r   r,   rL  r7  rf  r~  r*   r2   r&   r/   r3   r4   r+   r_  r  r  r  r  r  r  r  r  r  r  r)   r0   r5   r  r  r  r(   r-  r(  rD  rO  r_  ru  r}  r  r   r!   r   r   <module>r     s  0  



     + + + + + + !% % % % % % % %P       2        f
 f
 f
 f
 f
 f
 f
 f
RA A A A A A A AH7 7 7 7 7 7 7 7t! ! ! ! ! ! ! !$& & & & & & & &R.F .F .F .F .F .F .F .Fb    &   " " " " " " " "J    f       O       6       6   	 	 	 	 	 	 	 	    /       /       _    @ @ @ @ @> @ @ @F    ^   8" " " " "? " " "t! t! t! t! t! t! t! t!n= = = = = = = =@       &68 68 68 68 68x 68 68 68r!7 !7 !7 !7 !78 !7 !7 !7HF? F? F? F? F? F? F? F?R    y   ,I ,I ,I ,I ,Ii ,I ,I ,I^	* 	* 	* 	* 	* 	* 	* 	*       f f f f fF f f fR*E *E *E *E *E *E *E *EZ    
   *2 2 2 2 2h 2 2 2.    j   6 6 6 6 6J 6 6 6<    J   1 1 1 1 1j 1 1 15 5 5 5 5 5 5 5 D& D& D& D& D&j D& D& D&N
 
 
 
 
G 
 
 
	< 	< 	< 	< 	< 	< 	< 	<2; 2; 2; 2; 2; 2; 2; 2;jL$ L$ L$ L$ L$i L$ L$ L$^
1 
1 
1 
1 
1: 
1 
1 
1F F F F F F F FRS S S S SZ S S Sl9 9 9 9 9 9 9 9x; ; ; ; ;: ; ; ;
Q 
Q 
Q 
Q 
QJ 
Q 
Q 
Q         <      "# # # # #z # # #(! ! ! ! !Z ! ! !"    :   	" 	" 	" 	" 	"# 	" 	" 	"   8 8  , 0,-! 
;N ;N ;N ;N ;N ;N ;N ;N|< < < < <j < < << < < < <. < < < H H H H H H H H:) ) ) ) )j ) ) )X& & & & &? & & &2
 
 
 
 
O 
 
 
6 6 6 6 6? 6 6 6&    /   (    :   8    &  #( #( #( #( #(( #( #( #(L" " " " "& " " " " " " " "' " " " 	Q 	Q 	Q 	Q 	Q< 	Q 	Q 	Q( ( ( ( (< ( ( (K K K K Kn K K K\    %   "91 91 91 91 91~ 91 91 91x   *:*L.J J     O''))    
8 8 8 8 8 8 8 8v"" "" "" "" ""
 "" "" ""Jx% x% x% x% x%& x% x% x%v               $   ( (  $ $ $   zDFFFFF r   