0

The existing code written by Rupert Swarbrick, later modified by Rory Yorke, still leaves open the need to specify the file location with a save-as function (e.g. on OSX, this would be ns-write-file-using-panel). Does anyone have a suggestion, please, that adds an option similar to ns-write-file-using-panel and/or perhaps modifies the /tmp directory option written in the script?

Word wrap for Emacs print buffer to PDF

Formatting a header in an Emacs function to print a buffer to PDF w/ line wrapping

(defun harden-newlines ()
  (interactive)
  "Make all the newlines in the buffer hard."
  (save-excursion
    (goto-char (point-min))
    (while (search-forward "\n" nil t)
      (backward-char)
      (put-text-property (point) (1+ (point)) 'hard t)
      (forward-char))))

;;    (defun spool-buffer-given-name (name)
;;      (load "ps-print")
;;      (let ((tmp ps-left-header))
;;        (unwind-protect
;;            (progn
;;              (setq ps-left-header
;;                    (list (lambda () name) 'ps-header-dirpart))
;;              (ps-spool-buffer-with-faces))
;;          (setf ps-left-header tmp))))

(defun spool-buffer-given-name (name)
  (let ((ps-left-header (list (format "(%s)" name))))
    (ps-spool-buffer-with-faces)))

(defun print-to-pdf ()
  "Print the current file to /tmp/print.pdf"
  (interactive)
  (let ((wbuf (generate-new-buffer "*Wrapped*"))
        (sbuf (current-buffer)))
    (jit-lock-fontify-now)
    (save-current-buffer
      (set-buffer wbuf)
      (insert-buffer sbuf)
;;      (longlines-mode t)
      (visual-line-mode t)
      (harden-newlines)
      (spool-buffer-given-name (buffer-name sbuf))
      (kill-buffer wbuf)
      (switch-to-buffer "*PostScript*")
      (write-file "/tmp/print.ps")
      (kill-buffer (current-buffer)))
    (call-process "ps2pdf14" nil nil nil
                  "/tmp/print.ps" "/tmp/print.pdf")
    (delete-file "/tmp/print.ps")
    (message "PDF saved to /tmp/print.pdf")))
Community
  • 1
  • 1
lawlist
  • 13,099
  • 3
  • 49
  • 158

1 Answers1

2

You can modify the last function to take a filename as a parameter:

(defun print-to-pdf (pdf-file-name)
  "Print the current file to the given file."
  (interactive "FWrite PDF file: ")
  (let ((ps-file-name (concat (file-name-sans-extension pdf-file-name) ".ps"))
        (wbuf (generate-new-buffer "*Wrapped*"))
        (sbuf (current-buffer)))
    (jit-lock-fontify-now)
    (save-current-buffer
      (set-buffer wbuf)
      (insert-buffer sbuf)
      (setq fill-column 95)
      (longlines-mode t)
      (harden-newlines)
      (message (buffer-name sbuf))
      (spool-buffer-given-name (buffer-name sbuf))
      (kill-buffer wbuf)
      (switch-to-buffer "*PostScript*")
      (write-file ps-file-name t)
      (kill-buffer (current-buffer)))
    (call-process "ps2pdf14" nil nil nil ps-file-name pdf-file-name)
    (delete-file ps-file-name)
    (message "PDF saved to %s" pdf-file-name)))

You might want to add some code that tests if the PDF file already exist though, to avoid overwriting anything.

Thomas
  • 17,016
  • 4
  • 46
  • 70
  • The function (as is) in this answer will not open the OSX file/folder directory panel with a keyboard shortcut. I've not been able to locate any example on Google that modifies the `F` interactive code to permit me to use `ns-popup-save-panel` or `ns-write-file-using-panel`. I found various examples of `(interactive (list (. . .`, but the majority of them use `read-file-name` and I haven't had any luck inserting the open panel options. This example looks close, but no cigar: http://stackoverflow.com/questions/10278934/emacs-default-dir-for-interactive-f Any ideas on opening the panel? – lawlist May 28 '13 at 18:57
  • Ah . . . . OSX uses `ns-read-file-name` . . . I think I got it . . . I'll post the extra line of code after some more testing . . . – lawlist May 28 '13 at 19:13
  • For an OSX version of Emacs, line 3 would change to: `(interactive (list (ns-read-file-name "Write PDF file: ")))` Thanks again for giving me a working example of print-to-pdf. :) – lawlist May 28 '13 at 19:19
  • And the icing in the cake -- choose a default directory and add the proposed file extension: `(interactive (list (ns-read-file-name "Write PDF file: " "~/" nil ".pdf")))` – lawlist May 28 '13 at 20:18
  • NOTE: With this `print-to-pdf` code, it is not possible to substitute `visual-line-mode` for `longlines-mode` on a developer build of Emacs for OSX post-24.3 / pre-24.4. The easiest solution is to install the depricated `longlines.el` from emacswiki: http://www.emacswiki.org/emacs/download/longlines.el – lawlist May 28 '13 at 20:36
  • Here is a link to the evolution of print-to-pdf wherein Thomas has added support for a yes/no prompt of whether to overwrite a file with the same name that already exists: http://stackoverflow.com/questions/17077434/adding-a-file-exists-p-condition-inside-an-interactive-list-of-a-function – lawlist Jun 13 '13 at 01:37