Mercurial > hg > octave-lojdl
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 {