Mercurial > hg > octave-lojdl
changeset 11009:064aaf82222f
Print via a pipeline.
author | Ben Abbott <bpabbott@mac.com> |
---|---|
date | Tue, 21 Sep 2010 21:22:44 -0400 |
parents | 3622db30ff05 |
children | 9478b216752e |
files | scripts/ChangeLog scripts/plot/__fltk_print__.m scripts/plot/__gnuplot_print__.m scripts/plot/__print_parse_opts__.m scripts/plot/print.m scripts/plot/private/__ghostscript__.m |
diffstat | 6 files changed, 541 insertions(+), 295 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,9 @@ +2010-09-21 Ben Abbott <bpabbott@mac.com> + + * plot/__fltk_print__.m, plot/private/__ghostscript__.m, + plot/__gnuplot_print__.m, plot/__print_parse_opts__.m, + plot/print.m: Print via a pipeline. + 2010-09-20 Ben Abbott <bpabbott@mac.com> * plot/legend.m: Index location cellstr to obtain a string.
--- a/scripts/plot/__fltk_print__.m +++ b/scripts/plot/__fltk_print__.m @@ -23,22 +23,26 @@ function opts = __fltk_print__ (opts) + dos_shell = (ispc () && ! isunix ()); + figure (opts.figure) drawnow ("expose") if (! isempty (opts.fig2dev_binary)) + ## fig2dev is prefered for conversion to emf fig2dev_devices = {"pstex", "mf", "emf"}; else - ## If no fig2dev is present, support emf using pstoedit. fig2dev_devices = {"pstex", "mf"}; endif + gl2ps_device = {}; + pipeline = {}; switch lower (opts.devopt) case {"eps", "eps2", "epsc", "epsc2"} - drawnow ("eps", opts.name); - if (opts.tight_flag) - __tight_eps_bbox__ (opts, opts.name); - endif + ## format GL2PS_EPS + gl2ps_device = {"eps"}; + ## FIXME - use epstool to tighten bbox and provide preview. + pipeline = {opts.epstool_cmd(opts, "-", opts.name)}; case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ... "pslatexstandalone", "pdflatexstandalone"} ## format GL2PS_TEX @@ -57,143 +61,104 @@ elseif (dot == numel (opts.name)) name = opts.name; endif - drawnow (strcat (lower (suffix), "notxt"), strcat (name, ".", suffix)); - drawnow ("tex", strcat (name, ".tex")); - if (opts.tight_flag && strcmp (suffix, "eps")) - __tight_eps_bbox__ (opts, strcat (name, ".", suffix)); - endif - if (! isempty (strfind (opts.devopt, "standalone"))) - __latex_standalone__ (strcat (name, ".tex")); + gl2ps_device = {sprintf("%snotxt", lower (suffix))}; + gl2ps_device{2} = "tex"; + if (dos_shell) + pipeline = {sprintf("copy con %s.%s", name, suffix)}; + pipeline{2} = sprintf ("copy con %s.tex", name); + else + pipeline = {sprintf("cat > %s.%s", name, suffix)}; + pipeline{2} = sprintf ("cat > %s.tex", name); endif case {"tikz"} ## format GL2PS_PGF - drawnow ("pgf", opts.name); + gl2ps_device = {"pgf"}; + pipeline = {sprintf("cat > %s", opts.name)}; case {"svg"} ## format GL2PS_SVG - drawnow ("svg", opts.name); + gl2ps_device = {"svg"}; + pipeline = {sprintf("cat > %s", opts.name)}; case fig2dev_devices - tmp_figfile = strcat (tmpnam (), ".fig"); - opts.unlink{end+1} = tmp_figfile; - status = __pstoedit__ (opts, "fig", tmp_figfile); - if (status == 0) - status = __fig2dev__ (opts, tmp_figfile); - if (strcmp (opts.devopt, "pstex") && status == 0) - if (strfind (opts.name, ".ps") == numel(opts.name) - 2) - devfile = strcat (opts.name(1:end-2), "tex"); - else - devfile = strcat (opts.name, ".tex"); - endif - status = __fig2dev__ (opts, tmp_figfile, "pstex_t", devfile); + cmd_pstoedit = opts.pstoedit_cmd (opts, "fig"); + cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt); + if (strcmp (opts.devopt, "pstex")) + [~, ~, ext] = fileparts (opts.name); + if (any (strcmpi (ext, {".ps", ".tex", "."}))) + opts.name = opts.name(1:end-numel(ext)); endif + opts.name = strcat (opts.name, ".ps"); + cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); + gl2ps_device = {"eps"}; + pipeline = {cmd}; + cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t"); + gl2ps_device{2} = "eps"; + pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit, + cmd_fig2dev, strrep(opts.name, ".ps", ".tex")); + else + cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); + gl2ps_device = {"eps"}; + pipeline = {cmd}; endif case {"aifm"} - status = __pstoedit__ (opts, "ps2ai"); + cmd = opts.pstoedit_cmd (opts, "ps2ai"); + gl2ps_device = {"eps"}; + pipeline = {sprintf("%s > %s", cmd, opts.name)}; case {"dxf", "emf", "fig", "hpgl"} - status = __pstoedit__ (opts); + cmd = opts.pstoedit_cmd (opts); + gl2ps_device = {"eps"}; + pipeline = {sprintf("%s > %s", cmd, opts.name)}; case {"corel", "gif"} error ("print:unsupporteddevice", "print.m: %s output is not available for the FLTK backend.", upper (opts.devopt)) case opts.ghostscript.device - drawnow ("eps", opts.ghostscript.source); + opts.ghostscript.source = "-"; + opts.ghostscript.output = opts.name; + if (opts.send_to_printer) + opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = []; + opts.ghostscript.output = "-"; + endif + [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); + if (opts.send_to_printer || isempty (opts.name)) + cmd_lpr = opts.lpr_cmd (opts); + cmd = sprintf("%s | %s", cmd_gs, cmd_lpr); + else + cmd = sprintf("%s", cmd_gs); + endif + if (! isempty (cmd_cleanup)) + gl2ps_device = {"eps"}; + if (dos_shell) + pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; + else + pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; + endif + else + gl2ps_device = {"eps"}; + pipeline = {cmd}; + endif + otherwise + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: %s output is not available for GL2PS output.", + upper (opts.devopt)) endswitch + opts.pipeline = pipeline; + + for n = 1:numel(pipeline) + if (opts.debug) + fprintf ("fltk-pipeline: '%s'\n", pipeline{n}) + endif + pid = popen (pipeline{n}, "w"); + if (pid < 0) + error ("print:popenfailed", "print.m: failed to open pipe."); + endif + unwind_protect + drawnow (gl2ps_device{n} , sprintf ("%d" , pid)); + waitpid (pid); + unwind_protect_cleanup + pclose (pid); + end_unwind_protect + endfor + endfunction -function status = __fig2dev__ (opts, figfile, devopt, devfile) - persistent warn_on_absence = true - if (nargin < 4) - devfile = opts.name; - endif - if (nargin < 3) - devopt = opts.devopt; - endif - if (! isempty (opts.fig2dev_binary)) - cmd = sprintf ("%s -L %s %s %s 2>&1", opts.fig2dev_binary, devopt, - figfile, devfile); - [status, output] = system (cmd); - if (opts.debug || status != 0) - fprintf ("fig2dev command: %s", cmd) - endif - if (status != 0) - disp (output) - warning ("print:fig2devfailed", "print.m: error running fig2dev.") - endif - elseif (isempty (opts.fig2dev_binary) && warn_on_absence) - warning ("print:nofig2dev", "print.m: 'fig2dev' not found in EXEC_PATH.") - warn_on_absence = false; - endif -endfunction - -function status = __pstoedit__ (opts, devopt, name) - persistent warn_on_absence = true - if (nargin < 3) - name = opts.name; - endif - if (nargin < 2) - devopt = opts.devopt; - endif - if (! isempty (opts.pstoedit_binary)) - tmp_epsfile = strcat (tmpnam (), ".eps"); - unwind_protect - drawnow ("eps", tmp_epsfile) - if (opts.tight_flag) - __tight_eps_bbox__ (opts, tmp_epsfile); - endif - cmd = sprintf ("%s -f %s %s %s 2>&1", opts.pstoedit_binary, devopt, - tmp_epsfile, name); - [status, output] = system (cmd); - if (opts.debug || status != 0) - fprintf ("pstoedit command: %s", cmd) - endif - if (status != 0) - disp (output) - warning ("print:pstoeditfailed", "print.m: error running pstoedit.") - endif - unwind_protect_cleanup - [status, output] = unlink (tmp_epsfile); - if (status != 0) - warning ("print.m: %s, '%s'.", output, tmp_epsfile) - endif - end_unwind_protect - elseif (isempty (opts.pstoedit_binary) && warn_on_absence) - warning ("print:nopstoedit", "print.m: 'pstoedit' not found in EXEC_PATH.") - warn_on_absence = false; - endif -endfunction - -function __latex_standalone__ (latexfile) - prepend = {"\\documentclass{minimal}"; - "\\usepackage{epsfig,color}"; - "\\begin{document}"; - "\\centering"}; - postpend = {"\\end{document}"}; - fid = fopen (latexfile, "r"); - if (fid >= 0) - latex = fscanf (fid, "%c", Inf); - status = fclose (fid); - if (status != 0) - error ("print:errorclosingfile", - "print.m: error closing file '%s'", latexfile) - endif - else - error ("print:erroropeningfile", - "print.m: error opening file '%s'", latexfile) - endif - fid = fopen (latexfile, "w"); - if (fid >= 0) - fprintf (fid, "%s\n", prepend{:}); - fprintf (fid, "%s", latex); - fprintf (fid, "%s\n", postpend{:}); - status = fclose (fid); - if (status != 0) - error ("print:errorclosingfile", - "print.m: error closing file '%s'", latexfile) - endif - else - error ("print:erroropeningfile", - "print.m: error opening file '%s'", latexfile) - endif -endfunction - -
--- a/scripts/plot/__gnuplot_print__.m +++ b/scripts/plot/__gnuplot_print__.m @@ -27,6 +27,8 @@ function opts = __gnuplot_print__ (opts) + dos_shell = (ispc () && ! isunix ()); + if (isempty (opts.fontsize)) ## If no fontsize, determine the nominal axes fontsize. defaultfontsize = get (0, "defaultaxesfontsize"); @@ -44,12 +46,27 @@ ## the font spec given in "set terminal ..." gp_opts = font_spec (opts); + pipeline = ""; + switch lower (opts.devopt) case {"eps", "eps2", "epsc", "epsc2"} if (any (strcmp (opts.devopt, {"eps", "epsc"}))) gp_opts = sprintf ("%s level1", gp_opts); endif - eps_drawnow (opts, opts.name, gp_opts); + if (opts.tight_flag || ! isempty (opts.preview)) + tmp_file = strcat (tmpnam (), ".eps"); + eps_drawnow (opts, tmp_file, gp_opts); + if (dos_shell) + cleanup = sprintf (" & delete %s", tmp_file); + else + cleanup = sprintf (" ; rm %s", tmp_file); + endif + pipeline = {sprintf("%s %s", + opts.epstool_cmd (opts, tmp_file, opts.name), + cleanup)}; + else + eps_drawnow (opts, opts.name, gp_opts); + endif case {"epslatex", "pslatex", "pstex", "epslatexstandalone"} dot = find (opts.name == ".", 1, "last"); if ((! isempty (dot)) @@ -71,30 +88,77 @@ endif local_drawnow (sprintf ("%s %s", term, gp_opts), strcat (name, ".", suffix), opts) - if (opts.tight_flag && strncmpi (opts.devopt, "eps", 3)) - __tight_eps_bbox__ (opts, strcat (name, "-inc.eps")); + case {"tikz"} + if (__gnuplot_has_terminal__ ("tikz")) + local_drawnow (sprintf ("lua tikz %s", gp_opts), opts.name, opts); + else + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: '%s' output is not available for Gnuplot-%s.", + upper (opts.devopt), __gnuplot_version__ ()) endif - case {"tikz"} - local_drawnow (sprintf ("lua tikz %s", gp_opts), opts.name, opts); case {"svg"} local_drawnow (sprintf ("svg dynamic %s", gp_opts), opts.name, opts); - case {"aifm", "corel", "eepic", "emf", "fig", "pdfcairo", "pngcairo"} + case {"aifm", "corel", "eepic", "emf", "fig"} local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); + case {"pdfcairo", "pngcairo"} + if (__gnuplot_has_terminal__ (opts.devopt)) + local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); + else + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: '%s' output is not available for Gnuplot-%s.", + upper (opts.devopt), __gnuplot_version__ ()) + endif case {"canvas", "dxf", "hpgl", "mf", "gif", "pstricks", "texdraw"} local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts) case opts.ghostscript.device - if (opts.formatted_for_printing) - ## Gnuplot's BBox LLHC is located at [50,50] - opts.ghostscript.pageoffset = opts.ghostscript.pageoffset - 50; + gp_opts = font_spec (opts, "devopt", "eps"); + opts.ghostscript.output = opts.name; + opts.ghostscript.source = strcat (tmpnam (), ".eps"); + eps_drawnow (opts, opts.ghostscript.source, gp_opts); + [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); + if (opts.send_to_printer || isempty (opts.name)) + cmd_lpr = opts.lpr_cmd (opts); + cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr); + else + cmd = sprintf ("%s", cmd_gs); endif - gp_opts = font_spec (opts, "devopt", "eps"); - eps_drawnow (opts, opts.ghostscript.source, gp_opts); + if (dos_shell) + cmd = sprintf ("%s & delete %s", cmd, opts.ghostscript.source); + else + cmd = sprintf ("%s ; rm %s", cmd, opts.ghostscript.source); + endif + if (! isempty (cmd_cleanup)) + if (dos_shell) + pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; + else + pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; + endif + else + pipeline = {cmd}; + endif otherwise error (sprintf ("print:no%soutput", opts.devopt), - "print.m: %s output is not available for the GNUPLOT backend.", + "print.m: %s output is not available for the Gnuplot backend.", upper (opts.devopt)) endswitch + + opts.pipeline = pipeline; + + for n = 1:numel(pipeline) + if (opts.debug) + fprintf ("gnuplot-pipeline: '%s'\n", pipeline{n}) + endif + [status, output] = system (pipeline{n}); + if (status) + fprintf ("%s\n%s\n%s\n", + "---------- output begin ----------", + output, + "----------- output end -----------"); + error ("gnuplot:failedpipe", "print: Failed to print.") + endif + endfor + endfunction function eps_drawnow (opts, epsfile, gp_opts) @@ -104,9 +168,6 @@ set (h(n), "fontsize", 2 * fontsize{n}); endfor local_drawnow (sprintf ("postscript eps %s", gp_opts), epsfile, opts); - if (opts.tight_flag) - __tight_eps_bbox__ (opts, epsfile); - endif unwind_protect_cleanup for n = 1:numel(h) set (h(n), "fontsize", fontsize{n});
--- a/scripts/plot/__print_parse_opts__.m +++ b/scripts/plot/__print_parse_opts__.m @@ -26,11 +26,14 @@ function arg_st = __print_parse_opts__ (varargin) + persistent warn_on_missing_binary = true + arg_st.append_to_file = false; arg_st.canvas_size = []; arg_st.debug = false; arg_st.debug_file = "octave-print-commands.log"; arg_st.devopt = ""; + arg_st.epstool_binary = __quote_path__ (__find_binary__ ("epstool")); arg_st.figure = get (0, "currentfigure"); arg_st.fig2dev_binary = __quote_path__ (__find_binary__ ("fig2dev")); arg_st.fontsize = ""; @@ -48,15 +51,17 @@ arg_st.ghostscript.resolution = 150; arg_st.ghostscript.antialiasing = false; arg_st.loose = false; + arg_st.lpr_binary = __quote_path__ (__find_binary__ ("lpr")); arg_st.name = ""; arg_st.orientation = ""; arg_st.pstoedit_binary = __quote_path__ (__find_binary__ ("pstoedit")); + arg_st.preview = ""; arg_st.printer = ""; arg_st.send_to_printer = false; arg_st.special_flag = "textnormal"; arg_st.tight_flag = false; arg_st.use_color = 0; # 0=default, -1=mono, +1=color - + if (isunix ()) arg_st.lpr_options = "-l"; elseif (ispc ()) @@ -67,7 +72,7 @@ arg_st.unlink = {}; for i = 1:nargin - arg = varargin{i}; + arg = strtrim (varargin{i}); if (ischar (arg)) if (strcmp (arg, "-color")) arg_st.use_color = 1; @@ -91,6 +96,8 @@ arg_st.tight_flag = false; elseif (strcmp (arg, "-textspecial")) arg_st.special_flag = "textspecial"; + elseif (any (strcmp (arg, {"-interchange", "-metafile", "-pict", "-tiff"}))) + arg_st.preview = arg(2:end); elseif (strncmp (arg, "-debug", 6)) arg_st.debug = true; arg_st.ghostscript.debug = true; @@ -101,6 +108,12 @@ arg_st.devopt = tolower (arg(3:end)); elseif (length (arg) > 2 && arg(1:2) == "-P") arg_st.printer = arg; + elseif (strncmp (arg, "-EPSTOOL:", 9)) + arg_st.epstool_binary = arg{10:end}; + elseif (strncmp (arg, "-FIG2DEV:", 9)) + arg_st.fig2dev_binary = arg{10:end}; + elseif (strncmp (arg, "-PSTOEDIT:", 9)) + arg_st.pstoedit_binary = arg{10:end}; elseif ((length (arg) > 2) && arg(1:2) == "-G") arg_st.ghostscript.binary = file_in_path (EXEC_PATH, arg(3:end)); if (isempty (arg_st.ghostscript.binary)) @@ -198,7 +211,8 @@ "pslatexstandalone", "pdflatexstandalone", ... "pstex", "tiff", "tiffn" "tikz", "pcxmono", ... "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ... - "ppm", "ppmraw", "pdflatex"}; + "ppm", "ppmraw", "pdflatex", "texdraw", ... + "pdfcairo", "pngcairo", "pstricks"}; suffixes = {"ai", "cdr", "fig", "png", "jpg", ... "gif", "pbm", "pbm", "dxf", "mf", ... @@ -208,7 +222,8 @@ "tex", "tex", ... "ps", "tiff", "tiff", "tikz", "pcx", ... "pcx", "pcx", "pcx", "pgm", "pgm", ... - "ppm", "ppm", "tex"}; + "ppm", "ppm", "tex", "tex", ... + "pdf", "png", "tex"}; if (isfigure (arg_st.figure) && strcmp (get (arg_st.figure, "__backend__"), "gnuplot") @@ -238,7 +253,8 @@ "ps", "ps2", "psc", "psc2", "pdf"}))) have_ghostscript = ! isempty (__ghostscript_binary__ ()); if (have_ghostscript) - file_exists = ((numel (dir (arg_st.name)) == 1) && (! isdir (arg_st.name))); + file_exists = ((numel (dir (arg_st.name)) == 1) + && (! isdir (arg_st.name))); if (! file_exists) arg_st.append_to_file = false; end @@ -247,17 +263,14 @@ warning ("print.m: appended output requires ghostscript to be installed.") endif else - warning ("print.m: appended output is not supported for device '%s'", arg_st.devopt) + warning ("print.m: appended output is not supported for device '%s'", + arg_st.devopt) arg_st.append_to_file = false; endif endif if (! isempty (arg_st.printer) || isempty (arg_st.name)) arg_st.send_to_printer = true; - if (isempty (arg_st.name)) - arg_st.name = strcat (tmpnam (), ".", default_suffix); - arg_st.unlink{end+1} = arg_st.name; - endif endif aliases = gs_aliases (); @@ -290,8 +303,8 @@ if (isempty (arg_st.canvas_size)) if (isfigure (arg_st.figure)) - [arg_st.ghostscript.papersize, paperposition] = gs_papersize (arg_st.figure, - arg_st.orientation); + [arg_st.ghostscript.papersize, paperposition] = ... + gs_papersize (arg_st.figure, arg_st.orientation); else ## allows tests to be run arg_st.ghostscript.papersize = "letter"; @@ -309,6 +322,25 @@ if (arg_st.formatted_for_printing) arg_st.ghostscript.resolution = []; + else + arg_st.ghostscript.papersize = ""; + arg_st.ghostscript.pageoffset = [0, 0]; + endif + + if (warn_on_missing_binary) + if (isempty (arg_st.ghostscript.binary)) + warning ("print:missinggs", "print.m: Ghostscript binary is not available.") + endif + if (isempty (arg_st.epstool_binary)) + warning ("print:missinggs", "print.m: epstool binary is not available.") + endif + if (isempty (arg_st.fig2dev_binary)) + warning ("print:missinggs", "print.m: fig2dev binary is not available.") + endif + if (isempty (arg_st.pstoedit_binary)) + warning ("print:missinggs", "print.m: pstoedit binary is not available.") + endif + warn_on_missing_binary = false; endif endfunction @@ -318,12 +350,8 @@ %! assert (opts.devopt, "pswrite"); %! assert (opts.use_color, 1); %! assert (opts.send_to_printer, true); -%! assert (opts.name, opts.unlink{1}) %! assert (opts.canvas_size, [576, 432]); %! assert (opts.ghostscript.device, "pswrite") -%! for n = 1:numel(opts.unlink) -%! unlink (opts.unlink{n}); -%! endfor %!test %! opts = __print_parse_opts__ ("test.pdf", "-S640,480"); @@ -332,26 +360,18 @@ %!test %! opts = __print_parse_opts__ ("-dpsc", "-append", "-loose"); %! assert (opts.devopt, "pswrite"); -%! assert (opts.name(end+(-2:0)), ".ps"); %! assert (opts.send_to_printer, true); %! assert (opts.use_color, 1); %! assert (opts.append_to_file, false); %! assert (opts.ghostscript.device, "pswrite") %! assert (opts.ghostscript.epscrop, false); -%! for n = 1:numel(opts.unlink) -%! unlink (opts.unlink{n}); -%! endfor %!test %! opts = __print_parse_opts__ ("-deps", "-tight"); -%! assert (opts.name, opts.unlink{1}) %! assert (opts.tight_flag, true); %! assert (opts.send_to_printer, true); %! assert (opts.use_color, -1); %! assert (opts.ghostscript.device, "") -%! for n = 1:numel(opts.unlink) -%! unlink (opts.unlink{n}); -%! endfor %!test %! opts = __print_parse_opts__ ("-djpg", "foobar", "-mono", "-loose"); @@ -359,6 +379,8 @@ %! assert (opts.name, "foobar.jpg") %! assert (opts.ghostscript.device, "jpeg") %! assert (opts.ghostscript.epscrop, true); +%! assert (opts.ghostscript.papersize, ""); +%! assert (opts.ghostscript.pageoffset, [0, 0]); %! assert (opts.send_to_printer, false); %! assert (opts.printer, ""); %! assert (opts.use_color, -1); @@ -374,16 +396,11 @@ %!test %! opts = __print_parse_opts__ ("-f5", "-dljet3"); -%! assert (opts.name, opts.unlink{1}) -%! assert (opts.ghostscript.output, opts.unlink{1}) %! assert (opts.ghostscript.device, "ljet3") %! assert (strfind (opts.ghostscript.output, ".ljet3")) %! assert (opts.devopt, "ljet3") %! assert (opts.send_to_printer, true); %! assert (opts.figure, 5) -%! for n = 1:numel(opts.unlink) -%! unlink (opts.unlink{n}); -%! endfor function cmd = __quote_path__ (cmd) if (any (cmd == " ") && ! (cmd(1) == """" && cmd(end) == """"))
--- a/scripts/plot/print.m +++ b/scripts/plot/print.m @@ -194,9 +194,24 @@ ## To specify screen resolution, use "-r0". ## ## @item -tight -## Forces a tight bounding box for eps-files. Since Ghostscript -## is used to produce other devices, this option works for those -## devices as well. +## Forces a tight bounding box for eps-files. +## +## @item -@var{preview} +## Adds a preview to eps-files. Supported formats are; +## +## @table @code +## @item -interchange +## Provides a interchange preview. +## +## @item -metalfile +## Provides a metafile preview. +## +## @item -pict +## Provides pict preview. +## +## @item -tiff +## Provides a tiff preview. +## @end table ## ## @item -S@var{xsize},@var{ysize} ## Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG. For @@ -220,6 +235,12 @@ opts = __print_parse_opts__ (varargin{:}); + opts.pstoedit_cmd = @pstoedit; + opts.fig2dev_cmd = @fig2dev; + opts.latex_standalone = @latex_standalone; + opts.lpr_cmd = @lpr; + opts.epstool_cmd = @epstool; + if (! isfigure (opts.figure)) error ("print: no figure to print.") endif @@ -227,21 +248,15 @@ orig_figure = get (0, "currentfigure"); figure (opts.figure) - if (opts.append_to_file && ! (strncmp (opts.devopt, "pdf", 3) - || strncmp (opts.devopt(1:2), "ps", 2))) - warning ("print:cannotappendfile", - "print.m: Cannot append files of type '%s'.", opts.devopt) - opts.append_to_file = false; + if (opts.append_to_file) + [~, ~, ext] = fileparts (opts.ghostscript.output); + opts.ghostscript.prepend = strcat (tmpnam (), ext); + movefile (opts.ghostscript.output, opts.ghostscript.prepend); + opts.unlink{end+1} = opts.ghostscript.prepend; endif unwind_protect - if (opts.append_to_file) - saved_original_file = strcat (tmpnam (), ".", opts.devopt); - opts.unlink(end+1) = {saved_original_file}; - movefile (opts.name, saved_original_file); - endif - ## Modify properties as specified by options props = []; @@ -328,81 +343,13 @@ endif endif - if (strcmp (opts.devopt, opts.ghostscript.device)) - opts.ghostscript.output = opts.name; - opts.ghostscript.source = strcat (tmpnam (), ".eps"); - opts.unlink{end+1} = opts.ghostscript.source; - endif - ## call the backend print script - opts = feval (strcat ("__", get (opts.figure, "__backend__"), "_print__"), - opts); - - if (strcmp (opts.devopt, opts.ghostscript.device)) - if (opts.tight_flag && ! opts.formatted_for_printing) - __tight_eps_bbox__ (opts, opts.ghostscript.source); - endif - status = __ghostscript__ (opts.ghostscript); - if (status != 0) - warning ("print.m:gsfailed", "print.m: ghostscript failure") - endif - endif - - ## Send to the printer - if (opts.send_to_printer) - if (isempty (opts.ghostscript.output)) - prn_datafile = opts.name; - else - prn_datafile = opts.ghostscript.output; - endif - if (isempty (opts.printer)) - prn_cmd = sprintf ("lpr %s '%s' 2>&1", opts.lpr_options, prn_datafile); - else - prn_cmd = sprintf ("lpr %s -P %s '%s' 2>&1", opts.lpr_options, - opts.printer, prn_datafile); - endif - if (opts.debug) - fprintf ("lpr command: %s\n", prn_cmd) - [status, output] = system ("lpq"); - disp (output) - endif - [status, output] = system (prn_cmd); - if (status != 0) - disp (output) - warning ("print.m: printing failed.") - endif - endif - - ## Append to file using GS - if (opts.append_to_file) - if (strncmp (opts.devopt, "pdf", 3)) - suffix = "pdf"; - device = suffix; - elseif (strncmp (opts.devopt(1:2), "ps", 2)) - ## FIXME - For FLTK & Gnuplot the fonts get mangled - ## See "How to concatenate several PS files" at the link, - ## http://en.wikibooks.org/wiki/PostScript_FAQ - suffix = "ps"; - device = suffix; - endif - tmp_combined_file = strcat (tmpnam (), ".", suffix); - opts.unlink{end+1} = tmp_combined_file; - gs_opts = "-dQUIET -dNOPAUSE -dBATCH -dSAFER -dFIXEDMEDIA"; - gs_cmd = sprintf ("%s %s -sDEVICE=%swrite -sOutputFile=%s %s %s", - opts.ghostscript.binary, gs_opts, device, tmp_combined_file, - saved_original_file, opts.name); - [status, output] = system (gs_cmd); - if (opts.debug) - fprintf ("Append files: %s\n", gs_cmd); - endif - if (status != 0) - warning ("print:failedtoappendfile", - "print.m: failed to append output to file '%s'.", opts.name) - copyfile (saved_original_file, opts.name); - else - copyfile (tmp_combined_file, opts.name); - endif - endif + switch get (opts.figure, "__backend__") + case "gnuplot" + opts = __gnuplot_print__ (opts); + otherwise + opts = __fltk_print__ (opts); + endswitch unwind_protect_cleanup ## restore modified properties @@ -426,3 +373,236 @@ endif endfunction + +function cmd = epstool (opts, filein, fileout) + ## As epstool does not work with pipes, a subshell is used to + ## permit piping. Since this solution does not work with the DOS + ## command shell, the -tight and -preview options are disabled if + ## output must be piped. + + ## DOS Shell: + ## copy con <filein> & epstool -bbox -preview-tiff <filein> <fileout> & delete <filein> + ## Unix Shell; + ## cat > <filein> ; epstool -bbox -preview-tiff <filein> <fileout> ; rm <filein> + + dos_shell = (ispc () && ! isunix ()); + + cleanup = ""; + if (nargin < 3) + fileout = opts.name; + elseif (isempty (fileout)) + fileout = "-"; + endif + + if (nargin < 2 || strcmp (filein, "-") || isempty (filein)) + pipein = true; + filein = strcat (tmpnam (), ".eps"); + if (dos_shell) + cleanup = sprintf ("& delete %s ", filein); + else + cleanup = sprintf ("; rm %s ", filein); + endif + else + pipein = false; + filein = strcat ("'", strtrim (filein), "'"); + endif + if (strcmp (fileout, "-")) + pipeout = true; + fileout = strcat (tmpnam (), ".eps"); + if (dos_shell) + cleanup = horzcat (cleanup, sprintf ("& delete %s ", fileout)); + else + cleanup = horzcat (cleanup, sprintf ("; rm %s ", fileout)); + endif + else + pipeout = false; + fileout = strcat ("'", strtrim (fileout), "'"); + endif + + if (! isempty (opts.preview) && opts.tight_flag) + warning ("print:previewandtight", + "print.m: eps preview may not be combined with -tight.") + endif + if (! isempty (opts.preview) || opts.tight_flag) + if (! isempty (opts.epstool_binary)) + if (opts.tight_flag) + cmd = "--copy --bbox"; + elseif (! isempty (opts.preview)) + switch opts.preview + case "tiff" + cmd = sprintf ("--add-%s-preview --device tiffg3", opts.preview); + case {"tiff6u", "tiff6p", "metafile"} + cmd = sprintf ("--add-%s-preview --device bmpgray", opts.preview); + case {"tiff4", "interchange"} + cmd = sprintf ("--add-%s-preview", opts.preview); + case "pict" + cmd = sprintf ("--add-%s-preview --mac-single", opts.preview); + otherwise + error ("print:invalidpreview", + "print.m: epstool cannot include preview for format '%s'", + opts.preview); + endswitch + if (! isempty (opts.ghostscript.resolution)) + cmd = sprintf ("%s --dpi %d", cmd, opts.ghostscript.resolution); + endif + else + cmd = ""; + endif + if (! isempty (cmd)) + cmd = sprintf ("%s --quiet %s %s %s ", opts.epstool_binary, + cmd, filein, fileout); + endif + if (pipein) + if (dos_shell) + cmd = sprintf ("copy con %s & %s", filein, cmd); + else + cmd = sprintf ("cat > %s ; %s", filein, cmd); + endif + endif + if (pipeout) + if (dos_shell) + cmd = sprintf ("%s & type %s", cmd, fileout); + else + cmd = sprintf ("%s ; cat %s", cmd, fileout); + endif + endif + if (! isempty (cleanup)) + if (pipeout && dos_shell) + error ("print:epstoolpipe", + "print.m: cannot pipe output of 'epstool' for DOS shell.") + elseif (pipeout) + cmd = sprintf ("( %s %s )", cmd, cleanup); + else + cmd = sprintf ("%s %s", cmd, cleanup); + endif + endif + elseif (isempty (opts.epstool_binary)) + error ("print:noepstool", "print.m: 'epstool' not found in EXEC_PATH.") + endif + else + if (pipein && pipeout) + if (dos_shell) + cmd = sprintf ("copy con %s & type %s", filein, fileout); + else + cmd = " cat "; + endif + elseif (pipein && ! pipeout) + if (dos_shell) + cmd = sprintf (" copy con %s ", fileout); + else + cmd = sprintf (" cat > %s ", fileout); + endif + elseif (! pipein && pipeout) + if (dos_shell) + cmd = sprintf (" type %s ", filein); + else + cmd = sprintf (" cat %s ", filein); + endif + else + if (dos_shell) + cmd = sprintf (" copy %s %s ", filein, fileout); + else + cmd = sprintf (" cp %s %s ", filein, fileout); + endif + endif + endif + if (opts.debug) + fprintf ("epstool command: '%s'\n", cmd) + endif +endfunction + +function cmd = fig2dev (opts, devopt) + if (nargin < 2) + devopt = opts.devopt; + endif + dos_shell = (ispc () && ! isunix ()); + if (! isempty (opts.fig2dev_binary)) + if (dos_shell) + ## FIXME - is this the right thing to do for DOS? + cmd = sprintf ("%s -L %s 2> /dev/null", opts.fig2dev_binary, devopt); + else + cmd = sprintf ("%s -L %s 2> /dev/null", opts.fig2dev_binary, devopt); + endif + elseif (isempty (opts.fig2dev_binary)) + error ("print:nofig2dev", "print.m: 'fig2dev' not found in EXEC_PATH.") + endif + if (opts.debug) + fprintf ("fig2dev command: '%s'\n", cmd) + endif +endfunction + +function latex_standalone (latexfile) + prepend = {"\\documentclass{minimal}"; + "\\usepackage{epsfig,color}"; + "\\begin{document}"; + "\\centering"}; + postpend = {"\\end{document}"}; + fid = fopen (latexfile, "r"); + if (fid >= 0) + latex = fscanf (fid, "%c", Inf); + status = fclose (fid); + if (status != 0) + error ("print:errorclosingfile", + "print.m: error closing file '%s'", latexfile) + endif + else + error ("print:erroropeningfile", + "print.m: error opening file '%s'", latexfile) + endif + fid = fopen (latexfile, "w"); + if (fid >= 0) + fprintf (fid, "%s\n", prepend{:}); + fprintf (fid, "%s", latex); + fprintf (fid, "%s\n", postpend{:}); + status = fclose (fid); + if (status != 0) + error ("print:errorclosingfile", + "print.m: error closing file '%s'", latexfile) + endif + else + error ("print:erroropeningfile", + "print.m: error opening file '%s'", latexfile) + endif +endfunction + +function cmd = lpr (opts) + if (nargin < 2) + devopt = opts.devopt; + endif + if (! isempty (opts.lpr_binary)) + cmd = opts.lpr_binary; + if (! isempty (opts.lpr_options)) + cmd = sprintf ("%s %s", cmd, opts.lpr_options); + end + if (! isempty (opts.printer)) + cmd = sprintf ("%s -P %s", cmd, opts.printer); + end + elseif (isempty (opts.lpr_binary)) + error ("print:nolpr", "print.m: 'lpr' not found in EXEC_PATH.") + endif + if (opts.debug) + fprintf ("lpr command: '%s'\n", cmd) + endif +endfunction + +function cmd = pstoedit (opts, devopt) + if (nargin < 2) + devopt = opts.devopt; + endif + dos_shell = (ispc () && ! isunix ()); + if (! isempty (opts.pstoedit_binary)) + if (dos_shell) + cmd = sprintf ("%s -f %s 2> /dev/null", opts.pstoedit_binary, devopt); + else + ## FIXME - is this the right thing to do for DOS? + cmd = sprintf ("%s -f %s 2> /dev/null", opts.pstoedit_binary, devopt); + endif + elseif (isempty (opts.pstoedit_binary)) + error ("print:nopstoedit", "print.m: 'pstoedit' not found in EXEC_PATH.") + endif + if (opts.debug) + fprintf ("pstoedit command: '%s'\n", cmd) + endif +endfunction + +
--- a/scripts/plot/private/__ghostscript__.m +++ b/scripts/plot/private/__ghostscript__.m @@ -22,21 +22,24 @@ ## Author: Ben Abbott <bpabbott@mac.com> ## Created: 2010-07-26 -function status = __ghostscript__ (varargin); +function [gs_cmd, cleanup_cmd] = __ghostscript__ (varargin); opts.binary = ""; - opts.source = ""; - opts.output = ""; + opts.source = "-"; + opts.output = "-"; opts.device = ""; opts.epscrop = false; opts.antialiasing = false; - opts.resolution = []; + opts.resolution = 150; opts.papersize = ""; opts.pageoffset = [0 0]; opts.debug = false; opts.level = []; + opts.prepend = ""; offsetfile = ""; + offset_ps = {}; + cleanup_cmd = ""; args = varargin; n = find (cellfun (@isstruct, args)); @@ -51,23 +54,22 @@ opts.(args{n}) = args{n+1}; endfor - gs_opts = sprintf ("-dQUIET -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s", - opts.device); + if (isempty (opts.papersize)) + format_for_printer = false; + else + format_for_printer = true; + endif + + gs_opts = sprintf ("-dQUIET -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s", opts.device); if (! isempty (opts.level) && ismember (opts.level, [1, 2, 3])) gs_opts = sprintf ("%s -dLanguageLevel=%d", gs_opts, round (opts.level)); endif - if (isempty (strfind (opts.device, "write"))) - ## Empirical observation: "-dpxlcolor" requires a sign change as - ## compared to pdfwrite, or pswrite output. - opts.pageoffset = opts.pageoffset .* [1, -1]; - if (! isempty (opts.resolution)) - gs_opts = sprintf ("%s -r%dx%d", gs_opts, [1, 1] * opts.resolution); - endif - if (opts.antialiasing) - gs_opts = sprintf ("%s -dTextAlphaBits=4 -dGraphicsAlphaBits=4", gs_opts); - endif + if (opts.antialiasing && isempty (strfind (opts.device, "write"))) + ## Apply anti-aliasing to all bitmap formats/devices + gs_opts = sprintf ("%s -dTextAlphaBits=4 -dGraphicsAlphaBits=4", gs_opts); + gs_opts = sprintf ("%s -r%dx%d", gs_opts, [1, 1] * opts.resolution); elseif (any (strcmp (opts.device, {"pswrite", "ps2write", "pdfwrite"}))) gs_opts = sprintf ("%s -dEmbedAllFonts=true", gs_opts); if (strcmp (opts.device, "pdfwrite")) @@ -79,7 +81,8 @@ if (opts.epscrop) ## papersize is specified by the eps bbox gs_opts = sprintf ("%s -dEPSCrop", gs_opts); - elseif (! isempty (opts.papersize)) + endif + if (format_for_printer) if (ischar (opts.papersize)) gs_opts = sprintf ("%s -sPAPERSIZE=%s", gs_opts, opts.papersize); elseif (isnumeric (opts.papersize) && numel (opts.papersize) == 2) @@ -88,25 +91,30 @@ if (opts.papersize(1) > opts.papersize(2)) ## Lanscape mode: This option will result in automatic rotation of the ## document page if the requested page size matches one - ## of the default page sizes. + ## of the default page sizes gs_opts = sprintf ("%s -dNORANGEPAGESIZE", gs_opts); endif else error ("print:badpapersize", "__ghostscript__.m: invalid 'papersize'") endif gs_opts = sprintf ("%s -dFIXEDMEDIA", gs_opts); - offsetfile = strcat (tmpnam (), ".ps"); + ## "pageoffset" is relative to the coordinates, not the BBox LLHC. + str = sprintf ("%s [%d %d] %s", "<< /Margins [0 0] /.HWMargins [0 0 0 0] /PageOffset", + opts.pageoffset, ">> setpagedevice"); + offset_ps = {"%!PS-Adobe-3.0", str, "%%EOF"}; + if (isfield (opts, "offsetfile")) + offsetfile = opts.offsetfile; + cleanup_cmd = ""; + else + offsetfile = strcat (tmpnam (), ".ps"); + cleanup_cmd = sprintf ("rm %s", offsetfile); + endif unwind_protect fid = fopen (offsetfile, "w"); - onCleanup (@() unlink (offsetfile)); if (fid == -1) error ("print:fopenfailed", "__ghostscript__.m: fopen() failed."); endif - fprintf (fid, "%s\n", "%!PS-Adobe-3.0") - ## "pageoffset" is relative to the coordinates, not the BBox LLHC. - fprintf (fid, "%s [%d %d] %s\n", "<< /Margins [0 0] /.HWMargins [0 0 0 0] /PageOffset", - opts.pageoffset, ">> setpagedevice"); - fprintf (fid, "%%EOF"); + fprintf (fid, "%s\n", offset_ps{:}) unwind_protect_cleanup status = fclose (fid); if (status == -1) @@ -114,27 +122,36 @@ endif end_unwind_protect if (opts.debug) - [~,output] = system (sprintf ("cat %s", offsetfile)); fprintf ("---- begin %s ----\n", offsetfile) - disp (output) + fprintf ("%s\n", offset_ps{:}) fprintf ("----- end %s -----\n", offsetfile) endif endif - cmd = sprintf ("%s %s -sOutputFile=%s %s %s 2>&1", - opts.binary, gs_opts, - opts.output, offsetfile, opts.source); + if (isempty (opts.output)) + cmd = sprintf ("%s %s", opts.binary, gs_opts); + else + cmd = sprintf ("%s %s -sOutputFile=%s", opts.binary, gs_opts, opts.output); + endif + if (! isempty (opts.prepend) + && any (strcmpi (opts.device, {"pswrite", "ps2write", "pdfwrite"}))) + ## FIXME - Fonts get may be mangled when appending ps/ps2. + ## See "How to concatenate several PS files" at the link, + ## http://en.wikibooks.org/wiki/PostScript_FAQ + cmd = sprintf ("%s %s", cmd, opts.prepend); + endif + if (! isempty (offsetfile) && format_for_printer) + cmd = sprintf ("%s %s", cmd, offsetfile); + endif + if (! isempty (opts.source)) + cmd = sprintf ("%s %s", cmd, opts.source); + endif if (opts.debug) - fprintf ("Ghostscript command: %s\n", cmd); + fprintf ("Ghostscript command: '%s'\n", cmd); endif - [status, output] = system (cmd); - - if (status != 0) - warning ("print:ghostscripterror", - "print.m: %s, '%s'.", output, opts.output) - endif + gs_cmd = cmd; endfunction