3

I would like to convert .doc files to plain text when opening them in Emacs.

The command line tool antiword can read Word files.

How do I pass them to antiword and then get the result in an emacs buffer?

Can this be done automatically so it happens each time i open a doc file in dired?

1
  • Invoking dired-do-shell-command with point on file in dired (key !) proposes to run antiword. The result is displayed in buffer *Shell Command Output*.
    – JeanPierre
    Mar 18, 2017 at 20:53

1 Answer 1

4

You could use a custom file handler to automatically convert the doc file whenever Emacs tries to load it. To do this you need a function like:

(defun antiword-file-handler (name &rest args)
  (assert (eq name 'insert-file-contents))
  (let ((file-name (expand-file-name (car args))))
    (call-process "antiword" nil t nil file-name)
    (setq buffer-file-name file-name)
    ;; This prevents a "File exists, but cannot be read" error:
    (set-visited-file-modtime)
    ;; insert-file-contents should return the filename and size in characters
    (list file-name (point))))

and you need to set the following property on it:

(put 'antiword-file-handler 'operations '(insert-file-contents))

finally, add the following to file-name-handler-alist:

("\\.doc" . antiword-file-handler)

Whenever Emacs tries to load a file with a .doc extension it should then decode it by running it through antiword and inserting the contents into the buffer. The above should work (it worked for me) but it may well need extending as there are various other arguments to insert-file-contents that probably ought to be handled correctly...

1
  • It is also necessary to add (set-visited-file-modtime) after setting buffer-file-name. Otherwise, you'll get a "File exists, but cannot be read" error after the text is inserted into the buffer.
    – cjm
    Aug 11, 2022 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.