Subversion Repositories wimsdev

Rev

Rev 10 | Rev 5504 | 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.  
  18.         /* automatic selection of math rendering method */
  19.  
  20. void exec_instex(char *p);
  21. void calc_instexst(char *p);
  22.  
  23. struct {
  24.     char src[124], name[128];
  25.     int size;
  26. } oldinstex[100];
  27. int oldtexcnt=0;
  28.  
  29.         /* Use mathml to output TeX formula.
  30.          * Returns 1 if OK, 0 if unknown. */
  31.         /* It doesn't work yet. */
  32. int mathml(char *p)
  33. {
  34. /*    char *p1, buf[MAX_LINELEN+1];
  35.     if(strlen(p)==1 && isalpha(*p)) {
  36.         output("<math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n");
  37.         snprintf(buf,sizeof(buf),
  38.                  "<mrow><mi>%c</mi></mrow></math>\n",*p);
  39.         output("%s",buf); return 1;
  40.     }
  41.     output("<pre>%s</pre>\n",p); return 1;
  42. */    
  43.     return 0;
  44. }
  45.  
  46.         /* check whether the same tex source has already been produced */
  47. int instex_ready(char *p, char *n)
  48. {
  49.     int i;
  50.     char *cl, buf[MAX_LINELEN+1];
  51.    
  52.     if(strlen(p)>=124) return 0;
  53.     cl=getvar("instex_color"); if(cl!=NULL && *cl!=0) return 0;
  54.     mystrncpy(buf,p,sizeof(buf)); tex_nospace(buf);
  55.     for(i=0;i<oldtexcnt;i++) {
  56.         if(oldinstex[i].size==current_tex_size &&
  57.            strcmp(oldinstex[i].src,buf)==0) {
  58.             ovlstrcpy(n,oldinstex[i].name); return 1;
  59.         }
  60.     }
  61.     if(strlen(n)>=128 || oldtexcnt>=100) return 0;
  62.     ovlstrcpy(oldinstex[oldtexcnt].src,buf);
  63.     ovlstrcpy(oldinstex[oldtexcnt].name,n);
  64.     oldinstex[oldtexcnt].size=current_tex_size;
  65.     oldtexcnt++; return 0;
  66. }
  67.  
  68.         /* returns NULL if instex can use static */
  69. char *instex_check_static(char *p)
  70. {
  71.     char *f;
  72.     if(instex_usedynamic) return p;
  73.     for(f=strchr(p,'$');
  74.         f!=NULL && *(f+1)!='(' && *(f+1)!='[' && *(f+1)!='_' && !isalnum(*(f+1));
  75.         f=strchr(f+2,'$'));
  76.     if(f==NULL) f=strstr(m_file.name,"sessions/");
  77.     return f;
  78. }
  79.  
  80. char tnames[]="sqrt int integrate sum prod product \
  81. Int Sum Prod conj abs";
  82.  
  83.         /* Intelligent insertion of math formulas, kernel */
  84. void __insmath(char *p)
  85. {
  86.     char *f, *pp, *pe, *p1, buf[MAX_LINELEN+1], nbuf[256];
  87.     int ts, n, rawmathready;
  88.  
  89.     ovlstrcpy(buf,p); strip_trailing_spaces(buf);
  90.     p1=getvar("insmath_slashsubst");
  91.     if(p1!=NULL && strstr(p1,"yes")!=NULL) slashsubst(buf);
  92.     f=instex_check_static(buf); substit(buf);
  93.     for(pp=strstr(buf,".."); pp!=NULL; pp=strstr(pp,"..")) {
  94.         if(*(pp+2)=='.' || *(pp+2)==',') {
  95.             do pp++; while(*pp=='.'); continue;
  96.         }
  97.         *pp=','; *(pp+1)=' ';
  98.     }
  99.     ts=0; if(strchr(buf,'\\') || strchr(buf,'}')) ts=1;
  100.     rawmathready=0; if(!ts) {
  101.         pp=getvar("insmath_rawmath");
  102.         if(pp!=NULL && strstr(pp,"yes")!=NULL) {
  103.             rawmath(buf); rawmathready=1;
  104.         }
  105.     }
  106.     if(ts || mathalign_base==2 ||
  107.        (strchr(buf,'[')!=NULL &&
  108.         (strchr(buf,',')!=NULL || strchr(buf,';')!=NULL))) {
  109.         char alignbak[2048];
  110.         tex: instex_style="$$";
  111.         if(!ts) texmath(buf);
  112.         else {
  113.             char *p1;
  114.             p1=find_word_start(buf);
  115.             if(*p1=='\\') {
  116.                 int i;
  117.                 char *pt;
  118.                 for(i=1;isalnum(p1[i]);i++);
  119.                 if(p1[i]==0 && (pt=mathfont(p1))!=NULL) {
  120.                     _output_(pt); *p=0; return;
  121.                 }
  122.             }
  123.         }
  124.         if(mathalign_base==2 && mathml(buf)) {*p=0; return;}
  125.         pp=getvar("ins_align");
  126.         if(pp!=NULL) mystrncpy(alignbak,pp,sizeof(alignbak));
  127.         setvar("ins_align","middle");
  128.         mystrncpy(ins_alt,buf,sizeof(ins_alt));
  129.         if(f==NULL) {
  130.             calc_instexst(buf); output("%s",buf);
  131.         }
  132.         else {
  133.             instex_usedynamic=1; exec_instex(buf); instex_usedynamic=0;
  134.         }
  135.         instex_style="";
  136.         if(alignbak[0]) setvar("ins_align",alignbak);
  137.         return;
  138.     }
  139.     for(pp=find_mathvar_start(buf); *pp; pp=find_mathvar_start(pe)) {
  140.         pe=find_mathvar_end(pp); n=pe-pp;
  141.         if(!isalpha(*pp) || n<3 || n>16) continue;
  142.         memmove(nbuf,pp,n); nbuf[n]=0;
  143.         if(wordchr(tnames,nbuf)!=NULL) goto tex;
  144.     }
  145. /*    for(pp=strchr(buf,'{'); pp!=NULL; pp=strchr(pp+1,'{')) *pp='(';
  146.     for(pp=strchr(buf,'}'); pp!=NULL; pp=strchr(pp+1,'}')) *pp=')';
  147. */    for(pp=strchr(buf,'/'); pp!=NULL && *find_word_start(pp+1)!='(';
  148.         pp=strchr(pp+1,'/'));
  149.     if(pp!=NULL) goto tex;
  150.     if(rawmathready) rawmath_easy=1;
  151.     for(pp=strchr(buf,'<'); pp!=NULL; pp=strchr(pp+1,'<'))
  152.       string_modify(buf,pp,pp+1,"&lt;");
  153.     for(pp=strchr(buf,'>'); pp!=NULL; pp=strchr(pp+1,'>'))
  154.       string_modify(buf,pp,pp+1,"&gt;");
  155.     htmlmath(buf); output("%s",buf); rawmath_easy=0;
  156. }
  157.  
  158. char *andor[]={"and","or","not","is","isnot"};
  159. #define andorcnt (sizeof(andor)/sizeof(andor[0]))
  160. char *andorlang[andorcnt], andorlangbuf[1024];
  161. int andorlangcnt=-1;
  162.  
  163.         /* Processing logic statements in math formulas */
  164. void _mathlogic(char *p, void _put(char *pp))
  165. {
  166.     char *p1, *p2, *ps;
  167.     int i;
  168.     if(strstr(p,"qzis")==NULL) {
  169.         for(i=0;i<andorcnt && varchr(p,andor[i])==NULL; i++);
  170.         if(i>=andorcnt) {
  171.             _put(p); return;
  172.         }
  173.     }
  174.     if(andorlangcnt<0) {
  175.         char buf[MAX_LINELEN+1];
  176.         accessfile(buf,"r","bases/sys/andor.%s",lang);
  177.         mystrncpy(andorlangbuf,find_word_start(buf),sizeof(andorlangbuf));
  178.         for(i=0,p1=andorlangbuf;i<andorcnt;i++,p1=find_word_start(p2)) {
  179.             p2=strchr(p1,',');
  180.             if(p2==NULL) p2=p1+strlen(p1); else *p2++=0;
  181.             strip_trailing_spaces(p1);
  182.             if(*p1) andorlang[i]=p1; else break;           
  183.         }
  184.         andorlangcnt=i;
  185.     }
  186.     for(ps=p, p1=find_mathvar_start(p); *p1; p1=find_mathvar_start(p2)) {
  187.         p2=find_mathvar_end(p1);
  188.         if(!isalpha(*p1)) continue;
  189.         if(strncmp(p1,"qzis",4)==0) {
  190.             char *p3, *p4, *p5;
  191.             int tt;
  192.             p4=find_word_start(p2);
  193.             if(*p4!='(') continue;
  194.             if(strncmp(p1+4,"not",3)==0) {tt=4; p3=p1+7;}
  195.             else {tt=3; p3=p1+4;}
  196.             if(!isalpha(*p3)) continue;
  197.             p4++; p5=find_matching(p4,')');
  198.             if(*p5!=')') continue;
  199.             *p5=0; *p2=0; p2=p5+1;
  200.            
  201.            
  202.            
  203.            
  204.             continue;
  205.         }
  206.         for(i=0;i<andorlangcnt;i++) if(strncmp(p1,andor[i],p2-p1)==0) break;
  207.         if(i<andorlangcnt) {
  208.             *p1=0; ps=find_word_start(ps); if(*ps) _put(ps);
  209.             output(" %s ",andorlang[i]); ps=p2;
  210.         }
  211.     }
  212.     ps=find_word_start(ps); if(*ps) _put(ps);
  213. }
  214.  
  215.         /* Intelligent insertion of math formulas */
  216. void insmath(char *p)
  217. {
  218.     char *pt;
  219.     if(!outputing) goto end;
  220.     pt=getvar("insmath_logic");
  221.     if(pt==NULL || strstr(pt,"yes")==NULL) {
  222.         __insmath(p);
  223.         end: *p=0; return;
  224.     }
  225.     _mathlogic(p,__insmath);
  226. }
  227.  
  228.