- /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis 
-  * 
-  *  This program is free software; you can redistribute it and/or modify 
-  *  it under the terms of the GNU General Public License as published by 
-  *  the Free Software Foundation; either version 2 of the License, or 
-  *  (at your option) any later version. 
-  * 
-  *  This program is distributed in the hope that it will be useful, 
-  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-  *  GNU General Public License for more details. 
-  * 
-  *  You should have received a copy of the GNU General Public License 
-  *  along with this program; if not, write to the Free Software 
-  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-  */ 
- /* subroutines for texmath */ 
- #include "wims.h" 
-   
- /* Careful! increasing this number risks stack overflow. */ 
- #define MAX_FACTORS 256 
-   
- enum { 
-     type_integer, type_numeric, type_var, 
-       type_poly, type_transcend 
- }; 
-   
- typedef struct afactor{ 
-     char *beg, *end; 
-     int type, side; 
- } afactor; 
-   
- char texmathbuf[MAX_LINELEN+1]; 
- char *find_term_end(char *p); 
- void t_onestring(char *p); 
- void t_oneterm(char *p, int num); 
- void t_onefactor(struct afactor *p, int num); 
- /* never used or defined ?? */ 
- void n_onestring(char *p); 
- void n_oneterm(char *p, int num); 
- void n_onefactor(struct afactor *p, int num); 
- /* */ 
- void texmath(char *p); 
-   
- /* print to texmathbuf */ 
- void tprint(char *s,...) 
- { 
-     va_list vp; 
-     char buf[MAX_LINELEN+1]; 
-   
-       user_error("cmd_output_too_long"); 
- } 
- /* transforms sum(n,n=1..infinity) , product(n/(n+1),n=1..infinity). */ 
- void _tex_sums(char *p, char *name, int type) 
- { 
-     char *p1,*p2,*p3; 
-     p1=find_item_end(p); if(*p1) *(p1++)=0; 
-     p2=find_item_end(p1); p3=strparstr(p1,"="); 
-     if(p3<p2) p2=p3; 
-     if(*p2) *(p2++)=0; 
-     p3=find_item_end(p2); 
-     if(*p3) *(p3++)=0; 
-     tprint("\\%s ",name); 
-     if(type) { 
-       if(*p2) { 
-         tprint("_{"); t_onestring(p2); tprint("}"); 
-       } 
-     } 
-     else if(*p1) { 
-       tprint("_{%s",p1); 
-       if(*p2) { tprint("="); t_onestring(p2); } 
-       tprint("}"); 
-     } 
-     if(*p3) { 
-       tprint("^{"); t_onestring(p3); tprint("}"); 
-     } 
-     strip_trailing_spaces (- p ); if(- find_term_end (- p )<- p +strlen(- p )) {
-       tprint("\\left("); t_onestring(p); tprint("\\right)"); 
-     } 
-     else t_onestring(p); 
-     if(type && *p1) { 
-       strip_trailing_spaces(p1); tprint("\\,\\textrm{d}"); // case of the integrale 
-       if(- find_term_end (- p1 )<- p1 +strlen(- p1 )) {
 
-         tprint("\\left("); t_onestring(p1); tprint("\\right)"); 
-       } 
-       else t_onestring(p1); 
-     } 
- } 
-   
- /* integration, sum and product */ 
- void tex_int(char *p) {  _tex_sums(p,"int",1); } 
- void tex_sum(char *p) {  _tex_sums(p,"sum",0); } 
- void tex_prod(char *p) { _tex_sums(p,"prod",0);} 
-   
- struct tmathfn tmathfn[]={ 
-       {"Arg",      1,  "\\rm{Arg}",      "\\right)"}, 
-       {"Int",      2,  "","",        tex_int}, 
-       {"Prod",     2,  "","",        tex_prod}, 
-       {"Sum",      2,  "","",        tex_sum}, 
-       {"abs",      0,  "\\left|",      "\\right|"}, 
-       {"acos",     1,  "\\rm{arccos}",  "\\right)"}, 
-       {"acosh",    1,  "\\rm{Argch}",      "\\right)"}, 
-       {"arg",      1,  "\\rm{Arg}",      "\\right)"}, 
-       {"asin",     1,  "\\rm{arcsin}",  "\\right)"}, 
-       {"asinh",    1,  "\\rm{Argsh}",      "\\right)"}, 
-       {"atan",     1,  "\\rm{arctg}",      "\\right)"}, 
-       {"atanh",    1,  "\\rm{Argth}",      "\\right)"}, 
-       {"ch",       1,  "\\rm{ch}",      "\\right)"}, 
-       {"conj",     0,  "\\overline{",      "}"}, 
-       {"conjugate",0,  "\\overline{",      "}"}, 
-       {"cos",      1,  "\\cos",      "\\right)"}, 
-       {"cosh",     1,  "\\rm{ch}",      "\\right)"}, 
-       {"cot",      1,  "\\rm{ctg}",      "\\right)"}, 
-       {"cotan",    1,  "\\rm{ctg}",      "\\right)"}, 
-       {"cotanh",   1,  "\\rm{cth}",      "\\right)"}, 
-       {"csc",      1,  "\\rm{csc}",      "\\right)"}, 
-       {"ctg",      1,  "\\rm{ctg}",      "\\right)"}, 
-       {"cth",      1,  "\\rm{cth}",      "\\right)"}, 
-       {"det",      1,  "\\rm{det}",      "\\right)"}, 
-       {"erf",      1,  "\\rm{erf}",      "\\right)"}, 
-       {"exp",      1,  "\\exp",      "\\right)"}, 
-       {"int",      2,  "","",        tex_int}, 
-       {"integrate",2,  "","",        tex_int}, 
-       {"lg",       1,  "\\rm{lg}",      "\\right)"}, 
-       {"ln",       1,  "\\ln",        "\\right)"}, 
-       {"log",      1,  "\\log",      "\\right)"}, 
-       {"prod",     2,  "","",        tex_prod}, 
-       {"product",  2,  "","",        tex_prod}, 
-       {"sec",      1,  "\\rm{sec}",      "\\right)"}, 
-       {"sgn",      1,  "\\rm{sgn}",      "\\right)"}, 
-       {"sh",       1,  "\\rm{sh}",      "\\right)"}, 
-       {"sign",     1,  "\\rm{sign}",      "\\right)"}, 
-       {"sin",      1,  "\\sin",      "\\right)"}, 
-       {"sinh",     1,  "\\rm{sh}",      "\\right)"}, 
-       {"sqrt",     0,  "\\sqrt{",      "}"}, 
-       {"sum",      2,  "","",        tex_sum}, 
-       {"tan",      1,  "\\tan",      "\\right)"}, 
-       {"tanh",     1,  "\\rm{th}",      "\\right)"}, 
-       {"tg",       1,  "\\rm{tg}",      "\\right)"}, 
-       {"th",       1,  "\\rm{th}",      "\\right)"} 
- }; 
-   
- int tmathfn_no=(sizeof(tmathfn)/sizeof(tmathfn[0])); 
-   
- struct tmathvar tmathvar[]={ 
-       {"CC",      "\\mathbb{C}"}, 
-       {"Delta",   "\\Delta"}, 
-       {"Gamma",   "\\Gamma"}, 
-       {"Inf",     "\\infty"}, 
-       {"Lambda",  "\\Lambda"}, 
-       {"NN",      "\\mathbb{N}"}, 
-       {"Omega",   "\\Omega"}, 
-       {"PI",      "\\pi"}, 
-       {"Phi",     "\\Phi"}, 
-       {"Pi",      "\\Pi"}, 
-       {"Psi",     "\\Psi"}, 
-       {"QQ",      "\\mathbb{Q}"}, 
-       {"RR",      "\\mathbb{R}"}, 
-       {"Sigma",   "\\Sigma"}, 
-       {"Theta",   "\\Theta"}, 
-       {"Upsilon", "\\Upsilon"}, 
-       {"Xi",      "\\Xi"}, 
-       {"ZZ",      "\\mathbb{Z}"}, 
-       {"aleph",   "\\aleph"}, 
-       {"alpha",   "\\alpha"}, 
-       {"beta",   "\\beta"}, 
-       {"chi",    "\\chi"}, 
-       {"delta",  "\\delta"}, 
-       {"epsilon","\\epsilon"}, 
-       {"eta",    "\\eta"}, 
-       {"gamma",  "\\gamma"}, 
-       {"inf",    "\\infty"}, 
-       {"infinity","\\infty"}, 
-       {"infty",  "\\infty"}, 
-       {"iota",   "\\iota"}, 
-       {"kappa",  "\\kappa"}, 
-       {"lambda", "\\lambda"}, 
-       {"mu",     "\\mu"}, 
-       {"neq",    "\\neq"}, 
-       {"nu",     "\\nu"}, 
-       {"omega",  "\\omega"}, 
-       {"phi",    "\\phi"}, 
-       {"pi",     "\\pi"}, 
-       {"psi",    "\\psi"}, 
-       {"rho",    "\\rho"}, 
-       {"sigma",  "\\sigma"}, 
-       {"tau",    "\\tau"}, 
-       {"theta",  "\\theta"}, 
-       {"xi",     "\\xi"}, 
-       {"zeta",   "\\zeta"} 
- }; 
-   
- int tmathvar_no=(sizeof(tmathvar)/sizeof(tmathvar[0])); 
-   
-   
- /* find the end of an additive term. */ 
- char *find_term_end(char *p) 
- { 
-     char *pp; 
-     pp=p; 
-     if(*pp==',' || *pp==';' || *pp=='=' || *pp=='<') pp++; 
-     while(*pp=='+' || *pp=='-' || *pp=='=' || *pp=='>') pp++; 
-     for(;*pp;pp++) { 
-       switch(*pp) { 
-         case '(': pp=find_matching(pp+1,')'); goto loopend; 
-         case '[': pp=find_matching(pp+1,']'); goto loopend; 
- /*     case '{': pp=find_matching(pp+1,'}'); goto loopend;*/ 
-   
-         case 0: 
-         case '<': 
-         case '>': 
-         case ',': 
-         case ';': 
-         case '=': 
-         case ')': 
-         case ']': 
-         case '}': 
-         case '-': 
-         case '+': return pp; 
-   
-         case '*': 
-         case '/': 
-         case '^': { 
-           while(*(pp+1)=='+' || *(pp+1)=='-') pp++; 
-           goto loopend; 
-         } 
-       } 
-         pp=find_mathvar_end(pp); pp--; continue; 
-       } 
-       continue; 
-       loopend: 
-       if(pp==NULL) module_error("unmatched_parentheses"); 
-     } 
-     return pp; 
- } 
-   
- /* find the end of an multiplicative factor. */ 
- char *find_factor_end(char *p) 
- { 
-     char *pp; 
-     pp=p; if(*pp==',' || *pp==';' || *pp=='=') pp++; 
-     while(*pp=='+' || *pp=='-' || *pp=='*' || *pp=='/') pp++; 
-     for(;*pp;pp++) { 
-       switch(*pp) { 
-         case '(': pp=find_matching(pp+1,')'); goto loopend; 
-         case '[': pp=find_matching(pp+1,']'); goto loopend; 
- /*    case '{': pp=find_matching(pp+1,'}'); goto loopend;*/ 
-   
-         case 0: 
-         case '<': 
-         case '>': 
-         case ',': 
-         case ';': 
-         case '=': 
-         case ')': 
-         case ']': 
-         case '}': 
-         case '+': 
-         case '-': 
-         case '*': 
-         case '/': return pp; 
-   
-         case '^': { 
-           while(*(pp+1)=='+' || *(pp+1)=='-') pp++; 
-           goto loopend; 
-         } 
-       } 
-         pp=find_mathvar_end(pp); pp--; continue; 
-       } 
-       continue; 
-       loopend: 
-       if(pp==NULL) module_error("unmatched_parentheses"); 
-     } 
-     return pp; 
- } 
-   
-     /* returns the number of terms */ 
- int term_cnt(char *p) 
- { 
-     char *pe, *pp; 
-     int i; 
-   
-     for(i=0,pp=p;pp<pe;pp=find_term_end(pp),i++); 
-     return i; 
- } 
-   
- /* Print a number: transform 4E+05 in 4 \times 10^{5} and  4E-05 in 4 \times 10^{-5} 
- suppress multiple + or 0 ; see rawmath.c 
- */ 
- void putnumber(char *p) 
-  { 
-      char *- sgn  = "", *- pp  = strpbrk(- p ,"Ee");
 
-      if (pp == NULL) { tprint("%s",p); return; } 
-      *pp++ = 0; 
-      if (*pp == '-') { sgn = "-"; pp++; } 
-      while (*pp == '0' || *pp == '+') pp++; 
-      tprint("%s \\times 10^{%s%s}", p, sgn, pp); 
-  } 
-   
- /* Print a variable name ; transform abc475 in abc_475 */ 
- void putvar(char *p) 
- { 
-     char vbuf[1024]; 
-     char *pp, *p2; 
-     int i; 
-   
-     vbuf[0]=0; 
-     if(*(p+1)==0) {tprint("%c",*p); return;} 
-     if(myisdigit(*pp)) { 
-     for(p2=pp+1;myisdigit(*p2);p2++); 
-     if(*p2==0) {/* subscript */ 
-         mystrncpy(vbuf,pp,sizeof(vbuf));*pp=0; 
-     } 
-     } 
-     i=search_list(tmathvar, tmathvar_no, sizeof(tmathvar[0]), p); 
-     if(i>=0) tprint("%s ",tmathvar[i].tex); 
-     else tprint("%s ",p); 
-     if(vbuf[0]) { 
-     if(vbuf[1]==0) tprint("_%c ",vbuf[0]); 
-     else tprint("_{%s} ",vbuf); 
-     } 
- } 
-   
- /* sort according to type */ 
- int fsort(const void *p1, const void *p2) 
- { 
-   struct afactor *t1, *t2; 
-   int i1,i2; 
-   
-   t1=*(struct afactor **) p1; t2=*(struct afactor **) p2; 
-   i1=t1->type; i2=t2->type; 
-   if(i1>type_var) i1=type_var; 
-   if(i2>type_var) i2=type_var; 
-   return i1-i2; 
- } 
-   
- void t_oneterm(char *p, int num) 
- { 
-   int sign, fcnt, s, i, dentype, rel; 
-   char *pp, *pe, *pt; 
-   struct afactor factors[MAX_FACTORS]; 
-   struct afactor *numerator[MAX_FACTORS], 
-     *denominator[MAX_FACTORS], 
-     *neutral[MAX_FACTORS]; 
-   int numcnt,dencnt,neucnt; 
- /* interpret some arrows */ 
-   rel=0; 
-   switch(*p) { 
-     case '<': { 
-       rel++; p++; if(*p!='=') {tprint(" < "); break;} // < 
-       do p++; while(*p=='='); 
-       if(*p!='>') {tprint("\\le ");break;} // <= , <=== 
-       else {tprint("\\iff ");p++; break;} // <==> 
-     } 
-     case '>': { 
-       rel++; p++; if(*p!='=') {tprint(" > "); rel=1; break;} // > 
-       while(*p=='=') p++; 
-         tprint("\\ge "); // >= 
-         break; 
-     } 
-     case '-': { 
-       for(pp=p;*pp=='-';pp++); 
-       if(*pp!='>') break; 
-       rel++; tprint("\\to "); p=++pp; //-> 
-       break; 
-     } 
-     case '=': { 
-         rel++; for(pp=p;*pp=='=';pp++); 
-         if(*pp!='>') break; 
-         tprint("\\Rightarrow "); p=++pp; // => 
-         break; 
-     } 
-   } 
-   if(*p==',' || *p==';' || *p=='=') {tprint("%c",*p); p++; num=0;} 
-     sign=1; while(*p=='+' || *p=='-') { 
-       if(*p=='-') sign*=-1; 
-       p++; 
-   } 
-   for(fcnt=0, pp=p; fcnt<MAX_FACTORS && *pp; fcnt++, pp=pe) { 
-     s=1; 
-     while(*pp=='*' || *pp=='/') { 
-       if(*pp=='/') s=-1; 
-       pp++; 
-     } 
-     factors[fcnt].side=s; 
-     while(*pp=='+' || *pp=='-') { 
-       if(*pp=='-') sign*=-1; 
-       pp++; 
-     } 
-     pe=find_factor_end(pp); if(pe<=pp) break; 
-     factors[fcnt].beg=pp; factors[fcnt].end=pe; 
-     if(pe-pp==1 && *pp=='1') fcnt--; 
-     if(*pp=='(') { 
-       char *pt, *pe2, buf[MAX_LINELEN+1]; 
-       int ss; 
-       pp++; pt=find_matching(pp,')'); 
-       if(pt>=pe-1) { 
-         memmove(- buf ,- pp ,- pt -- pp );-  buf [- pt -- pp ]=0;
 
-         i=term_cnt(buf); 
-         if(i==1) { /* remove parentheses */ 
-           for(;pp<pt && fcnt<MAX_FACTORS;pp=pe2,fcnt++) { 
-             ss=s; 
-             while(*pp=='*' || *pp=='/') { 
-               if(*pp=='/') ss=-s; 
-               pp++; 
-             } 
-             factors[fcnt].side=ss; 
-             while(*pp=='+' || *pp=='-') { 
-               if(*pp=='-') sign*=-1; 
-               pp++; 
-             } 
-             pe2=find_factor_end(pp); 
-             if(pe2<=pp) goto bailout; 
-             factors[fcnt].beg=pp; factors[fcnt].end=pe2; 
-             if(pe2-pp==1 && *pp=='1') fcnt--; 
-           } 
-           fcnt--; 
-         } 
-       } 
-     } 
-   } 
-   bailout: 
- /* decide if the factor is of type numeric, integer, poly, transcend or variable 
- *  (see priorities) 
- */ 
-   for(i=0;i<fcnt;i++) { 
-     pp=factors[i].beg; pe=factors[i].end; 
-     if(myisdigit(*pp) || *pp=='.') { 
-       for(pt=pp;pt<pe && myisdigit(*pt);pt++); 
-       if(pt<pe) factors[i].type=type_numeric; // digits with a point 
-       else factors[i].type=type_integer;  // digits without point 
-       continue; 
-     } 
-     if(*pp=='(') { 
-       factors[i].type=type_poly; continue; //there exists a parenthesis 
-     } 
-     if(pt!=NULL && pt<pe) factors[i].type=type_transcend; //?? 
-     else factors[i].type=type_var;  // variable in other cases 
-   } 
-   dentype=-1; 
-   for(i=0;i<fcnt;i++) if(factors[i].side<0 && factors[i].type>dentype) 
-     dentype=factors[i].type; // denominator type will be compared to the type of the factors 
-   dencnt=numcnt=neucnt=0; 
-   for(i=0;i<fcnt;i++) { 
-     if(factors[i].type>dentype) neutral[neucnt++]=factors+i; 
-     else { 
-       if(factors[i].side>0) numerator[numcnt++]=factors+i; 
-       else denominator[dencnt++]=factors+i; 
-     } 
-   } 
-   if(- dencnt >0) qsort(- denominator ,- dencnt ,sizeof(- denominator [0]),- fsort );
 
-   if(- numcnt >0) qsort(- numerator ,- numcnt ,sizeof(- numerator [0]),- fsort );
 
-   if(- neucnt >0) qsort(- neutral ,- neucnt ,sizeof(- neutral [0]),- fsort );
 
-   if(sign>0 && num>0 && rel==0) tprint(" +"); 
-   if(sign<0) tprint(" -"); 
-   if(fcnt<1) tprint("1 "); // no factors why 1 - don't remove the 1 if [1,2;3,4], the 1 is useful? 
-   if(dencnt>0) { 
-     tprint(" {"); 
-     if(numcnt==0) tprint(" 1"); // no numerator ? will write {1 over denominator} 
-     else {/* numerator */ 
-       if(numcnt==1 && *numerator[0]->beg=='(' && 
-           find_matching(numerator[0]->beg+1,')')==(numerator[0]->end)-1) { 
-         *(numerator[0]->end-1)=0; 
-         t_onestring(numerator[0]->beg+1); 
-         *(numerator[0]->end-1)=')'; 
-       } 
-       else for(i=0; i<numcnt; i++) {t_onefactor(numerator[i],i); 
-       if(i<numcnt-1) tprint(" ");} /* add space between factors */ 
-     } 
-     tprint(" \\over ");      /* Now denominator */ 
-     if(dencnt==1 && *denominator[0]->beg=='(' && 
-       find_matching(denominator[0]->beg+1,')')==(denominator[0]->end)-1) { 
-        *(denominator[0]->end-1)=0; 
-        t_onestring(denominator[0]->beg+1); 
-        *(denominator[0]->end-1)=')'; 
-     } 
-     else for(i=0;i<dencnt;i++) {t_onefactor(denominator[i],i); 
-     if(i<dencnt-1) tprint(" ");} /* add space between factors */ 
-     tprint("} "); 
-   } 
-   for(i=0;i<neucnt;i++) {t_onefactor(neutral[i],i+dencnt); 
-   if(i<neucnt-1) tprint(" ");} /* add space between factors */ 
- } 
-   
- /* put exponential */ 
- void t_exponential(char *pp) 
- { 
-   char *pe, *pt; 
-   int t=0; 
-   
-   while(*- pp  && strchr("!'\"",*- pp )!=- NULL ) {
 
-     tprint("%c",*pp); pp++; 
-   } 
-   if(*pp=='^') pp++; else return; 
-   if(*pp=='(') { 
-     pe=find_matching(pp+1,')'); 
-     if(*(pe+1)==0) { 
-       pp++;*pe=0; 
-       for(- pt =- pp ;*- pt  && (isalnum(*- pt ) || *- pt =='.');- pt ++);
 
-       if(*pt==0) t=1; 
-     } 
-   } 
-   if(strlen(- pp )==1 &&-  t ==0)-  tprint ("^%s ",- pp );
 
-   else { 
-     tprint(" ^{"); if(t) tprint("("); 
-     t_onestring(pp); 
-     if(t) tprint(")"); 
-     tprint("} "); 
-   } 
- } 
-   
- void t_onefactor(struct afactor *fb, int num) 
- { 
-   char *p, *pe, lp, *rp, rp2, rpbuf[128]; 
-   char fbuf[MAX_LINELEN+1], pbuf[MAX_LINELEN+1]; 
-   int i; 
-   
-   memmove(- pbuf ,- fb ->- beg ,- fb ->- end -- fb ->- beg );
 
-   pbuf[fb->end-fb->beg]=0; 
-   if(num>0 && (myisdigit(pbuf[0]) || pbuf[0]=='.')) 
-     tprint("\\times "); 
-   rp2=')'; p=pbuf; 
-   lp=*p; switch(lp) { 
-     case '(': rp2=')';  break; 
-     case '[': { /* verify for matrices */ 
-       char *pt; 
-       pe=find_matching(p+1,']'); 
-       for(pt=p+1;pt<pe;pt++) { 
-         switch(*pt) { 
-           case '(': pt=find_matching(pt+1,')'); break; 
-           case '[': pt=find_matching(pt+1,']'); break; 
-           case '{': pt=find_matching(pt+1,'}'); break; 
-           case '|': pt=find_matching(pt+1,'|'); break; 
-   
-           case ',': 
-           case ';': goto out; 
-         } 
-       } 
-       out: if(*pt==';' || *pt==',') { /* is matrix of the form [ 1,2;5,6] */ 
-         char mbuf[MAX_LINELEN+1]; 
-         char *pp, *pt; 
-   
-         p++; if(*pe) *pe++=0; 
-         tprint(" \\begin{pmatrix}"); 
-         for(pp=p,i=0;*pp;pp=pt,i++) { 
-           pt=find_term_end(pp); 
-           memmove(- mbuf ,- pp ,- pt -- pp );-  mbuf [- pt -- pp ]=0;
 
-           t_oneterm(mbuf,i); 
-           if(*pt==',') { 
-             tprint(" &"); pt++; i=-1; 
-           } 
-           if(*pt==';') { 
-             tprint("\\cr "); pt++; i=-1; 
-           } 
-         } 
-         tprint(" \\end{pmatrix}"); goto expon; 
-       } 
-       rp2=']'; break; 
-     } 
-     case '{': { /* protected */ 
-       pe=find_matching(p+1,'}'); 
-       *pe=0;tprint(" %s} ",p); 
-       goto expon; 
-     } 
-   } 
-   tprint(" \\left%c",lp); 
-   snprintf(- rpbuf ,sizeof(- rpbuf ),"\\right%c ",- rp2 );-  rp =- rpbuf ;
 
-   paren: p++;pe=find_matching(p,rp2); *pe=0; 
-   t_onestring(p); tprint(rp); pe++; goto expon; 
-   } 
-   pe =- find_mathvar_end (- p ); while(*- pe  && strchr("'\"!",*- pe )!=- NULL )-  pe ++;
-   memmove(- fbuf ,- p ,- pe -- p );-  fbuf [- pe -- p ]=0;
 
-   if(myisdigit(*p) || *p=='.') putnumber(fbuf); 
-     pe =- find_mathvar_end (- p ); while(*- pe  && strchr("'\"!",*- pe )!=- NULL )-  pe ++;
-     if(*pe=='(') { 
-       p=pe; 
- /* search in list of math functions*/ 
-       i=search_list(tmathfn, tmathfn_no, sizeof(tmathfn[0]), fbuf); 
-       if(i>=0) { 
-         switch(tmathfn[i].expind) { 
-           case 0: { 
-             tprint(" %s",tmathfn[i].left); 
-             rp=tmathfn[i].right; break; 
-           } 
-           case 1: { 
-             tprint(" %s",tmathfn[i].left); 
-             pe=find_matching(pe+1,')')+1; 
-             if(*- pe  && strchr("^'\"!",*- pe )!=- NULL ) {
 
-               t_exponential(pe); *pe=0; 
-             } 
-             tprint(" \\left("); rp=tmathfn[i].right; 
-             break; 
-           } 
-           case 2: {  /* routine */ 
-             p++;pe=find_matching(p,rp2); *pe=0; 
-             tmathfn[i].routine(p); 
-             pe++; goto expon; 
-           } 
-           default: rp=""; break; 
-         } 
-       } 
-       else { 
-         putvar(fbuf); 
-         rp="\\right) "; tprint(" \\left("); 
-       } 
-       rp2=')'; goto paren; 
-     } 
-     else { 
-       putvar(fbuf); 
-       if(*pe=='_') { 
-         char *ptt, buff[256]; 
-         tprint("_"); pe++; 
-         if(*pe=='(') { 
-           ptt=find_matching(pe+1,')'); if(ptt) ptt++; 
-         } 
-         else { 
-           if(*pe=='{') { 
-             ptt=find_matching(pe+1,'}'); if(ptt) ptt++; 
-           } 
-           else ptt=find_mathvar_end(pe); 
-         } 
-         if(ptt==NULL || ptt-pe>128) goto expon; 
-         memmove(- buff ,- pe ,- ptt -- pe );-  buff [- ptt -- pe ]=0;-  pe =- ptt ;
 
-         strip_enclosing_par(buff); 
-         tprint("{%s}",buff); 
-       } 
-     } 
-   } 
-     /* exponential */ 
-   expon : if(*- pe  && strchr("^'\"!",*- pe )!=- NULL )-  t_exponential (- pe );
- } 
-   
- void t_onestring(char *p) 
- { 
-   char termbuf[MAX_LINELEN+1]; 
-   char *pp, *pe; 
-   int i; 
-   
-   for(pp=p,i=0;*pp;pp=pe,i++) { 
-   pe=find_term_end(pp); 
-   memmove(- termbuf ,- pp ,- pe -- pp );-  termbuf [- pe -- pp ]=0;
 
-   t_oneterm(termbuf,i); 
-   } 
- } 
- /* replace \pmatrix{  } by latex syntax \begin{pmatrix} .. \end{pmatrix} */ 
-   
- void _replace_matrix ( char *p , char *s_mat1, char *s_mat2 ) 
- { 
-   char pbuf[MAX_LINELEN]; 
-   while ( (- p  = strstr(- p ,- s_mat1 )) ){
 
-     char *- p2  =-  find_matching (- p +strlen(- s_mat1 ),'}');
 
-     long-  len  =-  p2 -- p -strlen(- s_mat1 );
 
-     if (!p2) { module_error("unmatched_parentheses"); return; } 
-     p2 ++ ; 
-     string_modify(p, p, p2, "\\begin{%s}%s\\end{%s}",s_mat2,pbuf,s_mat2); 
-   } 
- } 
-   
- /* translate raw math expression into TeX source */ 
- void texmath(char *p) 
- { 
-   char *pp; 
-   _replace_matrix (p,"\\matrix{","matrix"); 
-   _replace_matrix (p,"\\pmatrix{","pmatrix"); 
-   if(strpbrk(- p ,"{}\\")!=- NULL ) return;
 
-     if(- pp >- p  && !isspace(*(- pp -1))) continue;
 
-     string_modify(p,pp,pp+2,"*neq*"); 
-   } 
- /* remove spaces */ 
-   for(pp=p; *pp; pp++) { 
-   if(isspace(*- pp )) {- ovlstrcpy (- pp ,- pp +1);-  pp --;}
 
-   } 
- /* replace ** by ^  see __replace_badchar(p,"**", "^");*/ 
-     *pp='^'; ovlstrcpy(pp+1,pp+2); 
-   } 
-   if(check_parentheses(p,1)!=0) module_error("unmatched_parentheses"); 
-   texmathbuf[0]=0; t_onestring(p); 
-   singlespace(texmathbuf);strip_trailing_spaces(texmathbuf); 
-   mystrncpy(p,texmathbuf,MAX_LINELEN); 
- } 
-