/* Copyright (c) 2004-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dkfigdt.c Text handling. This module contains tool functions to write TeX/LaTeX commands to an output stream. */ /** Inside the dkfigdt module. */ #define DKFIGDT_C 1 #include "dkfig.h" $(trace-include) #ifdef TRACE_DEBUG #undef TRACE_DEBUG #endif $!trace-code /** Debug this module. */ $!trace-code #define TRACE_DEBUG 1 /** Do not include code to run latex/dvips. */ #define RUN_CMD_LATEX_DVIPS 0 /** String pointer. */ typedef char *CPTR; /** Keywords used when writing LaTeX source. */ static char *kw[] = { /* 0 */ "\\font", /* 1 */ "\\newfont", /* 2 */ "\\fnt", /* 3 */ "{", /* 4 */ "}", /* 5 */ "=", /* 6 */ " at ", /* 7 */ "pt", /* 8 */ " scaled ", /* 9 */ ";", /* 10 */ "\\begin{document}\n", /* 11 */ "\\newcommand", /* 12 */ "\\def", /* 13 */ "\\reset@font", /* 14 */ "\\fontsize", /* 15 */ "\\fontfamily", /* 16 */ "\\familydefault", /* 17 */ "\\rmdefault", /* 18 */ "\\sfdefault", /* 19 */ "\\ttdefault", /* 20 */ "\\fontseries", /* 21 */ "\\fontshape", /* 22 */ "\\selectfont", /* 23 */ "%", /* 24 */ " ", /* 25 */ "\n", /* 26 */ "\\mddefault", /* 27 */ "\\bfdefault", /* 28 */ "\\updefault", /* 29 */ "\\itdefault", /* 30 */ "\\def", /* 31 */ "\\fontencoding{T1}", /* 32 */ "\\begingroup\\makeatletter\\ifx", /* 33 */ "\\fi\\endgroup%\n", /* 34 */ "\\gdef", /* 35 */ "\\undefined%\n", /* 36 */ "\\end{document}\n", /* 37 */ "\\end\n", /* 38 */ "\\shipout\\hbox{%", /* "\\shipout\\hbox{\\smash{\\hbox{\\hbox{", */ /* 39 */ "}", /* "}\\vrule width1sp}}}", */ /* 40 */ "\\mbox{", /* 41 */ " ", /* 42 */ "\\renewcommand", /* 43 */ "\r\n", }; /** Number of elements in keywords array. */ static size_t array_size = sizeof(kw)/sizeof(CPTR); /** LaTeX preamble: article document class. */ static char allp1[] = { "\\documentclass{article}" }; /** LaTeX preamble: Input is latin1 or utf8 encoded. */ static char allp2[] = { "\\usepackage[latin1]{inputenc}" }; /** LaTeX preamble: Use T1 font encoding. */ static char allp3[] = { "\\usepackage[T1]{fontenc}" }; /** LaTeX preamble: Additional text symbols. */ static char allp4[] = { "\\usepackage{textcomp}" }; /** LaTeX preamble: article document class, larger font. */ static char allp5[] = { "\\documentclass[12pt]{article}" }; /** LaTeX preamble: Use AMS math package. */ static char ams01[] = { "\\usepackage[intlimits]{amsmath}" }; /** LaTeX preamble: Use other AMS packages (fonts, symbols). */ static char ams02[] = { "\\usepackage{amsfonts,amssymb,amscd}" }; /** Default LaTeX preamble. */ static char *def_preamble[] = { allp1, allp2, allp3, allp4, ams01, NULL }; /** Preamble using AMS fonts. */ static char *ams_preamble[] = { allp1, allp2, allp3, allp4, ams01, ams02, NULL }; /** Preamble using AMS fonts and larger text size. */ static char *ams12_preamble[] = { allp5, allp2, allp3, allp4, ams01, ams02, NULL }; /** LaTeX preamble: Use Times font. */ static char pdf01[] = { "\\usepackage{mathptmx}" }; /** LaTeX preamble: Use Helvetica font. */ static char pdf02[] = { "\\usepackage[scaled=.92]{helvet}" }; /** LaTeX preamble: Use Courier font. */ static char pdf03[] = { "\\usepackage{courier}" }; /** Preamble using Times, Helvetica and Courier. */ static char *pdf_preamble[] = { allp1, allp2, allp3, allp4, pdf01, pdf02, pdf03, ams01, NULL }; /** Preamble using Times, Helvetica and Courier and larger text size. */ static char *pdf12_preamble[] = { allp5, allp2, allp3, allp4, pdf01, pdf02, pdf03, ams01, NULL }; /** LaTeX preamble: Use New Century Schoolbook. */ static char new01[] = { "\\usepackage{newcent}" }; /** Preamble using New Century Schoolbook. */ static char *new_preamble[] = { allp1, allp2, allp3, allp4, new01, ams01, NULL }; /** Preamble using New Century Schoolbook and larger text size. */ static char *new12_preamble[] = { allp5, allp2, allp3, allp4, new01, ams01, NULL }; /** Default preamble for use with plain TeX. */ static char *plain_tex_preamble[] = { "\\font\\tenrm=cmr10 at 10.80pt \\font\\sevenrm=cmr7 at 7.56pt", "\\font\\fiverm=cmr5 at 5.40pt \\font\\teni=cmmi10 at 10.80pt", "\\font\\seveni=cmmi7 at 7.56pt \\font\\fivei=cmmi5 at 5.40pt", "\\font\\tensy=cmsy10 at 10.80pt \\font\\sevensy=cmsy7 at 7.56pt", "\\font\\fivesy=cmsy5 at 5.40pt \\textfont0\\tenrm", "\\scriptfont0\\sevenrm \\scriptscriptfont0\\fiverm", "\\textfont1\\teni \\scriptfont1\\seveni \\scriptscriptfont1\\fivei", "\\textfont2\\tensy \\scriptfont2\\sevensy \\scriptscriptfont2\\fivesy", NULL }; /** Command to run TeX. */ static char texcmd[] = { "tex" }; /** Command to run LaTeX. */ static char latexcmd[] = { "latex" }; /** Command line arguments to TeX/LaTeX. */ static char options[] = { "-interaction=batchmode -file-line-error" }; /** Command line argument to enable write18. */ static char write18on[] = { "-shell-escape" }; /** Command line argument to disable write18. */ static char write18off[] = { "-no-shell-escape" }; #if RUN_CMD_LATEX_DVIPS /** Command to run dvips. */ static char dvipscmd[] = { "dvips" }; /** Command line argument to enable execution of commands. */ static char dvipssec[] = { "-R" }; /** Command line argument to disable execution of commands. */ static char dvipsunsec[] = { "-R-" }; #endif /** File open mode: Read. */ static char str_open_read_text[] = { "r" }; /** File open mode: Write. */ static char str_open_write_text[] = { "w" }; /** Write one keyword to output stream. @param os Output stream to write to. @param index Index of keyword. @return 1 on success, 0 on error. */ static int kw_to_stream DK_P2(dk_stream_t *,os, size_t,index) { int back = 0; $? "+ kw_to_stream %lu / %lu", (unsigned long)index, (unsigned long)array_size if(index < array_size) { $? ". index ok" back = dkstream_puts(os, kw[index]); } $? "- kw_to_stream" return back; } /** Write newline (either nl or cr/nl). @param c Conversion job structure. @param os Output stream to write to. */ static void newline_to_c DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { if((c->opt2) & DKFIG_OPT_CRNL) { kw_to_stream(os, 43); } else { kw_to_stream(os, 25); } } /** Classify file name suffix (find compression algorithm). @param filename File name. @return 0 for plain (uncompressed) file, 1 for gzip compression, 2 for bzip2 compression. */ static int classify_suffix DK_P1(char *,filename) { int back = 0; char *ptr; $? "+ classify_suffix %s", TR_STR(filename) if(filename) { ptr = dksf_get_file_type_dot(filename); if(ptr) { if(strcmp(ptr, ".bz2") == 0) { back = 2; } else { if(strcmp(ptr, ".gz") == 0) { back = 1; } } } } $? "- classify_suffix %d", back return back; } /** Copy stream contents to another stream. @param os Output (destination) stream. @param is Input (source) stream. @return 1 on success, 0 on error. */ static int copy_streams DK_P2(dk_stream_t *,os, dk_stream_t *,is) { int back = 1; char buffer[512]; size_t rb, wb; int cc; $? "+ copy_streams" cc = 1; while(cc) { rb = dkstream_read(is, buffer, sizeof(buffer)); if(rb) { wb = dkstream_write(os, buffer, rb); if(rb != wb) { back = 0; } } else { cc = 0; } } $? "- copy_streams" return back; } /** Get preamble from named file and write it to output stream. The c->tpfn component contains the preamble file name. @param c Conversion job structure. @param os Output stream. @return 1 on success, 0 on error. */ static int preamble_from_file DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { int back = 0, ct = 0, reason = 0; size_t sz = 0; char *buffer = NULL; dk_stream_t *is = NULL; $? "+ preamble_from_file" sz = (size_t)dksf_get_maxpathlen(); buffer = dk_new(char,sz); if(buffer) { $? ". buffer allocated" if(c->app) { $? ". have app" back = dkapp_find_file(c->app, c->tpfn, buffer, sz); if(!back) { /* ERROR: Failed to find preamble file */ dkfig_tool2_msg3(c, DK_LOG_LEVEL_ERROR, 45, 46, c->tpfn); } } else { $? ". no app" if(strlen(c->tpfn) < sz) { $? ". length ok" strcpy(buffer, c->tpfn); back = 1; } if(!back) { /* ERROR: Preamble file name too long! */ dkfig_tool2_msg3(c, DK_LOG_LEVEL_ERROR, 47, 48, c->tpfn); } } if(back) { $? ". can use buffer" back = 0; ct = classify_suffix(buffer); is = NULL; switch(ct) { case 1: { if(c->app) { is = dkapp_stream_opengz(c->app, buffer, str_open_read_text); } else { is = dkstream_opengz(buffer, str_open_read_text, 0, &reason); } } break; case 2: { if(c->app) { is = dkapp_stream_openbz2(c->app, buffer, str_open_read_text); } else { is = dkstream_openbz2(buffer, str_open_read_text, 0, &reason); } } break; default: { if(c->app) { is = dkapp_stream_openfile(c->app, buffer, str_open_read_text); } else { is = dkstream_openfile(buffer, str_open_read_text, 0, &reason); } } break; } if(is) { back = copy_streams(os, is); dkstream_close(is); is = NULL; if(!back) { /* ERROR: Failed to copy preamble file */ dkfig_tool2_msg3(c, DK_LOG_LEVEL_ERROR, 49, 50, buffer); } } else { if(c->app) { /* ERROR: Failed to open preamble file! */ dkapp_err_fopenr(c->app, buffer); } else { } } } dk_delete(buffer); buffer = NULL; } else { /* ERROR: Memory */ if(c->app) { dkapp_err_memory(c->app, sizeof(char), sz); } } $? "- preamble_from_file %d", back return back; } /** Write one of the built-in preambles to the output stream. The c->latfs component chooses a preamble. @param c Conversion job structure. @param os Output stream. @return 1 on success, 0 on error. */ static int preamble_from_settings DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { int back = 1; $? "+ preamble_from_settings" if(!((c->opt1) & DKFIG_OPT_OLD_TEX)) { switch(c->latfs) { case 0: { dkstream_puts_array(os, ams_preamble); } break; case 1: { dkstream_puts_array(os, pdf_preamble); } break; case 2: { dkstream_puts_array(os, new_preamble); } break; case 3: { dkstream_puts_array(os, ams12_preamble); } break; case 4: { dkstream_puts_array(os, pdf12_preamble); } break; case 5: { dkstream_puts_array(os, new12_preamble); } break; default: { dkstream_puts_array(os, def_preamble); } break; } } else { dkstream_puts_array(os, plain_tex_preamble); } $? "- preamble_from_settings %d", back return back; } /** Write LaTeX preamble to a stream. @param c Conversion job structure. @param os Output stream. @return 1 on success, 0 on error. */ int dkfig_dt_tex_preamble DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { int back = 0; $? "+ dkfig_dt_tex_preamble" if(c && os) { if(c->tpfn) { back = preamble_from_file(c, os); } else { back = preamble_from_settings(c, os); } } $? "- dkfig_dt_tex_preamble %d", back return back; } /** Check whether or not the font handling requires LaTeX/TeX. @param fhptr Font handling structure. @return 1 if LaTeX or TeX is needed, 0 if not. */ int dkfig_dt_is_latex_text DK_P1(dk_fig_fonth_t *,fhptr) { int back = 0; $? "+ is_latex_text" if(fhptr) { switch(fhptr->handling) { case 2: case 3: case 4: case 5: { back = 1; } break; } } $? "- is_latex_text %d", back return back; } /** Find number of characters needed to string encode a number. @param num Number to encode. @return Needed string length. */ size_t dkfig_dt_needed_alpha DK_P1(unsigned long, num) { size_t back = 0; unsigned long n = 0UL; $? "+ needed_alpha %lu", num n = num; while(num) { back++; num = num / 26UL; } $? "- needed_alpha %lu", (unsigned long)back return back; } /** Write command to define one font to output stream. @param c Conversion job structure. @param os Output stream. @param fhptr Font handling structure. @return 1 on success, 0 on error. */ static int write_one_font_def DK_P3(dk_fig_conversion *,c, dk_stream_t *,os, dk_fig_fonth_t *,fhptr) { int back = 1; int me = 0; kw_to_stream(c->ostrm, 3); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); /* kw_to_stream(c->ostrm, 24); */ if((c->opt1) & DKFIG_OPT_OLD_TEX) { kw_to_stream(c->ostrm, 13); kw_to_stream(c->ostrm, 31); } if(fhptr->handling == 4) { $? ". fontsize" kw_to_stream(c->ostrm, 14); kw_to_stream(c->ostrm, 3); dkstream_puts_double( c->ostrm, dkma_mul_double_ok(fhptr->fontsize,c->fsf,&me) ); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 3); dkstream_puts_double( c->ostrm, dkma_mul_double_ok( 1.25, dkma_mul_double_ok(fhptr->fontsize,c->fsf,&me), &me ) ); kw_to_stream(c->ostrm, 7); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); /* kw_to_stream(c->ostrm, 24); */ } kw_to_stream(c->ostrm, 15); kw_to_stream(c->ostrm, 3); switch((fhptr->fontno) & DK_FONT_FEATURE_FAMILY) { case DK_FONT_FEATURE_RM : { kw_to_stream(c->ostrm, 17); } break; case DK_FONT_FEATURE_SF : { kw_to_stream(c->ostrm, 18); } break; case DK_FONT_FEATURE_TT : { kw_to_stream(c->ostrm, 19); } break; default: { kw_to_stream(c->ostrm, 16); } break; } kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); /* kw_to_stream(c->ostrm, 24); */ kw_to_stream(c->ostrm, 20); kw_to_stream(c->ostrm, 3); kw_to_stream(c->ostrm, (((fhptr->fontno) & DK_FONT_FEATURE_BD) ? 27 : 26) ); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); /* kw_to_stream(c->ostrm, 24); */ kw_to_stream(c->ostrm, 21); kw_to_stream(c->ostrm, 3); kw_to_stream(c->ostrm, (((fhptr->fontno) & DK_FONT_FEATURE_IT) ? 29 : 28) ); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); /* kw_to_stream(c->ostrm, 24); */ kw_to_stream(c->ostrm, 22); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); if(me) { back = 0; } return back; } /** Write a font name to output stream. The font number is encoded as character sequence. @param os Output stream. @param drw Fig drawing structure. @param fhptr Font handling structure. */ void dkfig_dt_write_fontname DK_P3(dk_stream_t *,os, dk_fig_drawing *,drw, dk_fig_fonth_t *,fhptr) { kw_to_stream(os, 2); dkfig_tool_num_as_string(os, fhptr->fonthno, drw->numlatalpha); } /** Write LaTeX commands to define all fonts to output stream. @param c Conversion job structure. @param os Output stream. @param drw Fig drawing structure. @param r Flag: Use renewcommand instead of newcommand. @return 1 on success, 0 on error. */ static int write_font_defs DK_P4(dk_fig_conversion *,c, dk_stream_t *,os, dk_fig_drawing *,drw, int,r) { int back = 0; int me = 0; dk_fig_fonth_t *fhptr = NULL; $? "+ write_font_defs" if(drw->fonthi) { back = 1; if(drw->numlatfonts) { dksto_it_reset(drw->fonthi); while((fhptr = (dk_fig_fonth_t *)dksto_it_next(drw->fonthi)) != NULL) { $? ". there is yet another font %d", fhptr->handling /* wird jetzt zentral erledigt if((c->opt1) & DKFIG_OPT_OLD_TEX) { correct_fonth_for_plain_tex(fhptr); } */ switch(fhptr->handling) { case 3: { /* exact font */ /* /font/fntAA=ptmr at 12 pt; */ /* /newfont{/fntAA}{ptmr scaled 12pt;} */ if((c->opt1) & DKFIG_OPT_OLD_TEX) { kw_to_stream(c->ostrm, 0); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); kw_to_stream(c->ostrm, 5); dkstream_puts(c->ostrm, dkfont_get_tex_name(fhptr->fontno)); kw_to_stream(c->ostrm, 6); dkstream_puts_double( c->ostrm, dkma_mul_double_ok(fhptr->fontsize, c->fsf, &me) ); kw_to_stream(c->ostrm, 7); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); } else { kw_to_stream(c->ostrm, 1); kw_to_stream(c->ostrm, 3); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 3); dkstream_puts(c->ostrm, dkfont_get_tex_name(fhptr->fontno)); kw_to_stream(c->ostrm, 6); dkstream_puts_double( c->ostrm, dkma_mul_double_ok(fhptr->fontsize,c->fsf,&me) ); kw_to_stream(c->ostrm, 7); kw_to_stream(c->ostrm, 4); kw_to_stream(c->ostrm, 23); newline_to_c(c, c->ostrm); } } break; case 4: case 5: { /* features and size */ if((c->opt1) & DKFIG_OPT_OLD_TEX) { kw_to_stream(c->ostrm, 32); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); kw_to_stream(c->ostrm, 35); kw_to_stream(c->ostrm, 34); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); back = write_one_font_def(c, c->ostrm, fhptr); kw_to_stream(c->ostrm, 33); } else { if((c->opt2) & DKFIG_OPT_TEX_DRIVER) { kw_to_stream(c->ostrm, 12); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); } else { if(r) { kw_to_stream(c->ostrm, 42); } else { kw_to_stream(c->ostrm, 11); } kw_to_stream(c->ostrm, 3); kw_to_stream(c->ostrm, 2); dkfig_tool_num_as_string( c->ostrm, fhptr->fonthno, drw->numlatalpha ); kw_to_stream(c->ostrm, 4); } back = write_one_font_def(c, c->ostrm, fhptr); } } break; #if TRACE_DEBUG default: { $? ". fhptr->handling=%d no definition necessary", fhptr->handling } break; #endif } } } } if(me) { back = 0; } $? "- write_font_defs %d", back return back; } /** Write LaTeX commands for font definitions to output stream. @param c Conversion job structure. @param os Output stream. @param r Flag: redefinition (1) or definition (0). @return 1 on success, 0 on error. */ int dkfig_dt_font_redef DK_P3(dk_fig_conversion *,c, dk_stream_t *,os, int,r) { int back = 0; /* dk_fig_output_mp *mpo = NULL; */ dk_fig_object *dro = NULL; dk_fig_drawing *drw = NULL; $? "+ dkfig_dt_font_defs" if(c && os) { /* mpo = (dk_fig_output_mp *)(c->outds); */ dro = c->drwng; /* if(mpo && dro) { */ if(dro) { drw = (dk_fig_drawing *)(dro->data); if(drw) { back = write_font_defs(c, os, drw, r); } } } $? "- dkfig_dt_font_defs" return back; } /** Write LaTeX commands for font definitions to output stream. @param c Conversion job structure. @param os Output stream. @return 1 on success, 0 on error. */ int dkfig_dt_font_defs DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { int back; back = dkfig_dt_font_redef(c, os, 0); return back; } /** Write end{document} sequence to output stream. @param c Conversion job structure. @param os Output stream. */ void dkfig_dt_end_document DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { if((c) && (os)) { if(!((c->opt1) & DKFIG_OPT_OLD_TEX)) { kw_to_stream(os, 36); } else { kw_to_stream(os, 37); } } } /** Write begin{document} to output stream. @param c Conversion job structure. @param os Output stream. */ void dkfig_dt_begin_document DK_P2(dk_fig_conversion *,c, dk_stream_t *,os) { if((c) && (os)) { if(!((c->opt1) & DKFIG_OPT_OLD_TEX)) { kw_to_stream(os, 10); } } } /** Check whether or not there is any text in the drawing requiring the use of LaTeX/TeX. @param c Conversion job structure. @return Test result (1=LaTeX/TeX needed, 0=not needed). */ int dkfig_dt_need_tex_file DK_P1(dk_fig_conversion *,c) { int back = 0; dk_fig_object *o = NULL; dk_fig_drawing *drw = NULL; dk_fig_fonth_t *fhptr = NULL; $? "+ dkfig_dt_need_tex_file" if(c) { o = c->drwng; if(o) { drw = (dk_fig_drawing *)(o->data); if(drw) { if(drw->fonthi) { dksto_it_reset(drw->fonthi); while(((fhptr = (dk_fig_fonth_t *)dksto_it_next(drw->fonthi)) != NULL) && (!back)) { switch(fhptr->handling) { case 2: case 3: case 4: case 5: back = 1; break; } } } } } } $? "- dkfig_dt_need_tex_file %d", back return back; } /** Write LaTeX/TeX file and run LaTeX/TeX. @param c Conversion job structure. @param d Fig drawing structure. @param it Iterator to flattened Fig objects container. @return 1 on success, 0 on error. */ int dkfig_dt_run_tex DK_P3(dk_fig_conversion *,c, dk_fig_drawing *,d, dk_storage_iterator_t *,it) { int back = 0; dk_stream_t *os = NULL; FILE *of = NULL; dk_fig_object *o; dk_fig_text *t; dk_fig_fonth_t *f; if(c && it) { if(c->texn) { if(c->app) { of = dkapp_fopen(c->app, c->texn, str_open_write_text); } else { of = dksf_fopen(c->texn, str_open_write_text); } if(of) { os = dkstream_for_file(of); if(os) { if(dkfig_dt_tex_preamble(c, os)) { dkfig_dt_begin_document(c, os); back = 1; dksto_it_reset(it); while((o = (dk_fig_object *)dksto_it_next(it)) != NULL) { if(o->objtype == DK_FIG_OBJ_TEXT) { t = (dk_fig_text *)(o->data); if(t) { f = t->font_handling; if(f) { switch(f->handling) { case 2: case 3: case 4: case 5: { kw_to_stream(os, 38); newline_to_c(c, os); if((c->special_text) & DKFIG_TH_MBOX) { kw_to_stream(os, 40); } if(f->handling != 2) { dkfig_dt_write_fontname(os, d, f); kw_to_stream(os, 41); } dkstream_puts(os, t->text); if((c->special_text) & DKFIG_TH_MBOX) { kw_to_stream(os, 4); } kw_to_stream(os, 39); newline_to_c(c, os); } break; } } } } } dkfig_dt_end_document(c, os); } dkstream_close(os); os = NULL; } else { $? "! Failed to create stream" dkfig_tool2_msg1(c, DK_LOG_LEVEL_ERROR, 59); } fclose(of); of = NULL; if(back) { char *tc, *to, *tw; #if RUN_CMD_LATEX_DVIPS char *cmdline; #endif size_t sz; back = 0; tc = to = tw = NULL; tc = (((c->opt1) & DKFIG_OPT_OLD_TEX) ? texcmd : latexcmd); to = options; if((c->opt1) & DKFIG_OPT_SPECIFY_WRITE18) { tw = (((c->opt1) & DKFIG_OPT_ENABLE_WRITE18) ? write18on : write18off); } sz = strlen(tc) + strlen(c->texn) + strlen(to) + 3; if(tw) { sz += (1 + strlen(tw)); } #if RUN_CMD_LATEX_DVIPS cmdline = dk_new(char,sz); if(cmdline) { strcpy(cmdline, tc); strcat(cmdline, kw[41]); strcat(cmdline, to); if(tw) { strcat(cmdline, kw[41]); strcat(cmdline, tw); } strcat(cmdline, kw[41]); strcat(cmdline, c->texn); $? ". cmdline=\"%s\"", cmdline if(system(cmdline) == 0) { back = 1; } else { $? "! Failed to run LaTeX" dkfig_tool2_msg3(c, DK_LOG_LEVEL_ERROR, 60, 61, cmdline); } dk_delete(cmdline); cmdline = NULL; if(back) { back = 0; tc = to = tw = NULL; tc = dvipscmd; if((c->opt1) & DKFIG_OPT_SPECIFY_WRITE18) { tw = (((c->opt1) & DKFIG_OPT_ENABLE_WRITE18) ? dvipsunsec : dvipssec); } sz = strlen(tc) + strlen(c->dvin) + 2; if(tw) { sz += (1 + strlen(tw)); } cmdline = dk_new(char,sz); if(cmdline) { strcpy(cmdline, tc); strcat(cmdline, kw[41]); if(tw) { strcat(cmdline, tw); strcat(cmdline, kw[41]); } strcat(cmdline, c->dvin); $? ". cmdline=\"%s\"", cmdline if(system(cmdline) == 0) { back = 1; } else { dkfig_tool2_msg3(c, DK_LOG_LEVEL_ERROR, 60, 61, cmdline); } dk_delete(cmdline); cmdline = NULL; } else { $? "! memory for cmdline" if(c->app) { dkapp_err_memory(c->app, sizeof(char), sz); } } } } else { $? "! memory for cmdline" if(c->app) { dkapp_err_memory(c->app, sizeof(char), sz); } } #else back = 1; #endif } } else { $? "! failed to write TeX file" if(c->app) { dkapp_err_fopenw(c->app, c->texn); } } } else { $? "! internal seteup problem" } } else { $? "! internal setup problem" } return back; }