Subversion Repositories wimsdev

Rev

Rev 10 | Rev 5465 | 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
 
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) {
3718 reyssat 58
            ovlstrcpy(n,oldinstex[i].name); return 1;
10 reyssat 59
        }
60
    }
61
    if(strlen(n)>=128 || oldtexcnt>=100) return 0;
3718 reyssat 62
    ovlstrcpy(oldinstex[oldtexcnt].src,buf);
63
    ovlstrcpy(oldinstex[oldtexcnt].name,n);
10 reyssat 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
 
3718 reyssat 89
    ovlstrcpy(buf,p); strip_trailing_spaces(buf);
10 reyssat 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