From: ram@cs.umb.edu (Robert Morris)
Newsgroups: comp.text.interleaf
Subject: Re: Printers (was Interleaf to .ps conversion
Date: 21 Jul 92 14:07:45 GMT
	<1992Jul16.203026.19994@engr.latech.edu>
	<1992Jul17.211204.29826@draco.macsch.com>
Reply-To: ram@cs.umb.edu
Organization: University of Massachusetts at Boston

In article <1992Jul17.211204.29826@draco.macsch.com> todd@draco.macsch.com (Todd C. Williams) writes:

  >Path: news.cs.umb.edu!hsdndev!wupost!usc!sdd.hp.com!swrinde!elroy.jpl.nasa.gov!nntp-server.caltech.edu!draco.macsch.com!todd
  >From: todd@draco.macsch.com (Todd C. Williams)
  >Newsgroups: comp.text.interleaf
  >Date: 17 Jul 92 21:12:04 GMT
  >References: <1992Jul16.171637.10467@draco.macsch.com><1992Jul16.203026.19994@engr.latech.edu>

  >In article <1992Jul16.203026.19994@engr.latech.edu> dan@engr.latech.edu writes:
	>>I have several printers defined to Interleaf for various areas of
	>>our network.  ...the problem is that printers that are not
	>>actually available for a particular host that Interleaf is running on
	>>still show up in the menus, they don't work, but they still appear.
	>>Am I doing something wrong?

  >No.

	>>It seems to me that the menu's
	>>should only contain entries for those printers defined to the
	>>workstation Interleaf is running on. 

  >That would require more work out of the Interleaf software.


Not that much.

You can change the printer popup menu with print-set-popups. It takes
as arguments the network names of the printers you want on your menu.
Possibly you don't actually want all the printers anyway, just the
ones near you if you have a lot. In this case, the simplest call is
something like
	(print-set-popups "printer1" "printer2" "printer3")
where printerN are the network names, as many as you want.
This means that you have to change your list any time the network list
changes (you will provoke a lisp error if you mention a printer not in
your network printer list). So if you really want everything, you have
to get ileaf's idea of the network names, Unix's idea of the network
names, intersect them and apply print-set-popups to the intersection.

The code below will do that. Probably the printcap parsing can be
improved. System V printing can probably get the printer names by
executing an appropriate "ls" from lisp. I have no clue about other
kinds of network printing, but I suppose each OS must have
some way to get the network printer names.

If you want to reset your printer popups to the entire list, do
   (apply #'print-set-popups 
      (mapcar #'(lambda (printer) (getf printer :netname)) *printers*))

or simply 
    (apply #'print-set-popups (get-ileaf-printer-list))
if you have loaded my lisp.

Any of these solutions can be put in your profile, or for
slightly more maintainability, in a separate lisp file in your profile
cabinet.




Bob Morris
ram@cs.umb.edu

lisp follows on next page.


(lisp-set-implementation "Interleaf Lisp" "2.0")

;;Copyright 1992
;;Robert A. Morris
;;40 Groveland Street
;;Newton MA 02166
;;
;;Permission is granted to copy, use or modify this program
;;for any purpose except sale provided that this notice remains
;;with the copy and that source code is provided with the copy.

;; Module name: printerselect
;; Purpose: Reduce printer popup to hosts available
;; from the current host. 
;;
;; Notes: This code assumes a Berkeley Unix spooling system
;; Additional notes at end

;; Audit:
;; DD-MON-YY USERNAME		COMMENT
;; 20-07-92  ram@cs.umb.edu	initial implementation

;; Put this lisp in a file named printers.lsp in your profile
;;
;; Additional comments at end

(defvar printerselect-version 1)

(defun get-ileaf-printer-list ()
  "Return list of networks names of printers presently known to ileaf"
  (mapcar #'(lambda (printer) (getf printer :netname)) *printers*))

(defun get-network-printer-list ()
  "Return list of Berkely unix printer names from termcap file"
;; This is the unpleasant part. System V may be easier, since
;; printer names come from the file system entries
;;
;;     Printer names are uniquely determined (?) by strings which
;; 1. are in a line not beginning with whitespace or #
;; 2. are terminated by | or :
;;
;; Probably there is some simpler way to parse the termcap lines
;; but I don't know all the Lisp string handling capability. Suggestions
;; welcome.

  (let* ((istream (open "/etc/printcap" :input))
	 line names)
     (while (not (eql 'eof (setq line (read-line istream))))
      (when (and (> (length line) 0)
		 (not (member (char line 0) '(#\# #\\t #\ ))))
	    (setq names (append (get-printer-names line) names)))
    names)))

(defun get-printer-names (line)
  "Parse a Berkeley printcap string LINE assumed to have printer names and
return a list of those names as strings"
  ;; strip trailing "\" from the line
  (setq line (string-right-trim "#\\" line))
  (let (namelist delim name)
    (while (> (length line) 0)				;find first "|" or ":"
      (when (not (setq delim (position '#\| line)))
	    (setq delim (position '#\: line))) ;should handle failure here too
      (setq 
       name (subseq line 0 delim)
       namelist (cons name namelist)
       line (subseq line (1+ delim))))
    namelist))

(defun intersection (l1 l2)
"Return intersection of lists L1 L2 of strings"
;;Hey this is in Common Lisp. Interleaf should provide it, and
;;better than this one...
  (let (intersection item)
    (while l1
      (when (member  (setq item (pop l1)) l2 #'string-equal)
	  (push item intersection)))
    intersection))

(defun set-my-printers (network-list ileaf-list)
  "Set the list of printers to the intersection of 
NETWORK-LIST and ILEAF-LIST so only printers accessible from
this host are seen on the printer menu"
  (when *printers*
	(apply #'print-set-popups  (intersection network-list ileaf-list))))


(set-my-printers (get-network-printer-list) (get-ileaf-printer-list))



;; Comments
;;If you really only want a small collection of printers, do
;;	(print-set-popups NAME*) 
;;where NAME's are the strings naming the printers
;;you want to see. 

;;If you want to avoid errors should you name printers
;;which don't exist, try an appropriate modification of
;;	(let ( (my-list '("printer1" "printer2")))
;;  	   (set-my-printers my-list (get-ileaf-printer-list)))

;; To reset the printers to the original list do
;;	(apply #'print-set-popups (get-ileaf-printer-list))

;; Putting calls to such things in your Custom->NoSelection cabinet
;; might make their use easier
Newsgroups: comp.text.interleaf