changeset 17371:dc103ce7c8cf

* Modified latex_render class to use unique temporary directory for all files.
author Andrej Lojdl <andrej.lojdl@gmail.com>
date Wed, 04 Sep 2013 18:16:54 +0200
parents 8a930cffa978
children f983570ba8b8
files libinterp/corefcn/txt-latex.cc libinterp/corefcn/txt-latex.h
diffstat 2 files changed, 137 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/txt-latex.cc
+++ b/libinterp/corefcn/txt-latex.cc
@@ -30,9 +30,12 @@
 #include <cstdlib>
 #include <cstring>
 
+#include <stdlib.h>
+
 #ifdef ENABLE_LATEX
 #include <png.h>
 
+#include "error.h"
 #include "txt-latex.h"
 #include "oct.h"
 #include "dim-vector.h"
@@ -51,14 +54,40 @@
 latex_render::adapter (const std::string& txt)
 {
   std::ofstream file;
-
-  file.open ("default.tex");
-  /* Adding LaTeX configuration lines to this file */
-  file << "\\documentclass[fleqn]{article} \n\\usepackage{amsmath} \n\\usepackage{color} \n\\pagestyle{empty}	\n\\begin{document} \n\t\\fontsize{12pt}{12pt}\\selectfont \n\t";
-  file << "\\usefont{T1}{" << fname << "}{m}{n} \n\t\t";
-  file << txt;
-  file << "\n\\end{document}";
-  file.close();	
+  char def[] = "/tmp/latexrenderXXXXXX"; // default path to tmp directory 
+  char *dp;
+  
+  /* Creating unique temporary directory */ 
+  dp = mkdtemp(def);
+  
+  /*Check if directory is created successfully. */  
+  if (dp != NULL)
+  {
+     /* Pointing to temporary directory, for creating .tex file */
+     sprintf(tex,"%s/%s",def,"default.tex");
+     
+     /* Creating and writing to temporary .tex file */
+     file.open (tex);
+     file << "\\documentclass[fleqn]{article} \n\\usepackage{amsmath} \n\\usepackage{color} \n\\pagestyle{empty}	\n\\begin{document} \n\t\\fontsize{12pt}{12pt}\\selectfont \n\t";
+     file << "\\usefont{T1}{" << fname << "}{m}{n} \n\t\t";
+     file << txt;
+     file << "\n\\end{document}";
+     file.close();
+     
+     /* Pointing to temporary directory, for using all files needed. */
+     sprintf(log,"%s/%s",def,"default.log");
+     sprintf(dvi,"%s/%s",def,"default.dvi");
+     sprintf(eps,"%s/%s",def,"default.eps");
+     sprintf(png,"%s/%s",def,"default.png");
+     sprintf(aux,"%s/%s",def,"default.aux");
+     
+     strcpy(path,def);
+  }
+  else
+  {
+     /* Printing error if directory is not created */
+     ::error("Failed to create temp directory.");
+  }
 }
 
 uint8NDArray 
@@ -68,47 +97,90 @@
   std::string comment;
   uint8NDArray data;
   std::ifstream file;
-  char skip,resolution[100],command[200];
+  char command[230];
 
   /* Check if command processor is available */
   if(system( NULL ))
     {
+      sprintf(command,"latex -output-directory=%s %s > %s", path, tex, log);
+      
       /* .tex -> .dvi */
-      cmd = system ("latex default.tex > latex.log");
-
-      /* checking if there is sign of error inside latex.log file */
-      file.open("latex.log");
-
-      for(int i=0; i<22; i++)
+      cmd = system (command);
+      
+      if(cmd != 0)
+      {
+         data = uint8NDArray (dim_vector (4, 2, 2), static_cast<uint8_t> (0));
+         
+         ::error("LaTeX converting .tex to .dvi file, failed.");
+         
+         file.open(log);
+         
+          for(int i=0; i<33; i++)
         {
           std::getline(file,comment);
         }
-
-      file>>skip;
-
-      if(skip!='!')
-        {
-
-          file.close();
-
-          /* .dvi -> .eps */
-          cmd = system ("dvips default.dvi -E -o default.eps -q");
+        
+         /* Print additional info from default.log */
+         comment = "Here is LaTeX description of error:";
+         std::cout<<comment<<std::endl;
+         std::getline(file,comment);
+         std::cout<<comment<<std::endl;
+         std::getline(file,comment); 
+         std::cout<<comment<<std::endl; 
+         file.close();       
+                  
+         return data;         
+      }
+          
+          /* .dvi -> .eps */     
+          sprintf(command,"dvips %s -E -o %s -q",dvi, eps);
+          
+          cmd = system (command);
+          
+          if(cmd != 0)
+          {
+             data = uint8NDArray (dim_vector (4, 2, 2), static_cast<uint8_t> (0));
+             
+             ::error("dvips converting .dvi to .eps file file, failed");
+             
+             return data;  
+          }
 
           /* .eps -> .png */
           fsize = fsize*(72/12);
-          sprintf(resolution, "%d", fsize);
-          sprintf(command, "gs -q -dEPSCrop -dSAFER -dBATCH -dNOPAUSE -r%s -dTextAlphaBits=4 -sDEVICE=pngalpha -sOutputFile=default.png \"default.eps\"", resolution) ;
+     
+          sprintf(command, "gs -q -dEPSCrop -dSAFER -dBATCH -dNOPAUSE -r%d -dTextAlphaBits=4 -sDEVICE=pngalpha -sOutputFile=%s \"%s\"", fsize, png, eps);
 
           cmd = system (command);
+          
+          if(cmd != 0)
+          {
+             data = uint8NDArray (dim_vector (4, 2, 2), static_cast<uint8_t> (0));
+             
+             ::error("GhostScript converting .eps to .png file, failed");
+             
+             return data; 
+          }
 
-          /* removing temporary files */
-          cmd = remove ("default.tex");
-          cmd = remove ("default.dvi");
-          cmd = remove ("default.log");
-          cmd = remove ("default.aux");
-          cmd = remove ("default.eps");
+          /* Removing temporary files and checking if there are removed successfully*/
+          cmd = remove (tex);
+          if(cmd != 0) 
+             ::warning("default.tex file is not deleted from temp directory.");
+          cmd = remove (dvi);
+          if(cmd != 0) 
+             ::warning("default.dvi file is not deleted from temp directory.");
+          cmd = remove (log);
+          if(cmd != 0) 
+             ::warning("default.log file is not deleted from temp directory.");
+          cmd = remove (aux);
+          if(cmd != 0) 
+             ::warning("default.aux file is not deleted from temp directory.");
+          cmd = remove (eps);
+          if(cmd != 0) 
+             ::warning("default.eps file is not deleted from temp directory.");
+          /* FIXME - the file that is not deleted should be forced to remove */
 
-          /* read image from PNG file */
+          /* Read image from PNG file */
           int x;
           int y;
 
@@ -121,38 +193,34 @@
           int number_of_passes;
           png_bytep * row_pointers;
 
-          char header [8], name [12] = "default.png";
+          char header [8];
 
-          /* open file and test for it being a png */
-          FILE *fp = fopen(name, "rb");
+          /* Open file and test for it being a png */
+          FILE *fp = fopen(png, "rb");
           if (!fp)
             {
-              fprintf(stderr,"File default.png could not be opened for reading");
-              abort();
+              ::error("File default.png could not be opened for reading");
             }
           fread(header, 1, 8, fp);
 
 
-          /* initialize stuff */
+          /* Initialize stuff */
           png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
           if (!png_ptr)
             {
-              fprintf(stderr,"png_create_read_struct failed");
-              abort();
+              ::error("png_create_read_struct failed");
             }
 
           info_ptr = png_create_info_struct(png_ptr);
           if (!info_ptr)
             {
-              fprintf(stderr,"png_create_info_struct failed");
-              abort();
+              ::error("png_create_info_struct failed");
             }
 
           if (setjmp(png_jmpbuf(png_ptr)))
             {
-              fprintf(stderr,"Error during init_io");
-              abort();
+              ::error("Error during init_io");
             }
 
           png_init_io(png_ptr, fp);
@@ -168,11 +236,10 @@
           number_of_passes = png_set_interlace_handling(png_ptr);
           png_read_update_info(png_ptr, info_ptr);
 
-          /* read file */
+          /* Read file */
           if (setjmp(png_jmpbuf(png_ptr)))
             {
-              fprintf(stderr,"Error during read_image");
-              abort();
+              ::error("Error during read_image");
             }
 
           row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
@@ -183,7 +250,7 @@
 
           fclose(fp);
 
-          /* instantise data array */
+          /* Instantise data array */
           data = uint8NDArray (dim_vector (4, width, height), static_cast<uint8_t> (0));
 
           for (int i=0; i<height; i++)
@@ -193,6 +260,7 @@
                 {
                   png_byte* ptr = &(row[j*4]);
 
+                  /* If the color of text is black we can change it, if not we render the original color. */
                   if(ptr[0] < 50 && ptr[1] < 50 && ptr[2] < 50 )
                     {
                       data(0,j,i) = red;
@@ -207,26 +275,25 @@
                       data(2,j,i) = ptr[2];
                       data(3,j,i) = ptr[3];                  	
                     }
-
-
                 }
             }
-          cmd = remove("default.png");
-
-        }
-      else
-        {
-          std::cout<<"There is some problem with your string. For more information take a look at latex.log file in your working directory."<<std::endl;
-          file.close();
-        }
+            
+          /* Removing .png file and the temporary directory. */
+          cmd = remove(png);
+          if(cmd != 0) 
+             ::warning("default.tex file is not deleted from temp directory.");
+             
+          unlink(path);
+          cmd = remove(path);
     }
   else
     {
-      std::cout<<"Command processor is not ready, try again."<<std::endl;
-      exit (EXIT_FAILURE); 
+      data = uint8NDArray (dim_vector (4, 2, 2), static_cast<uint8_t> (0));
+      
+      ::warning("Command processor not ready yet, please try again."); 
     }  
-
-  return data; 
+    
+    return data;
 }
 
 void
@@ -234,7 +301,10 @@
                         const std::string& angle, double size)
 {
   fsize = size;
-  fname = name;
+  if(name[0] == '*')
+    fname = "cmr";
+  else
+    fname = name;
 }
 
 void
@@ -260,7 +330,7 @@
   pixels = render();
 
   if(pixels.ndims () < 3)
-    std::cout<<"Pixels variable not properly set."<<std::endl;
+    ::warning("Pixels variable not properly set.");
   else
     {
 
--- a/libinterp/corefcn/txt-latex.h
+++ b/libinterp/corefcn/txt-latex.h
@@ -63,6 +63,7 @@
   Matrix bbox;
   uint8NDArray pixels;
   uint8_t red, green, blue;
+  char tex[40],aux[45],log[45],dvi[45],eps[45],png[45], path[23], *dp;
 
 };
 #endif