Subversion Repositories wimsdev

Rev

Rev 6525 | Rev 8155 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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