diff --git a/library/PDFSTREAM b/library/PDFSTREAM
new file mode 100644
index 00000000..24fdd70a
--- /dev/null
+++ b/library/PDFSTREAM
@@ -0,0 +1,228 @@
+(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "INTERLISP" BASE 10)
+
+(FILECREATED "24-Jun-2023 15:27:04" {WMEDLEY}<library>PDFSTREAM.;35 12465  
+
+      :EDIT-BY rmk
+
+      :PREVIOUS-DATE "24-Jun-2023 15:01:28" {WMEDLEY}<library>PDFSTREAM.;34)
+
+
+(PRETTYCOMPRINT PDFSTREAMCOMS)
+
+(RPAQQ PDFSTREAMCOMS
+       ([ADDVARS [PRINTERTYPES ((PDF)
+                                (CANPRINT (PDF))
+                                (STATUS TRUE)
+                                (PROPERTIES NILL)
+                                (SEND POSTSCRIPTSEND)
+                                (BITMAPSCALE POSTSCRIPT.BITMAPSCALE)
+                                (BITMAPFILE (PDF.HARDCOPYW FILE BITMAP SCALEFACTOR REGION ROTATION 
+                                                   TITLE]
+               [PRINTFILETYPES (PDF (TEST PDFFILEP)
+                                    (EXTENSION (PDF))
+                                    (CONVERSION (TEXT PDF.TEXT TEDIT PDF.TEDIT]
+               (IMAGESTREAMTYPES (PDF (OPENSTREAM OPEN-PDF-STREAM)
+                                      (FONTCREATE POSTSCRIPT.FONTCREATE)
+                                      (FONTSAVAILABLE POSTSCRIPT.FONTSAVAILABLE)
+                                      (CREATECHARSET \CREATECHARSET.PSC]
+        (DECLARE%: EVAL@COMPILE DONTCOPY (FILES EXPORTS.ALL (LOADCOMP)
+                                                POSTSCRIPTSTREAM))
+        (FNS PDFFILEP PDF.HARDCOPYW PDF.TEXT PDF.TEDIT)
+        (INITVARS (PDFCONVERTER 'ps2pdf))
+        (ALISTS (PDF-CONVERTER-TEMPLATES ps2pdf pstopdf))
+        (VARS (DEFAULTPRINTERTYPE 'PDF))
+        (GLOBALVARS PDFCONVERTER \PDFIMAGEOPS PDF-CONVERTER-TEMPLATES)
+        (FNS PDF-INIT OPEN-PDF-STREAM CLOSE-PDF-STREAM PDF-CONVERT)
+        (P (PDF-INIT))))
+
+(ADDTOVAR PRINTERTYPES ((PDF)
+                        (CANPRINT (PDF))
+                        (STATUS TRUE)
+                        (PROPERTIES NILL)
+                        (SEND POSTSCRIPTSEND)
+                        (BITMAPSCALE POSTSCRIPT.BITMAPSCALE)
+                        (BITMAPFILE (PDF.HARDCOPYW FILE BITMAP SCALEFACTOR REGION ROTATION TITLE))))
+
+(ADDTOVAR PRINTFILETYPES (PDF (TEST PDFFILEP)
+                              (EXTENSION (PDF))
+                              (CONVERSION (TEXT PDF.TEXT TEDIT PDF.TEDIT))))
+
+(ADDTOVAR IMAGESTREAMTYPES (PDF (OPENSTREAM OPEN-PDF-STREAM)
+                                (FONTCREATE POSTSCRIPT.FONTCREATE)
+                                (FONTSAVAILABLE POSTSCRIPT.FONTSAVAILABLE)
+                                (CREATECHARSET \CREATECHARSET.PSC)))
+(DECLARE%: EVAL@COMPILE DONTCOPY 
+
+(FILESLOAD EXPORTS.ALL (LOADCOMP)
+       POSTSCRIPTSTREAM)
+)
+(DEFINEQ
+
+(PDFFILEP
+  [LAMBDA (FILE)                                             (* ; "Edited 23-Jun-2023 14:43 by rmk")
+                                                             (* ; "Edited  5-Mar-93 21:40 by rmk:")
+                                                             (* ; "Edited 14-Jan-93 10:56 by jds")
+    (OR (CL:MEMBER (UNPACKFILENAME.STRING FILE 'EXTENSION)
+               '("PDF")
+               :TEST
+               (FUNCTION STRING-EQUAL))
+        (CL:WHEN (STREAMP FILE)
+            (SETFILEPTR FILE 0)
+            (PROG1 (AND (EQ (BIN FILE)
+                            (CHARCODE %%))
+                        (EQ (BIN FILE)
+                            (CHARCODE P))
+                        (EQ (BIN FILE)
+                            (CHARCODE D))
+                        (EQ (BIN FILE)
+                            (CHARCODE F)))
+                   (SETFILEPTR FILE 0)))])
+
+(PDF.HARDCOPYW
+  [LAMBDA (FILE BITMAP SCALEFACTOR REGION Landscape? TITLE)  (* ; "Edited 23-Jun-2023 13:28 by rmk")
+                                                             (* ; "Edited  6-Mar-2023 22:43 by rmk")
+    (LET ((PSTTMP (PACKFILENAME 'EXTENSION 'TMPPS 'BODY FILE)))
+         (PDF-CONVERT (POSTSCRIPT.HARDCOPYW PSTTMP FILE BITMAP SCALEFACTOR REGION Landscape? TITLE)
+                FILE])
+
+(PDF.TEXT
+  [LAMBDA (FILE PDFFILE FONTS HEADING TABS)                  (* ; "Edited 23-Jun-2023 13:23 by rmk")
+                                                             (* ; "Edited  7-Mar-2023 08:39 by rmk")
+    (TEXTTOIMAGEFILE FILE PDFFILE 'PDF FONTS HEADING TABS `(REGION ,POSTSCRIPT.DEFAULT.PAGEREGION 
+                                                                  ROTATION ,(NOT (NOT 
+                                                                        POSTSCRIPT.TEXTFILE.LANDSCAPE
+                                                                                      ])
+
+(PDF.TEDIT
+  [LAMBDA (FILE PDFFILE)                                     (* ; "Edited 23-Jun-2023 13:22 by rmk")
+                                                             (* ; "Edited  7-Mar-2023 08:39 by rmk")
+    (LET ((TSTREAM (OPENTEXTSTREAM FILE)))
+         (TEDIT.FORMAT.HARDCOPY FILE PDFFILE T NIL NIL NIL 'PDF)
+         (CLOSEF TSTREAM])
+)
+
+(RPAQ? PDFCONVERTER 'ps2pdf)
+
+(ADDTOVAR PDF-CONVERTER-TEMPLATES (ps2pdf " " PSTMPFILENAME " " PDFTMPFILENAME " 2> " ERRORFILE)
+                                  (pstopdf " " PSTMPFILENAME " -o " PDFTMPFILENAME " 2> " ERRORFILE))
+
+(RPAQQ DEFAULTPRINTERTYPE PDF)
+(DECLARE%: DOEVAL@COMPILE DONTCOPY
+
+(GLOBALVARS PDFCONVERTER \PDFIMAGEOPS PDF-CONVERTER-TEMPLATES)
+)
+(DEFINEQ
+
+(PDF-INIT
+  [LAMBDA NIL                                                (* ; "Edited 23-Jun-2023 11:23 by rmk")
+
+    (* ;; "Seems OK to make callers see this as PDF, even though the implementation is postscript.  The pdf stream is opened as a temporary postscript stream, and the closefn then uses an operating-system utility to convert it to the original target file-name.")
+
+    (SETQ \PDFIMAGEOPS (create IMAGEOPS using \POSTSCRIPTIMAGEOPS IMAGETYPE _ 'PDF IMCLOSEFN _
+                                              (FUNCTION CLOSE-PDF-STREAM])
+
+(OPEN-PDF-STREAM
+  [LAMBDA (FILE OPTIONS)                                     (* ; "Edited 24-Jun-2023 14:49 by rmk")
+
+    (* ;; "Open a temporary PS file, but set it up so that at closing it gets converted to PDF using an operating-system utility (if available), and then gets renamed to the original intended filename.")
+
+    (* ;; "We have to stash the original filename someplace.  We could put it in the tmp filename and then parse it out, but then we would have to worry about how unix filenames might parse against our {, },  etc.  ")
+
+    (* ;; 
+    "Simplest thing for now is to just add an extra field at the end of the \POSTSCRIPTDATA record.")
+
+    (* ;; "")
+
+    (if [AND NIL (EQ 'LPT (FILENAMEFIELD FILE 'HOST]
+        then 
+             (* ;; "If FILE is on the LPT device, we could just ssume that it can be printed directly, no point in converting.  But then we would alo have to lie that and give it a PDF extension so it thinks that we are heading to a PDF printer.")
+
+             (OPENPOSTSCRIPTSTREAM FILE OPTIONS)
+      else (CL:UNLESS (OR (ASSOC (OR PDFCONVERTER (MKATOM (UNIX-GETENV "MEDLEY-PDFCONVERTER")))
+                                 PDF-CONVERTER-TEMPLATES))
+                  (ERROR "POSTSCRIPT-to-PDF converter is not specified"))
+           (LET ((PSSTREAM (OPENPOSTSCRIPTSTREAM (CONCAT "{UNIX}/tmp/medley-pdf-" (IDATE)
+                                                        "-"
+                                                        (RAND)
+                                                        ".ps")
+                                  OPTIONS)))
+                (replace (STREAM IMAGEOPS) of PSSTREAM with \PDFIMAGEOPS)
+
+                (* ;; "Hopefully the postscript implementation functions won't notice that we did a shift to get the IMAGETYPE and IMCLOSEFN")
+
+                (replace (\POSTSCRIPTDATA POSTSCRIPTTARGETINFO) of (fetch (STREAM IMAGEDATA)
+                                                                      of PSSTREAM) with FILE)
+                PSSTREAM])
+
+(CLOSE-PDF-STREAM
+  [LAMBDA (PSSTREAM)                                         (* ; "Edited 24-Jun-2023 13:57 by rmk")
+
+    (* ;; "PSSTREAM is a tmp/ postscript rendition of what is intended to end up as a pdf.  If we are going directly to a printer, we can probably just pass it along without worrying about conversion.  In fact, in that case we probably should not have bothered even setting up the PDF stream.")
+
+    (* ;; "But for a file we execute the PDFCONVERTER as a shell command to make a pdf, and then we rename it to the intended filename")
+
+    (* ;; "We have to back up to the ordinary POSTSCRIPT close, so that we don't loop through here")
+
+    (replace (STREAM IMAGEOPS) of PSSTREAM with \POSTSCRIPTIMAGEOPS)
+    (PDF-CONVERT (CLOSEF PSSTREAM)
+           (fetch (\POSTSCRIPTDATA POSTSCRIPTTARGETINFO) of (fetch (STREAM IMAGEDATA) of PSSTREAM])
+
+(PDF-CONVERT
+  [LAMBDA (PSTMPFILENAME TARGETPDFNAME DONTDELETE)           (* ; "Edited 24-Jun-2023 15:01 by rmk")
+                                                             (* ; "Edited 16-Jul-2022 13:06 by rmk")
+                                                             (* ; "Edited  8-Jul-2022 10:20 by rmk")
+                                                             (* ; "Edited  7-May-2022 22:40 by rmk")
+                                                            (* ; "Edited  7-Oct-2021 11:15 by rmk:")
+
+    (* ;; "PSTMPFILENAME is the name of a closed PS file in a Unix tmp directory.  This function uses the PDFCONVERTER utility to convert that to a parallel pdf file, which is then renamed to TARGETPDFNAME.  ")
+
+    (* ;; "DONTDELETE is just for debugging, keeps the /tmp/ files")
+
+    (CL:UNLESS (INFILEP PSTMPFILENAME)
+           (ERROR "NO PS FILE TO CONVERT"))
+    (LET ((PDFTMPFILENAME (PACKFILENAME 'EXTENSION 'pdf 'BODY PSTMPFILENAME))
+          (ERRORFILENAME (PACKFILENAME 'EXTENSION 'error 'BODY PSTMPFILENAME))
+          COMPLETIONCODE)
+
+         (* ;; "PROCESS-COMMAND is currently from GITFNS.  Not sure whether ShellCommand in UNIXUTILS is appropriate.")
+
+         (* ;; "We have to map the filenames down to Unix conventions:  (not host, slashes, etc.")
+
+         [SETQ COMPLETIONCODE (PROCESS-COMMAND
+                               (CONCATLIST (SUBLIS `[(PSTMPFILENAME \, (SLASHIT (PACKFILENAME
+                                                                                 'HOST NIL
+                                                                                 'BODY PSTMPFILENAME)
+                                                                              ))
+                                                     (PDFTMPFILENAME \, (SLASHIT (PACKFILENAME
+                                                                                  'HOST NIL
+                                                                                  'BODY 
+                                                                                  PDFTMPFILENAME)))
+                                                     (ERRORFILENAME \, (SLASHIT (PACKFILENAME
+                                                                                 'HOST NIL
+                                                                                 'BODY ERRORFILENAME]
+                                                  (ASSOC (OR PDFCONVERTER (MKATOM (UNIX-GETENV 
+                                                                                "MEDLEY-PDFCONVERTER"
+                                                                                         )))
+                                                         PDF-CONVERTER-TEMPLATES]
+
+         (* ;; "Now use Medley names")
+
+         (CLOSEF? PSTMPFILENAME)
+         (CL:UNLESS DONTDELETE (DELFILE PSTMPFILENAME))
+         (CLOSEF? ERRORFILENAME)
+         (CL:WHEN (INFILEP ERRORFILENAME)
+             (CL:WHEN (IGREATERP (PROG1 (GETFILEINFO ERRORFILENAME 'LENGTH)
+                                     (CL:UNLESS DONTDELETE (DELFILE ERRORFILENAME)))
+                             0)
+                    (ERROR "Cannot create PDF file for " TARGETPDFNAME)))
+         (CL:WHEN (IGREATERP COMPLETIONCODE 0)
+                (ERROR "Cannot create PDF file for " TARGETPDFNAME))
+         (RENAMEFILE PDFTMPFILENAME TARGETPDFNAME])
+)
+
+(PDF-INIT)
+(DECLARE%: DONTCOPY
+  (FILEMAP (NIL (2668 5002 (PDFFILEP 2678 . 3592) (PDF.HARDCOPYW 3594 . 4021) (PDF.TEXT 4023 . 4631) (
+PDF.TEDIT 4633 . 5000)) (5378 12426 (PDF-INIT 5388 . 5957) (OPEN-PDF-STREAM 5959 . 8062) (
+CLOSE-PDF-STREAM 8064 . 8979) (PDF-CONVERT 8981 . 12424)))))
+STOP
diff --git a/library/PDFSTREAM.LCOM b/library/PDFSTREAM.LCOM
new file mode 100644
index 00000000..2e961a9b
Binary files /dev/null and b/library/PDFSTREAM.LCOM differ
