Subversion Repositories wimsdev

Rev

Rev 8185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. #include "wims.h"
  18.  
  19. /* automatic selection of math rendering method */
  20.  
  21. void exec_instex(char *p);
  22. void calc_instexst(char *p);
  23.  
  24. struct {
  25.     char src[124], name[128];
  26.     int size;
  27. } oldinstex[100];
  28. int oldtexcnt=0;
  29.  
  30.     /* check whether the same tex source has already been produced */
  31. int instex_ready(char *p, char *n)
  32. {
  33.     int i;
  34.     char *cl, buf[MAX_LINELEN+1];
  35.  
  36.     if(strlen(p)>=124) return 0;
  37.     cl=getvar("instex_color"); if(cl!=NULL && *cl!=0) return 0;
  38.     mystrncpy(buf,p,sizeof(buf)); tex_nospace(buf);
  39.     for(i=0;i<oldtexcnt;i++) {
  40.       if(oldinstex[i].size==current_tex_size &&
  41.        strcmp(oldinstex[i].src,buf)==0) {
  42.         ovlstrcpy(n,oldinstex[i].name); return 1;
  43.       }
  44.     }
  45.     if(strlen(n)>=128 || oldtexcnt>=100) return 0;
  46.     ovlstrcpy(oldinstex[oldtexcnt].src,buf);
  47.     ovlstrcpy(oldinstex[oldtexcnt].name,n);
  48.     oldinstex[oldtexcnt].size=current_tex_size;
  49.     oldtexcnt++; return 0;
  50. }
  51.  
  52.     /* returns NULL if instex can use static */
  53. char *instex_check_static(char *p)
  54. {
  55.     char *f;
  56.     if(instex_usedynamic) return p;
  57.     for(f=strchr(p,'$');
  58.     f!=NULL && *(f+1)!='(' && *(f+1)!='[' && *(f+1)!='_' && !isalnum(*(f+1));
  59.     f=strchr(f+2,'$'));
  60.     if(f==NULL) f=strstr(m_file.name,"sessions/");
  61.     return f;
  62. }
  63.  
  64. char tnames[]="sqrt int integrate sum prod product \
  65. Int Sum Prod conj abs";
  66.  
  67. int __gototex (char *p, char *f, int ts)
  68. {
  69.       char alignbak[2048];
  70.       char *pp, buf[MAX_LINELEN+1];
  71.       ovlstrcpy(buf,p);
  72.       instex_style="$$";
  73.       if(!ts) texmath(buf);
  74.          /* ts=0 but there is some computer matrix to transform
  75.           * done by texmath, but it does much more as replacing strings in tmathfn
  76.           * OK if buf contains " math computer-syntax" ; if not, the result may be bad
  77.         */
  78.       else {// seems tex : need to interpret names of variables as \x or \calB
  79.        //if (mathalign_base < 2) { //to check
  80.         char *p1;
  81.         p1=find_word_start(buf);
  82.         if(*p1=='\\') {
  83.           int i;
  84.           char *pt;
  85.           for(i=1;isalnum(p1[i]);i++); /* find an alphanumeric string beginning by \\ */
  86.           if(p1[i]==0 && (pt=mathfont(p1))!=NULL) {
  87.             _output_(pt); *p=0; return 1;
  88.           }
  89.         }
  90.       // }
  91.       }
  92.       /* send to mathml */
  93.       if( strcmp( getvar("force_mathml") , "yes" ) == 0 ){/* override math-with-gifs */
  94.        mathalign_base = 2;
  95.       }
  96.       if (mathalign_base == 2 && mathml(buf,0)) { *p=0 ;return 1; }
  97. /* end if mathml option in case ts=1 or "computer matrix" */
  98.  
  99. /* creating images*/
  100.       pp=getvar("ins_align");
  101.       if(pp!=NULL) mystrncpy(alignbak,pp,sizeof(alignbak));
  102.       setvar("ins_align","middle");
  103.       mystrncpy(ins_alt,buf,sizeof(ins_alt));
  104.       if(f==NULL) {
  105.         calc_instexst(buf); output("%s",buf);
  106.       }
  107.       else {
  108.         instex_usedynamic=1; exec_instex(buf); instex_usedynamic=0;
  109.       }
  110.       instex_style="";
  111.       if(alignbak[0]) setvar("ins_align",alignbak);
  112.       *p=0; return 0;
  113. }
  114.  
  115.     /* Intelligent insertion of math formulas, kernel */
  116. void __insmath(char *p)
  117. {
  118.     char *f, *pp, *pe, *p1, buf[MAX_LINELEN+1], nbuf[256];
  119.     int ts, n, rawmathready;
  120.  
  121.     ovlstrcpy(buf,p); strip_trailing_spaces(buf); singlespace(buf);
  122.     p1=getvar("insmath_slashsubst");
  123.     if(p1!=NULL && strstr(p1,"yes")!=NULL) slashsubst(buf); // substitute backslash parameters
  124.     f=instex_check_static(buf); //decide if image already exists
  125.     substit(buf);//substitute the variables
  126.     /* here replace .. by , : i=1 .. 5 -> i=1, 5 !*/
  127.     for(pp=strstr(buf,".."); pp!=NULL; pp=strstr(pp,"..")) {
  128.       if(*(pp+2)=='.' || *(pp+2)==',') {
  129.         do pp++; while(*pp=='.'); continue;
  130.       }
  131.       *pp=','; *(pp+1)=' ';
  132.     }
  133.     /* decide if it should be tex */
  134.     ts=0; if(strchr(buf,'\\') || strchr(buf,'}')) ts=1;
  135.     /* if not and if variable insmath_rawmath is there, do rawmath */
  136.     rawmathready=0;
  137.     if(!ts) { /* not tex, looking if rawmath is asked */
  138.       pp=getvar("insmath_rawmath");
  139.       if(pp!=NULL && strstr(pp,"yes")!=NULL) {
  140.         rawmath(buf); rawmathready=1;
  141.       }
  142.     }
  143.     if(ts) {
  144.          _replace_matrix (buf,"\\matrix{","matrix"); //could be done in any case if ts=1
  145.          _replace_matrix (buf,"\\pmatrix{","pmatrix");
  146.     }
  147. /* if ts=1 (it should be a tex formula)  or if there is a [ ,  ; ] matrix */
  148.     if(ts ||
  149.       (strchr(buf,'[')!=NULL && (strchr(buf,',')!=NULL || strchr(buf,';')!=NULL))) {
  150.        if(__gototex(buf, f, ts)) return;
  151.     }
  152.  
  153. /* end creating images
  154.  * we are now in the case where ts=0 and no need of tex for matrix */
  155.  
  156. /* find math variables */
  157.     for(pp=find_mathvar_start(buf); *pp; pp=find_mathvar_start(pe)) {
  158.       pe=find_mathvar_end(pp); n=pe-pp;
  159.       /* non alpha variable or too short or too long to be interpreted as tnames */
  160.       if(!isalpha(*pp) || n<3 || n>16) continue;
  161.       memmove(nbuf,pp,n); nbuf[n]=0;
  162.       if(wordchr(tnames,nbuf)!=NULL) { if(__gototex(buf, f, 0)) return;}
  163.       /* find sqrt int integrate sum prod product Int Sum Prod conj abs,
  164.        * so must be texmath interpretated ; after going to tex, return in any case
  165.        */
  166.     }
  167. /* look for  /  to interpretate as quotients -
  168.  * extend the version by accepting something else than (
  169. */
  170.     //for(pp=strchr(buf,'/'); pp!=NULL && *find_word_start(pp+1)!='('; pp=strchr(pp+1,'/'));
  171.     pp=strchr(buf,'/');
  172.     if(pp!=NULL){ if( __gototex(buf,f,0)) return;} /* so a/4 can be reinterpreted as {a over 4 } ; transform also 5/(x+1) */
  173.     if(rawmathready) rawmath_easy=1;
  174.     for(pp=strchr(buf,'<'); pp!=NULL; pp=strchr(pp+1,'<'))
  175.       string_modify(buf,pp,pp+1,"&lt;");
  176.     for(pp=strchr(buf,'>'); pp!=NULL; pp=strchr(pp+1,'>'))
  177.       string_modify(buf,pp,pp+1,"&gt;");
  178. /* no tex has been introduced - so go to mathmlmath */
  179.     mathmlmath(buf); output("%s",buf);
  180.     rawmath_easy=0;
  181. }
  182.  
  183. /* the following is not used in modules : no insmath_logic=yes somewhere */
  184.  
  185. char *andor[]={"and","or","not","is","isnot"};
  186. #define andorcnt (sizeof(andor)/sizeof(andor[0]))
  187. char *andorlang[andorcnt], andorlangbuf[1024];
  188. int andorlangcnt=-1;
  189.  
  190. /* Processing logic statements in math formulas */
  191. void _mathlogic(char *p, void _put(char *pp))
  192. {
  193.     char *p1, *p2, *ps;
  194.     int i;
  195.     if(strstr(p,"qzis")==NULL) {
  196.       for(i=0;i<andorcnt && varchr(p,andor[i])==NULL; i++);
  197.       if(i>=andorcnt) {
  198.         _put(p); return;
  199.       }
  200.     }
  201.     if(andorlangcnt<0) {
  202.       char buf[MAX_LINELEN+1];
  203.       accessfile(buf,"r","bases/sys/andor.%s",lang);
  204.       mystrncpy(andorlangbuf,find_word_start(buf),sizeof(andorlangbuf));
  205.       for(i=0,p1=andorlangbuf;i<andorcnt;i++,p1=find_word_start(p2)) {
  206.         p2=strchr(p1,',');
  207.         if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
  208.         strip_trailing_spaces(p1);
  209.         if(*p1) andorlang[i]=p1; else break;
  210.     }
  211.     andorlangcnt=i;
  212.     }
  213.     for(ps=p, p1=find_mathvar_start(p); *p1; p1=find_mathvar_start(p2)) {
  214.       p2=find_mathvar_end(p1);
  215.       if(!isalpha(*p1)) continue;
  216.       if(strncmp(p1,"qzis",4)==0) {
  217.         char *p3, *p4, *p5;
  218.         /*int tt;*/
  219.         p4=find_word_start(p2);
  220.         if(*p4!='(') continue;
  221.         if(strncmp(p1+4,"not",3)==0) {/*tt=4;*/ p3=p1+7;}
  222.         else {/*tt=3; */p3=p1+4;}
  223.         if(!isalpha(*p3)) continue;
  224.         p4++; p5=find_matching(p4,')');
  225.         if(*p5!=')') continue;
  226.         *p5=0; *p2=0; p2=p5+1;
  227.  
  228.  
  229.         continue;
  230.       }
  231.       for(i=0;i<andorlangcnt;i++) if(strncmp(p1,andor[i],p2-p1)==0) break;
  232.       if(i<andorlangcnt) {
  233.         *p1=0; ps=find_word_start(ps); if(*ps) _put(ps);
  234.         output(" %s ",andorlang[i]); ps=p2;
  235.       }
  236.     }
  237.     ps=find_word_start(ps); if(*ps) _put(ps);
  238. }
  239.  
  240. /* Intelligent insertion of math formulas */
  241. void insmath(char *p)
  242. {
  243.     char *pt;
  244.     if(!outputing) goto end;
  245.     pt=getvar("insmath_logic");
  246.     if(pt==NULL || strstr(pt,"yes")==NULL) {
  247.       __insmath(p);
  248.       end: *p=0; return;
  249.     }
  250.     _mathlogic(p,__insmath);
  251. }
  252.