Back to index

texmacs  1.0.7.15
tm_axiom.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_axiom.c
00004 * DESCRIPTION: Glue between TeXmacs and Axiom
00005 * COPYRIGHT  : (C) 1999  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 <unistd.h>
00016 
00017 #define NORMAL 0
00018 #define LONG   1
00019 #define END    2
00020 #define PROMPT 3
00021 #define MATH   4
00022 #define TYPE   5
00023 
00024 #define LEN 256
00025 /* #define LOG "/tmp/tm_axiom.log" */
00026 
00027 char buf[LEN];
00028 char mathbuf[4096];
00029 int len,code,writing=0,wait_type=0,mmode=0; /* was writing=1 */
00030 char prompt[]="-> ";
00031 char math[]="$$\n";
00032 char Type[]="Type: ";
00033 FILE *axin,*axout;
00034 
00035 #ifdef LOG
00036 FILE *log;
00037 int details=0;
00038 
00039 void lline(void)
00040 { switch (code)
00041   { case NORMAL: fputs("NORMAL",log); break;
00042     case LONG:   fputs("LONG  ",log); break;
00043     case END:    fputs("END   ",log); break;
00044     case PROMPT: fputs("PROMPT",log); break;
00045     case MATH:   fputs("MATH  ",log); break;
00046     case TYPE:   fputs("TYPE  ",log); break;
00047   }
00048   fprintf(log," %3d: ",len);
00049   fputs(buf,log);
00050   if ((code==PROMPT)||(code==MATH)) fputs("\n",log);
00051   fflush(log);
00052 }
00053 #endif
00054 
00055 int ch(void)
00056 { char c;
00057   while (1)
00058   { c=getc(axout);
00059 #ifdef LOG
00060     if (details)
00061     { fprintf(log,"%02x",c);
00062       if (c>=' ') fprintf(log," [%c]",c);
00063       fprintf(log,"\n"); fflush(log);
00064     }
00065 #endif
00066     if (c!='\r') return c;
00067   }
00068 }
00069 
00070 void tail(void)
00071 { int c;
00072   while (1)
00073   { c=ch();
00074     if (c==EOF) { code=END; break; }
00075     else if (c=='\r')
00076     { c=ch();
00077       if (c==EOF) { code=END; break; }
00078       else if (c=='\n') { if (writing) putchar('\n'); break; }
00079       else if (writing) putchar(c);
00080     }
00081     else if (writing) putchar(c);
00082   }
00083 }
00084 
00085 void iline(void)
00086 { int i=0,j=0,k,c;
00087   while (1)
00088   { c=ch();
00089     if (c==prompt[j])
00090       if (j==2) { code=PROMPT; break; } else j++;
00091     else
00092     { for (k=0;k<j;) buf[i++]=prompt[k++];
00093       j=0;
00094       if (i>LEN-4) { code=LONG; break; }
00095       else if (c==EOF) { code=END; break; }
00096       else if (c=='\n') { buf[i++]='\n'; code=NORMAL; break; }
00097       else buf[i++]=c;
00098     }
00099   }
00100   buf[i]='\0'; len=i;
00101   if (len==78)
00102   if (buf[77]=='\n')
00103   { j=1;
00104     for (k=0;k<76;k++) if (buf[k]!='-') { j=0; break; }
00105     if (j) code=TYPE;
00106   }
00107 #ifdef LOG
00108   lline();
00109 #endif
00110   if (code==PROMPT) return;
00111   if (writing) fputs(buf,stdout);
00112   if (code==LONG) tail();
00113   if (code==END)
00114   { fputs("\n\2latex:\\red Unexpected end\\black5\5",stdout);
00115     exit(1);
00116   }
00117   if (code==LONG) code=NORMAL;
00118 }
00119 
00120 void line(void)
00121 { int i=0,j,k,c; char *s;
00122   code=NORMAL; c=ch();
00123   if (c==EOF) code=END;
00124   else if (c=='-')
00125   { j=1;
00126     while (1)
00127     { c=ch();
00128       if (c==prompt[j])
00129         if (j==2) { code=PROMPT; break; } else j++;
00130       else
00131       { for (k=0;k<j;) buf[i++]=prompt[k++];
00132         break;
00133       }
00134     }
00135   }
00136   else if (c=='$')
00137   { j=1;
00138     while (1)
00139     { c=ch();
00140       if (c==math[j])
00141         if (j==2) { code=MATH; break; } else j++;
00142       else
00143       { for (k=0;k<j;) buf[i++]=math[k++];
00144         buf[i++]=c;
00145       }
00146     }
00147   }
00148   if (c!=EOF) buf[i++]=c;
00149   if ((code==PROMPT)||(code==MATH)||(code==END))
00150   { buf[i]='\0'; len=i;
00151 #ifdef LOG
00152     lline();
00153 #endif
00154     return;
00155   }
00156   while (1)
00157   { if (i>LEN-2) { code=LONG; break; }
00158     else if (c=='\n') break;
00159     c=ch();
00160     if (c==EOF) { code=END; break; }
00161     else buf[i++]=c;
00162   }
00163   buf[i]='\0'; len=i;
00164 #ifdef LOG
00165   lline();
00166 #endif
00167   if (/*wait_type && */(code==NORMAL))
00168   { if (len==1) return;
00169     wait_type=0;
00170     if (len==78)
00171     { for (s=buf,k=0;k<len-7;s++,k++) if ((*s)!=' ') break;
00172       for (k=0;k<6;s++,k++) if ((*s)!=Type[k]) break;
00173       if (k==6)
00174       { /* buf[77]='\0'; */
00175        wait_type=1;
00176         printf("\2latex:\\axiomtype{%s}\5",s);
00177         return;
00178       }
00179     }
00180   };
00181   if (wait_type) printf("\2latex:\\red$\\rightarrow$\\black\\ \5");
00182   if (mmode) {
00183     strcat(mathbuf,buf);
00184   } else {
00185     fputs(buf,stdout);
00186   };
00187   if (code==LONG) tail();
00188   if (code==LONG) code=NORMAL;
00189 }
00190 
00191 void must_be_prompt(char *mess)
00192 { iline();
00193   if (code!=PROMPT)
00194   { printf("\2latex:\\red Cannot get prompt %s\\black\5\5",mess);
00195     exit(1);
00196   }
00197 }
00198 
00199 void tex_to_latex(char buf[])
00200 {
00201   char *ptr1, *ptr2;
00202 
00203   while ((ptr1=strchr(buf,'\n'))) { strcpy(ptr1,ptr1+1); };
00204   while ((ptr1=strstr(buf,"\\root {"))) {
00205     if ((ptr2=strstr(ptr1,"} \\of "))) {
00206       strncpy(ptr1,"\\sqrt[",6);
00207       strncpy(ptr1+6,ptr1+7,ptr2-ptr1-7);
00208       strncpy(ptr1+6+(ptr2-ptr1-7),"]",1);
00209       strcpy(ptr1+7+(ptr2-ptr1-7),ptr2+6);
00210     }
00211   }
00212 }
00213 
00214 void session(void)
00215 { int c,delims=0;
00216 #ifdef LOG
00217   log=fopen(LOG,"w");
00218 #endif
00219   /* Write initial lines up to (but not including)
00220      the line with the first prompt
00221   */
00222   fputs("\2verbatim:",stdout);
00223   while (1)
00224   { iline();
00225     if (code==TYPE) { if ((++delims)==2) writing=0; }
00226     else if (code==PROMPT) break;
00227   }
00228   /* force-feeding */
00229   fputs(")set messages prompt plain\n",axin); fflush(axin);
00230 #ifdef LOG
00231   fputs("SENT )set messages prompt plain\n",log); fflush(log);
00232 #endif
00233   must_be_prompt("0");
00234   fputs(")set messages autoload off\n",axin); fflush(axin);
00235 #ifdef LOG
00236   fputs("SENT )set messages autoload off\n",log); fflush(log);
00237 #endif
00238   must_be_prompt("1");
00239   fputs(")set quit unprotected\n",axin); fflush(axin);
00240 #ifdef LOG
00241   fputs("SENT )set quit unprotected\n",log); fflush(log);
00242 #endif
00243   must_be_prompt("2");
00244   fputs(")set output tex on\n",axin); fflush(axin);
00245 #ifdef LOG
00246   fputs("SENT )set output tex on\n",log); fflush(log);
00247 #endif
00248   must_be_prompt("3");
00249   fputs(")set output algebra off\n",axin); fflush(axin);
00250 #ifdef LOG
00251   fputs("SENT )set output algebra off\n",log); fflush(log);
00252 #endif
00253   must_be_prompt("4");
00254   /* Main prompt-read-write loop */
00255   while (1)
00256   { fputs("\2channel:prompt\5\2latex:\\red$\\rightarrow$\\ \5\5",stdout);
00257     fflush(stdout);
00258     fputs("\2verbatim:",stdout);
00259     while (1)
00260     { c=getchar();
00261       if ((c==EOF)||(c=='\n')) break;
00262       putc(c,axin);
00263     }
00264     if (c==EOF) fputs(")quit\n",axin);
00265     else putc('\n',axin);
00266     fflush(axin);
00267     mmode=0;
00268     while (1)
00269     { line();
00270       if ((code==PROMPT)||(code==END)) break;
00271       if (code==MATH) {
00272         if (mmode) { /* convert TeX to LaTex etc. */
00273          tex_to_latex(mathbuf);
00274          fputs(mathbuf,stdout);
00275          mmode=0; wait_type=1; fputs("$\5\n",stdout);
00276               } else {
00277          strcpy(mathbuf,"");
00278          mmode=1; fputs("\2latex:$\\displaystyle\n",stdout);
00279               }
00280      };
00281     }
00282     if (code==END) break;
00283   }
00284   fputs("\2latex:\\red The end\\black\5\5",stdout);
00285 }
00286 
00287 void fatal(char *mess)
00288 { fprintf(stdout,"\2latex:\\red Cannot %s\\black\5\5",mess);
00289   exit(1);
00290 }
00291 
00292 int main()
00293 { int p1[2],p2[2];
00294   if (pipe(p1)<0) fatal("create pipe");
00295   if (pipe(p2)<0) fatal("create pipe");
00296   switch (fork())
00297   { case -1: fatal("fork");
00298     case 0: /* Axiom */
00299       dup2(p1[1],1); close(p1[1]); close(p1[0]);
00300       dup2(p2[0],0); close(p2[0]); close(p2[1]);
00301       execlp("AXIOMsys","AXIOMsys","-noclef",NULL);
00302       fatal("exec AXIOMsys");
00303     default: /* parent */
00304       close(p1[1]); close(p2[0]);
00305       axin=fdopen(p2[1],"w"); axout=fdopen(p1[0],"r");
00306       session();
00307   }
00308   return 0;
00309 }