Back to index

wims  3.65+svn20090927
Classes | Defines | Typedefs | Enumerations | Functions | Variables
texmath.c File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  afactor

Defines

#define MAX_FACTORS   256
#define tmathfn_no   (sizeof(tmathfn)/sizeof(tmathfn[0]))
#define tmathvar_no   (sizeof(tmathvar)/sizeof(tmathvar[0]))

Typedefs

typedef struct afactor afactor

Enumerations

enum  {
  type_integer, type_numeric, type_var, type_poly,
  type_transcend
}

Functions

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)
void n_onestring (char *p)
void n_oneterm (char *p, int num)
void n_onefactor (struct afactor *p, int num)
void texmath (char *p)
void tprint (char *s,...)
void _tex_sums (char *p, char *name, int type)
void tex_int (char *p)
void tex_sum (char *p)
void tex_prod (char *p)
char * find_factor_end (char *p)
int term_cnt (char *p)
void putnumber (char *p)
void putvar (char *p)
int fsort (const void *p1, const void *p2)
void t_exponential (char *pp)

Variables

char texmathbuf [MAX_LINELEN+1]
struct {
char * name
int expind
char * left
char * right
void(* routine )(char *p)
tmathfn []
struct {
char * name
char * tex
tmathvar []

Class Documentation

struct afactor

Definition at line 27 of file texmath.c.

Class Members
char * beg
char * end
int side
int type

Define Documentation

#define MAX_FACTORS   256

Definition at line 20 of file texmath.c.

#define tmathfn_no   (sizeof(tmathfn)/sizeof(tmathfn[0]))

Definition at line 147 of file texmath.c.

#define tmathvar_no   (sizeof(tmathvar)/sizeof(tmathvar[0]))

Definition at line 199 of file texmath.c.


Typedef Documentation

typedef struct afactor afactor

Enumeration Type Documentation

anonymous enum
Enumerator:
type_integer 
type_numeric 
type_var 
type_poly 
type_transcend 

Definition at line 22 of file texmath.c.


Function Documentation

void _tex_sums ( char *  p,
char *  name,
int  type 
)

Definition at line 54 of file texmath.c.

{
    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("d");
       if(find_term_end(p1)<p1+strlen(p1)) {
           tprint("\\left("); t_onestring(p1); tprint("\\right)");
       }
       else t_onestring(p1);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* find_factor_end ( char *  p)

Definition at line 245 of file texmath.c.

{
    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;
           }
       }
       if(isalnum(*pp) || *pp=='.') {
           pp=find_mathvar_end(pp); pp--; continue;
       }
       continue;
       loopend:
       if(pp==NULL) module_error("unmatched_parentheses");
    }
    return pp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * find_term_end ( char *  p)

Definition at line 203 of file texmath.c.

{
    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;
           }
       }
       if(isalnum(*pp) || *pp=='.') {
           pp=find_mathvar_end(pp); pp--; continue;
       }
       continue;
       loopend:
       if(pp==NULL) module_error("unmatched_parentheses");
    }
    return pp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int fsort ( const void *  p1,
const void *  p2 
)

Definition at line 331 of file texmath.c.

{
    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;
    
}

Here is the caller graph for this function:

void n_onefactor ( struct afactor p,
int  num 
)
void n_onestring ( char *  p)
void n_oneterm ( char *  p,
int  num 
)
void putnumber ( char *  p)

Definition at line 297 of file texmath.c.

{
    char *pp;
    pp=strpbrk(p,"Ee");
    if(pp==NULL) {tprint("%s",p); return;}
    *pp++=0;
    tprint("%s \\times 10^{%s} ",p,pp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void putvar ( char *  p)

Definition at line 307 of file texmath.c.

{
    char vbuf[1024];
    char *pp, *p2;
    int i;
    
    vbuf[0]=0;
    if(*(p+1)==0) {tprint("%c",*p); return;}
    for(pp=p;isalpha(*pp);pp++);
    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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void t_exponential ( char *  pp)

Definition at line 484 of file texmath.c.

{
    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("} ");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void t_onefactor ( struct afactor p,
int  num 
)

Definition at line 509 of file texmath.c.

{
    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;
    if(strchr("({[",*p)!=NULL) {
       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 */
                  char mbuf[MAX_LINELEN+1];
                  char *pp, *pt;
                  
                  p++; if(*pe) *pe++=0;
                  tprint(" \\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(" }"); 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);
    if(isalpha(*p)) {
       pe=find_mathvar_end(p); while(*pe && strchr("'\"!",*pe)!=NULL) pe++;
       if(*pe=='(') {
           p=pe;
           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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void t_onestring ( char *  p)

Definition at line 631 of file texmath.c.

{
    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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void t_oneterm ( char *  p,
int  num 
)

Definition at line 343 of file texmath.c.

{
    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;

    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=-1; 
                         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:
    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;
           else factors[i].type=type_integer;
           continue;       
       }
       if(*pp=='(') {
           factors[i].type=type_poly; continue;
       }
       pt=strchr(pp,'('); 
       if(pt!=NULL && pt<pe) factors[i].type=type_transcend;
       else factors[i].type=type_var;
    }
    dentype=-1;
    for(i=0;i<fcnt;i++) if(factors[i].side<0 && factors[i].type>dentype)
      dentype=factors[i].type;
    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 ");
    if(dencnt>0) {
       tprint(" {");
       if(numcnt==0) tprint(" 1"); 
       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);
       }
       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);
       tprint("} ");
    }
    for(i=0;i<neucnt;i++) t_onefactor(neutral[i],i+dencnt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int term_cnt ( char *  p)

Definition at line 286 of file texmath.c.

{
    char *pe, *pp;
    int i;
    
    pe=p+strlen(p);
    for(i=0,pp=p;pp<pe;pp=find_term_end(pp),i++);
    return i;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tex_int ( char *  p)

Definition at line 90 of file texmath.c.

{  _tex_sums(p,"int",1); }

Here is the call graph for this function:

void tex_prod ( char *  p)

Definition at line 92 of file texmath.c.

{ _tex_sums(p,"prod",0);}

Here is the call graph for this function:

void tex_sum ( char *  p)

Definition at line 91 of file texmath.c.

{  _tex_sums(p,"sum",0); }

Here is the call graph for this function:

void texmath ( char *  p)

Definition at line 645 of file texmath.c.

{
    char *pp;

    if(strpbrk(p,"{}\\")!=NULL) return;
    for(pp=strstr(p,"!="); pp; pp=strstr(pp+1,"!=")) {
       if(pp>p && !isspace(*(pp-1))) continue;
       string_modify(p,pp,pp+2,"*neq*");
    }
       /* remove spaces */
    for(pp=p; *pp; pp++) {
       if(isspace(*pp)) {strcpy(pp,pp+1); pp--;}
    }
       /* replace ** by ^ */
    for(pp=strstr(p,"**"); pp!=NULL; pp=strstr(pp,"**")) {
      *pp='^'; strcpy(pp+1,pp+2);
    }
    if(check_parentheses(p,1)!=0) module_error("unmatched_parentheses");
    texmathbuf[0]=0; t_onestring(p);
    mystrncpy(p,texmathbuf,MAX_LINELEN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tprint ( char *  s,
  ... 
)

Definition at line 43 of file texmath.c.

{
    va_list vp;
    char buf[MAX_LINELEN+1];

    va_start(vp,s); vsnprintf(buf,sizeof(buf),s,vp); va_end(vp);
    if(strlen(buf)+strlen(texmathbuf)>=MAX_LINELEN) 
      user_error("cmd_output_too_long");
    strcat(texmathbuf,buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 32 of file texmath.c.

struct { ... } tmathfn[]
struct { ... } tmathvar[]