UnPdf

See also DocViewMode which converts pdf files to images that Emacs can display.

This small piece of ugly code allows you to open .pdf files and run pdftotext on them before viewing them.

    (add-to-list 'auto-mode-alist '("\\.pdf\\'" . no-pdf))
    (defun no-pdf ()
      "Run pdftotext on the entire buffer."
      (interactive)
      (let ((modified (buffer-modified-p)))
        (erase-buffer)
        (shell-command
         (concat "pdftotext " (buffer-file-name) " -")
         (current-buffer)
         t)
        (set-buffer-modified-p modified)))

For Gnus, you can follow the advice given in MimeTypesWithGnus – if pdftotext is your only PDF viewer, and it is installed correctly. If you have other PDF viewers, but you don’t want to use them while using Gnus, then use the following setup.

First, tell Gnus that you want to inline PDF, that you will display it using the function ‘inline-no-pdf’, and that an attachment that identifies itself as “application/pdf” will always be considered PDF.

    (add-to-list 'mm-inlined-types "application/pdf")
    (add-to-list 'mm-inline-media-tests
                 '("application/pdf"
                   inline-no-pdf
                   identity))

Now all that is left to do is to write ‘inline-no-pdf’. :) The following code is modelled on ‘mm-inline-text’. First, it inserts the content of the attachment into a temporary unibyte buffer, saves it, calls pdftotext, and stores the output in a variable. Then it inserts the variable and marks the text inserted with a special property that will allow Gnus to get rid of it when you click on the MIME button again.

    (defun inline-no-pdf (handle)
      "Insert pdf attachment described in HANDLE into article bufffer."
      (let ((file (mm-make-temp-file "pdf.")))
        (mm-with-unibyte-buffer
          (mm-insert-part handle)
          (write-file file))
        (insert (shell-command-to-string (concat "pdftotext " file " -"))))
      (goto-char (point-max))
      (mm-handle-set-undisplayer
       handle
       `(lambda ()
          (let (buffer-read-only)
            (delete-region ,(point-min-marker)
                           ,(point-max-marker))))))

CategoryExternalUtilities CategoryGnus