From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tassilo Horn Newsgroups: gmane.emacs.devel Subject: Re: doc-view.el --- View PDF/PostScript/DVI files in Emacs Date: Fri, 24 Aug 2007 17:24:49 +0200 Message-ID: <87ir753qgu.fsf@baldur.tsdh.de> References: <87d4xd19f8.fsf@baldur.tsdh.de> <87ejhtkvc7.fsf@cadilhac.name> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1187969121 28097 80.91.229.12 (24 Aug 2007 15:25:21 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 24 Aug 2007 15:25:21 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Aug 24 17:25:18 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1IOb2D-0003QS-CR for ged-emacs-devel@m.gmane.org; Fri, 24 Aug 2007 17:25:18 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IOb2C-0005Wv-OE for ged-emacs-devel@m.gmane.org; Fri, 24 Aug 2007 11:25:16 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IOb28-0005UF-0d for emacs-devel@gnu.org; Fri, 24 Aug 2007 11:25:12 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IOb27-0005SW-2G for emacs-devel@gnu.org; Fri, 24 Aug 2007 11:25:11 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IOb26-0005Rw-Li for emacs-devel@gnu.org; Fri, 24 Aug 2007 11:25:10 -0400 Original-Received: from main.gmane.org ([80.91.229.2] helo=ciao.gmane.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1IOb24-000598-1o for emacs-devel@gnu.org; Fri, 24 Aug 2007 11:25:08 -0400 Original-Received: from list by ciao.gmane.org with local (Exim 4.43) id 1IOb21-0007rt-3f for emacs-devel@gnu.org; Fri, 24 Aug 2007 17:25:05 +0200 Original-Received: from dslb-084-063-001-053.pools.arcor-ip.net ([84.63.1.53]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 24 Aug 2007 17:25:05 +0200 Original-Received: from tassilo by dslb-084-063-001-053.pools.arcor-ip.net with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 24 Aug 2007 17:25:05 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 406 Original-X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: dslb-084-063-001-053.pools.arcor-ip.net Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAAAAAByaaZbAAAACXBIWXMAAABIAAAASABGyWs+ AAAATnRFWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYACmV4aWYKICAgICAgMjAKNDU3ODY5NjYwMDAw NGQ0ZDAwMmEwMDAwMDAwODAwMDAwMDAwMDAwMAqJuBZbAAAACXZwQWcAAAAwAAAAMADO7oxXAAAB jUlEQVRIx5VVWxLEIAjzJh6Ny+WMfm95iKhYu87ObIuEQARb2p+rjEc8P/wBgK3MK2yVbiFZlXYI 1E4kO6UHqIDYNsBjFivHQ2DonllKEFStHYB2TD4mBnqyYID4ryVmhUtOxeTErK68k9XpYfi9bP4P My/5E9WiWswAeVz9x3KEyCUAiF5mDJ5kXIFCa2BoN7k7MQARwbo2Zeg1aHySU212VlXltxJGSlBT xdQSIxOuTdrGAIxQSuGGykvN9aWumB5cJclXwz8Z+ZGQ9oqkRgGgglh89P5hz6EP1NJ7aTvVie3Z b3EettGpvXqYRO5v7c0csbHhZRjviObz4JOwzc9hpkfLbNMzmcvtlnBu2m6NNX6Y2SBJSfk9R7S2 zGOJrtMW5XdCCRfDuknZaEeVsEWkXbirSsca1qrDYKK9MSTn9w5IEEfAcnQyAXoZfS0aSXOVm8PL JytRCkTH9k5v+Er4whCTuwLgE5uP0zGlvwHJJFxqwHQzfGGAfgbwFSD5rH1xOweAvqf0T2u8rh9P LJ2hezyQygAAACp6VFh0Q29tbWVudAAAeNrzCnB1t0rPK9XNSE1M0csqSFcwMjerMDIzBABomgep tDkYGQAAABp6VFh0anBlZzpjb2xvcnNwYWNlAAB42jMEAAAyADIppJqJAAAAIXpUWHRqcGVnOnNh bXBsaW5nLWZhY3RvcgAAeNozqjACAAG7AN1zYDKrAAAAAElFTkSuQmCC User-Agent: Gnus/5.110007 (No Gnus v0.7) Emacs/22.1.50 (gnu/linux) Cancel-Lock: sha1:qtYgOSgKwcNgPEOA2Lq0N2nzQOo= X-Detected-Kernel: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:77097 Archived-At: --=-=-= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit michael@cadilhac.name (Michaël Cadilhac) writes: Hi Michaël, > This a good feature, but when I tried it on a 60-page document, my > processor load quickly reached 10 and I was completely stuck. C-g did > nothing, my firefox was killed, and one of the light bulb of my room > exploded (there may be no connection for the last one, I'm just not > sure). Yes, that's normal. Be happy that it caches the page files so that it will open immediately when you want to view this document again. You can limit the resources convert uses with some environment variables or it's -limit option. See the WARNING in the commentary. And now it displays a message while it's converting, too. > It may be a good thing that every 10 seconds, Emacs says « The DocView > conversion is still running after %d seconds, cancel? », and while the > question is asked, it (signal-process) to SIGSTOP before and then > SIGCONT after if the answer is yes. Hm, I don't think asking questions is a good thing. I limit convert's resources and when I open a doc I hadn't opened before, then I know that it may take some minutes with large files and continue my work until the *DocView* buffer eventually pops up. Granted, doc-view isn't too good for large docs that aren't cached. I added a function to cancel the conversion. > Oh, and you wrote `dac-view-' in the :prefix of the doc-view group. > Typo? Oh, yes. And there was an obsolete variable mentioned in the docs. And I changed the caching strategy a bit. Instead of using a md5 sum of the files path I use a md5 sum of its contents, so viewing 2 identical files in different filesystem locations or moving of files don't need a new conversion. I think now it's much better now. --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=doc-view.el Content-Transfer-Encoding: quoted-printable Content-Description: Second version of doc-view.el ;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs ;; Copyright (C) 2007 Free Software Foundation, Inc. ;; ;; Author: Tassilo Horn ;; Maintainer: Tassilo Horn ;; Keywords: files, pdf, ps, dvi ;; Version: <2007-08-24 Fri 17:18> ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify it und= er ;; the terms of the GNU General Public License as published by the Free ;; Software Foundation; either version 3, or (at your option) any later ;; version. ;; GNU Emacs is distributed in the hope that it will be useful, but WITHOUT= ANY ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ;; details. ;; You should have received a copy of the GNU General Public License along = with ;; GNU Emacs; see the file COPYING. If not, write to the Free Software ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ;; USA. ;;; Requirements: ;; I tested in on GNU Emacs 22, but maybe it works with older emacsen or ;; XEmacs, too. You need ImageMagick's `convert' tool. ;;; Commentary: ;; DocView is a document viewer for Emacs. It converts PDF, PS and DVI fil= es ;; to a set of PNG files, one PNG for each page, and displays the PNG images ;; inside an Emacs buffer. This buffer uses `doc-view-mode' which provides ;; convenient key bindings for browsing the document. ;; ;; To use it simply do ;; ;; M-x doc-view RET ;; ;; and you'll be queried for a document to open. ;; ;; Since conversion may take some time all the PNG images are cached in a ;; subdirectory of `doc-view-cache-directory' and reused when you want to v= iew ;; that file again. This reusing can be omitted if you provide a prefx ;; argument to `doc-view'. To delete all cached files use ;; `doc-view-clear-cache'. To open the cache with dired, so that you can t= idy ;; it out use `doc-view-dired-cache'. ;; ;; WARNING: The conversion process can make your computer unusable if the ;; document has many pages and the -density option in ;; `doc-view-converter-image-settings' has a huge value, because `convert' ;; grabs all your memory and the system will start swapping. You can restr= ict ;; the resources ImageMagick uses with the environment variables ;; MAGICK_AREA_LIMIT, MAGICK_DISK_LIMIT, MAGICK_FILE_LIMIT, MAGICK_MEMORY_L= IMIT ;; and MAGICK_MAP_LIMIT or with the -limit option of `convert'. See ;; http://www.imagemagick.org/script/resources.php#environment for their ;; meaning. If the limits are too low `convert' may fail. So you have to ;; fiddle a bit to get a good compromise between conversion speed and resou= rce ;; usage. ;; ;; The author uses the default values except for MAGICK_MEMORY_LIMIT (set to ;; 256) and MAGICK_MAP_LIMIT (set to 512) on his 1.7GHz Centrino Duo laptop ;; with 1GB of RAM. ;; ;; Other settings that influence the speed, memory usage and quality of the ;; resulting images are `doc-view-converter-image-settings' and ;; `doc-view-converter-image-operators'. If you find a combination that wo= rks ;; particulary well, please drop me a mail. ;;; Code: (require 'dired) (defgroup doc-view nil "In-buffer viewer for PDF, PostScript and DVI files." :link '(function-link doc-view) :version "22.2" :group 'applications :group 'multimedia :prefix "doc-view-") (defcustom doc-view-converter-program "convert" "Program to convert doc files to png." :type '(file) :group 'doc-view) (defcustom doc-view-converter-image-settings '("-density" "96") "A list of Image Settings. See http://www.imagemagick.org/script/command-line-processing.php#setting. The default is (\"-density\" \"96\") which determinates how big the resulting PNG images are. If the value is too small, reading might become hard. If it's too big, the images won't fit into an Emacs buffer. Fiddle with it!" :type '(string) :group 'doc-view) (defcustom doc-view-converter-image-operators '("-strip" "-trim") "A list of Image Operators. See http://www.imagemagick.org/script/command-line-processing.php#operator. The default is (\"-strip\" \"-trim\"). \"-strip\" removes all profiles or comments in the resulting png files. \"-trim\" cuts of the empty margins of the pages, so that display space is used as efficiently as possible." :type '(string) :group 'doc-view) (defcustom doc-view-cache-directory (concat temporary-file-directory "doc-v= iew") "The base directory, where the PNG images will be saved." :type '(directory) :group 'doc-view) (defcustom doc-view-display-margin 5 "The width of the margin put around the page's image." :type '(integer) :group 'doc-view) (defvar doc-view-current-files nil "Only used internally.") (defvar doc-view-current-page nil "Only used internally.") (defvar doc-view-current-doc nil "Only used internally.") (defvar doc-view-current-converter-process nil "Only used internally.") (defvar doc-view-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-v") 'doc-view-next-page) (define-key map (kbd "n") 'doc-view-next-page) (define-key map (kbd "") 'doc-view-next-page) (define-key map (kbd "SPC") 'doc-view-next-page) (define-key map (kbd "M-v") 'doc-view-previous-page) (define-key map (kbd "p") 'doc-view-previous-page) (define-key map (kbd "") 'doc-view-previous-page) (define-key map (kbd "M-<") 'doc-view-first-page) (define-key map (kbd "M->") 'doc-view-last-page) (define-key map (kbd "g") 'doc-view-goto-page) (define-key map (kbd "k") 'doc-view-kill-proc-and-buffer) (define-key map (kbd "C-x k") 'doc-view-kill-proc-and-buffer) (define-key map (kbd "q") 'bury-buffer) (suppress-keymap map) map) "Keymap used by `doc-view-mode'.") (defun doc-view-kill-proc-and-buffer () "Kill the current converter process and buffer." (interactive) (when (eq major-mode 'doc-view-mode) (when doc-view-current-converter-process (kill-process doc-view-current-converter-process)) (kill-buffer (current-buffer)))) (defun doc-view-goto-page (page) "View the page given by ARG." (interactive "nPage: ") (if (< page 1) (setq page 1) (when (> page (length doc-view-current-files)) (setq page (length doc-view-current-files)))) (setq doc-view-current-page page) (doc-view-display-image (nth (1- page) doc-view-current-files))) (defun doc-view-next-page (arg) "Browse ARG pages forward." (interactive "p") (doc-view-goto-page (+ doc-view-current-page arg))) (defun doc-view-previous-page (arg) "Browse ARG pages backward." (interactive "p") (doc-view-goto-page (- doc-view-current-page arg))) (defun doc-view-first-page () "View the first page." (interactive) (doc-view-goto-page 1)) (defun doc-view-last-page () "View the last page." (interactive) (doc-view-goto-page (length doc-view-current-files))) (defun doc-view-file-name-to-directory-name (file) "Return the directory where the png files of FILE should be saved. It'a a subdirectory of `doc-view-cache-directory'." (concat (file-name-as-directory doc-view-cache-directory) (with-temp-buffer (insert-file-contents-literally file) (md5 (current-buffer))))) (defun doc-view-convert-doc (doc) "Convert DOC to a set of png files, one file per page. Those files are saved in the directory given by `doc-view-file-name-to-directory-name'. Returns the converter process." (clear-image-cache) (let* ((dir (doc-view-file-name-to-directory-name doc)) (png-file (concat dir "/" "page.png"))) (when (file-exists-p dir) (dired-delete-file dir 'always)) (make-directory dir t) (apply 'start-process (append (list "doc-view-convert" "*doc-view conversion output*" doc-view-converter-program) doc-view-converter-image-settings (list doc) doc-view-converter-image-operators (list png-file))))) (defun doc-view-sort (a b) "Return non-nil if A should be sorted before B. Predicate for sorting `doc-view-current-files'." (if (< (length a) (length b)) t (if (> (length a) (length b)) nil (string< a b)))) (define-derived-mode doc-view-mode nil "DocView" "Major mode in DocView buffers. \\{doc-view-mode-map}" :group 'doc-view (setq buffer-read-only t) (make-local-variable 'doc-view-current-files) (make-local-variable 'doc-view-current-doc) (make-local-variable 'doc-view-current-page) (make-local-variable 'doc-view-current-converter-process)) (defun doc-view-display-image (file) "Display the given png FILE." (setq inhibit-read-only t) (erase-buffer) (let ((image (create-image file 'png nil :margin doc-view-display-margin :pointer 'hand))) (insert-image image)) (insert (propertize (format "\nPage %d of %d." doc-view-current-page (length doc-vie= w-current-files)) 'face 'bold)) (goto-char (point-min)) (forward-char) (setq inhibit-read-only nil)) (defun doc-view-display (doc) "Start viewing the document DOC." (let ((dir (doc-view-file-name-to-directory-name doc))) (switch-to-buffer (format "*DocView: %s*" doc)) (setq doc-view-current-files (sort (directory-files dir t "page-[0-9]+\\.png" t) 'doc-view-sort)) (doc-view-goto-page 1))) (defun doc-view-buffer-message () (setq inhibit-read-only t) (erase-buffer) (insert (propertize "Welcome to DocView!" 'face 'bold) "\n" " If you see this buffer it means that the document you want to view gets converted to PNG now. That's a time and memory consuming task. How much resources the conversion process uses can be limited. See the -limit option on http://www.imagemagick.org/script/command-line-options.php for details. For now these keys are useful: `q' : Bury this buffer. It'll pop up again when the conversion finished. `k' : Kill the conversion process and this buffer.\n") (setq inhibit-read-only nil)) (defun doc-view (no-cache) "Query for a document, convert it to png and start viewing it. If this file is still in the cache, don't convert and use the existing page files. With prefix arg NO-CACHE, don't use the cached files and convert anew." (interactive "P") (if (not (and (image-type-available-p 'png) (display-images-p))) (message "DocView: your emacs or display doesn't support png images.") (let* ((doc (expand-file-name (read-file-name "File: " nil nil t))) (buffer (get-buffer-create (format "*DocView: %s*" doc))) (dir (doc-view-file-name-to-directory-name doc))) (switch-to-buffer buffer) (doc-view-buffer-message) (doc-view-mode) (setq doc-view-current-doc doc) (if (and (file-exists-p dir) (not no-cache)) (progn (message "DocView: using cached files!") (doc-view-display doc-view-current-doc)) (message "DocView: starting conversion!") (setq doc-view-current-converter-process (doc-view-convert-doc doc-view-cu= rrent-doc)) (process-put doc-view-current-converter-process 'buffer (current-buffer)) (set-process-sentinel doc-view-current-converter-process '(lambda (proc event) (set-buffer (process-get proc 'buffer)) (setq doc-view-current-converter-process nil) (when (string-match "finished" event) (message "DocView: finished conversion!") (doc-view-display doc-view-current-doc)))))))) (defun doc-view-clear-cache () "Delete the whole cache (`doc-view-cache-directory')." (interactive) (dired-delete-file doc-view-cache-directory 'always) (make-directory doc-view-cache-directory)) (defun doc-view-dired-cache () "Open `dired' in `doc-view-cache-directory'.." (interactive) (dired doc-view-cache-directory)) (provide 'doc-view) ;;; doc-view.el ends here --=-=-= Bye, Tassilo --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--