Hardcopy to a printer ?
This used to work for me, but it doesn't now. If anybody else has a printer, can you try using the hardcopy button on, say, a Tedit window, or copying an existing PDF file to {LPT} ?
I get a message lpr: No such file or directory
I've tried printing on Linux Mint 22.1 Cinnamon to a Brother HL-L2340DW laser unit.
From TEdit, Hardcopy > To a printer > (Default printer) does nothing. Sometimes the (Default printer) menu item is missing, only Other is present and entering {LPT} yields the error:
`Spooling output to Unix printer '{LPT}'...lpr: Error - The printer or class does not exist.`
Hardcopy > To a printer > {LPT} yields the same error.
Copying to the printer yields the error too:
12_ (COPYFILE 'BITMAPFNS.PDF '{LPT})
{LPT}BITMAPFNS.PDF;1
OK, thanks for testing.
Looking at SEND.FILE.TO.PRINTER, it sees like it is somehow confusing the name of the file with the name of the printer. This is the command string that gets passed to the shell:
lpr -PGITFNS -JMedley\ Output -r -s /tmp/medleyprint.17875806041
Maybe this is a pdf problem. Why did it need to make a tmp file, if it was already a pdf?
(I'm on a Mac running Sequoia 15.16.1)
On Sep 11, 2025, at 10:20 AM, Paolo Amoroso @.***> wrote:
pamoroso left a comment (Interlisp/medley#2289) https://github.com/Interlisp/medley/issues/2289#issuecomment-3281974392 I've tried printing on Linux Mint 22.1 Cinnamon to a Brother HL-L2340DW laser unit.
From TEdit, Hardcopy > To a printer > (Default printer) does nothing. Sometimes the (Default printer) menu item is missing, only Other is present and entering {LPT} yields the error:
Spooling output to Unix printer '{LPT}'...lpr: Error - The printer or class does not exist.Hardcopy > To a printer > {LPT} yields the same error.Copying to the printer yields the error too:
12_ (COPYFILE 'BITMAPFNS.PDF '{LPT}) {LPT}BITMAPFNS.PDF;1 — Reply to this email directly, view it on GitHub https://github.com/Interlisp/medley/issues/2289#issuecomment-3281974392, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSTUJJK3BQMJH6DE2G7R233SGVOJAVCNFSM6AAAAACGILTE42VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEOBRHE3TIMZZGI. You are receiving this because you authored the thread.
It seems that the problem is in PRINTERDEVICE, which I last worked on in 96 (and Herb wrote in 86).
When a file is copied to {LPT}, it is first copied to the {LPT} file device, an instance of CORE. So GITFNS.PDF gets copied to {LPT}GITFNS.PDF. The LPT device has a CLOSEFILE method that calls SEND.FILE.TO.PRINTER with the file. But it first tries to get the printer HOST name from the file name. But it's not getting LPT, the host name, it's getting GITFNS. So it thinks that that's the name of the printer, which it can't find.
This worked about a year ago, as I remember, not sure what changed.
I think the idea must have been that {LPT} is the device for all printers, and {LPT}FOO. (it scans for the period) is the name of printer FOO. But it is getting {LPT}GITFNS.PDF. In the Venue sysout, it gets {LPT}.
But it's also not clear to me why it needs to copy the file to the LPT/corefile device and then copy it to /tmp/, if the file already exists in a local Unix directory. But there may be no way around that if the top-level call is COPYFILE, as opposed to a more specific call to a hardcopy function.
At least one problem seems to be in DIRECTORYNAMEP, as it is called from COPYFILE.
When FROMFILE is GITFNS.PDF and TOFILE is {LPT}, the first argument to DIRECTORYNAMEP is the empty atom ||(what you get by deleting the host LPT from {LPT}). The second argument is just LPT.
In our current system, DIRECTORYNAMEP returns T for these arguments, essentially saying that the empty directory exists for host LPT. The Venue sysout returns NIL.
This may be a consequences of changes that were made to UNPACKFILENAME in the last year or so, probably in response to the discussion of funky behavior when the directory field is empty #1685
Well, it seems that \CORE.DIRECTORYNAMEP in the Venue sysout had a specific test to say No for the empty directory, that got lost along the way. Unix/Dsk devices say Yes then and now.
In my opinion, {LPT} and hardcopy printing is ripe for "modernization". I think (at least for the default) of "Hardcopy" commands (especially for "online"). should produce a PDF (or HTML?) file and bring it up in a browser window and /or copy it to the clupboard.
If you really want to print something, print from the browser window opened to show the file.
We could go that route, not try to deal with printers.
But in the meantime, I have fixed up the \CORE.DIRECTORYNAMEP and the PRINTERDEVICE function to do better. The problem was introduced, I think, when the core directory function was made more honest, to actually report directories that actually exist, as opposed to any string.
There is still one glitch: When I try to print the previously created GITFNS.PDF file by the COPYFILE, it only prints part of the first page. But the file is good, when I bring it up in a browser and print it from there. The file is already in Unix, not sure if/why it is trying to do another copy
On the last glitch...
At the bottom it calls UnixPrint to copy the file to the Unix file system, and then calls ShellCommand to print the now-native file.
The problem is that it is using COPYCHARS to do the copy, not COPYBYTES. It looks to COPYCHARS like the files have different EOL conventions, even though they both have the same external format, and thus it copies character by character and presumably fiddles the EOL's. The most visible effect is that part of the first page drops out.
I'm not sure whether it is correct to always call COPYBYTES directly, assuming that the file is already set up properly for the lpr command. In any event, in this case it seems like it should test to see whether the file is already in the Unix/Dsk file device, and not do any copying at all.
I've looked more carefully at the printer/hardcopy/imagefile interfaces a pretzel that needs to be untwisted.
As I mentioned in the 9/15/25 technical meeting, I think the code for creating image files and the code for actually printing them are pretty tangled up. This is probably a legacy of the fact that this was all done in the 90's at a time when there were no ways of viewing image files (e.g. interpress, press) on the display--the only way to see them was to send them to a printer. So printers and hardcopy were the leading concepts. (Also, at Xerox, printers paid our salaries).
I have made a pass through the code, providing a function MAKE.IMAGEFILE that returns for an input file a corresponding imagefile of a requested type, without regard to the source of that type-request. The primitive SEND.FILE.TO.PRINTER separately calls that if it is asked to print a file on a printer and the file is not yet of a type that that printer can print. Under most modern scenarios (and perhaps with a helpful revision to highlight the file case from the printing case in some of the menus or their interpretation), SEND.FILE.TO.PRINTER would not be involved.
There are other higher-level functions that try to figure out which printer to go for, either because it is specified explicitly or, if the file is already an image file, because it's the first printer on the default printer list that can print that type.
There was a provision in the code whereby a high-level caller could pass in a printer+type combination request (e.g. by copying a file to a printer file-device {LPT}printer.type). Seems odd (and overly complicated) that the user would care to specify the type along with the printer. If a printer can only print one format and it isn't the one specified, then the only thing to do is to cause an error. And if can print several formats and files can be converted to any of them, is there any point in stipulating a preference? I'm going to ignore the type specification in this situation.
With respect to our PDF hack, I have extracted a separate function PS-TO-PDF that can be called on any PS file and will return a corresponding PDF file (by copying in and out of the Unix file system, as necessary). This works even if the PS is a Medley stream that doesn't exist in the Unix file system (e.g. NODIRCORE--the bytes get copied back into that stream-handle).
I changed the implementation of PDF imagestreams so that they have a copy of the postscript IMAGEOPS with IMAGETYPE set to PDF and a IMCLOSEFN that calls the PS closefn on the stream and then passes it to PS-TO-PDF, copying the PDF bytes back into the original Medley level file. It's all handled at the imageops level, doesn't depend on a separate AFTERCLOSE function on the stream (that was getting mixed up with stream closefn for the printer file device).
And if can print several formats and files can be converted to any of them, is there any point in stipulating a preference? I'm going to ignore the type specification in this situation.
The fidelity of the conversion from one output format to another is not necessarily perfect, if a printer can print several formats, and you already have the print-ready file then it would likely be better to avoid conversion and just deal with the file as-is. However if there is a choice of what print-ready format to convert the original file to, there may be better or worse choices - and the user may want to say printer "foo" in format "bar" so that the final rendering is as good as it can be.
I have opinions about the PS/PDF approach, but haven't had time to think through the implications.
If you had a print-ready file (e.g. Press), was there a way of converting it to anything else, even if you thought it would render better?
On Sep 15, 2025, at 10:09 PM, Nick Briggs @.***> wrote:
nbriggs left a comment (Interlisp/medley#2289) https://github.com/Interlisp/medley/issues/2289#issuecomment-3295284113 And if can print several formats and files can be converted to any of them, is there any point in stipulating a preference? I'm going to ignore the type specification in this situation.
The fidelity of the conversion from one output format to another is not necessarily perfect, if a printer can print several formats, and you already have the print-ready file then it would likely be better to avoid conversion and just deal with the file as-is. However if there is a choice of what print-ready format to convert the original file to, there may be better or worse choices - and the user may want to say printer "foo" in format "bar" so that the final rendering is as good as it can be.
I have opinions about the PS/PDF approach, but haven't had time to think through the implications.
— Reply to this email directly, view it on GitHub https://github.com/Interlisp/medley/issues/2289#issuecomment-3295284113, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSTUJJ5ZRAOZSUPAPSMA533S6LPLAVCNFSM6AAAAACGILTE42VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEOJVGI4DIMJRGM. You are receiving this because you authored the thread.
For Press, no, you'd choose the first printer that could print that format, but if you had a Postscript file you could convert to PDF (or HPPCL5) - but might not want to because the PDF representation may not print as well as the original PS version (possibly due to unadvertised conversions going on in the printer itself) but the second case I was considering was when you're starting with, say, a TEdit file, and you have a printer that can print any of Interpress, PostScript, PDF, HPPCL5 (or 6) - you may want to choose which print-ready format is generated because one may render the document better than the others (e.g., based on the printers internal font coercions, image half-toning algorithms, or job control capabilities such as plex)
But wouldn't that be a propery of the printer as embeded in a specification in the printer type list? That is, if you are converting from e.g. Tedit to any of the formats that a given printer can print, shouldn't the Lisp code know in general what the printer can do best and choose that? Rather than the user having to figure that out and specify it (and then needing code to interpret what the user says)?
On Sep 16, 2025, at 9:36 AM, Nick Briggs @.***> wrote:
nbriggs left a comment (Interlisp/medley#2289) https://github.com/Interlisp/medley/issues/2289#issuecomment-3299539922 For Press, no, you'd choose the first printer that could print that format, but if you had a Postscript file you could convert to PDF (or HPPCL5) - but might not want to because the PDF representation may not print as well as the original PS version (possibly due to unadvertised conversions going on in the printer itself) but the second case I was considering was when you're starting with, say, a TEdit file, and you have a printer that can print any of Interpress, PostScript, PDF, HPPCL5 (or 6) - you may want to choose which print-ready format is generated because one may render the document better than the others (e.g., based on the printers internal font coercions, image half-toning algorithms, or job control capabilities such as plex)
— Reply to this email directly, view it on GitHub https://github.com/Interlisp/medley/issues/2289#issuecomment-3299539922, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSTUJPNC3KIUVTNDEGNTUL3TA4BBAVCNFSM6AAAAACGILTE42VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEOJZGUZTSOJSGI. You are receiving this because you authored the thread.
We encode some of the printer capabilities in the printer type list - but certainly not to the level that the user may know about their own printer. I have an HP printer that does Postscript and PCL5 - certain features of the printer are only available (or better implemented) in one or the other PDL. Making the all those possibilities describable in the printer type properties, and then allowing me to say which matters to me for this print job in a way that Lisp will choose the right format is far more complicated than allowing me to say Hardcopy to "Officejet_Pro_8100 in format .PS" (or .PDF, or .PCL5 if we had a native driver for PCL5)
Another take on the implementation of PDF (given that we currently have to go through postscript):
I now see that there are 2 scenarios:
- Calling OPENIMAGESTREAM to create a PDF stream that arbitrary code can print to, draw to etc.
- Translating the contents of an existing image stream to a PDF formatted file, the conversion process defined by entries on PRINTFILETYPES.
In the first case, there is actually a PDF stream that floats around and can be given to the various image-stream operations. It becomes a valid file of that type only when it is closed and its image closefn is run. When it is next opened as a file, it is given the \NOIMAGEOPS imageops (and probably, a NODIRCORE image stream should revert to \NOIMAGEOPS when it is closed, in case anybody looks at it again). When you open a PDF or PS file (why would you?), you get its bytes but you don't get an image stream.
In the second case there is no access to the image stream itself--the source (e.g. a Tedit file) is given to the coercion function (e.g. PDF.TEDIT) which produces a closed PDF file. The image stream that may be used inside the conversion is not available outside of that process.
The current plan for making a PDF image stream is as previously described--install the PDF-modified postscript imageops when the stream is opened (based on the openstream entry on IMAGESTREAMTYPES), with a close-function that calls PS-TO-PDF to produce the PDF file. Before the close, the stream works as a valid PDF image stream, after the close it's a PDF file.
PDF conversion, on the other hand, doesn't need and shouldn't create such a stream. Rather, the conversion functions from other image types (e.g. TEXT or TEDIT) should internally compose the conversion from the source type to postscript with the conversion from postscript to PDF (i.e. the function PS-TO-PDF). PDF.TEDIT is basically defined as (PS-TO-PDF (POSTSCRIPT.TEDIT xxx)), with no call to OPENIMAGESTREAM other than the one for a vanilla postscript stream that the postscript converter might create.
One consequence of this arrangement is that it is easy to print a legacy postscript file: the PDF conversion list gets a new entry POSTSCRIPT PS-TO-PDF. In the file browser, for example, if an old PS file is selected, choosing to hardcopy that file will convert it to a scratch PDF file for a PDF printer. Or convert it to a named PDF file if you select that destination type.
But the main thing is that there is no confusion about the nature of the stream and various special behaviors when or how it is closed.
When you open a PDF or PS file (why would you?), you get its bytes but you don't get an image stream
I agree (it's not an image stream at that point) -- but, when you send a Postscript file to a printer, and want to specify that it is to be printed duplex (or the number of copies, or any of a few other properties), you have to prepend a sequence of characters, to set those properties, to the beginning of the data that is sent to the printer (or if you're being fancy, at selected places within what's being sent to the printer). You'll see an example of that in the function UnixPrint on UNIXPRINT.
I agree (mostly) on your two different scenarios - but I think we should keep "hardcopy to file" and "hardcopy to a printer" somewhat distinct. If you know you're going directl to a printer, and you have the printer properties and user's settings (plex, copy count, etc) in hand then you can generate the control information into the stream as well as the image operations. If you're doing "hardcopy to file" then you don't necessarily have the properties (or the info about the appropriate way to set them for any particular printer), so you should(?) get a generic file that you can later SEND.FILE.TO.PRINTER and specify the properties, or view in some external viewer. You might want to invoke a format conversion for one file to another, independent of whether you're printing it.
I agree (it's not an image stream at that point) -- but, when you send a Postscript file to a printer, and want to specify that it is to be printed duplex (or the number of copies, or any of a few other properties), you have to prepend a sequence of characters, to set those properties, to the beginning of the data that is sent to the printer (or if you're being fancy, at selected places within what's being sent to the printer). You'll see an example of that in the function
UnixPrinton UNIXPRINT.
Is this supposed to work if you are sending a PDF file to a Unix lpr printer? The comment in UnixPrint says that "we already know it's a PS printer".
I presume that the current code would jam that stuff at the beginning of the PDF (or maybe after the first line). What would you expect to happen?
At any rate, those parameters seemed to be passed into UnixPrint by separate arguments, not part of the file, of whatever format, it is trying to print. OPENPOSTSCRIPTSTREAM doesn't seem to put them in the stream, even if they might be passed as options.
I agree (mostly) on your two different scenarios - but I think we should keep "hardcopy to file" and "hardcopy to a printer" somewhat distinct. If you know you're going directl to a printer, and you have the printer properties and user's settings (plex, copy count, etc) in hand then you can generate the control information into the stream as well as the image operations.
As noted above, I don't see where at least the postscript creator puts the information the stream. It's added later when the closed file is about to be printed.
So it still seems to me that the difference between a hardcopy-to-file file and a hard-copy-to-printer file only shows up when you actual send it off to the printer. It doesn't get modified until then.
It seems to me that we're not optimizing what I suspect will be the prevelnt case, where people are working with Medley online or don't have (or rarely want to use) a printer at all. However, in most scenerios they do have a browser.
In this case, you can kind of treat the browser as a kind of printer -- a browser can "print" (display) PNG, PDF, HTML, pain text encoded in UTF-8. In the case of existing files, there is usually a natural choice that the "hardcopy" request should make automatically without too much user interaction.