mailing-list for TeXmacs Users

Text archives Help


Re: [TeXmacs] Mathematica plugin with Graphics


Chronological Thread 
  • From: Tian-Min Yan <address@hidden>
  • To: address@hidden
  • Subject: Re: [TeXmacs] Mathematica plugin with Graphics
  • Date: Wed, 31 Oct 2012 11:35:52 +0100

Hi all,

Now I know how to output PS/EPS graphics. According to the manual
section "Interfering TeXmacs with other programs", I simply put

fputs("\2ps:", stdout);
fflush(stdout);
system("cat ~/tmp.eps");
fputs("\5{}{}\n\n", stdout);

into the code (see the attachment), now the EPS figure shows up. Can we
adjust the size and the position of the figure within TeXmacs?

Besides, I am wondering if we can display a PNG file, since those
rasterized formats have significantly smaller size and the program runs
faster. We should be able to choose between different formats to meet
different purposes.

One more question, can anybody who is familiar with Mathematica figure
out why "Export["./tmp.eps", expr]" sometimes outputs figures in the
wrong position, as is shown in the attachment where the main part is not
at the center? In contrast, PNG file does not have this problem.

Best,
Tian-Min

On Tue, 2012-10-30 at 19:01 +0100, address@hidden
wrote:
> Hi Tian-Min,
>
> The plugin worked perfectly for graphics in old times when Mathematica
> produced pure postscript graphics (this was in versions <=5).
> If you are happy with the old-style Mathematica graphics, in your
> mathematica session simply evaluate : Get["Version5`Graphics`"]
> and then the plugin will recognize the ps graphics and show them in
> TeXmacs (but only for old -or unchanged- graphics functions, old options
> etc.)
>
> It would be nice to benefit from the new mathematica graphics, but that
> would require someone to volunteer for improving the plugin in that area.
>
> Best,
> Philippe
>
>
> Tian-Min Yan - address@hidden wrote:
> > Hi all,
> >
> > I am using Mathematica 8. The Mathematica plugin in TeXmacs works
> > perfectly with a single expression if it does not contain graphical
> > elements. But if we use functions involving plots, the output is
> > problematic. Has anybody figured out the implementation of embedded
> > figures with the Mathematica plugin?
> >
> > Best,
> > Tian-Min
> >
> >
> >
> >
>


Attachment: texmacs_wrong_position.png
Description: PNG image

/******************************************************************************
 * MODULE     : tm_mathematica.c
 * DESCRIPTION: Interface with Mathematica
 * COPYRIGHT  : (C) 2005  Andrey Grozin
 *******************************************************************************
 * This software falls under the GNU general public license version 3 or later.
 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 ******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mathlink.h"

#define CLOSED 11L
#define PRE_NAME  "/plugins/mathematica/ps/pre"
#define POST_NAME "/plugins/mathematica/ps/post"
#define LOG "./log.mma"
// #define LOG_PS "./log.ps"
/* MODIFY THE EXTENSION TO EXPORT DIFFERENT FORMAT*/
#define FIG_NAME "./tmp.eps" 

#ifdef LOG
static FILE *log;
#endif
#ifdef LOG_PS
static FILE *psfile;
#endif

MLENV env =(MLENV)0;
MLINK link=(MLINK)0;
static size_t size=128;
static char *input,*pre_name,*post_name;
static char *mls_buf;
static int protect_hat=0;

static void texput(char *s, FILE* fid) {
  char c; int n,nl; char* pc;
  nl=0; pc=s;
  while( (c=*(s++)) ) {
    if (c=='\\') {
      c=*(s++);
      if ((c>='0')&&(c<='9')) {
	n=c-'0';
	while (1) {
	  c=*(s++);
	  if ((c<'0')||(c>'9')) {
	    if (n==0x0a) { putc(' ', fid); *(pc++) = ' '; nl=1; }
	    else { putc(n, fid); *(pc++) = n; }
	    if (c)
	      if (nl) {
		if (c=='>') nl=0;
		else if (c>' ') { putc(c, fid); *(pc++) = c; nl=1; }
		else if (protect_hat&&(c=='^')) { putc(' ', fid); *(pc++) = ' '; }
		else {putc(c, fid); *(pc++) = c;}
	      }
	    break;
	  } else n=8*n+(c-'0');
	}
	if (c=='\0') {*(pc++) = '\0'; break;}
      } else if (protect_hat&&(c=='^')) {putc(' ', fid); *(pc++) = ' ';}
      else {putc(c, fid); *(pc++) = c;}
    } else if (nl) {
      if (c=='>') nl=0;
      else if (c>' ') {
	if (protect_hat&&(c=='^')) { putc(' ', fid); *(pc++) = ' '; }
	else { putc(c, fid); *(pc++) = c;}
	nl=1;
      }
    } else if (protect_hat&&(c=='^')) { putc(' ', fid); *(pc++) = ' '; }
    else {putc(c, fid); *(pc++) = c;}
  }
}

static void psput(char *s) {
  char c; int n,l; char* pc;
  pc = s;
  while( ( c=*(s++) ) ) {
    if (c=='\\') {
      c=*(s++);
      if ((c>='0')&&(c<='7')) {
	l=0; n=c-'0';
	while (1) {
	  l++; c=*(s++);
	  if ((l>=3)||(c<'0')||(c>'7')) {
	    putchar(n);
	    *(pc++) = n;
#ifdef LOG_PS
	    fputc(n,psfile);
#endif
	    if (c) {
	      putchar(c);
	      *(pc++) = c;
#ifdef LOG_PS
	      fputc(c,psfile);
#endif
	    }
	    break;
	  } else n=8*n+(c-'0');
	}
	if (c=='\0') {*(pc++)='\0'; break;}
      } else {
	putchar(c);
	*(pc++) = c;
#ifdef LOG_PS
	fputc(c,psfile);
#endif
      }
    } else {
      putchar(c);
      *(pc++) = c;
#ifdef LOG_PS
      fputc(c,psfile);
#endif
    }
  }
}

static void prelude(char *name) {
  FILE *ps=fopen(name,"r");
  char(c);
  while (1) {
    c=getc(ps);
    if (c==EOF) break;
    putchar(c);
#ifdef LOG_PS
    fputc(c,psfile);
#endif
  }
  fclose(ps);
}

static void regularize(char* s) 
{
  /* delete '\\\012' and '\012>' */
  char c; char* pc;
  pc=s;
  while( (c=*(s++)) ) {
    if(c=='\\') {
      c=*(s++);
      if(c=='\\') { s+=5; }
      else if((c<='9')&&(c>='0')) {
	while((c=*(s++))) { if(c=='>'||c==' ') break; }
      }
    }
    else *(pc++) = c;
  }
  *pc = '\0';
}

static void eps_to_string()
{
  FILE* f_ps; int c;
  
  fputs("ps:", stdout); fflush(stdout);
  if( ( f_ps = fopen(FIG_NAME, "r") ) ) {
    while((c=fgetc(f_ps)) != EOF) {
      putchar(c);
    }
    putchar( '\0' ); putchar( '\n' );
    fclose(f_ps);
  } else {
    fputs("Cannot open tmp.eps\n", stdout);
  }
}

static void evaluate(int type, char* s)
{
  int pkt,more,non_ps,msg; long err;
  char *result,*symbol;
  /* FILE* f_log; */

  MLPutFunction(link, "EvaluatePacket", 1L);
  switch(type) {
  case -1: /* No way! */
    exit(1);
  case 0: /* TeX */
    MLPutFunction(link, "Print", 1L);
    MLPutFunction(link, "TeXForm", 1L);
    MLPutFunction(link, "ToExpression", 1L);
    MLPutString(link,s);
    break;
  case 1: /* Graphics */
    regularize(s); /* remove control characters */
    /*    
	  f_log = fopen("./fig.log", "w");
	  fputs(s, f_log);
	  fclose(f_log);  
    */
    MLPutFunction(link, "Export", 2L);
    MLPutString(link, FIG_NAME);
    MLPutFunction(link, "ToExpression", 1L);
    MLPutString(link, s);
    break;
  }
  MLEndPacket(link);

  more=1; non_ps=1; msg=0;
  do {
    switch (pkt=MLNextPacket(link)) {
    case RETURNPKT:
#ifdef LOG
      fputs("RETURNPKT@evaluate\n\n",log); fflush(log);
#endif
      more=0; break;
    case RETURNTEXTPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"RETURNTEXTPKT@evaluate: \"%s\"\n\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      more=0; break;
    case INPUTNAMEPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"INPUTNAMEPKT@evaluate: \"%s\"\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      break;
    case OUTPUTNAMEPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"OUTPUTNAMEPKT@evaluate: \"%s\"\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      break;
    case TEXTPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"TEXTPKT@evaluate: \"%s\"\n",result); fflush(log);
#endif
      if (msg) {
	fputs("{\\magenta ",stdout);
	protect_hat=1; texput(result, stdout);
	fputs("}\n\n",stdout);
	protect_hat=0; msg=0;
      } else {
	
	switch(type) {
	case 0: /* TeX */
	  fputs("$\\displaystyle ",stdout);
	  texput(result, stdout);
	  fputs("$",stdout);
	  break;
	case 1: /* graphics */
	  break;
	default:
	  fputs("Oops, nothing happened...\n", stdout);
	  break;
	}
      }
      MLDisownString(link,result);
      break;
    case MESSAGEPKT:
      MLGetSymbol(link,(const char**)&symbol);
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"MESSAGEPKT@evaluate: \"%s\"  \"%s\"\n",symbol,result); fflush(log);
#endif
      MLDisownSymbol(link,symbol);
      MLDisownString(link,result);
      msg=1;
      break;
    case DISPLAYPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"DISPLAYPK@evaluate: \"%s\"\n",result); fflush(log);
#endif
      if (non_ps) {
	fputs("\2ps:",stdout);
#ifdef LOG_PS
	psfile=fopen(LOG_PS,"w");
#endif
	prelude(pre_name); non_ps=0;
      }
      psput(result);
      MLDisownString(link,result);
      break;
    case DISPLAYENDPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"DISPLAYENDPKT@evaluate: \"%s\"\n",result); fflush(log);
#endif
      psput(result);
      prelude(post_name);
      fputs("\5{}{}\n\n",stdout);
#ifdef LOG_PS
      fclose(psfile);
#endif
      non_ps=1;
      MLDisownString(link,result);
      break;
    case CALLPKT:
#ifdef LOG
      fputs("CALLPKT@evaluate\n",log); fflush(log);
#endif
      break;
    default:
#ifdef LOG
      fprintf(log,"UNKNOWN PACKET@evaluate: %1d\n",pkt); fflush(log);
#endif
      break;
    }
    MLNewPacket(link);
    err=MLError(link);
    if (err==CLOSED) {
      fputs("\\red The end\5",stdout);
      MLClose(link);
      MLDeinitialize(env);
      exit(0);
    } else if (err) {
      printf("\\red Error %ld: %s\5",err,MLErrorMessage(link));
      exit(1);
    }
  } while (more);

}

static void command(char *s) {
  int pkt,more,non_ps,msg, type, is_buf; long err;
  char *result,*symbol;
  fputs("\2latex:",stdout);
  MLPutFunction(link,"EvaluatePacket",1L);
  MLPutFunction(link,"Print",1L);
  //  MLPutFunction(link,"TeXForm",1L);
  MLPutFunction(link, "ExportString", 2L);
  MLPutFunction(link,"ToExpression",1L);
  MLPutString(link,s);
  MLPutString(link,"Text");
  MLEndPacket(link);
  more=1; non_ps=1; msg=0; type = 0; is_buf = 0;

  do {
    switch (pkt=MLNextPacket(link)) {
    case RETURNPKT:
#ifdef LOG
      fputs("RETURNPKT@command\n\n",log); fflush(log);
#endif
      more=0;
      break;
    case RETURNTEXTPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"RETURNTEXTPKT@command: \"%s\"\n\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      more=0;
      break;
    case INPUTNAMEPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"INPUTNAMEPKT@command: \"%s\"\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      break;
    case OUTPUTNAMEPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"OUTPUTNAMEPKT@command: \"%s\"\n",result); fflush(log);
#endif
      MLDisownString(link,result);
      break;
    case TEXTPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"TEXTPKT@command: \"%s\"\n",result); fflush(log);
#endif
      if (msg) {
	fputs("{\\magenta ",stdout);
	protect_hat=1; texput(result, stdout);
	fputs("}\n\n",stdout);
	protect_hat=0; msg=0;
      } else {
	
	if( is_buf ) {
	  fputs("TEXTPKT more than once?\n", stdout);
	  break;
	}
	if( ! ( mls_buf = (char*)malloc(strlen(result)+1) ) ) {
	  fputs("Cannot allocate memory for the returning TEXT packet.\n", stdout);
	  break;
	}
	is_buf = 1;
	
	strcpy(mls_buf, result);
	//	fputs("$\\displaystyle ",stdout);
	char* pKeyword;
	if( (pKeyword=strstr(mls_buf, "Graphics")) )
	  if( (mls_buf - pKeyword) == 0 )  { /* begin with keyword "Graphics" */
	    type = 1; fputs("Graphics\n", stdout); break;
	  }
	  
	// texput(result, stdout);
	//	fputs("$",stdout);
      }
      MLDisownString(link,result);
      break;
    case MESSAGEPKT:
      MLGetSymbol(link,(const char**)&symbol);
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"MESSAGEPKT@command: \"%s\"  \"%s\"\n",symbol,result); fflush(log);
#endif
      MLDisownSymbol(link,symbol);
      MLDisownString(link,result);
      msg=1;
      break;
    case DISPLAYPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"DISPLAYPK@command: \"%s\"\n",result); fflush(log);
#endif
      if (non_ps) {
	fputs("\2ps:",stdout);
#ifdef LOG_PS
	psfile=fopen(LOG_PS,"w");
#endif
	prelude(pre_name); non_ps=0;
      }
      psput(result);
      MLDisownString(link,result);
      break;
    case DISPLAYENDPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"DISPLAYENDPKT@command: \"%s\"\n",result); fflush(log);
#endif
      psput(result);
      prelude(post_name);
      fputs("\5{}{}\n\n",stdout);
#ifdef LOG_PS
      fclose(psfile);
#endif
      non_ps=1;
      MLDisownString(link,result);
      break;
    case INPUTPKT:
      MLGetString(link,(const char**)&result);
#ifdef LOG
      fprintf(log,"INPUTPKT@command: \"%s\"\n",result); fflush(log);
#endif
      printf("\2prompt#\\red %s{}\5\5",result);
      fflush(stdout);
      MLDisownString(link,result);
      if (getline(&input,&size,stdin)>=0) command(input);
      break;
    case CALLPKT:
#ifdef LOG
      fputs("CALLPKT@command\n",log); fflush(log);
#endif
      break;
    default:
#ifdef LOG
      fprintf(log,"UNKNOWN PACKET@command: %1d\n",pkt); fflush(log);
#endif
      break;
    }
    MLNewPacket(link);
    err=MLError(link);
    if (err==CLOSED) {
      fputs("\\red The end\5",stdout);
      MLClose(link);
      MLDeinitialize(env);
      exit(0);
    } else if (err) {
      printf("\\red Error %ld: %s\5",err,MLErrorMessage(link));
      exit(1);
    }
  } while (more);
  


  if(is_buf) {
    evaluate(type, mls_buf);
    free(mls_buf); is_buf = 0;
  }

  /* post-process, e.g., reading a generated figure */
  switch(type) {
  case 0: /* tex */
    break;
  case 1: /* figure */
    /* e.g., read the generated EPS file and dump to TeXmacs*/
    /* fputs("\2ps:",stdout); */
    /* prelude(pre_name); */
    /* eps_to_string(); */
    /* prelude(post_name); */
    /* fputs("\5{}{}\n\n",stdout);*/

    fputs("\2ps:", stdout);
    fflush(stdout);
    system("cat ~/tmp.eps");
    fputs("\5{}{}\n\n", stdout);


    /* or can use other methods, like loading .png, .svg., whatever */
    //fputs("$",stdout); 
    break;
  default:
    break;
  }
}



int main(int argc, char *argv[]) {
  int err;
  size_t InNum=1,l;
  char *tm_path;
#ifdef LOG
  log=fopen(LOG,"w");
#endif

  tm_path=getenv("TEXMACS_PATH");
  /* tm_path = (char*)"./"; */

  if (tm_path==NULL) exit(1);
  l=strlen(tm_path);
  pre_name=(char*)malloc(l+strlen(PRE_NAME)+1);
  post_name=(char*)malloc(l+strlen(POST_NAME)+1);
  strcpy(pre_name,tm_path);  strcpy(pre_name+l,PRE_NAME);
  strcpy(post_name,tm_path); strcpy(post_name+l,POST_NAME);

  input=(char*)malloc(size);

  env=MLInitialize((MLParametersPointer)0);
  if (env==(MLENV)0) {
    fputs("\2latex:\\red Initialization of MathLink failed\5",stdout);
    exit(1);
  }

  link=MLOpenString(env,"-linkname \"math -mathlink\"",&err);
  if (link==(MLINK)0) {
    fputs("\2latex:\\red Link with Mathematica failed",stdout);
    MLDeinitialize(env);
    exit(1);
  }

  fputs("\2latex:\\red Mathematica",stdout);

  while (1) {
    /* Prompt */
    printf("\2prompt#\\red In[%1d]:= {}\5\5",InNum++);
    fflush(stdout);
    if (getline(&input,&size,stdin)>=0) command(input);
  }

  return 0;
}



Archive powered by MHonArc 2.6.19.

Top of page