summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cask3
-rw-r--r--Makefile4
-rw-r--r--lisp/pdf-cache.el2
-rw-r--r--lisp/pdf-info.el153
-rw-r--r--lisp/pdf-isearch.el16
-rw-r--r--lisp/pdf-links.el164
-rw-r--r--lisp/pdf-occur.el15
-rw-r--r--lisp/pdf-outline.el95
-rw-r--r--lisp/pdf-sync.el25
-rw-r--r--lisp/pdf-tools.el2
-rw-r--r--test/pdf-info.ert64
11 files changed, 252 insertions, 291 deletions
diff --git a/Cask b/Cask
index 239b875..e67bd57 100644
--- a/Cask
+++ b/Cask
@@ -8,4 +8,5 @@
"server/epdfinfo")
(development
- (depends-on "emacs" "24.3"))
+ (depends-on "emacs" "24.3")
+ (depends-on "let-alist"))
diff --git a/Makefile b/Makefile
index d93fb40..0d740f3 100644
--- a/Makefile
+++ b/Makefile
@@ -54,10 +54,10 @@ server/configure: server/configure.ac
cd server && ./autogen.sh
bytecompile:
- $(EMACS) $(EFLAGS) -f batch-byte-compile lisp/*.el
+ cask exec $(EMACS) $(EFLAGS) -f batch-byte-compile lisp/*.el
test: all
- $(EMACS) $(EFLAGS) -l test/run-tests.el $(PACKAGE_NAME).tar
+ cask exec $(EMACS) $(EFLAGS) -l test/run-tests.el $(PACKAGE_NAME).tar
check: bytecompile test
diff --git a/lisp/pdf-cache.el b/lisp/pdf-cache.el
index 1103e06..216d90c 100644
--- a/lisp/pdf-cache.el
+++ b/lisp/pdf-cache.el
@@ -378,7 +378,7 @@ See also `pdf-info-renderpage-highlight' and
(mapcar
'cl-cadddr
(cl-remove-if-not
- (lambda (link) (eq (cadr link) 'goto-dest))
+ (lambda (link) (eq (assq 'type link) 'goto-dest))
(pdf-cache-pagelinks
(pdf-view-current-page)))))))))
diff --git a/lisp/pdf-info.el b/lisp/pdf-info.el
index 1bb8db9..36c5520 100644
--- a/lisp/pdf-info.el
+++ b/lisp/pdf-info.el
@@ -414,38 +414,28 @@ interrupted."
(string-to-number (cadr elt))))
response))
((search-string search-regexp)
- (let* ((matches
- (mapcar
- (lambda (r)
- `(,(string-to-number (nth 0 r))
- ,(let (case-fold-search)
+ (mapcar
+ (lambda (r)
+ `((page . ,(string-to-number (nth 0 r)))
+ (text . ,(let (case-fold-search)
(pdf-util-highlight-regexp-in-string
- (regexp-quote (nth 1 r)) (nth 2 r)))
- ,@(mapcar (lambda (m)
+ (regexp-quote (nth 1 r)) (nth 2 r))))
+ (edges . ,(mapcar (lambda (m)
(mapcar 'string-to-number
(split-string m " " t)))
- (cddr (cdr r)))))
- response))
- result)
- (while matches
- (let ((page (caar matches))
- items)
- (while (and matches
- (= (caar matches) page))
- (push (cdr (pop matches)) items))
- (push (cons page (nreverse items)) result)))
- (nreverse result)))
+ (cddr (cdr r))))))
+ response))
(outline
(mapcar (lambda (r)
- (cons (string-to-number (pop r))
- (pdf-info-query--transform-action r)))
+ `((depth . ,(string-to-number (pop r)))
+ ,@(pdf-info-query--transform-action r)))
response))
(pagelinks
(mapcar (lambda (r)
- (cons
- (mapcar 'string-to-number ;area
- (split-string (pop r) " " t))
- (pdf-info-query--transform-action r)))
+ `((edges .
+ ,(mapcar 'string-to-number ;area
+ (split-string (pop r) " " t)))
+ ,@(pdf-info-query--transform-action r)))
response))
(metadata
(let ((md (car response)))
@@ -482,11 +472,16 @@ interrupted."
(mapcar 'pdf-info-query--transform-attachment response))
((getattachment-from-annot)
(pdf-info-query--transform-attachment (car response)))
- ((synctex-forward-search boundingbox)
+ (boundingbox
(mapcar 'string-to-number (car response)))
+ (synctex-forward-search
+ (let ((list (mapcar 'string-to-number (car response))))
+ `((page . ,(car list))
+ (edges . ,(cdr list)))))
(synctex-backward-search
- (cons (caar response)
- (mapcar 'string-to-number (cdar response))))
+ `((filename . ,(caar response))
+ (line . ,(string-to-number (cadr (car response))))
+ (column . ,(string-to-number (cadr (cdar response))))))
(delannot nil)
((save) (caar response))
((renderpage renderpage-text-regions renderpage-highlight)
@@ -509,21 +504,19 @@ interrupted."
(defun pdf-info-query--transform-action (action)
"Transform ACTION response into a Lisp form."
(let ((type (intern (pop action))))
- (cons type
- (cons (pop action)
- (cl-case type
- (goto-dest
- (list (string-to-number (pop action))
- (and (> (length (car action)) 0)
- (string-to-number (pop action)))))
- (goto-remote
- (list (pop action)
- (string-to-number (pop action))
- (and (> (length (car action)) 0)
- (string-to-number (pop action)))
- (and (> (length (car action)) 0)
- (string-to-number (pop action)))))
- (t action))))))
+ `((type . ,type)
+ (title . ,(pop action))
+ ,@(cl-case type
+ (goto-dest
+ `((page . ,(string-to-number (pop action)))
+ (top . ,(and (> (length (car action)) 0)
+ (string-to-number (pop action))))))
+ (goto-remote
+ `((filename . ,(pop action))
+ (page . ,(string-to-number (pop action)))
+ (top . ,(and (> (length (car action)) 0)
+ (string-to-number (pop action))))))
+ (t `((uri . ,(pop action))))))))
(defun pdf-info-query--transform-annotation (a)
(cl-labels ((not-empty (s)
@@ -890,16 +883,18 @@ document."
(pdf-info--normalize-file-or-buffer file-or-buffer)))
(defun pdf-info-search-string (string &optional pages file-or-buffer)
- "Search for STRING in PAGES of docüment FILE-OR-BUFFER.
+ "Search for STRING in PAGES of document FILE-OR-BUFFER.
See `pdf-info-normalize-page-range' for valid PAGES formats.
-This function returns a list \(\((PAGE . MATCHES\) ... \), where
-MATCHES represents a list of matches on PAGE. Each MATCHES item
-looks like \(LINE EDGES\), where EDGES represent the coordinates
-of the match as a list of four relative values \(LEFT TOP RIGHT
-BOTTOM\). LINE is the matched line, containing `match' face
-properties on the matched parts.
+This function returns a list of matches. Each item is an alist
+containing keys PAGE, TEXT and EDGES, where PAGE and TEXT are the
+matched page resp. line. EDGES is a list containing a single
+edges element \(LEFT TOP RIGHT BOTTOM\). This is for consistency
+with `pdf-info-search-regexp', which may return matches with
+multiple edges.
+
+The TEXT contains `match' face properties on the matched parts.
Search is case-insensitive, unless `case-fold-search' is nil and
searching case-sensitive is supported by the server."
@@ -975,15 +970,8 @@ See the glib documentation at url
file-or-buffer)
"Search for a PCRE on PAGES of docüment FILE-OR-BUFFER.
-See `pdf-info-normalize-page-range' for valid PAGES formats.
-
-This function returns a list \(\((PAGE . MATCHES\) ... \), where
-MATCHES represents a list of matches on PAGE. Each MATCHES item
-looks like \(LINE EDGES EDGES ...\), where the EDGES elements
-represent the coordinates of the match, each one beeing a list of
-four relative values \(LEFT TOP RIGHT BOTTOM\). LINE is the
-matched line, containing `match' face properties on the matched
-parts.
+See `pdf-info-normalize-page-range' for valid PAGES formats and
+`pdf-info-search-string' for it's return value.
Uses the flags in `pdf-info-regexp-flags', which see. If
`case-fold-search' is non-nil, the caseless flag is added.
@@ -1031,27 +1019,24 @@ this kind of error as a `invalid-regexp' error."
(defun pdf-info-pagelinks (page &optional file-or-buffer)
"Return a list of links on PAGE in docüment FILE-OR-BUFFER.
-This function returns a list \(\(EDGES . ACTION\) ... \), where
-EDGES has the same form as in `pdf-info-search-string'. ACTION
-represents a PDF Action and has the form \(TYPE TITLE . ARGS\),
-there TYPE is the type of the action, TITLE is a, possibly empty,
-name for this action and ARGS a list of the action's arguments.
+This function returns a list of alists with the following keys.
+EDGES represents the relative bounding-box of the link , TYPE is
+the type of the action, TITLE is a, possibly empty, name for this
+action.
TYPE may be one of
-goto-dest -- This is a internal link to some page. ARGS has the
-form \(PAGE TOP\), where PAGE is the page of the link and TOP
-it's vertical position.
+goto-dest -- This is a internal link to some page. Each element
+contains additional keys PAGE and TOP, where PAGE is the page of
+the link and TOP it's vertical position.
-goto-remote -- This a external link to some document. ARGS is of
-the form \(PDFFILE PAGE TOP\), where PDFFILE is the filename of
-the external PDF, PAGE the page number and TOP the vertical
-position.
+goto-remote -- This a external link to some document. Same as
+goto-dest, with an additional FILENAME of the external PDF.
-uri -- A link in form of some URI. ARGS contains a single
-element, namely the URI.
+uri -- A link in form of some URI. Alist contains additional key
+URI.
-In the first two cases, PAGE may be 0 and TOP be nil, which means
+In the first two cases, PAGE may be 0 and TOP nil, which means
these data is unspecified."
(cl-check-type page natnum)
(pdf-info-query
@@ -1068,10 +1053,9 @@ these data is unspecified."
(defun pdf-info-outline (&optional file-or-buffer)
"Return the PDF outline of document FILE-OR-BUFFER.
-This function returns a list \(\(DEPTH . ACTION\) ... \) of
-outline items, where DEPTH >= 1 is the depth of this element in
-the tree and ACTION has the same format as in
-`pdf-info-pagelinks', which see."
+This function returns a list of alists like `pdf-info-pagelinks'.
+Additionally every alist has a DEPTH (>= 1) entry with the depth
+of this element in the tree."
(pdf-info-query
'outline
@@ -1126,8 +1110,8 @@ aforementioned function, when called with the same arguments."
(defun pdf-info-charlayout (page edges-or-pos &optional file-or-buffer)
"Return the layout of characters of PAGE in/at EDGES-OR-POS.
-Returns a list of elements \(CHAR . \(LEFT TOP RIGHT BOT\)\) of
-character and corresponding boundingboxes.
+Returns a list of elements \(CHAR . \(LEFT TOP RIGHT BOT\)\) mapping
+character to their corresponding relative bounding-boxes.
EDGES-OR-POS may be a region \(LEFT TOP RIGHT BOT\) restricting
the returned value to include only characters fully contained in
@@ -1382,9 +1366,9 @@ corresponding file. LINE and COLUMN represent the position in
the buffer or file. Finally FILE-OR-BUFFER corresponds to the
PDF document.
-Returns a list of \(PAGE LEFT TOP RIGHT BOT\) of coordinates
-describing the position in the PDF document corresponding to the
-SOURCE location."
+Returns an alist with entries PAGE and relative EDGES describing
+the position in the PDF document corresponding to the SOURCE
+location."
(let ((source (if (buffer-live-p (get-buffer source))
(buffer-file-name (get-buffer source))
@@ -1399,10 +1383,11 @@ SOURCE location."
(defun pdf-info-synctex-backward-search (page &optional x y file-or-buffer)
"Perform a backward search with synctex.
-This find the source location corresponding to the coordinates
+Find the source location corresponding to the coordinates
\(X . Y\) on PAGE in FILE-OR-BUFFER.
-Returns a list \(SOURCE LINE COLUMN\)."
+Returns an alist with entries FILENAME, LINE and COLUMN."
+
(pdf-info-query
'synctex-backward-search
diff --git a/lisp/pdf-isearch.el b/lisp/pdf-isearch.el
index 3e0d3c6..5dc6f9b 100644
--- a/lisp/pdf-isearch.el
+++ b/lisp/pdf-isearch.el
@@ -30,6 +30,8 @@
(require 'pdf-misc)
(require 'pdf-view)
(require 'pdf-cache)
+(require 'let-alist)
+
;;; Code:
@@ -439,14 +441,12 @@ Returns a list of edges (LEFT TOP RIGHT BOTTOM) in PDF
coordinates, sorted top to bottom, then left to right."
(unless page (setq page (pdf-view-current-page)))
- (let* ((case-fold-search isearch-case-fold-search)
- (matches
- (cdr (assq page
- (funcall (pdf-isearch-search-fun)
- string page)))))
- (mapcar (lambda (edge-list)
- (pdf-util-scale-relative-to-pixel edge-list 'round))
- (mapcar 'cdr matches))))
+ (mapcar (lambda (match)
+ (let-alist match
+ (pdf-util-scale-relative-to-pixel .edges 'round)))
+ (let ((case-fold-search isearch-case-fold-search))
+ (funcall (pdf-isearch-search-fun)
+ string page))))
(defun pdf-isearch-search-fun ()
(funcall (or pdf-isearch-search-fun-function
diff --git a/lisp/pdf-links.el b/lisp/pdf-links.el
index 86d3160..6138357 100644
--- a/lisp/pdf-links.el
+++ b/lisp/pdf-links.el
@@ -26,6 +26,7 @@
(require 'pdf-misc)
(require 'pdf-cache)
(require 'pdf-isearch)
+(require 'let-alist)
;;; Code:
@@ -129,7 +130,8 @@ links via \\[pdf-links-isearch-link].
(pointer 'hand)
hotspots)
(dolist (l links)
- (let ((e (pdf-util-scale (car l) size 'round))
+ (let ((e (pdf-util-scale
+ (cdr (assq 'edges l)) size 'round))
(id (intern (format id-fmt page
(cl-incf i)))))
(push `((rect . ((,(nth 0 e) . ,(nth 1 e))
@@ -137,112 +139,85 @@ links via \\[pdf-links-isearch-link].
,id
(pointer
,pointer
- help-echo ,(pdf-links-action-to-string (cdr l))))
+ help-echo ,(pdf-links-action-to-string l)))
hotspots)
(local-set-key
(vector id 'mouse-1)
(lambda nil
(interactive "@")
- (pdf-links-action-perform (cdr l))))
+ (pdf-links-action-perform l)))
(local-set-key
(vector id t)
'pdf-util-image-map-mouse-event-proxy)))
(nreverse hotspots)))
-(defun pdf-links-action-to-string (action)
+(defun pdf-links-action-to-string (link)
"Return a string representation of ACTION."
- (let ((title (nth 1 action))
- (str
- (cl-case (car action)
- (goto-dest
- (let ((page (nth 2 action)))
- (if (> page 0)
- (format "Goto page %d" page)
- "Destination not found")))
- (goto-remote
- (let* ((file (nth 2 action))
- (page (nth 3 action))
- (exists-p (and file (file-exists-p file))))
- (cond
- (exists-p
- (format "Goto %sfile '%s'"
- (if (> page 0)
- (format "p. %d of " page)
- "")
- file))
- (t
- (format "Link to nonexistent file '%s'" file)))))
- (launch
- (let* ((prg (nth 2 action))
- (args (nth 3 action))
- (exists-p (and prg (file-executable-p prg))))
- (if exists-p
- (format "Launch '%s' with arguments '%s'"
- prg args)
- (format "Link to nonexecutable program '%s'" prg))))
- (uri
- (let ((uri (nth 2 action)))
- (if (> (length uri) 0)
- (format "Link to uri '%s'" uri)
- (format "Link to empty uri"))))
- (t
- (error "Invalid link-type :%s" (car action))))))
- (if (> (length title) 0)
- (concat str (format " (%s)" title))
- str)))
+ (let-alist link
+ (concat
+ (cl-case .type
+ (goto-dest
+ (if (> .page 0)
+ (format "Goto page %d" .page)
+ "Destination not found"))
+ (goto-remote
+ (if (and .filename (file-exists-p .filename))
+ (format "Goto %sfile '%s'"
+ (if (> .page 0)
+ (format "p.%d of " .page)
+ "")
+ .file)
+ (format "Link to nonexistent file '%s'" .filename)))
+ (uri
+ (if (> (length .uri) 0)
+ (format "Link to uri '%s'" .uri)
+ (format "Link to empty uri")))
+ (t (format "Unrecognized link type: %s" .type)))
+ (if (> (length .title) 0)
+ (format " (%s)" .title)))))
;;;###autoload
-(defun pdf-links-action-perform (action)
- "Invoke ACTION, depending on it's type.
+(defun pdf-links-action-perform (link)
+ "Follow LINK, depending on it's type.
This may turn to another page, switch to another PDF buffer or
invoke `pdf-links-browse-uri-function'.
-Interactively, action is read via `pdf-links-read-link-action'.
+Interactively, link is read via `pdf-links-read-link-action'.
This function displays characters around the links in the current
page and starts reading characters (ignoring case). After a
sufficient number of characters have been read, the corresponding
-link's action is invoked. Additionally, SPC may be used to
+link's link is invoked. Additionally, SPC may be used to
scroll the current page."
(interactive
(list (or (pdf-links-read-link-action "Activate link (SPC scrolls): ")
(error "No link selected"))))
- (let ((type (car action))
- ;; (title (cadr action))
- )
- (cl-case type
+ (let-alist link
+ (cl-case .type
((goto-dest goto-remote)
- (let (file page top)
- (cl-case type
+ (let ((window (selected-window)))
+ (cl-case .type
(goto-dest
- (setq page (nth 2 action)
- top (nth 3 action))
- (unless (> page 0)
+ (unless (> .page 0)
(error "Link points to nowhere")))
(goto-remote
- (setq file (nth 2 action)
- page (nth 3 action)
- top (nth 4 action))
- (unless (file-exists-p file)
- (error "Link points to nonexistent file %s" file))))
-
- (when (and file (file-exists-p file))
- (display-buffer
- (or (find-buffer-visiting file)
- (find-file-noselect file))))
- (when (derived-mode-p 'pdf-view-mode)
- (when (> page 0)
- (pdf-view-goto-page page))
- (when top
- ;; Showing the tooltip is somewhat slow.
- (sit-for 0)
- (pdf-util-tooltip-arrow top)))))
+ (unless (and .filename (file-exists-p .filename))
+ (error "Link points to nonexistent file %s" .filename))
+ (setq window (display-buffer
+ (or (find-buffer-visiting .filename)
+ (find-file-noselect .filename))))))
+ (with-selected-window window
+ (when (derived-mode-p 'pdf-view-mode)
+ (when (> .page 0)
+ (pdf-view-goto-page .page))
+ (when .top
+ ;; Showing the tooltip is somewhat slow.
+ (sit-for 0)
+ (pdf-util-tooltip-arrow .top))))))
(uri
- (funcall pdf-links-browse-uri-function (nth 2 action)))
- ;; (launch
- ;; (shell-command (concat (nth 2 action) " " (nth 3 action))))
+ (funcall pdf-links-browse-uri-function .uri))
(t
- (error "Invalid link:%s" action)))
+ (error "Unrecognized link type: %s" .type)))
nil))
(defun pdf-links-read-link-action (prompt)
@@ -265,13 +240,14 @@ See `pdf-links-action-perform' for the interface."
:foreground (car colors)
:background (cdr colors)
:formats
- `((?c . ,(lambda (_edges) (pop key-strings)))
- (?P . ,(number-to-string
- (max 1 (* (cdr size)
- pdf-links-convert-pointsize-scale)))))
- :commands pdf-links-read-link-convert-commands
- :apply (pdf-util-scale-relative-to-pixel
- (mapcar 'car links)))))
+ `((?c . ,(lambda (_edges) (pop key-strings)))
+ (?P . ,(number-to-string
+ (max 1 (* (cdr size)
+ pdf-links-convert-pointsize-scale)))))
+ :commands pdf-links-read-link-convert-commands
+ :apply (pdf-util-scale-relative-to-pixel
+ (mapcar (lambda (l) (cdr (assq 'edges l)))
+ links)))))
(unless links
(error "No links on this page"))
(unwind-protect
@@ -286,7 +262,7 @@ See `pdf-links-action-perform' for the interface."
(car size) image-data 'pdf-links-read-link-action))
(pdf-view-display-image
(create-image image-data (pdf-view-image-type) t))
- (cdr (pdf-links-read-link-action--read-chars prompt alist)))
+ (pdf-links-read-link-action--read-chars prompt alist))
(pdf-view-redisplay))))
(defun pdf-links-read-link-action--read-chars (prompt alist)
@@ -347,21 +323,23 @@ See `pdf-links-action-perform' for the interface."
(lambda (e)
(= 0 (pdf-util-edges-intersection-area (car e) match)))
(mapcar (lambda (l)
- (cons (pdf-util-scale
- (car l) size)
- (cdr l)))
+ (cons (pdf-util-scale (alist-get 'edges l) size)
+ l))
(pdf-cache-pagelinks page)))
(lambda (e1 e2)
- (> (pdf-util-edges-intersection-area (car e1) match)
- (pdf-util-edges-intersection-area (car e2) match))))))
+ (> (pdf-util-edges-intersection-area
+ (alist-get 'edges e1) match)
+ (pdf-util-edges-intersection-area
+ (alist-get 'edges e2) match))))))
(unless links
(error "No link found at this position"))
- (pdf-links-action-perform (cdar links))))))
+ (pdf-links-action-perform (car links))))))
(defun pdf-links-isearch-link-filter-matches (matches)
(let ((links (pdf-util-scale
- (mapcar 'car (pdf-cache-pagelinks
- (pdf-view-current-page)))
+ (mapcar (apply-partially 'alist-get 'edges)
+ (pdf-cache-pagelinks
+ (pdf-view-current-page)))
(pdf-view-image-size))))
(cl-remove-if-not
(lambda (m)
diff --git a/lisp/pdf-occur.el b/lisp/pdf-occur.el
index ea64e9e..3d7f4b5 100644
--- a/lisp/pdf-occur.el
+++ b/lisp/pdf-occur.el
@@ -29,6 +29,7 @@
(require 'tablist)
(require 'ibuf-ext)
(require 'dired)
+(require 'let-alist)
;;; Code:
@@ -572,12 +573,10 @@ matches linked with PAGE."
(pdf-occur-assert-occur-buffer-p)
(when matches
(let (entries)
- (dolist (page-match matches)
- (let ((page (car page-match))
- (page-matches (cdr page-match)))
- (dolist (match page-matches)
- (push (pdf-occur-create-entry filename page match)
- entries))))
+ (dolist (match matches)
+ (let-alist match
+ (push (pdf-occur-create-entry filename .page (cons .text .edges))
+ entries)))
(setq entries (nreverse entries))
(pdf-occur-insert-entries entries))))
@@ -623,9 +622,7 @@ matches linked with PAGE."
:key 'car
:test 'equal)
(cl-incf pdf-occur-number-of-matches
- (cl-reduce (lambda (n elt)
- (+ n (length (cdr elt))))
- (cons 0 response)))
+ (length response))
(pdf-occur-add-matches document response)
(pdf-occur-update-header-line))))
(lambda (status buffer)
diff --git a/lisp/pdf-outline.el b/lisp/pdf-outline.el
index b6712a1..91a074b 100644
--- a/lisp/pdf-outline.el
+++ b/lisp/pdf-outline.el
@@ -26,6 +26,7 @@
(require 'pdf-view)
(require 'cl-lib)
(require 'imenu)
+(require 'let-alist)
;;; Code:
@@ -248,29 +249,26 @@ buffer, unless NO-SELECT-WINDOW-P is non-nil."
(defun pdf-outline-insert-outline (pdf-file)
(let ((labels (and pdf-outline-display-labels
(pdf-info-pagelabels pdf-file)))
- (outline (cl-remove-if-not
- (lambda (type)
- (eq type 'goto-dest))
- (pdf-info-outline pdf-file)
- :key 'cadr)))
- (dolist (item outline)
- (cl-destructuring-bind (lvl _type title page _top)
- item
- (insert-text-button
- (concat
- (make-string (* (1- lvl) pdf-outline-buffer-indent) ?\s)
- title
- (if (> page 0)
- (format " (%s)"
- (if labels
- (nth (1- page) labels)
- page))
- "(invalid)"))
- 'type 'pdf-outline
- 'help-echo (pdf-links-action-to-string (cdr item))
- 'pdf-outline-link (cdr item))
- (newline)))
- (length outline)))
+ (nitems 0))
+ (dolist (item (pdf-info-outline pdf-file))
+ (let-alist item
+ (when (eq .type 'goto-dest)
+ (insert-text-button
+ (concat
+ (make-string (* (1- .depth) pdf-outline-buffer-indent) ?\s)
+ .title
+ (if (> .page 0)
+ (format " (%s)"
+ (if labels
+ (nth (1- .page) labels)
+ .page))
+ "(invalid)"))
+ 'type 'pdf-outline
+ 'help-echo (pdf-links-action-to-string item)
+ 'pdf-outline-link item)
+ (newline)
+ (cl-incf nitems))))
+ nitems))
(defun pdf-outline-get-pdf-window (&optional if-visible-p)
(save-selected-window
@@ -420,7 +418,7 @@ Then quit the outline window."
(let (curpage)
(save-excursion
(goto-char (point-min))
- (while (and (setq curpage (nth 2 (pdf-outline-link-at-pos)))
+ (while (and (setq curpage (alist-get 'page (pdf-outline-link-at-pos)))
(< curpage page))
(forward-line))
(point))))
@@ -454,12 +452,11 @@ Then quit the outline window."
(use-local-map (keymap-parent (current-local-map)))))
-(defun pdf-outline-imenu-create-item (_lvl link &optional labels)
- (cl-destructuring-bind ( _type title page _top)
- link
- (list (format "%s (%s)" title (if labels
- (nth (1- page) labels)
- page))
+(defun pdf-outline-imenu-create-item (link &optional labels)
+ (let-alist link
+ (list (format "%s (%s)" .title (if labels
+ (nth (1- .page) labels)
+ .page))
0
'pdf-outline-imenu-activate-link
link)))
@@ -468,16 +465,12 @@ Then quit the outline window."
(let ((labels (and pdf-outline-display-labels
(pdf-info-pagelabels
(pdf-view-buffer-file-name))))
- (outline (cl-remove-if-not
- (lambda (type)
- (eq type 'goto-dest))
- (pdf-info-outline (pdf-view-buffer-file-name))
- :key 'cadr))
index)
- (dolist (o outline)
- (push (pdf-outline-imenu-create-item
- (car o) (cdr o) labels)
- index))
+ (dolist (item (pdf-info-outline (pdf-view-buffer-file-name)))
+ (let-alist item
+ (when (eq .type 'goto-dest)
+ (push (pdf-outline-imenu-create-item item labels)
+ index))))
(nreverse index)))
@@ -488,22 +481,20 @@ Then quit the outline window."
(lambda (type)
(eq type 'goto-dest))
(pdf-info-outline (pdf-view-buffer-file-name))
- :key 'cadr))
+ :key (apply-partially 'alist-get 'type)))
(and pdf-outline-display-labels
(pdf-info-pagelabels (pdf-view-buffer-file-name)))))
(defun pdf-outline-imenu-create-index-tree-1 (nodes &optional labels)
(mapcar (lambda (node)
(let (children)
- (when (consp (car node))
+ (when (consp (caar node))
(setq children (cdr node)
node (car node)))
- (let ((title (nth 2 node))
- (item
- (pdf-outline-imenu-create-item
- (car node) (cdr node) labels)))
+ (let ((item
+ (pdf-outline-imenu-create-item node labels)))
(if children
- (cons title
+ (cons (alist-get 'title node)
(cons item (pdf-outline-imenu-create-index-tree-1
children labels)))
item))))
@@ -511,16 +502,16 @@ Then quit the outline window."
(defun pdf-outline-treeify-outline-list (list)
(when list
- (let ((level (caar list))
+ (let ((depth (alist-get 'depth (car list)))
result)
(while (and list
- (>= (caar list)
- level))
- (when (= (caar list) level)
+ (>= (alist-get 'depth (car list))
+ depth))
+ (when (= (alist-get 'depth (car list)) depth)
(let ((item (car list)))
(when (and (cdr list)
- (> (car (cadr list))
- level))
+ (> (alist-get 'depth (cadr list))
+ depth))
(setq item
(cons
item
diff --git a/lisp/pdf-sync.el b/lisp/pdf-sync.el
index 1825211..80221a5 100644
--- a/lisp/pdf-sync.el
+++ b/lisp/pdf-sync.el
@@ -34,6 +34,7 @@
(require 'pdf-view)
(require 'pdf-info)
(require 'pdf-util)
+(require 'let-alist)
;;; Code:
@@ -323,14 +324,13 @@ point to the correct position."
(page (pdf-view-current-page)))
(setq x (/ x (float (car size)))
y (/ y (float (cdr size))))
- (cl-destructuring-bind (source line column)
- (pdf-info-synctex-backward-search page x y)
- (let ((data (list (expand-file-name source)
- line column)))
+ (let-alist (pdf-info-synctex-backward-search page x y)
+ (let ((data (list (expand-file-name .filename)
+ .line .column)))
(cl-destructuring-bind (source line column)
(or (save-selected-window
(apply 'run-hook-with-args-until-success
- 'pdf-sync-backward-redirect-functions data))
+ 'pdf-sync-backward-redirect-functions data))
data)
(list source
(if (not pdf-sync-backward-use-heuristic)
@@ -697,10 +697,11 @@ Returns a list \(PDF PAGE X1 Y1 X2 Y2\)."
(buffer-file-name) pdf)))
(condition-case err
(cons pdf
- (pdf-info-synctex-forward-search
- (or sfilename
- (buffer-file-name))
- line column pdf))
+ (let-alist (pdf-info-synctex-forward-search
+ (or sfilename
+ (buffer-file-name))
+ line column pdf)
+ (cons .page .edges)))
(error
(if (null sfilename)
(signal (car err) (cdr err))
@@ -708,9 +709,9 @@ Returns a list \(PDF PAGE X1 Y1 X2 Y2\)."
;; would actually work for some reason.
(condition-case nil
(cons pdf
- (pdf-info-synctex-forward-search
- (buffer-file-name)
- line column pdf))
+ (let-alist (pdf-info-synctex-forward-search
+ (buffer-file-name) line column pdf)
+ (cons .page .edges)))
(error (signal (car err) (cdr err)))))))))
diff --git a/lisp/pdf-tools.el b/lisp/pdf-tools.el
index 6d8d5f9..ec9e03b 100644
--- a/lisp/pdf-tools.el
+++ b/lisp/pdf-tools.el
@@ -6,7 +6,7 @@
;; Keywords: files, multimedia
;; Package: pdf-tools
;; Version: 0.70
-;; Package-Requires: ((emacs "24.3") (tablist "0.70"))
+;; Package-Requires: ((emacs "24.3") (tablist "0.70") (let-alist))
;; 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
diff --git a/test/pdf-info.ert b/test/pdf-info.ert
index 75e0fb4..82f3e38 100644
--- a/test/pdf-info.ert
+++ b/test/pdf-info.ert
@@ -1,5 +1,6 @@
;; -*- lexical-binding: t -*-
+(require 'let-alist)
(require 'pdf-info)
(require 'ert)
@@ -17,38 +18,44 @@
(ert-deftest pdf-info-search-string ()
(pdf-test-with-test-pdf
- (let (matches)
- (should (setq matches (pdf-info-search-string "PDF Tools")))
- (should (= 1 (length matches)))
- (should (= 2 (length (cdar matches))))
- (should (cl-every 'stringp
- (mapcar 'car (cdar matches))))
- (should (cl-every 'pdf-test-relative-edges-p
- (mapcar 'cadr (cdar matches)))))))
+ (let (matches)
+ (should (setq matches (pdf-info-search-string "PDF Tools")))
+ (should (= 2 (length matches)))
+ (should (cl-every (lambda (m)
+ (let-alist m
+ (and (stringp .text)
+ (cl-every 'pdf-test-relative-edges-p .edges)
+ (= 1 .page))))
+ matches)))))
(ert-deftest pdf-info-search-regexp ()
(pdf-test-with-test-pdf
(let (case-fold-search matches)
(should (setq matches (pdf-info-search-regexp "PDF Tools")))
- (should (= 1 (length matches)))
- (should (= 2 (length (cdar matches))))
- (should (cl-every 'stringp
- (mapcar 'car (cdar matches))))
- (should (cl-every 'pdf-test-relative-edges-p
- (mapcar 'cadr (cdar matches)))))))
+ (should (= 2 (length matches)))
+ (should (cl-every (lambda (m)
+ (let-alist m
+ (and (stringp .text)
+ (cl-every 'pdf-test-relative-edges-p .edges)
+ (= 1 .page))))
+ matches)))))
(ert-deftest pdf-info-pagelinks ()
(pdf-test-with-test-pdf
- (let (links)
- (should (= 2 (length (setq links (pdf-info-pagelinks 3)))))
+ (let ((links (pdf-info-pagelinks 3)))
+ (should (= 2 (length links)))
(should (cl-every 'pdf-test-relative-edges-p
- (mapcar 'car links)))
- (setq links (mapcar 'cdr links))
- (should (equal (mapcar 'car links)
+ (mapcar (apply-partially 'alist-get 'edges)
+ links)))
+ (should (equal (mapcar (apply-partially 'alist-get 'type) links)
'(goto-dest uri)))
- (should (equal (mapcar 'car (mapcar 'cddr links))
- '(1 "http://www.gnu.org"))))))
+ (should (equal (mapcar (apply-partially 'alist-get 'uri)
+ links)
+ '(nil "http://www.gnu.org")))
+ (should (equal (mapcar (apply-partially 'alist-get 'page)
+ links)
+ '(1 nil))))))
(ert-deftest pdf-info-number-of-pages ()
(pdf-test-with-test-pdf
@@ -56,13 +63,14 @@
(ert-deftest pdf-info-outline ()
(pdf-test-with-test-pdf
- (let (outline)
- (should (= 7 (length (setq outline (pdf-info-outline)))))
- (should (equal (mapcar 'car outline)
- '(1 1 1 1 1 2 3)))
- (should (cl-every (lambda (type)
- (equal type 'goto-dest))
- (mapcar 'cadr outline))))))
+ (let ((outline (pdf-info-outline)))
+ (should (= 7 (length outline)))
+ (should (equal (mapcar (apply-partially 'alist-get 'depth) outline)
+ '(1 1 1 1 1 2 3)))
+ (should (cl-every (lambda (elt)
+ (eq (alist-get 'type elt)
+ 'goto-dest))
+ outline)))))
(ert-deftest pdf-info-gettext ()
(pdf-test-with-test-pdf