Back to index

texmacs  1.0.7.15
tm_mathematica.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_mathematica.c
00004 * DESCRIPTION: Interface with Mathematica
00005 * COPYRIGHT  : (C) 2005  Andrey Grozin
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include "mathlink.h"
00016 
00017 #define CLOSED 11L
00018 #define PRE_NAME  "/plugins/mathematica/ps/pre"
00019 #define POST_NAME "/plugins/mathematica/ps/post"
00020 /* #define LOG "/tmp/log.mma"   */
00021 /* #define LOG_PS "/tmp/log.ps" */
00022 
00023 #ifdef LOG
00024 static FILE *log;
00025 #endif
00026 #ifdef LOG_PS
00027 static FILE *psfile;
00028 #endif
00029 
00030 MLENV env =(MLENV)0;
00031 MLINK link=(MLINK)0;
00032 static size_t size=128;
00033 static char *input,*pre_name,*post_name;
00034 static int protect_hat=0;
00035 
00036 static void texput(char *s) {
00037   char c; int n,nl;
00038   nl=0;
00039   while (c=*(s++)) {
00040     if (c=='\\') {
00041       c=*(s++);
00042       if ((c>='0')&&(c<='9')) {
00043        n=c-'0';
00044        while (1) {
00045          c=*(s++);
00046          if ((c<'0')||(c>'9')) {
00047            if (n==0x0a) { putchar(' '); nl=1; }
00048            else putchar(n);
00049            if (c)
00050              if (nl)
00051               if (c=='>') nl=0;
00052               else if (c>' ') { putchar(c); nl=1; }
00053              else if (protect_hat&&(c=='^')) putchar(' ');
00054              else putchar(c);
00055            break;
00056          } else n=8*n+(c-'0');
00057        }
00058        if (c=='\0') break;
00059       } else if (protect_hat&&(c=='^')) putchar(' ');
00060       else putchar(c);
00061     } else if (nl) {
00062       if (c=='>') nl=0;
00063       else if (c>' ') {
00064        if (protect_hat&&(c=='^')) putchar(' ');
00065        else putchar(c);
00066        nl=1;
00067       }
00068     } else if (protect_hat&&(c=='^')) putchar(' ');
00069     else putchar(c);
00070   }
00071 }
00072 
00073 static void psput(char *s) {
00074   char c; int n,l;
00075   while (c=*(s++)) {
00076     if (c=='\\') {
00077       c=*(s++);
00078       if ((c>='0')&&(c<='7')) {
00079        l=0; n=c-'0';
00080        while (1) {
00081          l++; c=*(s++);
00082          if ((l>=3)||(c<'0')||(c>'7')) {
00083            putchar(n);
00084 #ifdef LOG_PS
00085            fputc(n,psfile);
00086 #endif
00087            if (c) {
00088              putchar(c);
00089 #ifdef LOG_PS
00090              fputc(c,psfile);
00091 #endif
00092            }
00093            break;
00094          } else n=8*n+(c-'0');
00095        }
00096        if (c=='\0') break;
00097       } else {
00098        putchar(c);
00099 #ifdef LOG_PS
00100        fputc(c,psfile);
00101 #endif
00102       }
00103     } else {
00104       putchar(c);
00105 #ifdef LOG_PS
00106       fputc(c,psfile);
00107 #endif
00108     }
00109   }
00110 }
00111 
00112 static void prelude(char *name) {
00113   FILE *ps=fopen(name,"r");
00114   char(c);
00115   while (1) {
00116     c=getc(ps);
00117     if (c==EOF) break;
00118     putchar(c);
00119 #ifdef LOG_PS
00120     fputc(c,psfile);
00121 #endif
00122   }
00123   fclose(ps);
00124 }
00125 
00126 static void command(char *s) {
00127   int pkt,more,non_ps,msg; long err;
00128   char *result,*symbol;
00129   fputs("\2latex:",stdout);
00130   MLPutFunction(link,"EvaluatePacket",1L);
00131   MLPutFunction(link,"Print",1L);
00132   MLPutFunction(link,"TeXForm",1L);
00133   MLPutFunction(link,"ToExpression",1L);
00134   MLPutString(link,s);
00135   MLEndPacket(link);
00136   more=1; non_ps=1; msg=0;
00137   do {
00138     switch (pkt=MLNextPacket(link)) {
00139     case RETURNPKT:
00140 #ifdef LOG
00141       fputs("RETURNPKT\n",log); fflush(log);
00142 #endif
00143       more=0;
00144       break;
00145     case RETURNTEXTPKT:
00146       MLGetString(link,&result);
00147 #ifdef LOG
00148       fprintf(log,"RETURNTEXTPKT: \"%s\"\n",result); fflush(log);
00149 #endif
00150       MLDisownString(link,result);
00151       more=0;
00152       break;
00153     case INPUTNAMEPKT:
00154       MLGetString(link,&result);
00155 #ifdef LOG
00156       fprintf(log,"INPUTNAMEPKT: \"%s\"\n",result); fflush(log);
00157 #endif
00158       MLDisownString(link,result);
00159       break;
00160     case OUTPUTNAMEPKT:
00161       MLGetString(link,&result);
00162 #ifdef LOG
00163       fprintf(log,"OUTPUTNAMEPKT: \"%s\"\n",result); fflush(log);
00164 #endif
00165       MLDisownString(link,result);
00166       break;
00167     case TEXTPKT:
00168       MLGetString(link,&result);
00169 #ifdef LOG
00170       fprintf(log,"TEXTPKT: \"%s\"\n",result); fflush(log);
00171 #endif
00172       if (msg) {
00173        fputs("{\\magenta ",stdout);
00174        protect_hat=1; texput(result);
00175        fputs("}\n\n",stdout);
00176        protect_hat=0; msg=0;
00177       } else {
00178        fputs("$\\displaystyle ",stdout);
00179        texput(result);
00180        fputs("$",stdout);
00181       }
00182       MLDisownString(link,result);
00183       break;
00184     case MESSAGEPKT:
00185       MLGetSymbol(link,&symbol);
00186       MLGetString(link,&result);
00187 #ifdef LOG
00188       fprintf(log,"MESSAGEPKT: \"%s\"  \"%s\"\n",symbol,result); fflush(log);
00189 #endif
00190       MLDisownSymbol(link,symbol);
00191       MLDisownString(link,result);
00192       msg=1;
00193       break;
00194     case DISPLAYPKT:
00195       MLGetString(link,&result);
00196 #ifdef LOG
00197       fprintf(log,"DISPLAYPK: \"%s\"\n",result); fflush(log);
00198 #endif
00199       if (non_ps) {
00200        fputs("\2ps:",stdout);
00201 #ifdef LOG_PS
00202        psfile=fopen(LOG_PS,"w");
00203 #endif
00204        prelude(pre_name); non_ps=0;
00205       }
00206       psput(result);
00207       MLDisownString(link,result);
00208       break;
00209     case DISPLAYENDPKT:
00210       MLGetString(link,&result);
00211 #ifdef LOG
00212       fprintf(log,"DISPLAYENDPKT: \"%s\"\n",result); fflush(log);
00213 #endif
00214       psput(result);
00215       prelude(post_name);
00216       fputs("\5{}{}\n\n",stdout);
00217 #ifdef LOG_PS
00218       fclose(psfile);
00219 #endif
00220       non_ps=1;
00221       MLDisownString(link,result);
00222       break;
00223     case INPUTPKT:
00224       MLGetString(link,&result);
00225 #ifdef LOG
00226       fprintf(log,"INPUTPKT: \"%s\"\n",result); fflush(log);
00227 #endif
00228       printf("\2prompt#\\red %s{}\5\5",result);
00229       fflush(stdout);
00230       MLDisownString(link,result);
00231       if (getline(&input,&size,stdin)>=0) command(input);
00232       break;
00233     case CALLPKT:
00234 #ifdef LOG
00235       fputs("CALLPKT\n",log); fflush(log);
00236 #endif
00237       break;
00238     default:
00239 #ifdef LOG
00240       fprintf(log,"UNKNOWN PACKET: %1d\n",pkt); fflush(log);
00241 #endif
00242       break;
00243     }
00244     MLNewPacket(link);
00245     err=MLError(link);
00246     if (err==CLOSED) {
00247       fputs("\\red The end\5",stdout);
00248       MLClose(link);
00249       MLDeinitialize(env);
00250       exit(0);
00251     } else if (err) {
00252       printf("\\red Error %1d: %s\5",err,MLErrorMessage(link));
00253       exit(1);
00254     }
00255   } while (more);
00256 }
00257 
00258 int main(int argc, char *argv[]) {
00259   long err;
00260   size_t InNum=1,l;
00261   char *tm_path;
00262 #ifdef LOG
00263   log=fopen(LOG,"w");
00264 #endif
00265 
00266   tm_path=getenv("TEXMACS_PATH");
00267   if (tm_path==NULL) exit(1);
00268   l=strlen(tm_path);
00269   pre_name=malloc(l+strlen(PRE_NAME)+1);
00270   post_name=malloc(l+strlen(POST_NAME)+1);
00271   strcpy(pre_name,tm_path);  strcpy(pre_name+l,PRE_NAME);
00272   strcpy(post_name,tm_path); strcpy(post_name+l,POST_NAME);
00273 
00274   input=(char*)malloc(size);
00275 
00276   env=MLInitialize((MLParametersPointer)0);
00277   if (env==(MLENV)0) {
00278     fputs("\2latex:\\red Initialization of MathLink failed\5",stdout);
00279     exit(1);
00280   }
00281 
00282   link=MLOpenString(env,"-linkname \"math -mathlink\"",&err);
00283   if (link==(MLINK)0) {
00284     fputs("\2latex:\\red Link with Mathematica failed",stdout);
00285     MLDeinitialize(env);
00286     exit(1);
00287   }
00288 
00289   fputs("\2latex:\\red Mathematica",stdout);
00290 
00291   while (1) {
00292     /* Prompt */
00293     printf("\2prompt#\\red In[%1d]:= {}\5\5",InNum++);
00294     fflush(stdout);
00295     if (getline(&input,&size,stdin)>=0) command(input);
00296   }
00297 
00298   return 0;
00299 }