update packages
This commit is contained in:
@@ -1,381 +1,499 @@
|
||||
#+TITLE: PDF Tools README
|
||||
#+AUTHOR: Andreas Politz
|
||||
#+EMAIL: politza@fh-trier.de
|
||||
#+EMAIL: mail@andreas-politz.de
|
||||
#+Maintainer: Vedang Manerikar
|
||||
#+Maintainer_Email: vedang.manerikar@gmail.com
|
||||
|
||||
[[https://travis-ci.org/politza/pdf-tools.svg?branch%3Dmaster][https://travis-ci.org/politza/pdf-tools.svg?branch=master]]
|
||||
[[http://stable.melpa.org/#/pdf-tools][http://stable.melpa.org/packages/pdf-tools-badge.svg]]
|
||||
[[http://melpa.org/#/pdf-tools][http://melpa.org/packages/pdf-tools-badge.svg]]
|
||||
[[https://app.circleci.com/pipelines/github/vedang/pdf-tools][https://circleci.com/gh/vedang/pdf-tools.svg?style=svg]]
|
||||
[[https://elpa.nongnu.org/nongnu/pdf-tools.html][http://elpa.nongnu.org/nongnu/pdf-tools.svg]]
|
||||
[[https://stable.melpa.org/#/pdf-tools][http://stable.melpa.org/packages/pdf-tools-badge.svg]]
|
||||
[[https://melpa.org/#/pdf-tools][http://melpa.org/packages/pdf-tools-badge.svg]] [[https://ci.appveyor.com/project/vedang/pdf-tools][https://ci.appveyor.com/api/projects/status/yqic2san0wi7o5v8/branch/master?svg=true]]
|
||||
|
||||
The ~pdf-tools~ Wiki is maintained at https://pdftools.wiki. Head to the site if you find it easier to navigate a website for reading a manual. All the topics on the site are listed at https://pdftools.wiki/impulse.
|
||||
|
||||
* About PDF Tools
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 5a884389-6aec-498a-90d5-f37168809b4f
|
||||
:EXPORT_FILE_NAME: index
|
||||
:END:
|
||||
PDF Tools is, among other things, a replacement of DocView for PDF files. The key difference is that pages are not pre-rendered by e.g. ghostscript and stored in the file-system, but rather created on-demand and stored in memory.
|
||||
|
||||
** About this package
|
||||
PDF Tools is, among other things, a replacement of DocView for PDF
|
||||
files. The key difference is that pages are not pre-rendered by
|
||||
e.g. ghostscript and stored in the file-system, but rather created
|
||||
on-demand and stored in memory.
|
||||
This rendering is performed by a special library named, for whatever reason, ~poppler~, running inside a server program. This program is called ~epdfinfo~ and its job is to successively read requests from Emacs and produce the proper results, i.e. the PNG image of a PDF page.
|
||||
|
||||
This rendering is performed by a special library named, for
|
||||
whatever reason, poppler, running inside a server program. This
|
||||
program is called ~epdfinfo~ and its job is to successively
|
||||
read requests from Emacs and produce the proper results, i.e. the
|
||||
PNG image of a PDF page.
|
||||
Actually, displaying PDF files is just one part of ~pdf-tools~. Since ~poppler~ can provide us with all kinds of information about a document and is also able to modify it, there is a lot more we can do with it. [[http://www.dailymotion.com/video/x2bc1is_pdf-tools-tourdeforce_tech?forcedQuality%3Dhd720][Watch this video for a detailed demo!]]
|
||||
|
||||
Actually, displaying PDF files is just one part of PDF Tools.
|
||||
Since poppler can provide us with all kinds of information about a
|
||||
document and is also able to modify it, there is a lot more we can
|
||||
do with it. [[http://www.dailymotion.com/video/x2bc1is_pdf-tools-tourdeforce_tech?forcedQuality%3Dhd720][Watch]]
|
||||
* Installing ~pdf-tools~
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 6ceea50c-cbaa-4d8a-b450-8067c5e8c9da
|
||||
:NEURON_DIRTREE_DISPLAY: false
|
||||
:END:
|
||||
Installing this package via NonGNU ELPA or MELPA or any of the other package managers is straightforward and should just work.
|
||||
~pdf-tools~ requires a server ~epdfinfo~ to run against, which it will try to compile and build when it is activated for the first time.
|
||||
|
||||
Please read also about [[#known-problems][known problems.]]
|
||||
You should not require any manual changes. The documentation below is if you are installing from source, or for troubleshooting / debugging purposes.
|
||||
|
||||
** Features
|
||||
+ View :: View PDF documents in a buffer with DocView-like
|
||||
bindings.
|
||||
+ Isearch :: Interactively search PDF documents like any other
|
||||
buffer, either for a string or a PCRE.
|
||||
+ Occur :: List lines matching a string or regexp in one or more
|
||||
PDF documents.
|
||||
+ Follow ::
|
||||
Click on highlighted links, moving to some part of a different
|
||||
page, some external file, a website or any other URI. Links may
|
||||
also be followed by keyboard commands.
|
||||
+ Annotations :: Display and list text and markup annotations (like
|
||||
underline), edit their contents and attributes
|
||||
(e.g. color), move them around, delete them or
|
||||
create new ones and then save the modifications
|
||||
back to the PDF file.
|
||||
+ Attachments :: Save files attached to the PDF-file or list them
|
||||
in a dired buffer.
|
||||
+ Outline :: Use imenu or a special buffer to examine and navigate
|
||||
the PDF's outline.
|
||||
+ SyncTeX :: Jump from a position on a page directly to the TeX
|
||||
source and vice versa.
|
||||
+ Virtual ::
|
||||
Use a collection of documents as if it were one, big single PDF.
|
||||
- [[brain-child:8ce3cf4e-d186-4de1-a40e-f41063068ab0][Installing ~epdfinfo~ server prerequisites]]
|
||||
- [[brain-child:e305cd0a-e798-4c2b-af27-21bcd936c1c9][Compiling and Installing the ~epdfinfo~ server]]
|
||||
- [[brain-child:3d4e6b6b-f015-475d-8ea2-84988efd6c22][Installing ~pdf-tools~ elisp prerequisites]]
|
||||
- [[brain-child:32c4fc3b-b4ea-43bd-b92c-bdf2d3831fcf][Installing ~pdf-tools~ elisp code]]
|
||||
|
||||
+ Misc ::
|
||||
- Display PDF's metadata.
|
||||
- Mark a region and kill the text from the PDF.
|
||||
- Keep track of visited pages via a history.
|
||||
- Apply a color filter for reading in low light conditions.
|
||||
** Installing ~epdfinfo~ server prerequisites
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 8ce3cf4e-d186-4de1-a40e-f41063068ab0
|
||||
:END:
|
||||
You'll need GNU Emacs \ge 24.3 and some form of a GNU/Linux OS. Other operating systems are not officially supported, but ~pdf-tools~ is known to work on many of them. See links below for more details. The following instructions assume a Debian-based system.
|
||||
|
||||
** Installation
|
||||
The package may be installed via melpa and it will try to build the
|
||||
server part when it is activated the first time. Though the next
|
||||
section regarding build-prerequisites is still relevant, the rest
|
||||
of the installation instructions assume a build from within a git
|
||||
repository. (The melpa package has a different directory
|
||||
structure.)
|
||||
First make sure a suitable build-system is installed. We need at least a C/C++ compiler (both ~gcc~ and ~g++~), ~make~, ~automake~ and ~autoconf~.
|
||||
|
||||
*** Server Prerequisites
|
||||
You'll need GNU Emacs \ge 24.3 and some form of a GNU/Linux OS.
|
||||
Other operating systems are currently not supported (patches
|
||||
welcome). The following instructions assume a Debian-based
|
||||
system. (The prerequisites may be installed automatically on this
|
||||
kind of systems, see [[#compilation][Compilation]] .)
|
||||
|
||||
First make sure a suitable build-system is installed. We need at
|
||||
least a C/C++ compiler (both ~gcc~ and ~g++~), ~make~, ~automake~
|
||||
and ~autoconf~.
|
||||
|
||||
Next we need to install a few libraries PDF Tools depends on, some
|
||||
of which are probably already on your system.
|
||||
Next we need to install a few libraries ~pdf-tools~ depends on, some of which are probably already on your system.
|
||||
#+begin_src sh
|
||||
$ sudo aptitude install libpng-dev zlib1g-dev
|
||||
$ sudo aptitude install libpoppler-glib-dev
|
||||
$ sudo aptitude install libpoppler-private-dev
|
||||
$ sudo apt install libpng-dev zlib1g-dev libpoppler-glib-dev libpoppler-private-dev
|
||||
#+end_src
|
||||
On some older Ubuntu systems, the final command will possibly give
|
||||
an error. This should be no problem, since in some versions this
|
||||
package was contained in the main package ~libpoppler-dev~. Also
|
||||
note, that ~zlib1g-dev~ was for a long time called ~libz-dev~,
|
||||
which it still may be on your system.
|
||||
|
||||
Debian wheezy comes with libpoppler version 0.18, which is pretty
|
||||
old. The minimally required version is 0.16, but some features of
|
||||
PDF Tools depend on a more recent version of this library. See
|
||||
the following table for what they are and what version they
|
||||
require.
|
||||
On some older Ubuntu systems, the final command will possibly give an error. This should be no problem, since in some versions this package was contained in the main package ~libpoppler-dev~. Also note, that ~zlib1g-dev~ was for a long time called ~libz-dev~, which it still may be on your system.
|
||||
|
||||
| You want to ... | Required version |
|
||||
|-------------------------------------------+------------------|
|
||||
| ... create and modify text annotations. | \ge 0.19.4 |
|
||||
| ... search case-sensitive. | \ge 0.22 |
|
||||
| ... create and modify markup annotations. | \ge 0.26 |
|
||||
|-------------------------------------------+------------------|
|
||||
Debian wheezy comes with ~libpoppler~ version ~0.18~, which is pretty old. The minimally required version is ~0.16~, but some features of ~pdf-tools~ depend on a more recent version of this library. See the following table for what they are and what version they require.
|
||||
|
||||
In case you decide to install libpoppler from source, make sure
|
||||
to run its configure script with the ~--enable-xpdf-headers~
|
||||
option.
|
||||
| You want to ... | Required version |
|
||||
|-------------------------------------------+------------------|
|
||||
| ... create and modify text annotations. | \ge 0.19.4 |
|
||||
| ... search case-sensitive. | \ge 0.22 |
|
||||
| ... create and modify markup annotations. | \ge 0.26 |
|
||||
|-------------------------------------------+------------------|
|
||||
|
||||
Finally there is one feature (following links of a PDF document by
|
||||
plain keystrokes) which requires imagemagick's convert utility.
|
||||
This requirement is optional and you may install it like so:
|
||||
In case you decide to install ~libpoppler~ from source, make sure to run its configure script with the ~--enable-xpdf-headers~ option.
|
||||
|
||||
Finally there is one feature (following links of a PDF document by plain keystrokes) which requires imagemagick's convert utility. This requirement is optional and you may install it like so:
|
||||
#+begin_src sh
|
||||
$ sudo aptitude install imagemagick
|
||||
$ sudo apt install imagemagick
|
||||
#+end_src
|
||||
**** Compiling on OS X
|
||||
Although OS X is not officially supported, it has been reported
|
||||
to have been successfully compiled. You will need to install
|
||||
poppler which you can get with homebrew via
|
||||
*** Installing Server Prerequisites On macOS
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: f10e9d94-bdec-44dc-8d3c-1816d62ef1c4
|
||||
:END:
|
||||
Although macOS is not officially supported, it has been reported that ~pdf-tools~ works well on macOS. You will need to install ~poppler~ which you can get with Homebrew via
|
||||
#+BEGIN_SRC sh
|
||||
$ brew install poppler automake
|
||||
#+END_SRC
|
||||
|
||||
You will also have to help ~pkg-config~ find some libraries by
|
||||
setting ~PKG_CONFIG_PATH~, e.g.
|
||||
You will also have to help ~pkg-config~ find some libraries by setting ~PKG_CONFIG_PATH~, e.g.
|
||||
#+BEGIN_SRC sh
|
||||
$ export PKG_CONFIG_PATH=/usr/local/Cellar/zlib/1.2.8/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig
|
||||
#+END_SRC
|
||||
or likewise within Emacs using `setenv`.
|
||||
or likewise within Emacs using ~setenv~.
|
||||
|
||||
After that, compilation should proceed as normal.
|
||||
**** FreeBSD
|
||||
Although not officially supported, it has been reported that
|
||||
pdf-tools work well on FreeBSD. Instead of building pdf-tools, you
|
||||
can install one of the OS packages with, e.g.
|
||||
After that, compilation should proceed as normal.
|
||||
*** Installing Server Prerequisites On FreeBSD
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 00faf3e3-6d09-4cf7-9373-838f3d231504
|
||||
:END:
|
||||
Although not officially supported, it has been reported that ~pdf-tools~ work well on FreeBSD. Instead of building ~pdf-tools~, you can install one of the OS packages with e.g.
|
||||
#+BEGIN_SRC sh
|
||||
$ pkg install pdf-tools-emacs26
|
||||
#+END_SRC
|
||||
To see the current list of pdf-tools packages for FreeBSD visit
|
||||
[[https://repology.org/metapackages/?search=pdf-tools&inrepo=freebsd][the Repology list]].
|
||||
|
||||
To build pdf-tools from either melpa or directly from the source
|
||||
repository, install the dependencies with
|
||||
To see the current list of ~pdf-tools~ packages for FreeBSD visit [[https://repology.org/metapackages/?search=pdf-tools&inrepo=freebsd][the Repology list]].
|
||||
|
||||
To build ~pdf-tools~ from either MELPA or directly from the source repository, install the dependencies with
|
||||
#+BEGIN_SRC sh
|
||||
$ pkg install autotools gmake poppler-glib
|
||||
#+END_SRC
|
||||
|
||||
If you choose not to install from melpa, you must substitute
|
||||
~gmake~ for ~make~ in the instructions below.
|
||||
**** Compiling on Centos
|
||||
It is possible to compile pdf-tools on Centos. Install poppler the dependencies with:
|
||||
If you choose not to install from MELPA, you must substitute ~gmake~ for ~make~ in the instructions below.
|
||||
*** Installing Server Prerequisites On CentOS
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: e39946d0-3a28-405d-bb23-337120412dac
|
||||
:END:
|
||||
#+BEGIN_SRC sh
|
||||
$ yum install poppler-devel poppler-glib-devel
|
||||
#+END_SRC
|
||||
|
||||
**** Compiling on Fedora
|
||||
*** Installing Server Prerequisites On Fedora
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: d0013822-f4d0-4354-b3db-c54ffe41ce58
|
||||
:END:
|
||||
#+BEGIN_SRC sh
|
||||
$ sudo dnf install make automake autoconf gcc gcc-c++ ImageMagick libpng-devel zlib-devel poppler-glib-devel
|
||||
#+END_SRC
|
||||
|
||||
**** Compiling on Alpine Linux
|
||||
*** Installing Server Prerequisites On Alpine Linux
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 443d9b18-096e-4770-b59c-4e472a5d4b0e
|
||||
:END:
|
||||
#+BEGIN_SRC sh
|
||||
$ apk add build-base g++ gcc automake autoconf libpng-dev glib-dev poppler-dev
|
||||
#+END_SRC
|
||||
|
||||
**** Compiling on Windows
|
||||
PDF Tools can be built and used on Windows using the MSYS2
|
||||
compiler. This will work with native (not cygwin) Windows builds of
|
||||
emacs. This includes the standard binaries provided by the GNU
|
||||
project, those available as MSYS2 packages and numerous third-party
|
||||
binaries. It has been tested with emacs 25.1. Instructions are
|
||||
provided under [[#compilation-and-installation-on-windows][Compilation and installation on Windows]], below.
|
||||
PDF Tools will successfully compile using Cygwin, but it will not be
|
||||
able to open PDFs properly due to the way binaries compiled with Cygwin
|
||||
handle file paths.
|
||||
*** Installing Server Prerequisites On Windows
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 005243cb-1557-4f94-a73d-e647e0d4b53d
|
||||
:END:
|
||||
~pdf-tools~ can be built and used on Windows using the MSYS2 compiler. This will work with native (not cygwin) Windows builds of Emacs. This includes the standard binaries provided by the GNU project, those available as MSYS2 packages and numerous third-party binaries. It has been tested with Emacs 25.1. Instructions are provided under [[id:d14e01ff-9bd5-47ee-86fc-859b4499d5d7][Compilation and installation on Window]] below. ~pdf-tools~ will successfully compile using Cygwin, but it will not be able to open PDFs properly due to the way binaries compiled with Cygwin handle file paths.
|
||||
|
||||
*** Compilation
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: compilation
|
||||
:END:
|
||||
Now it's time to compile the source.
|
||||
** Compiling and Installing the ~epdfinfo~ server
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: e305cd0a-e798-4c2b-af27-21bcd936c1c9
|
||||
:END:
|
||||
#+begin_src sh
|
||||
$ cd /path/to/pdf-tools
|
||||
$ make install-server-deps # optional
|
||||
$ make -s
|
||||
#+end_src
|
||||
The ~make install-server-deps~ command will try to install all
|
||||
necessary programs and libraries to build the package, though
|
||||
it'll only work, if ~sudo~ and ~apt-get~ are available.
|
||||
|
||||
This should compile the source code and create a Emacs Lisp
|
||||
Package in the root directory of the project. The configure script
|
||||
also tells you at the very end, which features, depending on the
|
||||
libpoppler version, will be available. These commands should give
|
||||
no error, otherwise you are in trouble.
|
||||
**** Compilation and installation on Windows
|
||||
If using the GNU binaries for Windows, support for PNG and zlib
|
||||
must first be installed by copying the appropriate dlls into
|
||||
emacs' ~bin/~ directory. Most third-party binaries come with this
|
||||
already done.
|
||||
This should compile the source code and create a Emacs Lisp Package in the root directory of the project. The configure script also tells you at the very end, which features, depending on the libpoppler version, will be available. These commands should give no error, otherwise you are in trouble.
|
||||
*** On Windows
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: d14e01ff-9bd5-47ee-86fc-859b4499d5d7
|
||||
:END:
|
||||
If using the GNU binaries for Windows, support for PNG and ~zlib~ must first be installed by copying the appropriate dlls into emacs' ~bin/~ directory. Most third-party binaries come with this already done.
|
||||
|
||||
First, install [[http://www.msys2.org/][install MSYS2]] and update
|
||||
the package database and core packages using the instructions
|
||||
provided. Then, to compile PDF tools itself:
|
||||
First, install [[http://www.msys2.org/][install MSYS2]] and update the package database and core packages using the instructions provided. Then, to compile ~pdf-tools~ itself:
|
||||
|
||||
1. Open msys2 shell
|
||||
1. Open msys2 shell
|
||||
2. Update and install dependencies, skipping any you already have
|
||||
#+BEGIN_SRC sh
|
||||
$ pacman -Syu
|
||||
$ pacman -S base-devel
|
||||
$ pacman -S mingw-w64-x86_64-toolchain
|
||||
$ pacman -S mingw-w64-x86_64-zlib
|
||||
$ pacman -S mingw-w64-x86_64-libpng
|
||||
$ pacman -S mingw-w64-x86_64-poppler
|
||||
$ pacman -S mingw-w64-x86_64-imagemagick
|
||||
#+END_SRC
|
||||
3. Install ~pdf-tools~ in Emacs, but do not try to compile the server. Instead, get a separate copy of the source somewhere else.
|
||||
#+BEGIN_SRC sh
|
||||
$ git clone https://github.com/vedang/pdf-tools
|
||||
#+END_SRC
|
||||
4. Open ~mingw64~ shell (*Note:* You must use ~mingw64.exe~ and not ~msys2.exe~)
|
||||
5. Compile pdf-tools
|
||||
#+BEGIN_SRC sh
|
||||
$ cd /path/to/pdf-tools
|
||||
$ make -s
|
||||
#+END_SRC
|
||||
6. This should produce a file ~server/epdfinfo.exe~. Copy this file into the ~pdf-tools/~ installation directory in your Emacs.
|
||||
7. Start Emacs and activate the package.
|
||||
#+BEGIN_SRC
|
||||
M-x pdf-tools-install RET
|
||||
#+END_SRC
|
||||
8. Test.
|
||||
#+BEGIN_SRC
|
||||
M-x pdf-info-check-epdfinfo RET
|
||||
#+END_SRC
|
||||
|
||||
2. Update and install dependencies, skipping any you already have
|
||||
#+BEGIN_SRC sh
|
||||
$ pacman -Syu
|
||||
$ pacman -S base-devel
|
||||
$ pacman -S mingw-w64-x86_64-toolchain
|
||||
$ pacman -S mingw-w64-x86_64-zlib
|
||||
$ pacman -S mingw-w64-x86_64-libpng
|
||||
$ pacman -S mingw-w64-x86_64-poppler
|
||||
$ pacman -S mingw-w64-x86_64-imagemagick
|
||||
#+END_SRC
|
||||
If this is successful, ~(pdf-tools-install)~ can be added to Emacs' config. Note that libraries from other GNU utilities, such as Git for Windows, may interfere with those needed by ~pdf-tools~. ~pdf-info-check-epdinfo~ will succeed, but errors occur when trying to view a PDF file. This can be fixed by ensuring that the MSYS libraries are always preferred in Emacs:
|
||||
|
||||
3. Install PDF tools in Emacs, but do not try to compile the
|
||||
server. Instead, get a separate copy of the source somewhere
|
||||
else.
|
||||
#+BEGIN_SRC sh
|
||||
$ git clone https://github.com/politza/pdf-tools
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setenv "PATH" (concat "C:\\msys64\\mingw64\\bin;" (getenv "PATH")))
|
||||
#+END_SRC
|
||||
|
||||
4. Open mingw64 shell (*Note:* You must use mingw64.exe and not msys2.exe)
|
||||
** Installing ~pdf-tools~ elisp prerequisites
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 3d4e6b6b-f015-475d-8ea2-84988efd6c22
|
||||
:END:
|
||||
This package depends on the following Elisp packages, which should be installed before installing the ~pdf-tools~ package.
|
||||
| Package | Required version |
|
||||
|-----------+----------------------------------|
|
||||
| [[https://elpa.gnu.org/packages/let-alist.html][let-alist]] | >= 1.0.4 (comes with Emacs 25.2) |
|
||||
| [[http://melpa.org/#/tablist][tablist]] | >= 0.70 |
|
||||
|-----------+----------------------------------|
|
||||
|
||||
5. Compile pdf-tools
|
||||
#+BEGIN_SRC sh
|
||||
$ cd /path/to/pdf-tools
|
||||
$ make -s
|
||||
#+END_SRC
|
||||
|
||||
6. This should produce a file ~server/epdfinfo.exe~. Copy this file
|
||||
into the ~pdf-tools/~ installation directory in your Emacs.
|
||||
|
||||
7. Start Emacs and activate the package.
|
||||
#+BEGIN_SRC
|
||||
M-x pdf-tools-install RET
|
||||
#+END_SRC
|
||||
|
||||
8. Test.
|
||||
#+BEGIN_SRC
|
||||
M-x pdf-info-check-epdfinfo RET
|
||||
#+END_SRC
|
||||
|
||||
If this is successful, ~(pdf-tools-install)~ can be added to Emacs'
|
||||
config. Note that libraries from other GNU utilities, such as Git
|
||||
for Windows, may interfere with those needed by PDF Tools.
|
||||
~pdf-info-check-epdinfo~ will succeed, but errors occur when trying
|
||||
to view a PDF file. This can be fixed by ensuring that the MSYS
|
||||
libraries are always preferred in emacs:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setenv "PATH" (concat "C:\\msys64\\mingw64\\bin;" (getenv "PATH")))
|
||||
#+END_SRC
|
||||
|
||||
*** ELisp Prerequisites
|
||||
This package depends on the following Elisp packages, which should
|
||||
be installed before installing the Pdf Tools package.
|
||||
|
||||
| Package | Required version |
|
||||
|-----------+----------------------------------|
|
||||
| [[https://elpa.gnu.org/packages/let-alist.html][let-alist]] | >= 1.0.4 (comes with Emacs 25.2) |
|
||||
| [[http://melpa.org/#/tablist][tablist]] | >= 0.70 |
|
||||
|-----------+----------------------------------|
|
||||
|
||||
*** Installing
|
||||
If ~make~ produced the ELP file ~pdf-tools-${VERSION}.tar~ you are
|
||||
fine. This package contains all the necessary files for Emacs
|
||||
and may be installed by either using
|
||||
** Installing ~pdf-tools~ elisp code
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 32c4fc3b-b4ea-43bd-b92c-bdf2d3831fcf
|
||||
:END:
|
||||
If ~make~ produced the ELP file ~pdf-tools-${VERSION}.tar~ you are fine. This package contains all the necessary files for Emacs and may be installed by either using
|
||||
#+begin_src sh
|
||||
$ make install-package
|
||||
#+end_src
|
||||
or executing the Emacs command
|
||||
or executing the Emacs command
|
||||
#+begin_src elisp
|
||||
M-x package-install-file RET pdf-tools-${VERSION}.tar RET
|
||||
#+end_src
|
||||
|
||||
To complete the installation process, you need to activate the
|
||||
package by putting
|
||||
To complete the installation process, you need to activate the package by putting the code below somewhere in your ~.emacs~. Alternatively, and if you care about startup time, you may want to use the loader version instead.
|
||||
#+begin_src elisp
|
||||
(pdf-tools-install)
|
||||
#+end_src
|
||||
somewhere in your ~.emacs~. Alternatively, and if you care about
|
||||
start-up time, you may want to use
|
||||
#+begin_src elisp
|
||||
(pdf-loader-install)
|
||||
#+end_src
|
||||
instead. Next you probably want to take a look at the various
|
||||
features of what you've just installed. The following two commands
|
||||
might be of help for doing so.
|
||||
#+begin_src elisp
|
||||
M-x pdf-tools-help RET
|
||||
M-x pdf-tools-customize RET
|
||||
(pdf-tools-install) ; Standard activation command
|
||||
(pdf-loader-install) ; On demand loading, leads to faster startup time
|
||||
#+end_src
|
||||
|
||||
*** Updating
|
||||
Some day you might want to update this package via ~git pull~ and
|
||||
then reinstall it. Sometimes this may fail, especially if
|
||||
Lisp-Macros are involved and the version hasn't changed. To avoid
|
||||
this kind of problems, you should delete the old package via
|
||||
~list-packages~, restart Emacs and then reinstall the package.
|
||||
Once the Installation process is complete, check out [[id:19a3daea-6fa6-4ac3-9201-d2034c46ad8c][Easy Help for PDF Tools features]] and [[id:8dccd685-18b8-4c98-977a-0fe2d66b724c][Configuring PDF Tools features]] to get started!
|
||||
** Updating ~pdf-tools~
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 9dd62314-f5ad-4bd4-83fa-8e28343e3d9c
|
||||
:END:
|
||||
Some day you might want to update this package via ~git pull~ and then reinstall it. Sometimes this may fail, especially if Lisp-Macros are involved and the version hasn't changed. To avoid this kind of problems, you should delete the old package via ~list-packages~, restart Emacs and then reinstall the package.
|
||||
|
||||
This also applies when updating via package and melpa.
|
||||
|
||||
** Known problems
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: known-problems
|
||||
:END:
|
||||
|
||||
*** linum-mode
|
||||
PDF Tools does not work well together with ~linum-mode~ and
|
||||
activating it in a ~pdf-view-mode~, e.g. via ~global-linum-mode~,
|
||||
might make Emacs choke.
|
||||
|
||||
*** auto-revert
|
||||
Autorevert works by polling the file-system every
|
||||
~auto-revert-interval~ seconds, optionally combined with some
|
||||
event-based reverting via [[https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Notifications.html][file notification]]. But this currently
|
||||
does not work reliably, such that Emacs may revert the PDF-buffer
|
||||
while the corresponding file is still being written to (e.g. by
|
||||
LaTeX), leading to a potential error.
|
||||
|
||||
With a recent [[https://www.gnu.org/software/auctex/][auctex]] installation, you might want to put the
|
||||
following somewhere in your dotemacs, which will revert the PDF-buffer
|
||||
*after* the TeX compilation has finished.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
|
||||
#+END_SRC
|
||||
** Some keybindings
|
||||
|
||||
| Navigation | |
|
||||
|--------------------------------------------+-----------------------|
|
||||
| Scroll Up / Down by page-full | ~space~ / ~backspace~ |
|
||||
| Scroll Up / Down by line | ~C-n~ / ~C-p~ |
|
||||
| Scroll Right / Left | ~C-f~ / ~C-b~ |
|
||||
| Top of Page / Bottom of Page | ~<~ / ~>~ |
|
||||
| Next Page / Previous Page | ~n~ / ~p~ |
|
||||
| First Page / Last Page | ~M-<~ / ~M->~ |
|
||||
| Incremental Search Forward / Backward | ~C-s~ / ~C-r~ |
|
||||
| Occur (list all lines containing a phrase) | ~M-s o~ |
|
||||
| Jump to Occur Line | ~RETURN~ |
|
||||
| Pick a Link and Jump | ~F~ |
|
||||
| Incremental Search in Links | ~f~ |
|
||||
| History Back / Forwards | ~B~ / ~N~ |
|
||||
| Display Outline | ~o~ |
|
||||
| Jump to Section from Outline | ~RETURN~ |
|
||||
| Jump to Page | ~M-g g~ |
|
||||
This also applies when updating via package and MELPA.
|
||||
* Features
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 555b4a2a-7881-49ac-a066-7e3f10034ca4
|
||||
:END:
|
||||
+ View :: View PDF documents in a buffer with DocView-like bindings. [[id:18d362e1-a1a3-4c51-9d45-04e2c53d8c0c][More information here]].
|
||||
+ Isearch :: Interactively search PDF documents like any other buffer, either for a string or a PCRE.
|
||||
+ Occur :: List lines matching a string or regexp in one or more PDF documents.
|
||||
+ Follow :: Click on highlighted links, moving to some part of a different page, some external file, a website or any other URI. Links may also be followed by keyboard commands.
|
||||
+ Annotations :: Display and list text and markup annotations (like underline), edit their contents and attributes (e.g. color), move them around, delete them or create new ones and then save the modifications back to the PDF file. [[id:5fff6471-a933-46d7-8ae9-b2fa4a9de952][More information here]].
|
||||
+ Attachments :: Save files attached to the PDF-file or list them in a dired buffer.
|
||||
+ Outline :: Use ~imenu~ or a special buffer (~M-x pdf-outline~) to examine and navigate the PDF's outline.
|
||||
+ SyncTeX :: Jump from a position on a page directly to the TeX source and vice versa.
|
||||
+ Virtual :: Use a collection of documents as if it were one, big single PDF.
|
||||
+ Misc ::
|
||||
- Display PDF's metadata.
|
||||
- Mark a region and kill the text from the PDF.
|
||||
- Keep track of visited pages via a history.
|
||||
- Apply a color filter for reading in low light conditions.
|
||||
** View and Navigate PDFs
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:25]
|
||||
:ID: 18d362e1-a1a3-4c51-9d45-04e2c53d8c0c
|
||||
:END:
|
||||
PDFView Mode is an Emacs PDF viewer. It displays PDF files as PNG images in Emacs buffers. PDFs are navigable using DocView-like bindings. Once you have installed ~pdf-tools~, opening a PDF in Emacs will automatically trigger this mode.
|
||||
*** Keybindings for navigating PDF documents
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:25]
|
||||
:ID: 01864499-2286-4e64-91f5-f8133f53ec61
|
||||
:END:
|
||||
| Navigation | |
|
||||
|-----------------------------------------------+-----------------------|
|
||||
| Scroll Up / Down by Page-full | ~space~ / ~backspace~ |
|
||||
| Scroll Up / Down by Line | ~C-n~ / ~C-p~ |
|
||||
| Scroll Right / Left | ~C-f~ / ~C-b~ |
|
||||
| First Page / Last Page | ~<~ / ~>~ |
|
||||
| Next Page / Previous Page | ~n~ / ~p~ |
|
||||
| First Page / Last Page | ~M-<~ / ~M->~ |
|
||||
| Incremental Search Forward / Backward | ~C-s~ / ~C-r~ |
|
||||
| Occur (list all lines containing a phrase) | ~M-s o~ |
|
||||
| Jump to Occur Line | ~RETURN~ |
|
||||
| Pick a Link and Jump | ~F~ |
|
||||
| Incremental Search in Links | ~f~ |
|
||||
| History Back / Forwards | ~l~ / ~r~ |
|
||||
| Display Outline | ~o~ |
|
||||
| Jump to Section from Outline | ~RETURN~ |
|
||||
| Jump to Page | ~M-g g~ |
|
||||
| Store position / Jump to position in register | ~m~ / ~'~ |
|
||||
|-----------------------------------------------+-----------------------|
|
||||
| | |
|
||||
Note that ~pdf-tools~ renders the PDF as images inside Emacs. This means that all the keybindings of ~image-mode~ work on individual PDF pages as well.
|
||||
| Image Mode | |
|
||||
|------------------------+---------------------------------------------|
|
||||
| image-scroll-right | ~C-x >~ / ~<remap> <scroll-right>~ |
|
||||
| image-scroll-left | ~C-x <~ / ~<remap> <scroll-left>~ |
|
||||
| image-scroll-up | ~C-v~ / ~<remap> <scroll-up>~ |
|
||||
| image-scroll-down | ~M-v~ / ~<remap> <scroll-down>~ |
|
||||
| image-forward-hscroll | ~C-f~ / ~right~ / ~<remap> <forward-char>~ |
|
||||
| image-backward-hscroll | ~C-b~ / ~left~ / ~<remap> <backward-char>~ |
|
||||
| image-bob | ~<remap> <beginning-of-buffer>~ |
|
||||
| image-eob | ~<remap> <end-of-buffer>~ |
|
||||
| image-bol | ~<remap> <move-beginning-of-line>~ |
|
||||
| image-eol | ~<remap> <move-end-of-line>~ |
|
||||
| image-scroll-down | ~<remap> <scroll-down>~ |
|
||||
| image-scroll-up | ~<remap> <scroll-up>~ |
|
||||
| image-scroll-left | ~<remap> <scroll-left>~ |
|
||||
| image-scroll-right | ~<remap> <scroll-right>~ |
|
||||
|------------------------+---------------------------------------------|
|
||||
| | |
|
||||
|
||||
*** Keybindings for manipulating display of PDF
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:33]
|
||||
:ID: 73a18ea8-aa21-48d4-9d8b-dc64e3601000
|
||||
:END:
|
||||
| Display | |
|
||||
|------------------------------------------+-----------------|
|
||||
| Zoom in / Zoom out | ~+~ / ~-~ |
|
||||
| Fit Height / Fit Width / Fit Page | ~H~ / ~W~ / ~P~ |
|
||||
| Trim margins (set slice to bounding box) | ~s b~ |
|
||||
| Reset margins | ~s r~ |
|
||||
| Reset Zoom | 0 |
|
||||
| Trim Margins (set slice to bounding box) | ~s b~ |
|
||||
| Reset Margins | ~s r~ |
|
||||
| Reset Zoom | ~0~ |
|
||||
|
||||
| Annotations | |
|
||||
|-------------------------------+-------------------------------------------------|
|
||||
| List Annotations | ~C-c C-a l~ |
|
||||
| Jump to Annotations from List | ~SPACE~ |
|
||||
| Mark Annotation for Deletion | ~d~ |
|
||||
| Delete Marked Annotations | ~x~ |
|
||||
| Unmark Annotations | ~u~ |
|
||||
| Close Annotation List | ~q~ |
|
||||
| Add and edit annotations | via Mouse selection and left-click context menu |
|
||||
** Annotations
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 16:58]
|
||||
:ID: 5fff6471-a933-46d7-8ae9-b2fa4a9de952
|
||||
:END:
|
||||
~pdf-tools~ supports working with PDF Annotations. You can display and list text and markup annotations (like squiggly, highlight), edit their contents and attributes (e.g. color), move them around, delete them or create new ones and then save the modifications back to the PDF file.
|
||||
*** Keybindings for working with Annotations
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 17:08]
|
||||
:ID: 243b3843-b912-430b-884a-641304755b92
|
||||
:END:
|
||||
| Annotations | |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| List Annotations | ~C-c C-a l~ |
|
||||
| Jump to Annotations from List | ~SPACE~ |
|
||||
| Mark Annotation for Deletion | ~d~ |
|
||||
| Delete Marked Annotations | ~x~ |
|
||||
| Unmark Annotations | ~u~ |
|
||||
| Close Annotation List | ~q~ |
|
||||
| Enable/Disable Following Annotations | ~C-c C-f~ |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| Add and Edit Annotations | Select region via Mouse selection. |
|
||||
| | Then left-click context menu OR keybindings below |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| Add a Markup Annotation | ~C-c C-a m~ |
|
||||
| Add a Highlight Markup Annotation | ~C-c C-a h~ |
|
||||
| Add a Strikeout Markup Annotation | ~C-c C-a o~ |
|
||||
| Add a Squiggly Markup Annotation | ~C-c C-a s~ |
|
||||
| Add an Underline Markup Annotation | ~C-c C-a u~ |
|
||||
| Add a Text Annotation | ~C-c C-a t~ |
|
||||
|--------------------------------------+---------------------------------------------------|
|
||||
| | |
|
||||
|
||||
| Syncing with Auctex | |
|
||||
|----------------------------------+-------------|
|
||||
| jump to PDF location from source | ~C-c C-g~ |
|
||||
| jump source location from PDF | ~C-mouse-1~ |
|
||||
** Working with AUCTeX
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:37]
|
||||
:ID: 698bdbad-e5f1-4958-b61e-9ed12d4b1234
|
||||
:END:
|
||||
*** Keybindings for working with AUCTeX
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:37]
|
||||
:ID: ab7872c1-edd6-465d-9d1d-b621db6364a3
|
||||
:END:
|
||||
| Syncing with AUCTeX | |
|
||||
|-----------------------------------------------+-------------|
|
||||
| Refresh File (e.g., after recompiling source) | ~g~ |
|
||||
| Jump to PDF Location from Source | ~C-c C-g~ |
|
||||
| Jump Source Location from PDF | ~C-mouse-1~ |
|
||||
|
||||
** Miscellaneous features
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:37]
|
||||
:ID: bbefb49d-fca8-4d4f-9d16-4a4ad1946d89
|
||||
:END:
|
||||
*** Keybindings for miscellaneous features in PDF tools
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 18:35]
|
||||
:ID: 9148deff-dd5a-46be-a48f-cd2f96b7ce19
|
||||
:END:
|
||||
| Miscellaneous | |
|
||||
|-----------------------------------------------+-----------|
|
||||
| Refresh File (e.g., after recompiling source) | ~g~ |
|
||||
| Print File | ~C-c C-p~ |
|
||||
|
||||
** Easy Help for PDF Tools features
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 13:49]
|
||||
:ID: 19a3daea-6fa6-4ac3-9201-d2034c46ad8c
|
||||
:END:
|
||||
#+begin_src elisp
|
||||
M-x pdf-tools-help RET
|
||||
#+end_src
|
||||
|
||||
Run ~M-x pdf-tools-help~ inside Emacs, as shown above. It will list all the features provided by ~pdf-tools~ as well as the key-bindings for these features.
|
||||
|
||||
** Configuring PDF Tools features
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 13:51]
|
||||
:ID: 8dccd685-18b8-4c98-977a-0fe2d66b724c
|
||||
:END:
|
||||
Once you have read through the features provided by ~pdf-tools~, you probably want to customize the behavior of the features as per your requirements. Full customization of features is available by running the following:
|
||||
#+begin_src elisp
|
||||
M-x pdf-tools-customize RET
|
||||
#+end_src
|
||||
|
||||
* Known problems
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:29]
|
||||
:ID: 4baf936a-2454-41c9-99db-177133ee9568
|
||||
:END:
|
||||
|
||||
** linum-mode
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 73625d02-d472-4e7d-9805-db6d3b60e0ff
|
||||
:END:
|
||||
~pdf-tools~ does not work well together with ~linum-mode~ and activating it in a ~pdf-view-mode~, e.g. via ~global-linum-mode~, might make Emacs choke.
|
||||
|
||||
** display-line-numbers-mode
|
||||
:PROPERTIES:
|
||||
:CREATED: [2022-01-03 Mon 08:31]
|
||||
:ID: f178ba41-0f5a-4d22-b4a8-889af1af566e
|
||||
:END:
|
||||
This mode is an alternative to ~linum-mode~ and is available since Emacs 26. ~pdf-tools~ does not work well with it. For example, it makes horizontal navigation (such as ~C-f~, ~C-b~, ~C-x <~ or ~C-x >~ ) in a document impossible.
|
||||
|
||||
** auto-revert
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 24b671c6-c242-4983-9d11-38421d2752e9
|
||||
:END:
|
||||
Autorevert works by polling the file-system every ~auto-revert-interval~ seconds, optionally combined with some event-based reverting via [[https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Notifications.html][file notification]]. But this currently does not work reliably, such that Emacs may revert the PDF-buffer while the corresponding file is still being written to (e.g. by LaTeX), leading to a potential error.
|
||||
|
||||
With a recent [[https://www.gnu.org/software/auctex/][AUCTeX]] installation, you might want to put the following somewhere in your dotemacs, which will revert the PDF-buffer *after* the TeX compilation has finished.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
|
||||
#+END_SRC
|
||||
|
||||
** sublimity
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 4766d18a-c02a-456d-8398-701bbea3ee80
|
||||
:END:
|
||||
L/R scrolling breaks while zoomed into a pdf, with usage of sublimity smooth scrolling features
|
||||
|
||||
* Key-bindings in PDF Tools
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: fa99285a-437e-4be4-9a65-426db019019f
|
||||
:END:
|
||||
- [[brain-child:01864499-2286-4e64-91f5-f8133f53ec61][Keybindings for navigating PDF documents]]
|
||||
- [[brain-child:243b3843-b912-430b-884a-641304755b92][Keybindings for working with Annotations]]
|
||||
- [[brain-child:73a18ea8-aa21-48d4-9d8b-dc64e3601000][Keybindings for manipulating display of PDF]]
|
||||
- [[brain-child:ab7872c1-edd6-465d-9d1d-b621db6364a3][Keybindings for working with AUCTeX]]
|
||||
- [[brain-child:9148deff-dd5a-46be-a48f-cd2f96b7ce19][Keybindings for miscellaneous features in PDF tools]]
|
||||
|
||||
* Tips and Tricks for Developers
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: fd64c10c-4ea5-4ece-8d95-b723098dd4f6
|
||||
:END:
|
||||
** Turn on debug mode
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-29 Wed 18:34]
|
||||
:ID: 100fc888-7064-4dd3-9db4-c84a7e8f4af0
|
||||
:END:
|
||||
#+begin_src elisp
|
||||
M-x pdf-tools-toggle-debug RET
|
||||
#+end_src
|
||||
Toggling debug mode prints information about various operations in the ~*Messages*~ buffer, and this is useful to see what is happening behind the scenes
|
||||
|
||||
# Local Variables:
|
||||
# mode: org
|
||||
# End:
|
||||
|
||||
* FAQs
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 22:04]
|
||||
:ID: 3be6abe7-163e-4c3e-a7df-28e8470fe37f
|
||||
:END:
|
||||
** I'm on a Macbook and PDFs are rendering blurry
|
||||
:PROPERTIES:
|
||||
:CREATED: [2021-12-30 Thu 22:04]
|
||||
:ID: 20ef86be-7c92-4cda-97ec-70a22484e689
|
||||
:END:
|
||||
If you are on a Macbook with a Retina display, you may see PDFs as blurry due to the high resolution display. Use:
|
||||
|
||||
#+begin_src elisp
|
||||
(setq pdf-view-use-scaling t)
|
||||
#+end_src
|
||||
|
||||
to scale the images correctly when rendering them.
|
||||
|
||||
** What Emacs versions does ~pdf-tools~ support?
|
||||
:PROPERTIES:
|
||||
:CREATED: [2022-01-02 Sun 10:12]
|
||||
:ID: f44c66e6-402d-4154-b806-6bb4180a0a5b
|
||||
:END:
|
||||
~pdf-tools~ supports the 3 latest versions of Emacs major releases. At the moment of this writing, this means that the minimum supported Emacs version is ~25.1~.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
CASK = cask
|
||||
EMACS ?= emacs
|
||||
# Handle the mess when inside Emacs.
|
||||
unexport INSIDE_EMACS #cask not like this.
|
||||
@@ -15,21 +15,21 @@ version=$(shell sed -ne 's/^;\+ *Version: *\([0-9.]\)/\1/p' lisp/pdf-tools.el)
|
||||
pkgname=pdf-tools-$(version)
|
||||
pkgfile=$(pkgname).tar
|
||||
|
||||
.PHONY: all clean distclean bytecompile test check melpa cask-install
|
||||
.PHONY: all clean distclean bytecompile test check melpa
|
||||
|
||||
all: $(pkgfile)
|
||||
|
||||
# Create a elpa package including the server
|
||||
$(pkgfile): .cask/$(emacs_version) server/epdfinfo lisp/*.el
|
||||
cask package .
|
||||
$(CASK) package .
|
||||
|
||||
# Compile the Lisp sources
|
||||
bytecompile: .cask/$(emacs_version)
|
||||
cask exec $(emacs) --batch -L lisp -f batch-byte-compile lisp/*.el
|
||||
$(CASK) exec $(emacs) --batch -L lisp -f batch-byte-compile lisp/*.el
|
||||
|
||||
# Run ERT tests
|
||||
test: all
|
||||
PACKAGE_TAR=$(pkgfile) cask exec ert-runner
|
||||
PACKAGE_TAR=$(pkgfile) $(CASK) exec ert-runner
|
||||
|
||||
check: test
|
||||
|
||||
@@ -41,7 +41,7 @@ test-all: test test-autobuild
|
||||
|
||||
# Init cask
|
||||
.cask/$(emacs_version):
|
||||
cask install
|
||||
$(CASK) install
|
||||
|
||||
# Run the autobuild script (installing depends and compiling)
|
||||
autobuild:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##
|
||||
## Installs package dependencies and builds the application.
|
||||
@@ -64,16 +64,7 @@ which()
|
||||
if [ -z "$1" ]; then
|
||||
return 1
|
||||
fi
|
||||
IFS=:
|
||||
for dir in $PATH; do
|
||||
if [ -x "$dir/$1" ]; then
|
||||
printf "%s" "$dir/$1"
|
||||
unset IFS
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
return 1
|
||||
command -v "$1"
|
||||
}
|
||||
|
||||
# Quote $@ for the shell.
|
||||
@@ -167,9 +158,7 @@ have_packages_installed()
|
||||
which make || return 1
|
||||
which gcc || which cc || return 1
|
||||
which g++ || which c++ || return 1
|
||||
cc $(pkg-config --cflags poppler) -o /dev/null -E - 2>/dev/null <<EOF
|
||||
#include <PDFDocEncoding.h>
|
||||
EOF
|
||||
c++ $(pkg-config --cflags poppler) -o /dev/null -E install_test.cpp 2>/dev/null
|
||||
[ $? -eq 0 ] || return 1
|
||||
return 0
|
||||
} >/dev/null 2>&1
|
||||
@@ -260,7 +249,7 @@ os_openbsd() {
|
||||
fi
|
||||
PKGCMD=pkg_add
|
||||
PKGARGS="-uU"
|
||||
PACKAGES="autoconf-2.69p2 automake-1.15.1 poppler poppler-utils png"
|
||||
PACKAGES="autoconf%2.69 automake%1.15 poppler poppler-utils png"
|
||||
export AUTOCONF_VERSION=2.69
|
||||
export AUTOMAKE_VERSION=1.15
|
||||
if whereis clang++ ;then
|
||||
@@ -317,7 +306,7 @@ os_debian() {
|
||||
make
|
||||
pkg-config"
|
||||
PKGCMD=apt-get
|
||||
PKGARGS=install
|
||||
PKGARGS="install -y"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -409,7 +398,7 @@ os_gentoo() {
|
||||
PKGCMD=emerge
|
||||
PKGARGS=--noreplace
|
||||
PACKAGES="app-text/poppler
|
||||
dev-util/pkgconfig
|
||||
dev-util/pkgconf
|
||||
media-libs/libpng
|
||||
sys-devel/autoconf
|
||||
sys-devel/automake
|
||||
@@ -419,6 +408,29 @@ os_gentoo() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Void
|
||||
os_void() {
|
||||
if [ -f "/etc/os-release" ]; then
|
||||
. /etc/os-release
|
||||
if [ "$NAME" != "void" ]; then
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
PACKAGES="autoconf
|
||||
automake
|
||||
libpng-devel
|
||||
poppler-devel
|
||||
poppler-glib-devel
|
||||
zlib-devel
|
||||
make
|
||||
pkgconf"
|
||||
PKGCMD=xbps-install
|
||||
PKGARGS="-Sy"
|
||||
return 0
|
||||
}
|
||||
|
||||
# By Parameter --os
|
||||
os_argument() {
|
||||
[ -z "$OS" ] && return 1
|
||||
@@ -433,6 +445,7 @@ os_argument() {
|
||||
gentoo) os_gentoo "$@";;
|
||||
msys2) os_msys2 "$@";;
|
||||
nixos) os_nixos "$@";;
|
||||
void) os_void "$@";;
|
||||
*) echo "Invalid --os argument: $OS"
|
||||
exit 1
|
||||
esac || {
|
||||
@@ -458,6 +471,7 @@ os_debian "$@" || \
|
||||
os_gentoo "$@" || \
|
||||
os_msys2 "$@" || \
|
||||
os_nixos "$@" || \
|
||||
os_void "$@" || \
|
||||
{
|
||||
OS_IS_HANDLED=
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
@@ -490,10 +504,6 @@ if [ -n "$PKGCMD" ];then
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "---------------------------"
|
||||
echo " Configuring and compiling "
|
||||
echo "---------------------------"
|
||||
|
||||
# Try to be in the correct directory.
|
||||
if which dirname >/dev/null 2>&1; then
|
||||
cd "$(dirname "$0")" || {
|
||||
@@ -502,6 +512,10 @@ if which dirname >/dev/null 2>&1; then
|
||||
}
|
||||
fi
|
||||
|
||||
echo "---------------------------"
|
||||
echo " Configuring and compiling "
|
||||
echo "---------------------------"
|
||||
|
||||
# Create the configure script.
|
||||
if ! [ -f ./configure ]; then
|
||||
assert_program autoreconf
|
||||
@@ -515,8 +529,8 @@ if [ -n "$INSTALL_DIR" ]; then
|
||||
prefix=--bindir=$INSTALL_DIR
|
||||
fi
|
||||
|
||||
echo "./configure -q $prefix && make -s"
|
||||
eval "./configure -q $(quote "$prefix") && make -s || exit_fail"
|
||||
echo "./configure -q $prefix && make clean && make -s"
|
||||
eval "./configure -q $(quote "$prefix") && make clean && make -s || exit_fail"
|
||||
echo
|
||||
if [ -n "$INSTALL_DIR" ]; then
|
||||
echo "---------------------------"
|
||||
|
||||
@@ -339,7 +339,7 @@ strchomp (char *str)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new, temporary file and returns it's name.
|
||||
* Create a new, temporary file and returns its name.
|
||||
*
|
||||
* @return The filename.
|
||||
*/
|
||||
@@ -672,7 +672,7 @@ region_print (cairo_region_t *region, double width, double height)
|
||||
*
|
||||
* @param type The PopplerActionType.
|
||||
*
|
||||
* @return It's string representation.
|
||||
* @return Its string representation.
|
||||
*/
|
||||
static const char *
|
||||
xpoppler_action_type_string(PopplerActionType type)
|
||||
@@ -699,7 +699,7 @@ xpoppler_action_type_string(PopplerActionType type)
|
||||
*
|
||||
* @param type The PopplerAnnotType.
|
||||
*
|
||||
* @return It's string representation.
|
||||
* @return Its string representation.
|
||||
*/
|
||||
static const char *
|
||||
xpoppler_annot_type_string (PopplerAnnotType type)
|
||||
@@ -741,7 +741,7 @@ xpoppler_annot_type_string (PopplerAnnotType type)
|
||||
*
|
||||
* @param type The PopplerAnnotTextState.
|
||||
*
|
||||
* @return It's string representation.
|
||||
* @return Its string representation.
|
||||
*/
|
||||
static const char *
|
||||
xpoppler_annot_text_state_string (PopplerAnnotTextState state)
|
||||
|
||||
7
lisp/pdf-tools/build/server/install_test.cpp
Normal file
7
lisp/pdf-tools/build/server/install_test.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <PDFDocEncoding.h>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello World, pdf-tools!";
|
||||
return 0;
|
||||
}
|
||||
@@ -7592,7 +7592,7 @@ static synctex_nd_s _synctex_point_h_ordered_distance_v2
|
||||
int min,med,max,width;
|
||||
switch(synctex_node_type(node)) {
|
||||
/* The distance between a point and a box is special.
|
||||
* It is not the euclidian distance, nor something similar.
|
||||
* It is not the euclidean distance, nor something similar.
|
||||
* We have to take into account the particular layout,
|
||||
* and the box hierarchy.
|
||||
* Given a box, there are 9 regions delimited by the lines of the edges of the box.
|
||||
@@ -7733,7 +7733,7 @@ static synctex_nd_s _synctex_point_v_ordered_distance_v2
|
||||
int min,max,depth,height;
|
||||
switch(synctex_node_type(node)) {
|
||||
/* The distance between a point and a box is special.
|
||||
* It is not the euclidian distance, nor something similar.
|
||||
* It is not the euclidean distance, nor something similar.
|
||||
* We have to take into account the particular layout,
|
||||
* and the box hierarchy.
|
||||
* Given a box, there are 9 regions delimited by the lines of the edges of the box.
|
||||
@@ -7881,7 +7881,7 @@ SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hi
|
||||
|
||||
static int _synctex_distance_to_box_v2(synctex_point_p hit,synctex_box_p box) {
|
||||
/* The distance between a point and a box is special.
|
||||
* It is not the euclidian distance, nor something similar.
|
||||
* It is not the euclidean distance, nor something similar.
|
||||
* We have to take into account the particular layout,
|
||||
* and the box hierarchy.
|
||||
* Given a box, there are 9 regions delimited by the lines of the edges of the box.
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM base/archlinux
|
||||
FROM archlinux:latest
|
||||
RUN pacman -Syu --noconfirm --noprogressbar && \
|
||||
pacman -S --noconfirm --noprogressbar poppler-glib base-devel
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:artful
|
||||
FROM debian:10
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:24
|
||||
FROM fedora:32
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:25
|
||||
FROM fedora:33
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:26
|
||||
FROM fedora:34
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:35
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:bionic
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:groovy
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:focal
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:hirsute
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
@@ -37,6 +37,8 @@
|
||||
;; * Customizations
|
||||
;; * ================================================================== *
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defgroup pdf-annot nil
|
||||
"Annotation support for PDF documents."
|
||||
:group 'pdf-tools)
|
||||
@@ -53,17 +55,14 @@ called.
|
||||
|
||||
This hook is meant to allow for custom annotations. FIXME:
|
||||
Implement and describe basic org example."
|
||||
:group 'pdf-annot
|
||||
:type 'hook)
|
||||
|
||||
(defcustom pdf-annot-default-text-annotation-properties nil
|
||||
"Alist of initial properties for new text annotations."
|
||||
:group 'pdf-annot
|
||||
:type '(alist :key-type symbol :value-type sexp))
|
||||
|
||||
(defcustom pdf-annot-default-markup-annotation-properties nil
|
||||
"Alist of initial properties for new markup annotations."
|
||||
:group 'pdf-annot
|
||||
:type '(alist :key-type symbol :value-type sexp))
|
||||
|
||||
(make-obsolete-variable 'pdf-annot-default-text-annotation-properties
|
||||
@@ -107,7 +106,6 @@ would use a green color for highlight and a red one for other
|
||||
annotations. Additionally the label for all annotations is set
|
||||
to \"Joe\"."
|
||||
|
||||
:group 'pdf-annot
|
||||
:type (let* ((label '(cons :tag "Label" (const label) string))
|
||||
(contents '(cons :tag "Contents" (const contents) string))
|
||||
(color '(cons :tag "Color" (const color) color))
|
||||
@@ -147,7 +145,6 @@ will be used.
|
||||
|
||||
If all of them return nil, the default function
|
||||
`pdf-annot-print-annotation-default' is used."
|
||||
:group 'pdf-annot
|
||||
:type 'hook)
|
||||
|
||||
(defcustom pdf-annot-latex-string-predicate
|
||||
@@ -157,17 +154,14 @@ If all of them return nil, the default function
|
||||
|
||||
It receives a string and should return non-nil, if string is a
|
||||
LaTeX fragment."
|
||||
:group 'pdf-annot
|
||||
:type 'function)
|
||||
|
||||
(defcustom pdf-annot-latex-header
|
||||
(concat org-format-latex-header
|
||||
"\n\\setlength{\\textwidth}{12cm}")
|
||||
"Header used when latex compiling annotations.
|
||||
|
||||
The default value is `org-format-latex-header' + \
|
||||
The default value is `org-format-latex-header' +
|
||||
\"\\n\\\\setlength{\\\\textwidth}{12cm}\"."
|
||||
:group 'pdf-annot
|
||||
:type 'string)
|
||||
|
||||
(defcustom pdf-annot-tweak-tooltips t
|
||||
@@ -180,17 +174,14 @@ order to display text properties;
|
||||
|
||||
`tooltip-hide-delay' is set to infinity, in order to not being
|
||||
annoyed while reading the annotations."
|
||||
:group 'pdf-annot
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-annot-activate-created-annotations nil
|
||||
"Whether to activate (i.e. edit) created annotations."
|
||||
:group 'pdf-annot
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-annot-attachment-display-buffer-action nil
|
||||
"The display action used when displaying attachments."
|
||||
:group 'pdf-annot
|
||||
:type display-buffer--action-custom-type)
|
||||
|
||||
(defconst pdf-annot-annotation-types
|
||||
@@ -205,7 +196,6 @@ annoyed while reading the annotations."
|
||||
(list 'text 'file 'squiggly 'highlight 'underline 'strike-out)
|
||||
(list 'text 'file))
|
||||
"A list of annotation types displayed in the list buffer."
|
||||
:group 'pdf-annot
|
||||
:type `(set ,@(mapcar (lambda (type)
|
||||
(list 'const type))
|
||||
pdf-annot-annotation-types)))
|
||||
@@ -224,7 +214,7 @@ annoyed while reading the annotations."
|
||||
A function on this hook should accept one argument: A CLOSURE
|
||||
containing inserted, changed and deleted annotations.
|
||||
|
||||
It may access theses annotations by calling CLOSURE with one of
|
||||
It may access these annotations by calling CLOSURE with one of
|
||||
these arguments:
|
||||
|
||||
`:inserted' The list of recently added annotations.
|
||||
@@ -233,9 +223,9 @@ these arguments:
|
||||
|
||||
`:changed' The list of recently changed annotations.
|
||||
|
||||
`t' The union of recently added, deleted or changed annotations.
|
||||
t The union of recently added, deleted or changed annotations.
|
||||
|
||||
`nil' Just returns nil.
|
||||
nil Just returns nil.
|
||||
|
||||
Any other argument signals an error.")
|
||||
|
||||
@@ -258,8 +248,10 @@ no effect on the rendering.")
|
||||
"A list of standard icon properties for text annotations.")
|
||||
|
||||
(defvar pdf-annot-inhibit-modification-hooks nil
|
||||
"Non-nil, if running `pdf-annot-modified-functions' should be
|
||||
inhibited after some annotation has changed.")
|
||||
"Controls the behavior of `pdf-annot-modified-functions'.
|
||||
|
||||
If non-nil, `pdf-annot-modified-functions' are not run on any
|
||||
annotation change.")
|
||||
|
||||
(defvar-local pdf-annot-delayed-modified-annotations nil
|
||||
"A plist of not yet propagated modifications.
|
||||
@@ -294,25 +286,24 @@ current buffer, because that won't run the hooks properly."
|
||||
"The prefix to use for `pdf-annot-minor-mode-map'.
|
||||
|
||||
Setting this after the package was loaded has no effect."
|
||||
:group 'pdf-annot
|
||||
:type 'key-sequence)
|
||||
|
||||
(defvar pdf-annot-minor-mode-map
|
||||
(let ((kmap (make-sparse-keymap))
|
||||
(smap (make-sparse-keymap)))
|
||||
(define-key kmap pdf-annot-minor-mode-map-prefix smap)
|
||||
(define-key smap "l" 'pdf-annot-list-annotations)
|
||||
(define-key smap "l" #'pdf-annot-list-annotations)
|
||||
;; (define-key smap "d" 'pdf-annot-toggle-display-annotations)
|
||||
(define-key smap "a" 'pdf-annot-attachment-dired)
|
||||
(define-key smap "a" #'pdf-annot-attachment-dired)
|
||||
(when (pdf-info-writable-annotations-p)
|
||||
(define-key smap "D" 'pdf-annot-delete)
|
||||
(define-key smap "t" 'pdf-annot-add-text-annotation)
|
||||
(define-key smap "D" #'pdf-annot-delete)
|
||||
(define-key smap "t" #'pdf-annot-add-text-annotation)
|
||||
(when (pdf-info-markup-annotations-p)
|
||||
(define-key smap "m" 'pdf-annot-add-markup-annotation)
|
||||
(define-key smap "s" 'pdf-annot-add-squiggly-markup-annotation)
|
||||
(define-key smap "u" 'pdf-annot-add-underline-markup-annotation)
|
||||
(define-key smap "o" 'pdf-annot-add-strikeout-markup-annotation)
|
||||
(define-key smap "h" 'pdf-annot-add-highlight-markup-annotation)))
|
||||
(define-key smap "m" #'pdf-annot-add-markup-annotation)
|
||||
(define-key smap "s" #'pdf-annot-add-squiggly-markup-annotation)
|
||||
(define-key smap "u" #'pdf-annot-add-underline-markup-annotation)
|
||||
(define-key smap "o" #'pdf-annot-add-strikeout-markup-annotation)
|
||||
(define-key smap "h" #'pdf-annot-add-highlight-markup-annotation)))
|
||||
kmap)
|
||||
"Keymap used for `pdf-annot-minor-mode'.")
|
||||
|
||||
@@ -323,7 +314,7 @@ Setting this after the package was loaded has no effect."
|
||||
"Support for PDF Annotations.
|
||||
|
||||
\\{pdf-annot-minor-mode-map}"
|
||||
nil nil nil
|
||||
:group 'pdf-annot
|
||||
(cond
|
||||
(pdf-annot-minor-mode
|
||||
(when pdf-annot-tweak-tooltips
|
||||
@@ -332,14 +323,14 @@ Setting this after the package was loaded has no effect."
|
||||
(setq tooltip-hide-delay 3600))
|
||||
(pdf-view-add-hotspot-function 'pdf-annot-hotspot-function 9)
|
||||
(add-hook 'pdf-info-close-document-hook
|
||||
'pdf-annot-attachment-delete-base-directory nil t)
|
||||
#'pdf-annot-attachment-delete-base-directory nil t)
|
||||
(when (featurep 'savehist)
|
||||
(add-to-list 'savehist-minibuffer-history-variables
|
||||
'pdf-annot-color-history)))
|
||||
(t
|
||||
(pdf-view-remove-hotspot-function 'pdf-annot-hotspot-function)
|
||||
(remove-hook 'pdf-info-close-document-hook
|
||||
'pdf-annot-attachment-delete-base-directory t)))
|
||||
#'pdf-annot-attachment-delete-base-directory t)))
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
(defun pdf-annot-create-context-menu (a)
|
||||
@@ -386,41 +377,43 @@ Setting this after the package was loaded has no effect."
|
||||
menu))
|
||||
|
||||
(defun pdf-annot-create-color-submenu (a)
|
||||
"Show the user a color menu for their annotation A."
|
||||
(let ((menu (make-sparse-keymap)))
|
||||
(define-key menu [color-chooser]
|
||||
`(menu-item "Choose ..."
|
||||
,(lambda ()
|
||||
(interactive)
|
||||
(list-colors-display
|
||||
nil "*Choose annotation color*"
|
||||
;; list-colors-print does not like closures.
|
||||
(let ((callback (make-symbol "xcallback")))
|
||||
(fset callback
|
||||
(lambda (color)
|
||||
(pdf-annot-put a 'color color)
|
||||
(setq pdf-annot-color-history
|
||||
(cons color
|
||||
(remove color pdf-annot-color-history)))
|
||||
(quit-window t)))
|
||||
(list 'function callback))))))
|
||||
`(menu-item "Choose ..."
|
||||
,(lambda ()
|
||||
(interactive)
|
||||
(list-colors-display
|
||||
nil "*Choose annotation color*"
|
||||
;; list-colors-print does not like closures.
|
||||
(let ((callback (make-symbol "xcallback")))
|
||||
(fset callback
|
||||
(lambda (color)
|
||||
(pdf-annot-put a 'color color)
|
||||
(setq pdf-annot-color-history
|
||||
(cons color
|
||||
(remove color pdf-annot-color-history)))
|
||||
(quit-window t)))
|
||||
(list 'function callback))))))
|
||||
(dolist (color (butlast (reverse pdf-annot-color-history)
|
||||
(max 0 (- (length pdf-annot-color-history)
|
||||
12))))
|
||||
(define-key menu (vector (intern (format "color-%s" color)))
|
||||
`(menu-item ,color
|
||||
,(lambda nil
|
||||
(interactive)
|
||||
(pdf-annot-put a 'color color)))))
|
||||
`(menu-item ,color
|
||||
,(lambda nil
|
||||
(interactive)
|
||||
(pdf-annot-put a 'color color)))))
|
||||
menu))
|
||||
|
||||
(defun pdf-annot-create-icon-submenu (a)
|
||||
"Show the user an icon menu for the annotation A."
|
||||
(let ((menu (make-sparse-keymap)))
|
||||
(dolist (icon (reverse pdf-annot-standard-text-icons))
|
||||
(define-key menu (vector (intern (format "icon-%s" icon)))
|
||||
`(menu-item ,icon
|
||||
,(lambda nil
|
||||
(interactive)
|
||||
(pdf-annot-put a 'icon icon)))))
|
||||
`(menu-item ,icon
|
||||
,(lambda nil
|
||||
(interactive)
|
||||
(pdf-annot-put a 'icon icon)))))
|
||||
menu))
|
||||
|
||||
;; * ================================================================== *
|
||||
@@ -460,6 +453,10 @@ current buffer."
|
||||
result)))
|
||||
|
||||
(defun pdf-annot-getannot (id &optional buffer)
|
||||
"Return the annotation object for annotation ID.
|
||||
|
||||
Optionally take the BUFFER name of the PDF buffer. When none is
|
||||
provided, the `current-buffer' is picked up."
|
||||
(pdf-annot-create
|
||||
(pdf-info-getannot id buffer)
|
||||
buffer))
|
||||
@@ -540,7 +537,7 @@ the variable is nil and this function is called again."
|
||||
(run-hook-with-args
|
||||
'pdf-annot-modified-functions closure)
|
||||
(setq pdf-annot-delayed-modified-annotations nil)
|
||||
(apply 'pdf-view-redisplay-pages pages))))))
|
||||
(apply #'pdf-view-redisplay-pages pages))))))
|
||||
|
||||
(defun pdf-annot-equal (a1 a2)
|
||||
"Return non-nil, if annotations A1 and A2 are equal.
|
||||
@@ -593,14 +590,19 @@ This function always returns nil."
|
||||
nil)
|
||||
|
||||
(defun pdf-annot-text-annotation-p (a)
|
||||
"Return non-nil if annotation A is of type text."
|
||||
(eq 'text (pdf-annot-get a 'type)))
|
||||
|
||||
(defun pdf-annot-markup-annotation-p (a)
|
||||
"Return non-nil if annotation A is a known markup type.
|
||||
|
||||
Annotation types are defined in `pdf-annot-markup-annotation-types'."
|
||||
(not (null
|
||||
(memq (pdf-annot-get a 'type)
|
||||
pdf-annot-markup-annotation-types))))
|
||||
|
||||
(defun pdf-annot-property-modifiable-p (a property)
|
||||
"Return non-nil if PROPERTY for annotation A is editable."
|
||||
(or (memq property '(edges color flags contents))
|
||||
(and (pdf-annot-markup-annotation-p a)
|
||||
(memq property '(label opacity popup popup-is-open)))
|
||||
@@ -608,12 +610,18 @@ This function always returns nil."
|
||||
(memq property '(icon is-open)))))
|
||||
|
||||
(defun pdf-annot-activate-annotation (a)
|
||||
"Run handler functions on A to activate the annotation.
|
||||
|
||||
Activation functions are defined in `pdf-annot-activate-handler-functions'."
|
||||
(or (run-hook-with-args-until-success
|
||||
'pdf-annot-activate-handler-functions
|
||||
a)
|
||||
(pdf-annot-default-activate-handler a)))
|
||||
|
||||
(defun pdf-annot-default-activate-handler (a)
|
||||
"The default activation function to run on annotation A.
|
||||
|
||||
Activation functions are defined in `pdf-annot-activate-handler-functions'."
|
||||
(cond
|
||||
((pdf-annot-has-attachment-p a)
|
||||
(pdf-annot-pop-to-attachment a))
|
||||
@@ -678,7 +686,7 @@ The DO-SAVE argument is given to
|
||||
|
||||
|
||||
(defun pdf-annot-attachment-save (attachment &optional regenerate-p)
|
||||
"Save ATTACHMENT's data to a unique filename and return it's name.
|
||||
"Save ATTACHMENT's data to a unique filename and return its name.
|
||||
|
||||
If REGENERATE-P is non-nil, copy attachment's file even if the
|
||||
copy already exists.
|
||||
@@ -712,13 +720,13 @@ Signals an error, if A has no data attached."
|
||||
(delete-file tmpfile))))))
|
||||
|
||||
(defun pdf-annot-attachment-dired (&optional regenerate-p)
|
||||
"List all attachments in a dired buffer.
|
||||
"List all attachments in a Dired buffer.
|
||||
|
||||
If REGENERATE-P is non-nil, create attachment's files even if
|
||||
they already exist. Interactively REGENERATE-P is non-nil if a
|
||||
prefix argument was given.
|
||||
|
||||
Return the dired buffer."
|
||||
Return the Dired buffer."
|
||||
(interactive (list current-prefix-arg))
|
||||
(let ((attachments (pdf-info-getattachments t)))
|
||||
(unwind-protect
|
||||
@@ -850,7 +858,7 @@ Return nil, if no annotation was found."
|
||||
(setq window (posn-window pos)
|
||||
pos (posn-object-x-y pos)))
|
||||
(save-selected-window
|
||||
(when window (select-window window))
|
||||
(when window (select-window window 'norecord))
|
||||
(let* ((annots (pdf-annot-getannots (pdf-view-current-page)))
|
||||
(size (pdf-view-image-size))
|
||||
(rx (/ (car pos) (float (car size))))
|
||||
@@ -906,14 +914,16 @@ i.e. a non mouse-movement event is read."
|
||||
|
||||
(defun pdf-annot-hotspot-function (page size)
|
||||
"Create image hotspots for page PAGE of size SIZE."
|
||||
(apply 'nconc (mapcar (lambda (a)
|
||||
(unless (eq (pdf-annot-get a 'type)
|
||||
'link)
|
||||
(pdf-annot-create-hotspots a size)))
|
||||
(pdf-annot-getannots page))))
|
||||
(apply #'nconc (mapcar (lambda (a)
|
||||
(unless (eq (pdf-annot-get a 'type)
|
||||
'link)
|
||||
(pdf-annot-create-hotspots a size)))
|
||||
(pdf-annot-getannots page))))
|
||||
|
||||
(defun pdf-annot-create-hotspots (a size)
|
||||
"Return a list of image hotspots for annotation A."
|
||||
"Return a list of image hotspots for annotation A.
|
||||
|
||||
SIZE is a cons (SX . SY), by which edges are scaled."
|
||||
(let ((id (pdf-annot-get-id a))
|
||||
(edges (pdf-util-scale
|
||||
(pdf-annot-get-display-edges a)
|
||||
@@ -935,6 +945,11 @@ i.e. a non mouse-movement event is read."
|
||||
|
||||
;; FIXME: Define a keymap as a template for this. Much cleaner.
|
||||
(defun pdf-annot-create-hotspot-binding (id moveable-p annotation)
|
||||
"Create a local keymap for interacting with ANNOTATION using the mouse.
|
||||
|
||||
ID is the identifier for the ANNOTATION, as returned
|
||||
`pdf-annot-get-id'. MOVEABLE-P indicates whether the annotation
|
||||
is moveable."
|
||||
;; Activating
|
||||
(local-set-key
|
||||
(vector id 'mouse-1)
|
||||
@@ -968,7 +983,7 @@ If HIGHLIGHT-P is non-nil, visually distinguish annotation A from
|
||||
other annotations."
|
||||
|
||||
(save-selected-window
|
||||
(when window (select-window window))
|
||||
(when window (select-window window 'norecord))
|
||||
(pdf-util-assert-pdf-window)
|
||||
(let ((page (pdf-annot-get a 'page))
|
||||
(size (pdf-view-image-size)))
|
||||
@@ -982,7 +997,8 @@ other annotations."
|
||||
page (car size)
|
||||
`("white" "steel blue" 0.35 ,@edges))
|
||||
:map (pdf-view-apply-hotspot-functions
|
||||
window page size))))
|
||||
window page size)
|
||||
:width (car size))))
|
||||
(pdf-util-scroll-to-edges
|
||||
(pdf-util-scale-relative-to-pixel (car edges)))))))
|
||||
|
||||
@@ -998,7 +1014,7 @@ other annotations."
|
||||
;; * ================================================================== *
|
||||
|
||||
(defun pdf-annot-add-annotation (type edges &optional property-alist page)
|
||||
"Creates and adds a new annotation of type TYPE to the document.
|
||||
"Create and add a new annotation of type TYPE to the document.
|
||||
|
||||
TYPE determines the kind of annotation to add and maybe one of
|
||||
`text', `squiggly', `underline', `strike-out' or `highlight'.
|
||||
@@ -1037,7 +1053,7 @@ Return the new annotation."
|
||||
(when (and (eq type 'text)
|
||||
(> (length edges) 1))
|
||||
(error "Edges argument should be a single edge-list for text annotations"))
|
||||
(let* ((a (apply 'pdf-info-addannot
|
||||
(let* ((a (apply #'pdf-info-addannot
|
||||
page
|
||||
(if (eq type 'text)
|
||||
(car edges)
|
||||
@@ -1121,6 +1137,9 @@ Return the new annotation."
|
||||
`((color . ,(car pdf-annot-color-history))))))))
|
||||
|
||||
(defun pdf-annot-mouse-add-text-annotation (ev)
|
||||
"Add a text annotation using the mouse.
|
||||
|
||||
EV describes the captured mouse event."
|
||||
(interactive "@e")
|
||||
(pdf-annot-add-text-annotation
|
||||
(if (eq (car-safe ev)
|
||||
@@ -1174,7 +1193,9 @@ Return the new annotation."
|
||||
&optional color property-alist)
|
||||
"Add a new squiggly annotation in the selected window.
|
||||
|
||||
See also `pdf-annot-add-markup-annotation'."
|
||||
LIST-OF-EDGES defines the annotation boundary. COLOR defines the
|
||||
annotation color and PROPERTY-ALIST defines additional annotation
|
||||
properties. See also `pdf-annot-add-markup-annotation'."
|
||||
(interactive (list (pdf-view-active-region t)))
|
||||
(pdf-annot-add-markup-annotation list-of-edges 'squiggly color property-alist))
|
||||
|
||||
@@ -1182,7 +1203,9 @@ See also `pdf-annot-add-markup-annotation'."
|
||||
&optional color property-alist)
|
||||
"Add a new underline annotation in the selected window.
|
||||
|
||||
See also `pdf-annot-add-markup-annotation'."
|
||||
LIST-OF-EDGES defines the annotation boundary. COLOR defines the
|
||||
annotation color and PROPERTY-ALIST defines additional annotation
|
||||
properties. See also `pdf-annot-add-markup-annotation'."
|
||||
(interactive (list (pdf-view-active-region t)))
|
||||
(pdf-annot-add-markup-annotation list-of-edges 'underline color property-alist))
|
||||
|
||||
@@ -1190,7 +1213,9 @@ See also `pdf-annot-add-markup-annotation'."
|
||||
&optional color property-alist)
|
||||
"Add a new strike-out annotation in the selected window.
|
||||
|
||||
See also `pdf-annot-add-markup-annotation'."
|
||||
LIST-OF-EDGES defines the annotation boundary. COLOR defines the
|
||||
annotation color and PROPERTY-ALIST defines additional annotation
|
||||
properties. See also `pdf-annot-add-markup-annotation'."
|
||||
(interactive (list (pdf-view-active-region t)))
|
||||
(pdf-annot-add-markup-annotation list-of-edges 'strike-out color property-alist))
|
||||
|
||||
@@ -1198,7 +1223,9 @@ See also `pdf-annot-add-markup-annotation'."
|
||||
&optional color property-alist)
|
||||
"Add a new highlight annotation in the selected window.
|
||||
|
||||
See also `pdf-annot-add-markup-annotation'."
|
||||
LIST-OF-EDGES defines the annotation boundary. COLOR defines the
|
||||
annotation color and PROPERTY-ALIST defines additional annotation
|
||||
properties. See also `pdf-annot-add-markup-annotation'."
|
||||
(interactive (list (pdf-view-active-region t)))
|
||||
(pdf-annot-add-markup-annotation list-of-edges 'highlight color property-alist))
|
||||
|
||||
@@ -1236,7 +1263,7 @@ Suppresses successive duplicate entries of keys after the first
|
||||
occurrence in ALISTS."
|
||||
|
||||
(let (merged)
|
||||
(dolist (elt (apply 'append alists))
|
||||
(dolist (elt (apply #'append alists))
|
||||
(unless (assq (car elt) merged)
|
||||
(push elt merged)))
|
||||
(nreverse merged)))
|
||||
@@ -1300,7 +1327,7 @@ property."
|
||||
(t
|
||||
(format "%s"
|
||||
(mapconcat
|
||||
'identity
|
||||
#'identity
|
||||
(mapcar
|
||||
(lambda (property)
|
||||
(pdf-annot-print-property
|
||||
@@ -1340,6 +1367,13 @@ by a header."
|
||||
"pdf-annot-print-annotation-latex%s%s%s"
|
||||
page header contents)))
|
||||
(data (pdf-cache-lookup-image page 0 nil hash))
|
||||
;; pdf-tools can only work with png files, so this
|
||||
;; binding ensures that pdf-tools can print the
|
||||
;; latex-preview regardless of the user
|
||||
;; configuration.
|
||||
(org-preview-latex-default-process 'dvipng)
|
||||
;; For backward compatibility with emacs-version < 26.1
|
||||
(org-latex-create-formula-image-program 'dvipng)
|
||||
(org-format-latex-header
|
||||
pdf-annot-latex-header)
|
||||
(temporary-file-directory
|
||||
@@ -1399,8 +1433,7 @@ is about to be edited in this buffer.
|
||||
|
||||
The default value turns on `latex-mode' if
|
||||
`pdf-annot-latex-string-predicate' returns non-nil on the
|
||||
annotation's contents and otherwise `text-mode'. "
|
||||
:group 'pdf-annot
|
||||
annotation's contents and otherwise `text-mode'."
|
||||
:type 'function)
|
||||
|
||||
(defcustom pdf-annot-edit-contents-display-buffer-action
|
||||
@@ -1409,19 +1442,18 @@ annotation's contents and otherwise `text-mode'. "
|
||||
(inhibit-same-window . t)
|
||||
(window-height . 0.25))
|
||||
"Display action when showing the edit buffer."
|
||||
:group 'pdf-annot
|
||||
:type display-buffer--action-custom-type)
|
||||
|
||||
(defvar pdf-annot-edit-contents-minor-mode-map
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(set-keymap-parent kmap text-mode-map)
|
||||
(define-key kmap (kbd "C-c C-c") 'pdf-annot-edit-contents-commit)
|
||||
(define-key kmap (kbd "C-c C-q") 'pdf-annot-edit-contents-abort)
|
||||
(define-key kmap (kbd "C-c C-c") #'pdf-annot-edit-contents-commit)
|
||||
(define-key kmap (kbd "C-c C-q") #'pdf-annot-edit-contents-abort)
|
||||
kmap))
|
||||
|
||||
(define-minor-mode pdf-annot-edit-contents-minor-mode
|
||||
"Active when editing the contents of annotations."
|
||||
nil nil nil
|
||||
:group 'pdf-annot
|
||||
(when pdf-annot-edit-contents-minor-mode
|
||||
(message "%s"
|
||||
(substitute-command-keys
|
||||
@@ -1429,8 +1461,15 @@ annotation's contents and otherwise `text-mode'. "
|
||||
|
||||
(put 'pdf-annot-edit-contents-minor-mode 'permanent-local t)
|
||||
|
||||
;; FIXME: Document pdf-annot-edit-* functions below.
|
||||
(defun pdf-annot-edit-contents-finalize (do-save &optional do-kill)
|
||||
"Finalize edit-operations on an Annotation.
|
||||
|
||||
If DO-SAVE is t, save the changes to annotation content without
|
||||
asking. If DO-SAVE is 'ask, check if the user if contents should
|
||||
be saved.
|
||||
|
||||
If DO-KILL is t, kill all windows displaying the annotation
|
||||
contents. Else just bury the buffers."
|
||||
(when (buffer-modified-p)
|
||||
(cond
|
||||
((eq do-save 'ask)
|
||||
@@ -1445,6 +1484,7 @@ annotation's contents and otherwise `text-mode'. "
|
||||
(quit-window do-kill win)))
|
||||
|
||||
(defun pdf-annot-edit-contents-save-annotation ()
|
||||
"Internal function to save the contents of the annotation under editing."
|
||||
(when pdf-annot-edit-contents--annotation
|
||||
(pdf-annot-put pdf-annot-edit-contents--annotation
|
||||
'contents
|
||||
@@ -1452,14 +1492,19 @@ annotation's contents and otherwise `text-mode'. "
|
||||
(set-buffer-modified-p nil)))
|
||||
|
||||
(defun pdf-annot-edit-contents-commit ()
|
||||
"Save the change made to the current annotation."
|
||||
(interactive)
|
||||
(pdf-annot-edit-contents-finalize t))
|
||||
|
||||
(defun pdf-annot-edit-contents-abort ()
|
||||
"Abort the change made to the current annotation."
|
||||
(interactive)
|
||||
(pdf-annot-edit-contents-finalize nil t))
|
||||
|
||||
(defun pdf-annot-edit-contents-noselect (a)
|
||||
"Internal function to setup all prerequisites for editing annotation A.
|
||||
|
||||
At any given point of time, only one annotation can be in edit mode."
|
||||
(with-current-buffer (pdf-annot-get-buffer a)
|
||||
(when (and (buffer-live-p pdf-annot-edit-contents--buffer)
|
||||
(not (eq a pdf-annot-edit-contents--annotation)))
|
||||
@@ -1482,12 +1527,14 @@ annotation's contents and otherwise `text-mode'. "
|
||||
(current-buffer))))
|
||||
|
||||
(defun pdf-annot-edit-contents (a)
|
||||
"Edit the contents of annotation A."
|
||||
(select-window
|
||||
(display-buffer
|
||||
(pdf-annot-edit-contents-noselect a)
|
||||
pdf-annot-edit-contents-display-buffer-action)))
|
||||
|
||||
(defun pdf-annot-edit-contents-mouse (ev)
|
||||
"Edit the contents of the annotation described by mouse event EV."
|
||||
(interactive "@e")
|
||||
(let* ((pos (posn-object-x-y (event-start ev)))
|
||||
(a (and pos (pdf-annot-at-position pos))))
|
||||
@@ -1506,7 +1553,6 @@ annotation's contents and otherwise `text-mode'. "
|
||||
display-buffer-pop-up-window)
|
||||
(inhibit-same-window . t))
|
||||
"Display action used when displaying the list buffer."
|
||||
:group 'pdf-annot
|
||||
:type display-buffer--action-custom-type)
|
||||
|
||||
(defcustom pdf-annot-list-format
|
||||
@@ -1526,12 +1572,10 @@ Currently supported properties are page, type, label, date and contents."
|
||||
(type (integer :value 10 :tag "Column Width" ))
|
||||
(label (integer :value 24 :tag "Column Width"))
|
||||
(date (integer :value 24 :tag "Column Width"))
|
||||
(contents (integer :value 56 :tag "Column Width")))
|
||||
:group 'pdf-annot)
|
||||
(contents (integer :value 56 :tag "Column Width"))))
|
||||
|
||||
(defcustom pdf-annot-list-highlight-type nil
|
||||
"Whether to highlight \"Type\" column annotation list with annotation color."
|
||||
:group 'pdf-annot
|
||||
:type 'boolean)
|
||||
|
||||
(defvar-local pdf-annot-list-buffer nil)
|
||||
@@ -1540,8 +1584,8 @@ Currently supported properties are page, type, label, date and contents."
|
||||
|
||||
(defvar pdf-annot-list-mode-map
|
||||
(let ((km (make-sparse-keymap)))
|
||||
(define-key km (kbd "C-c C-f") 'pdf-annot-list-follow-minor-mode)
|
||||
(define-key km (kbd "SPC") 'pdf-annot-list-display-annotation-from-id)
|
||||
(define-key km (kbd "C-c C-f") #'pdf-annot-list-follow-minor-mode)
|
||||
(define-key km (kbd "SPC") #'pdf-annot-list-display-annotation-from-id)
|
||||
km))
|
||||
|
||||
(defun pdf-annot-property-completions (property)
|
||||
@@ -1573,14 +1617,19 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(<= e1-left e2-left)))))))))
|
||||
|
||||
(defun pdf-annot-list-entries ()
|
||||
"Return all the annotations of this PDF buffer as a `tabulated-list'."
|
||||
(unless (buffer-live-p pdf-annot-list-document-buffer)
|
||||
(error "No PDF document associated with this buffer"))
|
||||
(mapcar 'pdf-annot-list-create-entry
|
||||
(mapcar #'pdf-annot-list-create-entry
|
||||
(sort (pdf-annot-getannots nil pdf-annot-list-listed-types
|
||||
pdf-annot-list-document-buffer)
|
||||
'pdf-annot-compare-annotations)))
|
||||
#'pdf-annot-compare-annotations)))
|
||||
|
||||
(defun pdf-annot--make-entry-formatter (a)
|
||||
"Return a formatter function for annotation A.
|
||||
|
||||
A formatter function takes a format cons-cell and returns
|
||||
pretty-printed output."
|
||||
(lambda (fmt)
|
||||
(let ((entry-type (car fmt))
|
||||
(entry-width (cdr fmt))
|
||||
@@ -1609,7 +1658,7 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(propertize
|
||||
type 'face
|
||||
`(:background ,color
|
||||
:foreground ,(funcall contrasty-color color)))
|
||||
:foreground ,(funcall contrasty-color color)))
|
||||
type)))))))
|
||||
|
||||
(defun pdf-annot-list-create-entry (a)
|
||||
@@ -1647,7 +1696,7 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(tabulated-list-init-header))
|
||||
|
||||
(defun pdf-annot-list-annotations ()
|
||||
"List annotations in a dired like buffer.
|
||||
"List annotations in a Dired like buffer.
|
||||
|
||||
\\{pdf-annot-list-mode-map}"
|
||||
(interactive)
|
||||
@@ -1664,7 +1713,7 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(tabulated-list-print)
|
||||
(setq tablist-context-window-function
|
||||
(lambda (id) (pdf-annot-list-context-function id buffer))
|
||||
tablist-operations-function 'pdf-annot-list-operation-function)
|
||||
tablist-operations-function #'pdf-annot-list-operation-function)
|
||||
(let ((list-buffer (current-buffer)))
|
||||
(with-current-buffer buffer
|
||||
(setq pdf-annot-list-buffer list-buffer))))
|
||||
@@ -1675,11 +1724,14 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(tablist-move-to-major-column)
|
||||
(tablist-display-context-window))
|
||||
(add-hook 'pdf-info-close-document-hook
|
||||
'pdf-annot-list-update nil t)
|
||||
#'pdf-annot-list-update nil t)
|
||||
(add-hook 'pdf-annot-modified-functions
|
||||
'pdf-annot-list-update nil t)))
|
||||
#'pdf-annot-list-update nil t)))
|
||||
|
||||
(defun pdf-annot-list-goto-annotation (a)
|
||||
"List all the annotations in the current buffer.
|
||||
|
||||
Goto the annotation A in the list."
|
||||
(with-current-buffer (pdf-annot-get-buffer a)
|
||||
(unless (and (buffer-live-p pdf-annot-list-buffer)
|
||||
(get-buffer-window pdf-annot-list-buffer))
|
||||
@@ -1698,6 +1750,9 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
|
||||
|
||||
(defun pdf-annot-list-update (&optional _fn)
|
||||
"Update the list of annotations on any change.
|
||||
|
||||
This is an internal function which runs as a hook in various situations."
|
||||
(when (buffer-live-p pdf-annot-list-buffer)
|
||||
(with-current-buffer pdf-annot-list-buffer
|
||||
(unless tablist-edit-column-minor-mode
|
||||
@@ -1705,6 +1760,10 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(tablist-context-window-update))))
|
||||
|
||||
(defun pdf-annot-list-context-function (id buffer)
|
||||
"Show the contents of an Annotation.
|
||||
|
||||
For an annotation identified by ID, belonging to PDF in BUFFER,
|
||||
get the contents and display them on demand."
|
||||
(with-current-buffer (get-buffer-create "*Contents*")
|
||||
(set-window-buffer nil (current-buffer))
|
||||
(let ((inhibit-read-only t))
|
||||
@@ -1717,6 +1776,12 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(read-only-mode 1))))
|
||||
|
||||
(defun pdf-annot-list-operation-function (op &rest args)
|
||||
"Define bulk operations in Annotation list buffer.
|
||||
|
||||
OP is the operation that the user wants to execute. Supported
|
||||
operations are `delete' and `find-entry'.
|
||||
|
||||
ARGS contain the annotation-ids to operate on."
|
||||
(cl-ecase op
|
||||
(supported-operations '(delete find-entry))
|
||||
(delete
|
||||
@@ -1725,7 +1790,7 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(when (buffer-live-p pdf-annot-list-document-buffer)
|
||||
(with-current-buffer pdf-annot-list-document-buffer
|
||||
(pdf-annot-with-atomic-modifications
|
||||
(dolist (a (mapcar 'pdf-annot-getannot ids))
|
||||
(dolist (a (mapcar #'pdf-annot-getannot ids))
|
||||
(pdf-annot-delete a)))))))
|
||||
(find-entry
|
||||
(cl-destructuring-bind (id)
|
||||
@@ -1752,6 +1817,10 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(defvar pdf-annot-list-display-annotation--timer nil)
|
||||
|
||||
(defun pdf-annot-list-display-annotation-from-id (id)
|
||||
"Display the Annotation ID in the PDF file.
|
||||
|
||||
This allows us to follow the tabulated-list of annotations and
|
||||
have the PDF buffer automatically move along with us."
|
||||
(interactive (list (tabulated-list-get-id)))
|
||||
(when id
|
||||
(unless (buffer-live-p pdf-annot-list-document-buffer)
|
||||
@@ -1772,19 +1841,20 @@ belong to the same page and A1 is displayed above/left of A2."
|
||||
(pdf-annot-getannot id pdf-annot-list-document-buffer)))))
|
||||
|
||||
(define-minor-mode pdf-annot-list-follow-minor-mode
|
||||
"" nil nil nil
|
||||
"Make the PDF follow the annotations in the list buffer."
|
||||
:group 'pdf-annot
|
||||
(unless (derived-mode-p 'pdf-annot-list-mode)
|
||||
(error "No in pdf-annot-list-mode."))
|
||||
(error "Not in pdf-annot-list-mode"))
|
||||
(cond
|
||||
(pdf-annot-list-follow-minor-mode
|
||||
(add-hook 'tablist-selection-changed-functions
|
||||
'pdf-annot-list-display-annotation-from-id nil t)
|
||||
#'pdf-annot-list-display-annotation-from-id nil t)
|
||||
(let ((id (tabulated-list-get-id)))
|
||||
(when id
|
||||
(pdf-annot-list-display-annotation-from-id id))))
|
||||
(t
|
||||
(remove-hook 'tablist-selection-changed-functions
|
||||
'pdf-annot-list-display-annotation-from-id t))))
|
||||
#'pdf-annot-list-display-annotation-from-id t))))
|
||||
|
||||
(provide 'pdf-annot)
|
||||
;;; pdf-annot.el ends here
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
;;; Code:
|
||||
;;
|
||||
|
||||
(require 'pdf-macs)
|
||||
(require 'pdf-info)
|
||||
(require 'pdf-util)
|
||||
|
||||
@@ -62,15 +63,25 @@ be prefetched and their order."
|
||||
(defvar pdf-annot-modified-functions)
|
||||
|
||||
(defun pdf-cache--initialize ()
|
||||
"Initialize the cache to store document data.
|
||||
|
||||
Note: The cache is only initialized once. After that it needs to
|
||||
be cleared before this function makes any changes to it. This is
|
||||
an internal function and not meant to be directly used."
|
||||
(unless pdf-cache--data
|
||||
(setq pdf-cache--data (make-hash-table))
|
||||
(add-hook 'pdf-info-close-document-hook 'pdf-cache-clear-data nil t)
|
||||
(add-hook 'pdf-info-close-document-hook #'pdf-cache-clear-data nil t)
|
||||
(add-hook 'pdf-annot-modified-functions
|
||||
'pdf-cache--clear-data-of-annotations
|
||||
#'pdf-cache--clear-data-of-annotations
|
||||
nil t)))
|
||||
|
||||
(defun pdf-cache--clear-data-of-annotations (fn)
|
||||
(apply 'pdf-cache-clear-data-of-pages
|
||||
"Clear the data cache when annotations are modified.
|
||||
|
||||
FN is a closure as described in `pdf-annot-modified-functions'.
|
||||
|
||||
Note: This is an internal function and not meant to be directly used."
|
||||
(apply #'pdf-cache-clear-data-of-pages
|
||||
(mapcar (lambda (a)
|
||||
(cdr (assq 'page a)))
|
||||
(funcall fn t))))
|
||||
@@ -89,7 +100,7 @@ be prefetched and their order."
|
||||
"Get value of KEY in the cache of PAGE.
|
||||
|
||||
Returns a cons \(HIT . VALUE\), where HIT is non-nil if KEY was
|
||||
stored previously for PAGE and VALUE it's value. Otherwise HIT
|
||||
stored previously for PAGE and VALUE its value. Otherwise HIT
|
||||
is nil and VALUE undefined."
|
||||
(pdf-cache--initialize)
|
||||
(let ((elt (assq key (gethash page pdf-cache--data))))
|
||||
@@ -98,6 +109,7 @@ is nil and VALUE undefined."
|
||||
(cons nil nil))))
|
||||
|
||||
(defun pdf-cache--data-clear (key &optional page)
|
||||
"Remove KEY from the cache of PAGE."
|
||||
(pdf-cache--initialize)
|
||||
(puthash page
|
||||
(assq-delete-all key (gethash page pdf-cache--data))
|
||||
@@ -105,11 +117,13 @@ is nil and VALUE undefined."
|
||||
nil)
|
||||
|
||||
(defun pdf-cache-clear-data-of-pages (&rest pages)
|
||||
"Remove all PAGES from the cache."
|
||||
(when pdf-cache--data
|
||||
(dolist (page pages)
|
||||
(remhash page pdf-cache--data))))
|
||||
|
||||
(defun pdf-cache-clear-data ()
|
||||
"Remove the entire cache."
|
||||
(interactive)
|
||||
(when pdf-cache--data
|
||||
(clrhash pdf-cache--data)))
|
||||
@@ -130,7 +144,7 @@ Both args are unevaluated."
|
||||
(ifn (intern (format "pdf-info-%s" command)))
|
||||
(doc (format "Cached version of `pdf-info-%s', which see.
|
||||
|
||||
Make sure, not to modify it's return value." command)))
|
||||
Make sure, not to modify its return value." command)))
|
||||
`(defun ,fn ,args
|
||||
,doc
|
||||
(let ((hit-value (pdf-cache--data-get ',command ,(if page-arg-p 'page))))
|
||||
@@ -161,19 +175,30 @@ Make sure, not to modify it's return value." command)))
|
||||
(defvar-local pdf-cache--image-cache nil)
|
||||
|
||||
(defmacro pdf-cache--make-image (page width data hash)
|
||||
"Make the image that we store in the image cache.
|
||||
|
||||
An image is a tuple of PAGE WIDTH DATA HASH."
|
||||
`(list ,page ,width ,data ,hash))
|
||||
(defmacro pdf-cache--image/page (img) `(nth 0 ,img))
|
||||
(defmacro pdf-cache--image/width (img) `(nth 1 ,img))
|
||||
(defmacro pdf-cache--image/data (img) `(nth 2 ,img))
|
||||
(defmacro pdf-cache--image/hash (img) `(nth 3 ,img))
|
||||
(defmacro pdf-cache--image/page (img)
|
||||
"Return the page value for IMG."
|
||||
`(nth 0 ,img))
|
||||
(defmacro pdf-cache--image/width (img)
|
||||
"Return the width value for IMG."
|
||||
`(nth 1 ,img))
|
||||
(defmacro pdf-cache--image/data (img)
|
||||
"Return the data value for IMG."
|
||||
`(nth 2 ,img))
|
||||
(defmacro pdf-cache--image/hash (img)
|
||||
"Return the hash value for IMG."
|
||||
`(nth 3 ,img))
|
||||
|
||||
(defun pdf-cache--image-match (image page min-width &optional max-width hash)
|
||||
"Match IMAGE with specs.
|
||||
|
||||
IMAGE should be a list as created by `pdf-cache--make-image'.
|
||||
|
||||
Return non-nil, if IMAGE's page is the same as PAGE, it's width
|
||||
is at least MIN-WIDTH and at most MAX-WIDTH and it's stored
|
||||
Return non-nil, if IMAGE's page is the same as PAGE, its width
|
||||
is at least MIN-WIDTH and at most MAX-WIDTH and its stored
|
||||
hash-value is `eql' to HASH."
|
||||
(and (= (pdf-cache--image/page image)
|
||||
page)
|
||||
@@ -189,12 +214,15 @@ hash-value is `eql' to HASH."
|
||||
(defun pdf-cache-lookup-image (page min-width &optional max-width hash)
|
||||
"Return PAGE's cached PNG data as a string or nil.
|
||||
|
||||
Return an image of at least MIN-WIDTH and, if non-nil, maximum
|
||||
width MAX-WIDTH and `eql' HASH value.
|
||||
|
||||
Does not modify the cache. See also `pdf-cache-get-image'."
|
||||
(let ((image (car (cl-member
|
||||
(list page min-width max-width hash)
|
||||
pdf-cache--image-cache
|
||||
:test (lambda (spec image)
|
||||
(apply 'pdf-cache--image-match image spec))))))
|
||||
(apply #'pdf-cache--image-match image spec))))))
|
||||
(and image
|
||||
(pdf-cache--image/data image))))
|
||||
|
||||
@@ -202,7 +230,7 @@ Does not modify the cache. See also `pdf-cache-get-image'."
|
||||
"Return PAGE's PNG data as a string.
|
||||
|
||||
Return an image of at least MIN-WIDTH and, if non-nil, maximum
|
||||
width MAX-WIDTH and `eql' hash value.
|
||||
width MAX-WIDTH and `eql' HASH value.
|
||||
|
||||
Remember that image was recently used.
|
||||
|
||||
@@ -228,9 +256,9 @@ the HASH argument.
|
||||
|
||||
This function always returns nil."
|
||||
(unless pdf-cache--image-cache
|
||||
(add-hook 'pdf-info-close-document-hook 'pdf-cache-clear-images nil t)
|
||||
(add-hook 'pdf-info-close-document-hook #'pdf-cache-clear-images nil t)
|
||||
(add-hook 'pdf-annot-modified-functions
|
||||
'pdf-cache--clear-images-of-annotations nil t))
|
||||
#'pdf-cache--clear-images-of-annotations nil t))
|
||||
(push (pdf-cache--make-image page width data hash)
|
||||
pdf-cache--image-cache)
|
||||
;; Forget old image(s).
|
||||
@@ -266,19 +294,25 @@ from the cache."
|
||||
|
||||
|
||||
(defun pdf-cache--clear-images-of-annotations (fn)
|
||||
(apply 'pdf-cache-clear-images-of-pages
|
||||
"Clear the images cache when annotations are modified.
|
||||
|
||||
FN is a closure as described in `pdf-annot-modified-functions'.
|
||||
|
||||
Note: This is an internal function and not meant to be directly used."
|
||||
(apply #'pdf-cache-clear-images-of-pages
|
||||
(mapcar (lambda (a)
|
||||
(cdr (assq 'page a)))
|
||||
(funcall fn t))))
|
||||
|
||||
(defun pdf-cache-clear-images-of-pages (&rest pages)
|
||||
"Remove all images of PAGES from the image cache."
|
||||
(pdf-cache-clear-images-if
|
||||
(lambda (page &rest _) (memq page pages))))
|
||||
|
||||
(defun pdf-cache-renderpage (page min-width &optional max-width)
|
||||
"Render PAGE according to MIN-WIDTH and MAX-WIDTH.
|
||||
|
||||
Return the PNG data of an image as a string, such that it's width
|
||||
Return the PNG data of an image as a string, such that its width
|
||||
is at least MIN-WIDTH and, if non-nil, at most MAX-WIDTH.
|
||||
|
||||
If such an image is not available in the cache, call
|
||||
@@ -297,13 +331,13 @@ If such an image is not available in the cache, call
|
||||
See also `pdf-info-renderpage-text-regions' and
|
||||
`pdf-cache-renderpage'."
|
||||
(if pdf-cache-image-inihibit
|
||||
(apply 'pdf-info-renderpage-text-regions
|
||||
(apply #'pdf-info-renderpage-text-regions
|
||||
page width single-line-p nil selection)
|
||||
(let ((hash (sxhash
|
||||
(format "%S" (cons 'renderpage-text-regions
|
||||
(cons single-line-p selection))))))
|
||||
(or (pdf-cache-get-image page width width hash)
|
||||
(let ((data (apply 'pdf-info-renderpage-text-regions
|
||||
(let ((data (apply #'pdf-info-renderpage-text-regions
|
||||
page width single-line-p nil selection)))
|
||||
(pdf-cache-put-image page width data hash)
|
||||
data)))))
|
||||
@@ -314,13 +348,13 @@ See also `pdf-info-renderpage-text-regions' and
|
||||
See also `pdf-info-renderpage-highlight' and
|
||||
`pdf-cache-renderpage'."
|
||||
(if pdf-cache-image-inihibit
|
||||
(apply 'pdf-info-renderpage-highlight
|
||||
(apply #'pdf-info-renderpage-highlight
|
||||
page width nil regions)
|
||||
(let ((hash (sxhash
|
||||
(format "%S" (cons 'renderpage-highlight
|
||||
regions)))))
|
||||
(or (pdf-cache-get-image page width width hash)
|
||||
(let ((data (apply 'pdf-info-renderpage-highlight
|
||||
(let ((data (apply #'pdf-info-renderpage-highlight
|
||||
page width nil regions)))
|
||||
(pdf-cache-put-image page width data hash)
|
||||
data)))))
|
||||
@@ -338,21 +372,25 @@ See also `pdf-info-renderpage-highlight' and
|
||||
|
||||
(define-minor-mode pdf-cache-prefetch-minor-mode
|
||||
"Try to load images which will probably be needed in a while."
|
||||
nil nil nil
|
||||
:group 'pdf-cache
|
||||
(pdf-cache--prefetch-cancel)
|
||||
(cond
|
||||
(pdf-cache-prefetch-minor-mode
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(add-hook 'pre-command-hook 'pdf-cache--prefetch-stop nil t)
|
||||
;; FIXME: Disable the time when the buffer is killed or it's
|
||||
(add-hook 'pre-command-hook #'pdf-cache--prefetch-stop nil t)
|
||||
;; FIXME: Disable the time when the buffer is killed or its
|
||||
;; major-mode changes.
|
||||
(setq pdf-cache--prefetch-timer
|
||||
(run-with-idle-timer (or pdf-cache-prefetch-delay 1)
|
||||
t 'pdf-cache--prefetch-start (current-buffer))))
|
||||
(run-with-idle-timer (or pdf-cache-prefetch-delay 1) t
|
||||
#'pdf-cache--prefetch-start (current-buffer))))
|
||||
(t
|
||||
(remove-hook 'pre-command-hook 'pdf-cache--prefetch-stop t))))
|
||||
(remove-hook 'pre-command-hook #'pdf-cache--prefetch-stop t))))
|
||||
|
||||
(defun pdf-cache-prefetch-pages-function-default ()
|
||||
"The default function to prefetch pages.
|
||||
|
||||
See `pdf-cache-prefetch-pages-function' for an explanation of
|
||||
what this function does."
|
||||
(let ((page (pdf-view-current-page)))
|
||||
(pdf-util-remove-duplicates
|
||||
(cl-remove-if-not
|
||||
@@ -379,7 +417,11 @@ See also `pdf-info-renderpage-highlight' and
|
||||
(pdf-cache-pagelinks
|
||||
(pdf-view-current-page)))))))))
|
||||
|
||||
(defvar pdf-view-use-scaling)
|
||||
(defun pdf-cache--prefetch-pages (window image-width)
|
||||
"Internal function to prefetch pages and store them in the cache.
|
||||
|
||||
WINDOW and IMAGE-WIDTH decide the page and scale of the final image."
|
||||
(when (and (eq window (selected-window))
|
||||
(pdf-util-pdf-buffer-p))
|
||||
(let ((page (pop pdf-cache--prefetch-pages)))
|
||||
@@ -387,7 +429,7 @@ See also `pdf-info-renderpage-highlight' and
|
||||
(pdf-cache-lookup-image
|
||||
page
|
||||
image-width
|
||||
(if (not (pdf-view-use-scaling-p))
|
||||
(if (not pdf-view-use-scaling)
|
||||
image-width
|
||||
(* 2 image-width))))
|
||||
(setq page (pop pdf-cache--prefetch-pages)))
|
||||
@@ -411,7 +453,8 @@ See also `pdf-info-renderpage-highlight' and
|
||||
(message "Prefetched page %s." page))
|
||||
;; Avoid max-lisp-eval-depth
|
||||
(run-with-timer
|
||||
0.001 nil 'pdf-cache--prefetch-pages window image-width)))))))
|
||||
0.001 nil
|
||||
#'pdf-cache--prefetch-pages window image-width)))))))
|
||||
(condition-case err
|
||||
(pdf-info-renderpage page image-width)
|
||||
(error
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(file-name-directory load-file-name))))
|
||||
|
||||
(defun pdf-dev-reload ()
|
||||
"Reload lisp files from source."
|
||||
"Reload Lisp files from source."
|
||||
(interactive)
|
||||
(let ((default-directory (expand-file-name
|
||||
"lisp"
|
||||
@@ -53,8 +53,8 @@ Quits the server and sets `pdf-info-epdfinfo-program' to
|
||||
Installs a `compilation-finish-functions' which will restart
|
||||
epdfinfo after a successful recompilation.
|
||||
|
||||
Sets up `load-path' and reloads all PDF Tools lisp files."
|
||||
nil nil nil
|
||||
Sets up `load-path' and reloads all PDF Tools Lisp files."
|
||||
:group 'pdf-dev
|
||||
(let ((lisp-dir (expand-file-name "lisp" pdf-dev-root-directory)))
|
||||
(setq load-path (remove lisp-dir load-path))
|
||||
(cond
|
||||
@@ -71,6 +71,10 @@ Sets up `load-path' and reloads all PDF Tools lisp files."
|
||||
(remove-hook 'compilation-finish-functions 'pdf-dev-compilation-finished)))))
|
||||
|
||||
(defun pdf-dev-compilation-finished (buffer status)
|
||||
"Restart the epdfinfo server.
|
||||
|
||||
BUFFER is the PDF buffer and STATUS is the compilation status of
|
||||
building epdfinfo."
|
||||
(with-current-buffer buffer
|
||||
(when (and (equal status "finished\n")
|
||||
(file-equal-p
|
||||
|
||||
@@ -38,8 +38,10 @@
|
||||
|
||||
(defvar pdf-history-minor-mode-map
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(define-key kmap (kbd "B") 'pdf-history-backward)
|
||||
(define-key kmap (kbd "N") 'pdf-history-forward)
|
||||
(define-key kmap (kbd "B") #'pdf-history-backward)
|
||||
(define-key kmap (kbd "N") #'pdf-history-forward)
|
||||
(define-key kmap (kbd "l") #'pdf-history-backward)
|
||||
(define-key kmap (kbd "r") #'pdf-history-forward)
|
||||
kmap)
|
||||
"Keymap used in `pdf-history-minor-mode'.")
|
||||
|
||||
@@ -52,17 +54,17 @@ following a link pushes the left-behind page on the stack, which
|
||||
may be navigated with the following keys.
|
||||
|
||||
\\{pdf-history-minor-mode-map}"
|
||||
nil nil nil
|
||||
:group 'pdf-history
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(pdf-history-clear)
|
||||
(cond
|
||||
(pdf-history-minor-mode
|
||||
(pdf-history-push)
|
||||
(add-hook 'pdf-view-after-change-page-hook
|
||||
'pdf-history-before-change-page-hook nil t))
|
||||
#'pdf-history-before-change-page-hook nil t))
|
||||
(t
|
||||
(remove-hook 'pdf-view-after-change-page-hook
|
||||
'pdf-history-before-change-page-hook t))))
|
||||
#'pdf-history-before-change-page-hook t))))
|
||||
|
||||
(defun pdf-history-before-change-page-hook ()
|
||||
"Push a history item, before leaving this page."
|
||||
@@ -110,7 +112,7 @@ represents the current page."
|
||||
(1- (length pdf-history-stack))))
|
||||
|
||||
(defun pdf-history-backward (n)
|
||||
"Go N-times backward in the history."
|
||||
"Go N times backward in the history."
|
||||
(interactive "p")
|
||||
(cond
|
||||
((and (> n 0)
|
||||
@@ -128,7 +130,7 @@ represents the current page."
|
||||
(t 0)))
|
||||
|
||||
(defun pdf-history-forward (n)
|
||||
"Go N-times forward in the history."
|
||||
"Go N times forward in the history."
|
||||
(interactive "p")
|
||||
(pdf-history-backward (- n)))
|
||||
|
||||
|
||||
@@ -85,14 +85,12 @@
|
||||
;; Fall back to epdfinfo in the directory of this file.
|
||||
(expand-file-name executable))))
|
||||
"Filename of the epdfinfo executable."
|
||||
:group 'pdf-info
|
||||
:type 'file)
|
||||
|
||||
(defcustom pdf-info-epdfinfo-error-filename nil
|
||||
"Filename for error output of the epdfinfo executable.
|
||||
|
||||
If nil, discard any error messages. Useful for debugging."
|
||||
:group 'pdf-info
|
||||
:type `(choice (const :tag "None" nil)
|
||||
,@(when (file-directory-p "/tmp/")
|
||||
'((const "/tmp/epdfinfo.log")))
|
||||
@@ -103,14 +101,12 @@ If nil, discard any error messages. Useful for debugging."
|
||||
|
||||
If this is non-nil, all communication with the epdfinfo program
|
||||
will be logged to the buffer \"*pdf-info-log*\"."
|
||||
:group 'pdf-info
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-info-log-entry-max 512
|
||||
"Maximum number of characters in a single log entry.
|
||||
|
||||
This variable has no effect if `pdf-info-log' is nil."
|
||||
:group 'pdf-info
|
||||
:type 'integer)
|
||||
|
||||
(defcustom pdf-info-restart-process-p 'ask
|
||||
@@ -123,7 +119,6 @@ ask -- ask whether to restart or not.
|
||||
|
||||
If it is `ask', the server quits and you answer no, this variable
|
||||
is set to nil."
|
||||
:group 'pdf-info
|
||||
:type '(choice (const :tag "Do nothing" nil)
|
||||
(const :tag "Restart silently" t)
|
||||
(const :tag "Always ask" ask)))
|
||||
@@ -133,7 +128,6 @@ is set to nil."
|
||||
|
||||
The hook is run in the documents buffer, if it exists. Otherwise
|
||||
in a `with-temp-buffer' form."
|
||||
:group 'pdf-info
|
||||
:type 'hook)
|
||||
|
||||
|
||||
@@ -194,7 +188,7 @@ This variable should only be let-bound.")
|
||||
(defvar pdf-info--queue t
|
||||
"Internally used transmission-queue for the server.
|
||||
|
||||
This variable is initially `t', telling the code starting the
|
||||
This variable is initially t, telling the code starting the
|
||||
server, that it never ran.")
|
||||
|
||||
|
||||
@@ -311,41 +305,44 @@ error."
|
||||
(setq pdf-info--queue (tq-create proc))))
|
||||
pdf-info--queue)
|
||||
|
||||
(defadvice tq-process-buffer (around bugfix activate)
|
||||
"Fix a bug in trunk where the wrong callback gets called."
|
||||
(advice-add 'tq-process-buffer :around #'pdf-info--tq-workaround)
|
||||
(defun pdf-info--tq-workaround (orig-fun tq &rest args)
|
||||
"Fix a bug in trunk where the wrong callback gets called.
|
||||
|
||||
ORIG-FUN is the callback that should be called. TQ and ARGS are
|
||||
the transmission-queue and arguments to the callback."
|
||||
;; FIXME: Make me iterative.
|
||||
(let ((tq (ad-get-arg 0)))
|
||||
(if (not (equal (car (process-command (tq-process tq)))
|
||||
pdf-info-epdfinfo-program))
|
||||
ad-do-it
|
||||
(let ((buffer (tq-buffer tq))
|
||||
done)
|
||||
(when (buffer-live-p buffer)
|
||||
(set-buffer buffer)
|
||||
(while (and (not done)
|
||||
(> (buffer-size) 0))
|
||||
(setq done t)
|
||||
(if (tq-queue-empty tq)
|
||||
(let ((buf (generate-new-buffer "*spurious*")))
|
||||
(copy-to-buffer buf (point-min) (point-max))
|
||||
(delete-region (point-min) (point))
|
||||
(pop-to-buffer buf nil)
|
||||
(error "Spurious communication from process %s, see buffer %s"
|
||||
(process-name (tq-process tq))
|
||||
(buffer-name buf)))
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward (tq-queue-head-regexp tq) nil t)
|
||||
(setq done nil)
|
||||
(let ((answer (buffer-substring (point-min) (point)))
|
||||
(fn (tq-queue-head-fn tq))
|
||||
(closure (tq-queue-head-closure tq)))
|
||||
(delete-region (point-min) (point))
|
||||
(tq-queue-pop tq)
|
||||
(condition-case-unless-debug err
|
||||
(funcall fn closure answer)
|
||||
(error
|
||||
(message "Error while processing tq callback: %s"
|
||||
(error-message-string err)))))))))))))
|
||||
(if (not (equal (car (process-command (tq-process tq)))
|
||||
pdf-info-epdfinfo-program))
|
||||
(apply orig-fun tq args)
|
||||
(let ((buffer (tq-buffer tq))
|
||||
done)
|
||||
(when (buffer-live-p buffer)
|
||||
(set-buffer buffer)
|
||||
(while (and (not done)
|
||||
(> (buffer-size) 0))
|
||||
(setq done t)
|
||||
(if (tq-queue-empty tq)
|
||||
(let ((buf (generate-new-buffer "*spurious*")))
|
||||
(copy-to-buffer buf (point-min) (point-max))
|
||||
(delete-region (point-min) (point))
|
||||
(pop-to-buffer buf nil)
|
||||
(error "Spurious communication from process %s, see buffer %s"
|
||||
(process-name (tq-process tq))
|
||||
(buffer-name buf)))
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward (tq-queue-head-regexp tq) nil t)
|
||||
(setq done nil)
|
||||
(let ((answer (buffer-substring (point-min) (point)))
|
||||
(fn (tq-queue-head-fn tq))
|
||||
(closure (tq-queue-head-closure tq)))
|
||||
(delete-region (point-min) (point))
|
||||
(tq-queue-pop tq)
|
||||
(condition-case-unless-debug err
|
||||
(funcall fn closure answer)
|
||||
(error
|
||||
(message "Error while processing tq callback: %s"
|
||||
(error-message-string err))))))))))))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
@@ -357,8 +354,9 @@ error."
|
||||
(pdf-info-process-assert-running)
|
||||
(unless (symbolp cmd)
|
||||
(setq cmd (intern cmd)))
|
||||
(let* ((query (concat (mapconcat 'pdf-info-query--escape
|
||||
(cons cmd args) ":") "\n"))
|
||||
(let* ((query (concat (mapconcat #'pdf-info-query--escape
|
||||
(cons cmd args) ":")
|
||||
"\n"))
|
||||
(callback
|
||||
(lambda (closure response)
|
||||
(cl-destructuring-bind (status &rest result)
|
||||
@@ -384,7 +382,7 @@ error."
|
||||
(not (eq (process-status (pdf-info-process))
|
||||
'run))
|
||||
(not (eq cmd 'quit)))
|
||||
(error "The epdfinfo server quit unexpectedly."))
|
||||
(error "The epdfinfo server quit unexpectedly"))
|
||||
(cond
|
||||
((null status) response)
|
||||
((eq status 'error)
|
||||
@@ -392,7 +390,7 @@ error."
|
||||
((eq status 'interrupted)
|
||||
(error "epdfinfo: Command was interrupted"))
|
||||
(t
|
||||
(error "internal error: invalid response status"))))))
|
||||
(error "Internal error: invalid response status"))))))
|
||||
|
||||
(defun pdf-info-interrupt ()
|
||||
"FIXME: This command does currently nothing."
|
||||
@@ -483,7 +481,7 @@ interrupted."
|
||||
(mapcar (lambda (elt)
|
||||
(cl-assert (= 1 (length (cadr elt))) t)
|
||||
`(,(aref (cadr elt) 0)
|
||||
,(mapcar 'string-to-number
|
||||
,(mapcar #'string-to-number
|
||||
(split-string (car elt) " " t))))
|
||||
response))
|
||||
(regexp-flags
|
||||
@@ -499,7 +497,7 @@ interrupted."
|
||||
(pdf-util-highlight-regexp-in-string
|
||||
(regexp-quote (nth 1 r)) (nth 2 r))))
|
||||
(edges . ,(mapcar (lambda (m)
|
||||
(mapcar 'string-to-number
|
||||
(mapcar #'string-to-number
|
||||
(split-string m " " t)))
|
||||
(cddr (cdr r))))))
|
||||
response))
|
||||
@@ -511,7 +509,7 @@ interrupted."
|
||||
(pagelinks
|
||||
(mapcar (lambda (r)
|
||||
`((edges .
|
||||
,(mapcar 'string-to-number ;area
|
||||
,(mapcar #'string-to-number ;area
|
||||
(split-string (pop r) " " t)))
|
||||
,@(pdf-info-query--transform-action r)))
|
||||
response))
|
||||
@@ -534,10 +532,10 @@ interrupted."
|
||||
(or (caar response) ""))
|
||||
(getselection
|
||||
(mapcar (lambda (line)
|
||||
(mapcar 'string-to-number
|
||||
(mapcar #'string-to-number
|
||||
(split-string (car line) " " t)))
|
||||
response))
|
||||
(features (mapcar 'intern (car response)))
|
||||
(features (mapcar #'intern (car response)))
|
||||
(pagesize
|
||||
(setq response (car response))
|
||||
(cons (round (string-to-number (car response)))
|
||||
@@ -545,15 +543,15 @@ interrupted."
|
||||
((getannot editannot addannot)
|
||||
(pdf-info-query--transform-annotation (car response)))
|
||||
(getannots
|
||||
(mapcar 'pdf-info-query--transform-annotation response))
|
||||
(mapcar #'pdf-info-query--transform-annotation response))
|
||||
(getattachments
|
||||
(mapcar 'pdf-info-query--transform-attachment response))
|
||||
(mapcar #'pdf-info-query--transform-attachment response))
|
||||
((getattachment-from-annot)
|
||||
(pdf-info-query--transform-attachment (car response)))
|
||||
(boundingbox
|
||||
(mapcar 'string-to-number (car response)))
|
||||
(mapcar #'string-to-number (car response)))
|
||||
(synctex-forward-search
|
||||
(let ((list (mapcar 'string-to-number (car response))))
|
||||
(let ((list (mapcar #'string-to-number (car response))))
|
||||
`((page . ,(car list))
|
||||
(edges . ,(cdr list)))))
|
||||
(synctex-backward-search
|
||||
@@ -575,7 +573,7 @@ interrupted."
|
||||
(push value options)
|
||||
(push key options)))
|
||||
options))
|
||||
(pagelabels (mapcar 'car response))
|
||||
(pagelabels (mapcar #'car response))
|
||||
(ping (caar response))
|
||||
(t response)))
|
||||
|
||||
@@ -604,7 +602,7 @@ interrupted."
|
||||
(cl-destructuring-bind (page edges type id flags color contents modified &rest rest)
|
||||
a
|
||||
(setq a1 `((page . ,(string-to-number page))
|
||||
(edges . ,(mapcar 'string-to-number
|
||||
(edges . ,(mapcar #'string-to-number
|
||||
(split-string edges " " t)))
|
||||
(type . ,(intern type))
|
||||
(id . ,(intern id))
|
||||
@@ -623,7 +621,7 @@ interrupted."
|
||||
(and o (string-to-number o))))
|
||||
(popup-edges . ,(let ((p (not-empty popup-edges)))
|
||||
(when p
|
||||
(mapcar 'string-to-number
|
||||
(mapcar #'string-to-number
|
||||
(split-string p " " t)))))
|
||||
(popup-is-open . ,(equal popup-is-open "1"))
|
||||
(created . ,(pdf-info-parse-pdf-date (not-empty created)))))
|
||||
@@ -639,7 +637,7 @@ interrupted."
|
||||
'(squiggly highlight underline strike-out))
|
||||
(setq a3 `((markup-edges
|
||||
. ,(mapcar (lambda (r)
|
||||
(mapcar 'string-to-number
|
||||
(mapcar #'string-to-number
|
||||
(split-string r " " t)))
|
||||
rest)))))))))
|
||||
(append a1 a2 a3))))
|
||||
@@ -851,9 +849,8 @@ i.e. `pdf-info-asynchronous' is non-nil, transparently.
|
||||
;; Let-bind responses corresponding to their variables,
|
||||
;; i.e. keys in alist RESULTS.
|
||||
(let (,@(mapcar (lambda (var)
|
||||
(list var (list 'cdr (list 'assq (list 'quote var)
|
||||
results))))
|
||||
(mapcar 'car let-forms)))
|
||||
`(,var (cdr (assq ',var ,results))))
|
||||
(mapcar #'car let-forms)))
|
||||
(setq ,status (not (not ,first-error))
|
||||
,response (or ,first-error
|
||||
(with-current-buffer ,buffer
|
||||
@@ -888,7 +885,7 @@ i.e. `pdf-info-asynchronous' is non-nil, transparently.
|
||||
(when (and (not ,done)
|
||||
(not (eq (process-status (pdf-info-process))
|
||||
'run)))
|
||||
(error "The epdfinfo server quit unexpectedly."))
|
||||
(error "The epdfinfo server quit unexpectedly"))
|
||||
(when ,status
|
||||
(error "epdfinfo: %s" ,response))
|
||||
,response))))
|
||||
@@ -920,7 +917,7 @@ restart it."
|
||||
(tq-close pdf-info--queue))
|
||||
(set (make-local-variable 'pdf-info--queue) nil)
|
||||
(pdf-info-process-assert-running t)
|
||||
(add-hook 'kill-buffer-hook 'pdf-info-kill-local-server nil t)
|
||||
(add-hook 'kill-buffer-hook #'pdf-info-kill-local-server nil t)
|
||||
pdf-info--queue)))
|
||||
|
||||
(defun pdf-info-kill-local-server (&optional buffer)
|
||||
@@ -1259,7 +1256,7 @@ Return the text contained in the selection."
|
||||
'gettext
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
page
|
||||
(mapconcat 'number-to-string edges " ")
|
||||
(mapconcat #'number-to-string edges " ")
|
||||
(cl-case selection-style
|
||||
(glyph 0)
|
||||
(word 1)
|
||||
@@ -1278,7 +1275,7 @@ aforementioned function, when called with the same arguments."
|
||||
'getselection
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
page
|
||||
(mapconcat 'number-to-string edges " ")
|
||||
(mapconcat #'number-to-string edges " ")
|
||||
(cl-case selection-style
|
||||
(glyph 0)
|
||||
(word 1)
|
||||
@@ -1314,7 +1311,7 @@ contains at most one element."
|
||||
'charlayout
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
page
|
||||
(mapconcat 'number-to-string edges-or-pos " ")))
|
||||
(mapconcat #'number-to-string edges-or-pos " ")))
|
||||
|
||||
(defun pdf-info-pagesize (page &optional file-or-buffer)
|
||||
"Return the size of PAGE as a cons \(WIDTH . HEIGHT\)
|
||||
@@ -1428,7 +1425,7 @@ returns."
|
||||
(push file-or-buffer markup-edges)
|
||||
(setq file-or-buffer nil))
|
||||
(apply
|
||||
'pdf-info-query
|
||||
#'pdf-info-query
|
||||
'addannot
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
page
|
||||
@@ -1488,11 +1485,11 @@ The server must support modifying annotations for this to work."
|
||||
(t
|
||||
(list (car elt) (cdr elt)))))
|
||||
modifications)))
|
||||
(apply 'pdf-info-query
|
||||
(apply #'pdf-info-query
|
||||
'editannot
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
id
|
||||
(apply 'append edits))))
|
||||
(apply #'append edits))))
|
||||
|
||||
(defun pdf-info-save (&optional file-or-buffer)
|
||||
"Save FILE-OR-BUFFER.
|
||||
@@ -1590,7 +1587,7 @@ Return the data of the corresponding PNG image."
|
||||
(when (keywordp file-or-buffer)
|
||||
(push file-or-buffer commands)
|
||||
(setq file-or-buffer nil))
|
||||
(apply 'pdf-info-query
|
||||
(apply #'pdf-info-query
|
||||
'renderpage
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
page
|
||||
@@ -1602,7 +1599,7 @@ Return the data of the corresponding PNG image."
|
||||
(setq value
|
||||
(cl-case kw
|
||||
((:crop-to :highlight-line :highlight-region :highlight-text)
|
||||
(mapconcat 'number-to-string value " "))
|
||||
(mapconcat #'number-to-string value " "))
|
||||
((:foreground :background)
|
||||
(pdf-util-hexcolor value))
|
||||
(:alpha
|
||||
@@ -1636,9 +1633,9 @@ Return the data of the corresponding PNG image."
|
||||
(push file-or-buffer regions)
|
||||
(setq file-or-buffer nil))
|
||||
|
||||
(apply 'pdf-info-renderpage
|
||||
(apply #'pdf-info-renderpage
|
||||
page width file-or-buffer
|
||||
(apply 'append
|
||||
(apply #'append
|
||||
(mapcar (lambda (elt)
|
||||
`(:foreground ,(pop elt)
|
||||
:background ,(pop elt)
|
||||
@@ -1668,9 +1665,9 @@ Return the data of the corresponding PNG image."
|
||||
(push file-or-buffer regions)
|
||||
(setq file-or-buffer nil))
|
||||
|
||||
(apply 'pdf-info-renderpage
|
||||
(apply #'pdf-info-renderpage
|
||||
page width file-or-buffer
|
||||
(apply 'append
|
||||
(apply #'append
|
||||
(mapcar (lambda (elt)
|
||||
`(:background ,(pop elt)
|
||||
:foreground ,(pop elt)
|
||||
@@ -1701,7 +1698,7 @@ Returns a list \(LEFT TOP RIGHT BOT\)."
|
||||
(setq file-or-buffer nil))
|
||||
(unless (= (% (length options) 2) 0)
|
||||
(error "Missing a option value"))
|
||||
(apply 'pdf-info-query
|
||||
(apply #'pdf-info-query
|
||||
'setoptions
|
||||
(pdf-info--normalize-file-or-buffer file-or-buffer)
|
||||
(let (soptions)
|
||||
|
||||
@@ -127,7 +127,9 @@ keymap is `isearch-mode-map'.")
|
||||
(put 'image-scroll-up 'isearch-scroll t)
|
||||
(put 'image-scroll-down 'isearch-scroll t)
|
||||
|
||||
(define-minor-mode pdf-isearch-active-mode "" nil nil nil
|
||||
(define-minor-mode pdf-isearch-active-mode
|
||||
"This mode is enabled when isearch is active in a PDF file."
|
||||
:group 'pdf-isearch
|
||||
(cond
|
||||
(pdf-isearch-active-mode
|
||||
(set (make-local-variable 'isearch-mode-map)
|
||||
@@ -218,7 +220,6 @@ If this mode is enabled, isearching does not stop at every match,
|
||||
but rather moves to the next one not currently visible. This
|
||||
behaviour is much faster than ordinary isearch, since far less
|
||||
different images have to be displayed."
|
||||
nil nil nil
|
||||
:group 'pdf-isearch
|
||||
(when isearch-mode
|
||||
(pdf-isearch-redisplay)
|
||||
@@ -742,7 +743,7 @@ MATCH-BG LAZY-FG LAZY-BG\)."
|
||||
occur-hack-p)
|
||||
(eq page (pdf-view-current-page)))
|
||||
(pdf-view-display-image
|
||||
(pdf-view-create-image data))))))))
|
||||
(pdf-view-create-image data :width width))))))))
|
||||
(pdf-info-renderpage-text-regions
|
||||
page width t nil
|
||||
`(,fg1 ,bg1 ,@(pdf-util-scale-pixel-to-relative
|
||||
|
||||
@@ -111,8 +111,6 @@ one of the displayed keys, or by using isearch limited to
|
||||
links via \\[pdf-links-isearch-link].
|
||||
|
||||
\\{pdf-links-minor-mode-map}"
|
||||
|
||||
nil nil nil
|
||||
:group 'pdf-links
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(cond
|
||||
@@ -369,7 +367,12 @@ Wraps the URI in \[\[ ... \]\] and calls `org-open-link-from-string'
|
||||
on the resulting string."
|
||||
(cl-check-type uri string)
|
||||
(message "Opening `%s' with Org" uri)
|
||||
(org-open-link-from-string (format "[[%s]]" uri)))
|
||||
(cond
|
||||
((fboundp 'org-link-open-from-string)
|
||||
(org-link-open-from-string (format "[[%s]]" uri)))
|
||||
;; For Org 9.2 and older
|
||||
((fboundp 'org-open-link-from-string)
|
||||
(org-open-link-from-string (format "[[%s]]" uri)))))
|
||||
|
||||
(provide 'pdf-links)
|
||||
|
||||
|
||||
51
lisp/pdf-tools/pdf-macs.el
Normal file
51
lisp/pdf-tools/pdf-macs.el
Normal file
@@ -0,0 +1,51 @@
|
||||
;;; pdf-macs.el --- Macros for pdf-tools. -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2013 Andreas Politz
|
||||
|
||||
;; Author: Andreas Politz <politza@fh-trier.de>
|
||||
;; Keywords: files, doc-view, pdf
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;;; Code:
|
||||
;;
|
||||
|
||||
(defmacro pdf-view-current-page (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'page ,window))
|
||||
|
||||
(defmacro pdf-view-current-overlay (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'overlay ,window))
|
||||
|
||||
(defmacro pdf-view-current-image (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'image ,window))
|
||||
|
||||
(defmacro pdf-view-current-slice (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'slice ,window))
|
||||
|
||||
(defmacro pdf-view-current-window-size (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'window-size ,window))
|
||||
|
||||
(defmacro pdf-view-window-needs-redisplay (&optional window)
|
||||
`(image-mode-window-get 'needs-redisplay ,window))
|
||||
|
||||
(provide 'pdf-macs)
|
||||
|
||||
;;; pdf-macs.el ends here
|
||||
@@ -1,4 +1,4 @@
|
||||
;;; pdf-misc.el --- Miscellaneous commands for PDF buffer.
|
||||
;;; pdf-misc.el --- Miscellaneous commands for PDF buffer. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2013, 2014 Andreas Politz
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
;;;###autoload
|
||||
(define-minor-mode pdf-misc-minor-mode
|
||||
"FIXME: Not documented."
|
||||
nil nil nil)
|
||||
:group 'pdf-misc)
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode pdf-misc-size-indication-minor-mode
|
||||
"Provide a working size indication in the mode-line."
|
||||
nil nil nil
|
||||
:group 'pdf-misc
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(cond
|
||||
(pdf-misc-size-indication-minor-mode
|
||||
@@ -171,7 +171,7 @@
|
||||
;;;###autoload
|
||||
(define-minor-mode pdf-misc-menu-bar-minor-mode
|
||||
"Display a PDF Tools menu in the menu-bar."
|
||||
nil nil nil
|
||||
:group 'pdf-misc
|
||||
(pdf-util-assert-pdf-buffer))
|
||||
|
||||
(defvar pdf-misc-context-menu-minor-mode-map
|
||||
@@ -184,16 +184,18 @@
|
||||
"Provide a right-click context menu in PDF buffers.
|
||||
|
||||
\\{pdf-misc-context-menu-minor-mode-map}"
|
||||
nil nil nil
|
||||
:group 'pdf-misc
|
||||
(pdf-util-assert-pdf-buffer))
|
||||
|
||||
(defun pdf-misc-popup-context-menu (event)
|
||||
"Popup a context menu at position determined by EVENT."
|
||||
(defun pdf-misc-popup-context-menu ()
|
||||
"Popup a context menu at position."
|
||||
(interactive "@e")
|
||||
(popup-menu
|
||||
(cons 'keymap
|
||||
(cddr (lookup-key pdf-misc-menu-bar-minor-mode-map
|
||||
[menu-bar PDF\ Tools])))))
|
||||
(cddr (or (lookup-key pdf-misc-menu-bar-minor-mode-map
|
||||
[menu-bar PDF\ Tools])
|
||||
(lookup-key pdf-misc-menu-bar-minor-mode-map
|
||||
[menu-bar pdf\ tools]))))))
|
||||
|
||||
(defun pdf-misc-display-metadata ()
|
||||
"Display all available metadata in a separate buffer."
|
||||
@@ -206,8 +208,7 @@
|
||||
(pad (apply' max (mapcar (lambda (d)
|
||||
(length (symbol-name (car d))))
|
||||
md)))
|
||||
(fmt (format "%%%ds:%%s\n" pad))
|
||||
window)
|
||||
(fmt (format "%%%ds:%%s\n" pad)))
|
||||
(erase-buffer)
|
||||
(setq header-line-format (buffer-name buffer)
|
||||
buffer-read-only t)
|
||||
@@ -235,8 +236,8 @@
|
||||
:group 'pdf-tools)
|
||||
|
||||
(define-obsolete-variable-alias 'pdf-misc-print-programm
|
||||
'pdf-misc-print-program "1.0")
|
||||
(defcustom pdf-misc-print-programm nil
|
||||
'pdf-misc-print-program-executable "1.0")
|
||||
(defcustom pdf-misc-print-program-executable nil
|
||||
"The program used for printing.
|
||||
|
||||
It is called with one argument, the PDF file."
|
||||
@@ -245,14 +246,20 @@ It is called with one argument, the PDF file."
|
||||
|
||||
(define-obsolete-variable-alias 'pdf-misc-print-programm-args
|
||||
'pdf-misc-print-program-args "1.0")
|
||||
(defcustom pdf-misc-print-programm-args nil
|
||||
(defcustom pdf-misc-print-program-args nil
|
||||
"List of additional arguments passed to `pdf-misc-print-program'."
|
||||
:group 'pdf-misc
|
||||
:type '(repeat string))
|
||||
|
||||
(defun pdf-misc-print-programm (&optional interactive-p)
|
||||
(or (and pdf-misc-print-programm
|
||||
(executable-find pdf-misc-print-programm))
|
||||
(define-obsolete-function-alias 'pdf-misc-print-programm
|
||||
'pdf-misc-print-program "1.0")
|
||||
(defun pdf-misc-print-program (&optional interactive-p)
|
||||
"Return the program used to print PDFs (if the executable is installed).
|
||||
|
||||
If INTERACTIVE-P is non-nil, ask the user for which program to
|
||||
use when printing the PDF. Optionally, save the choice"
|
||||
(or (and pdf-misc-print-program-executable
|
||||
(executable-find pdf-misc-print-program-executable))
|
||||
(when interactive-p
|
||||
(let* ((default (car (delq nil (mapcar
|
||||
'executable-find
|
||||
@@ -264,17 +271,17 @@ It is called with one argument, the PDF file."
|
||||
"Print with: " default nil t nil 'file-executable-p))))
|
||||
(when (and program
|
||||
(executable-find program))
|
||||
(when (y-or-n-p "Save choice using customize ?")
|
||||
(when (y-or-n-p "Save choice using customize? ")
|
||||
(customize-save-variable
|
||||
'pdf-misc-print-program program))
|
||||
(setq pdf-misc-print-program program))))))
|
||||
'pdf-misc-print-program-executable program))
|
||||
(setq pdf-misc-print-program-executable program))))))
|
||||
|
||||
(defun pdf-misc-print-document (filename &optional interactive-p)
|
||||
(interactive
|
||||
(list (pdf-view-buffer-file-name) t))
|
||||
(cl-check-type filename (and string file-readable))
|
||||
(cl-check-type filename (and string (satisfies file-readable-p)))
|
||||
(let ((program (pdf-misc-print-program interactive-p))
|
||||
(args (append pdf-misc-print-programm-args (list filename))))
|
||||
(args (append pdf-misc-print-program-args (list filename))))
|
||||
(unless program
|
||||
(error "No print program available"))
|
||||
(apply #'start-process "printing" nil program args)
|
||||
|
||||
@@ -46,25 +46,21 @@
|
||||
|
||||
(defface pdf-occur-document-face
|
||||
'((default (:inherit font-lock-string-face)))
|
||||
"Face used to highlight documents in the list buffer."
|
||||
:group 'pdf-occur)
|
||||
"Face used to highlight documents in the list buffer.")
|
||||
|
||||
(defface pdf-occur-page-face
|
||||
'((default (:inherit font-lock-type-face)))
|
||||
"Face used to highlight page numbers in the list buffer."
|
||||
:group 'pdf-occur)
|
||||
"Face used to highlight page numbers in the list buffer.")
|
||||
|
||||
(defcustom pdf-occur-search-batch-size 16
|
||||
"Maximum number of pages searched in one query.
|
||||
|
||||
Lower numbers will make Emacs more responsive when searching at
|
||||
the cost of slightly increased search time."
|
||||
:group 'pdf-occur
|
||||
:type 'integer)
|
||||
|
||||
(defcustom pdf-occur-prefer-string-search nil
|
||||
"If non-nil, reverse the meaning of the regexp-p prefix-arg."
|
||||
:group 'pdf-occur
|
||||
:type 'boolean)
|
||||
|
||||
(defvar pdf-occur-history nil
|
||||
@@ -78,7 +74,7 @@ the cost of slightly increased search time."
|
||||
|
||||
Each element should be either the filename of a PDF document or a
|
||||
cons \(FILENAME . PAGES\), where PAGES is the list of pages to
|
||||
search. See `pdf-info-normalize-page-range' for it's format.")
|
||||
search. See `pdf-info-normalize-page-range' for its format.")
|
||||
|
||||
(defvar pdf-occur-number-of-matches 0
|
||||
"The number of matches in all searched documents.")
|
||||
@@ -92,15 +88,15 @@ search. See `pdf-info-normalize-page-range' for it's format.")
|
||||
(defvar pdf-occur-buffer-mode-map
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(set-keymap-parent kmap tablist-mode-map)
|
||||
(define-key kmap (kbd "RET") 'pdf-occur-goto-occurrence)
|
||||
(define-key kmap (kbd "C-o") 'pdf-occur-view-occurrence)
|
||||
(define-key kmap (kbd "SPC") 'pdf-occur-view-occurrence)
|
||||
(define-key kmap (kbd "C-c C-f") 'next-error-follow-minor-mode)
|
||||
(define-key kmap (kbd "g") 'pdf-occur-revert-buffer-with-args)
|
||||
(define-key kmap (kbd "K") 'pdf-occur-abort-search)
|
||||
(define-key kmap (kbd "D") 'pdf-occur-tablist-do-delete)
|
||||
(define-key kmap (kbd "x") 'pdf-occur-tablist-do-flagged-delete)
|
||||
(define-key kmap (kbd "A") 'pdf-occur-tablist-gather-documents)
|
||||
(define-key kmap (kbd "RET") #'pdf-occur-goto-occurrence)
|
||||
(define-key kmap (kbd "C-o") #'pdf-occur-view-occurrence)
|
||||
(define-key kmap (kbd "SPC") #'pdf-occur-view-occurrence)
|
||||
(define-key kmap (kbd "C-c C-f") #'next-error-follow-minor-mode)
|
||||
(define-key kmap (kbd "g") #'pdf-occur-revert-buffer-with-args)
|
||||
(define-key kmap (kbd "K") #'pdf-occur-abort-search)
|
||||
(define-key kmap (kbd "D") #'pdf-occur-tablist-do-delete)
|
||||
(define-key kmap (kbd "x") #'pdf-occur-tablist-do-flagged-delete)
|
||||
(define-key kmap (kbd "A") #'pdf-occur-tablist-gather-documents)
|
||||
kmap)
|
||||
"The keymap used for `pdf-occur-buffer-mode'.")
|
||||
|
||||
@@ -128,9 +124,9 @@ Some useful keys are:
|
||||
|
||||
\\{pdf-occur-buffer-mode-map}"
|
||||
(setq-local case-fold-search case-fold-search)
|
||||
(setq-local next-error-function 'pdf-occur-next-error)
|
||||
(setq-local next-error-function #'pdf-occur-next-error)
|
||||
(setq-local revert-buffer-function
|
||||
'pdf-occur-revert-buffer)
|
||||
#'pdf-occur-revert-buffer)
|
||||
(setq next-error-last-buffer (current-buffer))
|
||||
(setq-local tabulated-list-sort-key nil)
|
||||
(setq-local tabulated-list-use-header-line t)
|
||||
@@ -192,10 +188,10 @@ For a programmatic search of multiple documents see
|
||||
(let* ((2-columns-p (= 1 (length pdf-occur-search-documents)))
|
||||
(filename-width
|
||||
(min 24
|
||||
(apply 'max
|
||||
(mapcar 'length
|
||||
(mapcar 'pdf-occur-abbrev-document
|
||||
(mapcar 'car pdf-occur-search-documents))))))
|
||||
(apply #'max
|
||||
(mapcar #'length
|
||||
(mapcar #'pdf-occur-abbrev-document
|
||||
(mapcar #'car pdf-occur-search-documents))))))
|
||||
(page-sorter (tablist-generate-sorter
|
||||
(if 2-columns-p 0 1)
|
||||
'<
|
||||
@@ -353,8 +349,8 @@ Compatibility function for \\[next-error] invocations."
|
||||
|
||||
This global minor mode enables (or disables)
|
||||
`pdf-occur-ibuffer-minor-mode' and `pdf-occur-dired-minor-mode'
|
||||
in all current and future ibuffer/dired buffer." nil nil nil
|
||||
:global t
|
||||
in all current and future ibuffer/dired buffer."
|
||||
:global t
|
||||
(let ((arg (if pdf-occur-global-minor-mode 1 -1)))
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
@@ -365,15 +361,15 @@ in all current and future ibuffer/dired buffer." nil nil nil
|
||||
(pdf-occur-ibuffer-minor-mode arg)))))
|
||||
(cond
|
||||
(pdf-occur-global-minor-mode
|
||||
(add-hook 'dired-mode-hook 'pdf-occur-dired-minor-mode)
|
||||
(add-hook 'ibuffer-mode-hook 'pdf-occur-ibuffer-minor-mode))
|
||||
(add-hook 'dired-mode-hook #'pdf-occur-dired-minor-mode)
|
||||
(add-hook 'ibuffer-mode-hook #'pdf-occur-ibuffer-minor-mode))
|
||||
(t
|
||||
(remove-hook 'dired-mode-hook 'pdf-occur-dired-minor-mode)
|
||||
(remove-hook 'ibuffer-mode-hook 'pdf-occur-ibuffer-minor-mode)))))
|
||||
(remove-hook 'dired-mode-hook #'pdf-occur-dired-minor-mode)
|
||||
(remove-hook 'ibuffer-mode-hook #'pdf-occur-ibuffer-minor-mode)))))
|
||||
|
||||
(defvar pdf-occur-ibuffer-minor-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap ibuffer-do-occur] 'pdf-occur-ibuffer-do-occur)
|
||||
(define-key map [remap ibuffer-do-occur] #'pdf-occur-ibuffer-do-occur)
|
||||
map)
|
||||
"Keymap used in `pdf-occur-ibuffer-minor-mode'.")
|
||||
|
||||
@@ -384,9 +380,7 @@ in all current and future ibuffer/dired buffer." nil nil nil
|
||||
This mode remaps `ibuffer-do-occur' to
|
||||
`pdf-occur-ibuffer-do-occur', which will start the PDF Tools
|
||||
version of `occur', if all marked buffer's are in `pdf-view-mode'
|
||||
and otherwise fallback to `ibuffer-do-occur'."
|
||||
|
||||
nil nil nil)
|
||||
and otherwise fallback to `ibuffer-do-occur'.")
|
||||
|
||||
(defun pdf-occur-ibuffer-do-occur (&optional regexp-p)
|
||||
"Uses `pdf-occur-search', if appropriate.
|
||||
@@ -409,7 +403,7 @@ I.e. all marked buffers are in PDFView mode."
|
||||
|
||||
(defvar pdf-occur-dired-minor-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap dired-do-search] 'pdf-occur-dired-do-search)
|
||||
(define-key map [remap dired-do-search] #'pdf-occur-dired-do-search)
|
||||
map)
|
||||
"Keymap used in `pdf-occur-dired-minor-mode'.")
|
||||
|
||||
@@ -420,9 +414,7 @@ I.e. all marked buffers are in PDFView mode."
|
||||
This mode remaps `dired-do-search' to
|
||||
`pdf-occur-dired-do-search', which will start the PDF Tools
|
||||
version of `occur', if all marked buffer's are in `pdf-view-mode'
|
||||
and otherwise fallback to `dired-do-search'."
|
||||
|
||||
nil nil nil)
|
||||
and otherwise fallback to `dired-do-search'.")
|
||||
|
||||
(defun pdf-occur-dired-do-search ()
|
||||
"Uses `pdf-occur-search', if appropriate.
|
||||
@@ -453,7 +445,7 @@ I.e. all marked files look like PDF documents."
|
||||
DOCUMENTS should be a list of buffers (objects, not names),
|
||||
filenames or conses \(BUFFER-OR-FILENAME . PAGES\), where PAGES
|
||||
determines the scope of the search of the respective document.
|
||||
See `pdf-info-normalize-page-range' for it's format.
|
||||
See `pdf-info-normalize-page-range' for its format.
|
||||
|
||||
STRING is either the string to search for or, if REGEXP-P is
|
||||
non-nil, a Perl compatible regular expression (PCRE).
|
||||
@@ -478,7 +470,8 @@ Returns the window where the buffer is displayed."
|
||||
(display-buffer
|
||||
(current-buffer))))
|
||||
|
||||
(defadvice tabulated-list-init-header (after update-header activate)
|
||||
(advice-add 'tabulated-list-init-header :after #'pdf-occur--update-header)
|
||||
(defun pdf-occur--update-header (&rest _)
|
||||
"We want our own headers, thank you."
|
||||
(when (derived-mode-p 'pdf-occur-buffer-mode)
|
||||
(save-current-buffer
|
||||
@@ -555,7 +548,7 @@ matches linked with PAGE."
|
||||
(mapcar (lambda (doc)
|
||||
(pdf-occur-create-entry doc 1))
|
||||
(cl-set-difference
|
||||
(mapcar 'car
|
||||
(mapcar #'car
|
||||
pdf-occur-search-documents)
|
||||
(mapcar (lambda (elt)
|
||||
(plist-get (car elt) :document))
|
||||
@@ -635,7 +628,7 @@ matches linked with PAGE."
|
||||
batches)
|
||||
(setq pdf-occur-number-of-matches 0)
|
||||
(setq pdf-occur-search-pages-left
|
||||
(apply '+ (mapcar (lambda (elt)
|
||||
(apply #'+ (mapcar (lambda (elt)
|
||||
(1+ (- (cdr (nth 1 elt))
|
||||
(car (nth 1 elt)))))
|
||||
batches)))))
|
||||
@@ -696,7 +689,7 @@ matches linked with PAGE."
|
||||
Examine all dired/ibuffer windows and offer to put marked files
|
||||
in the search list."
|
||||
(interactive)
|
||||
(let ((searched (mapcar 'car pdf-occur-search-documents))
|
||||
(let ((searched (mapcar #'car pdf-occur-search-documents))
|
||||
files)
|
||||
(dolist (win (window-list))
|
||||
(with-selected-window win
|
||||
@@ -709,7 +702,7 @@ in the search list."
|
||||
(setq files
|
||||
(append files marked nil)))))
|
||||
((derived-mode-p 'ibuffer-mode)
|
||||
(dolist (fname (mapcar 'buffer-file-name
|
||||
(dolist (fname (mapcar #'buffer-file-name
|
||||
(ibuffer-get-marked-buffers)))
|
||||
(when fname
|
||||
(push fname files))))
|
||||
@@ -735,7 +728,7 @@ in the search list."
|
||||
(when (tablist-yes-or-no-p
|
||||
'add nil (mapcar (lambda (file)
|
||||
(cons nil (vector file)))
|
||||
(cl-sort files 'string-lessp)))
|
||||
(cl-sort files #'string-lessp)))
|
||||
(setq pdf-occur-search-documents
|
||||
(append pdf-occur-search-documents
|
||||
(pdf-occur-normalize-documents files)))
|
||||
|
||||
@@ -41,73 +41,73 @@
|
||||
|
||||
(defcustom pdf-outline-buffer-indent 2
|
||||
"The level of indent in the Outline buffer."
|
||||
:type 'integer
|
||||
:group 'pdf-outline)
|
||||
:type 'integer)
|
||||
|
||||
(defcustom pdf-outline-enable-imenu t
|
||||
"Whether `imenu' should be enabled in PDF documents."
|
||||
:group 'pdf-outline
|
||||
:type '(choice (const :tag "Yes" t)
|
||||
(const :tag "No" nil)))
|
||||
|
||||
(defcustom pdf-outline-imenu-keep-order t
|
||||
"Whether `imenu' should be advised not to reorder the outline."
|
||||
:group 'pdf-outline
|
||||
:type '(choice (const :tag "Yes" t)
|
||||
(const :tag "No" nil)))
|
||||
|
||||
(defcustom pdf-outline-imenu-use-flat-menus nil
|
||||
"Whether the constructed Imenu should be a list, rather than a tree."
|
||||
:group 'pdf-outline
|
||||
:type '(choice (const :tag "Yes" t)
|
||||
(const :tag "No" nil)))
|
||||
|
||||
(defcustom pdf-outline-display-buffer-action '(nil . nil)
|
||||
"The display action used, when displaying the outline buffer."
|
||||
:group 'pdf-outline
|
||||
:type display-buffer--action-custom-type)
|
||||
|
||||
(defcustom pdf-outline-display-labels nil
|
||||
"Whether the outline should display labels instead of page numbers.
|
||||
|
||||
Usually a page's label is it's displayed page number."
|
||||
:group 'pdf-outline
|
||||
Usually a page's label is its displayed page number."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-outline-fill-column fill-column
|
||||
"The value of `fill-column' in pdf outline buffers.
|
||||
|
||||
Set to nil to disable line wrapping."
|
||||
:type 'integer)
|
||||
|
||||
(defvar pdf-outline-minor-mode-map
|
||||
(let ((km (make-sparse-keymap)))
|
||||
(define-key km (kbd "o") 'pdf-outline)
|
||||
(define-key km (kbd "o") #'pdf-outline)
|
||||
km)
|
||||
"Keymap used for `pdf-outline-minor-mode'.")
|
||||
|
||||
(defvar pdf-outline-buffer-mode-map
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(dotimes (i 10)
|
||||
(define-key kmap (vector (+ i ?0)) 'digit-argument))
|
||||
(define-key kmap "-" 'negative-argument)
|
||||
(define-key kmap (kbd "p") 'previous-line)
|
||||
(define-key kmap (kbd "n") 'next-line)
|
||||
(define-key kmap (kbd "b") 'outline-backward-same-level)
|
||||
(define-key kmap (kbd "d") 'hide-subtree)
|
||||
(define-key kmap (kbd "a") 'show-all)
|
||||
(define-key kmap (kbd "s") 'show-subtree)
|
||||
(define-key kmap (kbd "f") 'outline-forward-same-level)
|
||||
(define-key kmap (kbd "u") 'pdf-outline-up-heading)
|
||||
(define-key kmap (kbd "Q") 'hide-sublevels)
|
||||
(define-key kmap (kbd "<") 'beginning-of-buffer)
|
||||
(define-key kmap (kbd ">") 'pdf-outline-end-of-buffer)
|
||||
(define-key kmap (kbd "TAB") 'outline-toggle-children)
|
||||
(define-key kmap (kbd "RET") 'pdf-outline-follow-link)
|
||||
(define-key kmap (kbd "C-o") 'pdf-outline-display-link)
|
||||
(define-key kmap (kbd "SPC") 'pdf-outline-display-link)
|
||||
(define-key kmap [mouse-1] 'pdf-outline-mouse-display-link)
|
||||
(define-key kmap (kbd "o") 'pdf-outline-select-pdf-window)
|
||||
(define-key kmap (kbd ".") 'pdf-outline-move-to-current-page)
|
||||
;; (define-key kmap (kbd "Q") 'pdf-outline-quit)
|
||||
(define-key kmap (kbd "C-c C-q") 'pdf-outline-quit-and-kill)
|
||||
(define-key kmap (kbd "q") 'quit-window)
|
||||
(define-key kmap (kbd "M-RET") 'pdf-outline-follow-link-and-quit)
|
||||
(define-key kmap (kbd "C-c C-f") 'pdf-outline-follow-mode)
|
||||
(define-key kmap (vector (+ i ?0)) #'digit-argument))
|
||||
(define-key kmap "-" #'negative-argument)
|
||||
(define-key kmap (kbd "p") #'previous-line)
|
||||
(define-key kmap (kbd "n") #'next-line)
|
||||
(define-key kmap (kbd "b") #'outline-backward-same-level)
|
||||
(define-key kmap (kbd "d") #'hide-subtree)
|
||||
(define-key kmap (kbd "a") #'show-all)
|
||||
(define-key kmap (kbd "s") #'show-subtree)
|
||||
(define-key kmap (kbd "f") #'outline-forward-same-level)
|
||||
(define-key kmap (kbd "u") #'pdf-outline-up-heading)
|
||||
(define-key kmap (kbd "Q") #'hide-sublevels)
|
||||
(define-key kmap (kbd "<") #'beginning-of-buffer)
|
||||
(define-key kmap (kbd ">") #'pdf-outline-end-of-buffer)
|
||||
(define-key kmap (kbd "TAB") #'outline-toggle-children)
|
||||
(define-key kmap (kbd "RET") #'pdf-outline-follow-link)
|
||||
(define-key kmap (kbd "C-o") #'pdf-outline-display-link)
|
||||
(define-key kmap (kbd "SPC") #'pdf-outline-display-link)
|
||||
(define-key kmap [mouse-1] #'pdf-outline-mouse-display-link)
|
||||
(define-key kmap (kbd "o") #'pdf-outline-select-pdf-window)
|
||||
(define-key kmap (kbd ".") #'pdf-outline-move-to-current-page)
|
||||
;; (define-key kmap (kbd "Q") #'pdf-outline-quit)
|
||||
(define-key kmap (kbd "C-c C-q") #'pdf-outline-quit-and-kill)
|
||||
(define-key kmap (kbd "q") #'quit-window)
|
||||
(define-key kmap (kbd "M-RET") #'pdf-outline-follow-link-and-quit)
|
||||
(define-key kmap (kbd "C-c C-f") #'pdf-outline-follow-mode)
|
||||
kmap)
|
||||
"Keymap used in `pdf-outline-buffer-mode'.")
|
||||
|
||||
@@ -141,7 +141,7 @@ Additionally the same outline may be viewed in a designated
|
||||
buffer.
|
||||
|
||||
\\{pdf-outline-minor-mode-map}"
|
||||
nil nil nil
|
||||
:group 'pdf-outline
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(cond
|
||||
(pdf-outline-minor-mode
|
||||
@@ -155,7 +155,7 @@ buffer.
|
||||
"View and traverse the outline of a PDF file.
|
||||
|
||||
Press \\[pdf-outline-display-link] to display the PDF document,
|
||||
\\[pdf-outline-select-pdf-window] to select it's window,
|
||||
\\[pdf-outline-select-pdf-window] to select its window,
|
||||
\\[pdf-outline-move-to-current-page] to move to the outline item
|
||||
of the current page, \\[pdf-outline-follow-link] to goto the
|
||||
corresponding page or \\[pdf-outline-follow-link-and-quit] to
|
||||
@@ -186,13 +186,13 @@ rebound to their respective last character.
|
||||
|
||||
(define-minor-mode pdf-outline-follow-mode
|
||||
"Display links as point moves."
|
||||
nil nil nil
|
||||
:group 'pdf-outline
|
||||
(setq pdf-outline-follow-mode-last-link nil)
|
||||
(cond
|
||||
(pdf-outline-follow-mode
|
||||
(add-hook 'post-command-hook 'pdf-outline-follow-mode-pch nil t))
|
||||
(add-hook 'post-command-hook #'pdf-outline-follow-mode-pch nil t))
|
||||
(t
|
||||
(remove-hook 'post-command-hook 'pdf-outline-follow-mode-pch t))))
|
||||
(remove-hook 'post-command-hook #'pdf-outline-follow-mode-pch t))))
|
||||
|
||||
(defun pdf-outline-follow-mode-pch ()
|
||||
(let ((link (pdf-outline-link-at-pos (point))))
|
||||
@@ -229,6 +229,7 @@ buffer, unless NO-SELECT-WINDOW-P is non-nil."
|
||||
(buffer-exists-p (get-buffer bname))
|
||||
(buffer (get-buffer-create bname)))
|
||||
(with-current-buffer buffer
|
||||
(setq-local fill-column pdf-outline-fill-column)
|
||||
(unless buffer-exists-p
|
||||
(when (= 0 (save-excursion
|
||||
(pdf-outline-insert-outline pdf-buffer)))
|
||||
@@ -313,7 +314,7 @@ Open nodes as necessary."
|
||||
(pdf-outline-move-to-page page)))
|
||||
|
||||
(defun pdf-outline-quit-and-kill ()
|
||||
"Quit browsing the outline and kill it's buffer."
|
||||
"Quit browsing the outline and kill its buffer."
|
||||
(interactive)
|
||||
(pdf-outline-quit t))
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
;;
|
||||
;; The backward search uses a heuristic, which is pretty simple, but
|
||||
;; effective: It extracts the text around the click-position in the
|
||||
;; PDF, normalizes it's whitespace, deletes certain notorious
|
||||
;; character and translates certain other character into their latex
|
||||
;; PDF, normalizes its whitespace, deletes certain notorious
|
||||
;; characters and translates certain other characters into their latex
|
||||
;; equivalents. This transformed text is split into a series of
|
||||
;; token. A similar operation is performed on the source code around
|
||||
;; the position synctex points at. These two sequences of token are
|
||||
@@ -43,11 +43,10 @@
|
||||
:group 'pdf-tools)
|
||||
|
||||
(defcustom pdf-sync-forward-display-pdf-key "C-c C-g"
|
||||
"Key to jump from a TeX buffer to it's PDF file.
|
||||
"Key to jump from a TeX buffer to its PDF file.
|
||||
|
||||
This key is added to `TeX-source-correlate-method', when
|
||||
command `pdf-sync-minor-mode' is activated and this map is defined."
|
||||
:group 'pdf-sync
|
||||
:type 'key-sequence)
|
||||
|
||||
(make-obsolete-variable
|
||||
@@ -58,7 +57,6 @@ command `pdf-sync-minor-mode' is activated and this map is defined."
|
||||
"Hook ran after going to a source location.
|
||||
|
||||
The hook is run in the TeX buffer."
|
||||
:group 'pdf-sync
|
||||
:type 'hook
|
||||
:options '(pdf-sync-backward-beginning-of-word))
|
||||
|
||||
@@ -66,17 +64,14 @@ The hook is run in the TeX buffer."
|
||||
"Hook ran after displaying the PDF buffer.
|
||||
|
||||
The hook is run in the PDF's buffer."
|
||||
:group 'pdf-sync
|
||||
:type 'hook)
|
||||
|
||||
(defcustom pdf-sync-forward-display-action nil
|
||||
"Display action used when displaying PDF buffers."
|
||||
:group 'pdf-sync
|
||||
:type 'display-buffer--action-custom-type)
|
||||
|
||||
(defcustom pdf-sync-backward-display-action nil
|
||||
"Display action used when displaying TeX buffers."
|
||||
:group 'pdf-sync
|
||||
:type 'display-buffer--action-custom-type)
|
||||
|
||||
(defcustom pdf-sync-locate-synctex-file-functions nil
|
||||
@@ -86,13 +81,12 @@ Each function on this hook should accept a single argument: The
|
||||
absolute path of a PDF file. It should return the absolute path
|
||||
of the corresponding synctex database or nil, if it was unable to
|
||||
locate it."
|
||||
:group 'pdf-sync
|
||||
:type 'hook)
|
||||
|
||||
(defvar pdf-sync-minor-mode-map
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(define-key kmap [double-mouse-1] 'pdf-sync-backward-search-mouse)
|
||||
(define-key kmap [C-mouse-1] 'pdf-sync-backward-search-mouse)
|
||||
(define-key kmap [double-mouse-1] #'pdf-sync-backward-search-mouse)
|
||||
(define-key kmap [C-mouse-1] #'pdf-sync-backward-search-mouse)
|
||||
kmap))
|
||||
|
||||
(defcustom pdf-sync-backward-redirect-functions nil
|
||||
@@ -110,7 +104,6 @@ none) values modified.
|
||||
AUCTeX installs a function here which changes the backward search
|
||||
location for synthetic `TeX-region' files back to the equivalent
|
||||
position in the original tex file."
|
||||
:group 'pdf-sync
|
||||
:type '(repeat function))
|
||||
|
||||
|
||||
@@ -132,8 +125,7 @@ to `pdf-sync-forward-search' in `TeX-source-correlate-map'. This
|
||||
function displays the PDF page corresponding to the current
|
||||
position in the TeX buffer. This function only works together
|
||||
with AUCTeX."
|
||||
|
||||
nil nil nil
|
||||
:group 'pdf-sync
|
||||
(pdf-util-assert-pdf-buffer))
|
||||
|
||||
|
||||
@@ -146,7 +138,6 @@ with AUCTeX."
|
||||
|
||||
If nil, just go where Synctex tells us. Otherwise try to find
|
||||
the exact location of the clicked-upon text in the PDF."
|
||||
:group 'pdf-sync
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom pdf-sync-backward-text-translations
|
||||
@@ -258,13 +249,12 @@ the exact location of the clicked-upon text in the PDF."
|
||||
(9830 "diamondsuit"))
|
||||
"Alist mapping PDF character to a list of LaTeX macro names.
|
||||
|
||||
Adding a character here with it's LaTeX equivalent names allows
|
||||
the heuristic backward search to find it's location in the source
|
||||
Adding a character here with its LaTeX equivalent names allows
|
||||
the heuristic backward search to find its location in the source
|
||||
file. These strings should not match
|
||||
`pdf-sync-backward-source-flush-regexp'.
|
||||
|
||||
Has no effect if `pdf-sync-backward-use-heuristic' is nil."
|
||||
:group 'pdf-sync
|
||||
:type '(alist :key-type character
|
||||
:value-type (repeat string)))
|
||||
|
||||
@@ -321,7 +311,7 @@ point to the correct position."
|
||||
.line .column)))
|
||||
(cl-destructuring-bind (source line column)
|
||||
(or (save-selected-window
|
||||
(apply 'run-hook-with-args-until-success
|
||||
(apply #'run-hook-with-args-until-success
|
||||
'pdf-sync-backward-redirect-functions data))
|
||||
data)
|
||||
(list source
|
||||
@@ -539,23 +529,20 @@ word-level searching is desired."
|
||||
|
||||
(define-minor-mode pdf-sync-backward-debug-minor-mode
|
||||
"Aid in debugging the backward search."
|
||||
nil nil nil
|
||||
(if (and (fboundp 'advice-add)
|
||||
(fboundp 'advice-remove))
|
||||
(let ((functions
|
||||
'(pdf-sync-backward-search
|
||||
pdf-sync-backward--tokenize
|
||||
pdf-util-seq-alignment)))
|
||||
(cond
|
||||
(pdf-sync-backward-debug-minor-mode
|
||||
(dolist (fn functions)
|
||||
(advice-add fn :around (apply-partially 'pdf-sync-backward-debug-wrapper
|
||||
fn)
|
||||
`((name . ,(format "%s-debug" fn))))))
|
||||
(t
|
||||
(dolist (fn functions)
|
||||
(advice-remove fn (format "%s-debug" fn))))))
|
||||
(error "Need Emacs version >= 24.4")))
|
||||
:group 'pdf-sync
|
||||
(let ((functions
|
||||
'(pdf-sync-backward-search
|
||||
pdf-sync-backward--tokenize
|
||||
pdf-util-seq-alignment)))
|
||||
(cond
|
||||
(pdf-sync-backward-debug-minor-mode
|
||||
(dolist (fn functions)
|
||||
(advice-add fn :around
|
||||
(apply-partially #'pdf-sync-backward-debug-wrapper fn)
|
||||
`((name . ,(format "%s-debug" fn))))))
|
||||
(t
|
||||
(dolist (fn functions)
|
||||
(advice-remove fn (format "%s-debug" fn)))))))
|
||||
|
||||
(defun pdf-sync-backward-debug-explain ()
|
||||
"Explain the last backward search.
|
||||
@@ -592,7 +579,7 @@ Needs to have `pdf-sync-backward-debug-minor-mode' enabled."
|
||||
(insert
|
||||
(mapconcat (lambda (elt)
|
||||
(if (consp elt)
|
||||
(mapconcat 'identity elt or-sep)
|
||||
(mapconcat #'identity elt or-sep)
|
||||
elt))
|
||||
(nth 2 (cdr text)) " "))
|
||||
(point)))
|
||||
@@ -605,7 +592,7 @@ Needs to have `pdf-sync-backward-debug-minor-mode' enabled."
|
||||
(insert (propertize "Source Token:" 'face 'font-lock-keyword-face))
|
||||
(insert sep)
|
||||
(fill-region (point)
|
||||
(progn (insert (mapconcat 'identity (nth 2 (cdr source)) " "))
|
||||
(progn (insert (mapconcat #'identity (nth 2 (cdr source)) " "))
|
||||
(point)))
|
||||
(insert sep)
|
||||
|
||||
@@ -618,7 +605,7 @@ Needs to have `pdf-sync-backward-debug-minor-mode' enabled."
|
||||
(dolist (a (cdr (cdr alignment)))
|
||||
(let* ((source (cdr a))
|
||||
(text (if (consp (car a))
|
||||
(mapconcat 'identity (car a) or-sep)
|
||||
(mapconcat #'identity (car a) or-sep)
|
||||
(car a)))
|
||||
(extend (max (length text)
|
||||
(length source))))
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
(define-package "pdf-tools" "20200512.1524" "Support library for PDF documents."
|
||||
(define-package "pdf-tools" "20220103.308" "Support library for PDF documents"
|
||||
'((emacs "24.3")
|
||||
(nadvice "0.3")
|
||||
(tablist "1.0")
|
||||
(let-alist "1.0.4"))
|
||||
:commit "c510442ab89c8a9e9881230eeb364f4663f59e76" :keywords
|
||||
'("files" "multimedia")
|
||||
:authors
|
||||
'(("Andreas Politz" . "politza@fh-trier.de"))
|
||||
:commit "ed1d4fc4b02eaf40fbaa7a1a8a2c59eff2a8555d" :authors
|
||||
'(("Andreas Politz" . "mail@andreas-politz.de"))
|
||||
:maintainer
|
||||
'("Andreas Politz" . "politza@fh-trier.de"))
|
||||
'("Vedang Manerikar" . "vedang.manerikar@gmail.com")
|
||||
:keywords
|
||||
'("files" "multimedia")
|
||||
:url "http://github.com/vedang/pdf-tools/")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
;;; pdf-tools.el --- Support library for PDF documents. -*- lexical-binding:t -*-
|
||||
;;; pdf-tools.el --- Support library for PDF documents -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2013, 2014 Andreas Politz
|
||||
|
||||
;; Author: Andreas Politz <politza@fh-trier.de>
|
||||
;; Author: Andreas Politz <mail@andreas-politz.de>
|
||||
;; Maintainer: Vedang Manerikar <vedang.manerikar@gmail.com>
|
||||
;; URL: http://github.com/vedang/pdf-tools/
|
||||
;; Keywords: files, multimedia
|
||||
;; Package: pdf-tools
|
||||
;; Version: 1.0
|
||||
;; Package-Requires: ((emacs "24.3") (tablist "1.0") (let-alist "1.0.4"))
|
||||
;; Version: 1.0.0snapshot
|
||||
;; Package-Requires: ((emacs "24.3") (nadvice "0.3") (tablist "1.0") (let-alist "1.0.4"))
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
@@ -28,8 +30,11 @@
|
||||
;; e.g. ghostscript and stored in the file-system, but rather created
|
||||
;; on-demand and stored in memory.
|
||||
;;
|
||||
;; Note: This package requires external libraries and works currently
|
||||
;; only on GNU/Linux systems.
|
||||
;; Note: This package is built and tested on GNU/Linux systems. It
|
||||
;; works on macOS and Windows, but is officially supported only on
|
||||
;; GNU/Linux systems. This package will not make macOS or Windows
|
||||
;; specific functionality changes, behaviour on these systems is
|
||||
;; provided as-is.
|
||||
;;
|
||||
;; Note: If you ever update it, you need to restart Emacs afterwards.
|
||||
;;
|
||||
@@ -68,7 +73,7 @@
|
||||
;; back to the PDF file.
|
||||
;;
|
||||
;; * Attachments
|
||||
;; Save files attached to the PDF-file or list them in a dired buffer.
|
||||
;; Save files attached to the PDF-file or list them in a Dired buffer.
|
||||
;;
|
||||
;; * Outline
|
||||
;; Use imenu or a special buffer to examine and navigate the PDF's
|
||||
@@ -303,10 +308,11 @@ Returns the buffer of the compilation process."
|
||||
(unless callback (setq callback #'ignore))
|
||||
(unless build-directory
|
||||
(setq build-directory (pdf-tools-locate-build-directory)))
|
||||
(cl-check-type target-directory file-directory)
|
||||
(cl-check-type target-directory (satisfies file-directory-p))
|
||||
(setq target-directory (file-name-as-directory
|
||||
(expand-file-name target-directory)))
|
||||
(cl-check-type build-directory (and (not null) file-directory))
|
||||
(cl-check-type build-directory (and (not null)
|
||||
(satisfies file-directory-p)))
|
||||
(when (and skip-dependencies-p force-dependencies-p)
|
||||
(error "Can't simultaneously skip and force dependencies"))
|
||||
(let* ((compilation-auto-jump-to-first-error nil)
|
||||
@@ -424,7 +430,7 @@ See `pdf-view-mode' and `pdf-tools-enabled-modes'."
|
||||
(when (memq 'pdf-virtual-global-minor-mode
|
||||
pdf-tools-enabled-modes)
|
||||
(pdf-virtual-global-minor-mode 1))
|
||||
(add-hook 'pdf-view-mode-hook 'pdf-tools-enable-minor-modes)
|
||||
(add-hook 'pdf-view-mode-hook #'pdf-tools-enable-minor-modes)
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(when (and (not (derived-mode-p 'pdf-view-mode))
|
||||
@@ -442,7 +448,7 @@ See `pdf-view-mode' and `pdf-tools-enabled-modes'."
|
||||
(remove pdf-tools-magic-mode-alist-entry magic-mode-alist))
|
||||
(pdf-occur-global-minor-mode -1)
|
||||
(pdf-virtual-global-minor-mode -1)
|
||||
(remove-hook 'pdf-view-mode-hook 'pdf-tools-enable-minor-modes)
|
||||
(remove-hook 'pdf-view-mode-hook #'pdf-tools-enable-minor-modes)
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(when (pdf-util-pdf-buffer-p buf)
|
||||
@@ -450,7 +456,9 @@ See `pdf-view-mode' and `pdf-tools-enabled-modes'."
|
||||
(normal-mode)))))
|
||||
|
||||
(defun pdf-tools-pdf-buffer-p (&optional buffer)
|
||||
"Return non-nil if BUFFER contains a PDF document."
|
||||
"Check if the current buffer is a PDF document.
|
||||
|
||||
Optionally, take BUFFER as an argument and check if it is a PDF document."
|
||||
(save-current-buffer
|
||||
(when buffer (set-buffer buffer))
|
||||
(save-excursion
|
||||
@@ -460,10 +468,14 @@ See `pdf-view-mode' and `pdf-tools-enabled-modes'."
|
||||
(looking-at "%PDF")))))
|
||||
|
||||
(defun pdf-tools-assert-pdf-buffer (&optional buffer)
|
||||
"Throw an error if the current BUFFER does not contain a PDF document."
|
||||
(unless (pdf-tools-pdf-buffer-p buffer)
|
||||
(error "Buffer does not contain a PDF document")))
|
||||
|
||||
(defun pdf-tools-set-modes-enabled (enable &optional modes)
|
||||
"Enable/Disable all the pdf-tools modes on the current buffer based on ENABLE.
|
||||
|
||||
Accepts MODES as a optional argument to enable/disable specific modes."
|
||||
(dolist (m (or modes pdf-tools-enabled-modes))
|
||||
(let ((enabled-p (and (boundp m)
|
||||
(symbol-value m))))
|
||||
@@ -493,6 +505,7 @@ MODES defaults to `pdf-tools-enabled-modes'."
|
||||
|
||||
;;;###autoload
|
||||
(defun pdf-tools-help ()
|
||||
"Show a Help buffer for `pdf-tools'."
|
||||
(interactive)
|
||||
(help-setup-xref (list #'pdf-tools-help)
|
||||
(called-interactively-p 'interactive))
|
||||
@@ -500,7 +513,7 @@ MODES defaults to `pdf-tools-enabled-modes'."
|
||||
(princ "PDF Tools Help\n\n")
|
||||
(princ "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
|
||||
(dolist (m (cons 'pdf-view-mode
|
||||
(sort (copy-sequence pdf-tools-modes) 'string<)))
|
||||
(sort (copy-sequence pdf-tools-modes) #'string<)))
|
||||
(princ (format "`%s' is " m))
|
||||
(describe-function-1 m)
|
||||
(terpri) (terpri)
|
||||
@@ -515,6 +528,7 @@ MODES defaults to `pdf-tools-enabled-modes'."
|
||||
"Non-nil, if debugging PDF Tools.")
|
||||
|
||||
(defun pdf-tools-toggle-debug ()
|
||||
"Turn debugging on/off for pdf-tools."
|
||||
(interactive)
|
||||
(setq pdf-tools-debug (not pdf-tools-debug))
|
||||
(when (called-interactively-p 'any)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'pdf-macs)
|
||||
(require 'cl-lib)
|
||||
(require 'format-spec)
|
||||
(require 'faces)
|
||||
@@ -33,10 +34,7 @@
|
||||
;; which won't succeed, if pdf-view.el isn't loaded.
|
||||
(declare-function pdf-view-image-size "pdf-view")
|
||||
(declare-function pdf-view-image-offset "pdf-view")
|
||||
(declare-function pdf-view-current-image "pdf-view")
|
||||
(declare-function pdf-view-current-overlay "pdf-view")
|
||||
(declare-function pdf-cache-pagesize "pdf-cache")
|
||||
|
||||
(declare-function pdf-view-image-type "pdf-view")
|
||||
|
||||
|
||||
@@ -73,7 +71,7 @@ remove the entry if the new value is `eql' to DEFAULT."
|
||||
|
||||
(require 'register)
|
||||
(unless (fboundp 'register-read-with-preview)
|
||||
(defalias 'register-read-with-preview 'read-char
|
||||
(defalias 'register-read-with-preview #'read-char
|
||||
"Compatibility alias for pdf-tools."))
|
||||
|
||||
;; In Emacs 24.3 window-width does not have a PIXELWISE argument.
|
||||
@@ -93,6 +91,7 @@ remove the entry if the new value is `eql' to DEFAULT."
|
||||
(require 'image-mode)
|
||||
(defvar image-mode-winprops-original-function
|
||||
(symbol-function 'image-mode-winprops))
|
||||
(defvar image-mode-winprops-alist)
|
||||
(eval-after-load "image-mode"
|
||||
'(defun image-mode-winprops (&optional window cleanup)
|
||||
(if (not (eq major-mode 'pdf-view-mode))
|
||||
@@ -304,6 +303,42 @@ See `pdf-util-scale' for the LIST-OF-EDGES-OR-POS argument."
|
||||
result
|
||||
(car result)))))
|
||||
|
||||
(defmacro pdf-util-with-edges (list-of-edges &rest body)
|
||||
"Provide some convenient macros for the edges in LIST-OF-EDGES.
|
||||
|
||||
LIST-OF-EDGES should be a list of variables \(X ...\), each one
|
||||
holding a list of edges. Inside BODY the symbols X-left, X-top,
|
||||
X-right, X-bot, X-width and X-height expand to their respective
|
||||
values."
|
||||
|
||||
(declare (indent 1) (debug (sexp &rest form)))
|
||||
(unless (cl-every 'symbolp list-of-edges)
|
||||
(error "Argument should be a list of symbols"))
|
||||
(let ((list-of-syms
|
||||
(mapcar (lambda (edge)
|
||||
(cons edge (mapcar
|
||||
(lambda (kind)
|
||||
(intern (format "%s-%s" edge kind)))
|
||||
'(left top right bot width height))))
|
||||
list-of-edges)))
|
||||
(macroexpand-all
|
||||
`(cl-symbol-macrolet
|
||||
,(apply #'nconc
|
||||
(mapcar
|
||||
(lambda (edge-syms)
|
||||
(let ((edge (nth 0 edge-syms))
|
||||
(syms (cdr edge-syms)))
|
||||
`((,(pop syms) (nth 0 ,edge))
|
||||
(,(pop syms) (nth 1 ,edge))
|
||||
(,(pop syms) (nth 2 ,edge))
|
||||
(,(pop syms) (nth 3 ,edge))
|
||||
(,(pop syms) (- (nth 2 ,edge)
|
||||
(nth 0 ,edge)))
|
||||
(,(pop syms) (- (nth 3 ,edge)
|
||||
(nth 1 ,edge))))))
|
||||
list-of-syms))
|
||||
,@body))))
|
||||
|
||||
(defun pdf-util-edges-transform (region elts &optional to-region-p)
|
||||
"Translate ELTS according to REGION.
|
||||
|
||||
@@ -356,43 +391,6 @@ depending on the input."
|
||||
result
|
||||
(car result))))))
|
||||
|
||||
(defmacro pdf-util-with-edges (list-of-edges &rest body)
|
||||
"Provide some convenient macros for the edges in LIST-OF-EDGES.
|
||||
|
||||
LIST-OF-EDGES should be a list of variables \(X ...\), each one
|
||||
holding a list of edges. Inside BODY the symbols X-left, X-top,
|
||||
X-right, X-bot, X-width and X-height expand to their respective
|
||||
values."
|
||||
|
||||
(declare (indent 1) (debug (sexp &rest form)))
|
||||
(unless (cl-every 'symbolp list-of-edges)
|
||||
(error "Argument should be a list of symbols"))
|
||||
(let ((list-of-syms
|
||||
(mapcar (lambda (edge)
|
||||
(cons edge (mapcar
|
||||
(lambda (kind)
|
||||
(intern (format "%s-%s" edge kind)))
|
||||
'(left top right bot width height))))
|
||||
list-of-edges)))
|
||||
(macroexpand-all
|
||||
`(cl-symbol-macrolet
|
||||
,(apply 'nconc
|
||||
(mapcar
|
||||
(lambda (edge-syms)
|
||||
(let ((edge (nth 0 edge-syms))
|
||||
(syms (cdr edge-syms)))
|
||||
`((,(pop syms) (nth 0 ,edge))
|
||||
(,(pop syms) (nth 1 ,edge))
|
||||
(,(pop syms) (nth 2 ,edge))
|
||||
(,(pop syms) (nth 3 ,edge))
|
||||
(,(pop syms) (- (nth 2 ,edge)
|
||||
(nth 0 ,edge)))
|
||||
(,(pop syms) (- (nth 3 ,edge)
|
||||
(nth 1 ,edge))))))
|
||||
list-of-syms))
|
||||
,@body))))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Scrolling
|
||||
;; * ================================================================== *
|
||||
@@ -416,7 +414,7 @@ Returns a list of pixel edges."
|
||||
(+ x0 (- (nth 2 edges) (nth 0 edges)))))
|
||||
(y1 (min (cdr isize)
|
||||
(+ y0 (- (nth 3 edges) (nth 1 edges))))))
|
||||
(mapcar 'round (list x0 y0 x1 y1))))
|
||||
(mapcar #'round (list x0 y0 x1 y1))))
|
||||
|
||||
(defun pdf-util-required-hscroll (edges &optional eager-p context-pixel)
|
||||
"Return the amount of scrolling necessary, to make image EDGES visible.
|
||||
@@ -467,9 +465,11 @@ Keep CONTEXT-PIXEL pixel of the image visible at the bottom and
|
||||
top of the window. CONTEXT-PIXEL defaults to an equivalent pixel
|
||||
value of `next-screen-context-lines'.
|
||||
|
||||
Return the required vscroll in lines or nil, if scrolling is not
|
||||
needed."
|
||||
Return the required vscroll in pixels or nil, if scrolling is not
|
||||
needed.
|
||||
|
||||
Note: For versions of emacs before 27 this will return lines instead of
|
||||
pixels. This is because of a change that occurred to `image-mode' in 27."
|
||||
(pdf-util-assert-pdf-window)
|
||||
(let* ((win (window-inside-pixel-edges))
|
||||
(image-height (cdr (pdf-view-image-size t)))
|
||||
@@ -483,20 +483,28 @@ needed."
|
||||
(frame-char-height))))
|
||||
;;Be careful not to modify edges.
|
||||
(edges-top (- edges-top context-pixel))
|
||||
(edges-bot (+ edges-bot context-pixel)))
|
||||
(if (< edges-top image-top)
|
||||
(round (/ (max 0 (if eager-p
|
||||
(- edges-bot win-height)
|
||||
edges-top))
|
||||
(float (frame-char-height))))
|
||||
(if (> (min image-height
|
||||
edges-bot)
|
||||
(+ image-top win-height))
|
||||
(round (/ (min (- image-height win-height)
|
||||
(if eager-p
|
||||
edges-top
|
||||
(- edges-bot win-height)))
|
||||
(float (frame-char-height))))))))))
|
||||
(edges-bot (+ edges-bot context-pixel))
|
||||
(vscroll
|
||||
(cond ((< edges-top image-top)
|
||||
(max 0 (if eager-p
|
||||
(- edges-bot win-height)
|
||||
edges-top)))
|
||||
((> (min image-height
|
||||
edges-bot)
|
||||
(+ image-top win-height))
|
||||
(min (- image-height win-height)
|
||||
(if eager-p
|
||||
edges-top
|
||||
(- edges-bot win-height)))))))
|
||||
|
||||
|
||||
(when vscroll
|
||||
(round
|
||||
;; `image-set-window-vscroll' changed in version 27 to using
|
||||
;; pixels, not lines.
|
||||
(if (version< emacs-version "27")
|
||||
(/ vscroll (float (frame-char-height)))
|
||||
vscroll)))))))
|
||||
|
||||
(defun pdf-util-scroll-to-edges (edges &optional eager-p)
|
||||
"Scroll window such that image EDGES are visible.
|
||||
@@ -549,14 +557,9 @@ killed."
|
||||
(let ((temporary-file-directory
|
||||
pdf-util--base-directory))
|
||||
(setq pdf-util--dedicated-directory
|
||||
(make-temp-file (convert-standard-filename
|
||||
(concat (if buffer-file-name
|
||||
(file-name-nondirectory
|
||||
buffer-file-name)
|
||||
(buffer-name))
|
||||
"-"))
|
||||
(make-temp-file (convert-standard-filename (pdf-util-temp-prefix))
|
||||
t))
|
||||
(add-hook 'kill-buffer-hook 'pdf-util-delete-dedicated-directory
|
||||
(add-hook 'kill-buffer-hook #'pdf-util-delete-dedicated-directory
|
||||
nil t)))
|
||||
pdf-util--dedicated-directory))
|
||||
|
||||
@@ -568,13 +571,21 @@ killed."
|
||||
"Expand filename against current buffer's dedicated directory."
|
||||
(expand-file-name name (pdf-util-dedicated-directory)))
|
||||
|
||||
(defun pdf-util-make-temp-file (prefix &optional dir-flag suffix)
|
||||
(defun pdf-util-temp-prefix ()
|
||||
"Create a temp-file prefix for the current buffer"
|
||||
(concat (if buffer-file-name
|
||||
(file-name-nondirectory buffer-file-name)
|
||||
(replace-regexp-in-string "[^[:alnum:]]+" "-" (buffer-name)))
|
||||
"-"))
|
||||
|
||||
(defun pdf-util-make-temp-file (&optional prefix dir-flag suffix)
|
||||
"Create a temporary file in current buffer's dedicated directory.
|
||||
|
||||
See `make-temp-file' for the arguments."
|
||||
(let ((temporary-file-directory
|
||||
(pdf-util-dedicated-directory)))
|
||||
(make-temp-file (convert-standard-filename prefix) dir-flag suffix)))
|
||||
(let ((temporary-file-directory (pdf-util-dedicated-directory)))
|
||||
(make-temp-file (convert-standard-filename
|
||||
(or prefix (pdf-util-temp-prefix)))
|
||||
dir-flag suffix)))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
@@ -636,7 +647,7 @@ Signal an error, if color is invalid."
|
||||
(let ((values (color-values color)))
|
||||
(unless values
|
||||
(signal 'wrong-type-argument (list 'color-defined-p color)))
|
||||
(apply 'format "#%02x%02x%02x"
|
||||
(apply #'format "#%02x%02x%02x"
|
||||
(mapcar (lambda (c) (lsh c -8))
|
||||
values)))))
|
||||
|
||||
@@ -678,6 +689,10 @@ string."
|
||||
,@tooltip-frame-parameters)))
|
||||
(tooltip-show text)))
|
||||
|
||||
;; FIXME: Defined in `pdf-view' but we can't require it here because it
|
||||
;; requires us :-(
|
||||
(defvar pdf-view-midnight-colors)
|
||||
|
||||
(defun pdf-util-tooltip-arrow (image-top &optional timeout)
|
||||
(pdf-util-assert-pdf-window)
|
||||
(when (floatp image-top)
|
||||
@@ -713,14 +728,18 @@ string."
|
||||
'face `(:foreground
|
||||
"orange red"
|
||||
:background
|
||||
,(if (bound-and-true-p pdf-view-midnight-minor-mode)
|
||||
(cdr pdf-view-midnight-colors)
|
||||
"white"))))
|
||||
,(cond
|
||||
((bound-and-true-p pdf-view-midnight-minor-mode)
|
||||
(cdr pdf-view-midnight-colors))
|
||||
((bound-and-true-p pdf-view-themed-minor-mode)
|
||||
(face-background 'default nil))
|
||||
(t "white")))))
|
||||
dx dy)))
|
||||
|
||||
(defvar pdf-util--face-colors-cache (make-hash-table))
|
||||
|
||||
(defadvice enable-theme (after pdf-util-clear-faces-cache activate)
|
||||
(advice-add 'enable-theme :after #'pdf-util--clear-faces-cache)
|
||||
(defun pdf-util--clear-faces-cache (&rest _)
|
||||
(clrhash pdf-util--face-colors-cache))
|
||||
|
||||
(defun pdf-util-face-colors (face &optional dark-p)
|
||||
@@ -747,7 +766,7 @@ colors, otherwise light."
|
||||
(let ((colors
|
||||
(cons (face-attribute face :foreground nil 'default)
|
||||
(face-attribute face :background nil 'default))))
|
||||
(puthash face `(,(mapcar 'copy-sequence spec)
|
||||
(puthash face `(,(mapcar #'copy-sequence spec)
|
||||
((,bg . ,colors) ,@color-alist))
|
||||
pdf-util--face-colors-cache)
|
||||
colors)
|
||||
@@ -844,15 +863,14 @@ them is nil, it means there is gap at this position in the
|
||||
respective sequence."
|
||||
|
||||
(cl-macrolet ((make-matrix (rows columns)
|
||||
(list 'apply (list 'quote 'vector)
|
||||
(list 'cl-loop 'for 'i 'from 1 'to rows
|
||||
'collect (list 'make-vector columns nil))))
|
||||
`(apply #'vector
|
||||
(cl-loop for i from 1 to ,rows
|
||||
collect (make-vector ,columns nil))))
|
||||
(mset (matrix row column newelt)
|
||||
(list 'aset (list 'aref matrix row) column newelt))
|
||||
`(aset (aref ,matrix ,row) ,column ,newelt))
|
||||
(mref (matrix row column)
|
||||
(list 'aref (list 'aref matrix row) column)))
|
||||
(let* ((nil-value nil)
|
||||
(len1 (length seq1))
|
||||
`(aref (aref ,matrix ,row) ,column)))
|
||||
(let* ((len1 (length seq1))
|
||||
(len2 (length seq2))
|
||||
(d (make-matrix (1+ len1) (1+ len2)))
|
||||
(prefix-p (memq alignment-type '(prefix infix)))
|
||||
@@ -888,7 +906,7 @@ respective sequence."
|
||||
(= (mref d i j)
|
||||
(1- (mref d (1- i) j))))
|
||||
(cl-decf i)
|
||||
(push (cons (elt seq1 i) nil-value) alignment))
|
||||
(push (cons (elt seq1 i) nil) alignment))
|
||||
((and (> j 0)
|
||||
(= (mref d i j)
|
||||
(+ (mref d i (1- j))
|
||||
@@ -896,13 +914,14 @@ respective sequence."
|
||||
(and (= i len1) prefix-p))
|
||||
0 -1))))
|
||||
(cl-decf j)
|
||||
(push (cons nil-value (elt seq2 j)) alignment))
|
||||
(push (cons nil (elt seq2 j)) alignment))
|
||||
(t
|
||||
(cl-assert (and (> i 0) (> j 0)) t)
|
||||
(cl-decf i)
|
||||
(cl-decf j)
|
||||
(push (cons (elt seq1 i)
|
||||
(elt seq2 j)) alignment))))
|
||||
(elt seq2 j))
|
||||
alignment))))
|
||||
(cons (mref d len1 len2) alignment)))))
|
||||
|
||||
|
||||
@@ -919,7 +938,7 @@ See also `regexp-quote'."
|
||||
(when (memq ch to-escape)
|
||||
(push ?\\ escaped))
|
||||
(push ch escaped))
|
||||
(apply 'string (nreverse escaped))))
|
||||
(apply #'string (nreverse escaped))))
|
||||
|
||||
(defun pdf-util-frame-ppi ()
|
||||
"Return the PPI of the current frame."
|
||||
@@ -936,15 +955,14 @@ See also `regexp-quote'."
|
||||
|
||||
(defun pdf-util-frame-scale-factor ()
|
||||
"Return the frame scale factor depending on the image type used for display.
|
||||
When `pdf-view-use-scaling' is non-nil and imagemagick or
|
||||
image-io are used as the image type for display, return the
|
||||
backing-scale-factor of the frame if available. If a
|
||||
backing-scale-factor attribute isn't available, return 2 if the
|
||||
When `pdf-view-use-scaling' is non-nil, return the scale factor of the frame
|
||||
if available. If the scale factor isn't available, return 2 if the
|
||||
frame's PPI is larger than 180. Otherwise, return 1."
|
||||
(if (and pdf-view-use-scaling
|
||||
(memq (pdf-view-image-type) '(imagemagick image-io))
|
||||
(fboundp 'frame-monitor-attributes))
|
||||
(or (cdr (assq 'backing-scale-factor (frame-monitor-attributes)))
|
||||
(if pdf-view-use-scaling
|
||||
(or (and (fboundp 'frame-scale-factor)
|
||||
(truncate (frame-scale-factor)))
|
||||
(and (fboundp 'frame-monitor-attributes)
|
||||
(cdr (assq 'backing-scale-factor (frame-monitor-attributes))))
|
||||
(if (>= (pdf-util-frame-ppi) 180)
|
||||
2
|
||||
1))
|
||||
@@ -1045,10 +1063,10 @@ of the last commands given earlier in SPEC. E.g. a call like
|
||||
image-file out-file
|
||||
:foreground \"black\"
|
||||
:background \"white\"
|
||||
:commands '\(\"-fill\" \"%f\" \"-draw\" \"rectangle %x,%y,%X,%Y\"\)
|
||||
:apply '\(\(0 0 10 10\) \(10 10 20 20\)\)
|
||||
:commands '\(\"-fill\" \"%b\" \"-draw\" \"rectangle %x,%y,%X,%Y\"\)
|
||||
:apply '\(\(10 0 20 10\) \(0 10 10 20\)\)\)
|
||||
:commands '(\"-fill\" \"%f\" \"-draw\" \"rectangle %x,%y,%X,%Y\")
|
||||
:apply '((0 0 10 10) (10 10 20 20))
|
||||
:commands '(\"-fill\" \"%b\" \"-draw\" \"rectangle %x,%y,%X,%Y\")
|
||||
:apply '((10 0 20 10) (0 10 10 20)))
|
||||
|
||||
would draw a 4x4 checkerboard pattern in the left corner of the
|
||||
image, while leaving the rest of it as it was.
|
||||
@@ -1058,7 +1076,7 @@ Returns OUT-FILE.
|
||||
See url `http://www.imagemagick.org/script/convert.php'."
|
||||
(pdf-util-assert-convert-program)
|
||||
(let* ((cmds (pdf-util-convert--create-commands spec))
|
||||
(status (apply 'call-process
|
||||
(status (apply #'call-process
|
||||
pdf-util-convert-program nil
|
||||
(get-buffer-create "*pdf-util-convert-output*")
|
||||
nil
|
||||
@@ -1083,7 +1101,7 @@ Returns the convert process."
|
||||
callback nil))
|
||||
(let* ((cmds (pdf-util-convert--create-commands spec))
|
||||
(proc
|
||||
(apply 'start-process "pdf-util-convert"
|
||||
(apply #'start-process "pdf-util-convert"
|
||||
(get-buffer-create "*pdf-util-convert-output*")
|
||||
pdf-util-convert-program
|
||||
`(,in-file ,@cmds ,out-file))))
|
||||
@@ -1108,7 +1126,7 @@ Return the converted PNG image as a string. See also
|
||||
(set-buffer-file-coding-system 'binary)
|
||||
(insert image-data))
|
||||
(pdf-util-munch-file
|
||||
(apply 'pdf-util-convert
|
||||
(apply #'pdf-util-convert
|
||||
in-file out-file specs)))
|
||||
(when (file-exists-p in-file)
|
||||
(delete-file in-file))
|
||||
@@ -1210,10 +1228,10 @@ If RELATIVE-P is non-nil, also check that all values <= 1."
|
||||
(defun pdf-util-edges-union (&rest edges)
|
||||
(if (null (cdr edges))
|
||||
(car edges)
|
||||
(list (apply 'min (mapcar 'car edges))
|
||||
(apply 'min (mapcar 'cadr edges))
|
||||
(apply 'max (mapcar 'cl-caddr edges))
|
||||
(apply 'max (mapcar 'cl-cadddr edges)))))
|
||||
(list (apply #'min (mapcar #'car edges))
|
||||
(apply #'min (mapcar #'cadr edges))
|
||||
(apply #'max (mapcar #'cl-caddr edges))
|
||||
(apply #'max (mapcar #'cl-cadddr edges)))))
|
||||
|
||||
(defun pdf-util-edges-intersection-area (e1 e2)
|
||||
(let ((inters (pdf-util-edges-intersection e1 e2)))
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
;;; Code:
|
||||
|
||||
(require 'image-mode)
|
||||
(require 'pdf-macs)
|
||||
(require 'pdf-util)
|
||||
(require 'pdf-info)
|
||||
(require 'pdf-cache)
|
||||
@@ -33,7 +34,7 @@
|
||||
(require 'password-cache)
|
||||
|
||||
(declare-function cua-copy-region "cua-base")
|
||||
|
||||
(declare-function pdf-tools-pdf-buffer-p "pdf-tools")
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Customizations
|
||||
@@ -91,10 +92,7 @@ FIXME: Explain dis-/advantages of imagemagick and png."
|
||||
This variable affects both the reuse of higher-resolution images
|
||||
as lower-resolution ones by down-scaling the image. As well as
|
||||
the rendering of higher-resolution for high-resolution displays,
|
||||
if available.
|
||||
|
||||
It has no effect, unless either the imagemagick or image-io
|
||||
image-format is available."
|
||||
if available."
|
||||
:group 'pdf-view
|
||||
:type 'boolean)
|
||||
|
||||
@@ -113,7 +111,7 @@ image-format is available."
|
||||
:group 'pdf-tools-faces)
|
||||
|
||||
(defcustom pdf-view-midnight-colors '("#839496" . "#002b36" )
|
||||
"Colors used when `pdf-view-midnight-minor-mode' is activated.
|
||||
"Colors used when command `pdf-view-midnight-minor-mode' is activated.
|
||||
|
||||
This should be a cons \(FOREGROUND . BACKGROUND\) of colors."
|
||||
:group 'pdf-view
|
||||
@@ -169,7 +167,7 @@ See :relief property in Info node `(elisp) Image Descriptors'."
|
||||
:type '(integer :tag "Pixel"))
|
||||
|
||||
(defcustom pdf-view-use-unicode-ligther t
|
||||
"Whether to use unicode symbols in the mode-line
|
||||
"Decide whether to use unicode symbols in the mode-line.
|
||||
|
||||
On some systems finding a font which supports those symbols can
|
||||
take some time. If you don't want to spend that time waiting and
|
||||
@@ -222,29 +220,6 @@ regarding display of the region in the later function.")
|
||||
(defvar-local pdf-view-register-alist nil
|
||||
"Local, dedicated register for PDF positions.")
|
||||
|
||||
(defmacro pdf-view-current-page (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'page ,window))
|
||||
|
||||
(defmacro pdf-view-current-overlay (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'overlay ,window))
|
||||
|
||||
(defmacro pdf-view-current-image (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'image ,window))
|
||||
|
||||
(defmacro pdf-view-current-slice (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'slice ,window))
|
||||
|
||||
(defmacro pdf-view-current-window-size (&optional window)
|
||||
;;TODO: write documentation!
|
||||
`(image-mode-window-get 'window-size ,window))
|
||||
|
||||
(defmacro pdf-view-window-needs-redisplay (&optional window)
|
||||
`(image-mode-window-get 'needs-redisplay ,window))
|
||||
|
||||
(defun pdf-view-current-pagelabel (&optional window)
|
||||
(nth (1- (pdf-view-current-page window)) (pdf-info-pagelabels)))
|
||||
|
||||
@@ -259,7 +234,7 @@ regarding display of the region in the later function.")
|
||||
|
||||
(defconst pdf-view-have-image-mode-pixel-vscroll
|
||||
(>= emacs-major-version 27)
|
||||
"Whether image-mode scrolls vertically by pixels.")
|
||||
"Whether `image-mode' scrolls vertically by pixels.")
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
@@ -282,10 +257,14 @@ regarding display of the region in the later function.")
|
||||
(define-key map (kbd "DEL") 'pdf-view-scroll-down-or-previous-page)
|
||||
(define-key map (kbd "C-n") 'pdf-view-next-line-or-next-page)
|
||||
(define-key map (kbd "<down>") 'pdf-view-next-line-or-next-page)
|
||||
(define-key map (kbd "C-p") 'pdf-view-previous-line-or-previous-page)
|
||||
(define-key map (kbd "<up>") 'pdf-view-previous-line-or-previous-page)
|
||||
(define-key map (kbd "M-<") 'pdf-view-first-page)
|
||||
(define-key map (kbd "M->") 'pdf-view-last-page)
|
||||
(define-key map [remap next-line] 'pdf-view-next-line-or-next-page)
|
||||
(define-key map (kbd "C-p") 'pdf-view-previous-line-or-previous-page)
|
||||
(define-key map (kbd "<up>") 'pdf-view-previous-line-or-previous-page)
|
||||
(define-key map [remap previous-line] 'pdf-view-previous-line-or-previous-page)
|
||||
(define-key map (kbd "M-<") 'pdf-view-first-page)
|
||||
(define-key map [remap beginning-of-buffer] 'pdf-view-first-page)
|
||||
(define-key map (kbd "M->") 'pdf-view-last-page)
|
||||
(define-key map [remap end-of-buffer] 'pdf-view-last-page)
|
||||
(define-key map [remap goto-line] 'pdf-view-goto-page)
|
||||
(define-key map (kbd "M-g l") 'pdf-view-goto-label)
|
||||
(define-key map (kbd "RET") 'image-next-line)
|
||||
@@ -305,7 +284,6 @@ regarding display of the region in the later function.")
|
||||
;; Reconvert
|
||||
(define-key map (kbd "C-c C-c") 'doc-view-mode)
|
||||
(define-key map (kbd "g") 'revert-buffer)
|
||||
(define-key map (kbd "r") 'revert-buffer)
|
||||
;; Region
|
||||
(define-key map [down-mouse-1] 'pdf-view-mouse-set-region)
|
||||
(define-key map [M-down-mouse-1] 'pdf-view-mouse-set-region-rectangle)
|
||||
@@ -321,6 +299,7 @@ regarding display of the region in the later function.")
|
||||
(define-key map (kbd "C-c C-i") 'pdf-view-extract-region-image)
|
||||
;; Rendering
|
||||
(define-key map (kbd "C-c C-r m") 'pdf-view-midnight-minor-mode)
|
||||
(define-key map (kbd "C-c C-r t") 'pdf-view-themed-minor-mode)
|
||||
(define-key map (kbd "C-c C-r p") 'pdf-view-printer-minor-mode)
|
||||
map)
|
||||
"Keymap used by `pdf-view-mode' when displaying a doc as a set of images.")
|
||||
@@ -339,12 +318,7 @@ PNG images in Emacs buffers."
|
||||
(not (and buffer-file-name
|
||||
(file-readable-p buffer-file-name)))))
|
||||
(pdf-tools-pdf-buffer-p))
|
||||
(let ((tempfile (pdf-util-make-temp-file
|
||||
(concat (if buffer-file-name
|
||||
(file-name-nondirectory
|
||||
buffer-file-name)
|
||||
(buffer-name))
|
||||
"-"))))
|
||||
(let ((tempfile (pdf-util-make-temp-file)))
|
||||
(write-region nil nil tempfile nil 'no-message)
|
||||
(setq-local pdf-view--buffer-file-name tempfile)))
|
||||
;; Decryption needs to be done before any other function calls into
|
||||
@@ -426,16 +400,15 @@ PNG images in Emacs buffers."
|
||||
(current-buffer)))
|
||||
|
||||
(unless (version< emacs-version "24.4")
|
||||
(advice-add 'cua-copy-region
|
||||
:before-until
|
||||
#'cua-copy-region--pdf-view-advice)
|
||||
(defun cua-copy-region--pdf-view-advice (&rest _)
|
||||
"If the current buffer is in `pdf-view' mode, call
|
||||
`pdf-view-kill-ring-save'."
|
||||
(when (eq major-mode 'pdf-view-mode)
|
||||
(pdf-view-kill-ring-save)
|
||||
t))
|
||||
|
||||
(advice-add 'cua-copy-region
|
||||
:before-until
|
||||
#'cua-copy-region--pdf-view-advice))
|
||||
t)))
|
||||
|
||||
(defun pdf-view-check-incompatible-modes (&optional buffer)
|
||||
"Check BUFFER for incompatible modes, maybe issue a warning."
|
||||
@@ -606,6 +579,9 @@ For example, (pdf-view-shrink 1.25) decreases size by 20%."
|
||||
;; * Moving by pages and scrolling
|
||||
;; * ================================================================== *
|
||||
|
||||
(defvar pdf-view-inhibit-redisplay nil)
|
||||
(defvar pdf-view-inhibit-hotspots nil)
|
||||
|
||||
(defun pdf-view-goto-page (page &optional window)
|
||||
"Go to PAGE in PDF.
|
||||
|
||||
@@ -626,7 +602,7 @@ windows."
|
||||
(save-selected-window
|
||||
;; Select the window for the hooks below.
|
||||
(when (window-live-p window)
|
||||
(select-window window))
|
||||
(select-window window 'norecord))
|
||||
(let ((changing-p
|
||||
(not (eq page (pdf-view-current-page window)))))
|
||||
(when changing-p
|
||||
@@ -809,9 +785,9 @@ displayed page number."
|
||||
;; * ================================================================== *
|
||||
|
||||
(defun pdf-view-set-slice (x y width height &optional window)
|
||||
;; TODO: add WINDOW to docstring.
|
||||
"Set the slice of the pages that should be displayed.
|
||||
"Set the slice of the pages that should be displayed in WINDOW.
|
||||
|
||||
WINDOW defaults to `selected-window' if not provided.
|
||||
X, Y, WIDTH and HEIGHT should be relative coordinates, i.e. in
|
||||
\[0;1\]. To reset the slice use `pdf-view-reset-slice'."
|
||||
(unless (equal (pdf-view-current-slice window)
|
||||
@@ -848,9 +824,10 @@ dragging it to its bottom-right corner. See also
|
||||
(/ 1.0 (float (cdr size))))))))
|
||||
|
||||
(defun pdf-view-set-slice-from-bounding-box (&optional window)
|
||||
;; TODO: add WINDOW to docstring.
|
||||
"Set the slice from the page's bounding-box.
|
||||
|
||||
WINDOW defaults to `selected-window' if not provided.
|
||||
|
||||
The result is that the margins are almost completely cropped,
|
||||
much more accurate than could be done manually using
|
||||
`pdf-view-set-slice-using-mouse'.
|
||||
@@ -871,8 +848,9 @@ See also `pdf-view-bounding-box-margin'."
|
||||
(append slice (and window (list window))))))
|
||||
|
||||
(defun pdf-view-reset-slice (&optional window)
|
||||
;; TODO: add WINDOW to doctring.
|
||||
"Reset the current slice.
|
||||
"Reset the current slice and redisplay WINDOW.
|
||||
|
||||
WINDOW defaults to `selected-window' if not provided.
|
||||
|
||||
After calling this function the whole page will be visible
|
||||
again."
|
||||
@@ -886,7 +864,7 @@ again."
|
||||
"Automatically slice pages according to their bounding boxes.
|
||||
|
||||
See also `pdf-view-set-slice-from-bounding-box'."
|
||||
nil nil nil
|
||||
:group 'pdf-view
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(cond
|
||||
(pdf-view-auto-slice-minor-mode
|
||||
@@ -896,17 +874,15 @@ See also `pdf-view-set-slice-from-bounding-box'."
|
||||
(add-hook 'pdf-view-change-page-hook
|
||||
'pdf-view-set-slice-from-bounding-box nil t))
|
||||
(t
|
||||
(remove-hook 'pdf-view-change-page-hook
|
||||
'pdf-view-set-slice-from-bounding-box t))))
|
||||
(progn (remove-hook 'pdf-view-change-page-hook
|
||||
'pdf-view-set-slice-from-bounding-box t)
|
||||
(pdf-view-reset-slice)))))
|
||||
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Display
|
||||
;; * ================================================================== *
|
||||
|
||||
(defvar pdf-view-inhibit-redisplay nil)
|
||||
(defvar pdf-view-inhibit-hotspots nil)
|
||||
|
||||
(defun pdf-view-image-type ()
|
||||
"Return the image type that should be used.
|
||||
|
||||
@@ -928,12 +904,6 @@ See also `pdf-view-use-imagemagick'."
|
||||
(t
|
||||
(error "PNG image supported not compiled into Emacs"))))
|
||||
|
||||
(defun pdf-view-use-scaling-p ()
|
||||
"Return t if scaling should be used."
|
||||
(and (memq (pdf-view-image-type)
|
||||
'(imagemagick image-io))
|
||||
pdf-view-use-scaling))
|
||||
|
||||
(defmacro pdf-view-create-image (data &rest props)
|
||||
;; TODO: add DATA and PROPS to docstring.
|
||||
"Like `create-image', but with set DATA-P and TYPE arguments."
|
||||
@@ -952,7 +922,7 @@ See also `pdf-view-use-imagemagick'."
|
||||
(let* ((size (pdf-view-desired-image-size page window))
|
||||
(data (pdf-cache-renderpage
|
||||
page (car size)
|
||||
(if (not (pdf-view-use-scaling-p))
|
||||
(if (not pdf-view-use-scaling)
|
||||
(car size)
|
||||
(* 2 (car size)))))
|
||||
(hotspots (pdf-view-apply-hotspot-functions
|
||||
@@ -1167,7 +1137,7 @@ This will display a text cursor, when hovering over them."
|
||||
"Mode for PDF documents with dark background.
|
||||
|
||||
This tells the various modes to use their face's dark colors."
|
||||
nil nil nil
|
||||
:group 'pdf-view
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
;; FIXME: This should really be run in a hook.
|
||||
(when (bound-and-true-p pdf-isearch-active-mode)
|
||||
@@ -1178,7 +1148,8 @@ This tells the various modes to use their face's dark colors."
|
||||
|
||||
(define-minor-mode pdf-view-printer-minor-mode
|
||||
"Display the PDF as it would be printed."
|
||||
nil " Prn" nil
|
||||
:group 'pdf-view
|
||||
:lighter " Prn"
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(let ((enable (lambda ()
|
||||
(pdf-info-setoptions :render/printed t))))
|
||||
@@ -1198,8 +1169,8 @@ This tells the various modes to use their face's dark colors."
|
||||
|
||||
The colors are determined by the variable
|
||||
`pdf-view-midnight-colors', which see. "
|
||||
|
||||
nil " Mid" nil
|
||||
:group 'pdf-view
|
||||
:lighter " Mid"
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
;; FIXME: Maybe these options should be passed stateless to pdf-info-renderpage ?
|
||||
(let ((enable (lambda ()
|
||||
@@ -1219,6 +1190,43 @@ The colors are determined by the variable
|
||||
(pdf-cache-clear-images)
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
(defun pdf-view-refresh-themed-buffer (&optional get-theme)
|
||||
"Refresh the current buffer to activate applied colors.
|
||||
|
||||
When GET-THEME is non-nil, also reset the applied colors to the
|
||||
current theme's colors."
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(pdf-cache-clear-images)
|
||||
(when get-theme
|
||||
(pdf-view-set-theme-background))
|
||||
(pdf-view-redisplay t))
|
||||
|
||||
(defun pdf-view-set-theme-background ()
|
||||
"Set the buffer's color filter to correspond to the current Emacs theme."
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(pdf-info-setoptions
|
||||
:render/foreground (face-foreground 'default nil)
|
||||
:render/background (face-background 'default nil)
|
||||
:render/usecolors t))
|
||||
|
||||
(define-minor-mode pdf-view-themed-minor-mode
|
||||
"Synchronize color filter with the present Emacs theme.
|
||||
|
||||
The colors are determined by the `face-foreground' and
|
||||
`face-background' of the currently active theme."
|
||||
:group 'pdf-view
|
||||
:lighter " Thm"
|
||||
(pdf-util-assert-pdf-buffer)
|
||||
(cond
|
||||
(pdf-view-themed-minor-mode
|
||||
(add-hook 'after-save-hook #'pdf-view-set-theme-background nil t)
|
||||
(add-hook 'after-revert-hook #'pdf-view-set-theme-background nil t))
|
||||
(t
|
||||
(remove-hook 'after-save-hook #'pdf-view-set-theme-background t)
|
||||
(remove-hook 'after-revert-hook #'pdf-view-set-theme-background t)
|
||||
(pdf-info-setoptions :render/usecolors nil)))
|
||||
(pdf-view-refresh-themed-buffer pdf-view-themed-minor-mode))
|
||||
|
||||
(when pdf-view-use-unicode-ligther
|
||||
;; This check uses an implementation detail, which hopefully gets the
|
||||
;; right answer.
|
||||
@@ -1261,7 +1269,7 @@ supersede hotspots in lower ones."
|
||||
;; TODO: write documentation!
|
||||
(unless pdf-view-inhibit-hotspots
|
||||
(save-selected-window
|
||||
(when window (select-window window))
|
||||
(when window (select-window window 'norecord))
|
||||
(apply 'nconc
|
||||
(mapcar (lambda (fn)
|
||||
(funcall fn page image-size))
|
||||
@@ -1418,7 +1426,8 @@ This is more useful for commands like
|
||||
`(,(car colors) ,(cdr colors) 0.35 ,@region))
|
||||
(pdf-info-renderpage-text-regions
|
||||
page width nil nil
|
||||
`(,(car colors) ,(cdr colors) ,@region)))))))
|
||||
`(,(car colors) ,(cdr colors) ,@region)))
|
||||
:width width))))
|
||||
|
||||
(defun pdf-view-kill-ring-save ()
|
||||
"Copy the region to the `kill-ring'."
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
;; order to transparently make this collection appear as one single
|
||||
;; document.
|
||||
;;
|
||||
;; The trickiest part is to make theses intermediate functions behave
|
||||
;; The trickiest part is to make these intermediate functions behave
|
||||
;; like the pdf-info-* equivalents in both the synchronous and
|
||||
;; asynchronous case.
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
(require 'pdf-info)
|
||||
(require 'pdf-util)
|
||||
|
||||
(declare-function pdf-view-mode "pdf-view.el")
|
||||
|
||||
;; * ================================================================== *
|
||||
;; * Variables
|
||||
@@ -477,8 +478,8 @@ PAGE should be a page-number."
|
||||
;;;###autoload
|
||||
(define-minor-mode pdf-virtual-global-minor-mode
|
||||
"Enable recognition and handling of VPDF files."
|
||||
nil nil nil
|
||||
:global t
|
||||
:group 'pdf-tools
|
||||
(let ((elt `(,pdf-virtual-magic-mode-regexp . pdf-virtual-view-mode)))
|
||||
(cond
|
||||
(pdf-virtual-global-minor-mode
|
||||
@@ -518,7 +519,7 @@ PAGE should be a page-number."
|
||||
(concat " " f))
|
||||
unreadable "\n"))))
|
||||
(if (= (pdf-virtual-document-number-of-pages) 0)
|
||||
(error "Docüment is empty.")
|
||||
(error "Document is empty.")
|
||||
(unless pdf-virtual-global-minor-mode
|
||||
(pdf-virtual-global-minor-mode 1))
|
||||
(funcall fn))))
|
||||
@@ -567,7 +568,7 @@ PAGE should be a page-number."
|
||||
|
||||
(defun pdf-virtual-view-window-p (&optional window)
|
||||
(save-selected-window
|
||||
(when window (select-window window))
|
||||
(when window (select-window window 'norecord))
|
||||
(derived-mode-p 'pdf-virtual-view-mode)))
|
||||
|
||||
(defun pdf-virtual-filename-p (filename)
|
||||
|
||||
Reference in New Issue
Block a user