2020-11-09 15:29:54 +00:00
|
|
|
|
;;; doc-view.el --- Document viewer for Emacs -*- lexical-binding: t -*-
|
2011-02-17 21:19:13 +00:00
|
|
|
|
|
2022-01-01 07:45:51 +00:00
|
|
|
|
;; Copyright (C) 2007-2022 Free Software Foundation, Inc.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; Author: Tassilo Horn <tsdh@gnu.org>
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; Keywords: files, pdf, ps, dvi, djvu, epub, cbz, fb2, xps, openxps
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;; 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
|
2017-09-13 22:52:52 +00:00
|
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;; Requirements:
|
|
|
|
|
|
2020-11-10 13:53:03 +00:00
|
|
|
|
;; Viewing PS/PDF/DVI files requires Ghostscript, `dvipdf' (comes with
|
|
|
|
|
;; Ghostscript) or `dvipdfm' (comes with teTeX or TeXLive) and
|
2020-11-13 17:00:26 +00:00
|
|
|
|
;; `pdftotext', which comes with xpdf (https://www.foolabs.com/xpdf/)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; or poppler (https://poppler.freedesktop.org/). EPUB, CBZ, FB2, XPS
|
|
|
|
|
;; and OXPS documents require `mutool' which comes with mupdf
|
|
|
|
|
;; (https://mupdf.com/index.html). Djvu documents require `ddjvu'
|
|
|
|
|
;; (from DjVuLibre). ODF files require `soffice' (from LibreOffice).
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
2020-11-09 14:38:35 +00:00
|
|
|
|
;; DocView is a document viewer for Emacs. It converts a number of
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; document formats (including PDF, PS, DVI, Djvu, ODF, EPUB, CBZ,
|
|
|
|
|
;; FB2, XPS and OXPS files) to a set of PNG (or TIFF for djvu) files,
|
|
|
|
|
;; one image for each page, and displays the images inside an Emacs
|
|
|
|
|
;; buffer. This buffer uses `doc-view-mode' which provides convenient
|
|
|
|
|
;; key bindings for browsing the document.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; To use it simply open a document file with
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; C-x C-f ~/path/to/document RET
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
2021-09-14 06:43:18 +00:00
|
|
|
|
;; and the document will be converted and displayed, if your Emacs supports PNG
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; images. With `C-c C-c' you can toggle between the rendered images
|
2007-10-31 03:10:32 +00:00
|
|
|
|
;; representation and the source text representation of the document.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
|
|
|
|
;; 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 view
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; that file again. To reconvert a document hit `g' (`doc-view-reconvert-doc')
|
|
|
|
|
;; when displaying the document. To delete all cached files use
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; `doc-view-clear-cache'. To open the cache with dired, so that you can tidy
|
|
|
|
|
;; it out use `doc-view-dired-cache'.
|
|
|
|
|
;;
|
2018-06-23 07:26:33 +00:00
|
|
|
|
;; When conversion is underway the first page will be displayed as soon as it
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; is available and the available pages are refreshed every
|
|
|
|
|
;; `doc-view-conversion-refresh-interval' seconds. If that variable is nil the
|
|
|
|
|
;; pages won't be displayed before conversion of the document finished
|
|
|
|
|
;; completely.
|
|
|
|
|
;;
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; DocView lets you select a slice of the displayed pages. This slice
|
|
|
|
|
;; will be remembered and applied to all pages of the current
|
|
|
|
|
;; document. This enables you to cut away the margins of a document
|
|
|
|
|
;; to save some space. To select a slice you can use
|
2020-04-22 23:14:42 +00:00
|
|
|
|
;; `doc-view-set-slice' (bound to `c s') which will query you for the
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; coordinates of the slice's top-left corner and its width and
|
|
|
|
|
;; height. A much more convenient way to do the same is offered by
|
2020-04-22 23:14:42 +00:00
|
|
|
|
;; the command `doc-view-set-slice-using-mouse' (bound to `c m').
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; After invocation you only have to press mouse-1 at the top-left
|
|
|
|
|
;; corner and drag it to the bottom-right corner of the desired slice.
|
|
|
|
|
;; Even more accurate and convenient is to use
|
2020-04-22 23:14:42 +00:00
|
|
|
|
;; `doc-view-set-slice-from-bounding-box' (bound to `c b') which uses
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; the BoundingBox information of the current page to set an optimal
|
2020-04-22 23:14:42 +00:00
|
|
|
|
;; slice. To reset the slice use `doc-view-reset-slice' (bound to `c
|
2012-09-19 17:35:18 +00:00
|
|
|
|
;; r').
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
|
|
|
|
;; You can also search within the document. The command `doc-view-search'
|
|
|
|
|
;; (bound to `C-s') queries for a search regexp and initializes a list of all
|
|
|
|
|
;; matching pages and messages how many match-pages were found. After that you
|
2007-11-10 21:53:47 +00:00
|
|
|
|
;; can jump to the next page containing a match with an additional `C-s'. With
|
|
|
|
|
;; `C-r' you can do the same, but backwards. To search for a new regexp give a
|
|
|
|
|
;; prefix arg to one of the search functions, e.g. by typing `C-u C-s'. The
|
|
|
|
|
;; searching works by using a plain text representation of the document. If
|
2009-03-02 08:55:47 +00:00
|
|
|
|
;; that doesn't already exist the first invocation of `doc-view-search' (or
|
2007-11-10 21:53:47 +00:00
|
|
|
|
;; `doc-view-search-backward') starts the conversion. When that finishes and
|
|
|
|
|
;; you're still viewing the document (i.e. you didn't switch to another buffer)
|
|
|
|
|
;; you're queried for the regexp then.
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;;
|
|
|
|
|
;; Dired users can simply hit `v' on a document file. If it's a PS, PDF or DVI
|
|
|
|
|
;; it will be opened using `doc-view-mode'.
|
|
|
|
|
;;
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;; Configuration:
|
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; If the images are too small or too big you should set the "-rXXX" option in
|
|
|
|
|
;; `doc-view-ghostscript-options' to another value. (The bigger your screen,
|
|
|
|
|
;; the higher the value.)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;
|
|
|
|
|
;; This and all other options can be set with the customization interface.
|
|
|
|
|
;; Simply do
|
|
|
|
|
;;
|
|
|
|
|
;; M-x customize-group RET doc-view RET
|
|
|
|
|
;;
|
|
|
|
|
;; and modify them to your needs.
|
|
|
|
|
|
2007-11-11 22:24:04 +00:00
|
|
|
|
;;; Todo:
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-02-25 20:04:59 +00:00
|
|
|
|
;; - add print command.
|
|
|
|
|
;; - share more code with image-mode.
|
2007-10-30 17:45:41 +00:00
|
|
|
|
;; - better menu.
|
|
|
|
|
;; - Bind slicing to a drag event.
|
2008-01-18 20:09:26 +00:00
|
|
|
|
;; - zoom the region around the cursor (like xdvi).
|
2007-10-30 21:53:05 +00:00
|
|
|
|
;; - get rid of the silly arrow in the fringe.
|
|
|
|
|
;; - improve anti-aliasing (pdf-utils gets it better).
|
2007-10-30 17:45:41 +00:00
|
|
|
|
|
2007-11-11 22:24:04 +00:00
|
|
|
|
;;;; About isearch support
|
|
|
|
|
|
|
|
|
|
;; I tried implementing isearch by setting
|
|
|
|
|
;; `isearch-search-fun-function' buffer-locally, but that didn't
|
|
|
|
|
;; work too good. The function doing the real search was called
|
|
|
|
|
;; endlessly somehow. But even if we'd get that working no real
|
|
|
|
|
;; isearch feeling comes up due to the missing match highlighting.
|
|
|
|
|
;; Currently I display all lines containing a match in a tooltip and
|
|
|
|
|
;; each C-s or C-r jumps directly to the next/previous page with a
|
|
|
|
|
;; match. With isearch we could only display the current match. So
|
|
|
|
|
;; we had to decide if another C-s jumps to the next page with a
|
|
|
|
|
;; match (thus only the first match in a page will be displayed in a
|
|
|
|
|
;; tooltip) or to the next match, which would do nothing visible
|
|
|
|
|
;; (except the tooltip) if the next match is on the same page.
|
|
|
|
|
|
|
|
|
|
;; And it's much slower than the current search facility, because
|
2011-11-23 07:03:56 +00:00
|
|
|
|
;; isearch really searches for each step forward or backward whereas
|
2007-11-11 22:24:04 +00:00
|
|
|
|
;; the current approach searches once and then it knows to which
|
|
|
|
|
;; pages to jump.
|
|
|
|
|
|
|
|
|
|
;; Anyway, if someone with better isearch knowledge wants to give it a try,
|
|
|
|
|
;; feel free to do it. --Tassilo
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2013-07-12 03:54:57 +00:00
|
|
|
|
(require 'cl-lib)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(require 'dired)
|
2007-10-18 19:33:57 +00:00
|
|
|
|
(require 'image-mode)
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(require 'jka-compr)
|
2022-06-26 15:52:29 +00:00
|
|
|
|
(require 'filenotify)
|
2017-04-18 23:07:28 +00:00
|
|
|
|
(eval-when-compile (require 'subr-x))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;;; Customization Options
|
|
|
|
|
|
|
|
|
|
(defgroup doc-view nil
|
2022-01-27 16:03:38 +00:00
|
|
|
|
"In-buffer document viewer.
|
|
|
|
|
The viewer handles PDF, PostScript, DVI, DJVU, ODF, EPUB, CBZ,
|
|
|
|
|
FB2, XPS and OXPS files, if the appropriate converter programs
|
|
|
|
|
are available (see Info node `(emacs)Document View')"
|
2007-09-09 22:29:16 +00:00
|
|
|
|
:link '(function-link doc-view)
|
|
|
|
|
:version "22.2"
|
|
|
|
|
:group 'applications
|
2010-02-16 14:35:45 +00:00
|
|
|
|
:group 'data
|
2007-09-09 22:29:16 +00:00
|
|
|
|
:group 'multimedia
|
|
|
|
|
:prefix "doc-view-")
|
|
|
|
|
|
2019-07-06 11:49:23 +00:00
|
|
|
|
(defcustom doc-view-ghostscript-program
|
|
|
|
|
(cond
|
|
|
|
|
((memq system-type '(windows-nt ms-dos))
|
2020-04-23 16:25:07 +00:00
|
|
|
|
(cond
|
2020-04-22 17:23:23 +00:00
|
|
|
|
;; Windows Ghostscript
|
2020-04-23 16:25:07 +00:00
|
|
|
|
((executable-find "gswin64c") "gswin64c")
|
|
|
|
|
((executable-find "gswin32c") "gswin32c")
|
2020-04-22 17:23:23 +00:00
|
|
|
|
;; The GS wrapper coming with TeX Live
|
2020-04-23 16:25:07 +00:00
|
|
|
|
((executable-find "rungs") "rungs")
|
2020-04-22 17:23:23 +00:00
|
|
|
|
;; The MikTeX builtin GS Check if mgs is functional for external
|
|
|
|
|
;; non-MikTeX apps. Was available under:
|
|
|
|
|
;; http://blog.miktex.org/post/2005/04/07/Starting-mgsexe-at-the-DOS-Prompt.aspx
|
2020-04-23 16:25:07 +00:00
|
|
|
|
((and (executable-find "mgs")
|
|
|
|
|
(= 0 (shell-command "mgs -q -dNODISPLAY -c quit")))
|
|
|
|
|
"mgs")))
|
2020-04-22 17:23:23 +00:00
|
|
|
|
(t "gs"))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Program to convert PS and PDF files to PNG."
|
2019-07-06 11:49:23 +00:00
|
|
|
|
:type 'file
|
|
|
|
|
:version "27.1")
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defcustom doc-view-pdfdraw-program
|
|
|
|
|
(cond
|
|
|
|
|
((executable-find "pdfdraw") "pdfdraw")
|
2019-01-23 22:27:21 +00:00
|
|
|
|
((executable-find "mudraw") "mudraw")
|
|
|
|
|
((executable-find "mutool") "mutool")
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(t "mudraw"))
|
|
|
|
|
"Name of MuPDF's program to convert PDF files to PNG."
|
2013-01-09 19:48:42 +00:00
|
|
|
|
:type 'file
|
|
|
|
|
:version "24.4")
|
|
|
|
|
|
2019-09-29 12:26:26 +00:00
|
|
|
|
(defcustom doc-view-pdftotext-program-args '("-raw")
|
|
|
|
|
"Parameters to give to the pdftotext command."
|
|
|
|
|
:version "27.1"
|
|
|
|
|
:type '(repeat string))
|
|
|
|
|
|
2013-01-09 19:48:42 +00:00
|
|
|
|
(defcustom doc-view-pdf->png-converter-function
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(if (executable-find doc-view-pdfdraw-program)
|
|
|
|
|
#'doc-view-pdf->png-converter-mupdf
|
|
|
|
|
#'doc-view-pdf->png-converter-ghostscript)
|
2013-01-09 19:48:42 +00:00
|
|
|
|
"Function to call to convert a PDF file into a PNG file."
|
|
|
|
|
:type '(radio
|
|
|
|
|
(function-item doc-view-pdf->png-converter-ghostscript
|
|
|
|
|
:doc "Use ghostscript")
|
|
|
|
|
(function-item doc-view-pdf->png-converter-mupdf
|
|
|
|
|
:doc "Use mupdf")
|
|
|
|
|
function)
|
|
|
|
|
:version "24.4")
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defcustom doc-view-ghostscript-options
|
2007-10-18 19:24:30 +00:00
|
|
|
|
'("-dSAFER" ;; Avoid security problems when rendering files from untrusted
|
2011-02-10 18:53:49 +00:00
|
|
|
|
;; sources.
|
2019-02-03 16:48:31 +00:00
|
|
|
|
"-dNOPAUSE" "-dTextAlphaBits=4"
|
2007-11-15 19:56:44 +00:00
|
|
|
|
"-dBATCH" "-dGraphicsAlphaBits=4" "-dQUIET")
|
2007-10-17 20:58:02 +00:00
|
|
|
|
"A list of options to give to ghostscript."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type '(repeat string))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(defcustom doc-view-ghostscript-device "png16m"
|
|
|
|
|
"Output device to give to ghostscript."
|
|
|
|
|
:type 'string
|
|
|
|
|
:version "27.1")
|
|
|
|
|
|
2007-11-15 19:56:44 +00:00
|
|
|
|
(defcustom doc-view-resolution 100
|
|
|
|
|
"Dots per inch resolution used to render the documents.
|
|
|
|
|
Higher values result in larger images."
|
Make some defcustom types more restrictive
* lisp/abbrev.el (abbrev-suggest-hint-threshold):
* lisp/bookmark.el (bookmark-bmenu-file-column)
(bookmark-menu-length):
* lisp/buff-menu.el (Buffer-menu-size-width)
(Buffer-menu-mode-width):
* lisp/calendar/calendar.el (calendar-week-start-day)
(calendar-intermonth-spacing, calendar-column-width)
(calendar-day-digit-width):
* lisp/calc/calc.el (calc-undo-length):
* lisp/calendar/timeclock.el (timeclock-workday):
* lisp/comint.el (comint-buffer-maximum-size)
(comint-input-ring-size):
* lisp/doc-view.el (doc-view-resolution, doc-view-image-width):
* lisp/emacs-lisp/bytecomp.el (byte-compile-docstring-max-column):
* lisp/emacs-lisp/comp.el (native-comp-debug)
(native-comp-verbose, native-comp-async-jobs-number):
* lisp/emacs-lisp/package.el (package-name-column-width)
(package-version-column-width, package-status-column-width)
(package-archive-column-width):
* lisp/eshell/esh-mode.el (eshell-buffer-maximum-lines):
* lisp/frame.el (blink-cursor-blinks):
* lisp/info.el (Info-breadcrumbs-depth):
* lisp/jit-lock.el (jit-lock-chunk-size):
* lisp/kmacro.el (kmacro-ring-max):
* lisp/menu-bar.el (yank-menu-length, yank-menu-max-items):
* lisp/midnight.el (clean-buffer-list-delay-general)
(clean-buffer-list-delay-special):
* lisp/net/dictionary.el (dictionary-port)
(dictionary-proxy-port):
* lisp/net/ldap.el (ldap-default-port):
* lisp/net/pop3.el (pop3-port, pop3-stream-length):
* lisp/net/rcirc.el (rcirc-default-port):
* lisp/net/sieve-manage.el (sieve-manage-default-port):
* lisp/play/spook.el (spook-phrase-default-count):
* lisp/play/tetris.el (tetris-buffer-width)
(tetris-buffer-height, tetris-width, tetris-height)
(tetris-top-left-x, tetris-top-left-y):
* lisp/profiler.el (profiler-sampling-interval):
* lisp/progmodes/sql.el (sql-port):
* lisp/recentf.el (recentf-max-menu-items):
* lisp/strokes.el (strokes-grid-resolution):
* lisp/tab-bar.el (tab-bar-tab-name-truncated-max):
* lisp/term/xterm.el (xterm-max-cut-length):
* lisp/time.el (display-time-interval, world-clock-timer-second):
* lisp/url/url-cache.el (url-cache-expire-time):
* lisp/url/url-cookie.el (url-cookie-save-interval):
* lisp/url/url-history.el (url-history-save-interval):
* lisp/url/url-queue.el (url-queue-parallel-processes)
(url-queue-timeout):
* lisp/url/url-vars.el (url-max-password-attempts)
(url-max-redirections):
* lisp/vc/emerge.el (emerge-min-visible-lines):
* lisp/vc/vc.el (vc-log-show-limit):
* lisp/window.el (window-min-height, window-min-width):
* lisp/winner.el (winner-ring-size): Use :type natnum.
* lisp/savehist.el (savehist-file-modes): Fix setting to nil value and
use :type natnum.
2022-07-05 14:26:45 +00:00
|
|
|
|
:type 'natnum)
|
2007-11-15 19:56:44 +00:00
|
|
|
|
|
2022-01-27 16:10:13 +00:00
|
|
|
|
(defvar doc-view-doc-type nil
|
|
|
|
|
"The type of document in the current buffer.
|
2022-04-22 14:17:22 +00:00
|
|
|
|
Can be `dvi', `pdf', `ps', `djvu', `odf', `epub', `cbz', `fb2',
|
|
|
|
|
`xps' or `oxps'.")
|
2022-01-27 16:10:13 +00:00
|
|
|
|
|
2022-06-26 15:52:29 +00:00
|
|
|
|
(defvar doc-view--epub-stylesheet-watcher nil
|
|
|
|
|
"File watcher for `doc-view-epub-user-stylesheet'.")
|
|
|
|
|
|
|
|
|
|
(defun doc-view--epub-reconvert (&optional _event)
|
|
|
|
|
"Reconvert all epub buffers.
|
|
|
|
|
|
|
|
|
|
EVENT is unused, but neccesary to work with the filenotify API"
|
|
|
|
|
(dolist (x (buffer-list))
|
|
|
|
|
(with-current-buffer x
|
|
|
|
|
(when (eq doc-view-doc-type 'epub)
|
|
|
|
|
(doc-view-reconvert-doc)))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-custom-set-epub-user-stylesheet (option-name new-value)
|
|
|
|
|
"Setter for `doc-view-epub-user-stylesheet'.
|
|
|
|
|
|
|
|
|
|
Reconverts existing epub buffers when the file used as a user
|
|
|
|
|
stylesheet is switched, or its contents modified."
|
|
|
|
|
(set-default option-name new-value)
|
|
|
|
|
(file-notify-rm-watch doc-view--epub-stylesheet-watcher)
|
|
|
|
|
(doc-view--epub-reconvert)
|
|
|
|
|
(setq doc-view--epub-stylesheet-watcher
|
|
|
|
|
(when new-value
|
|
|
|
|
(file-notify-add-watch new-value '(change) #'doc-view--epub-reconvert))))
|
|
|
|
|
|
|
|
|
|
(defcustom doc-view-epub-user-stylesheet nil
|
|
|
|
|
"User stylesheet to use when converting EPUB documents to PDF."
|
|
|
|
|
:type '(choice (const nil)
|
|
|
|
|
(file :must-match t))
|
|
|
|
|
:version "29.1"
|
|
|
|
|
:set #'doc-view-custom-set-epub-user-stylesheet)
|
|
|
|
|
|
|
|
|
|
(defvar-local doc-view--current-cache-dir nil
|
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
|
|
|
|
(defun doc-view-custom-set-epub-font-size (option-name new-value)
|
|
|
|
|
(set-default option-name new-value)
|
|
|
|
|
(doc-view--epub-reconvert))
|
|
|
|
|
|
2022-01-27 16:10:13 +00:00
|
|
|
|
;; FIXME: The doc-view-current-* definitions below are macros because they
|
|
|
|
|
;; map to accessors which we want to use via `setf' as well!
|
|
|
|
|
(defmacro doc-view-current-page (&optional win)
|
|
|
|
|
`(image-mode-window-get 'page ,win))
|
|
|
|
|
(defmacro doc-view-current-info () '(image-mode-window-get 'info))
|
|
|
|
|
(defmacro doc-view-current-overlay () '(image-mode-window-get 'overlay))
|
|
|
|
|
(defmacro doc-view-current-image () '(image-mode-window-get 'image))
|
|
|
|
|
(defmacro doc-view-current-slice () '(image-mode-window-get 'slice))
|
|
|
|
|
|
|
|
|
|
(defvar-local doc-view--current-cache-dir nil
|
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(defcustom doc-view-epub-font-size nil
|
|
|
|
|
"Font size in points for EPUB layout."
|
2022-01-27 22:21:15 +00:00
|
|
|
|
:type '(choice (const nil) integer)
|
|
|
|
|
:set #'doc-view-custom-set-epub-font-size
|
|
|
|
|
:version "29.1")
|
2022-01-27 16:03:38 +00:00
|
|
|
|
|
2013-01-04 02:45:59 +00:00
|
|
|
|
(defcustom doc-view-scale-internally t
|
|
|
|
|
"Whether we should try to rescale images ourselves.
|
|
|
|
|
If nil, the document is re-rendered every time the scaling factor is modified.
|
|
|
|
|
This only has an effect if the image libraries linked with Emacs support
|
|
|
|
|
scaling."
|
2013-12-28 02:16:05 +00:00
|
|
|
|
:version "24.4"
|
2013-01-04 02:45:59 +00:00
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-01-05 21:17:51 +00:00
|
|
|
|
(defcustom doc-view-image-width 850
|
|
|
|
|
"Default image width.
|
2013-01-04 02:45:59 +00:00
|
|
|
|
Has only an effect if `doc-view-scale-internally' is non-nil and support for
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-20 22:27:53 +00:00
|
|
|
|
scaling is compiled into Emacs."
|
Add missing :version tags to new defgroups and defcustoms
* window.el (window-sides-slots):
* tool-bar.el (tool-bar-position):
* term/xterm.el (xterm-extra-capabilities):
* ses.el (ses-self-reference-early-detection):
* progmodes/verilog-mode.el (verilog-auto-declare-nettype)
(verilog-auto-wire-type)
(verilog-auto-delete-trailing-whitespace)
(verilog-auto-reset-blocking-in-non, verilog-auto-inst-sort)
(verilog-auto-tieoff-declaration):
* progmodes/sql.el (sql-login-hook, sql-ansi-statement-starters)
(sql-oracle-statement-starters, sql-oracle-scan-on):
* progmodes/prolog.el (prolog-align-comments-flag)
(prolog-indent-mline-comments-flag, prolog-object-end-to-0-flag)
(prolog-left-indent-regexp, prolog-paren-indent-p)
(prolog-paren-indent, prolog-parse-mode, prolog-keywords)
(prolog-types, prolog-mode-specificators)
(prolog-determinism-specificators, prolog-directives)
(prolog-electric-newline-flag, prolog-hungry-delete-key-flag)
(prolog-electric-dot-flag)
(prolog-electric-dot-full-predicate-template)
(prolog-electric-underscore-flag, prolog-electric-tab-flag)
(prolog-electric-if-then-else-flag, prolog-electric-colon-flag)
(prolog-electric-dash-flag, prolog-old-sicstus-keys-flag)
(prolog-program-switches, prolog-prompt-regexp)
(prolog-debug-on-string, prolog-debug-off-string)
(prolog-trace-on-string, prolog-trace-off-string)
(prolog-zip-on-string, prolog-zip-off-string)
(prolog-use-standard-consult-compile-method-flag)
(prolog-use-prolog-tokenizer-flag, prolog-imenu-flag)
(prolog-imenu-max-lines, prolog-info-predicate-index)
(prolog-underscore-wordchar-flag, prolog-use-sicstus-sd)
(prolog-char-quote-workaround):
* progmodes/cc-vars.el (c-defun-tactic):
* net/tramp.el (tramp-encoding-command-interactive)
(tramp-local-end-of-line):
* net/soap-client.el (soap-client):
* net/netrc.el (netrc-file):
* net/gnutls.el (gnutls):
* minibuffer.el (completion-category-overrides)
(completion-cycle-threshold)
(completion-pcm-complete-word-inserts-delimiters):
* man.el (Man-name-local-regexp):
* mail/feedmail.el (feedmail-display-full-frame):
* international/characters.el (glyphless-char-display-control):
* eshell/em-ls.el (eshell-ls-date-format):
* emacs-lisp/cl-indent.el (lisp-lambda-list-keyword-alignment)
(lisp-lambda-list-keyword-parameter-indentation)
(lisp-lambda-list-keyword-parameter-alignment):
* doc-view.el (doc-view-image-width, doc-view-unoconv-program):
* dired-x.el (dired-omit-verbose):
* cus-theme.el (custom-theme-allow-multiple-selections):
* calc/calc.el (calc-highlight-selections-with-faces)
(calc-lu-field-reference, calc-lu-power-reference)
(calc-note-threshold):
* battery.el (battery-mode-line-limit):
* arc-mode.el (archive-7z-extract, archive-7z-expunge)
(archive-7z-update):
* allout.el (allout-prefixed-keybindings)
(allout-unprefixed-keybindings)
(allout-inhibit-auto-fill-on-headline)
(allout-flattened-numbering-abbreviation):
* allout-widgets.el (allout-widgets-auto-activation)
(allout-widgets-icons-dark-subdir)
(allout-widgets-icons-light-subdir, allout-widgets-icon-types)
(allout-widgets-theme-dark-background)
(allout-widgets-theme-light-background)
(allout-widgets-item-image-properties-emacs)
(allout-widgets-item-image-properties-xemacs)
(allout-widgets-run-unit-tests-on-load)
(allout-widgets-time-decoration-activity)
(allout-widgets-hook-error-post-time)
(allout-widgets-track-decoration):
* gnus/sieve-manage.el (sieve-manage-default-stream):
* gnus/shr.el (shr):
* gnus/nnir.el (nnir-ignored-newsgroups, nnir-summary-line-format)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-notmuch-program)
(nnir-notmuch-additional-switches, nnir-notmuch-remove-prefix)
(nnir-method-default-engines):
* gnus/message.el (message-cite-reply-position):
* gnus/gssapi.el (gssapi-program):
* gnus/gravatar.el (gravatar):
* gnus/gnus-sum.el (gnus-refer-thread-use-nnir):
* gnus/gnus-registry.el (gnus-registry-unfollowed-addresses)
(gnus-registry-max-pruned-entries):
* gnus/gnus-picon.el (gnus-picon-inhibit-top-level-domains):
* gnus/gnus-int.el (gnus-after-set-mark-hook)
(gnus-before-update-mark-hook):
* gnus/gnus-async.el (gnus-async-post-fetch-function):
* gnus/auth-source.el (auth-source-cache-expiry):
Add missing :version tags to new defcustoms and defgroups.
2012-02-11 22:13:29 +00:00
|
|
|
|
:version "24.1"
|
Make some defcustom types more restrictive
* lisp/abbrev.el (abbrev-suggest-hint-threshold):
* lisp/bookmark.el (bookmark-bmenu-file-column)
(bookmark-menu-length):
* lisp/buff-menu.el (Buffer-menu-size-width)
(Buffer-menu-mode-width):
* lisp/calendar/calendar.el (calendar-week-start-day)
(calendar-intermonth-spacing, calendar-column-width)
(calendar-day-digit-width):
* lisp/calc/calc.el (calc-undo-length):
* lisp/calendar/timeclock.el (timeclock-workday):
* lisp/comint.el (comint-buffer-maximum-size)
(comint-input-ring-size):
* lisp/doc-view.el (doc-view-resolution, doc-view-image-width):
* lisp/emacs-lisp/bytecomp.el (byte-compile-docstring-max-column):
* lisp/emacs-lisp/comp.el (native-comp-debug)
(native-comp-verbose, native-comp-async-jobs-number):
* lisp/emacs-lisp/package.el (package-name-column-width)
(package-version-column-width, package-status-column-width)
(package-archive-column-width):
* lisp/eshell/esh-mode.el (eshell-buffer-maximum-lines):
* lisp/frame.el (blink-cursor-blinks):
* lisp/info.el (Info-breadcrumbs-depth):
* lisp/jit-lock.el (jit-lock-chunk-size):
* lisp/kmacro.el (kmacro-ring-max):
* lisp/menu-bar.el (yank-menu-length, yank-menu-max-items):
* lisp/midnight.el (clean-buffer-list-delay-general)
(clean-buffer-list-delay-special):
* lisp/net/dictionary.el (dictionary-port)
(dictionary-proxy-port):
* lisp/net/ldap.el (ldap-default-port):
* lisp/net/pop3.el (pop3-port, pop3-stream-length):
* lisp/net/rcirc.el (rcirc-default-port):
* lisp/net/sieve-manage.el (sieve-manage-default-port):
* lisp/play/spook.el (spook-phrase-default-count):
* lisp/play/tetris.el (tetris-buffer-width)
(tetris-buffer-height, tetris-width, tetris-height)
(tetris-top-left-x, tetris-top-left-y):
* lisp/profiler.el (profiler-sampling-interval):
* lisp/progmodes/sql.el (sql-port):
* lisp/recentf.el (recentf-max-menu-items):
* lisp/strokes.el (strokes-grid-resolution):
* lisp/tab-bar.el (tab-bar-tab-name-truncated-max):
* lisp/term/xterm.el (xterm-max-cut-length):
* lisp/time.el (display-time-interval, world-clock-timer-second):
* lisp/url/url-cache.el (url-cache-expire-time):
* lisp/url/url-cookie.el (url-cookie-save-interval):
* lisp/url/url-history.el (url-history-save-interval):
* lisp/url/url-queue.el (url-queue-parallel-processes)
(url-queue-timeout):
* lisp/url/url-vars.el (url-max-password-attempts)
(url-max-redirections):
* lisp/vc/emerge.el (emerge-min-visible-lines):
* lisp/vc/vc.el (vc-log-show-limit):
* lisp/window.el (window-min-height, window-min-width):
* lisp/winner.el (winner-ring-size): Use :type natnum.
* lisp/savehist.el (savehist-file-modes): Fix setting to nil value and
use :type natnum.
2022-07-05 14:26:45 +00:00
|
|
|
|
:type 'natnum)
|
2011-01-05 21:17:51 +00:00
|
|
|
|
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(defcustom doc-view-dvipdfm-program "dvipdfm"
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Program to convert DVI files to PDF.
|
|
|
|
|
|
|
|
|
|
DVI file will be converted to PDF before the resulting PDF is
|
2008-04-14 13:18:12 +00:00
|
|
|
|
converted to PNG.
|
|
|
|
|
|
|
|
|
|
If this and `doc-view-dvipdf-program' are set,
|
|
|
|
|
`doc-view-dvipdf-program' will be preferred."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'file)
|
2008-04-14 13:18:12 +00:00
|
|
|
|
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(defcustom doc-view-dvipdf-program "dvipdf"
|
2008-04-14 13:18:12 +00:00
|
|
|
|
"Program to convert DVI files to PDF.
|
|
|
|
|
|
|
|
|
|
DVI file will be converted to PDF before the resulting PDF is
|
|
|
|
|
converted to PNG.
|
|
|
|
|
|
|
|
|
|
If this and `doc-view-dvipdfm-program' are set,
|
|
|
|
|
`doc-view-dvipdf-program' will be preferred."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'file)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(define-obsolete-variable-alias 'doc-view-unoconv-program 'doc-view-odf->pdf-converter-program "24.4")
|
2013-02-09 09:58:48 +00:00
|
|
|
|
|
|
|
|
|
(defcustom doc-view-odf->pdf-converter-program
|
|
|
|
|
(cond
|
|
|
|
|
((executable-find "soffice") "soffice")
|
|
|
|
|
((executable-find "unoconv") "unoconv")
|
|
|
|
|
(t "soffice"))
|
2010-12-30 13:45:09 +00:00
|
|
|
|
"Program to convert any file type readable by OpenOffice.org to PDF.
|
|
|
|
|
|
|
|
|
|
Needed for viewing OpenOffice.org (and MS Office) files."
|
2013-02-09 09:58:48 +00:00
|
|
|
|
:version "24.4"
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'file)
|
2010-12-30 13:45:09 +00:00
|
|
|
|
|
2013-02-09 09:58:48 +00:00
|
|
|
|
(defcustom doc-view-odf->pdf-converter-function
|
|
|
|
|
(cond
|
|
|
|
|
((string-match "unoconv\\'" doc-view-odf->pdf-converter-program)
|
|
|
|
|
#'doc-view-odf->pdf-converter-unoconv)
|
|
|
|
|
((string-match "soffice\\'" doc-view-odf->pdf-converter-program)
|
|
|
|
|
#'doc-view-odf->pdf-converter-soffice))
|
|
|
|
|
"Function to call to convert a ODF file into a PDF file."
|
|
|
|
|
:type '(radio
|
|
|
|
|
(function-item doc-view-odf->pdf-converter-unoconv
|
|
|
|
|
:doc "Use unoconv")
|
|
|
|
|
(function-item doc-view-odf->pdf-converter-soffice
|
|
|
|
|
:doc "Use LibreOffice")
|
|
|
|
|
function)
|
|
|
|
|
:version "24.4")
|
|
|
|
|
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(defcustom doc-view-ps2pdf-program "ps2pdf"
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Program to convert PS files to PDF.
|
|
|
|
|
|
|
|
|
|
PS files will be converted to PDF before searching is possible."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'file)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(defcustom doc-view-pdftotext-program "pdftotext"
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Program to convert PDF files to plain text.
|
|
|
|
|
|
|
|
|
|
Needed for searching."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'file)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(defcustom doc-view-cache-directory
|
2007-11-01 03:53:44 +00:00
|
|
|
|
(expand-file-name (format "docview%d" (user-uid))
|
2007-10-31 21:17:32 +00:00
|
|
|
|
temporary-file-directory)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"The base directory, where the PNG images will be saved."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'directory)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-02-25 20:04:59 +00:00
|
|
|
|
(defvar doc-view-conversion-buffer " *doc-view conversion output*"
|
|
|
|
|
"The buffer where messages from the converter programs go to.")
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-02-25 20:04:59 +00:00
|
|
|
|
(defcustom doc-view-conversion-refresh-interval 1
|
2007-10-31 03:10:32 +00:00
|
|
|
|
"Interval in seconds between refreshes of the DocView buffer while converting.
|
|
|
|
|
After such a refresh newly converted pages will be available for
|
2007-09-09 22:29:16 +00:00
|
|
|
|
viewing. If set to nil there won't be any refreshes and the
|
|
|
|
|
pages won't be displayed before conversion of the whole document
|
|
|
|
|
has finished."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:type 'integer)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2009-11-30 16:14:48 +00:00
|
|
|
|
(defcustom doc-view-continuous nil
|
2009-11-23 20:34:53 +00:00
|
|
|
|
"In Continuous mode reaching the page edge advances to next/previous page.
|
|
|
|
|
When non-nil, scrolling a line upward at the bottom edge of the page
|
|
|
|
|
moves to the next page, and scrolling a line downward at the top edge
|
|
|
|
|
of the page moves to the previous page."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:version "23.2")
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;;; Internal Variables
|
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar-local doc-view--current-converter-processes nil
|
2013-05-21 07:25:14 +00:00
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(defun doc-view-new-window-function (winprops)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
;; (message "New window %s for buf %s" (car winprops) (current-buffer))
|
|
|
|
|
(cl-assert (or (eq t (car winprops))
|
|
|
|
|
(eq (window-buffer (car winprops)) (current-buffer))))
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(let ((ol (image-mode-window-get 'overlay winprops)))
|
|
|
|
|
(if ol
|
2010-02-01 18:25:47 +00:00
|
|
|
|
(progn
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(setq ol (copy-overlay ol))
|
|
|
|
|
;; `ol' might actually be dead.
|
|
|
|
|
(move-overlay ol (point-min) (point-max)))
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(setq ol (make-overlay (point-min) (point-max) nil t))
|
|
|
|
|
(overlay-put ol 'doc-view t))
|
|
|
|
|
(overlay-put ol 'window (car winprops))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(unless (windowp (car winprops))
|
|
|
|
|
;; It's a pseudo entry. Let's make sure it's not displayed (the
|
|
|
|
|
;; `window' property is only effective if its value is a window).
|
|
|
|
|
(cl-assert (eq t (car winprops)))
|
|
|
|
|
(delete-overlay ol))
|
2013-03-14 21:33:07 +00:00
|
|
|
|
(image-mode-window-put 'overlay ol winprops)
|
2013-05-24 17:42:23 +00:00
|
|
|
|
(when (and (windowp (car winprops))
|
|
|
|
|
(stringp (overlay-get ol 'display))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(null doc-view--current-converter-processes))
|
2013-05-24 17:42:23 +00:00
|
|
|
|
;; We're not displaying an image yet, so let's do so. This happens when
|
|
|
|
|
;; the buffer is displayed for the first time.
|
|
|
|
|
;; Don't do it if there's a conversion is running, since in that case, it
|
|
|
|
|
;; will be done later.
|
|
|
|
|
(with-selected-window (car winprops)
|
2014-04-17 03:58:25 +00:00
|
|
|
|
(doc-view-goto-page (image-mode-window-get 'page t))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar-local doc-view--current-files nil
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar-local doc-view--current-timer nil
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar-local doc-view--current-search-matches nil
|
2007-09-09 22:29:16 +00:00
|
|
|
|
"Only used internally.")
|
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar doc-view--pending-cache-flush nil
|
2007-12-03 07:24:34 +00:00
|
|
|
|
"Only used internally.")
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defvar doc-view--buffer-file-name nil
|
2008-01-10 15:08:34 +00:00
|
|
|
|
"Only used internally.
|
|
|
|
|
The file name used for conversion. Normally it's the same as
|
|
|
|
|
`buffer-file-name', but for remote files, compressed files and
|
|
|
|
|
files inside an archive it is a temporary copy of
|
|
|
|
|
the (uncompressed, extracted) file residing in
|
|
|
|
|
`doc-view-cache-directory'.")
|
|
|
|
|
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(defvar doc-view-single-page-converter-function nil
|
|
|
|
|
"Function to call to convert a single page of the document to a bitmap file.
|
|
|
|
|
May operate on the source document or on some intermediate (typically PDF)
|
|
|
|
|
conversion of it.")
|
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defvar-local doc-view--image-type nil
|
2013-01-09 21:24:42 +00:00
|
|
|
|
"The type of image in the current buffer.
|
|
|
|
|
Can be `png' or `tiff'.")
|
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defvar-local doc-view--image-file-pattern nil
|
|
|
|
|
"The `format' pattern of image file names.
|
|
|
|
|
Typically \"page-%s.png\".")
|
2013-01-09 21:24:42 +00:00
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;;;; DocView Keymaps
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defvar doc-view-mode-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
2008-06-03 07:42:03 +00:00
|
|
|
|
(set-keymap-parent map image-mode-map)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Navigation in the document
|
|
|
|
|
(define-key map (kbd "n") 'doc-view-next-page)
|
|
|
|
|
(define-key map (kbd "p") 'doc-view-previous-page)
|
2007-10-19 16:03:09 +00:00
|
|
|
|
(define-key map (kbd "<next>") 'forward-page)
|
|
|
|
|
(define-key map (kbd "<prior>") 'backward-page)
|
|
|
|
|
(define-key map [remap forward-page] 'doc-view-next-page)
|
|
|
|
|
(define-key map [remap backward-page] 'doc-view-previous-page)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(define-key map (kbd "SPC") 'doc-view-scroll-up-or-next-page)
|
2013-02-13 08:28:47 +00:00
|
|
|
|
(define-key map (kbd "S-SPC") 'doc-view-scroll-down-or-previous-page)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(define-key map (kbd "DEL") 'doc-view-scroll-down-or-previous-page)
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(define-key map (kbd "C-n") 'doc-view-next-line-or-next-page)
|
|
|
|
|
(define-key map (kbd "<down>") 'doc-view-next-line-or-next-page)
|
|
|
|
|
(define-key map (kbd "C-p") 'doc-view-previous-line-or-previous-page)
|
|
|
|
|
(define-key map (kbd "<up>") 'doc-view-previous-line-or-previous-page)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(define-key map (kbd "M-<") 'doc-view-first-page)
|
|
|
|
|
(define-key map (kbd "M->") 'doc-view-last-page)
|
2007-10-31 20:40:30 +00:00
|
|
|
|
(define-key map [remap goto-line] 'doc-view-goto-page)
|
2009-03-13 21:03:21 +00:00
|
|
|
|
(define-key map (kbd "RET") 'image-next-line)
|
2007-11-15 19:56:44 +00:00
|
|
|
|
;; Zoom in/out.
|
|
|
|
|
(define-key map "+" 'doc-view-enlarge)
|
2013-09-26 19:05:50 +00:00
|
|
|
|
(define-key map "=" 'doc-view-enlarge)
|
2007-11-15 19:56:44 +00:00
|
|
|
|
(define-key map "-" 'doc-view-shrink)
|
2013-09-27 06:46:49 +00:00
|
|
|
|
(define-key map "0" 'doc-view-scale-reset)
|
|
|
|
|
(define-key map [remap text-scale-adjust] 'doc-view-scale-adjust)
|
2011-04-08 20:09:19 +00:00
|
|
|
|
;; Fit the image to the window
|
|
|
|
|
(define-key map "W" 'doc-view-fit-width-to-window)
|
|
|
|
|
(define-key map "H" 'doc-view-fit-height-to-window)
|
|
|
|
|
(define-key map "P" 'doc-view-fit-page-to-window)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(define-key map "F" 'doc-view-fit-window-to-page) ;F = frame
|
2008-06-03 07:42:03 +00:00
|
|
|
|
;; Killing the buffer (and the process)
|
2020-12-11 09:24:58 +00:00
|
|
|
|
(define-key map (kbd "k") 'image-kill-buffer)
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(define-key map (kbd "K") 'doc-view-kill-proc)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Slicing the image
|
2020-04-22 23:14:42 +00:00
|
|
|
|
(define-key map (kbd "c s") 'doc-view-set-slice)
|
|
|
|
|
(define-key map (kbd "c m") 'doc-view-set-slice-using-mouse)
|
|
|
|
|
(define-key map (kbd "c b") 'doc-view-set-slice-from-bounding-box)
|
|
|
|
|
(define-key map (kbd "c r") 'doc-view-reset-slice)
|
2020-08-14 15:43:03 +00:00
|
|
|
|
;; Centering the image
|
|
|
|
|
(define-key map (kbd "c h") 'doc-view-center-page-horizontally)
|
|
|
|
|
(define-key map (kbd "c v") 'doc-view-center-page-vertically)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Searching
|
|
|
|
|
(define-key map (kbd "C-s") 'doc-view-search)
|
|
|
|
|
(define-key map (kbd "<find>") 'doc-view-search)
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(define-key map (kbd "C-r") 'doc-view-search-backward)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Show the tooltip
|
|
|
|
|
(define-key map (kbd "C-t") 'doc-view-show-tooltip)
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;; Toggle between text and image display or editing
|
|
|
|
|
(define-key map (kbd "C-c C-c") 'doc-view-toggle-display)
|
2008-03-12 12:05:30 +00:00
|
|
|
|
;; Open a new buffer with doc's text contents
|
|
|
|
|
(define-key map (kbd "C-c C-t") 'doc-view-open-text)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(define-key map (kbd "r") 'revert-buffer)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
map)
|
2007-10-17 21:34:19 +00:00
|
|
|
|
"Keymap used by `doc-view-mode' when displaying a doc as a set of images.")
|
|
|
|
|
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(define-obsolete-function-alias 'doc-view-revert-buffer #'revert-buffer "27.1")
|
|
|
|
|
(defvar revert-buffer-preserve-modes)
|
|
|
|
|
(defun doc-view--revert-buffer (orig-fun &rest args)
|
|
|
|
|
"Preserve the buffer's current mode and check PDF sanity."
|
2017-02-02 15:57:37 +00:00
|
|
|
|
(if (< undo-outer-limit (* 2 (buffer-size)))
|
|
|
|
|
;; It's normal for this operation to result in a very large undo entry.
|
|
|
|
|
(setq-local undo-outer-limit (* 2 (buffer-size))))
|
2015-10-22 15:01:57 +00:00
|
|
|
|
(cl-labels ((revert ()
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(let ((revert-buffer-preserve-modes t))
|
|
|
|
|
(apply orig-fun args)
|
|
|
|
|
;; Update the cached version of the pdf file,
|
|
|
|
|
;; too. This is the one that's used when
|
|
|
|
|
;; rendering (bug#26996).
|
|
|
|
|
(unless (equal buffer-file-name
|
|
|
|
|
doc-view--buffer-file-name)
|
|
|
|
|
;; FIXME: Lars says he needed to recreate
|
|
|
|
|
;; the dir, we should figure out why.
|
|
|
|
|
(doc-view-make-safe-dir doc-view-cache-directory)
|
|
|
|
|
(write-region nil nil doc-view--buffer-file-name)))))
|
2015-10-22 15:01:57 +00:00
|
|
|
|
(if (and (eq 'pdf doc-view-doc-type)
|
|
|
|
|
(executable-find "pdfinfo"))
|
|
|
|
|
;; We don't want to revert if the PDF file is corrupted which
|
2017-10-28 00:09:17 +00:00
|
|
|
|
;; might happen when it is currently recompiled from a tex
|
2015-10-22 15:01:57 +00:00
|
|
|
|
;; file. (TODO: We'd like to have something like that also
|
|
|
|
|
;; for other types, at least PS, but I don't know a good way
|
|
|
|
|
;; to test if a PS file is complete.)
|
2018-11-13 19:47:35 +00:00
|
|
|
|
(if (= 0 (call-process "pdfinfo" nil nil nil
|
2015-10-22 15:01:57 +00:00
|
|
|
|
doc-view--buffer-file-name))
|
|
|
|
|
(revert)
|
|
|
|
|
(when (called-interactively-p 'interactive)
|
|
|
|
|
(message "Can't revert right now because the file is corrupted.")))
|
|
|
|
|
(revert))))
|
2010-02-01 18:25:47 +00:00
|
|
|
|
|
|
|
|
|
|
2007-10-30 17:45:41 +00:00
|
|
|
|
(easy-menu-define doc-view-menu doc-view-mode-map
|
|
|
|
|
"Menu for Doc View mode."
|
|
|
|
|
'("DocView"
|
2021-11-19 10:34:28 +00:00
|
|
|
|
["Next page" doc-view-next-page
|
|
|
|
|
:help "Go to the next page"]
|
|
|
|
|
["Previous page" doc-view-previous-page
|
|
|
|
|
:help "Go to the previous page"]
|
|
|
|
|
("Other Navigation"
|
|
|
|
|
["Go to page..." doc-view-goto-page
|
|
|
|
|
:help "Go to specific page"]
|
|
|
|
|
"---"
|
|
|
|
|
["First page" doc-view-first-page
|
|
|
|
|
:help "View the first page"]
|
|
|
|
|
["Last page" doc-view-last-page
|
|
|
|
|
:help "View the last page"]
|
|
|
|
|
"---"
|
|
|
|
|
["Move forward" doc-view-scroll-up-or-next-page
|
|
|
|
|
:help "Scroll page up or go to next page"]
|
|
|
|
|
["Move backward" doc-view-scroll-down-or-previous-page
|
|
|
|
|
:help "Scroll page down or go to previous page"])
|
|
|
|
|
("Continuous Scrolling"
|
2009-11-30 16:14:48 +00:00
|
|
|
|
["Off" (setq doc-view-continuous nil)
|
2021-11-19 10:34:28 +00:00
|
|
|
|
:style radio :selected (eq doc-view-continuous nil)
|
|
|
|
|
:help "Scrolling stops at page beginning and end"]
|
2009-11-30 16:14:48 +00:00
|
|
|
|
["On" (setq doc-view-continuous t)
|
2021-11-19 10:34:28 +00:00
|
|
|
|
:style radio :selected (eq doc-view-continuous t)
|
|
|
|
|
:help "Scrolling continues to next or previous page"]
|
2009-11-30 16:14:48 +00:00
|
|
|
|
"---"
|
2021-11-19 10:34:28 +00:00
|
|
|
|
["Save as Default" (customize-save-variable 'doc-view-continuous doc-view-continuous)
|
|
|
|
|
:help "Save current continuous scrolling option as default"]
|
2009-11-30 16:14:48 +00:00
|
|
|
|
)
|
|
|
|
|
"---"
|
2021-11-19 10:34:28 +00:00
|
|
|
|
("Toggle edit/display"
|
|
|
|
|
["Edit document" doc-view-toggle-display
|
|
|
|
|
:style radio :selected (eq major-mode 'doc-view--text-view-mode)]
|
|
|
|
|
["Display document" (lambda ()) ; ignore but show no keybinding
|
|
|
|
|
:style radio :selected (eq major-mode 'doc-view-mode)])
|
|
|
|
|
("Adjust Display"
|
|
|
|
|
["Fit to window" doc-view-fit-page-to-window
|
|
|
|
|
:help "Fit the image to the window"]
|
|
|
|
|
["Fit width" doc-view-fit-width-to-window
|
|
|
|
|
:help "Fit the image width to the window width"]
|
|
|
|
|
["Fit height" doc-view-fit-height-to-window
|
|
|
|
|
:help "Fit the image height to the window height"]
|
|
|
|
|
"---"
|
|
|
|
|
["Enlarge" doc-view-enlarge
|
|
|
|
|
:help "Enlarge the document"]
|
|
|
|
|
["Shrink" doc-view-shrink
|
|
|
|
|
:help "Shrink the document"]
|
|
|
|
|
"---"
|
|
|
|
|
["Set Slice" doc-view-set-slice-using-mouse
|
|
|
|
|
:help "Set the slice of the images that should be displayed"]
|
|
|
|
|
["Set Slice (BoundingBox)" doc-view-set-slice-from-bounding-box
|
|
|
|
|
:help "Set the slice from the document's BoundingBox information"]
|
|
|
|
|
["Set Slice (manual)" doc-view-set-slice
|
|
|
|
|
:help "Set the slice of the images that should be displayed"]
|
|
|
|
|
["Reset Slice" doc-view-reset-slice
|
|
|
|
|
:help "Reset the current slice"
|
|
|
|
|
:enabled (image-mode-window-get 'slice)])
|
2007-10-30 17:45:41 +00:00
|
|
|
|
"---"
|
2021-11-19 10:34:28 +00:00
|
|
|
|
["New Search" (doc-view-search t)
|
|
|
|
|
:help "Initiate a new search"]
|
|
|
|
|
["Search Forward" doc-view-search
|
|
|
|
|
:help "Jump to the next match or initiate a new search"]
|
|
|
|
|
["Search Backward" doc-view-search-backward
|
|
|
|
|
:help "Jump to the previous match or initiate a new search"]
|
2007-10-30 17:45:41 +00:00
|
|
|
|
))
|
|
|
|
|
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(defvar doc-view-minor-mode-map
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
;; Toggle between text and image display or editing
|
|
|
|
|
(define-key map (kbd "C-c C-c") 'doc-view-toggle-display)
|
|
|
|
|
map)
|
2020-09-23 11:35:55 +00:00
|
|
|
|
"Keymap used by `doc-view-minor-mode'.")
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2021-11-19 10:34:28 +00:00
|
|
|
|
(easy-menu-define doc-view-minor-mode-menu doc-view-minor-mode-map
|
|
|
|
|
"Menu for Doc View minor mode."
|
|
|
|
|
'("DocView (edit)"
|
|
|
|
|
("Toggle edit/display"
|
|
|
|
|
["Edit document" (lambda ()) ; ignore but show no keybinding
|
|
|
|
|
:style radio :selected (eq major-mode 'doc-view--text-view-mode)]
|
|
|
|
|
["Display document" doc-view-toggle-display
|
|
|
|
|
:style radio :selected (eq major-mode 'doc-view-mode)])
|
|
|
|
|
["Exit DocView Mode" doc-view-minor-mode]))
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;;; Navigation Commands
|
|
|
|
|
|
2010-02-05 01:53:40 +00:00
|
|
|
|
(defun doc-view-last-page-number ()
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(length doc-view--current-files))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-goto-page (page)
|
|
|
|
|
"View the page given by PAGE."
|
|
|
|
|
(interactive "nPage: ")
|
2013-02-28 04:02:36 +00:00
|
|
|
|
(let ((len (doc-view-last-page-number)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(if (< page 1)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(setq page 1)
|
2008-02-25 20:04:59 +00:00
|
|
|
|
(when (and (> page len)
|
|
|
|
|
;; As long as the converter is running, we don't know
|
|
|
|
|
;; how many pages will be available.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(null doc-view--current-converter-processes))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(setq page len)))
|
2013-11-28 22:43:09 +00:00
|
|
|
|
(force-mode-line-update) ;To update `current-page'.
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(setf (doc-view-current-page) page
|
|
|
|
|
(doc-view-current-info)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(concat
|
|
|
|
|
(propertize
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(format "Page %d of %d." page len) 'face 'bold)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
;; Tell user if converting isn't finished yet
|
2022-05-04 12:24:31 +00:00
|
|
|
|
(and doc-view--current-converter-processes
|
|
|
|
|
" (still converting...)")
|
|
|
|
|
;; Display context infos if this page matches the last search
|
|
|
|
|
(when (and doc-view--current-search-matches
|
|
|
|
|
(assq page doc-view--current-search-matches))
|
|
|
|
|
(concat "\n" (propertize "Search matches:" 'face 'bold)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(let ((contexts ""))
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(dolist (m (cdr (assq page
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches)))
|
2022-05-04 12:24:31 +00:00
|
|
|
|
(setq contexts (concat contexts "\n - \"" m "\"")))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
contexts)))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Update the buffer
|
2013-05-27 01:08:43 +00:00
|
|
|
|
;; We used to find the file name from doc-view--current-files but
|
2008-02-25 20:04:59 +00:00
|
|
|
|
;; that's not right if the pages are not generated sequentially
|
2013-05-27 01:08:43 +00:00
|
|
|
|
;; or if the page isn't in doc-view--current-files yet.
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(let ((file (expand-file-name
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(format doc-view--image-file-pattern page)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir))))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(doc-view-insert-image file :pointer 'arrow)
|
|
|
|
|
(when (and (not (file-exists-p file))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-converter-processes)
|
2008-03-31 15:14:16 +00:00
|
|
|
|
;; The PNG file hasn't been generated yet.
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(funcall doc-view-single-page-converter-function
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--buffer-file-name file page
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(let ((win (selected-window)))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(and (eq (current-buffer) (window-buffer win))
|
|
|
|
|
;; If we changed page in the mean
|
|
|
|
|
;; time, don't mess things up.
|
|
|
|
|
(eq (doc-view-current-page win) page)
|
|
|
|
|
;; Make sure we don't infloop.
|
|
|
|
|
(file-readable-p file)
|
|
|
|
|
(with-selected-window win
|
|
|
|
|
(doc-view-goto-page page))))))))
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(overlay-put (doc-view-current-overlay)
|
2013-03-14 21:33:07 +00:00
|
|
|
|
'help-echo (doc-view-current-info))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-next-page (&optional arg)
|
|
|
|
|
"Browse ARG pages forward."
|
|
|
|
|
(interactive "p")
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(doc-view-goto-page (+ (doc-view-current-page) (or arg 1))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-previous-page (&optional arg)
|
|
|
|
|
"Browse ARG pages backward."
|
|
|
|
|
(interactive "p")
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(doc-view-goto-page (- (doc-view-current-page) (or arg 1))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(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)
|
2010-02-05 01:53:40 +00:00
|
|
|
|
(doc-view-goto-page (doc-view-last-page-number)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(defun doc-view-scroll-up-or-next-page (&optional arg)
|
|
|
|
|
"Scroll page up ARG lines if possible, else goto next page.
|
2009-11-30 16:14:48 +00:00
|
|
|
|
When `doc-view-continuous' is non-nil, scrolling upward
|
2009-11-25 17:18:26 +00:00
|
|
|
|
at the bottom edge of the page moves to the next page.
|
|
|
|
|
Otherwise, goto next page only on typing SPC (ARG is nil)."
|
|
|
|
|
(interactive "P")
|
2009-11-30 16:14:48 +00:00
|
|
|
|
(if (or doc-view-continuous (null arg))
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(let ((hscroll (window-hscroll))
|
|
|
|
|
(cur-page (doc-view-current-page)))
|
2019-10-25 20:07:39 +00:00
|
|
|
|
(when (= (window-vscroll nil t) (image-scroll-up arg))
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(doc-view-next-page)
|
|
|
|
|
(when (/= cur-page (doc-view-current-page))
|
|
|
|
|
(image-bob)
|
|
|
|
|
(image-bol 1))
|
|
|
|
|
(set-window-hscroll (selected-window) hscroll)))
|
|
|
|
|
(image-scroll-up arg)))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-scroll-down-or-previous-page (&optional arg)
|
|
|
|
|
"Scroll page down ARG lines if possible, else goto previous page.
|
2009-11-30 16:14:48 +00:00
|
|
|
|
When `doc-view-continuous' is non-nil, scrolling downward
|
2009-11-25 17:18:26 +00:00
|
|
|
|
at the top edge of the page moves to the previous page.
|
|
|
|
|
Otherwise, goto previous page only on typing DEL (ARG is nil)."
|
|
|
|
|
(interactive "P")
|
2009-11-30 16:14:48 +00:00
|
|
|
|
(if (or doc-view-continuous (null arg))
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(let ((hscroll (window-hscroll))
|
|
|
|
|
(cur-page (doc-view-current-page)))
|
2019-10-25 20:07:39 +00:00
|
|
|
|
(when (= (window-vscroll nil t) (image-scroll-down arg))
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(doc-view-previous-page)
|
|
|
|
|
(when (/= cur-page (doc-view-current-page))
|
|
|
|
|
(image-eob)
|
|
|
|
|
(image-bol 1))
|
|
|
|
|
(set-window-hscroll (selected-window) hscroll)))
|
|
|
|
|
(image-scroll-down arg)))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-next-line-or-next-page (&optional arg)
|
|
|
|
|
"Scroll upward by ARG lines if possible, else goto next page.
|
2009-11-30 16:14:48 +00:00
|
|
|
|
When `doc-view-continuous' is non-nil, scrolling a line upward
|
2009-11-25 17:18:26 +00:00
|
|
|
|
at the bottom edge of the page moves to the next page."
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(interactive "p")
|
2009-11-30 16:14:48 +00:00
|
|
|
|
(if doc-view-continuous
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(let ((hscroll (window-hscroll))
|
|
|
|
|
(cur-page (doc-view-current-page)))
|
2019-10-25 20:07:39 +00:00
|
|
|
|
(when (= (window-vscroll nil t) (image-next-line arg))
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(doc-view-next-page)
|
|
|
|
|
(when (/= cur-page (doc-view-current-page))
|
|
|
|
|
(image-bob)
|
|
|
|
|
(image-bol 1))
|
|
|
|
|
(set-window-hscroll (selected-window) hscroll)))
|
2016-03-14 10:15:10 +00:00
|
|
|
|
(image-next-line arg)))
|
2009-11-23 20:34:53 +00:00
|
|
|
|
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(defun doc-view-previous-line-or-previous-page (&optional arg)
|
|
|
|
|
"Scroll downward by ARG lines if possible, else goto previous page.
|
2009-11-30 16:14:48 +00:00
|
|
|
|
When `doc-view-continuous' is non-nil, scrolling a line downward
|
2009-11-23 20:34:53 +00:00
|
|
|
|
at the top edge of the page moves to the previous page."
|
|
|
|
|
(interactive "p")
|
2009-11-30 16:14:48 +00:00
|
|
|
|
(if doc-view-continuous
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(let ((hscroll (window-hscroll))
|
|
|
|
|
(cur-page (doc-view-current-page)))
|
2019-10-25 20:07:39 +00:00
|
|
|
|
(when (= (window-vscroll nil t) (image-previous-line arg))
|
2009-11-23 20:34:53 +00:00
|
|
|
|
(doc-view-previous-page)
|
|
|
|
|
(when (/= cur-page (doc-view-current-page))
|
|
|
|
|
(image-eob)
|
|
|
|
|
(image-bol 1))
|
|
|
|
|
(set-window-hscroll (selected-window) hscroll)))
|
2009-11-25 17:18:26 +00:00
|
|
|
|
(image-previous-line arg)))
|
2009-11-23 20:34:53 +00:00
|
|
|
|
|
2007-10-30 06:29:51 +00:00
|
|
|
|
;;;; Utility Functions
|
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(defun doc-view-kill-proc ()
|
2008-03-31 15:14:16 +00:00
|
|
|
|
"Kill the current converter process(es)."
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(interactive)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(while (consp doc-view--current-converter-processes)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(ignore-errors ;; Some entries might not be processes, and maybe
|
2022-01-27 16:03:38 +00:00
|
|
|
|
; some are dead already?
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(kill-process (pop doc-view--current-converter-processes))))
|
|
|
|
|
(when doc-view--current-timer
|
|
|
|
|
(cancel-timer doc-view--current-timer)
|
|
|
|
|
(setq doc-view--current-timer nil))
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(setq mode-line-process nil))
|
|
|
|
|
|
2015-02-05 17:57:01 +00:00
|
|
|
|
(define-obsolete-function-alias 'doc-view-kill-proc-and-buffer
|
|
|
|
|
#'image-kill-buffer "25.1")
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(defun doc-view-make-safe-dir (dir)
|
|
|
|
|
(condition-case nil
|
2014-05-14 17:15:15 +00:00
|
|
|
|
;; Create temp files with strict access rights. It's easy to
|
|
|
|
|
;; loosen them later, whereas it's impossible to close the
|
|
|
|
|
;; time-window of loose permissions otherwise.
|
|
|
|
|
(with-file-modes #o0700 (make-directory dir))
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(file-already-exists
|
|
|
|
|
;; In case it was created earlier with looser rights.
|
|
|
|
|
;; We could check the mode info returned by file-attributes, but it's
|
|
|
|
|
;; a pain to parse and it may not tell you what we want under
|
|
|
|
|
;; non-standard file-systems. So let's just say what we want and let
|
|
|
|
|
;; the underlying C code and file-system figure it out.
|
|
|
|
|
;; This also ends up checking a bunch of useful conditions: it makes
|
|
|
|
|
;; sure we have write-access to the directory and that we own it, thus
|
|
|
|
|
;; closing a bunch of security holes.
|
2011-07-16 19:38:25 +00:00
|
|
|
|
(condition-case error
|
Add 'nofollow' flag to set-file-modes etc.
This avoids some race conditions (Bug#39683). E.g., if some other
program changes a file to a symlink between the time Emacs creates
the file and the time it changes the file’s permissions, using the
new flag prevents Emacs from inadvertently changing the
permissions of a victim in some completely unrelated directory.
* admin/merge-gnulib (GNULIB_MODULES): Add fchmodat.
* doc/lispref/files.texi (Testing Accessibility, Changing Files):
* doc/lispref/os.texi (File Notifications):
* etc/NEWS:
Adjust documentation accordingly.
* lib/chmodat.c, lib/fchmodat.c, lib/lchmod.c, m4/fchmodat.m4:
* m4/lchmod.m4: New files, copied from Gnulib.
* lib/gnulib.mk.in: Regenerate.
* lisp/dired-aux.el (dired-do-chmod):
* lisp/doc-view.el (doc-view-make-safe-dir):
* lisp/emacs-lisp/autoload.el (autoload--save-buffer):
* lisp/emacs-lisp/bytecomp.el (byte-compile-file):
* lisp/eshell/em-pred.el (eshell-pred-file-mode):
* lisp/files.el (backup-buffer-copy, copy-directory):
* lisp/gnus/mail-source.el (mail-source-movemail):
* lisp/gnus/mm-decode.el (mm-display-external):
* lisp/gnus/nnmail.el (nnmail-write-region):
* lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy)
(tramp-adb-handle-write-region):
* lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-write-region):
* lisp/net/tramp.el (tramp-handle-write-region)
(tramp-make-tramp-temp-file):
* lisp/server.el (server-ensure-safe-dir):
* lisp/url/url-util.el (url-make-private-file):
When getting or setting file modes, avoid following symbolic links
when the file is not supposed to be a symbolic link.
* lisp/doc-view.el (doc-view-make-safe-dir):
Omit no-longer-needed separate symlink test.
* lisp/gnus/gnus-util.el (gnus-set-file-modes):
* lisp/net/tramp.el (tramp-handle-file-modes):
* lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes):
* src/fileio.c (symlink_nofollow_flag): New function.
(Ffile_modes, Fset_file_modes):
Support an optional FLAG arg. All C callers changed.
* lisp/net/ange-ftp.el (ange-ftp-set-file-modes):
* lisp/net/tramp-adb.el (tramp-adb-handle-set-file-modes):
* lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes):
* lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes):
Accept an optional FLAG arg that is currently ignored,
and add a FIXME comment for it.
* m4/gnulib-comp.m4: Regenerate.
2020-02-24 00:19:42 +00:00
|
|
|
|
(set-file-modes dir #o0700 'nofollow)
|
2011-07-16 19:38:25 +00:00
|
|
|
|
(file-error
|
|
|
|
|
(error
|
|
|
|
|
(format "Unable to use temporary directory %s: %s"
|
2019-01-23 22:27:21 +00:00
|
|
|
|
dir (mapconcat #'identity (cdr error) " "))))))))
|
2007-10-30 21:53:05 +00:00
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(defun doc-view--current-cache-dir ()
|
2007-10-30 06:29:51 +00:00
|
|
|
|
"Return the directory where the png files of the current doc should be saved.
|
|
|
|
|
It's a subdirectory of `doc-view-cache-directory'."
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(if doc-view--current-cache-dir
|
|
|
|
|
doc-view--current-cache-dir
|
2007-10-30 21:53:05 +00:00
|
|
|
|
;; Try and make sure doc-view-cache-directory exists and is safe.
|
|
|
|
|
(doc-view-make-safe-dir doc-view-cache-directory)
|
|
|
|
|
;; Now compute the subdirectory to use.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--current-cache-dir
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(file-name-as-directory
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(expand-file-name
|
2016-02-15 11:09:46 +00:00
|
|
|
|
(concat (thread-last
|
2021-09-22 03:57:48 +00:00
|
|
|
|
(file-name-nondirectory doc-view--buffer-file-name)
|
2016-02-14 18:56:46 +00:00
|
|
|
|
;; bug#13679
|
|
|
|
|
(subst-char-in-string ?% ?_)
|
2016-02-15 03:44:38 +00:00
|
|
|
|
;; arc-mode concatenates archive name and file name
|
2016-02-15 11:09:46 +00:00
|
|
|
|
;; with colon, which isn't allowed on MS-Windows.
|
2016-02-14 18:56:46 +00:00
|
|
|
|
(subst-char-in-string ?: ?_))
|
|
|
|
|
"-"
|
|
|
|
|
(let ((file doc-view--buffer-file-name))
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(set-buffer-multibyte nil)
|
|
|
|
|
(insert-file-contents-literally file)
|
|
|
|
|
(md5 (current-buffer)))))
|
2007-10-30 21:53:05 +00:00
|
|
|
|
doc-view-cache-directory)))))
|
2007-10-30 06:29:51 +00:00
|
|
|
|
|
2007-11-25 20:11:47 +00:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun doc-view-mode-p (type)
|
2010-12-30 13:45:09 +00:00
|
|
|
|
"Return non-nil if document type TYPE is available for `doc-view'.
|
2022-01-27 16:03:38 +00:00
|
|
|
|
Document types are symbols like `dvi', `ps', `pdf', `epub',
|
|
|
|
|
`cbz', `fb2', `xps', `oxps', or`odf' (any OpenDocument format)."
|
2007-11-25 20:11:47 +00:00
|
|
|
|
(and (display-graphic-p)
|
2020-08-14 11:53:09 +00:00
|
|
|
|
(image-type-available-p 'png)
|
2007-11-25 20:11:47 +00:00
|
|
|
|
(cond
|
|
|
|
|
((eq type 'dvi)
|
|
|
|
|
(and (doc-view-mode-p 'pdf)
|
2008-04-14 13:18:12 +00:00
|
|
|
|
(or (and doc-view-dvipdf-program
|
|
|
|
|
(executable-find doc-view-dvipdf-program))
|
|
|
|
|
(and doc-view-dvipdfm-program
|
|
|
|
|
(executable-find doc-view-dvipdfm-program)))))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
((memq type '(postscript ps eps pdf))
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(or (and doc-view-ghostscript-program
|
2021-11-29 14:48:03 +00:00
|
|
|
|
(executable-find doc-view-ghostscript-program))
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; for pdf also check for `doc-view-pdfdraw-program'
|
|
|
|
|
(when (eq type 'pdf)
|
|
|
|
|
(and doc-view-pdfdraw-program
|
|
|
|
|
(executable-find doc-view-pdfdraw-program)))))
|
2010-12-30 13:45:09 +00:00
|
|
|
|
((eq type 'odf)
|
2013-02-09 09:58:48 +00:00
|
|
|
|
(and doc-view-odf->pdf-converter-program
|
|
|
|
|
(executable-find doc-view-odf->pdf-converter-program)
|
2010-12-30 13:45:09 +00:00
|
|
|
|
(doc-view-mode-p 'pdf)))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
((eq type 'djvu)
|
|
|
|
|
(executable-find "ddjvu"))
|
2022-01-27 16:03:38 +00:00
|
|
|
|
((memq type '(epub cbz fb2 xps oxps))
|
|
|
|
|
;; first check if `doc-view-pdfdraw-program' is set to mutool
|
|
|
|
|
(and (string= doc-view-pdfdraw-program "mutool")
|
|
|
|
|
(executable-find "mutool")))
|
2007-11-25 20:11:47 +00:00
|
|
|
|
(t ;; unknown image type
|
|
|
|
|
nil))))
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;;; Conversion Functions
|
|
|
|
|
|
2007-11-15 19:56:44 +00:00
|
|
|
|
(defvar doc-view-shrink-factor 1.125)
|
|
|
|
|
|
|
|
|
|
(defun doc-view-enlarge (factor)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
"Enlarge the document by FACTOR."
|
2007-11-15 19:56:44 +00:00
|
|
|
|
(interactive (list doc-view-shrink-factor))
|
2020-08-14 11:53:09 +00:00
|
|
|
|
(if doc-view-scale-internally
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(let ((new (ceiling (* factor doc-view-image-width))))
|
|
|
|
|
(unless (equal new doc-view-image-width)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local doc-view-image-width new)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(doc-view-insert-image
|
|
|
|
|
(plist-get (cdr (doc-view-current-image)) :file)
|
|
|
|
|
:width doc-view-image-width)))
|
|
|
|
|
(let ((new (ceiling (* factor doc-view-resolution))))
|
|
|
|
|
(unless (equal new doc-view-resolution)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local doc-view-resolution new)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(doc-view-reconvert-doc)))))
|
2007-11-15 19:56:44 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-shrink (factor)
|
2021-09-14 06:43:18 +00:00
|
|
|
|
"Shrink the document by FACTOR."
|
2007-11-15 19:56:44 +00:00
|
|
|
|
(interactive (list doc-view-shrink-factor))
|
|
|
|
|
(doc-view-enlarge (/ 1.0 factor)))
|
|
|
|
|
|
2013-09-27 06:46:49 +00:00
|
|
|
|
(defun doc-view-scale-reset ()
|
2013-09-26 19:05:50 +00:00
|
|
|
|
"Reset the document size/zoom level to the initial one."
|
|
|
|
|
(interactive)
|
2020-08-14 11:53:09 +00:00
|
|
|
|
(if doc-view-scale-internally
|
2013-09-26 19:05:50 +00:00
|
|
|
|
(progn
|
|
|
|
|
(kill-local-variable 'doc-view-image-width)
|
|
|
|
|
(doc-view-insert-image
|
|
|
|
|
(plist-get (cdr (doc-view-current-image)) :file)
|
|
|
|
|
:width doc-view-image-width))
|
|
|
|
|
(kill-local-variable 'doc-view-resolution)
|
|
|
|
|
(doc-view-reconvert-doc)))
|
|
|
|
|
|
2013-09-27 06:46:49 +00:00
|
|
|
|
(defun doc-view-scale-adjust (factor)
|
|
|
|
|
"Adjust the scale of the DocView page images by FACTOR.
|
|
|
|
|
FACTOR defaults to `doc-view-shrink-factor'.
|
|
|
|
|
|
|
|
|
|
The actual adjustment made depends on the final component of the
|
2021-09-14 06:43:18 +00:00
|
|
|
|
keybinding used to invoke the command, with all modifiers removed:
|
2013-09-27 06:46:49 +00:00
|
|
|
|
|
|
|
|
|
+, = Increase the image scale by FACTOR
|
|
|
|
|
- Decrease the image scale by FACTOR
|
|
|
|
|
0 Reset the image scale to the initial scale"
|
|
|
|
|
(interactive (list doc-view-shrink-factor))
|
|
|
|
|
(let ((ev last-command-event)
|
|
|
|
|
(echo-keystrokes nil))
|
|
|
|
|
(pcase (event-basic-type ev)
|
|
|
|
|
((or ?+ ?=) (doc-view-enlarge factor))
|
|
|
|
|
(?- (doc-view-shrink factor))
|
|
|
|
|
(?0 (doc-view-scale-reset)))))
|
|
|
|
|
|
2011-04-08 20:09:19 +00:00
|
|
|
|
(defun doc-view-fit-width-to-window ()
|
|
|
|
|
"Fit the image width to the window width."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((win-width (- (nth 2 (window-inside-pixel-edges))
|
|
|
|
|
(nth 0 (window-inside-pixel-edges))))
|
|
|
|
|
(slice (doc-view-current-slice)))
|
|
|
|
|
(if (not slice)
|
|
|
|
|
(let ((img-width (car (image-display-size
|
|
|
|
|
(image-get-display-property) t))))
|
|
|
|
|
(doc-view-enlarge (/ (float win-width) (float img-width))))
|
|
|
|
|
|
|
|
|
|
;; If slice is set
|
|
|
|
|
(let* ((slice-width (nth 2 slice))
|
|
|
|
|
(scale-factor (/ (float win-width) (float slice-width)))
|
|
|
|
|
(new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
|
|
|
|
|
|
|
|
|
|
(doc-view-enlarge scale-factor)
|
|
|
|
|
(setf (doc-view-current-slice) new-slice)
|
|
|
|
|
(doc-view-goto-page (doc-view-current-page))))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-fit-height-to-window ()
|
|
|
|
|
"Fit the image height to the window height."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((win-height (- (nth 3 (window-inside-pixel-edges))
|
|
|
|
|
(nth 1 (window-inside-pixel-edges))))
|
|
|
|
|
(slice (doc-view-current-slice)))
|
|
|
|
|
(if (not slice)
|
|
|
|
|
(let ((img-height (cdr (image-display-size
|
|
|
|
|
(image-get-display-property) t))))
|
|
|
|
|
;; When users call 'doc-view-fit-height-to-window',
|
|
|
|
|
;; they might want to go to next page by typing SPC
|
|
|
|
|
;; ONLY once. So I used '(- win-height 1)' instead of
|
|
|
|
|
;; 'win-height'
|
|
|
|
|
(doc-view-enlarge (/ (float (- win-height 1)) (float img-height))))
|
|
|
|
|
|
|
|
|
|
;; If slice is set
|
|
|
|
|
(let* ((slice-height (nth 3 slice))
|
|
|
|
|
(scale-factor (/ (float (- win-height 1)) (float slice-height)))
|
|
|
|
|
(new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
|
|
|
|
|
|
|
|
|
|
(doc-view-enlarge scale-factor)
|
|
|
|
|
(setf (doc-view-current-slice) new-slice)
|
|
|
|
|
(doc-view-goto-page (doc-view-current-page))))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-fit-page-to-window ()
|
|
|
|
|
"Fit the image to the window.
|
|
|
|
|
More specifically, this function enlarges image by:
|
|
|
|
|
|
|
|
|
|
min {(window-width / image-width), (window-height / image-height)} times."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((win-width (- (nth 2 (window-inside-pixel-edges))
|
|
|
|
|
(nth 0 (window-inside-pixel-edges))))
|
|
|
|
|
(win-height (- (nth 3 (window-inside-pixel-edges))
|
|
|
|
|
(nth 1 (window-inside-pixel-edges))))
|
|
|
|
|
(slice (doc-view-current-slice)))
|
|
|
|
|
(if (not slice)
|
|
|
|
|
(let ((img-width (car (image-display-size
|
|
|
|
|
(image-get-display-property) t)))
|
|
|
|
|
(img-height (cdr (image-display-size
|
|
|
|
|
(image-get-display-property) t))))
|
|
|
|
|
(doc-view-enlarge (min (/ (float win-width) (float img-width))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(/ (float (- win-height 1))
|
|
|
|
|
(float img-height)))))
|
2011-04-08 20:09:19 +00:00
|
|
|
|
;; If slice is set
|
|
|
|
|
(let* ((slice-width (nth 2 slice))
|
|
|
|
|
(slice-height (nth 3 slice))
|
|
|
|
|
(scale-factor (min (/ (float win-width) (float slice-width))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(/ (float (- win-height 1))
|
|
|
|
|
(float slice-height))))
|
2011-04-08 20:09:19 +00:00
|
|
|
|
(new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
|
|
|
|
|
(doc-view-enlarge scale-factor)
|
|
|
|
|
(setf (doc-view-current-slice) new-slice)
|
|
|
|
|
(doc-view-goto-page (doc-view-current-page))))))
|
|
|
|
|
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(defun doc-view-fit-window-to-page ()
|
|
|
|
|
"Resize selected window so it just fits the current page.
|
|
|
|
|
Resize the containing frame if needed."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((slice (doc-view-current-slice))
|
|
|
|
|
(img-width (if slice (nth 2 slice)
|
|
|
|
|
(car (image-display-size
|
|
|
|
|
(image-get-display-property) t))))
|
|
|
|
|
(img-height (if slice (nth 3 slice)
|
|
|
|
|
(cdr (image-display-size
|
|
|
|
|
(image-get-display-property) t))))
|
|
|
|
|
(win-width (- (nth 2 (window-inside-pixel-edges))
|
|
|
|
|
(nth 0 (window-inside-pixel-edges))))
|
|
|
|
|
(win-height (- (nth 3 (window-inside-pixel-edges))
|
|
|
|
|
(nth 1 (window-inside-pixel-edges))))
|
|
|
|
|
(width-diff (- img-width win-width))
|
|
|
|
|
(height-diff (- img-height win-height))
|
|
|
|
|
(new-frame-params
|
2020-10-07 14:51:35 +00:00
|
|
|
|
;; If we can't resize the window, try and resize the frame.
|
|
|
|
|
;; We used to compare the `window-width/height` and the
|
|
|
|
|
;; `frame-width/height` instead of catching the errors, but
|
|
|
|
|
;; it's too fiddly (e.g. in the presence of the miniwindow,
|
|
|
|
|
;; the height the frame should be equal to the height of the
|
|
|
|
|
;; root window +1).
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(append
|
2020-10-07 14:51:35 +00:00
|
|
|
|
(condition-case nil
|
|
|
|
|
(progn
|
|
|
|
|
(enlarge-window (/ width-diff (frame-char-width)) 'horiz)
|
|
|
|
|
nil)
|
|
|
|
|
(error
|
|
|
|
|
`((width . (text-pixels
|
|
|
|
|
. ,(+ (frame-text-width) width-diff))))))
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(progn
|
|
|
|
|
(enlarge-window (/ height-diff (frame-char-height)) nil)
|
|
|
|
|
nil)
|
|
|
|
|
(error
|
|
|
|
|
`((height . (text-pixels
|
|
|
|
|
. ,(+ (frame-text-height) height-diff)))))))))
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(when new-frame-params
|
|
|
|
|
(modify-frame-parameters (selected-frame) new-frame-params))))
|
|
|
|
|
|
2020-08-14 15:43:03 +00:00
|
|
|
|
(defun doc-view-center-page-horizontally ()
|
|
|
|
|
"Center page horizontally when page is wider than window."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((page-width (car (image-size (doc-view-current-image) 'pixel)))
|
|
|
|
|
(window-width (window-body-width nil 'pixel))
|
|
|
|
|
;; How much do we scroll in order to center the page?
|
|
|
|
|
(pixel-hscroll 0)
|
|
|
|
|
;; How many pixels are there in a column?
|
|
|
|
|
(col-in-pixel (/ (window-body-width nil 'pixel)
|
|
|
|
|
(window-body-width nil))))
|
|
|
|
|
(when (> page-width window-width)
|
|
|
|
|
(setq pixel-hscroll (/ (- page-width window-width) 2))
|
|
|
|
|
(set-window-hscroll (selected-window)
|
|
|
|
|
(/ pixel-hscroll col-in-pixel)))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-center-page-vertically ()
|
|
|
|
|
"Center page vertically when page is wider than window."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((page-height (cdr (image-size (doc-view-current-image) 'pixel)))
|
|
|
|
|
(window-height (window-body-height nil 'pixel))
|
|
|
|
|
;; How much do we scroll in order to center the page?
|
|
|
|
|
(pixel-scroll 0))
|
|
|
|
|
(when (> page-height window-height)
|
|
|
|
|
(setq pixel-scroll (/ (- page-height window-height) 2))
|
|
|
|
|
(set-window-vscroll (selected-window) pixel-scroll 'pixel))))
|
|
|
|
|
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(defun doc-view-reconvert-doc ()
|
2007-10-17 21:34:19 +00:00
|
|
|
|
"Reconvert the current document.
|
|
|
|
|
Should be invoked when the cached images aren't up-to-date."
|
|
|
|
|
(interactive)
|
2007-10-30 17:45:41 +00:00
|
|
|
|
(doc-view-kill-proc)
|
|
|
|
|
;; Clear the old cached files
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(when (file-exists-p (doc-view--current-cache-dir))
|
|
|
|
|
(delete-directory (doc-view--current-cache-dir) 'recursive))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(kill-local-variable 'doc-view-last-page-number)
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(doc-view-initiate-display))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(defun doc-view-sentinel (proc event)
|
|
|
|
|
"Generic sentinel for doc-view conversion processes."
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(if (not (string-match "finished" event))
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(message "DocView: process %s changed status to %s."
|
2009-03-14 02:12:06 +00:00
|
|
|
|
(process-name proc)
|
|
|
|
|
(if (string-match "\\(.+\\)\n?\\'" event)
|
|
|
|
|
(match-string 1 event)
|
|
|
|
|
event))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(when (buffer-live-p (process-get proc 'buffer))
|
|
|
|
|
(with-current-buffer (process-get proc 'buffer)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--current-converter-processes
|
|
|
|
|
(delq proc doc-view--current-converter-processes))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(setq mode-line-process
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(if doc-view--current-converter-processes
|
|
|
|
|
(format ":%s" (car doc-view--current-converter-processes))))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(funcall (process-get proc 'callback))))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-start-process (name program args callback)
|
2008-04-14 11:02:31 +00:00
|
|
|
|
;; Make sure the process is started in an existing directory, (rather than
|
|
|
|
|
;; some file-name-handler-managed dir, for example).
|
2013-04-16 00:51:46 +00:00
|
|
|
|
(let* ((default-directory (or (unhandled-file-name-directory
|
|
|
|
|
default-directory)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(expand-file-name "~/")))
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(proc (apply #'start-process name doc-view-conversion-buffer
|
2008-03-31 15:14:16 +00:00
|
|
|
|
program args)))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(push proc doc-view--current-converter-processes)
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(setq mode-line-process (list (format ":%s" proc)))
|
|
|
|
|
(set-process-sentinel proc 'doc-view-sentinel)
|
|
|
|
|
(process-put proc 'buffer (current-buffer))
|
|
|
|
|
(process-put proc 'callback callback)))
|
2008-03-12 15:26:49 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-dvi->pdf (dvi pdf callback)
|
|
|
|
|
"Convert DVI to PDF asynchronously and call CALLBACK when finished."
|
2008-04-14 13:18:12 +00:00
|
|
|
|
;; Prefer dvipdf over dvipdfm, because the latter has problems if the DVI
|
|
|
|
|
;; references and includes other PS files.
|
|
|
|
|
(if (and doc-view-dvipdf-program
|
|
|
|
|
(executable-find doc-view-dvipdf-program))
|
|
|
|
|
(doc-view-start-process "dvi->pdf" doc-view-dvipdf-program
|
2011-02-10 18:53:49 +00:00
|
|
|
|
(list dvi pdf)
|
|
|
|
|
callback)
|
2008-04-14 13:18:12 +00:00
|
|
|
|
(doc-view-start-process "dvi->pdf" doc-view-dvipdfm-program
|
|
|
|
|
(list "-o" pdf dvi)
|
|
|
|
|
callback)))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(defun doc-view-pdf-password-protected-ghostscript-p (pdf)
|
|
|
|
|
"Return non-nil if a PDF file is password-protected.
|
|
|
|
|
The test is performed using `doc-view-ghostscript-program'."
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(apply #'call-process doc-view-ghostscript-program nil (current-buffer)
|
|
|
|
|
nil `(,@doc-view-ghostscript-options
|
|
|
|
|
"-sNODISPLAY"
|
|
|
|
|
,pdf))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(search-forward "This file requires a password for access." nil t)))
|
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defun doc-view-pdf->png-converter-ghostscript (pdf png page callback)
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(let ((pdf-passwd (if (doc-view-pdf-password-protected-ghostscript-p pdf)
|
|
|
|
|
(read-passwd "Enter password for PDF file: "))))
|
|
|
|
|
(doc-view-start-process
|
|
|
|
|
"pdf/ps->png" doc-view-ghostscript-program
|
|
|
|
|
`(,@doc-view-ghostscript-options
|
|
|
|
|
,(concat "-sDEVICE=" doc-view-ghostscript-device)
|
|
|
|
|
,(format "-r%d" (round doc-view-resolution))
|
|
|
|
|
,@(if page `(,(format "-dFirstPage=%d" page)))
|
|
|
|
|
,@(if page `(,(format "-dLastPage=%d" page)))
|
|
|
|
|
,@(if pdf-passwd `(,(format "-sPDFPassword=%s" pdf-passwd)))
|
|
|
|
|
,(concat "-sOutputFile=" png)
|
|
|
|
|
,pdf)
|
|
|
|
|
callback)))
|
2013-01-09 19:48:42 +00:00
|
|
|
|
|
|
|
|
|
(defalias 'doc-view-ps->png-converter-ghostscript
|
|
|
|
|
'doc-view-pdf->png-converter-ghostscript)
|
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defun doc-view-djvu->tiff-converter-ddjvu (djvu tiff page callback)
|
|
|
|
|
"Convert PAGE of a DJVU file to bitmap(s) asynchronously.
|
|
|
|
|
Call CALLBACK with no arguments when done.
|
|
|
|
|
If PAGE is nil, convert the whole document."
|
|
|
|
|
(doc-view-start-process
|
|
|
|
|
"djvu->tiff" "ddjvu"
|
|
|
|
|
`("-format=tiff"
|
|
|
|
|
;; ddjvu only accepts the range 1-999.
|
|
|
|
|
,(format "-scale=%d" (round doc-view-resolution))
|
|
|
|
|
;; -eachpage was only added after djvulibre-3.5.25.3!
|
|
|
|
|
,@(unless page '("-eachpage"))
|
|
|
|
|
,@(if page `(,(format "-page=%d" page)))
|
|
|
|
|
,djvu
|
|
|
|
|
,tiff)
|
|
|
|
|
callback))
|
|
|
|
|
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(defun doc-view-pdfdraw-program-subcommand ()
|
|
|
|
|
"Return the mutool subcommand replacing mudraw.
|
2019-11-11 18:30:13 +00:00
|
|
|
|
Recent MuPDF distributions replaced `mudraw' with `mutool draw'."
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(when (string-match "mutool[^/\\]*$" doc-view-pdfdraw-program)
|
|
|
|
|
'("draw")))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-pdf-password-protected-pdfdraw-p (pdf)
|
|
|
|
|
"Return non-nil if a PDF file is password-protected.
|
|
|
|
|
The test is performed using `doc-view-pdfdraw-program'."
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(apply #'call-process doc-view-pdfdraw-program nil (current-buffer) nil
|
|
|
|
|
`(,@(doc-view-pdfdraw-program-subcommand)
|
|
|
|
|
,(concat "-o" null-device)
|
|
|
|
|
;; In case PDF isn't password-protected, "draw" only one page.
|
|
|
|
|
,pdf "1"))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(search-forward "error: cannot authenticate password" nil t)))
|
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(defun doc-view-pdf->png-converter-mupdf (pdf png page callback)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(let* ((pdf-passwd (if (doc-view-pdf-password-protected-pdfdraw-p pdf)
|
|
|
|
|
(read-passwd "Enter password for PDF file: ")))
|
|
|
|
|
(options `(,(concat "-o" png)
|
|
|
|
|
,(format "-r%d" (round doc-view-resolution))
|
|
|
|
|
,@(if pdf-passwd `("-p" ,pdf-passwd)))))
|
2022-03-07 16:29:38 +00:00
|
|
|
|
(when (eq doc-view-doc-type 'epub)
|
|
|
|
|
(when doc-view-epub-font-size
|
|
|
|
|
(setq options (append options
|
|
|
|
|
(list (format "-S%s" doc-view-epub-font-size)))))
|
2022-06-26 15:52:29 +00:00
|
|
|
|
(when doc-view-epub-user-stylesheet
|
2022-03-07 16:29:38 +00:00
|
|
|
|
(setq options
|
|
|
|
|
(append options
|
|
|
|
|
(list (format "-U%s"
|
|
|
|
|
(expand-file-name
|
2022-06-26 15:52:29 +00:00
|
|
|
|
doc-view-epub-user-stylesheet)))))))
|
2019-02-03 16:48:31 +00:00
|
|
|
|
(doc-view-start-process
|
|
|
|
|
"pdf->png" doc-view-pdfdraw-program
|
|
|
|
|
`(,@(doc-view-pdfdraw-program-subcommand)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
,@options
|
2019-02-03 16:48:31 +00:00
|
|
|
|
,pdf
|
|
|
|
|
,@(if page `(,(format "%d" page))))
|
|
|
|
|
callback)))
|
2013-01-09 19:48:42 +00:00
|
|
|
|
|
2013-02-09 09:58:48 +00:00
|
|
|
|
(defun doc-view-odf->pdf-converter-unoconv (odf callback)
|
2010-12-30 13:45:09 +00:00
|
|
|
|
"Convert ODF to PDF asynchronously and call CALLBACK when finished.
|
|
|
|
|
The converted PDF is put into the current cache directory, and it
|
|
|
|
|
is named like ODF with the extension turned to pdf."
|
2013-02-09 09:58:48 +00:00
|
|
|
|
(doc-view-start-process "odf->pdf" doc-view-odf->pdf-converter-program
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(list "-f" "pdf" "-o" (doc-view--current-cache-dir) odf)
|
2010-12-30 13:45:09 +00:00
|
|
|
|
callback))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2013-02-09 09:58:48 +00:00
|
|
|
|
(defun doc-view-odf->pdf-converter-soffice (odf callback)
|
|
|
|
|
"Convert ODF to PDF asynchronously and call CALLBACK when finished.
|
|
|
|
|
The converted PDF is put into the current cache directory, and it
|
|
|
|
|
is named like ODF with the extension turned to pdf."
|
2013-02-12 11:53:34 +00:00
|
|
|
|
;; FIXME: soffice doesn't work when there's another running
|
|
|
|
|
;; LibreOffice instance, in which case it returns success without
|
|
|
|
|
;; actually doing anything. See LibreOffice bug
|
|
|
|
|
;; https://bugs.freedesktop.org/show_bug.cgi?id=37531. A workaround
|
|
|
|
|
;; is to start soffice with a separate UserInstallation directory.
|
|
|
|
|
(let ((tmp-user-install-dir (make-temp-file "libreoffice-docview" t)))
|
|
|
|
|
(doc-view-start-process "odf->pdf" doc-view-odf->pdf-converter-program
|
|
|
|
|
(list
|
|
|
|
|
(concat "-env:UserInstallation=file://"
|
2016-02-16 16:38:44 +00:00
|
|
|
|
;; The URL must be
|
|
|
|
|
;; file:///C:/tmp/dir on Windows.
|
|
|
|
|
;; https://wiki.documentfoundation.org/UserProfile.
|
|
|
|
|
(when (eq system-type 'windows-nt)
|
|
|
|
|
"/")
|
2013-02-12 11:53:34 +00:00
|
|
|
|
tmp-user-install-dir)
|
|
|
|
|
"--headless" "--convert-to" "pdf"
|
2013-05-27 01:08:43 +00:00
|
|
|
|
"--outdir" (doc-view--current-cache-dir) odf)
|
2013-02-12 11:53:34 +00:00
|
|
|
|
(lambda ()
|
|
|
|
|
(delete-directory tmp-user-install-dir t)
|
|
|
|
|
(funcall callback)))))
|
2013-02-09 09:58:48 +00:00
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-pdf/ps->png (pdf-ps png)
|
2013-01-09 21:24:42 +00:00
|
|
|
|
;; FIXME: Fix name and docstring to account for djvu&tiff.
|
2007-10-31 03:10:32 +00:00
|
|
|
|
"Convert PDF-PS to PNG asynchronously."
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(funcall
|
|
|
|
|
(pcase doc-view-doc-type
|
2022-01-28 13:47:15 +00:00
|
|
|
|
((or 'pdf 'odf 'epub 'cbz 'fb2 'xps 'oxps)
|
|
|
|
|
doc-view-pdf->png-converter-function)
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('djvu #'doc-view-djvu->tiff-converter-ddjvu)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(_ #'doc-view-ps->png-converter-ghostscript))
|
|
|
|
|
pdf-ps png nil
|
2011-02-10 18:53:49 +00:00
|
|
|
|
(let ((resolution doc-view-resolution))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
(lambda ()
|
|
|
|
|
;; Only create the resolution file when it's all done, so it also
|
|
|
|
|
;; serves as a witness that the conversion is complete.
|
|
|
|
|
(write-region (prin1-to-string resolution) nil
|
|
|
|
|
(expand-file-name "resolution.el"
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
nil 'silently)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(when doc-view--current-timer
|
|
|
|
|
(cancel-timer doc-view--current-timer)
|
|
|
|
|
(setq doc-view--current-timer nil))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(doc-view-display (current-buffer) 'force))))
|
|
|
|
|
|
2008-03-31 15:14:16 +00:00
|
|
|
|
;; Update the displayed pages as soon as they're done generating.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(when doc-view-conversion-refresh-interval
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--current-timer
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(run-at-time "1 secs" doc-view-conversion-refresh-interval
|
|
|
|
|
'doc-view-display
|
|
|
|
|
(current-buffer)))))
|
|
|
|
|
|
2008-06-12 03:56:20 +00:00
|
|
|
|
(declare-function clear-image-cache "image.c" (&optional filter))
|
|
|
|
|
|
2013-01-10 15:50:04 +00:00
|
|
|
|
(defun doc-view-document->bitmap (pdf png pages)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
"Convert a document file to bitmap images asynchronously.
|
2008-03-31 15:14:16 +00:00
|
|
|
|
Start by converting PAGES, and then the rest."
|
|
|
|
|
(if (null pages)
|
|
|
|
|
(doc-view-pdf/ps->png pdf png)
|
|
|
|
|
;; We could render several `pages' with a single process if they're
|
|
|
|
|
;; (almost) consecutive, but since in 99% of the cases, there'll be only
|
|
|
|
|
;; a single page anyway, and of the remaining 1%, few cases will have
|
|
|
|
|
;; consecutive pages, it's not worth the trouble.
|
2011-02-10 18:53:49 +00:00
|
|
|
|
(let ((rest (cdr pages)))
|
2013-01-10 15:50:04 +00:00
|
|
|
|
(funcall doc-view-single-page-converter-function
|
2013-01-09 21:24:42 +00:00
|
|
|
|
pdf (format png (car pages)) (car pages)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(lambda ()
|
|
|
|
|
(if rest
|
|
|
|
|
(doc-view-document->bitmap pdf png rest)
|
|
|
|
|
;; Yippie, the important pages are done, update the display.
|
|
|
|
|
(clear-image-cache)
|
|
|
|
|
;; For the windows that have a message (like "Welcome to
|
|
|
|
|
;; DocView") display property, clearing the image cache is
|
|
|
|
|
;; not sufficient.
|
|
|
|
|
(dolist (win (get-buffer-window-list (current-buffer) nil 'visible))
|
|
|
|
|
(with-selected-window win
|
|
|
|
|
(when (stringp (overlay-get (doc-view-current-overlay) 'display))
|
|
|
|
|
(doc-view-goto-page (doc-view-current-page)))))
|
|
|
|
|
;; Convert the rest of the pages.
|
|
|
|
|
(doc-view-pdf/ps->png pdf png)))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(defun doc-view-pdf->txt (pdf txt callback)
|
|
|
|
|
"Convert PDF to TXT asynchronously and call CALLBACK when finished."
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(or (executable-find doc-view-pdftotext-program)
|
2008-10-18 22:30:55 +00:00
|
|
|
|
(error "You need the `pdftotext' program to convert a PDF to text"))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(doc-view-start-process "pdf->txt" doc-view-pdftotext-program
|
2019-09-29 12:26:26 +00:00
|
|
|
|
(append doc-view-pdftotext-program-args
|
|
|
|
|
(list pdf txt))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
callback))
|
2008-03-12 12:05:30 +00:00
|
|
|
|
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(defun doc-view-current-cache-doc-pdf ()
|
|
|
|
|
"Return the name of the doc.pdf in the current cache dir.
|
2021-09-14 06:43:18 +00:00
|
|
|
|
This file exists only if the current document isn't a PDF or PS file already."
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(expand-file-name "doc.pdf" (doc-view--current-cache-dir)))
|
2012-09-28 10:05:46 +00:00
|
|
|
|
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(defun doc-view-doc->txt (txt callback)
|
|
|
|
|
"Convert the current document to text and call CALLBACK when done."
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(make-directory (doc-view--current-cache-dir) t)
|
Reduce use of (require 'cl).
* admin/bzrmerge.el: Use cl-lib.
* leim/quail/hangul.el: Don't require CL.
* leim/quail/ipa.el: Use cl-lib.
* vc/smerge-mode.el, vc/pcvs.el, vc/pcvs-util.el, vc/pcvs-info.el:
* vc/diff-mode.el, vc/cvs-status.el, uniquify.el, scroll-bar.el:
* register.el, progmodes/sh-script.el, net/gnutls.el, net/dbus.el:
* msb.el, mpc.el, minibuffer.el, international/ucs-normalize.el:
* international/quail.el, info-xref.el, imenu.el, image-mode.el:
* font-lock.el, filesets.el, edmacro.el, doc-view.el, bookmark.el:
* battery.el, avoid.el, abbrev.el: Use cl-lib.
* vc/pcvs-parse.el, vc/pcvs-defs.el, vc/log-view.el, vc/log-edit.el:
* vc/diff.el, simple.el, pcomplete.el, lpr.el, comint.el, loadhist.el:
* jit-lock.el, international/iso-ascii.el, info.el, frame.el, bs.el:
* emulation/crisp.el, electric.el, dired.el, cus-dep.el, composite.el:
* calculator.el, autorevert.el, apropos.el: Don't require CL.
* emacs-bytecomp.el (byte-recompile-directory, display-call-tree)
(byte-compile-unfold-bcf, byte-compile-check-variable):
* emacs-byte-opt.el (byte-compile-trueconstp)
(byte-compile-nilconstp):
* emacs-autoload.el (make-autoload): Use pcase.
* face-remap.el (text-scale-adjust): Simplify pcase patterns.
2012-07-10 11:51:54 +00:00
|
|
|
|
(pcase doc-view-doc-type
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('pdf
|
2008-03-12 15:26:49 +00:00
|
|
|
|
;; Doc is a PDF, so convert it to TXT
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-pdf->txt doc-view--buffer-file-name txt callback))
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('ps
|
2008-03-12 15:26:49 +00:00
|
|
|
|
;; Doc is a PS, so convert it to PDF (which will be converted to
|
|
|
|
|
;; TXT thereafter).
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(let ((pdf (doc-view-current-cache-doc-pdf)))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-ps->pdf doc-view--buffer-file-name pdf
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(lambda () (doc-view-pdf->txt pdf txt callback)))))
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('dvi
|
2008-03-12 15:26:49 +00:00
|
|
|
|
;; Doc is a DVI. This means that a doc.pdf already exists in its
|
|
|
|
|
;; cache subdirectory.
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(doc-view-pdf->txt (doc-view-current-cache-doc-pdf) txt callback))
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('odf
|
2010-12-30 13:53:22 +00:00
|
|
|
|
;; Doc is some ODF (or MS Office) doc. This means that a doc.pdf
|
|
|
|
|
;; already exists in its cache subdirectory.
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(doc-view-pdf->txt (doc-view-current-cache-doc-pdf) txt callback))
|
Reduce use of (require 'cl).
* admin/bzrmerge.el: Use cl-lib.
* leim/quail/hangul.el: Don't require CL.
* leim/quail/ipa.el: Use cl-lib.
* vc/smerge-mode.el, vc/pcvs.el, vc/pcvs-util.el, vc/pcvs-info.el:
* vc/diff-mode.el, vc/cvs-status.el, uniquify.el, scroll-bar.el:
* register.el, progmodes/sh-script.el, net/gnutls.el, net/dbus.el:
* msb.el, mpc.el, minibuffer.el, international/ucs-normalize.el:
* international/quail.el, info-xref.el, imenu.el, image-mode.el:
* font-lock.el, filesets.el, edmacro.el, doc-view.el, bookmark.el:
* battery.el, avoid.el, abbrev.el: Use cl-lib.
* vc/pcvs-parse.el, vc/pcvs-defs.el, vc/log-view.el, vc/log-edit.el:
* vc/diff.el, simple.el, pcomplete.el, lpr.el, comint.el, loadhist.el:
* jit-lock.el, international/iso-ascii.el, info.el, frame.el, bs.el:
* emulation/crisp.el, electric.el, dired.el, cus-dep.el, composite.el:
* calculator.el, autorevert.el, apropos.el: Don't require CL.
* emacs-bytecomp.el (byte-recompile-directory, display-call-tree)
(byte-compile-unfold-bcf, byte-compile-check-variable):
* emacs-byte-opt.el (byte-compile-trueconstp)
(byte-compile-nilconstp):
* emacs-autoload.el (make-autoload): Use pcase.
* face-remap.el (text-scale-adjust): Simplify pcase patterns.
2012-07-10 11:51:54 +00:00
|
|
|
|
(_ (error "DocView doesn't know what to do"))))
|
2008-03-12 15:26:49 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-ps->pdf (ps pdf callback)
|
|
|
|
|
"Convert PS to PDF asynchronously and call CALLBACK when finished."
|
2011-10-29 00:39:57 +00:00
|
|
|
|
(or (executable-find doc-view-ps2pdf-program)
|
2008-10-18 22:30:55 +00:00
|
|
|
|
(error "You need the `ps2pdf' program to convert PS to PDF"))
|
2008-03-31 15:14:16 +00:00
|
|
|
|
(doc-view-start-process "ps->pdf" doc-view-ps2pdf-program
|
|
|
|
|
(list
|
|
|
|
|
;; Avoid security problems when rendering files from
|
|
|
|
|
;; untrusted sources.
|
|
|
|
|
"-dSAFER"
|
|
|
|
|
;; in-file and out-file
|
|
|
|
|
ps pdf)
|
|
|
|
|
callback))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-active-pages ()
|
|
|
|
|
(let ((pages ()))
|
|
|
|
|
(dolist (win (get-buffer-window-list (current-buffer) nil 'visible))
|
|
|
|
|
(let ((page (image-mode-window-get 'page win)))
|
|
|
|
|
(unless (memq page pages) (push page pages))))
|
|
|
|
|
pages))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(defun doc-view-convert-current-doc ()
|
2013-05-27 01:08:43 +00:00
|
|
|
|
"Convert `doc-view--buffer-file-name' to a set of png files, one file per page.
|
2007-10-17 21:34:19 +00:00
|
|
|
|
Those files are saved in the directory given by the function
|
2013-05-27 01:08:43 +00:00
|
|
|
|
`doc-view--current-cache-dir'."
|
2007-10-30 21:53:05 +00:00
|
|
|
|
;; Let stale files still display while we recompute the new ones, so only
|
|
|
|
|
;; flush the cache when the conversion is over. One of the reasons why it
|
|
|
|
|
;; is important to keep displaying the stale page is so that revert-buffer
|
|
|
|
|
;; preserves the horizontal/vertical scroll settings (which are otherwise
|
2013-05-27 01:08:43 +00:00
|
|
|
|
;; reset during the redisplay).
|
|
|
|
|
(setq doc-view--pending-cache-flush t)
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(let ((png-file (expand-file-name
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(format doc-view--image-file-pattern "%d")
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir))))
|
|
|
|
|
(make-directory (doc-view--current-cache-dir) t)
|
Reduce use of (require 'cl).
* admin/bzrmerge.el: Use cl-lib.
* leim/quail/hangul.el: Don't require CL.
* leim/quail/ipa.el: Use cl-lib.
* vc/smerge-mode.el, vc/pcvs.el, vc/pcvs-util.el, vc/pcvs-info.el:
* vc/diff-mode.el, vc/cvs-status.el, uniquify.el, scroll-bar.el:
* register.el, progmodes/sh-script.el, net/gnutls.el, net/dbus.el:
* msb.el, mpc.el, minibuffer.el, international/ucs-normalize.el:
* international/quail.el, info-xref.el, imenu.el, image-mode.el:
* font-lock.el, filesets.el, edmacro.el, doc-view.el, bookmark.el:
* battery.el, avoid.el, abbrev.el: Use cl-lib.
* vc/pcvs-parse.el, vc/pcvs-defs.el, vc/log-view.el, vc/log-edit.el:
* vc/diff.el, simple.el, pcomplete.el, lpr.el, comint.el, loadhist.el:
* jit-lock.el, international/iso-ascii.el, info.el, frame.el, bs.el:
* emulation/crisp.el, electric.el, dired.el, cus-dep.el, composite.el:
* calculator.el, autorevert.el, apropos.el: Don't require CL.
* emacs-bytecomp.el (byte-recompile-directory, display-call-tree)
(byte-compile-unfold-bcf, byte-compile-check-variable):
* emacs-byte-opt.el (byte-compile-trueconstp)
(byte-compile-nilconstp):
* emacs-autoload.el (make-autoload): Use pcase.
* face-remap.el (text-scale-adjust): Simplify pcase patterns.
2012-07-10 11:51:54 +00:00
|
|
|
|
(pcase doc-view-doc-type
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('dvi
|
2008-03-12 14:50:36 +00:00
|
|
|
|
;; DVI files have to be converted to PDF before Ghostscript can process
|
|
|
|
|
;; it.
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(let ((pdf (doc-view-current-cache-doc-pdf)))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-dvi->pdf doc-view--buffer-file-name pdf
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(lambda () (doc-view-pdf/ps->png pdf png-file)))))
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('odf
|
2010-12-30 13:45:09 +00:00
|
|
|
|
;; ODF files have to be converted to PDF before Ghostscript can
|
|
|
|
|
;; process it.
|
2012-09-28 10:05:46 +00:00
|
|
|
|
(let ((pdf (doc-view-current-cache-doc-pdf))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(opdf (expand-file-name
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(concat (file-name-base doc-view--buffer-file-name)
|
2013-01-09 21:24:42 +00:00
|
|
|
|
".pdf")
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-cache-dir))
|
2012-04-26 12:43:28 +00:00
|
|
|
|
(png-file png-file))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
;; The unoconv tool only supports an output directory, but no
|
2010-12-30 13:45:09 +00:00
|
|
|
|
;; file name. It's named like the input file with the
|
|
|
|
|
;; extension replaced by pdf.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(funcall doc-view-odf->pdf-converter-function doc-view--buffer-file-name
|
2018-11-05 00:22:15 +00:00
|
|
|
|
(lambda ()
|
|
|
|
|
;; Rename to doc.pdf
|
|
|
|
|
(rename-file opdf pdf)
|
|
|
|
|
(doc-view-pdf/ps->png pdf png-file)))))
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; The doc-view-mode-p check ensures that epub, cbz, fb2 and
|
|
|
|
|
;; (o)xps are handled with mutool
|
|
|
|
|
((or 'pdf 'djvu 'epub 'cbz 'fb2 'xps 'oxps)
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(let ((pages (doc-view-active-pages)))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
;; Convert doc to bitmap images starting with the active pages.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-document->bitmap doc-view--buffer-file-name png-file pages)))
|
Reduce use of (require 'cl).
* admin/bzrmerge.el: Use cl-lib.
* leim/quail/hangul.el: Don't require CL.
* leim/quail/ipa.el: Use cl-lib.
* vc/smerge-mode.el, vc/pcvs.el, vc/pcvs-util.el, vc/pcvs-info.el:
* vc/diff-mode.el, vc/cvs-status.el, uniquify.el, scroll-bar.el:
* register.el, progmodes/sh-script.el, net/gnutls.el, net/dbus.el:
* msb.el, mpc.el, minibuffer.el, international/ucs-normalize.el:
* international/quail.el, info-xref.el, imenu.el, image-mode.el:
* font-lock.el, filesets.el, edmacro.el, doc-view.el, bookmark.el:
* battery.el, avoid.el, abbrev.el: Use cl-lib.
* vc/pcvs-parse.el, vc/pcvs-defs.el, vc/log-view.el, vc/log-edit.el:
* vc/diff.el, simple.el, pcomplete.el, lpr.el, comint.el, loadhist.el:
* jit-lock.el, international/iso-ascii.el, info.el, frame.el, bs.el:
* emulation/crisp.el, electric.el, dired.el, cus-dep.el, composite.el:
* calculator.el, autorevert.el, apropos.el: Don't require CL.
* emacs-bytecomp.el (byte-recompile-directory, display-call-tree)
(byte-compile-unfold-bcf, byte-compile-check-variable):
* emacs-byte-opt.el (byte-compile-trueconstp)
(byte-compile-nilconstp):
* emacs-autoload.el (make-autoload): Use pcase.
* face-remap.el (text-scale-adjust): Simplify pcase patterns.
2012-07-10 11:51:54 +00:00
|
|
|
|
(_
|
2008-03-12 14:50:36 +00:00
|
|
|
|
;; Convert to PNG images.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-pdf/ps->png doc-view--buffer-file-name png-file)))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;;; Slicing
|
|
|
|
|
|
2008-06-12 03:56:20 +00:00
|
|
|
|
(declare-function image-size "image.c" (spec &optional pixels frame))
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-set-slice (x y width height)
|
|
|
|
|
"Set the slice of the images that should be displayed.
|
|
|
|
|
You can use this function to tell doc-view not to display the
|
|
|
|
|
margins of the document. It prompts for the top-left corner (X
|
|
|
|
|
and Y) of the slice to display and its WIDTH and HEIGHT.
|
|
|
|
|
|
2012-09-19 17:35:18 +00:00
|
|
|
|
See `doc-view-set-slice-using-mouse' and
|
|
|
|
|
`doc-view-set-slice-from-bounding-box' for more convenient ways
|
|
|
|
|
to do that. To reset the slice use `doc-view-reset-slice'."
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(interactive
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(let* ((size (image-size (doc-view-current-image) t))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(a (read-number (format "Top-left X (0..%d): " (car size))))
|
|
|
|
|
(b (read-number (format "Top-left Y (0..%d): " (cdr size))))
|
|
|
|
|
(c (read-number (format "Width (0..%d): " (- (car size) a))))
|
|
|
|
|
(d (read-number (format "Height (0..%d): " (- (cdr size) b)))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(list a b c d)))
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(setf (doc-view-current-slice) (list x y width height))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Redisplay
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(doc-view-goto-page (doc-view-current-page)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-set-slice-using-mouse ()
|
|
|
|
|
"Set the slice of the images that should be displayed.
|
|
|
|
|
You set the slice by pressing mouse-1 at its top-left corner and
|
|
|
|
|
dragging it to its bottom-right corner. See also
|
|
|
|
|
`doc-view-set-slice' and `doc-view-reset-slice'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let (x y w h done)
|
|
|
|
|
(while (not done)
|
|
|
|
|
(let ((e (read-event
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(concat "Press mouse-1 at the top-left corner and "
|
|
|
|
|
"drag it to the bottom-right corner!"))))
|
|
|
|
|
(when (eq (car e) 'drag-mouse-1)
|
|
|
|
|
(setq x (car (posn-object-x-y (event-start e))))
|
|
|
|
|
(setq y (cdr (posn-object-x-y (event-start e))))
|
|
|
|
|
(setq w (- (car (posn-object-x-y (event-end e))) x))
|
|
|
|
|
(setq h (- (cdr (posn-object-x-y (event-end e))) y))
|
|
|
|
|
(setq done t))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(doc-view-set-slice x y w h)))
|
|
|
|
|
|
2012-09-19 17:35:18 +00:00
|
|
|
|
(defun doc-view-get-bounding-box ()
|
|
|
|
|
"Get the BoundingBox information of the current page."
|
2020-08-26 12:37:13 +00:00
|
|
|
|
(let ((page (doc-view-current-page))
|
|
|
|
|
(doc (let ((cache-doc (doc-view-current-cache-doc-pdf)))
|
|
|
|
|
(if (file-exists-p cache-doc)
|
|
|
|
|
cache-doc
|
|
|
|
|
doc-view--buffer-file-name))))
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(when (eq 0 (ignore-errors
|
|
|
|
|
(process-file doc-view-ghostscript-program nil t
|
|
|
|
|
nil "-dSAFER" "-dBATCH" "-dNOPAUSE" "-q"
|
|
|
|
|
"-sDEVICE=bbox"
|
|
|
|
|
(format "-dFirstPage=%s" page)
|
|
|
|
|
(format "-dLastPage=%s" page)
|
|
|
|
|
doc)))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(save-match-data
|
|
|
|
|
(when (re-search-forward
|
|
|
|
|
(concat "%%BoundingBox: "
|
|
|
|
|
"\\([[:digit:]]+\\) \\([[:digit:]]+\\) "
|
|
|
|
|
"\\([[:digit:]]+\\) \\([[:digit:]]+\\)")
|
|
|
|
|
nil t)
|
|
|
|
|
(mapcar #'string-to-number
|
|
|
|
|
(list (match-string 1)
|
|
|
|
|
(match-string 2)
|
|
|
|
|
(match-string 3)
|
|
|
|
|
(match-string 4)))))))))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
|
|
|
|
|
(defvar doc-view-paper-sizes
|
|
|
|
|
'((a4 595 842)
|
|
|
|
|
(a4-landscape 842 595)
|
|
|
|
|
(letter 612 792)
|
|
|
|
|
(letter-landscape 792 612)
|
|
|
|
|
(legal 612 1008)
|
|
|
|
|
(legal-landscape 1008 612)
|
|
|
|
|
(a3 842 1191)
|
|
|
|
|
(a3-landscape 1191 842)
|
|
|
|
|
(tabloid 792 1224)
|
|
|
|
|
(ledger 1224 792))
|
|
|
|
|
"An alist from paper size names to dimensions.")
|
|
|
|
|
|
|
|
|
|
(defun doc-view-guess-paper-size (iw ih)
|
|
|
|
|
"Guess the paper size according to the aspect ratio."
|
|
|
|
|
(cl-labels ((div (x y)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
(round (/ (* 100.0 x) y))))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
(let ((ar (div iw ih))
|
|
|
|
|
(al (mapcar (lambda (l)
|
2012-09-19 17:54:59 +00:00
|
|
|
|
(list (div (nth 1 l) (nth 2 l)) (car l)))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
doc-view-paper-sizes)))
|
|
|
|
|
(cadr (assoc ar al)))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-scale-bounding-box (ps iw ih bb)
|
2012-09-19 17:54:59 +00:00
|
|
|
|
(list (/ (* (nth 0 bb) iw) (nth 1 (assoc ps doc-view-paper-sizes)))
|
|
|
|
|
(/ (* (nth 1 bb) ih) (nth 2 (assoc ps doc-view-paper-sizes)))
|
|
|
|
|
(/ (* (nth 2 bb) iw) (nth 1 (assoc ps doc-view-paper-sizes)))
|
|
|
|
|
(/ (* (nth 3 bb) ih) (nth 2 (assoc ps doc-view-paper-sizes)))))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-set-slice-from-bounding-box (&optional force-paper-size)
|
|
|
|
|
"Set the slice from the document's BoundingBox information.
|
|
|
|
|
The result is that the margins are almost completely cropped,
|
|
|
|
|
much more accurate than could be done manually using
|
|
|
|
|
`doc-view-set-slice-using-mouse'."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((bb (doc-view-get-bounding-box)))
|
|
|
|
|
(if (not bb)
|
|
|
|
|
(message "BoundingBox couldn't be determined")
|
|
|
|
|
(let* ((is (image-size (doc-view-current-image) t))
|
|
|
|
|
(iw (car is))
|
|
|
|
|
(ih (cdr is))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(ps (or (and (null force-paper-size)
|
|
|
|
|
(doc-view-guess-paper-size iw ih))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
(intern (completing-read "Paper size: "
|
2013-01-10 05:05:24 +00:00
|
|
|
|
doc-view-paper-sizes
|
2012-09-19 17:35:18 +00:00
|
|
|
|
nil t))))
|
|
|
|
|
(bb (doc-view-scale-bounding-box ps iw ih bb))
|
|
|
|
|
(x1 (nth 0 bb))
|
|
|
|
|
(y1 (nth 1 bb))
|
|
|
|
|
(x2 (nth 2 bb))
|
|
|
|
|
(y2 (nth 3 bb)))
|
|
|
|
|
;; We keep a 2 pixel margin.
|
|
|
|
|
(doc-view-set-slice (- x1 2) (- ih y2 2)
|
|
|
|
|
(+ (- x2 x1) 4) (+ (- y2 y1) 4))))))
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-reset-slice ()
|
2007-10-03 23:40:07 +00:00
|
|
|
|
"Reset the current slice.
|
2007-10-31 03:10:32 +00:00
|
|
|
|
After calling this function whole pages will be visible again."
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(interactive)
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(setf (doc-view-current-slice) nil)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;; Redisplay
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(doc-view-goto-page (doc-view-current-page)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
;;;; Display
|
|
|
|
|
|
|
|
|
|
(defun doc-view-insert-image (file &rest args)
|
|
|
|
|
"Insert the given png FILE.
|
2007-10-03 23:40:07 +00:00
|
|
|
|
ARGS is a list of image descriptors."
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(when doc-view--pending-cache-flush
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(clear-image-cache)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--pending-cache-flush nil))
|
2013-03-14 15:24:04 +00:00
|
|
|
|
(let ((ol (doc-view-current-overlay)))
|
2013-03-14 21:33:07 +00:00
|
|
|
|
;; Only insert the image if the buffer is visible.
|
|
|
|
|
(when (window-live-p (overlay-get ol 'window))
|
2013-03-14 15:24:04 +00:00
|
|
|
|
(let* ((image (if (and file (file-readable-p file))
|
2020-08-14 11:53:09 +00:00
|
|
|
|
(if (not doc-view-scale-internally)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(apply #'create-image file doc-view--image-type nil args)
|
2013-03-14 15:24:04 +00:00
|
|
|
|
(unless (member :width args)
|
|
|
|
|
(setq args `(,@args :width ,doc-view-image-width)))
|
2021-03-09 18:05:10 +00:00
|
|
|
|
(unless (member :transform-smoothing args)
|
|
|
|
|
(setq args `(,@args :transform-smoothing t)))
|
2020-08-14 11:53:09 +00:00
|
|
|
|
(apply #'create-image file doc-view--image-type nil args))))
|
2013-03-14 15:24:04 +00:00
|
|
|
|
(slice (doc-view-current-slice))
|
|
|
|
|
(img-width (and image (car (image-size image))))
|
|
|
|
|
(displayed-img-width (if (and image slice)
|
|
|
|
|
(* (/ (float (nth 2 slice))
|
|
|
|
|
(car (image-size image 'pixels)))
|
|
|
|
|
img-width)
|
|
|
|
|
img-width))
|
Do not call to `selected-window' where it is assumed by default.
Affected functions are `window-minibuffer-p', `window-dedicated-p',
`window-hscroll', `window-width', `window-height', `window-buffer',
`window-frame', `window-start', `window-point', `next-window'
and `window-display-table'.
* abbrev.el (abbrev--default-expand):
* bs.el (bs--show-with-configuration):
* buff-menu.el (Buffer-menu-mouse-select):
* calc/calc.el (calc):
* calendar/calendar.el (calendar-generate-window):
* calendar/diary-lib.el (diary-simple-display, diary-show-all-entries)
(diary-make-entry):
* comint.el (send-invisible, comint-dynamic-complete-filename)
(comint-dynamic-simple-complete, comint-dynamic-list-completions):
* completion.el (complete):
* dabbrev.el (dabbrev-expand, dabbrev--make-friend-buffer-list):
* disp-table.el (describe-current-display-table):
* doc-view.el (doc-view-insert-image):
* ebuff-menu.el (Electric-buffer-menu-mouse-select):
* ehelp.el (with-electric-help):
* emacs-lisp/easy-mmode.el (easy-mmode-define-navigation):
* emacs-lisp/edebug.el (edebug-two-window-p, edebug-pop-to-buffer):
* emacs-lisp/helper.el (Helper-help-scroller):
* emulation/cua-base.el (cua--post-command-handler-1):
* eshell/esh-mode.el (eshell-output-filter):
* ffap.el (ffap-gnus-wrapper):
* help-macro.el (make-help-screen):
* hilit-chg.el (highlight-compare-buffers):
* hippie-exp.el (hippie-expand, try-expand-dabbrev-visible):
* hl-line.el (global-hl-line-highlight):
* icomplete.el (icomplete-simple-completing-p):
* isearch.el (isearch-done):
* jit-lock.el (jit-lock-stealth-fontify):
* mail/rmailsum.el (rmail-summary-scroll-msg-up):
* lisp/mouse-drag.el (mouse-drag-should-do-col-scrolling):
* mpc.el (mpc-tagbrowser, mpc):
* net/rcirc.el (rcirc-any-buffer):
* play/gomoku.el (gomoku-max-width, gomoku-max-height):
* play/landmark.el (landmark-max-width, landmark-max-height):
* play/zone.el (zone):
* progmodes/compile.el (compilation-goto-locus):
* progmodes/ebrowse.el (ebrowse-view/find-file-and-search-pattern):
* progmodes/etags.el (find-tag-other-window):
* progmodes/fortran.el (fortran-column-ruler):
* progmodes/gdb-mi.el (gdb-mouse-toggle-breakpoint-fringe):
* progmodes/verilog-mode.el (verilog-point-text):
* reposition.el (reposition-window):
* rot13.el (toggle-rot13-mode):
* server.el (server-switch-buffer):
* shell.el (shell-dynamic-complete-command)
(shell-dynamic-complete-environment-variable):
* simple.el (insert-buffer, set-selective-display)
(delete-completion-window):
* speedbar.el (speedbar-timer-fn, speedbar-center-buffer-smartly)
(speedbar-recenter):
* startup.el (fancy-splash-head):
* textmodes/ispell.el (ispell-command-loop):
* textmodes/makeinfo.el (makeinfo-compilation-sentinel-region):
* tutorial.el (help-with-tutorial):
* vc/add-log.el (add-change-log-entry):
* vc/compare-w.el (compare-windows):
* vc/ediff-help.el (ediff-indent-help-message):
* vc/ediff-util.el (ediff-setup-control-buffer, ediff-position-region):
* vc/ediff-wind.el (ediff-skip-unsuitable-frames)
(ediff-setup-control-frame):
* vc/emerge.el (emerge-position-region):
* vc/pcvs-util.el (cvs-bury-buffer):
* window.el (walk-windows, mouse-autoselect-window-select):
* winner.el (winner-set-conf, winner-undo): Related users changed.
2013-08-05 14:26:57 +00:00
|
|
|
|
(window-width (window-width)))
|
2013-03-14 15:24:04 +00:00
|
|
|
|
(setf (doc-view-current-image) image)
|
|
|
|
|
(move-overlay ol (point-min) (point-max))
|
|
|
|
|
;; In case the window is wider than the image, center the image
|
|
|
|
|
;; horizontally.
|
|
|
|
|
(overlay-put ol 'before-string
|
|
|
|
|
(when (and image (> window-width displayed-img-width))
|
|
|
|
|
(propertize " " 'display
|
|
|
|
|
`(space :align-to (+ center (-0.5 . ,displayed-img-width))))))
|
|
|
|
|
(overlay-put ol 'display
|
|
|
|
|
(cond
|
|
|
|
|
(image
|
|
|
|
|
(if slice
|
|
|
|
|
(list (cons 'slice slice) image)
|
|
|
|
|
image))
|
|
|
|
|
;; We're trying to display a page that doesn't exist.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-converter-processes
|
2013-03-14 15:24:04 +00:00
|
|
|
|
;; Maybe the page doesn't exist *yet*.
|
|
|
|
|
"Cannot display this page (yet)!")
|
|
|
|
|
(t
|
|
|
|
|
;; Typically happens if the conversion process somehow
|
|
|
|
|
;; failed. Better not signal an error here because it
|
|
|
|
|
;; could prevent a subsequent reconversion from fixing
|
|
|
|
|
;; the problem.
|
|
|
|
|
(concat "Cannot display this page!\n"
|
|
|
|
|
"Maybe because of a conversion failure!"))))
|
|
|
|
|
(let ((win (overlay-get ol 'window)))
|
|
|
|
|
(if (stringp (overlay-get ol 'display))
|
|
|
|
|
(progn ;Make sure the text is not scrolled out of view.
|
|
|
|
|
(set-window-hscroll win 0)
|
|
|
|
|
(set-window-vscroll win 0))
|
|
|
|
|
(let ((hscroll (image-mode-window-get 'hscroll win))
|
|
|
|
|
(vscroll (image-mode-window-get 'vscroll win)))
|
|
|
|
|
;; Reset scroll settings, in case they were changed.
|
|
|
|
|
(if hscroll (set-window-hscroll win hscroll))
|
2019-10-25 20:07:39 +00:00
|
|
|
|
(if vscroll (set-window-vscroll win vscroll t)))))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-sort (a b)
|
|
|
|
|
"Return non-nil if A should be sorted before B.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
Predicate for sorting `doc-view--current-files'."
|
2007-10-30 17:45:41 +00:00
|
|
|
|
(or (< (length a) (length b))
|
|
|
|
|
(and (= (length a) (length b))
|
|
|
|
|
(string< a b))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-02-12 02:41:55 +00:00
|
|
|
|
(defun doc-view-display (buffer &optional force)
|
|
|
|
|
"Start viewing the document in BUFFER.
|
2007-12-06 15:04:29 +00:00
|
|
|
|
If FORCE is non-nil, start viewing even if the document does not
|
|
|
|
|
have the page we want to view."
|
2008-02-12 02:41:55 +00:00
|
|
|
|
(with-current-buffer buffer
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(let ((prev-pages doc-view--current-files))
|
|
|
|
|
(setq doc-view--current-files
|
|
|
|
|
(sort (directory-files (doc-view--current-cache-dir) t
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(format doc-view--image-file-pattern
|
|
|
|
|
"[0-9]+")
|
2013-01-09 21:24:42 +00:00
|
|
|
|
t)
|
2008-02-25 20:04:59 +00:00
|
|
|
|
'doc-view-sort))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(unless (eq (length prev-pages) (length doc-view--current-files))
|
2013-01-24 03:34:20 +00:00
|
|
|
|
(force-mode-line-update))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(dolist (win (or (get-buffer-window-list buffer nil t)
|
|
|
|
|
(list t)))
|
2008-04-28 23:49:02 +00:00
|
|
|
|
(let* ((page (doc-view-current-page win))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(pagefile (expand-file-name
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(format doc-view--image-file-pattern page)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir))))
|
2008-04-28 23:49:02 +00:00
|
|
|
|
(when (or force
|
|
|
|
|
(and (not (member pagefile prev-pages))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(member pagefile doc-view--current-files)))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(if (windowp win)
|
|
|
|
|
(with-selected-window win
|
|
|
|
|
(cl-assert (eq (current-buffer) buffer) t)
|
|
|
|
|
(doc-view-goto-page page))
|
2012-09-19 17:35:18 +00:00
|
|
|
|
(doc-view-goto-page page))))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-buffer-message ()
|
2007-10-30 21:53:05 +00:00
|
|
|
|
;; Only show this message initially, not when refreshing the buffer (in which
|
|
|
|
|
;; case it's better to keep displaying the "stale" page while computing
|
|
|
|
|
;; the fresh new ones).
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(unless (overlay-get (doc-view-current-overlay) 'display)
|
|
|
|
|
(overlay-put (doc-view-current-overlay) 'display
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(concat (propertize "Welcome to DocView!" 'face 'bold)
|
|
|
|
|
"\n"
|
2021-03-08 09:56:51 +00:00
|
|
|
|
(substitute-command-keys "
|
2007-10-31 03:10:32 +00:00
|
|
|
|
If you see this buffer it means that the document you want to view is being
|
2007-10-30 17:45:41 +00:00
|
|
|
|
converted to PNG and the conversion of the first page hasn't finished yet or
|
2007-09-09 22:29:16 +00:00
|
|
|
|
`doc-view-conversion-refresh-interval' is set to nil.
|
|
|
|
|
|
|
|
|
|
For now these keys are useful:
|
2021-03-08 09:56:51 +00:00
|
|
|
|
\\<doc-view-mode-map>
|
|
|
|
|
\\[quit-window] : Bury this buffer. Conversion will go on in background.
|
|
|
|
|
\\[image-kill-buffer] : Kill the conversion process and this buffer.
|
|
|
|
|
\\[doc-view-kill-proc] : Kill the conversion process.\n")))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2022-05-14 13:19:12 +00:00
|
|
|
|
(declare-function tooltip-show "tooltip" (text &optional use-echo-area
|
|
|
|
|
text-face default-face))
|
2008-06-12 03:56:20 +00:00
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-show-tooltip ()
|
|
|
|
|
(interactive)
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(tooltip-show (doc-view-current-info)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2019-03-09 21:05:38 +00:00
|
|
|
|
;; We define an own major mode for DocView's text display so that we
|
|
|
|
|
;; can easily distinguish when we want to toggle back because
|
|
|
|
|
;; text-mode is a likely candidate for a default major-mode
|
|
|
|
|
;; (bug#34451).
|
2019-03-13 22:22:57 +00:00
|
|
|
|
(define-derived-mode doc-view--text-view-mode text-mode "DV/Text"
|
2019-03-09 21:05:38 +00:00
|
|
|
|
"View mode used in DocView's text buffers."
|
2019-03-13 22:22:57 +00:00
|
|
|
|
(view-mode))
|
2019-03-09 21:05:38 +00:00
|
|
|
|
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(defun doc-view-open-text ()
|
2014-10-22 13:30:16 +00:00
|
|
|
|
"Display the current doc's contents as text."
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(interactive)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(if doc-view--current-converter-processes
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(message "DocView: please wait till conversion finished.")
|
2019-10-03 14:54:44 +00:00
|
|
|
|
(let ((txt (expand-file-name "doc.txt" (doc-view--current-cache-dir)))
|
|
|
|
|
(page (doc-view-current-page)))
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(if (file-readable-p txt)
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(let ((inhibit-read-only t)
|
|
|
|
|
(buffer-undo-list t)
|
|
|
|
|
(dv-bfn doc-view--buffer-file-name))
|
|
|
|
|
(erase-buffer)
|
2019-03-13 22:22:57 +00:00
|
|
|
|
;; FIXME: Replacing the buffer's PDF content with its txt rendering
|
|
|
|
|
;; is pretty risky. We should probably use *another*
|
|
|
|
|
;; buffer instead, so there's much less risk of
|
|
|
|
|
;; overwriting the PDF file with some text rendering.
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(set-buffer-multibyte t)
|
|
|
|
|
(insert-file-contents txt)
|
2019-03-09 21:05:38 +00:00
|
|
|
|
(doc-view--text-view-mode)
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(setq-local doc-view--buffer-file-name dv-bfn)
|
|
|
|
|
(set-buffer-modified-p nil)
|
|
|
|
|
(doc-view-minor-mode)
|
2019-10-03 14:54:44 +00:00
|
|
|
|
(goto-char (point-min))
|
2019-10-03 14:57:03 +00:00
|
|
|
|
;; Put point at the start of the page the user was
|
2019-10-03 14:54:44 +00:00
|
|
|
|
;; reading. Pages are separated by Control-L characters.
|
|
|
|
|
(re-search-forward page-delimiter nil t (1- page))
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(add-hook 'write-file-functions
|
|
|
|
|
(lambda ()
|
2019-03-13 22:22:57 +00:00
|
|
|
|
;; FIXME: If the user changes major mode and then
|
|
|
|
|
;; saves the buffer, the PDF file will be clobbered
|
|
|
|
|
;; with its txt rendering!
|
2019-03-09 21:05:38 +00:00
|
|
|
|
(when (eq major-mode 'doc-view--text-view-mode)
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(error "Cannot save text contents of document %s"
|
|
|
|
|
buffer-file-name)))
|
|
|
|
|
nil t))
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(doc-view-doc->txt txt 'doc-view-open-text)))))
|
2008-03-12 12:05:30 +00:00
|
|
|
|
|
2007-10-30 06:29:51 +00:00
|
|
|
|
;;;;; Toggle between editing and viewing
|
2007-10-17 21:34:19 +00:00
|
|
|
|
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(defvar-local doc-view-saved-settings nil
|
|
|
|
|
"Doc-view settings saved while in some other mode.")
|
|
|
|
|
(put 'doc-view-saved-settings 'permanent-local t)
|
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(defun doc-view-toggle-display ()
|
2007-10-30 06:29:51 +00:00
|
|
|
|
"Toggle between editing a document as text or viewing it."
|
2007-10-17 21:34:19 +00:00
|
|
|
|
(interactive)
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(cond
|
|
|
|
|
((eq major-mode 'doc-view-mode)
|
|
|
|
|
;; Switch to editing mode
|
|
|
|
|
(doc-view-kill-proc)
|
|
|
|
|
(setq buffer-read-only nil)
|
|
|
|
|
;; Switch to the previously used major mode or fall back to
|
|
|
|
|
;; normal mode.
|
|
|
|
|
(doc-view-fallback-mode)
|
|
|
|
|
(doc-view-minor-mode 1))
|
2019-03-09 21:05:38 +00:00
|
|
|
|
((eq major-mode 'doc-view--text-view-mode)
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(let ((buffer-undo-list t))
|
|
|
|
|
;; We're currently viewing the document's text contents, so switch
|
|
|
|
|
;; back to .
|
|
|
|
|
(setq buffer-read-only nil)
|
|
|
|
|
(insert-file-contents doc-view--buffer-file-name nil nil nil t)
|
|
|
|
|
(doc-view-fallback-mode)
|
|
|
|
|
(doc-view-minor-mode 1)
|
|
|
|
|
(set-buffer-modified-p nil)))
|
|
|
|
|
(t
|
2007-10-30 06:29:51 +00:00
|
|
|
|
;; Switch to doc-view-mode
|
|
|
|
|
(when (and (buffer-modified-p)
|
|
|
|
|
(y-or-n-p "The buffer has been modified. Save the changes? "))
|
|
|
|
|
(save-buffer))
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(doc-view-mode))))
|
2007-10-17 21:34:19 +00:00
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;;; Searching
|
|
|
|
|
|
2008-03-12 12:05:30 +00:00
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(defun doc-view-search-internal (regexp file)
|
|
|
|
|
"Return a list of FILE's pages that contain text matching REGEXP.
|
2007-10-03 23:28:19 +00:00
|
|
|
|
The value is an alist of the form (PAGE CONTEXTS) where PAGE is
|
|
|
|
|
the pagenumber and CONTEXTS are all lines of text containing a match."
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(insert-file-contents file)
|
|
|
|
|
(let ((page 1)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(lastpage 1)
|
|
|
|
|
matches)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(while (re-search-forward (concat "\\(?:\\([]\\)\\|\\("
|
2007-10-03 23:28:19 +00:00
|
|
|
|
regexp "\\)\\)") nil t)
|
2008-01-04 03:12:17 +00:00
|
|
|
|
(when (match-string 1) (setq page (1+ page)))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(when (match-string 2)
|
|
|
|
|
(if (/= page lastpage)
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(push (cons page
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(list (buffer-substring
|
|
|
|
|
(line-beginning-position)
|
|
|
|
|
(line-end-position))))
|
|
|
|
|
matches)
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(setq matches (cons
|
|
|
|
|
(append
|
|
|
|
|
(or
|
|
|
|
|
;; This page already is a match.
|
|
|
|
|
(car matches)
|
|
|
|
|
;; This is the first match on page.
|
|
|
|
|
(list page))
|
|
|
|
|
(list (buffer-substring
|
|
|
|
|
(line-beginning-position)
|
|
|
|
|
(line-end-position))))
|
|
|
|
|
(cdr matches))))
|
|
|
|
|
(setq lastpage page)))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(nreverse matches))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-search-no-of-matches (list)
|
|
|
|
|
"Extract the number of matches from the search result LIST."
|
|
|
|
|
(let ((no 0))
|
|
|
|
|
(dolist (p list)
|
|
|
|
|
(setq no (+ no (1- (length p)))))
|
|
|
|
|
no))
|
|
|
|
|
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(defun doc-view-search-backward (new-query)
|
|
|
|
|
"Call `doc-view-search' for backward search.
|
|
|
|
|
If prefix NEW-QUERY is given, ask for a new regexp."
|
|
|
|
|
(interactive "P")
|
2007-11-16 18:00:39 +00:00
|
|
|
|
(doc-view-search new-query t))
|
2007-11-10 21:53:47 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-search (new-query &optional backward)
|
|
|
|
|
"Jump to the next match or initiate a new search if NEW-QUERY is given.
|
2007-09-09 22:29:16 +00:00
|
|
|
|
If the current document hasn't been transformed to plain text
|
2007-11-10 21:53:47 +00:00
|
|
|
|
till now do that first.
|
|
|
|
|
If BACKWARD is non-nil, jump to the previous match."
|
|
|
|
|
(interactive "P")
|
2007-11-16 18:00:39 +00:00
|
|
|
|
(if (and (not new-query)
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches)
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(if backward
|
|
|
|
|
(doc-view-search-previous-match 1)
|
|
|
|
|
(doc-view-search-next-match 1))
|
|
|
|
|
;; New search, so forget the old results.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--current-search-matches nil)
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(let ((txt (expand-file-name "doc.txt"
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir))))
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(if (file-readable-p txt)
|
|
|
|
|
(progn
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq doc-view--current-search-matches
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(doc-view-search-internal
|
|
|
|
|
(read-from-minibuffer "Regexp: ")
|
|
|
|
|
txt))
|
|
|
|
|
(message "DocView: search yielded %d matches."
|
|
|
|
|
(doc-view-search-no-of-matches
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches)))
|
2007-11-10 21:53:47 +00:00
|
|
|
|
;; We must convert to TXT first!
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(if doc-view--current-converter-processes
|
2007-11-10 21:53:47 +00:00
|
|
|
|
(message "DocView: please wait till conversion finished.")
|
2008-03-12 15:26:49 +00:00
|
|
|
|
(doc-view-doc->txt txt (lambda () (doc-view-search nil))))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-search-next-match (arg)
|
|
|
|
|
"Go to the ARGth next matching page."
|
|
|
|
|
(interactive "p")
|
2013-07-12 03:54:57 +00:00
|
|
|
|
(let* ((next-pages (cl-remove-if
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(lambda (i) (<= (car i) (doc-view-current-page)))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(page (car (nth (1- arg) next-pages))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(if page
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(doc-view-goto-page page)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(when (and
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(y-or-n-p "No more matches after current page. Wrap to first match? "))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-goto-page (caar doc-view--current-search-matches))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-search-previous-match (arg)
|
|
|
|
|
"Go to the ARGth previous matching page."
|
|
|
|
|
(interactive "p")
|
2013-07-12 03:54:57 +00:00
|
|
|
|
(let* ((prev-pages (cl-remove-if
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(lambda (i) (>= (car i) (doc-view-current-page)))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches))
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(page (car (nth (1- arg) (nreverse prev-pages)))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(if page
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(doc-view-goto-page page)
|
2007-09-09 22:29:16 +00:00
|
|
|
|
(when (and
|
2013-05-27 01:08:43 +00:00
|
|
|
|
doc-view--current-search-matches
|
2007-10-03 23:28:19 +00:00
|
|
|
|
(y-or-n-p "No more matches before current page. Wrap to last match? "))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view-goto-page (caar (last doc-view--current-search-matches)))))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;;;; User interface commands and the mode
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2010-02-05 22:36:20 +00:00
|
|
|
|
(put 'doc-view-mode 'mode-class 'special)
|
2007-10-30 21:53:05 +00:00
|
|
|
|
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(defun doc-view-already-converted-p ()
|
|
|
|
|
"Return non-nil if the current doc was already converted."
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(and (file-exists-p (doc-view--current-cache-dir))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
;; Check that the resolution info is there, otherwise it means
|
|
|
|
|
;; the conversion is incomplete.
|
|
|
|
|
(file-readable-p (expand-file-name "resolution.el"
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir)))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(> (length (directory-files
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(doc-view--current-cache-dir)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
nil (format doc-view--image-file-pattern "[0-9]+")))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
0)))
|
2008-03-12 12:05:30 +00:00
|
|
|
|
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(defun doc-view-initiate-display ()
|
2013-01-09 21:24:42 +00:00
|
|
|
|
;; Switch to image display if possible.
|
2008-03-18 17:43:26 +00:00
|
|
|
|
(if (doc-view-mode-p doc-view-doc-type)
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(progn
|
|
|
|
|
(doc-view-buffer-message)
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(setf (doc-view-current-page) (or (doc-view-current-page) 1))
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(if (doc-view-already-converted-p)
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(progn
|
|
|
|
|
(message "DocView: using cached files!")
|
2013-01-10 05:05:24 +00:00
|
|
|
|
;; Load the saved resolution.
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(let* ((res-file
|
|
|
|
|
(expand-file-name "resolution.el"
|
|
|
|
|
(doc-view--current-cache-dir)))
|
2010-02-05 01:53:40 +00:00
|
|
|
|
(res
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(when (file-readable-p res-file)
|
|
|
|
|
(insert-file-contents res-file)
|
|
|
|
|
(read (current-buffer))))))
|
|
|
|
|
(when (numberp res)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local doc-view-resolution res)))
|
2008-02-12 02:41:55 +00:00
|
|
|
|
(doc-view-display (current-buffer) 'force))
|
2007-10-30 21:53:05 +00:00
|
|
|
|
(doc-view-convert-current-doc))
|
|
|
|
|
(message
|
|
|
|
|
"%s"
|
|
|
|
|
(substitute-command-keys
|
|
|
|
|
(concat "Type \\[doc-view-toggle-display] to toggle between "
|
|
|
|
|
"editing or viewing the document."))))
|
2019-09-30 15:39:38 +00:00
|
|
|
|
(if (image-type-available-p 'png)
|
|
|
|
|
(message "Conversion utility \"%s\" not available for %s"
|
|
|
|
|
doc-view-ghostscript-program
|
|
|
|
|
(file-name-extension doc-view--buffer-file-name))
|
|
|
|
|
(message "PNG support not available; can't view document"))
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(if (and (executable-find doc-view-pdftotext-program)
|
|
|
|
|
(y-or-n-p
|
|
|
|
|
"Unable to render file. View extracted text instead? "))
|
|
|
|
|
(doc-view-open-text)
|
|
|
|
|
(doc-view-toggle-display))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2008-03-07 05:44:37 +00:00
|
|
|
|
(defvar bookmark-make-record-function)
|
2008-01-04 03:12:17 +00:00
|
|
|
|
|
2008-02-12 02:41:55 +00:00
|
|
|
|
(defun doc-view-clone-buffer-hook ()
|
|
|
|
|
;; FIXME: There are several potential problems linked with reconversion
|
|
|
|
|
;; and auto-revert when we have indirect buffers because they share their
|
|
|
|
|
;; /tmp cache directory. This sharing is good (you'd rather not reconvert
|
|
|
|
|
;; for each clone), but that means that clones need to collaborate a bit.
|
|
|
|
|
;; I guess it mostly means: detect when a reconversion process is already
|
|
|
|
|
;; running, and run the sentinel in all clones.
|
2008-03-12 12:05:30 +00:00
|
|
|
|
;;
|
2008-02-21 03:45:04 +00:00
|
|
|
|
;; Maybe the clones should really have a separate /tmp directory
|
2008-02-12 02:41:55 +00:00
|
|
|
|
;; so they could have a different resolution and you could use clones
|
|
|
|
|
;; for zooming.
|
2008-02-21 03:45:04 +00:00
|
|
|
|
(remove-overlays (point-min) (point-max) 'doc-view t)
|
|
|
|
|
(if (consp image-mode-winprops-alist) (setq image-mode-winprops-alist nil)))
|
2008-02-12 02:41:55 +00:00
|
|
|
|
|
2010-12-30 18:08:18 +00:00
|
|
|
|
(defun doc-view-set-doc-type ()
|
|
|
|
|
"Figure out the current document type (`doc-view-doc-type')."
|
|
|
|
|
(let ((name-types
|
|
|
|
|
(when buffer-file-name
|
2014-10-22 13:30:16 +00:00
|
|
|
|
(cdr (assoc-string
|
2014-04-14 21:01:37 +00:00
|
|
|
|
(file-name-extension buffer-file-name)
|
|
|
|
|
'(
|
|
|
|
|
;; DVI
|
|
|
|
|
("dvi" dvi)
|
|
|
|
|
;; PDF
|
|
|
|
|
("pdf" pdf) ("epdf" pdf)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
;; EPUB
|
|
|
|
|
("epub" epub)
|
2014-04-14 21:01:37 +00:00
|
|
|
|
;; PostScript
|
|
|
|
|
("ps" ps) ("eps" ps)
|
|
|
|
|
;; DjVu
|
|
|
|
|
("djvu" djvu)
|
|
|
|
|
;; OpenDocument formats.
|
|
|
|
|
("odt" odf) ("ods" odf) ("odp" odf) ("odg" odf)
|
|
|
|
|
("odc" odf) ("odi" odf) ("odm" odf) ("ott" odf)
|
|
|
|
|
("ots" odf) ("otp" odf) ("otg" odf)
|
|
|
|
|
;; Microsoft Office formats (also handled by the odf
|
|
|
|
|
;; conversion chain).
|
|
|
|
|
("doc" odf) ("docx" odf) ("xls" odf) ("xlsx" odf)
|
2022-01-27 16:03:38 +00:00
|
|
|
|
("ppt" odf) ("pps" odf) ("pptx" odf) ("rtf" odf)
|
|
|
|
|
;; CBZ
|
|
|
|
|
("cbz" cbz)
|
|
|
|
|
;; FB2
|
|
|
|
|
("fb2" fb2)
|
|
|
|
|
;; (Open)XPS
|
|
|
|
|
("xps" xps) ("oxps" oxps))
|
2014-10-22 13:30:16 +00:00
|
|
|
|
t))))
|
2010-12-30 18:08:18 +00:00
|
|
|
|
(content-types
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(cond
|
|
|
|
|
((looking-at "%!") '(ps))
|
|
|
|
|
((looking-at "%PDF") '(pdf))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
((looking-at "\367\002") '(dvi))
|
2022-01-27 16:03:38 +00:00
|
|
|
|
((looking-at "AT&TFORM") '(djvu))
|
|
|
|
|
;; The following pattern actually is for recognizing
|
|
|
|
|
;; zip-archives, so that this same association is used for
|
|
|
|
|
;; cbz files. This is fine, as cbz files should be handled
|
|
|
|
|
;; like epub anyway.
|
2022-04-16 09:21:25 +00:00
|
|
|
|
((looking-at "PK") '(epub odf))))))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq-local
|
|
|
|
|
doc-view-doc-type
|
2021-04-04 23:13:54 +00:00
|
|
|
|
(car (or (nreverse (seq-intersection name-types content-types #'eq))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(when (and name-types content-types)
|
|
|
|
|
(error "Conflicting types: name says %s but content says %s"
|
|
|
|
|
name-types content-types))
|
|
|
|
|
name-types content-types
|
|
|
|
|
(error "Cannot determine the document type"))))))
|
2010-12-30 18:08:18 +00:00
|
|
|
|
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(defun doc-view-set-up-single-converter ()
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-20 22:27:53 +00:00
|
|
|
|
"Find the right single-page converter for the current document type."
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(pcase-let ((`(,conv-function ,type ,extension)
|
|
|
|
|
(pcase doc-view-doc-type
|
2018-11-05 00:22:15 +00:00
|
|
|
|
('djvu (list #'doc-view-djvu->tiff-converter-ddjvu 'tiff "tif"))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(_ (list doc-view-pdf->png-converter-function 'png "png")))))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(setq-local doc-view-single-page-converter-function conv-function)
|
|
|
|
|
(setq-local doc-view--image-type type)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local doc-view--image-file-pattern (concat "page-%s." extension))))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
|
2013-05-24 10:54:20 +00:00
|
|
|
|
;; desktop.el integration
|
|
|
|
|
|
2013-05-24 17:42:23 +00:00
|
|
|
|
(defun doc-view-desktop-save-buffer (_desktop-dirname)
|
2015-02-05 15:26:57 +00:00
|
|
|
|
;; FIXME: This is wrong, since this info is per-window but we only do it once
|
|
|
|
|
;; here for the buffer. IOW it should be saved via something like
|
|
|
|
|
;; `window-persistent-parameters'.
|
2013-05-24 10:54:20 +00:00
|
|
|
|
`((page . ,(doc-view-current-page))
|
|
|
|
|
(slice . ,(doc-view-current-slice))))
|
|
|
|
|
|
2013-05-24 17:42:23 +00:00
|
|
|
|
(declare-function desktop-restore-file-buffer "desktop"
|
|
|
|
|
(buffer-filename buffer-name buffer-misc))
|
|
|
|
|
|
2013-05-24 10:54:20 +00:00
|
|
|
|
(defun doc-view-restore-desktop-buffer (file name misc)
|
|
|
|
|
(let ((page (cdr (assq 'page misc)))
|
|
|
|
|
(slice (cdr (assq 'slice misc))))
|
2013-05-24 17:42:23 +00:00
|
|
|
|
(desktop-restore-file-buffer file name misc)
|
2015-02-05 15:26:57 +00:00
|
|
|
|
;; FIXME: We need to run this code after displaying the buffer.
|
2013-05-24 10:54:20 +00:00
|
|
|
|
(with-selected-window (or (get-buffer-window (current-buffer) 0)
|
|
|
|
|
(selected-window))
|
2015-02-05 15:26:57 +00:00
|
|
|
|
;; FIXME: This should be done for all windows restored that show
|
|
|
|
|
;; this buffer. Basically, the page/slice should be saved as
|
|
|
|
|
;; window-parameters in the window-state(s) and then restoring this
|
|
|
|
|
;; window-state should call us back (to interpret/use those parameters).
|
2013-05-24 10:54:20 +00:00
|
|
|
|
(doc-view-goto-page page)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(when slice (apply #'doc-view-set-slice slice))
|
2016-01-21 10:19:21 +00:00
|
|
|
|
(current-buffer))))
|
2013-05-24 10:54:20 +00:00
|
|
|
|
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(add-to-list 'desktop-buffer-mode-handlers
|
|
|
|
|
'(doc-view-mode . doc-view-restore-desktop-buffer))
|
2013-05-24 10:54:20 +00:00
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
;;;###autoload
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(defun doc-view-mode ()
|
2007-10-17 21:34:19 +00:00
|
|
|
|
"Major mode in DocView buffers.
|
2009-01-27 15:52:17 +00:00
|
|
|
|
|
|
|
|
|
DocView Mode is an Emacs document viewer. It displays PDF, PS
|
|
|
|
|
and DVI files (as PNG images) in Emacs buffers.
|
|
|
|
|
|
2007-10-17 21:34:19 +00:00
|
|
|
|
You can use \\<doc-view-mode-map>\\[doc-view-toggle-display] to
|
2008-02-01 03:00:55 +00:00
|
|
|
|
toggle between displaying the document or editing it as text.
|
|
|
|
|
\\{doc-view-mode-map}"
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(interactive)
|
2008-01-09 20:16:14 +00:00
|
|
|
|
|
2009-04-02 21:12:54 +00:00
|
|
|
|
(if (= (point-min) (point-max))
|
2009-01-28 20:33:44 +00:00
|
|
|
|
;; The doc is empty or doesn't exist at all, so fallback to
|
2009-04-02 21:12:54 +00:00
|
|
|
|
;; another mode. We used to also check file-exists-p, but this
|
|
|
|
|
;; returns nil for tar members.
|
2010-12-30 18:08:18 +00:00
|
|
|
|
(doc-view-fallback-mode)
|
2009-01-27 15:52:17 +00:00
|
|
|
|
|
2018-06-22 03:30:11 +00:00
|
|
|
|
(major-mode-suspend)
|
2012-09-27 03:16:35 +00:00
|
|
|
|
|
|
|
|
|
(dolist (var doc-view-saved-settings)
|
|
|
|
|
(set (make-local-variable (car var)) (cdr var)))
|
2009-02-09 15:33:47 +00:00
|
|
|
|
|
2009-01-27 15:52:17 +00:00
|
|
|
|
;; Figure out the document type.
|
2010-12-30 18:08:18 +00:00
|
|
|
|
(unless doc-view-doc-type
|
|
|
|
|
(doc-view-set-doc-type))
|
2013-01-09 21:24:42 +00:00
|
|
|
|
(doc-view-set-up-single-converter)
|
2017-02-02 15:57:37 +00:00
|
|
|
|
(unless (memq doc-view-doc-type '(ps))
|
|
|
|
|
(setq-local require-final-newline nil))
|
2009-02-09 15:33:47 +00:00
|
|
|
|
|
2021-05-02 09:28:30 +00:00
|
|
|
|
;; These modes will just display "1", so they're not very useful
|
|
|
|
|
;; in this mode.
|
|
|
|
|
(setq-local global-linum-mode nil
|
|
|
|
|
display-line-numbers-mode nil)
|
|
|
|
|
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(doc-view-make-safe-dir doc-view-cache-directory)
|
|
|
|
|
;; Handle compressed files, remote files, files inside archives
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(setq-local doc-view--buffer-file-name
|
2018-10-10 10:45:57 +00:00
|
|
|
|
(convert-standard-filename
|
|
|
|
|
(cond
|
|
|
|
|
(jka-compr-really-do-compress
|
|
|
|
|
;; FIXME: there's a risk of name conflicts here.
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(file-name-nondirectory
|
|
|
|
|
(file-name-sans-extension buffer-file-name))
|
|
|
|
|
doc-view-cache-directory))
|
|
|
|
|
;; Is the file readable by local processes?
|
|
|
|
|
;; We used to use `file-remote-p' but it's unclear what it's
|
|
|
|
|
;; supposed to return nil for things like local files accessed
|
|
|
|
|
;; via `su' or via file://...
|
|
|
|
|
((let ((file-name-handler-alist nil))
|
|
|
|
|
(not (and buffer-file-name
|
|
|
|
|
(file-readable-p buffer-file-name))))
|
|
|
|
|
;; FIXME: there's a risk of name conflicts here.
|
|
|
|
|
(expand-file-name
|
|
|
|
|
(if buffer-file-name
|
|
|
|
|
(file-name-nondirectory buffer-file-name)
|
|
|
|
|
(buffer-name))
|
|
|
|
|
doc-view-cache-directory))
|
|
|
|
|
(t buffer-file-name))))
|
2013-05-27 01:08:43 +00:00
|
|
|
|
(when (not (string= doc-view--buffer-file-name buffer-file-name))
|
|
|
|
|
(write-region nil nil doc-view--buffer-file-name))
|
2009-02-09 15:33:47 +00:00
|
|
|
|
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(add-function :around (local 'revert-buffer-function) #'doc-view--revert-buffer)
|
2015-10-22 15:01:57 +00:00
|
|
|
|
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(add-hook 'change-major-mode-hook
|
|
|
|
|
(lambda ()
|
|
|
|
|
(doc-view-kill-proc)
|
|
|
|
|
(remove-overlays (point-min) (point-max) 'doc-view t))
|
|
|
|
|
nil t)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(add-hook 'clone-indirect-buffer-hook #'doc-view-clone-buffer-hook nil t)
|
|
|
|
|
(add-hook 'kill-buffer-hook #'doc-view-kill-proc nil t)
|
|
|
|
|
(setq-local desktop-save-buffer #'doc-view-desktop-save-buffer)
|
2009-02-09 15:33:47 +00:00
|
|
|
|
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(remove-overlays (point-min) (point-max) 'doc-view t) ;Just in case.
|
|
|
|
|
;; Keep track of display info ([vh]scroll, page number, overlay,
|
|
|
|
|
;; ...) for each window in which this document is shown.
|
|
|
|
|
(add-hook 'image-mode-new-window-functions
|
2019-01-23 22:27:21 +00:00
|
|
|
|
#'doc-view-new-window-function nil t)
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(image-mode-setup-winprops)
|
2009-02-09 15:33:47 +00:00
|
|
|
|
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local mode-line-position
|
|
|
|
|
'(" P" (:eval (number-to-string (doc-view-current-page)))
|
|
|
|
|
"/" (:eval (number-to-string (doc-view-last-page-number)))))
|
2009-01-27 15:52:17 +00:00
|
|
|
|
;; Don't scroll unless the user specifically asked for it.
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local auto-hscroll-mode nil)
|
2013-09-18 04:38:49 +00:00
|
|
|
|
(if (boundp 'mwheel-scroll-up-function) ; not --without-x build
|
|
|
|
|
(setq-local mwheel-scroll-up-function
|
|
|
|
|
#'doc-view-scroll-up-or-next-page))
|
|
|
|
|
(if (boundp 'mwheel-scroll-down-function)
|
|
|
|
|
(setq-local mwheel-scroll-down-function
|
|
|
|
|
#'doc-view-scroll-down-or-previous-page))
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local cursor-type nil)
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(use-local-map doc-view-mode-map)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(add-hook 'after-revert-hook #'doc-view-reconvert-doc nil t)
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local bookmark-make-record-function
|
|
|
|
|
#'doc-view-bookmark-make-record)
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(setq mode-name "DocView"
|
|
|
|
|
buffer-read-only t
|
|
|
|
|
major-mode 'doc-view-mode)
|
|
|
|
|
(doc-view-initiate-display)
|
2009-11-24 07:47:45 +00:00
|
|
|
|
;; Switch off view-mode explicitly, because doc-view-mode is the
|
|
|
|
|
;; canonical view mode for PDF/PS/DVI files. This could be
|
|
|
|
|
;; switched on automatically depending on the value of
|
|
|
|
|
;; `view-read-only'.
|
2013-01-10 05:05:24 +00:00
|
|
|
|
(setq-local view-read-only nil)
|
2009-01-27 15:52:17 +00:00
|
|
|
|
(run-mode-hooks 'doc-view-mode-hook)))
|
2007-10-30 06:29:51 +00:00
|
|
|
|
|
2010-12-30 18:08:18 +00:00
|
|
|
|
(defun doc-view-fallback-mode ()
|
|
|
|
|
"Fallback to the previous or next best major mode."
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(let ((vars (if (derived-mode-p 'doc-view-mode)
|
|
|
|
|
(mapcar (lambda (var) (cons var (symbol-value var)))
|
|
|
|
|
'(doc-view-resolution
|
|
|
|
|
image-mode-winprops-alist)))))
|
2013-02-28 04:02:36 +00:00
|
|
|
|
(remove-overlays (point-min) (point-max) 'doc-view t)
|
2018-06-22 03:30:11 +00:00
|
|
|
|
(major-mode-restore '(doc-view-mode-maybe doc-view-mode))
|
2012-09-27 03:16:35 +00:00
|
|
|
|
(when vars
|
|
|
|
|
(setq-local doc-view-saved-settings vars))))
|
2010-12-30 18:08:18 +00:00
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun doc-view-mode-maybe ()
|
|
|
|
|
"Switch to `doc-view-mode' if possible.
|
|
|
|
|
If the required external tools are not available, then fallback
|
|
|
|
|
to the next best mode."
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(doc-view-set-doc-type)
|
|
|
|
|
(error (doc-view-fallback-mode)))
|
|
|
|
|
(if (doc-view-mode-p doc-view-doc-type)
|
|
|
|
|
(doc-view-mode)
|
|
|
|
|
(doc-view-fallback-mode)))
|
|
|
|
|
|
2007-10-30 06:29:51 +00:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(define-minor-mode doc-view-minor-mode
|
Fix minor mode docstrings for the new meaning of a nil ARG.
* abbrev.el (abbrev-mode):
* allout.el (allout-mode):
* autoinsert.el (auto-insert-mode):
* autoarg.el (autoarg-mode, autoarg-kp-mode):
* autorevert.el (auto-revert-mode, auto-revert-tail-mode)
(global-auto-revert-mode):
* battery.el (display-battery-mode):
* composite.el (global-auto-composition-mode)
(auto-composition-mode):
* delsel.el (delete-selection-mode):
* desktop.el (desktop-save-mode):
* dired-x.el (dired-omit-mode):
* dirtrack.el (dirtrack-mode):
* doc-view.el (doc-view-minor-mode):
* double.el (double-mode):
* electric.el (electric-indent-mode, electric-pair-mode):
* emacs-lock.el (emacs-lock-mode):
* epa-hook.el (auto-encryption-mode):
* follow.el (follow-mode):
* font-core.el (font-lock-mode):
* frame.el (auto-raise-mode, auto-lower-mode, blink-cursor-mode):
* help.el (temp-buffer-resize-mode):
* hilit-chg.el (highlight-changes-mode)
(highlight-changes-visible-mode):
* hi-lock.el (hi-lock-mode):
* hl-line.el (hl-line-mode, global-hl-line-mode):
* icomplete.el (icomplete-mode):
* ido.el (ido-everywhere):
* image-file.el (auto-image-file-mode):
* image-mode.el (image-minor-mode):
* iswitchb.el (iswitchb-mode):
* jka-cmpr-hook.el (auto-compression-mode):
* linum.el (linum-mode):
* longlines.el (longlines-mode):
* master.el (master-mode):
* mb-depth.el (minibuffer-depth-indicate-mode):
* menu-bar.el (menu-bar-mode):
* minibuf-eldef.el (minibuffer-electric-default-mode):
* mouse-sel.el (mouse-sel-mode):
* msb.el (msb-mode):
* mwheel.el (mouse-wheel-mode):
* outline.el (outline-minor-mode):
* paren.el (show-paren-mode):
* recentf.el (recentf-mode):
* reveal.el (reveal-mode, global-reveal-mode):
* rfn-eshadow.el (file-name-shadow-mode):
* ruler-mode.el (ruler-mode):
* savehist.el (savehist-mode):
* scroll-all.el (scroll-all-mode):
* scroll-bar.el (scroll-bar-mode):
* server.el (server-mode):
* shell.el (shell-dirtrack-mode):
* simple.el (auto-fill-mode, transient-mark-mode)
(visual-line-mode, overwrite-mode, binary-overwrite-mode)
(line-number-mode, column-number-mode, size-indication-mode)
(auto-save-mode, normal-erase-is-backspace-mode, visible-mode):
* strokes.el (strokes-mode):
* time.el (display-time-mode):
* t-mouse.el (gpm-mouse-mode):
* tool-bar.el (tool-bar-mode):
* tooltip.el (tooltip-mode):
* type-break.el (type-break-mode-line-message-mode)
(type-break-query-mode):
* view.el (view-mode):
* whitespace.el (whitespace-mode, whitespace-newline-mode)
(global-whitespace-mode, global-whitespace-newline-mode):
* xt-mouse.el (xterm-mouse-mode): Doc fix.
* emacs-lisp/easy-mmode.el (define-globalized-minor-mode): Fix
autogenerated docstring.
2011-10-19 12:54:24 +00:00
|
|
|
|
"Toggle displaying buffer via Doc View (Doc View minor mode).
|
|
|
|
|
|
2007-10-30 06:29:51 +00:00
|
|
|
|
See the command `doc-view-mode' for more information on this mode."
|
2019-01-23 22:27:21 +00:00
|
|
|
|
:lighter " DocView"
|
2007-10-30 06:29:51 +00:00
|
|
|
|
(when doc-view-minor-mode
|
|
|
|
|
(add-hook 'change-major-mode-hook (lambda () (doc-view-minor-mode -1)) nil t)
|
|
|
|
|
(message
|
|
|
|
|
"%s"
|
|
|
|
|
(substitute-command-keys
|
|
|
|
|
"Type \\[doc-view-toggle-display] to toggle between editing or viewing the document."))))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-clear-cache ()
|
|
|
|
|
"Delete the whole cache (`doc-view-cache-directory')."
|
|
|
|
|
(interactive)
|
2008-03-12 12:05:30 +00:00
|
|
|
|
(dired-delete-file doc-view-cache-directory 'always))
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
|
|
|
|
(defun doc-view-dired-cache ()
|
|
|
|
|
"Open `dired' in `doc-view-cache-directory'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(dired doc-view-cache-directory))
|
|
|
|
|
|
2019-01-23 22:27:21 +00:00
|
|
|
|
;;;; Presentation mode
|
|
|
|
|
|
|
|
|
|
(defvar doc-view-presentation-mode-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map "\e" 'doc-view-presentation-exit)
|
|
|
|
|
(define-key map "q" 'doc-view-presentation-exit)
|
|
|
|
|
;; (define-key map "C" 'doc-view-convert-all-pages)
|
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(defvar-local doc-view-presentation--src-data nil)
|
|
|
|
|
|
|
|
|
|
(defun doc-view-presentation-exit ()
|
|
|
|
|
"Leave Doc-View's presentation mode."
|
|
|
|
|
(interactive)
|
|
|
|
|
(doc-view-presentation-mode -1))
|
|
|
|
|
|
|
|
|
|
(define-minor-mode doc-view-presentation-mode
|
|
|
|
|
"Minor mode used while in presentation mode."
|
|
|
|
|
:init-value nil :keymap doc-view-presentation-mode-map
|
|
|
|
|
(if doc-view-presentation-mode
|
|
|
|
|
(progn
|
2020-12-09 08:44:38 +00:00
|
|
|
|
(setq-local mode-line-format nil)
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(doc-view-fit-page-to-window)
|
|
|
|
|
;; (doc-view-convert-all-pages)
|
|
|
|
|
)
|
|
|
|
|
(kill-local-variable 'mode-line-format)
|
|
|
|
|
(let ((pn (doc-view-current-page))
|
|
|
|
|
(win (selected-window)))
|
|
|
|
|
(doc-view-presentation--propagate-pn doc-view-presentation--src-data pn)
|
|
|
|
|
(setq doc-view-presentation--src-data nil)
|
|
|
|
|
(with-selected-window win
|
|
|
|
|
(if (and (one-window-p) (window-dedicated-p))
|
|
|
|
|
(delete-frame))))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-presentation--propagate-pn (src-data pn)
|
|
|
|
|
(when src-data
|
|
|
|
|
(let ((win (car src-data)))
|
|
|
|
|
(when (and (window-live-p win)
|
|
|
|
|
(eq (current-buffer) (window-buffer win)))
|
|
|
|
|
(select-window win))
|
|
|
|
|
(when (eq (doc-view-current-page) (cdr src-data))
|
|
|
|
|
(doc-view-goto-page pn)))))
|
|
|
|
|
|
|
|
|
|
(defun doc-view-presentation ()
|
|
|
|
|
"Put Doc-View in presentation mode."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((src-data (cons (selected-window) (doc-view-current-page)))
|
|
|
|
|
(mal (display-monitor-attributes-list))
|
|
|
|
|
(monitor-top 0)
|
|
|
|
|
(monitor-left 0)
|
|
|
|
|
(monitor-height (display-pixel-height))
|
|
|
|
|
(monitor-width (display-pixel-width)))
|
|
|
|
|
(dolist (attrs mal)
|
|
|
|
|
(when (memq (selected-frame) (alist-get 'frames attrs))
|
|
|
|
|
(let ((geom (alist-get 'geometry attrs)))
|
|
|
|
|
(when geom
|
2020-05-23 03:36:57 +00:00
|
|
|
|
(setq monitor-left (nth 0 geom))
|
|
|
|
|
(setq monitor-top (nth 1 geom))
|
2019-01-23 22:27:21 +00:00
|
|
|
|
(setq monitor-width (nth 2 geom))
|
|
|
|
|
(setq monitor-height (nth 3 geom))))))
|
|
|
|
|
(let ((frame (make-frame
|
|
|
|
|
`((minibuffer . nil)
|
|
|
|
|
(fullscreen . fullboth)
|
|
|
|
|
(height . ,(ceiling monitor-height (frame-char-height)))
|
|
|
|
|
;; Don't use `ceiling' here since doc-view will center the
|
|
|
|
|
;; image instead.
|
|
|
|
|
(width . ,(ceiling monitor-width (frame-char-width)))
|
|
|
|
|
(name . "Doc-View-Presentation")
|
|
|
|
|
(top . ,monitor-top) (left . ,monitor-left) (user-position . t)
|
|
|
|
|
(vertical-scroll-bars . nil)
|
|
|
|
|
(left-fringe . 0) (right-fringe . 0)
|
|
|
|
|
(menu-bar-lines . 0)
|
|
|
|
|
(tool-bar-lines . 0)))))
|
|
|
|
|
(select-window (frame-root-window frame))
|
|
|
|
|
(setq doc-view-presentation--src-data src-data)
|
|
|
|
|
(set-window-dedicated-p (selected-window) t)
|
|
|
|
|
(doc-view-presentation-mode 1))))
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
|
2007-12-26 08:53:06 +00:00
|
|
|
|
;;;; Bookmark integration
|
|
|
|
|
|
2010-07-14 15:57:54 +00:00
|
|
|
|
(declare-function bookmark-make-record-default
|
|
|
|
|
"bookmark" (&optional no-file no-context posn))
|
2008-03-09 21:37:16 +00:00
|
|
|
|
(declare-function bookmark-prop-get "bookmark" (bookmark prop))
|
2008-06-25 16:51:33 +00:00
|
|
|
|
(declare-function bookmark-default-handler "bookmark" (bmk))
|
2008-03-09 21:37:16 +00:00
|
|
|
|
|
2008-03-09 03:05:34 +00:00
|
|
|
|
(defun doc-view-bookmark-make-record ()
|
2008-06-25 16:51:33 +00:00
|
|
|
|
(nconc (bookmark-make-record-default)
|
|
|
|
|
`((page . ,(doc-view-current-page))
|
|
|
|
|
(handler . doc-view-bookmark-jump))))
|
2007-12-26 08:53:06 +00:00
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun doc-view-bookmark-jump (bmk)
|
2008-01-02 07:49:04 +00:00
|
|
|
|
;; This implements the `handler' function interface for record type
|
2008-03-07 05:44:37 +00:00
|
|
|
|
;; returned by `doc-view-bookmark-make-record', which see.
|
2014-04-04 17:42:55 +00:00
|
|
|
|
(let ((page (bookmark-prop-get bmk 'page))
|
|
|
|
|
(show-fn-sym (make-symbol "doc-view-bookmark-after-jump-hook")))
|
|
|
|
|
(fset show-fn-sym
|
|
|
|
|
(lambda ()
|
|
|
|
|
(remove-hook 'bookmark-after-jump-hook show-fn-sym)
|
|
|
|
|
(when (not (eq major-mode 'doc-view-mode))
|
|
|
|
|
(doc-view-toggle-display))
|
|
|
|
|
(with-selected-window
|
|
|
|
|
(or (get-buffer-window (current-buffer) 0)
|
|
|
|
|
(selected-window))
|
|
|
|
|
(doc-view-goto-page page))))
|
|
|
|
|
(add-hook 'bookmark-after-jump-hook show-fn-sym)
|
|
|
|
|
(bookmark-default-handler bmk)))
|
2008-01-04 03:12:17 +00:00
|
|
|
|
|
2022-06-17 23:39:12 +00:00
|
|
|
|
(put 'doc-view-bookmark-jump 'bookmark-handler-type "DocView")
|
2022-02-15 22:39:02 +00:00
|
|
|
|
|
2021-04-04 23:13:54 +00:00
|
|
|
|
;; Obsolete.
|
|
|
|
|
|
|
|
|
|
(defun doc-view-intersection (l1 l2)
|
|
|
|
|
(declare (obsolete seq-intersection "28.1"))
|
|
|
|
|
(nreverse (seq-intersection l1 l2 #'eq)))
|
|
|
|
|
|
2008-01-04 03:12:17 +00:00
|
|
|
|
(provide 'doc-view)
|
|
|
|
|
|
|
|
|
|
;; Local Variables:
|
2011-06-09 20:22:06 +00:00
|
|
|
|
;; eval: (outline-minor-mode 1)
|
2008-01-04 03:12:17 +00:00
|
|
|
|
;; End:
|
|
|
|
|
|
2007-09-09 22:29:16 +00:00
|
|
|
|
;;; doc-view.el ends here
|