Back to index

wims  3.65+svn20090927
insmath.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018        /* automatic selection of math rendering method */
00019 
00020 void exec_instex(char *p);
00021 void calc_instexst(char *p);
00022 
00023 struct {
00024     char src[124], name[128];
00025     int size;
00026 } oldinstex[100];
00027 int oldtexcnt=0;
00028 
00029        /* Use mathml to output TeX formula.
00030         * Returns 1 if OK, 0 if unknown. */
00031        /* It doesn't work yet. */
00032 int mathml(char *p)
00033 {
00034 /*    char *p1, buf[MAX_LINELEN+1];
00035     if(strlen(p)==1 && isalpha(*p)) {
00036        output("<math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n");
00037        snprintf(buf,sizeof(buf),
00038                "<mrow><mi>%c</mi></mrow></math>\n",*p);
00039        output("%s",buf); return 1;
00040     }
00041     output("<pre>%s</pre>\n",p); return 1;
00042 */    
00043     return 0;
00044 }
00045 
00046        /* check whether the same tex source has already been produced */
00047 int instex_ready(char *p, char *n)
00048 {
00049     int i;
00050     char *cl, buf[MAX_LINELEN+1];
00051     
00052     if(strlen(p)>=124) return 0;
00053     cl=getvar("instex_color"); if(cl!=NULL && *cl!=0) return 0;
00054     mystrncpy(buf,p,sizeof(buf)); tex_nospace(buf);
00055     for(i=0;i<oldtexcnt;i++) {
00056        if(oldinstex[i].size==current_tex_size &&
00057           strcmp(oldinstex[i].src,buf)==0) {
00058            strcpy(n,oldinstex[i].name); return 1;
00059        }
00060     }
00061     if(strlen(n)>=128 || oldtexcnt>=100) return 0;
00062     strcpy(oldinstex[oldtexcnt].src,buf);
00063     strcpy(oldinstex[oldtexcnt].name,n);
00064     oldinstex[oldtexcnt].size=current_tex_size;
00065     oldtexcnt++; return 0;
00066 }
00067 
00068        /* returns NULL if instex can use static */
00069 char *instex_check_static(char *p)
00070 {
00071     char *f;
00072     if(instex_usedynamic) return p;
00073     for(f=strchr(p,'$');
00074        f!=NULL && *(f+1)!='(' && *(f+1)!='[' && *(f+1)!='_' && !isalnum(*(f+1));
00075        f=strchr(f+2,'$'));
00076     if(f==NULL) f=strstr(m_file.name,"sessions/");
00077     return f;
00078 }
00079 
00080 char tnames[]="sqrt int integrate sum prod product \
00081 Int Sum Prod conj abs";
00082 
00083        /* Intelligent insertion of math formulas, kernel */
00084 void __insmath(char *p)
00085 {
00086     char *f, *pp, *pe, *p1, buf[MAX_LINELEN+1], nbuf[256];
00087     int ts, n, rawmathready;
00088 
00089     strcpy(buf,p); strip_trailing_spaces(buf);
00090     p1=getvar("insmath_slashsubst");
00091     if(p1!=NULL && strstr(p1,"yes")!=NULL) slashsubst(buf);
00092     f=instex_check_static(buf); substit(buf);
00093     for(pp=strstr(buf,".."); pp!=NULL; pp=strstr(pp,"..")) {
00094        if(*(pp+2)=='.' || *(pp+2)==',') {
00095            do pp++; while(*pp=='.'); continue;
00096        }
00097        *pp=','; *(pp+1)=' ';
00098     }
00099     ts=0; if(strchr(buf,'\\') || strchr(buf,'}')) ts=1;
00100     rawmathready=0; if(!ts) {
00101        pp=getvar("insmath_rawmath");
00102        if(pp!=NULL && strstr(pp,"yes")!=NULL) {
00103            rawmath(buf); rawmathready=1;
00104        }
00105     }
00106     if(ts || mathalign_base==2 ||
00107        (strchr(buf,'[')!=NULL && 
00108        (strchr(buf,',')!=NULL || strchr(buf,';')!=NULL))) {
00109        char alignbak[2048];
00110        tex: instex_style="$$";
00111        if(!ts) texmath(buf);
00112        else {
00113            char *p1;
00114            p1=find_word_start(buf);
00115            if(*p1=='\\') {
00116               int i;
00117               char *pt;
00118               for(i=1;isalnum(p1[i]);i++);
00119               if(p1[i]==0 && (pt=mathfont(p1))!=NULL) {
00120                   _output_(pt); *p=0; return;
00121               }
00122            }
00123        }
00124        if(mathalign_base==2 && mathml(buf)) {*p=0; return;}
00125        pp=getvar("ins_align");
00126        if(pp!=NULL) mystrncpy(alignbak,pp,sizeof(alignbak));
00127        setvar("ins_align","middle");
00128        mystrncpy(ins_alt,buf,sizeof(ins_alt));
00129        if(f==NULL) {
00130            calc_instexst(buf); output("%s",buf);
00131        }
00132        else {
00133            instex_usedynamic=1; exec_instex(buf); instex_usedynamic=0;
00134        }
00135        instex_style=""; 
00136        if(alignbak[0]) setvar("ins_align",alignbak);
00137        return;
00138     }
00139     for(pp=find_mathvar_start(buf); *pp; pp=find_mathvar_start(pe)) {
00140        pe=find_mathvar_end(pp); n=pe-pp;
00141        if(!isalpha(*pp) || n<3 || n>16) continue;
00142        memmove(nbuf,pp,n); nbuf[n]=0;
00143        if(wordchr(tnames,nbuf)!=NULL) goto tex;
00144     }
00145 /*    for(pp=strchr(buf,'{'); pp!=NULL; pp=strchr(pp+1,'{')) *pp='(';
00146     for(pp=strchr(buf,'}'); pp!=NULL; pp=strchr(pp+1,'}')) *pp=')';
00147 */    for(pp=strchr(buf,'/'); pp!=NULL && *find_word_start(pp+1)!='(';
00148        pp=strchr(pp+1,'/'));
00149     if(pp!=NULL) goto tex;
00150     if(rawmathready) rawmath_easy=1;
00151     for(pp=strchr(buf,'<'); pp!=NULL; pp=strchr(pp+1,'<'))
00152       string_modify(buf,pp,pp+1,"&lt;");
00153     for(pp=strchr(buf,'>'); pp!=NULL; pp=strchr(pp+1,'>'))
00154       string_modify(buf,pp,pp+1,"&gt;");
00155     htmlmath(buf); output("%s",buf); rawmath_easy=0;
00156 }
00157 
00158 char *andor[]={"and","or","not","is","isnot"};
00159 #define andorcnt (sizeof(andor)/sizeof(andor[0]))
00160 char *andorlang[andorcnt], andorlangbuf[1024];
00161 int andorlangcnt=-1;
00162 
00163        /* Processing logic statements in math formulas */
00164 void _mathlogic(char *p, void _put(char *pp))
00165 {
00166     char *p1, *p2, *ps;
00167     int i;
00168     if(strstr(p,"qzis")==NULL) {
00169        for(i=0;i<andorcnt && varchr(p,andor[i])==NULL; i++);
00170        if(i>=andorcnt) {
00171            _put(p); return;
00172        }
00173     }
00174     if(andorlangcnt<0) {
00175        char buf[MAX_LINELEN+1];
00176        accessfile(buf,"r","bases/sys/andor.%s",lang);
00177        mystrncpy(andorlangbuf,find_word_start(buf),sizeof(andorlangbuf));
00178        for(i=0,p1=andorlangbuf;i<andorcnt;i++,p1=find_word_start(p2)) {
00179            p2=strchr(p1,',');
00180            if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
00181            strip_trailing_spaces(p1);
00182            if(*p1) andorlang[i]=p1; else break;      
00183        }
00184        andorlangcnt=i;
00185     }
00186     for(ps=p, p1=find_mathvar_start(p); *p1; p1=find_mathvar_start(p2)) {
00187        p2=find_mathvar_end(p1);
00188        if(!isalpha(*p1)) continue;
00189        if(strncmp(p1,"qzis",4)==0) {
00190            char *p3, *p4, *p5;
00191            int tt;
00192            p4=find_word_start(p2);
00193            if(*p4!='(') continue;
00194            if(strncmp(p1+4,"not",3)==0) {tt=4; p3=p1+7;}
00195            else {tt=3; p3=p1+4;}
00196            if(!isalpha(*p3)) continue;
00197            p4++; p5=find_matching(p4,')');
00198            if(*p5!=')') continue;
00199            *p5=0; *p2=0; p2=p5+1;
00200            
00201            
00202            
00203            
00204            continue;
00205        }
00206        for(i=0;i<andorlangcnt;i++) if(strncmp(p1,andor[i],p2-p1)==0) break;
00207        if(i<andorlangcnt) {
00208            *p1=0; ps=find_word_start(ps); if(*ps) _put(ps);
00209            output(" %s ",andorlang[i]); ps=p2;
00210        }
00211     }
00212     ps=find_word_start(ps); if(*ps) _put(ps);
00213 }
00214 
00215        /* Intelligent insertion of math formulas */
00216 void insmath(char *p)
00217 {
00218     char *pt;
00219     if(!outputing) goto end;
00220     pt=getvar("insmath_logic");
00221     if(pt==NULL || strstr(pt,"yes")==NULL) {
00222        __insmath(p); 
00223        end: *p=0; return;
00224     }
00225     _mathlogic(p,__insmath);
00226 }
00227