1
2 /******************************************************************************
3 * MODULE : tm_mathematica.c
4 * DESCRIPTION: Interface with Mathematica
5 * COPYRIGHT : (C) 2005 Andrey Grozin
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "mathlink.h"
16
17 #define CLOSED 11L
18 #define PRE_NAME "/plugins/mathematica/ps/pre"
19 #define POST_NAME "/plugins/mathematica/ps/post"
20 /* #define LOG "/tmp/log.mma" */
21 /* #define LOG_PS "/tmp/log.ps" */
22
23 #ifdef LOG
24 static FILE *log;
25 #endif
26 #ifdef LOG_PS
27 static FILE *psfile;
28 #endif
29
30 MLENV env =(MLENV)0;
31 MLINK link=(MLINK)0;
32 static size_t size=128;
33 static char *input,*pre_name,*post_name;
34 static int protect_hat=0;
35
texput(char * s)36 static void texput(char *s) {
37 char c; int n,nl;
38 nl=0;
39 while (c=*(s++)) {
40 if (c=='\\') {
41 c=*(s++);
42 if ((c>='0')&&(c<='9')) {
43 n=c-'0';
44 while (1) {
45 c=*(s++);
46 if ((c<'0')||(c>'9')) {
47 if (n==0x0a) { putchar(' '); nl=1; }
48 else putchar(n);
49 if (c)
50 if (nl)
51 if (c=='>') nl=0;
52 else if (c>' ') { putchar(c); nl=1; }
53 else if (protect_hat&&(c=='^')) putchar(' ');
54 else putchar(c);
55 break;
56 } else n=8*n+(c-'0');
57 }
58 if (c=='\0') break;
59 } else if (protect_hat&&(c=='^')) putchar(' ');
60 else putchar(c);
61 } else if (nl) {
62 if (c=='>') nl=0;
63 else if (c>' ') {
64 if (protect_hat&&(c=='^')) putchar(' ');
65 else putchar(c);
66 nl=1;
67 }
68 } else if (protect_hat&&(c=='^')) putchar(' ');
69 else putchar(c);
70 }
71 }
72
psput(char * s)73 static void psput(char *s) {
74 char c; int n,l;
75 while (c=*(s++)) {
76 if (c=='\\') {
77 c=*(s++);
78 if ((c>='0')&&(c<='7')) {
79 l=0; n=c-'0';
80 while (1) {
81 l++; c=*(s++);
82 if ((l>=3)||(c<'0')||(c>'7')) {
83 putchar(n);
84 #ifdef LOG_PS
85 fputc(n,psfile);
86 #endif
87 if (c) {
88 putchar(c);
89 #ifdef LOG_PS
90 fputc(c,psfile);
91 #endif
92 }
93 break;
94 } else n=8*n+(c-'0');
95 }
96 if (c=='\0') break;
97 } else {
98 putchar(c);
99 #ifdef LOG_PS
100 fputc(c,psfile);
101 #endif
102 }
103 } else {
104 putchar(c);
105 #ifdef LOG_PS
106 fputc(c,psfile);
107 #endif
108 }
109 }
110 }
111
prelude(char * name)112 static void prelude(char *name) {
113 FILE *ps=fopen(name,"r");
114 char(c);
115 while (1) {
116 c=getc(ps);
117 if (c==EOF) break;
118 putchar(c);
119 #ifdef LOG_PS
120 fputc(c,psfile);
121 #endif
122 }
123 fclose(ps);
124 }
125
command(char * s)126 static void command(char *s) {
127 int pkt,more,non_ps,msg; long err;
128 char *result,*symbol;
129 fputs("\2latex:",stdout);
130 MLPutFunction(link,"EvaluatePacket",1L);
131 MLPutFunction(link,"Print",1L);
132 MLPutFunction(link,"TeXForm",1L);
133 MLPutFunction(link,"ToExpression",1L);
134 MLPutString(link,s);
135 MLEndPacket(link);
136 more=1; non_ps=1; msg=0;
137 do {
138 switch (pkt=MLNextPacket(link)) {
139 case RETURNPKT:
140 #ifdef LOG
141 fputs("RETURNPKT\n",log); fflush(log);
142 #endif
143 more=0;
144 break;
145 case RETURNTEXTPKT:
146 MLGetString(link,&result);
147 #ifdef LOG
148 fprintf(log,"RETURNTEXTPKT: \"%s\"\n",result); fflush(log);
149 #endif
150 MLDisownString(link,result);
151 more=0;
152 break;
153 case INPUTNAMEPKT:
154 MLGetString(link,&result);
155 #ifdef LOG
156 fprintf(log,"INPUTNAMEPKT: \"%s\"\n",result); fflush(log);
157 #endif
158 MLDisownString(link,result);
159 break;
160 case OUTPUTNAMEPKT:
161 MLGetString(link,&result);
162 #ifdef LOG
163 fprintf(log,"OUTPUTNAMEPKT: \"%s\"\n",result); fflush(log);
164 #endif
165 MLDisownString(link,result);
166 break;
167 case TEXTPKT:
168 MLGetString(link,&result);
169 #ifdef LOG
170 fprintf(log,"TEXTPKT: \"%s\"\n",result); fflush(log);
171 #endif
172 if (msg) {
173 fputs("{\\magenta ",stdout);
174 protect_hat=1; texput(result);
175 fputs("}\n\n",stdout);
176 protect_hat=0; msg=0;
177 } else {
178 fputs("$\\displaystyle ",stdout);
179 texput(result);
180 fputs("$",stdout);
181 }
182 MLDisownString(link,result);
183 break;
184 case MESSAGEPKT:
185 MLGetSymbol(link,&symbol);
186 MLGetString(link,&result);
187 #ifdef LOG
188 fprintf(log,"MESSAGEPKT: \"%s\" \"%s\"\n",symbol,result); fflush(log);
189 #endif
190 MLDisownSymbol(link,symbol);
191 MLDisownString(link,result);
192 msg=1;
193 break;
194 case DISPLAYPKT:
195 MLGetString(link,&result);
196 #ifdef LOG
197 fprintf(log,"DISPLAYPK: \"%s\"\n",result); fflush(log);
198 #endif
199 if (non_ps) {
200 fputs("\2ps:",stdout);
201 #ifdef LOG_PS
202 psfile=fopen(LOG_PS,"w");
203 #endif
204 prelude(pre_name); non_ps=0;
205 }
206 psput(result);
207 MLDisownString(link,result);
208 break;
209 case DISPLAYENDPKT:
210 MLGetString(link,&result);
211 #ifdef LOG
212 fprintf(log,"DISPLAYENDPKT: \"%s\"\n",result); fflush(log);
213 #endif
214 psput(result);
215 prelude(post_name);
216 fputs("\5{}{}\n\n",stdout);
217 #ifdef LOG_PS
218 fclose(psfile);
219 #endif
220 non_ps=1;
221 MLDisownString(link,result);
222 break;
223 case INPUTPKT:
224 MLGetString(link,&result);
225 #ifdef LOG
226 fprintf(log,"INPUTPKT: \"%s\"\n",result); fflush(log);
227 #endif
228 printf("\2prompt#\\red %s{}\5\5",result);
229 fflush(stdout);
230 MLDisownString(link,result);
231 if (getline(&input,&size,stdin)>=0) command(input);
232 break;
233 case CALLPKT:
234 #ifdef LOG
235 fputs("CALLPKT\n",log); fflush(log);
236 #endif
237 break;
238 default:
239 #ifdef LOG
240 fprintf(log,"UNKNOWN PACKET: %1d\n",pkt); fflush(log);
241 #endif
242 break;
243 }
244 MLNewPacket(link);
245 err=MLError(link);
246 if (err==CLOSED) {
247 fputs("\\red The end\5",stdout);
248 MLClose(link);
249 MLDeinitialize(env);
250 exit(0);
251 } else if (err) {
252 printf("\\red Error %1d: %s\5",err,MLErrorMessage(link));
253 exit(1);
254 }
255 } while (more);
256 }
257
main(int argc,char * argv[])258 int main(int argc, char *argv[]) {
259 long err;
260 size_t InNum=1,l;
261 char *tm_path;
262 #ifdef LOG
263 log=fopen(LOG,"w");
264 #endif
265
266 tm_path=getenv("TEXMACS_PATH");
267 if (tm_path==NULL) exit(1);
268 l=strlen(tm_path);
269 pre_name=malloc(l+strlen(PRE_NAME)+1);
270 post_name=malloc(l+strlen(POST_NAME)+1);
271 strcpy(pre_name,tm_path); strcpy(pre_name+l,PRE_NAME);
272 strcpy(post_name,tm_path); strcpy(post_name+l,POST_NAME);
273
274 input=(char*)malloc(size);
275
276 env=MLInitialize((MLParametersPointer)0);
277 if (env==(MLENV)0) {
278 fputs("\2latex:\\red Initialization of MathLink failed\5",stdout);
279 exit(1);
280 }
281
282 link=MLOpenString(env,"-linkname \"math -mathlink\"",&err);
283 if (link==(MLINK)0) {
284 fputs("\2latex:\\red Link with Mathematica failed",stdout);
285 MLDeinitialize(env);
286 exit(1);
287 }
288
289 fputs("\2latex:\\red Mathematica",stdout);
290
291 while (1) {
292 /* Prompt */
293 printf("\2prompt#\\red In[%1d]:= {}\5\5",InNum++);
294 fflush(stdout);
295 if (getline(&input,&size,stdin)>=0) command(input);
296 }
297
298 return 0;
299 }
300