%% options copyright owner = Dirk Krause copyright year = 2014 license = bsd %% header #include "dk3all.h" /** Current state of the program. */ enum { /** No output produced yet. */ PLPT_STATE_NO_OUTPUT_YET = 0, /** Document class line written. */ PLPT_STATE_DOCUMENT_CLASS, /** Lines of user-specified font setup written. */ PLPT_STATE_USER_FONT_SETUP, /** Lines of user-specified usepackage instructions written. */ PLPT_STATE_USER_PACKAGES, /** User-specified setup lines were written. */ PLPT_STATE_USER_SETUP, /** The begin document line was written, contents may be added. */ PLPT_STATE_IN_DOCUMENT, /** Finished, the end document line was written. */ PLPT_STATE_AFTER_DOCUMENT }; /** Job structure for the plpdftex program. */ typedef struct { dk3_app_t *app; /**< Application structure. */ dkChar const * const *msg; /**< Localized messages texts. */ dkChar const * const *kwnl; /**< Keywords not localized. */ dkChar const * const *argv; /**< Command line arguments array. */ dkChar const *infn; /**< Input file name. */ dk3_sto_t *sco; /**< Storage for colors. */ dk3_sto_it_t *sico; /**< Storage iterator for colors. */ char *fnb1; /**< File name as read from input. */ char *fnpdf; /**< File name, PDF output file. */ char *fntex; /**< File name, TeX output file. */ char *ilbuf; /**< Input line buffer. */ dk3_option_set_t *opt; /**< Options. */ dk3_pdf_t *opdf; /**< PDF output structure. */ FILE *infi; /**< Input file. */ FILE *fopdf; /**< PDF output file. */ FILE *fotex; /**< TeX output file. */ long imgw; /**< Image width. */ long imgh; /**< Image height. */ size_t szfn; /**< File name buffer size. */ size_t szilb; /**< Size of input line buffer. */ int state; /**< Current program state. */ int exc; /**< Exit code. */ int argc; /**< Number of command line arguments. */ int stagr; /**< Flag: Produce standalone graphics. */ } plpdftex_job_t; /** Named color. */ typedef struct { char const *name; /**< Color name. */ double r; /**< Red. */ double g; /**< Green. */ double b; /**< Blue. */ } plpt_named_color_t; #include "plptcol.h" %% module #include "dk3all.h" #include "dkt-version.h" #include "dkt.h" #include "dk3pdf.h" #include "plpdftex.h" #include $!trace-include /** Option to check for the presence of the program. */ static dkChar const plpdftex_check_presence[] = { dkT("--check-presence") }; /** Protocol version to issue as response to a presence check. */ static dkChar const plpdftex_protocol[] = { dkT("1\n") }; /** Application group name. */ static dkChar const plpdftex_group_name[] = { dkT("dkt-3") }; /** DK tools version number. */ static dkChar const plpdftex_version[] = { DKT_VERSION }; /** Default help text shown if help file is not found. */ static dkChar const * const plpdftex_text_help[] = { $!text macro=dkT NAME plpdftex - Plot into a combination of *.pdf/*.tex files. SYNOPSIS plpdftex plpdftex --check-presence plpdftex --help plpdftex --license-terms DESCRIPTION The program processes an incoming data stream containing both graphics instructions and text labels. Graphics instructions are written to a PDF file, text labels are written to a *.tex file. The *.tex file includes the PDF file containing the graphics and typesets the text labels on top of it. This program is not intended to be used directly, it is an output driver for the octpgfpl package for GNU Octave. OPTIONS -h shows this help text. --help -v shows version information. --version -l shows the license conditions. --license-terms --check-presence Prints the protocol version, may be used to check for the presence of the program. RETURN VALUE The program returns exit status code 0 on success, all other status codes indicate an error. INPUT FILE Input is read from standard input. The first line specifies a file name combination. It must end on either ``.pdftex'' to produce a *.pdf/*.tex combination for inclusion in a LaTeX document or on ``.pdftexs'' to produce a *.pdf/*.tex combination for standalone processing. The second line contains two unsigned integer numbers, separated by spaces: Image width and height in PS/PDF points (known as bp in LaTeX). The remaining lines describe the image, there are ``t'' lines and ``p'' lines, i.e. t fs 12 t font-setup \usepackage[T1]{fontenc} t package \usepackage[intlimit]{amsmath} t preamble \DeclareMathOperator{\intd}{\text{d}} t text 10 20 base left black This is a test. t text-box 10 20 base left red This is another test. p gsave p grestore p lw 3 p buttcap p miterjoin p nodash p stroke-color blue!50!black p fill-color red!80!white p rectangle 5 5 200 80 p circle 20 30 5 p moveto 30 80 p lineto 50 90 p curveto 50 100 100 100 100 90 p closepath p stroke p fill p clip The ``t fs'' ``t font-setup'', ``t package'' and ``t preamble'' lines are only used when producing a *.pdf/*.tex file combination for standalone processing, otherwise they are ignored. ``t fs'' specifies the font size for the documentclass line. This line must be used before ``t font-setup'', ``t package'', ``t preamble'', ``t text'' or ``p'' lines. The line is optional, by default the documentclass is written without the font size specification. ``t font-setup'' specifies usepackage and other instructions for font setup. These lines are optional, a default font setup section is used if no ``t font-setup'' lines are used. Any ``t font-setup'' lines must be used before ``t package'', ``t preamble'', ``t text'' or ``p'' lines. ``t preamble'' lines contain further setup instructions for the preamble, they are optional. ``t text'' lines contain text labels to show. The line contains x position, y position, vertical alignment (bottom, base, centered, or top), horizontal alignment (left, centered, or right), color and the text to show. All color definitions must be LaTeX color strings like ``blue!50!white''... ``t text-box'' lines contain text labels to show. The line contains x position, y position, vertical alignment (bottom, base, centered, or top), horizontal alignment (left, centered, or right), color and the text to show. ``p'' lines contain graphics instructions transferred to the PDF file. ``p gsave'' saves the current graphics state. ``p grestore'' restores the graphics state. ``p lw'' sets the line width for stroking. ``p buttcap'' sets line cap style to butted. ``p miterjoin'' sets the line join style to miter. ``p nodash'' sets up contiguous line style. ``p stroke-color'' sets the stroke color. ``p fill-color'' sets the fill color. ``p rectangle'' creates a rectangular path, specify start x position, start y position, end x position and end y position. ``p circle'' creates a circular path, specify center x position, center y position and radius. ``p moveto'' starts a new path and moves the current position to the specified x and y position. ``p lineto'' adds a line segment from the current position to the specified x and y position to the path. ``p curveto'' adds a Bezier segment starting at the current position to the path. Specify x and y position of the first control point, x and y position of the second control point and x and y position of the final point. ``p closepath'' closes the current path. ``p stroke'' strokes the current path. ``p fill'' fills the current path. ``p clip'' uses the current path as clip path. OUTPUT FILES The names of the output files are determined from the first input line. NOTES The plpdftex program does not support all features of PDF/TeX file pairs, it is only intended as an output driver for the pgfplot() instruction in the octpgfpl package for GNU Octave. RESTRICTIONS Color definitions for plpdftex must only contain color names ``white'', ``black'', ``red'', ``green'', ``blue'', ``cyan'', ``magenta'', ``yellow'', ``gray'', ``lightgray'', ``darkgray'', ``brown'', ``lime'', ``olive'', ``orange'', ``pink'', ``purple'', ``teal'', ``violet'' and combinations like ``red!50!black''. AUTHOR Dirk Krause COPYRIGHT AND LICENSE Run plpdftex -l to see the license conditions. SEE ALSO http://dktools.sourceforge.net http://octpgfpl.sourceforge.net $!end }; /** License conditions. */ static dkChar const * const plpdftex_license_text[] = { $!text macro=dkT Copyright (c) 2014, 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 copyright 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 copyright holder(s) 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. $!end }; static dkChar const * const plpdftex_kw[] = { $!string-table macro=dkT,file=plpdftex.str # # 0 Program name # plpdftex # # 1 # Too many command line arguments, just one input file name allowed! # # 2 # Failed to retrieve first command line argument (probably a bug)! # # 3 # Output file names missing in first line! # # 4 # File name too long in first line! # # 5 # Wrong file name suffix, must be *.pdftex or *.pdftexs! # # 6 # Missing second line, containing width and height! # # 7 # Failed to retrieve width and height! # # 8 # Numeric overflow, width and/or height too large! # # 9 # Failed to write PDF data to file! # # 10 # Failed to open PDF page! # # 11 # Failed to close PDF page! # # 12 # Syntax error, document already closed! # # 13 # Syntax error, line not started by ``t'', ``p'', or ``#''! # # 14 # Syntax error, missing command! # # 15 # PDF clip operation failed! # # 16 # PDF fill operation failed! # # 17 # PDF stroke operation failed! # # 18 # PDF closepath operation failed! # # 19 # PDF curveto operation failed! # # 20 # Syntax error, numeric value expected! # # 21 # Syntax error, too few arguments for command! # # 22 # PDF moveto operation failed! # # 23 # Syntax error, radius is negative! # # 24 # PDF lineto operation failed! # # 25 # PDF set nonstroking color operation failed! # # 26 # No such color! # # 27 # PDF set stroking color operation failed! # # 28 # PDF set dash operation failed! # # 29 # PDF set linejoin operation failed! # # 30 # PDF set linecap operation failed! # # 31 # Syntax error, linewidth negative! # # 32 # PDF set linewidth operation failed! # # 33 # PDF grestore operation failed! # # 34 # PDF gsave operation failed! # # 35 # Write operation failed to TeX output file! # # 36 # Syntax error, invalid horizontal alignment specification! # # 37 # Syntax error, invalid horizontal alignment specification! # # 38 # Syntax error, order must be fs, font-setup, package, preamble, text! $!end }; /** 8 bit strings */ static char const * const plpdftex_c8_kw[] = { $!string-table # # 0 1 Output file name suffixes # -i.pdf .tex # # 2 # \\documentclass{article} # # 3 4 # % font setup (begin) % font setup (end) # # 5 6 # % other packages (begin) % other packages (end) # # 7 8 # \\setlength{\\paperwidth}{%ldbp}\n \\setlength{\\paperheight}{%ldbp}\n # # 9 10 # % user-specific setup instructions (begin) % user-specific setup instructions (end) # # 11 # \\begin{document}% # # 12 13 14 15 16 # \\begin{picture}(0,0)% \\includegraphics{ }% \\end{picture}% \\setlength{\\unitlength}{1bp}% # # 17 18 # \\begin{picture}(%ld,%ld)%\n \\end{document} # # 19 20 21 22 # \\put(%lg,%lg){\\makebox(0,0) [ ] {{\\color{%s}%s}}}\n # # 23 # {\\colorbox{white}{\\color{%s}\\ovalbox{%s}}}}\n $!end }; /** Default font setup. */ static char const * const plpdftex_default_font_setup[] = { $!string-table % begin font setup \\usepackage[T1]{fontenc} \\usepackage{textcomp} \\usepackage{mathptmx} \\usepackage[scaled=.92]{helvet} \\usepackage{courier} % end font setup $!end }; /** Default additional packages. */ static char const * const plpdftex_default_packages[] = { $!string-table % other packages (begin) \\usepackage{textcomp} \\usepackage[intlimits]{amsmath} % other packages (end) $!end }; static char const * const plpdftex_required_packages[] = { $!string-table % required packages (begin) \\usepackage{fancybox} \\usepackage{graphicx} \\usepackage{xcolor} % required packages (end) % required instructions (begin) $!end }; static char const * const plpdftex_required_instructions[] = { $!string-table \\pagestyle{empty} \\setlength{\\voffset}{-1in} \\setlength{\\topmargin}{0bp} \\setlength{\\headheight}{0bp} \\setlength{\\headsep}{0bp} \\setlength{\\topskip}{0bp} \\setlength{\\hoffset}{-1in} \\setlength{\\oddsidemargin}{0bp} \\setlength{\\evensidemargin}{0bp} \\setlength{\\marginparwidth}{0bp} \\setlength{\\marginparsep}{0bp} \\setlength{\\textwidth}{\\paperwidth} \\setlength{\\textheight}{\\paperheight} \\setlength{\\parskip}{0bp} \\setlength{\\parindent}{0bp} \\setlength{\\pdfpagewidth}{\\paperwidth} \\setlength{\\pdfpageheight}{\\paperheight} % required instructions (end) $!end }; /** Output file suffixes. */ static char const * const pldftex_output_file_suffixes[] = { $!string-table pdftex pdftexs $!end }; /** Instruction names in TeX lines. */ static char const * const plpdftex_tex_instructions[] = { $!string-table # # 0 # fs # # 1 # font-setup # # 2 # package # # 3 # preamble # # 4 # text # # 5 # text-box $!end }; /** Instruction names in PDF instructions. */ static char const * const plpdftex_pdf_instructions[] = { $!string-table # # 0 # gsave # # 1 # grestore # # 2 # lw # # 3 # buttcap # # 4 # miterjoin # # 5 # nodash # # 6 # stroke-color # # 7 # fill-color # # 8 # rectangle # # 9 # circle # # 10 # moveto # # 11 # lineto # # 12 # curveto # # 13 # closepath # # 14 # stroke # # 15 # fill # # 16 # clip $!end }; /** Vertical alignments. */ char const * const plpdftex_vertical_alignments[] = { "top", "centered", "base", "bottom", NULL }; /** Horizontal alignments. */ char const * const plpdftex_horizontal_alignments[] = { "left", "centered", "right", NULL }; /** Options expected by the program. */ static dk3_option_t const plpdftex_options[] = { { dkT('h'), dkT("help"), 0 }, { dkT('v'), dkT("version"), 0 }, { dkT('l'), dkT("license-terms"), 0 } }; /** Number of options in plpdftex_options array. */ static size_t const sz_plpdftex_options = sizeof(plpdftex_options)/sizeof(dk3_option_t); /** Initialize job structure. @param jptr Job to initialize. */ static void plpdftex_job_init(plpdftex_job_t *jptr) { $? "+ plpdftex_job_init" jptr->app = NULL; jptr->msg = NULL; jptr->kwnl = NULL; jptr->exc = 1; $? ". exc 1" jptr->argc = 0; jptr->argv = NULL; jptr->infn = NULL; jptr->opt = NULL; jptr->infi = NULL; jptr->fnb1 = NULL; jptr->fnpdf = NULL; jptr->fntex = NULL; jptr->opdf = NULL; jptr->fopdf = NULL; jptr->fotex = NULL; jptr->szfn = 0; jptr->ilbuf = NULL; jptr->szilb = 0; jptr->stagr = 0; jptr->state = PLPT_STATE_NO_OUTPUT_YET; jptr->sco = NULL; jptr->sico = NULL; jptr->imgw = 0UL; jptr->imgh = 0UL; $? "- plpdftex_job_init" } /** Clean up job structure before exiting the program. @param jptr Job structure to clean up. */ static void plpdftex_job_cleanup(plpdftex_job_t *jptr) { plpt_named_color_t *colptr; $? "+ plpdftex_job_cleanup" if (jptr->sico) { dk3sto_it_reset(jptr->sico); do { colptr = (plpt_named_color_t *)dk3sto_it_next(jptr->sico); if (colptr) { plptcolor_delete(colptr); } } while (colptr); dk3sto_it_close(jptr->sico); } jptr->sico = NULL; if (jptr->sco) { dk3sto_close(jptr->sco); } jptr->sco = NULL; jptr->msg = NULL; jptr->kwnl = NULL; if (jptr->opt) { dk3opt_close(jptr->opt); } jptr->opt = NULL; if (jptr->app) { dk3app_close(jptr->app); } jptr->app = NULL; $? "- plpdftex_job_cleanup" } /** Process font size line. @param job Job structure. @param txt Text line to process. */ static void plpdftex_process_tex_fontsize(plpdftex_job_t *job, char *txt) { double fs = 10.0; int ok = 0; $? "+ plpdftex_process_tex_fontsize" if (NULL == txt) { /* ERROR: No text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } if (0 == dk3ma_d_from_c8_string(&fs, txt, NULL)) { /* ERROR: Not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == job->stagr) { ok = 1; goto finished; } switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; job->state = PLPT_STATE_DOCUMENT_CLASS; fprintf(job->fotex, "\\documentclass[%lgpt]{article}\n", fs); } break; default: { /* ERROR: Too late */ ok = 1; dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38); goto finished; } break; } finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_process_tex_fontsize" } static void plpdftex_write_textline(plpdftex_job_t *job, char const *txt) { $? "+ plpdftex_write_textline" if (EOF == fputs(txt, job->fotex)) { /* Write error */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); job->exc = 1; $? ". exc 1" } if (EOF == fputc('\n', job->fotex)) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_write_textline" } /** Process font setup line. @param job Job structure. @param txt Text line to process. */ static void plpdftex_process_tex_font_setup(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ plpdftex_process_tex_font_setup" if (0 == job->stagr) { ok = 1; goto finished; } if (NULL == txt) { /* ERROR: Not text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; /* documentclass{article} */ plpdftex_write_textline(job, plpdftex_c8_kw[2]); /* font setup (begin) */ plpdftex_write_textline(job, plpdftex_c8_kw[3]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_FONT_SETUP; } break; case PLPT_STATE_DOCUMENT_CLASS: { ok = 1; /* font setup (begin) */ plpdftex_write_textline(job, plpdftex_c8_kw[3]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_FONT_SETUP; } break; case PLPT_STATE_USER_FONT_SETUP: { ok = 1; plpdftex_write_textline(job, txt); } break; default: { /* ERROR: Too late */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38); } } finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_process_tex_font_setup" } static void plpdftex_write_default_font_setup(plpdftex_job_t *job) { char const * const *ptr; $? "+ plpdftex_write_default_font_setup" ptr = plpdftex_default_font_setup; while (NULL != *ptr) { plpdftex_write_textline(job, *(ptr++)); } $? "- plpdftex_write_default_font_setup" } static void plpdftex_write_default_packages(plpdftex_job_t *job) { char const * const *ptr; $? "+ plpdftex_write_default_packages" ptr = plpdftex_default_packages; while (NULL != *ptr) { plpdftex_write_textline(job, *(ptr++)); } $? "- plpdftex_write_default_packages" } static void plpdftex_write_required_packages(plpdftex_job_t *job) { char const * const *ptr; $? "+ plpdftex_write_required_packages" ptr = plpdftex_required_packages; while (NULL != *ptr) { plpdftex_write_textline(job, *(ptr++)); } fprintf(job->fotex, plpdftex_c8_kw[7], job->imgw); fprintf(job->fotex, plpdftex_c8_kw[8], job->imgh); ptr = plpdftex_required_instructions; while (NULL != *ptr) { plpdftex_write_textline(job, *(ptr++)); } $? "- plpdftex_write_required_packages" } /** Process package selection line. @param job Job structure. @param txt Text line to process. */ static void plpdftex_process_tex_package(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ plpdftex_process_tex_package" if (0 == job->stagr) { ok = 1; goto finished; } if (NULL == txt) { /* ERROR: Missing text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; /* documentclass{article} */ plpdftex_write_textline(job, plpdftex_c8_kw[2]); plpdftex_write_default_font_setup(job); plpdftex_write_textline(job, plpdftex_c8_kw[5]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_PACKAGES; } break; case PLPT_STATE_DOCUMENT_CLASS: { ok = 1; plpdftex_write_default_font_setup(job); plpdftex_write_textline(job, plpdftex_c8_kw[5]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_PACKAGES; } break; case PLPT_STATE_USER_FONT_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[4]); plpdftex_write_textline(job, plpdftex_c8_kw[5]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_PACKAGES; } break; case PLPT_STATE_USER_PACKAGES: { ok = 1; plpdftex_write_textline(job, txt); } break; } finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_process_tex_package" } /** Process preamble line. @param job Job structure. @param txt Text line to process. */ static void plpdftex_process_tex_preamble(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ plpdftex_process_tex_preamble" if (0 == job->stagr) { ok = 1; goto finished; } if (NULL == txt) { /* ERROR: No text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; /* documentclass{article} */ plpdftex_write_textline(job, plpdftex_c8_kw[2]); plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_SETUP; } break; case PLPT_STATE_DOCUMENT_CLASS: { ok = 1; plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_SETUP; } break; case PLPT_STATE_USER_FONT_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[4]); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_SETUP; } break; case PLPT_STATE_USER_PACKAGES: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[6]); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, txt); job->state = PLPT_STATE_USER_SETUP; } break; case PLPT_STATE_USER_SETUP: { ok = 1; plpdftex_write_textline(job, txt); } break; } finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_process_tex_preamble" } /** Write start of TeX file. @param job Job structure. */ static void plpdftex_open_picture_set(plpdftex_job_t *job) { $? "+ plpdftex_open_picture_set" if (0 != job->stagr) { plpdftex_write_textline(job, plpdftex_c8_kw[11]); } plpdftex_write_textline(job, plpdftex_c8_kw[12]); if (EOF == fputs(plpdftex_c8_kw[13], job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); job->exc = 1; $? ". exc 1" } if (EOF == fputs(job->fnpdf, job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); job->exc = 1; $? ". exc 1" } plpdftex_write_textline(job, plpdftex_c8_kw[14]); plpdftex_write_textline(job, plpdftex_c8_kw[15]); plpdftex_write_textline(job, plpdftex_c8_kw[16]); if (0 >= fprintf(job->fotex, plpdftex_c8_kw[17], job->imgw, job->imgh)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); job->exc = 1; $? ". exc 1" } $? "- plpdftex_open_picture_set" } static void plpdftex_close_picture_set(plpdftex_job_t *job) { $? "+ plpdftex_close_picture_set" plpdftex_write_textline(job, plpdftex_c8_kw[15]); if (0 != job->stagr) { plpdftex_write_textline(job, plpdftex_c8_kw[18]); } $? "- plpdftex_close_picture_set" } /** Process text label line. @param job Job structure. @param txt Text line to process. @param withbox Flag: With box (1) or without box (0). */ static void plpdftex_process_tex_text(plpdftex_job_t *job, char *txt, int withbox) { char *p1 = NULL; /* Y position */ char *p2 = NULL; /* Vertical alignment */ char *p3 = NULL; /* Horizontal alignment */ char *p4 = NULL; /* Color */ char *p5 = NULL; /* Label text */ double x = 0.0; /* X position */ double y = 0.0; /* Y position */ int av = 0; /* Vertical alignment */ int ah = 0; /* Horizontal alignment */ int ok = 0; char c; $? "+ plpdftex_process_tex_text" /* Split strings. */ if (NULL == txt) { /* ERROR: No text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p1 = dk3str_c8_next(txt, NULL); if (NULL == p1) { /* ERROR: No y position */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p2 = dk3str_c8_next(p1, NULL); if (NULL == p2) { /* ERROR: No vertical alignment */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p3 = dk3str_c8_next(p2, NULL); if (NULL == p3) { /* ERROR: No horizontal alignment */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p4 = dk3str_c8_next(p3, NULL); if (NULL == p4) { /* ERROR: No color */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p5 = dk3str_c8_next(p4, NULL); if (NULL == p5) { /* ERROR: No text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } /* Retrieve values from strings. */ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) { /* ERROR: x value not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&y, p1, NULL)) { /* ERROR: y value not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } av = dk3str_c8_array_index(plpdftex_vertical_alignments, p2, 0); if (0 > av) { /* ERROR: Not a valid vertical alignment */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37); goto finished; } ah = dk3str_c8_array_index(plpdftex_horizontal_alignments, p3, 0); if (0 > ah) { /* ERROR: Not a valid horizontal alignment */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36); goto finished; } /* Write file header parts not yet written. */ if (0 != job->stagr) { switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; /* documentclass{article} */ plpdftex_write_textline(job, plpdftex_c8_kw[2]); plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; case PLPT_STATE_DOCUMENT_CLASS: { ok = 1; plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; case PLPT_STATE_USER_FONT_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[4]); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; case PLPT_STATE_USER_PACKAGES: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[6]); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; case PLPT_STATE_USER_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; case PLPT_STATE_IN_DOCUMENT: { ok = 1; } break; default: { /* ERROR: Too late */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12); goto finished; } break; } } else { switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: case PLPT_STATE_DOCUMENT_CLASS: case PLPT_STATE_USER_FONT_SETUP: case PLPT_STATE_USER_PACKAGES: case PLPT_STATE_USER_SETUP: case PLPT_STATE_IN_DOCUMENT: { ok = 1; plpdftex_open_picture_set(job); job->state = PLPT_STATE_IN_DOCUMENT; } break; default: { /* ERROR: Too late */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12); goto finished; } break; } } /* Write text label. */ if (1 == ok) { if (1 == withbox) { $? ". text box" /* put(%lg,%lg)makebox(0,0) */ $? ". 19" if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) { /* ERROR: fprintf failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } /* Alignment */ if ((ah != 1) || (av != 1)) { $? ". alignment" if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } c = '\0'; switch (ah) { case 0: { c = 'l'; } break; case 2: { c = 'r'; } break; } if ('\0' != c) { if (EOF == fputc(c, job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } c = '\0'; switch (av) { case 0: { c = 't'; } break; case 2: case 3: { c = 'b'; } break; } if ('\0' != c) { if (EOF == fputc(c, job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } if (0 >= fprintf(job->fotex, plpdftex_c8_kw[23], p4, p5)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } else { $? ". text" /* put(%lg,%lg)makebox(0,0) */ $? ". 19" if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) { /* ERROR: fprintf failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } /* Alignment */ if ((ah != 1) || (av != 1)) { $? ". alignment" if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } c = '\0'; switch (ah) { case 0: { c = 'l'; } break; case 2: { c = 'r'; } break; } if ('\0' != c) { if (EOF == fputc(c, job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } c = '\0'; switch (av) { case 0: { c = 't'; } break; case 2: case 3: { c = 'b'; } break; } if ('\0' != c) { if (EOF == fputc(c, job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } if (0 >= fprintf(job->fotex, plpdftex_c8_kw[22], p4, p5)) { /* ERROR: Write failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35); ok = 0; goto finished; } } } /* Return. */ finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_process_tex_text" } /** Process a TeX line. @param job Job structure. @param txt Text to process. */ static void plpdftex_process_tex_line(plpdftex_job_t *job, char *txt) { char *firstarg; $? "+ plpdftex_process_tex_line" firstarg = dk3str_c8_next(txt, NULL); switch(dk3str_c8_array_index(plpdftex_tex_instructions, txt, 0)) { case 0: { plpdftex_process_tex_fontsize(job, firstarg); } break; case 1: { plpdftex_process_tex_font_setup(job, firstarg); } break; case 2: { plpdftex_process_tex_package(job, firstarg); } break; case 3: { plpdftex_process_tex_preamble(job, firstarg); } break; case 4: { plpdftex_process_tex_text(job, firstarg, 0); } break; case 5: { plpdftex_process_tex_text(job, firstarg, 1); } break; } $? "- plpdftex_process_tex_line" } /** Process PDF gsave line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_gsave(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_gsave" if (0 != dk3pdf_gsave(job->opdf)) { ok = 1; } else { /* ERROR: gsave failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 34); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_gsave" } /** Process PDF grestore line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_grestore(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_grestore" if (0 != dk3pdf_grestore(job->opdf)) { ok = 1; } else { /* ERROR grestore failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_grestore" } /** Process PDF linewidth line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_lw(plpdftex_job_t *job, char *txt) { double lw = 1.0; int ok = 0; int mec = 0; $? "+ pldpdftex_process_pdf_lw" if (NULL != txt) { if (0 != dk3ma_d_from_c8_string(&lw, txt, &mec)) { if (0.0 <= lw) { if (0 != dk3pdf_set_linewidth(job->opdf, lw)) { ok = 1; } else { /* ERROR: Failed to set line width */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32); } } else { /* Syntax error, negative number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 31); } } else { /* Syntax error, not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); } } else { /* Syntax error, missing line width */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_lw" } /** Process PDF buttcap line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_buttcap(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_buttcap" if (0 != dk3pdf_set_linecap(job->opdf, DK3_LINECAP_BUTT)) { ok = 1; } else { /* ERROR: Failed to set line cap */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 30); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_buttcap" } /** Process PDF miterjoin line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_miterjoin(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_miterjoin" if (0 != dk3pdf_set_linejoin(job->opdf, DK3_LINEJOIN_MITER)) { ok = 1; } else { /* Failed to set linejoin */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 29); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_miterjoin" } /** Process PDF nodash line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_nodash(plpdftex_job_t *job, char *txt) { double d = 0.0; int ok = 0; $? "+ pldpdftex_process_pdf_nodash" if (0 != dk3pdf_set_line_dash(job->opdf, &d, 0, 0.0)) { ok = 1; } else { /* Failed to set dash */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 28); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_nodash" } /** Process PDF stroke color line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_stroke_color(plpdftex_job_t *job, char *txt) { double r = 0.0; double g = 0.0; double b = 0.0; int ok = 0; $? "+ pldpdftex_process_pdf_stroke_color" if (NULL != txt) { if (0 != plptcol_get_color(job, txt, &r, &g, &b)) { if (0 != dk3pdf_stroking_rgb(job->opdf, r, g, b)) { ok = 1; } else { /* Failed to set stroke color */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 27); } } else { /* Color not found! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26); } } else { /* Syntax error, missing text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_stroke_color" } /** Process PDF fill color line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_fill_color(plpdftex_job_t *job, char *txt) { double r = 0.0; double g = 0.0; double b = 0.0; int ok = 0; $? "+ pldpdftex_process_pdf_fill_color" if (NULL != txt) { if (0 != plptcol_get_color(job, txt, &r, &g, &b)) { if (0 != dk3pdf_nonstroking_rgb(job->opdf, r, g, b)) { ok = 1; } else { /* Failed to set stroke color */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 25); } } else { /* Color not found! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } } else { /* Syntax error, missing text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_fill_color" } /** Process PDF rectangle line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_rectangle(plpdftex_job_t *job, char *txt) { char *p1 = NULL; char *p2 = NULL; char *p3 = NULL; double x1 = 0.0; double x2 = 0.0; double y1 = 0.0; double y2 = 0.0; int ok = 0; $? "+ pldpdftex_process_pdf_rectangle" /* Set txt, p1, p2, p3 to x1, y1, x2, y2. */ if (NULL == txt) { /* Syntax error, missing text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto cleanup; } p1 = dk3str_c8_next(txt, NULL); if (NULL == p1) { /* Syntax error, missing y1 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto cleanup; } p2 = dk3str_c8_next(p1, NULL); if (NULL == p2) { /* Syntax error, missing x2 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto cleanup; } p3 = dk3str_c8_next(p2, NULL); if (NULL == p3) { /* Syntax error, missing y2 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto cleanup; } /* Read values from strings. */ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) { /* Syntax error, x1 not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto cleanup; } if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) { /* Syntax error, y1 not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto cleanup; } if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) { /* Syntax error, x2 not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto cleanup; } if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) { /* Syntax error, y2 not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto cleanup; } /* PDF drawing operations. */ if (0 == dk3pdf_newpath_moveto(job->opdf, x1, y1)) { /* ERROR: moveto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22); goto cleanup; } if (0 == dk3pdf_lineto(job->opdf, x2, y1)) { /* ERROR: lineto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24); goto cleanup; } if (0 == dk3pdf_lineto(job->opdf, x2, y2)) { /* ERROR: lineto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24); goto cleanup; } if (0 == dk3pdf_lineto(job->opdf, x1, y2)) { /* ERROR: lineto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24); goto cleanup; } if (0 == dk3pdf_lineto(job->opdf, x1, y1)) { /* ERROR: lineto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24); goto cleanup; } if (0 == dk3pdf_closepath(job->opdf)) { /* ERROR: closepath failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 18); goto cleanup; } /* Success. */ ok = 1; cleanup: if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_rectangle" } /** Segments per quarter circle. */ static size_t const plpt_segments = 2; /** Calculate kappa value to draw a circle. @param segments Number of segments for one _quarter_ of the circle. @return Kappa value (factor to apply to first derivative when calculating control points). */ static double plpdftex_kappa(size_t segments) { double back = 0.0; double alpha; $? "+ plpdftex_kappa %u", (unsigned)segments alpha = M_PI / (2.0 * (double)segments); /* kappa = (2*sqrt(8*(1-cos(a)))-4*sin(a)) / (3*a*(1-cos(a))) */ back = (2.0 * sqrt(8.0 * (1.0 - cos(alpha))) - 4.0 * sin(alpha)) / (3.0 * alpha * (1.0 - cos(alpha))); $? "- plpdftex_kappa %lg", back return back; } /** Process PDF circle line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_circle(plpdftex_job_t *job, char *txt) { char *p1; /* Text containing y */ char *p2; /* Text containing radius */ double x; /* Center x */ double y; /* Center y */ double r; /* Radius */ double x0; /* Current point x */ double y0; /* Current point y */ double x1; /* First control point x */ double y1; /* First control point y */ double x2; /* Second control point x */ double y2; /* Second control point y */ double x3; /* Final point x */ double y3; /* Final point y */ double alpha; /* Arc angle. */ double a1; /* Start angle. */ double a2; /* End angle. */ double kappa; /* Kappa value. */ size_t i; /* Current sub-segment */ int ok = 0; /* Flag: Success */ $? "+ pldpdftex_process_pdf_circle" /* Find strings */ if (NULL == txt) { /* Syntax error, no data */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p1 = dk3str_c8_next(txt, NULL); if (NULL == p1) { /* Syntax error, missing y */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p2 = dk3str_c8_next(p1, NULL); if (NULL == p2) { /* Syntax error, missing r */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } /* Retrieve values from strings. */ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) { /* Syntax error, not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&y, txt, NULL)) { /* Syntax error, not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&r, txt, NULL)) { /* Syntax error, not a number */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0.0 > r) { /* ERROR: Negative radius */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23); goto finished; } if (0 == dk3pdf_newpath_moveto(job->opdf, x+r, y)) { goto finished; } kappa = plpdftex_kappa(plpt_segments); alpha = 2.0 * M_PI / ((double)(4 * plpt_segments)); ok = 1; for (i = 0; i < (4 * plpt_segments); i++) { a1 = (double)i * alpha; a2 = a1 + alpha; if (0 == i) a1 = 0.0; if ((4 * plpt_segments - 1) == i) a2 = 2.0 * M_PI; x0 = r * cos(a1); y0 = r * sin(a1); if (0 == i) { x0 = r; y0 = 0.0; } x3 = r * cos(a2); y3 = r * sin(a2); if ((4 * plpt_segments - 1) == i) { x3 = r; y3 = 0.0; } x1 = -1.0 * r * alpha * sin(a1); y1 = r * alpha * cos(a1); x2 = -1.0 * r * alpha * sin(a2); y2 = r * alpha * cos(a2); x1 = x1 * kappa; y1 = y1 * kappa; x2 = -1.0 * kappa * x2; y2 = -1.0 * kappa * y2; x1 += x0; y1 += y0; x2 += x3; y2 += y3; x0 += x; x1 += x; x2 += x; x3 += x; y0 += y; y1 += y; y2 += y; y3 += y; if (0 == dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) { ok = 0; goto finished; } } if (0 == dk3pdf_closepath(job->opdf)) { ok = 0; } /* Return */ finished: if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_circle" } /** Process PDF moveto line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_moveto(plpdftex_job_t *job, char *txt) { char *p1; double x; double y; int ok = 0; $? "+ pldpdftex_process_pdf_moveto" if (NULL != txt) { p1 = dk3str_c8_next(txt, NULL); if (NULL != p1) { if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) { if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) { if (0 != dk3pdf_newpath_moveto(job->opdf, x, y)) { ok = 1; } else { /* ERROR, moveto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22); } } else { /* ERROR, y not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); } } else { /* ERROR, x not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); } } else { /* Syntax error, missing y value */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } } else { /* Syntax error, no coordinates */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_moveto" } /** Process PDF lineto line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_lineto(plpdftex_job_t *job, char *txt) { char *p1; double x; double y; int ok = 0; $? "+ pldpdftex_process_pdf_lineto" if (NULL != txt) { p1 = dk3str_c8_next(txt, NULL); if (NULL != p1) { if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) { if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) { if (0 != dk3pdf_lineto(job->opdf, x, y)) { ok = 1; } else { /* ERROR, moveto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22); } } else { /* ERROR, y not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); } } else { /* ERROR, x not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); } } else { /* Syntax error, missing y value */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } } else { /* Syntax error, no coordinates */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_lineto" } /** Process PDF curveto line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_curveto(plpdftex_job_t *job, char *txt) { char *p1; /* y1 */ char *p2; /* x2 */ char *p3; /* y2 */ char *p4; /* x3 */ char *p5; /* y3 */ double x1; double y1; double x2; double y2; double x3; double y3; int ok = 0; $? "+ pldpdftex_process_pdf_curveto" /* Split string. */ if (NULL == txt) { /* ERROR: No text */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p1 = dk3str_c8_next(txt, NULL); if (NULL == p1) { /* ERROR: No y1 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p2 = dk3str_c8_next(p1, NULL); if (NULL == p2) { /* ERROR: No x2 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p3 = dk3str_c8_next(p2, NULL); if (NULL == p3) { /* ERROR: No y2 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p4 = dk3str_c8_next(p3, NULL); if (NULL == p4) { /* ERROR: No x3 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } p5 = dk3str_c8_next(p4, NULL); if (NULL == p5) { /* ERROR: No y3 */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21); goto finished; } /* Retrieve values. */ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) { /* ERROR: x1 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) { /* ERROR: y1 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) { /* ERROR: x2 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) { /* ERROR: y2 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&x3, p4, NULL)) { /* ERROR: x3 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } if (0 == dk3ma_d_from_c8_string(&y3, p5, NULL)) { /* ERROR: y3 not numeric */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20); goto finished; } /* Write curve segment. */ if (0 != dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) { ok = 1; } else { /* ERROR: curveto failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 19); } /* Return. */ finished: if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_curveto" } /** Process PDF closepath line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_closepath(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_closepath" if (0 != dk3pdf_closepath(job->opdf)) { ok = 1; } else { /* ERROR: closepath failed */ } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_closepath" } /** Process PDF stroke line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_stroke(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_stroke" if (0 != dk3pdf_stroke(job->opdf)) { ok = 1; } else { /* ERROR: stroke failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 17); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_stroke" } /** Process PDF fill line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_fill(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_fill" if (0 != dk3pdf_fill_eo(job->opdf)) { ok = 1; } else { /* ERROR: Fill failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 16); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_fill" } /** Process PDF clip line. @param job Job structure. @param txt Text to process, may be NULL. */ static void pldpdftex_process_pdf_clip(plpdftex_job_t *job, char *txt) { int ok = 0; $? "+ pldpdftex_process_pdf_clip" if (0 != dk3pdf_clip_eo(job->opdf)) { ok = 1; } else { /* ERROR: clip failed */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 15); } if(0 == ok) { job->exc = 1; $? ". exc 1" } $? "- pldpdftex_process_pdf_clip" } /** Process a PDF line. @param job Job structure. @param txt Text to process. */ static void plpdftex_process_pdf_line(plpdftex_job_t *job, char *txt) { char *firstarg; $? "+ plpdftex_process_pdf_line" firstarg = dk3str_c8_next(txt, NULL); switch(dk3str_c8_array_index(plpdftex_pdf_instructions, txt, 0)) { case 0: { pldpdftex_process_pdf_gsave(job, firstarg); } break; case 1: { pldpdftex_process_pdf_grestore(job, firstarg); } break; case 2: { pldpdftex_process_pdf_lw(job, firstarg); } break; case 3: { pldpdftex_process_pdf_buttcap(job, firstarg); } break; case 4: { pldpdftex_process_pdf_miterjoin(job, firstarg); } break; case 5: { pldpdftex_process_pdf_nodash(job, firstarg); } break; case 6: { pldpdftex_process_pdf_stroke_color(job, firstarg); } break; case 7: { pldpdftex_process_pdf_fill_color(job, firstarg); } break; case 8: { pldpdftex_process_pdf_rectangle(job, firstarg); } break; case 9: { pldpdftex_process_pdf_circle(job, firstarg); } break; case 10: { pldpdftex_process_pdf_moveto(job, firstarg); } break; case 11: { pldpdftex_process_pdf_lineto(job, firstarg); } break; case 12: { pldpdftex_process_pdf_curveto(job, firstarg); } break; case 13: { pldpdftex_process_pdf_closepath(job, firstarg); } break; case 14: { pldpdftex_process_pdf_stroke(job, firstarg); } break; case 15: { pldpdftex_process_pdf_fill(job, firstarg); } break; case 16: { pldpdftex_process_pdf_clip(job, firstarg); } break; } $? "- plpdftex_process_pdf_line" } /** Process one input line stored into ilbuf by plpdftex_run_for_input(). @param job Job structure. */ static void plpdftex_process_line(plpdftex_job_t *job) { char *p1; $? "+ plpdftex_process_line" p1 = dk3str_c8_start(job->ilbuf, NULL); if (NULL != p1) { dk3str_c8_chomp(p1, NULL); $? ". input line \"%s\"", p1 switch(*p1) { case 't': { p1 = dk3str_c8_start(++p1, NULL); if (NULL != p1) { plpdftex_process_tex_line(job, p1); } else { /* Syntax error */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14); job->exc = 1; $? ". exc 1" } } break; case 'p': { p1 = dk3str_c8_start(++p1, NULL); if (NULL != p1) { plpdftex_process_pdf_line(job, p1); } else { /* Syntax error */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14); job->exc = 1; $? ". exc 1" } } break; case '#': { $? ". comment, ignore" } break; default: { /* Syntax error */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13); job->exc = 1; $? ". exc 1" } break; } } $? "- plpdftex_process_line" } /** Process the normal input lines. @param job Job structure. */ static void plpdftex_run_for_input(plpdftex_job_t *job) { int ok = 0; $? "+ plpdftex_run_for_input" while (NULL != fgets(job->ilbuf, job->szilb, job->infi)) { plpdftex_process_line(job); } if (0 != job->stagr) { switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: { ok = 1; /* documentclass{article} */ plpdftex_write_textline(job, plpdftex_c8_kw[2]); plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_DOCUMENT_CLASS: { ok = 1; plpdftex_write_default_font_setup(job); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_USER_FONT_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[4]); plpdftex_write_default_packages(job); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_USER_PACKAGES: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[6]); plpdftex_write_required_packages(job); plpdftex_write_textline(job, plpdftex_c8_kw[9]); plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_USER_SETUP: { ok = 1; plpdftex_write_textline(job, plpdftex_c8_kw[10]); plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_IN_DOCUMENT: { ok = 1; plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_AFTER_DOCUMENT: { ok = 1; } break; default: { /* ERROR: Too late */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12); goto finished; } break; } } else { switch (job->state) { case PLPT_STATE_NO_OUTPUT_YET: case PLPT_STATE_DOCUMENT_CLASS: case PLPT_STATE_USER_FONT_SETUP: case PLPT_STATE_USER_PACKAGES: case PLPT_STATE_USER_SETUP: { plpdftex_open_picture_set(job); plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_IN_DOCUMENT: { ok = 1; plpdftex_close_picture_set(job); job->state = PLPT_STATE_AFTER_DOCUMENT; } break; case PLPT_STATE_AFTER_DOCUMENT: { ok = 1; } break; default: { /* ERROR: Too late */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12); goto finished; } break; } } finished: if (0 == ok) { job->exc = 1; $? ". exc 1" } $? "- plpdftex_run_for_input" } /** Open PDF and TeX output file, create output structures and process all input. @param job Job structure. */ static void plpdftex_run_with_output_filenames(plpdftex_job_t *job) { unsigned long w; unsigned long h; $? "+ plpdftex_run_with_output_filenames" if (fgets(job->ilbuf, job->szilb, job->infi)) { if (sscanf(job->ilbuf, "%lu %lu", &w, &h) == 2) { job->imgw = w; job->imgh = h; if (((unsigned long)DK3_L_MAX >= w) && ((unsigned long)DK3_L_MAX >= h)) { job->fotex = dk3sf_c8_fopen_app(job->fntex, "w", job->app); if (NULL != job->fotex) { job->fopdf = dk3sf_c8_fopen_app(job->fnpdf, "wb", job->app); if (NULL != job->fopdf) { job->opdf = dk3pdf_open_app(job->app); if (NULL != job->opdf) { dk3pdf_set_next_mediabox(job->opdf, 0L, (long)w, 0L, (long)h); if (0 != dk3pdf_open_page_with_clip(job->opdf, 1)) { job->exc = 0; $? ". exc 0" plpdftex_run_for_input(job); if (0 == dk3pdf_close_page(job->opdf)) { job->exc = 1; $? ". exc 1" /* ERROR: Failed to close PDF page */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11); } } else { /* ERROR: Failed to open a PDF page */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10); } if (0 == dk3pdf_write_file(job->opdf, job->fopdf)) { job->exc = 1; $? ". exc 1" /* ERROR: Failed to write PDF to file! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 9); } dk3pdf_close(job->opdf); job->opdf = NULL; } else { /* Failed to open PDF output structure */ } if (0 == dk3sf_fclose_app(job->fopdf, job->app)) { job->exc = 1; $? ". exc 1" } job->fopdf = NULL; } else { /* Failed to open PDF output file */ } if (0 == dk3sf_fclose_app(job->fotex, job->app)) { job->exc = 1; $? ". exc 1" } job->fotex = NULL; } else { /* Failed to open TeX output file */ } } else { /* Overflow, w or h too large! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 8); } } else { /* ERROR: No w h */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 7); } } else { /* ERROR: Missing w h line */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 6); } $? "- plpdftex_run_with_output_filenames" } /** Process input from file or stdin. @param job Job structure. */ static void plpdftex_process_input(plpdftex_job_t *job) { char *p1; $? "+ plpdftex_process_input" if (fgets(job->ilbuf, job->szilb, job->infi)) { p1 = dk3str_c8_start(job->ilbuf, NULL); if (p1) { dk3str_c8_chomp(job->ilbuf, NULL); if (dk3str_c8_len(job->ilbuf) < job->szfn) { dk3str_c8_cpy(job->fnb1, job->ilbuf); dk3str_c8_cpy(job->fnpdf, job->ilbuf); p1 = dk3str_c8_get_suffix(job->fnpdf); if (p1) { *p1 = '\0'; } dk3str_c8_cpy(job->fntex, job->fnpdf); if ( (dk3str_c8_len(job->fnpdf)+dk3str_c8_len(plpdftex_c8_kw[0])) < job->szfn ) { dk3str_c8_cat(job->fnpdf, plpdftex_c8_kw[0]); dk3str_c8_cat(job->fntex, plpdftex_c8_kw[1]); p1 = dk3str_c8_get_suffix(job->fnb1); if (p1) { p1++; switch (dk3str_c8_array_index(pldftex_output_file_suffixes,p1,0)) { case 0: { /* pdf + tex for inclusion */ plpdftex_run_with_output_filenames(job); } break; case 1: { /* standalone pdf + tex */ job->stagr = 1; plpdftex_run_with_output_filenames(job); } break; default: { /* ERROR: Invalid file name */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5); } break; } } } else { /* ERROR: File name too long! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4); } } else { /* ERROR: File name too long in first input line */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4); } } else { /* ERROR: Syntax error, first line must not be empty */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3); } } $? "- plpdftex_process_input" } /** Process input. @param job Job structure. */ static void plpdftex_run_processing(plpdftex_job_t *job) { dk3_dir_t *fne; dkChar const *fnpattern; dkChar const *fn; dk3_um_t nfiles; int numargs; $? "+ plpdftex_run_processing" numargs = dk3opt_get_num_args(job->opt); switch (numargs) { case 0: { job->infi = stdin; plpdftex_process_input(job); } break; case 1: { fnpattern = dk3opt_get_arg(job->opt, 0); if (fnpattern) { if (dk3sf_must_expand(fnpattern)) { fne = dk3dir_fne_open_app(fnpattern, job->app); if (fne) { nfiles = dk3dir_get_number_of_files(fne); if (nfiles) { if (DK3_UM_1 == nfiles) { if (dk3dir_get_next_file(fne)) { fn = dk3dir_get_fullname(fne); if (fn) { job->infi = dk3sf_fopen_app(fn, dkT("r"), job->app); if (job->infi) { plpdftex_process_input(job); fclose(job->infi); job->infi = NULL; } } else { /* ERROR: Must not happen */ dk3app_log_i1(job->app, DK3_LL_ERROR, 166); } } else { /* ERROR: Must not happen */ dk3app_log_i1(job->app, DK3_LL_ERROR, 166); } } else { /* ERROR: Too many file names match pattern! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 168, 169, fnpattern); } } else { /* ERROR: No files match pattern */ dk3app_log_i3(job->app, DK3_LL_ERROR, 215, 216, fnpattern); } dk3dir_close(fne); } } else { job->infi = dk3sf_fopen_app(fnpattern, dkT("r"), job->app); if (job->infi) { plpdftex_process_input(job); fclose(job->infi); job->infi = NULL; } } } else { /* ERROR: Something wrong with options */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 2); } } break; default: { /* ERROR: One argument is maximum */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 1); } break; } $? "- plpdftex_run_processing" } /** Run. @param job Job structure. */ static void plpdftex_run(plpdftex_job_t *job) { int cmd; /* Command to execute */ $? "+ plpdftex_run" job->opt = dk3opt_open_from_app( plpdftex_options, sz_plpdftex_options, dkT('\0'), NULL, job->app ); if (job->opt) { if (0 == dk3opt_get_error_code(job->opt)) { cmd = 0; if(dk3opt_is_set(job->opt, dkT('h'))) { cmd |= DK3_APP_CMD_HELP; } if(dk3opt_is_set(job->opt, dkT('v'))) { cmd |= DK3_APP_CMD_VERSION; } if(dk3opt_is_set(job->opt, dkT('l'))) { cmd |= DK3_APP_CMD_LICENSE; } if (cmd) { dk3sf_initialize_stdout(); /* Show version */ if (cmd & DK3_APP_CMD_VERSION) { dk3sf_fputs(plpdftex_version, stdout); dk3sf_fputc(dkT('\n'), stdout); } if (cmd & DK3_APP_CMD_LICENSE) { /* Show license */ dk3sf_fputt(plpdftex_license_text, stdout); } if (cmd & DK3_APP_CMD_HELP) { /* Show help */ dk3app_help(job->app, dkT("plpdftex.txt"), plpdftex_text_help); } job->exc = 0; $? ". exc 0" } else { /* Run normally */ plpdftex_run_processing(job); } } } $? "- plpdftex_run" } /** File name as read from input. */ static char plpdftex_input_filename[DK3_MAX_PATH]; /** PDF output file name. */ static char plpdftex_pdf_filename[DK3_MAX_PATH]; /** TeX output file name. */ static char plpdftex_tex_filename[DK3_MAX_PATH]; /** Input line buffer (one line from input file). */ static char plpdftex_input_buffer[1024]; /** Main function, entry point of the program. @param argc Number of command line arguments. @param argv Command line arguments array. @return 0 on success, any other value indicates an error. */ DK3_MAIN { plpdftex_job_t job; /* Job structure. */ int check_presence = 0; /* Flag: Just presence check. */ int exit_code = 1; /* Exit code returned to OS. */ $!trace-init /tmp/plpdftex.deb $? "- main" if (2 == argc) { if (dk3str_cmp(argv[1], plpdftex_check_presence) == 0) { check_presence = 1; } } if (check_presence) { fputs(plpdftex_protocol, stdout); exit_code = 0; } else { plpdftex_job_init(&job); job.fnb1 = plpdftex_input_filename; job.fnpdf = plpdftex_pdf_filename; job.fntex = plpdftex_tex_filename; job.szfn = DK3_MAX_PATH; job.ilbuf = plpdftex_input_buffer; job.szilb = sizeof(plpdftex_input_buffer); job.app = dk3app_open_command( argc, (dkChar const * const *)argv, plpdftex_group_name ); if (job.app) { job.msg = dk3app_messages( job.app, dkT("plpdftex.str"), (dkChar const **)plpdftex_kw ); job.sco = dk3sto_open_app(job.app); if (job.sco) { job.sico = dk3sto_it_open(job.sco); if (job.sico) { plpdftex_run(&job); } } } exit_code = job.exc; plpdftex_job_cleanup(&job); } $? "- main %d", exit_code $!trace-end fflush(stdout); exit(exit_code); return exit_code; }