/* * mma2ltx.c - Copyright (C) 1994, 1995 by Giuseppe Ghibo` * * Written by Giuseppe Ghibo` * * Version 1.23 - 21 Jun 1995 * */ #include #include #include #include #include #include #include typedef int bool; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef min #define min(a, b) (a < b ? a : b) #endif #ifndef max #define max(a, b) (a > b ? a : b) #endif struct pnts { float gx, gy, tx, ty; }; struct point { float x, y; }; struct scaletrasl { float Ax, Ay, Bx, By; }; struct cw { float ctx, wtx, cgx, wgx, cty, wty, cgy, wgy; }; struct TeXunits { float convfactor; char *strunit; }; struct TeXunits TeXtable[] = { {72.0/25.4,"mm"}, /* mm to bp */ {72.0/2.54,"cm"}, /* cm to bp */ {72.0/72.27,"pt"}, /* pt to bp */ {1.0,"bp"}, /* bp to bp */ {72.0/72.27*12.0,"pc"}, /* pc to bp */ {72.0,"in"}, /* in to bp */ {1238.0/1157.0*72.0/72.27,"dd"}, /* dd to bp */ {1238.0/1157.0*12.0*72.0/72.27,"cc"}, /* cc to bp */ {72.0/72.27/65536.0,"sp"}, /* sp to bp */ {1.0,""} }; /* Function prototypes */ void Mlprun(float,float,struct cw *); void Mlp(float,float,struct scaletrasl *); void Mlp1(float,float,float,float,float,float,float *,float *,bool *); float strtobp(char *); float bptounit(char *); void stripext(char *,char *); char *strtolwr(char *); #ifdef MSDOS #define NMAX 1000 #else #define NMAX 10000 #endif /* MSDOS */ #define NMAXFILEIN 256 /* maximun number of files to process */ #define NMAXBBSUB 256 #define TMPLEN 1024 #define PROLOG "texmma22.pro" #define OPTSWITCH1 '-' #define OPTSWITCH2 '/' char tmpbuf1[TMPLEN], tmpbuf2[TMPLEN], fnametex[256], namebuf[256]; char errbuf[512]; struct pnts *p; bool Mnodistort = TRUE; /* keep the aspect ratio ? */ int np = 0; /* This is the Mathematica v2.2 prologue file (extracted) */ char prologue[] = { "/Mlmarg 0 def /Mrmarg 0 def /Mbmarg 0 def /Mtmarg 0 def /Mtransform{}\n" "bind def /Mfixwid true def /Mfixdash false def /Mrot 0 def /Mpstart{\n" "MathPictureStart}bind def /Mpend{MathPictureEnd}bind def /Mscale{0 1 0 1\n" "5 -1 roll MathScale}bind def /ISOLatin1Encoding dup where{pop pop}{[\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" "/space /exclam /quotedbl /numbersign /dollar /percent /ampersand\n" "/quoteright /parenleft /parenright /asterisk /plus /comma /minus /period\n" "/slash /zero /one /two /three /four /five /six /seven /eight /nine\n" "/colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F\n" "/G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft\n" "/backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d\n" "/e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z\n" "/braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /dotlessi /grave\n" "/acute /circumflex /tilde /macron /breve /dotaccent /dieresis /.notdef\n" "/ring /cedilla /.notdef /hungarumlaut /ogonek /caron /space /exclamdown\n" "/cent /sterling /currency /yen /brokenbar /section /dieresis /copyright\n" "/ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron\n" "/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph\n" "/periodcentered /cedilla /onesuperior /ordmasculine /guillemotright\n" "/onequarter /onehalf /threequarters /questiondown /Agrave /Aacute\n" "/Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute\n" "/Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth\n" "/Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n" "/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n" "/germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae\n" "/ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute\n" "/icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex\n" "/otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex\n" "/udieresis /yacute /thorn /ydieresis]def}ifelse /MFontDict 50 dict def\n" "/MStrCat{exch dup length 2 index length add string dup 3 1 roll copy\n" "length exch dup 4 2 roll exch putinterval}def /MCreateEncoding{1 index\n" "255 string cvs(-)MStrCat 1 index MStrCat cvn exch(Encoding)MStrCat cvn\n" "dup where{exch get}{pop StandardEncoding}ifelse 3 1 roll dup MFontDict\n" "exch known not{1 index findfont dup length dict begin{1 index /FID ne{\n" "def}{pop pop}ifelse}forall /Encoding 3 index def currentdict end 1 index\n" "exch definefont pop MFontDict 1 index null put}if exch pop exch pop}def\n" "/ISOLatin1{(ISOLatin1)MCreateEncoding}def /ISO8859{(ISOLatin1)\n" "MCreateEncoding}def /Mcopyfont{dup maxlength dict exch{1 index /FID eq{\n" "pop pop}{2 index 3 1 roll put}ifelse}forall}def /Plain /Courier findfont\n" "Mcopyfont definefont pop /Bold /Courier-Bold findfont Mcopyfont\n" "definefont pop /Italic /Courier-Oblique findfont Mcopyfont definefont\n" "pop /MathPictureStart{gsave Mtransform Mlmarg Mbmarg translate Mwidth\n" "Mlmarg Mrmarg add sub /Mwidth exch def Mheight Mbmarg Mtmarg add sub\n" "/Mheight exch def /Mtmatrix matrix currentmatrix def /Mgmatrix matrix\n" "currentmatrix def}bind def /MathPictureEnd{grestore}bind def /MFill{0 0\n" "moveto Mwidth 0 lineto Mwidth Mheight lineto 0 Mheight lineto fill}bind\n" "def /MPlotRegion{3 index Mwidth mul 2 index Mheight mul translate exch\n" "sub Mheight mul /Mheight exch def exch sub Mwidth mul /Mwidth exch def}\n" "bind def /MathSubStart{Momatrix Mgmatrix Mtmatrix Mwidth Mheight 7 -2\n" "roll moveto Mtmatrix setmatrix currentpoint Mgmatrix setmatrix 9 -2 roll\n" "moveto Mtmatrix setmatrix currentpoint 2 copy translate /Mtmatrix matrix\n" "currentmatrix def 3 -1 roll exch sub /Mheight exch def sub /Mwidth exch\n" "def}bind def /MathSubEnd{/Mheight exch def /Mwidth exch def /Mtmatrix\n" "exch def dup setmatrix /Mgmatrix exch def /Momatrix exch def}bind def\n" "/Mdot{moveto 0 0 rlineto stroke}bind def /Mtetra{moveto lineto lineto\n" "lineto fill}bind def /Metetra{moveto lineto lineto lineto closepath\n" "gsave fill grestore 0 setgray stroke}bind def /Mistroke{flattenpath 0 0\n" "0{4 2 roll pop pop}{4 -1 roll 2 index sub dup mul 4 -1 roll 2 index sub\n" "dup mul add sqrt 4 -1 roll add 3 1 roll}{stop}{stop}pathforall pop pop\n" "currentpoint stroke moveto currentdash 3 -1 roll add setdash}bind def\n" "/Mfstroke{stroke currentdash pop 0 setdash}bind def /Mrotsboxa{gsave dup\n" "/Mrot exch def Mrotcheck Mtmatrix dup setmatrix 7 1 roll 4 index 4 index\n" "translate rotate 3 index -1 mul 3 index -1 mul translate /Mtmatrix\n" "matrix currentmatrix def grestore Msboxa 3 -1 roll /Mtmatrix exch def\n" "/Mrot 0 def}bind def /Msboxa{newpath 5 -1 roll Mvboxa pop Mboxout 6 -1\n" "roll 5 -1 roll 4 -1 roll Msboxa1 5 -3 roll Msboxa1 Mboxrot[7 -2 roll 2\n" "copy[3 1 roll 10 -1 roll 9 -1 roll]6 1 roll 5 -2 roll]}bind def /Msboxa1\n" "{sub 2 div dup 2 index 1 add mul 3 -1 roll -1 add 3 -1 roll mul}bind def\n" "/Mvboxa{Mfixwid{Mvboxa1}{dup Mwidthcal 0 exch{add}forall exch Mvboxa1 4\n" "index 7 -1 roll add 4 -1 roll pop 3 1 roll}ifelse}bind def /Mvboxa1{\n" "gsave newpath[true 3 -1 roll{Mbbox 5 -1 roll{0 5 1 roll}{7 -1 roll exch\n" "sub(m)stringwidth pop .3 mul sub 7 1 roll 6 -1 roll 4 -1 roll Mmin 3 -1\n" "roll 5 index add 5 -1 roll 4 -1 roll Mmax 4 -1 roll}ifelse false}forall{\n" "stop}if counttomark 1 add 4 roll]grestore}bind def /Mbbox{1 dict begin 0\n" "0 moveto /temp(T)def{gsave currentpoint newpath moveto temp 0 3 -1 roll\n" "put temp false charpath flattenpath currentpoint pathbbox grestore\n" "moveto lineto moveto}forall pathbbox newpath end}bind def /Mmin{2 copy\n" "gt{exch}if pop}bind def /Mmax{2 copy lt{exch}if pop}bind def /Mrotshowa{\n" "dup /Mrot exch def Mrotcheck Mtmatrix dup setmatrix 7 1 roll 4 index 4\n" "index translate rotate 3 index -1 mul 3 index -1 mul translate /Mtmatrix\n" "matrix currentmatrix def Mgmatrix setmatrix Mshowa /Mtmatrix exch def\n" "/Mrot 0 def}bind def /Mshowa{4 -2 roll moveto 2 index Mtmatrix setmatrix\n" "Mvboxa 7 1 roll Mboxout 6 -1 roll 5 -1 roll 4 -1 roll Mshowa1 4 1 roll\n" "Mshowa1 rmoveto currentpoint Mfixwid{Mshowax}{Mshoway}ifelse pop pop pop\n" "pop Mgmatrix setmatrix}bind def /Mshowax{0 1 4 index length -1 add{2\n" "index 4 index 2 index get 3 index add moveto 4 index exch get Mfixdash{\n" "Mfixdashp}if show}for}bind def /Mfixdashp{dup length 1 gt 1 index true\n" "exch{45 eq and}forall and{gsave(--)stringwidth pop(-)stringwidth pop sub\n" "2 div 0 rmoveto dup length 1 sub{(-)show}repeat grestore}if}bind def\n" "/Mshoway{3 index Mwidthcal 5 1 roll 0 1 4 index length -1 add{2 index 4\n" "index 2 index get 3 index add moveto 4 index exch get[6 index aload\n" "length 2 add -1 roll{pop Strform stringwidth pop neg exch add 0 rmoveto}\n" "exch kshow cleartomark}for pop}bind def /Mwidthcal{[exch{Mwidthcal1}\n" "forall][exch dup Maxlen -1 add 0 1 3 -1 roll{[exch 2 index{1 index Mget\n" "exch}forall pop Maxget exch}for pop]Mreva}bind def /Mreva{[exch aload\n" "length -1 1{1 roll}for]}bind def /Mget{1 index length -1 add 1 index ge{\n" "get}{pop pop 0}ifelse}bind def /Maxlen{[exch{length}forall Maxget}bind\n" "def /Maxget{counttomark -1 add 1 1 3 -1 roll{pop Mmax}for exch pop}bind\n" "def /Mwidthcal1{[exch{Strform stringwidth pop}forall]}bind def /Strform{\n" "/tem(x)def tem 0 3 -1 roll put tem}bind def /Mshowa1{2 copy add 4 1 roll\n" "sub mul sub -2 div}bind def /MathScale{Mwidth Mheight Mlp translate\n" "scale /yscale exch def /ybias exch def /xscale exch def /xbias exch def\n" "/Momatrix xscale yscale matrix scale xbias ybias matrix translate matrix\n" "concatmatrix def /Mgmatrix matrix currentmatrix def}bind def /Mlp{3 copy\n" "Mlpfirst{Mnodistort{Mmin dup}if 4 index 2 index 2 index Mlprun 11 index\n" "11 -1 roll 10 -4 roll Mlp1 8 index 9 -5 roll Mlp1 4 -1 roll and{exit}if\n" "3 -1 roll pop pop}loop exch 3 1 roll 7 -3 roll pop pop pop}bind def\n" "/Mlpfirst{3 -1 roll dup length 2 copy -2 add get aload pop pop pop 4 -2\n" "roll -1 add get aload pop pop pop 6 -1 roll 3 -1 roll 5 -1 roll sub div\n" "4 1 roll exch sub div}bind def /Mlprun{2 copy 4 index 0 get dup 4 1 roll\n" "Mlprun1 3 copy 8 -2 roll 9 -1 roll{3 copy Mlprun1 3 copy 11 -3 roll /gt\n" "Mlpminmax 8 3 roll 11 -3 roll /lt Mlpminmax 8 3 roll}forall pop pop pop\n" "pop 3 1 roll pop pop aload pop 5 -1 roll aload pop exch 6 -1 roll\n" "Mlprun2 8 2 roll 4 -1 roll Mlprun2 6 2 roll 3 -1 roll Mlprun2 4 2 roll\n" "exch Mlprun2 6 2 roll}bind def /Mlprun1{aload pop exch 6 -1 roll 5 -1\n" "roll mul add 4 -2 roll mul 3 -1 roll add}bind def /Mlprun2{2 copy add 2\n" "div 3 1 roll exch sub}bind def /Mlpminmax{cvx 2 index 6 index 2 index\n" "exec{7 -3 roll 4 -1 roll}if 1 index 5 index 3 -1 roll exec{4 1 roll pop\n" "5 -1 roll aload pop pop 4 -1 roll aload pop[8 -2 roll pop 5 -2 roll pop\n" "6 -2 roll pop 5 -1 roll]4 1 roll pop}{pop pop pop}ifelse}bind def /Mlp1{\n" "5 index 3 index sub 5 index 2 index mul 1 index le 1 index 0 le or dup\n" "not{1 index 3 index div .99999 mul 8 -1 roll pop 7 1 roll}if 8 -1 roll 2\n" "div 7 -2 roll pop sub 5 index 6 -3 roll pop pop mul sub exch}bind def\n" "/intop 0 def /inrht 0 def /inflag 0 def /outflag 0 def /xadrht 0 def\n" "/xadlft 0 def /yadtop 0 def /yadbot 0 def /Minner{outflag 1 eq{/outflag\n" "0 def /intop 0 def /inrht 0 def}if 5 index gsave Mtmatrix setmatrix\n" "Mvboxa pop grestore 3 -1 roll pop dup intop gt{/intop exch def}{pop}\n" "ifelse dup inrht gt{/inrht exch def}{pop}ifelse pop /inflag 1 def}bind\n" "def /Mouter{/xadrht 0 def /xadlft 0 def /yadtop 0 def /yadbot 0 def\n" "inflag 1 eq{dup 0 lt{dup intop mul neg /yadtop exch def}if dup 0 gt{dup\n" "intop mul /yadbot exch def}if pop dup 0 lt{dup inrht mul neg /xadrht\n" "exch def}if dup 0 gt{dup inrht mul /xadlft exch def}if pop /outflag 1\n" "def}{pop pop}ifelse /inflag 0 def /inrht 0 def /intop 0 def}bind def\n" "/Mboxout{outflag 1 eq{4 -1 roll xadlft leadjust add sub 4 1 roll 3 -1\n" "roll yadbot leadjust add sub 3 1 roll exch xadrht leadjust add add exch\n" "yadtop leadjust add add /outflag 0 def /xadlft 0 def /yadbot 0 def\n" "/xadrht 0 def /yadtop 0 def}if}bind def /leadjust{(m)stringwidth pop .5\n" "mul}bind def /Mrotcheck{dup 90 eq{yadbot /yadbot xadrht def /xadrht\n" "yadtop def /yadtop xadlft def /xadlft exch def}if dup cos 1 index sin\n" "Checkaux dup cos 1 index sin neg exch Checkaux 3 1 roll pop pop}bind def\n" "/Checkaux{4 index exch 4 index mul 3 1 roll mul add 4 1 roll}bind def\n" "/Mboxrot{Mrot 90 eq{brotaux 4 2 roll}if Mrot 180 eq{4 2 roll brotaux 4 2\n" "roll brotaux}if Mrot 270 eq{4 2 roll brotaux}if}bind def /brotaux{neg\n" "exch neg}bind def /Mabsproc{0 matrix defaultmatrix dtransform\n" "idtransform dup mul exch dup mul add sqrt}bind def /Mabswid{Mabsproc\n" "setlinewidth}bind def /Mabsdash{exch[exch{Mabsproc}forall]exch setdash}\n" "bind def /MBeginOrig{Momatrix concat}bind def /MEndOrig{Mgmatrix\n" "setmatrix}bind def /sampledsound where{pop}{/sampledsound{exch pop exch\n" "5 1 roll mul 4 idiv mul 2 idiv exch pop exch /Mtempproc exch def{\n" "Mtempproc pop}repeat}bind def}ifelse /g{setgray}bind def /k{\n" "setcmykcolor}bind def /m{moveto}bind def /p{gsave}bind def /r{\n" "setrgbcolor}bind def /w{setlinewidth}bind def /C{curveto}bind def /F{\n" "fill}bind def /L{lineto}bind def /P{grestore}bind def /s{stroke}bind def\n" "/setcmykcolor where{pop}{/setcmykcolor{4 1 roll[4 1 roll]{1 index sub 1\n" "sub neg dup 0 lt{pop 0}if dup 1 gt{pop 1}if exch}forall pop setrgbcolor}\n" "bind def}ifelse /Mcharproc{currentfile(x)readhexstring pop 0 get exch\n" "div}bind def /Mshadeproc{dup 3 1 roll{dup Mcharproc 3 1 roll}repeat 1 eq\n" "{setgray}{3 eq{setrgbcolor}{setcmykcolor}ifelse}ifelse}bind def\n" "/Mrectproc{3 index 2 index moveto 2 index 3 -1 roll lineto dup 3 1 roll\n" "lineto lineto fill}bind def /Mcolorimage{7 1 roll pop pop matrix\n" "invertmatrix concat 2 exch exp 1 sub 3 1 roll 1 1 2 index{1 1 4 index{\n" "dup 1 sub exch 2 index dup 1 sub exch 7 index 9 index Mshadeproc\n" "Mrectproc}for pop}for pop pop pop pop}bind def /Mimage{pop matrix\n" "invertmatrix concat 2 exch exp 1 sub 3 1 roll 1 1 2 index{1 1 4 index{\n" "dup 1 sub exch 2 index dup 1 sub exch 7 index Mcharproc setgray\n" "Mrectproc}for pop}for pop pop pop}bind def\n" }; void main(argc,argv) int argc; char *argv[]; { float width = 161.0; /* Picture width in bp */ float height = 100.0; /* Picture height in bp */ float aspectratio = 0.61803; /* MMA aspect ratio */ float convfactor; /* conversion factor from bp to a TeX's unit */ bool widthchoosen = FALSE; /* the width has been choosen ? */ bool heightchoosen = FALSE; /* the height has been choosen ? */ bool enclosemath = TRUE; /* enclose MMA labels in $...$ ? */ bool addfbox = FALSE; /* enclose the picture into an \fbox ? */ bool addfontsize = FALSE; /* change default font size ? */ bool nofnameout = TRUE; /* output filename specified ? */ bool substbboffs = FALSE; /* substitute text bb offsets ? */ bool includeprolog = FALSE; /* include the PostScript prolog ? */ bool usedefprolog = TRUE; /* use the default PostScript prolog ? */ bool whitebg = FALSE; /* white background in mmaputtex ? */ bool useescseq = FALSE; /* use escape sequence ? */ bool drawarrow = FALSE; /* draw axes arrow ? */ bool drawxarrow = FALSE; /* draw x-axis arrow ? */ bool drawyarrow = FALSE; /* draw y-axis arrow ? */ struct scaletrasl st, mat; int i, j, k, nfilein = 0; char *tmpptr; char *fnamein[NMAXFILEIN]; char *fnameout = ""; char *fboxsep = "0pt"; char *fontsize = ""; char outunit[3]; char tmpunit1[3], tmpunit2[3]; char *prologuename = NULL; char *escstring = ""; FILE *filein, *fileout, *filetex; long tc; /* for time/date */ struct tm *tp; /* for time/date */ float *bboffx_old, *bboffy_old, *bboffx_new, *bboffy_new, *bbaddx_new, *bbaddy_new; int nbbsubs = 0; /* number of bb substitutions */ float xmax, xmin, ymax, ymin; float xarrow_length = 0.025; /* length of the x-axis arrow */ float xarrow_width = 0.012; /* width of the x-axis arrow */ float xarrow_inset = 0.006; /* inset of the x-axis arrow */ float yarrow_length = 0.025; /* length of the y-axis arrow */ float yarrow_width = 0.012; /* width of the y-axis arrow */ float yarrow_inset = 0.006; /* inset of the y-axis arrow */ if ((p = malloc(sizeof(struct pnts) * NMAX)) == NULL) { fprintf(stderr,"Error: not enough memory! (need %u bytes)\n", sizeof(struct pnts) * NMAX); exit(1); } if ( (bboffx_old = malloc(sizeof(float) * NMAXBBSUB)) == NULL || (bboffy_old = malloc(sizeof(float) * NMAXBBSUB)) == NULL || (bboffx_new = malloc(sizeof(float) * NMAXBBSUB)) == NULL || (bboffy_new = malloc(sizeof(float) * NMAXBBSUB)) == NULL || (bbaddx_new = malloc(sizeof(float) * NMAXBBSUB)) == NULL || (bbaddy_new = malloc(sizeof(float) * NMAXBBSUB)) == NULL ) { fprintf(stderr,"Error: not enough memory! (need %u - %u bytes)\n", sizeof(float) * NMAXBBSUB, 6 * sizeof(float) * NMAXBBSUB); exit(1); } printf("mma2ltx v1.23 - Copyright (C) 1994, 1995 by Giuseppe Ghibo`\n\n"); strcpy(outunit,"bp"); /* scan options */ for (i = 1; i < argc; i++) { if (*argv[i] == OPTSWITCH1 || *argv[i] == OPTSWITCH2) { char *s = argv[i] + 2; /* skip next char */ char opt = argv[i][1]; /* option string */ switch (opt) { case 'w': case 'W': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; width = strtobp(s); widthchoosen = TRUE; /* a width has been choosen */ break; case 'h': case 'H': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; height=strtobp(s); heightchoosen = TRUE; /* an height has been choosen */ break; case 'd': case 'D': Mnodistort = FALSE; break; case '?': fprintf(stderr,"Usage: mma2ltx [] []\n" "Where is one or more of:\n\n" "\t -? Show these messages\n" "\t -d Don't keep the aspect ratio\n" "\t -n Deactivate automatic $...$ enclosing\n" "\t -b Enclose every string into a white box (default = transpar. box)\n" "\t -p[] Include the Mathematica PostScript prologue in the .EPS file\n" "\t -h[] Set picture height to (default = 100bp)\n" "\t -w[] Set picture width to (default = 161bp)\n" "\t -f[] Add an \\fbox to the picture (\\fboxsep=)\n" "\t -u Set all dimensions in the unit \n" "\t -s Set the font size with the TeX command \n" "\t -o Output filename\n" "\t -e Change only MMA labels which begin with \n" "\t -c(sx,sy)=(newsx,newsy)(,) (change alignment)\n" "\t -a[::] Draw arrows on x and y axes\n\n" "\t = a number followed by one of TeX's unit (e.g. 10.3cm)\n" "\t = a number (e.g. 0.0125)\n" "\t = a TeX's unit (e.g. cm)\n" "\t = a TeX command without the backslash '\\'\n" "\t = a text string\n\n" "Example:\n" "\t mma2ltx -sfootnotesize -w5in pic1.ps pic2.ps\n" "processes the files `pic1.ps' and `pic2.ps'. The width of the pictures\n" "will be 5 inch and \\footnotesize will be used as LaTeX command to\n" "set the font size.\n"); exit(1); case 'n': case 'N': enclosemath = FALSE; break; case 'o': case 'O': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; fnameout = s; nofnameout = FALSE; break; case 's': case 'S': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; addfontsize = TRUE; if (*s != '\0') fontsize = s; break; case 'f': case 'F': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; addfbox = TRUE; if (*s != '\0') fboxsep = s; break; case 'u': case 'U': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; sscanf(s,"%2s",outunit); break; case 'c': case 'C': { float oldoffx, oldoffy, newoffx, newoffy, addoffx, addoffy; if (*s=='\0' && argv[i+1]) s = argv[++i]; k = sscanf(s,"(%f,%f)=(%f,%f)(%f%2s,%f%2s)", &oldoffx,&oldoffy,&newoffx,&newoffy, &addoffx,tmpunit1,&addoffy,tmpunit2); if (k != 8) { fprintf(stderr,"Warning: option '-c %s': bad argument!\n",s); break; } sprintf(tmpbuf1,"%f%2s",addoffx,tmpunit1); sprintf(tmpbuf2,"%f%2s",addoffy,tmpunit2); addoffx = strtobp(tmpbuf1); addoffy = strtobp(tmpbuf2); bboffx_old[nbbsubs] = oldoffx; bboffy_old[nbbsubs] = oldoffy; bboffx_new[nbbsubs] = newoffx; bboffy_new[nbbsubs] = newoffy; bbaddx_new[nbbsubs] = addoffx; bbaddy_new[nbbsubs] = addoffy; nbbsubs++; if (!substbboffs) substbboffs = TRUE; break; } case 'p': case 'P': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; if (*s != '\0') { prologuename = s; usedefprolog = FALSE; } includeprolog = TRUE; break; case 'b': case 'B': whitebg = TRUE; break; case 'e': case 'E': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; if (*s != '\0') { escstring = s; useescseq = TRUE; } break; case 'a': case 'A': if (*s == '\0' && argv[i+1] && *argv[i+1] != OPTSWITCH1 && *argv[i+1] != OPTSWITCH2) s = argv[++i]; if (*s != '\0') { float length, width, inset; if (sscanf(s, "%f:%f:%f", &length, &width, &inset) == 3) { xarrow_length = yarrow_length = length; xarrow_width = yarrow_width = width; xarrow_inset = yarrow_inset = inset; } else fprintf(stderr,"Warning: option '-a %s': bad argument!\n", s); } drawarrow = TRUE; break; default: break; } } else { if (nfilein >= NMAXFILEIN) { fprintf(stderr,"Error: Can't process more than %d files!\n", NMAXFILEIN); exit(1); } else fnamein[nfilein++] = argv[i]; } } if (nfilein == 0) { fprintf(stderr,"Error: You must specify at least one filename to process!\n"); exit(1); } if (nfilein > 1 && !nofnameout) { fprintf(stderr,"Error: You can't specify the output name in multiple files mode!\n"); exit(1); } /* Main loop */ for (j = 0; j < nfilein; j++) { if ((filein = fopen(fnamein[j], "r")) == NULL) { sprintf(errbuf,"Warning: Can't open file '%s' (r)", fnamein[j]); perror(errbuf); continue; } printf("Processing picture '%s' ", fnamein[j]); fflush(stdout); if (*fnameout == '\0' || nofnameout) { stripext(tmpbuf1, fnamein[j]); strcat(tmpbuf1, ".eps"); strncpy(namebuf,tmpbuf1,256); fnameout = namebuf; } if ((fileout = fopen(fnameout, "w")) == NULL) { sprintf(errbuf, "Error: Can't open file '%s' (w)", fnameout); perror(errbuf); exit(1); } /* search aspect ratio */ while ((fgets(tmpbuf1, TMPLEN, filein) != NULL)) { if ((tmpptr = strstr(tmpbuf1,"AspectRatio")) != NULL) { tmpptr += 12; sscanf(tmpptr, "%f", &aspectratio); break; } } mat.Ax = 0.0; mat.Ay = 0.0; mat.Bx = 0.0; mat.By = 0.0; /* get transformation matrix */ while ((fgets(tmpbuf1, TMPLEN, filein) != NULL)) { if (strstr(tmpbuf1, "Scaling calc") != NULL) { fgets(tmpbuf1, TMPLEN, filein); sscanf(tmpbuf1, "%f %f %f %f [", &mat.Bx, &mat.Ax, &mat.By, &mat.Ay); break; } } /* test for axes arrows */ if (drawarrow) { xmin = - mat.Bx / mat.Ax; xmax = (1.0 - mat.Bx) / mat.Ax; ymin = - mat.By / mat.Ay; ymax = (aspectratio - mat.By) / mat.Ay; if (xmax >= 0.0 && xmin <= 0.0) drawyarrow = TRUE; if (ymax >= 0.0 && ymin <= 0.0) drawxarrow = TRUE; } /* get size */ np = 0; while ((fgets(tmpbuf1, TMPLEN, filein) != NULL) && (np < NMAX)) { float gx, gy, tx, ty; if (strstr(tmpbuf1,"] MathSca") != NULL) break; if (sscanf(tmpbuf1,"[ %f %f %f %f ]",&gx, &gy, &tx, &ty) == 4) { p[np].gx = gx; p[np].gy = gy; p[np].tx = tx; p[np++].ty = ty; } } stripext(fnametex, fnameout); strcat(fnametex, ".tex"); if ((filetex=fopen(fnametex,"w")) == NULL) { sprintf(errbuf, "Error: Can't open file '%s' (w)", fnametex); perror(errbuf); exit(1); } rewind(filein); /* compute new scale factor */ if (widthchoosen && !heightchoosen) height = width * aspectratio; else if (heightchoosen && !widthchoosen) width = height / aspectratio; if (np < 2) { p[0].gx = -0.001; p[0].gy = -0.001; p[0].tx = 0.0; p[0].ty = 0.0; p[1].gx = 1.001; p[1].gy = 0.61903; p[1].tx = 0.0; p[1].ty = 0.0; np = 2; } Mlp(width,height,&st); /* Prepare PostScript file */ time(&tc); /* get current time */ tp = localtime(&tc); fprintf(fileout,"%%!PS-Adobe-2.0 EPSF-2.0\n" "%%%%BoundingBox: 0 0 %.0f %.0f\n" "%%%%Title: %s\n" "%%%%Creator: mma2ltx v1.23\n" "%%%%CreationDate: %s" "%%%%EndComments\n" "%%Mma2ltxCommandLine: ", ceil(width), ceil(height), fnameout, asctime(tp)); for (i = 0; i < argc; i++) fprintf(fileout,"%s ",argv[i]); fprintf(fileout,"\n"); if (!includeprolog) { fprintf(fileout,"%%Mma2ltxComment: For use with Mathematica prologue '%s'\n", PROLOG); fprintf(fileout,"Mathdict begin\n" "/Mwidth %.2f def\n" "/Mheight %.2f def\n" "/Mnodistort %s def\n",width,height,(Mnodistort ? "true" : "false")); } else /* include prologue */ { if (!usedefprolog) { FILE *tmpfp; if ((tmpfp = fopen(prologuename, "r")) == NULL) { fprintf(stderr,"\nWarning: prologue file `%s' not found. Use default prologue `%s'\n", prologuename, PROLOG); usedefprolog = TRUE; } else { int c, c1, c2, c3, c4; fprintf(fileout,"%%%%BeginProcSet: %s\n", prologuename); while (fgets(tmpbuf1, TMPLEN, tmpfp) != NULL) { if (strstr(tmpbuf1, "Mathdict begin") != NULL) { fputs(tmpbuf1,fileout); fprintf(fileout,"/Mwidth %.2f def\n" "/Mheight %.2f def\n" "/Mnodistort %s def\n", width, height, (Mnodistort ? "true" : "false")); break; } else fputs(tmpbuf1, fileout); } while ((c = fgetc(tmpfp)) != EOF) { if (c == 'e') /* search the last 'end' occurrence */ { if ((c1 = fgetc(tmpfp)) == 'n') { if ((c2 = fgetc(tmpfp)) == 'd') { if ((c3 = fgetc(tmpfp)) == '\n' || c3 == '\r') { if ((c4 = fgetc(tmpfp)) == EOF) { break; /* skip last 'end' occurrence */ } else { ungetc(c4, tmpfp); fputc(c, fileout); fputc(c1, fileout); fputc(c2, fileout); fputc(c3, fileout); } } else { ungetc(c3, tmpfp); fputc(c, fileout); fputc(c1, fileout); fputc(c2, fileout); } } else { ungetc(c2, tmpfp); fputc(c, fileout); fputc(c1, fileout); } } else { ungetc(c1, tmpfp); fputc(c, fileout); } } else fputc(c, fileout); /* insert prologue file */ } fclose(tmpfp); } } if (usedefprolog) { fprintf(fileout,"%%%%BeginProcSet: %s\n" "%% Mathematica v2.2 prologue\n" "/Mathdict 150 dict def\n" "Mathdict begin\n" "/Mwidth %.2f def\n" "/Mheight %.2f def\n" "/Mnodistort %s def\n", PROLOG, width, height, (Mnodistort ? "true" : "false")); fwrite(prologue, strlen(prologue), 1, fileout); } fprintf(fileout,"%%%%EndProcSet: %s\n", (usedefprolog ? PROLOG : prologuename)); } fprintf(fileout,"%%Mma2ltxComment: Here follow the original Mathematica file stripped of the text labels\n"); /* Prepare TeX file */ fprintf(filetex,"%% Picture: %s\n" "%% Created by mma2ltx v1.23 - Copyright (C) 1994, 1995 by Giuseppe Ghib\\`o\n" "%% Command line : ", fnameout); for (i = 0; i < argc; i++) fprintf(filetex, "%s ", argv[i]); fprintf(filetex, "\n%% Creation date: %s", asctime(tp)); convfactor = bptounit(outunit); /* set convfactor */ if (includeprolog) /* don't use \special{header=texmmaXX.pro} */ fprintf(filetex, "\\mmaheaderprofalse\n"); else /* use \special{header=texmmaXX.pro} */ fprintf(filetex, "\\mmaheaderprotrue\n"); fprintf(filetex, "\173%%\n"); /* left bracket */ if (addfontsize) fprintf(filetex,"\\%s%%\n", fontsize); if (addfbox) fprintf(filetex,"\\fboxsep=%s%%\n\\fbox\173%%\n",fboxsep); fprintf(filetex,"\\mmasetpic(%.4f,%.4f)[%2s]\173%s\175\n", width/convfactor, height/convfactor, outunit, fnameout); /* Scan #1 of Mathematica PostScript file, for text fits */ while ((fgets(tmpbuf1, TMPLEN, filein) != NULL)) { float x, y, gx, gy, offx, offy; bool donesubs = FALSE; if (strstr(tmpbuf1, "Mshowa") != NULL) { char *s1 = tmpbuf1, *s2 = tmpbuf2; while (*s1) { if (*s1 == '[' && *(s1+1) == '(') s1 += 2; if (*s1 == ')' && *(s1+1) == ']') { s1 += 2; break; } if (*s1 == '\\') /* handle \( and \) and \\ in PS file */ if (*(s1+1) == '(' || *(s1+1) == ')' || *(s1+1) == '\\') s1++; *s2++ = *s1++; } *s2 = '\0'; sscanf(s1,"%f %f %f %f\n", &gx, &gy, &offx, &offy); x = st.Ax * gx + st.Bx; y = st.Ay * gy + st.By; if (useescseq) { int esclen = strlen(escstring); if (!strncmp(tmpbuf2, escstring, esclen)) { char *p1 = tmpbuf2, *p2; for (p2 = tmpbuf2 + esclen; *p2 != '\0'; p2++) { *p1++ = *p2; /* throw away the escape string */ } *p1 = '\0'; } else { fputs(tmpbuf1,fileout); continue; /* don't process labels without esc sequence */ } } if (substbboffs) { int k; for (k = 0; k < nbbsubs; k++) { if (offx == bboffx_old[k] && offy == bboffy_old[k]) { fprintf(filetex,"\\mmatextfits(%.3f,%.3f)(%g,%g)(%g,%g)\173%s%s%s\175\n", x/convfactor, y/convfactor, bboffx_new[k], bboffy_new[k], bbaddx_new[k]/convfactor, bbaddy_new[k]/convfactor, (enclosemath ? "$" : ""), tmpbuf2, (enclosemath ? "$" : "")); donesubs = TRUE; break; } } } if (donesubs) continue; else { fprintf(filetex,"\\mmatextfits(%.3f,%.3f)(%g,%g)\173%s%s%s\175\n", x/convfactor,y/convfactor,offx,offy,(enclosemath ? "$" : ""), tmpbuf2,(enclosemath ? "$" : "")); continue; } } if (strstr(tmpbuf1,"Msboxa") != NULL || strstr(tmpbuf1,"Mshowa") != NULL) { if (useescseq) { char *p1; int esclen = strlen(escstring); for (p1 = tmpbuf1; *p1 != '\0'; p1++) { if (*p1 == '(') { p1++; /* p1 points to the label */ break; } } if (!strncmp(p1, escstring, esclen)) continue; else fputs(tmpbuf1, fileout); } else continue; } else if ((drawxarrow || drawyarrow) && strstr(tmpbuf1,"End of Graphics") != NULL) { struct point p0, p1, p2, p3; if (drawxarrow) { p0.x = 1.001; p0.y = mat.By; p1.x = p0.x - xarrow_length; p1.y = p0.y + xarrow_width/2.0; p2.x = p1.x + xarrow_inset; p2.y = p0.y; p3.x = p1.x; p3.y = p0.y - xarrow_width/2.0; fprintf(fileout,"p\n0 w\n0 g\n" "%1.5f %1.5f m\n" "%1.5f %1.5f L\n" "%1.5f %1.5f L\n" "%1.5f %1.5f L\n" "F\nP\n", p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); } if (drawyarrow) { p0.x = mat.Bx; p0.y = aspectratio + 0.001; p1.x = p0.x - yarrow_width/2.0; p1.y = p0.y - yarrow_length; p2.x = p0.x; p2.y = p0.y - yarrow_length + yarrow_inset; p3.x = p0.x + yarrow_width/2.0; p3.y = p1.y; fprintf(fileout,"p\n0 w\n0 g\n" "%1.5f %1.5f m\n" "%1.5f %1.5f L\n" "%1.5f %1.5f L\n" "%1.5f %1.5f L\n" "F\nP\n", p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); } fputs(tmpbuf1, fileout); } else fputs(tmpbuf1, fileout); } fprintf(fileout,"end\n"); /* appending end Mathdict */ fclose(fileout); rewind(filein); /* Scan #2 of Mathematica PostScript file to put text */ fprintf(filetex,"\\begin{mmapicture}\n"); while ((fgets(tmpbuf1,TMPLEN,filein) != NULL)) { float x, y, gx, gy, offx, offy; bool donesubs = FALSE; if (strstr(tmpbuf1,"Mshowa") != NULL) { char *s1 = tmpbuf1, *s2 = tmpbuf2; while (*s1) { if (*s1 == '[' && *(s1+1) == '(') s1 += 2; if (*s1 == ')' && *(s1+1) == ']') { s1 += 2; break; } if (*s1 == '\\') if (*(s1+1) == '(' || *(s1+1) == ')' || *(s1+1) == '\\') s1++; *s2++ = *s1++; } *s2 = '\0'; sscanf(s1,"%f %f %f %f\n",&gx,&gy,&offx,&offy); x = st.Ax * gx + st.Bx; y = st.Ay * gy + st.By; if (useescseq) { int esclen = strlen(escstring); if (!strncmp(tmpbuf2, escstring, esclen)) { char *p1 = tmpbuf2, *p2; for (p2 = tmpbuf2 + esclen; *p2 != '\0'; p2++) { *p1++ = *p2; /* throw away the escape string */ } *p1 = '\0'; } else continue; /* skip string without esc sequence */ } if (substbboffs) { int k; for (k = 0; k < nbbsubs; k++) { if (offx == bboffx_old[k] && offy == bboffy_old[k]) { fprintf(filetex,"\\mmaputtext%s(%.3f,%.3f)(%g,%g)(%g,%g)\173%s%s%s\175\n", (whitebg ? "*" : ""), x/convfactor, y/convfactor, bboffx_new[k], bboffy_new[k], bbaddx_new[k]/convfactor, bbaddy_new[k]/convfactor, (enclosemath ? "$" : ""), tmpbuf2, (enclosemath ? "$" : "")); donesubs = TRUE; break; } } } if (donesubs) continue; else { fprintf(filetex,"\\mmaputtext%s(%.3f,%.3f)(%g,%g)\173%s%s%s\175\n", (whitebg ? "*" : ""), x/convfactor, y/convfactor, offx, offy, (enclosemath ? "$" : ""), tmpbuf2, (enclosemath ? "$" : "")); continue; } } } fprintf(filetex,"\\end{mmapicture}%s%%\n\175%%\n",(addfbox ? "\175" : "")); fclose(filetex); fclose(filein); printf("...done (width=%g%s height=%g%s).\n\n", width/convfactor, outunit, height/convfactor, outunit); } free(p); free(bboffx_old); free(bboffy_old); free(bboffx_new); free(bboffy_new); free(bbaddx_new); free(bbaddy_new); exit(0); } void Mlp(float sx, float sy, struct scaletrasl *st) { struct cw cw; bool xok, yok; float Anew, Bnew; st->Ax = sx/(p[np-1].gx - p[np-2].gx); st->Ay = sy/(p[np-1].gy - p[np-2].gy); st->Bx = 0.0; st->By = 0.0; while (1) { if (Mnodistort) st->Ax = st->Ay = min(st->Ax, st->Ay); Mlprun(st->Ax, st->Ay,&cw); Mlp1(sx, st->Ax, cw.ctx, cw.wtx, cw.cgx, cw.wgx, &Anew, &Bnew, &xok); st->Ax = Anew; st->Bx = Bnew; Mlp1(sy, st->Ay, cw.cty, cw.wty, cw.cgy, cw.wgy, &Anew, &Bnew, &yok); st->Ay = Anew; st->By = Bnew; if (xok && yok) break; } } void Mlprun(float Ax, float Ay, struct cw *cw) { struct pnts low,high; float rx1, rx2, ry1, ry2; int i; low.gx = high.gx = p[0].gx; low.gy = high.gy = p[0].gy; low.tx = high.tx = p[0].tx; low.ty = high.ty = p[0].ty; for (i = 0; i < np; i++) { rx1 = p[i].gx * Ax + p[i].tx; ry1 = p[i].gy * Ay + p[i].ty; /* get low */ rx2 = low.gx * Ax + low.tx; ry2 = low.gy * Ay + low.ty; if (rx1 < rx2) { low.gx = p[i].gx; low.tx = p[i].tx; } if (ry1 < ry2) { low.gy = p[i].gy; low.ty = p[i].ty; } /* get high */ rx2 = high.gx * Ax + high.tx; ry2 = high.gy * Ay + high.ty; if (rx1 > rx2) { high.gx = p[i].gx; high.tx = p[i].tx; } if (ry1 > ry2) { high.gy = p[i].gy; high.ty = p[i].ty; } } cw->ctx = (low.tx + high.tx)/2.0; cw->wtx = high.tx - low.tx; cw->cgx = (low.gx + high.gx)/2.0; cw->wgx = high.gx - low.gx; cw->cty = (low.ty + high.ty)/2.0; cw->wty = high.ty - low.ty; cw->cgy = (low.gy + high.gy)/2.0; cw->wgy = high.gy - low.gy; } void Mlp1(float s, float A, float ct, float wt, float cg, float wg, float *Anew, float *B, bool *done) { *Anew = A; *done = TRUE; if ((A*wg) >= (s-wt)) { *Anew = (s-wt)/wg*0.99999; *done = FALSE; } *B = s/2.0 - ct - (*Anew) * cg; } /* converts TeX units to bp */ float strtobp(char *s) { char unit[3]; float value; struct TeXunits *t; if (*s == ':' || *s == '=') s++; sscanf(s,"%f%2s", &value, unit); for (t = TeXtable; *(t->strunit) != '\0'; t++) { if (strcmp(strtolwr(unit), t->strunit) == 0) { value *= t->convfactor; break; } } return(value); } /* converts bp to TeX units */ float bptounit(char *unit) { struct TeXunits *t; for (t = TeXtable; *(t->strunit) != '\0'; t++) { if (strcmp(strtolwr(unit), t->strunit) == 0) return (t->convfactor); } return(1.0); } /* remove the extension from a filename */ void stripext(char *to, char *from) { register char *p, *last; if ((last = strrchr(from, '.')) == NULL) strcpy(to, from); else { for (p = from; p < last; p++) *to++ = *p; *to = '\0'; } } /* convert a string to a lowercase string */ char *strtolwr(char *str) { register char *p; for (p = str; *p != '\0'; p++) *p = (char) tolower((int) *p); return (str); }