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