Ken Sharp <ken.sh...@artifex.com> writes: > On 17/03/2025 15:20, David Kastrup wrote: >> >> The problem is that judging from previous experience with Ghostscript >> development, this would not be a one-time task. > > Well nothing ever is, is it ? On-going maintenance is part of the > deal. The problem here is that you want us to take on that task.
That is the point of an API: provide a stable interface to defined functionality that doesn't need to change along with changes in the implementation. That separates maintenance of the calling code from maintenance of the called code and provides dependable spheres of responsibility. We cannot perform that task for Ghostscript. >> This is then employed in the following manner: > > I don't see from this how the initial header is set up, this appears > only to access individual pages. > > >> (defun preview-gs-dsc-cvx (page dsc) >> "Generate PostScript code accessing PAGE in the DSC object. >> The returned PostScript code will need the file on >> top of the stack, and will replace it with an executable >> object corresponding to the wanted page." >> (let ((curpage (aref dsc page))) >> (format "dup %d setfileposition %d()/SubFileDecode filter cvx" >> (1- (car curpage)) (nth 1 curpage)))) >> >> This works the same whether or not the "PostScript" file is generated >> with dvips or with pdf2dsc . > > Well, I would want to get away from DELAYSAFER, so I'd prefer to have > the permissions sent as part of the 'dsc' file creation, and when > setting up the initial Prolog from the 'dsc' file. > > >> The safety management has been a moving target for a number of years but >> has been comparatively stable for decades now. Essentially everything >> is setup and opened in advance, then safety is switched on. > > Yeah, I don't like that, presuming that's what DELAYSAFER is all > about. I suppose we could live with it. The talk to Ghostscript is performed in the following functions. I am quoting them in full right now for showing the logic, but of course the actual strings sent to Ghostscript are just there in calls to the `format' function and easily discernible as PostScript sequences with formatting codes like %s, %d, and %% strewn in. (defun preview-gs-open (&optional setup) "Start a Ghostscript conversion pass. SETUP may contain a parser setup function." (let ((image-info (assq preview-image-type preview-gs-image-type-alist))) (setq preview-gs-image-type (nth 1 image-info)) (setq preview-gs-sequence nil) (setq preview-gs-command-line (append preview-gs-options (nthcdr 2 image-info)) preview-gs-init-string (format "{DELAYSAFER{.setsafe}if}stopped pop\ /.preview-BP currentpagedevice/BeginPage get dup \ null eq{pop{pop}bind}if def\ <</BeginPage{currentpagedevice/PageSize get dup 0 get 1 ne exch 1 get 1 ne or\ {.preview-BP %s}{pop}ifelse}bind/PageSize[1 1]>>setpagedevice\ /preview-do{/.preview-ST[count 4 roll save]def dup length 0 eq\ {pop}{setpagedevice}{ifelse exec}\ stopped{handleerror quit}if \ .preview-ST aload pop restore}bind def " (preview-gs-color-string preview-colors ;; Compatibility for gs 9.27 with non-trivial ;; foreground color and dark background. ;; Suppress color adjustment with PDF backend ;; when `preview-pdf-color-adjust-method' is nil. (and (not preview-pdf-color-adjust-method) ;; The switch `preview-parsed-pdfoutput' isn't ;; set before parsing the latex output, so use ;; heuristic here. (with-current-buffer TeX-command-buffer (and TeX-PDF-mode (not (TeX-PDF-from-DVI)))))))) (preview-gs-queue-empty) (preview-parse-messages (or setup #'preview-gs-dvips-process-setup)))) (defun preview-prepare-fast-conversion () "This fixes up all parameters for fast conversion." (let* ((file (if (consp (car preview-ps-file)) (if (consp (caar preview-ps-file)) (car (last (caar preview-ps-file))) (caar preview-ps-file)) (car preview-ps-file))) (all-files (if (and (consp (car preview-ps-file)) (consp (caar preview-ps-file))) (caar preview-ps-file) (list file)))) (setq preview-gs-dsc (preview-dsc-parse file)) (setq preview-gs-init-string ;; Add commands for revised file access controls introduced ;; after gs 9.27 (bug#37719) (concat (format "systemdict /.addcontrolpath known {%s} if " (mapconcat (lambda (f) (format "/PermitFileReading %s .addcontrolpath" (preview-ps-quote-filename f))) all-files "\n")) (format "{<</PermitFileReading[%s]>> setuserparams \ .locksafe} stopped pop " (mapconcat #'preview-ps-quote-filename all-files "")) preview-gs-init-string (format " %s(r)file /.preview-ST 1 index def %s exec .preview-ST " (preview-ps-quote-filename file) (preview-gs-dsc-cvx 0 preview-gs-dsc)))))) Most of the job is done by the function `preview-do' defined in the setup PostScript fragment in the first of those two functions. -- David Kastrup