Viewing contents of file '../idllib/contrib/meron/output.pro'
Pro Output, comm, que = qu, file = fil, option = opt, keep = kp, beep = bp, $
    mail = nam, subst = sub, v_0, v_1, v_2, v_3, v_4, v_5, v_6, v_7

;+
; NAME:
;	OUTPUT
; VERSION:
;	3.0
; PURPOSE:
;	Generic output interface.  Allows sending the results of virtually any
;	IDL command or file to any predefined hard copy device.  In detail,
;	OUTPUT executes the provided command, writes the output to a file and 
;	sends the file to a printout que.  Currently a VMS routine only.
; CATEGORY:
;	Input/Output.
; CALLING SEQUENCE:
;	OUTPUT, COMM [, keywords] [,optional input parameters]
; INPUTS:
;    COMM
;	Character value representing a valid IDL command.  Can be (and usually
;	is) a procedure or function call.
; OPTIONAL INPUT PARAMETERS:
;    V_0 through V_7
;	Serve to pass variables which are used in the command COMM.  Since COMM
;	is passed to output as a single string, OUTPUT is not receiving the 
;	values of any variables used by COMM.  If such values are needed they
;	have to be passed separately.  This is done using the variables V_0
;	through V_7 in combination with the keyword SUBST (see below), which
;	accepts a string made of the names of the variables separated by spaces
;	or commas.
;	Example:
;	    Assume a routine named NEWPLOT which is called using the syntax
;		NEWPLOT, I, X, SCOPE = Y
;	    If at the time of call I, X, and Y have known values, say 3, 12.4
;	    and [12,95] then it is possible to issue the command
;		OUTPUT, 'NEWPLOT, 3, 12.4, SCOPE = [12,95]'
;	    If, on the other hand one would want to pass NEWPLOT to output 
;	    using the variables K, E and RANG for I, X, Y, the command can be
;		OUTPUT, 'NEWPLOT, I, X, SCOPE = Y', $
;		SUBST = 'I,X   Y', K, E, RANG
;	    The order in which the variable names appear in SUBST is arbitrary
;	    but it has to be in a one-to-one correspondence with the order in 
;	    which the actual arguments are given.  Therefore, the following is
;	    equally valid
;		OUTPUT, 'NEWPLOT, I, X, SCOPE = Y', $
;		SUBST = 'Y, I, X', RANG, K, E
; KEYWORD PARAMETERS:
;    QUE
;	Accepts a string and sets the printout queue.  Currently accepted 
;	values and the queues they represent are as follows:
;	    'LN03'	-  The LN03 printer at the X26.
;	    'SIXEL'	-  The SIXEL printer in 901.
;	    'EPS'	-  Writes an encapsulated PostScript file, no printout.
;	    'FILE'	-  Writes a PostScript file, no printout.
;	    'PHASER'	-  Phaser color printer.  Valid only in BNL.
;	    'TRANSP'	-  Phaser Printer with LEGAL sized paper.  Use this
;			   one for transparencies.
;	    'CARS1'	-  The PostScript printer at CARS1.
;	    'SYS$PRINT'	-  Generic PostScript.  This is the initial Default.
;	This is by no means the final list, as new queues keep being added from
;	time to time.  For all queues on this list only the first three 
;	characters of the name are needed as input.
;	If a queue name not on the list is entered, OUTPUT will use this name
;	with the parameters of the default queue, SYS$PRINT.  If no queue name
;	is entered, output will use SYS$PRINT when first called, and the name 
;	of the last queue used subsequently.
;    FIL
;	Accepts a string representing a valid VMS file name.  
;	Extension isn't necessery.  Default is 'IDL'.
;    /KEEP
;	Switch.  Specifies file disposition.  If set, the file is kept after 
;	printout.  The default is 'DELETE', unless the queue is 'EPS' or 'FILE'.
;    /BEEP
;	Switch.  If set, a beep will sound when OUTPUT finishes processing the 
;	file, and another beep sounds when the printout is complete.  Useful 
;	for long files.  Also, if set, the VAX verifies that the printer is on.
;    OPTION
;	Accepts a string representing a valid IDL command.  If given, this
;	command will be executed BEFORE COMM.  If the command in OPTION 
;	includes variables, their values can be passed using the same mechanism
;	as the one used for COMM (see above).
;    MAIL
;	Name of a recipient to whom the resulting file is mailed.  Optional.
;    SUBST
;	Accepts a string containing the names of the variables which are to 
;	receive the values V_0 through V_7 (or part of them) for substitution
;	purposes.  Commas and/or spaces are valid delimiters.
; OUTPUTS:
;	None, other then the file that's created and whatever outputs are 
;	generated by COMM.
; OPTIONAL OUTPUT PARAMETERS:
;	None.
; COMMON BLOCKS:
;	M_OUT_PREFS.  Contains the name of the last queue used.
; SIDE EFFECTS:
;	OUTPUT tries to avoid any side effects, as far as possible.  
;	Specifically, the values of all the system variables are reset at exit
;	from OUTPUT to the values they had before output was called.  Still,
;	since COMM can be any possible command, side effects cannot be totally
;	avoided.
;	A currently known side effect has to do with PostScript printers.  If
;	either COMM or OPTION change the postscipt settings, the new settings
;	will remain in effect after OUTPUT exits.
; RESTRICTIONS:
;    1) With IDL before version 3.1, the commands in COMM and OPTION (if used) 
;	are not allowed to use calls to the EXECUTE system routine, either 
;	directly or indirectly.  This is so since OUTPUT itself relies on 
;	EXECUTE and since EXECUTE (in older versions of IDL) could not be 
;	called recursively.
;    2) Currently the number of substitution variables is limited to 8.  If 
;	it'll turn out that this number isn't sufficient it can be easily 
;	increased.  Let me know.
;    3) The commands in COMM (and OPTION) shouldn't change the output device
;	(i.e. NO using SET_PLOT, DEVICE/CLOSE, etc., all this is taken care of
;	by OUTPUT).  If they do, no error will result but the outcome will be 
;	unpredictable.
;    4) In order to make the best use of OUTPUT it is recommended that the
;	commands in COMM will be totally device independent (i.e. no using 
;	explicit device coordinates etc.).  This allows to send the output of 
;	the same procedure to the various printers and get consistent results.
;	If one finds it necessery to use some device specific commands (like
;	setting a color table for the Phaser printer), they should be put in
;	OPTION (that's really the whole purpose of having OPTION)
; PROCEDURE:
;	OUTPUT contains a list of the appropriate device opening and closing
;	commands for the ques it recognizes.  When called, it does the 
;	following.
;	1)  Checks QUE and if recognizable generates the appropriate OPEN, 
;	CLOSE and PRINTOUT commands.  If QUE isn't recognized, OUTPUT assumes
;	SYS$PRINT.
;	2)  Performs variable substitution if so specified (by a non-blank 
;	value of SUBST)
;	3)  Opens device.
;	4)  Executes OPTION, if given.
;	5)  Executes COMM
;	6)  Closes device.
;	7)  Optionally mails the file to the specified recipient.
;	8)  Spawns PRINT command to the appropriate que (unless que = 'EPS' or 
;	'FILE' is specified).
;	9)  Deletes the file unless specified otherwise.
;
;	OUTPUT uses various routines from MIDL, namely:
;	TYPE, DEFAULT, STREQ, STRMATCH, STRPARSE and PLVAR_KEEP.
; MODIFICATION HISTORY:
;	Created 15-JUL-1991 by Mati Meron.
;	Modified 15-SEP-1991 by Mati Meron.  Added Phaser and Sixel support.
;	Modified 15-NOV-1991 by Mati Meron.  Added the 'TRANSP' que and the
;	/BEEP keyword.
;	Modified 28-DEC-1991 by Mati Meron.  Now any changes made to the color
;	table of PostScript devices by either COMM or OPTION are undone before
;	OUTPUT exits.
;	Modified 15-MAY-1993 by Mati Meron.  Added 'EPS', 'FILE' and 'CARS1'
;	queues.
;	Modified 20-NOV-1993 by Mati Meron.  Introduced SYS$PRINT as default
;	queue and maintenance of last que as current default.
;-

    common m_out_prefs, outque

    posib = ['LN03','SIXEL', 'EPS','FILE','PHASER','TRANSP','CARS1','SYS$PRINT']
    ext   = [ '.LN','.SXL.','.EPS', '.PS',   '.PS',   '.PS',  '.PS',      '.PS']
    fcod =  [0,0,1,1,0,0,0,0]
    opcom = ['ln03, outfile', $
	     'set_plot, ''SIXEL'' &device, /landscape, file = outfile', $
	     'set_plot, ''PS'' &device, /encapsulated, file = outfile', $
	     'set_plot, ''PS'' &device, /landscape, file = outfile', $
	     'set_plot, ''PS'' &device, /landscape, /color, file = outfile', $
	     'set_plot, ''PS'' &device, /landscape, /color, file = outfile', $
	     'set_plot, ''PS'' &device, /landscape, file = outfile', $
	     'set_plot, ''PS'' &device, /landscape, file = outfile']
    clcom = ['ln03','device, /close', 'device, /close', 'device, /close', $
    	    'device, /close','device, /close','device, /close','device, /close']
    npos = n_elements(posib)

    on_error, 1
    if Type(comm) ne 7 then message, 'No command on line!'
    outque = Default(qu,Default(outque,'SYS$PRINT'),/strict)
    nqu = (StrMatch(outque,posib,3) + npos) mod npos
    outfile = Default(fil,'IDL', /strict)
    if Strparse(outfile,'.') eq 0 then outfile = outfile + ext(nqu)
    if (fcod(nqu) or keyword_set(kp)) then disp = ' ' else disp = '/delete '
    if keyword_set(bp) then disp = '/notify' + disp

    if Type(sub) eq 7 then begin
	snams = ['v_0','v_1','v_2','v_3','v_4','v_5','v_6','v_7']
	vnum = Strparse(sub,' ,',vlist)
	if n_params() gt vnum then begin
	    for i_v = 0, vnum do idum = execute(vlist(i_v) + ' = ' + snams(i_v))
	endif else message, 'Insuficient number of substitution variables!'
    endif

    Plvar_keep, action = 'save'

    dum = execute(opcom(nqu))
    if !d.name eq 'PS' then tvlct, red, gre, blu, /get
    if Type(opt) ne 7 then comstat = 1 else comstat = execute(opt)
    if comstat then comstat = execute(comm)
    print, ''
    if !d.name eq 'PS' then tvlct, red, gre, blu
    dum = execute(clcom(nqu))

    Plvar_keep, action = 'restore'

    if comstat then begin
	if n_elements(nam) ne 0 then spawn, 'mail ' + outfile + ' ' + nam
	if not fcod(nqu) then begin
	    spawn, 'print/que=' + outque + disp + outfile, tem
	    print, tem
	    if Streq(tem(0),'%',1) then spawn, 'delete ' + outfile + ';'
	endif
    endif else begin
	message, 'Command errors, output file deleted!', /continue
	spawn, 'delete ' + outfile + ';'
    endelse

    if keyword_set(bp) then print, string(007B)
    return
end