summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS7
-rw-r--r--lisp/pdf-info.el11
-rw-r--r--lisp/pdf-outline.el39
-rw-r--r--lisp/pdf-view.el14
-rw-r--r--server/epdfinfo.c26
5 files changed, 86 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index ebd588d..0c8f8d7 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,13 @@
M-s w now does a word search, which will also find hyphenated
words (as determined by pdf-isearch-hyphenation-character), though
not at page boundaries.
+** View
+*** Navigate by pagelabels
+ M-g l may be used to jump to a page by label, i.e. it's displayed
+ number.
+** Outline
+ New option `pdf-outline-display-labels', determining whether to
+ display labels instead of plain page-numbers.
* Version 0.50
** PDF Tools is now available on MELPA.
** SyncTeX
diff --git a/lisp/pdf-info.el b/lisp/pdf-info.el
index c706aa9..9e186ca 100644
--- a/lisp/pdf-info.el
+++ b/lisp/pdf-info.el
@@ -489,6 +489,7 @@ interrupted."
((save) (caar response))
((renderpage renderpage-text-regions renderpage-highlight)
(pdf-util-munch-file (caar response)))
+ (pagelabels (mapcar 'car response))
(t response)))
@@ -1495,6 +1496,16 @@ Returns a list \(LEFT TOP RIGHT BOT\)."
(pdf-info--normalize-file-or-buffer file-or-buffer)
page))
+(defun pdf-info-pagelabels (&optional file-or-buffer)
+ "Return a list of pagelabels.
+
+Returns a list of strings corresponding to the labels of the
+pages in FILE-OR-BUFFER."
+
+ (pdf-info-query
+ 'pagelabels
+ (pdf-info--normalize-file-or-buffer file-or-buffer)))
+
(provide 'pdf-info)
;;; pdf-info.el ends here
diff --git a/lisp/pdf-outline.el b/lisp/pdf-outline.el
index 165c059..b6712a1 100644
--- a/lisp/pdf-outline.el
+++ b/lisp/pdf-outline.el
@@ -65,6 +65,13 @@
: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
+ :type 'boolean)
+
(defvar pdf-outline-minor-mode-map
(let ((km (make-sparse-keymap)))
(define-key km (kbd "o") 'pdf-outline)
@@ -239,7 +246,9 @@ buffer, unless NO-SELECT-WINDOW-P is non-nil."
buf))
(defun pdf-outline-insert-outline (pdf-file)
- (let ((outline (cl-remove-if-not
+ (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)
@@ -252,7 +261,10 @@ buffer, unless NO-SELECT-WINDOW-P is non-nil."
(make-string (* (1- lvl) pdf-outline-buffer-indent) ?\s)
title
(if (> page 0)
- (format " (%d)" page)
+ (format " (%s)"
+ (if labels
+ (nth (1- page) labels)
+ page))
"(invalid)"))
'type 'pdf-outline
'help-echo (pdf-links-action-to-string (cdr item))
@@ -442,16 +454,21 @@ Then quit the outline window."
(use-local-map (keymap-parent (current-local-map)))))
-(defun pdf-outline-imenu-create-item (_lvl link)
+(defun pdf-outline-imenu-create-item (_lvl link &optional labels)
(cl-destructuring-bind ( _type title page _top)
link
- (list (format "%s (%d)" title page)
+ (list (format "%s (%s)" title (if labels
+ (nth (1- page) labels)
+ page))
0
'pdf-outline-imenu-activate-link
link)))
(defun pdf-outline-imenu-create-index-flat ()
- (let ((outline (cl-remove-if-not
+ (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))
@@ -459,7 +476,7 @@ Then quit the outline window."
index)
(dolist (o outline)
(push (pdf-outline-imenu-create-item
- (car o) (cdr o))
+ (car o) (cdr o) labels)
index))
(nreverse index)))
@@ -471,9 +488,11 @@ Then quit the outline window."
(lambda (type)
(eq type 'goto-dest))
(pdf-info-outline (pdf-view-buffer-file-name))
- :key 'cadr))))
+ :key 'cadr))
+ (and pdf-outline-display-labels
+ (pdf-info-pagelabels (pdf-view-buffer-file-name)))))
-(defun pdf-outline-imenu-create-index-tree-1 (nodes)
+(defun pdf-outline-imenu-create-index-tree-1 (nodes &optional labels)
(mapcar (lambda (node)
(let (children)
(when (consp (car node))
@@ -482,11 +501,11 @@ Then quit the outline window."
(let ((title (nth 2 node))
(item
(pdf-outline-imenu-create-item
- (car node) (cdr node))))
+ (car node) (cdr node) labels)))
(if children
(cons title
(cons item (pdf-outline-imenu-create-index-tree-1
- children)))
+ children labels)))
item))))
nodes))
diff --git a/lisp/pdf-view.el b/lisp/pdf-view.el
index 1a538b2..18213b1 100644
--- a/lisp/pdf-view.el
+++ b/lisp/pdf-view.el
@@ -186,6 +186,7 @@ Edge values are image coordinates.")
(define-key map (kbd "M-<") 'pdf-view-first-page)
(define-key map (kbd "M->") '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)
;; Zoom in/out.
(define-key map "+" 'pdf-view-enlarge)
@@ -550,6 +551,19 @@ at the top edge of the page moves to the previous page."
(set-window-hscroll (selected-window) hscroll)))
(image-previous-line arg)))
+(defun pdf-view-goto-label (label)
+ "Goto the page corresponding to LABEL.
+
+Usually the label of a document's page is the same as it's
+displayed page number."
+ (interactive
+ (list (let ((labels (pdf-info-pagelabels)))
+ (completing-read "Goto label: " labels nil t))))
+ (let ((index (cl-position label (pdf-info-pagelabels) :test 'equal)))
+ (unless index
+ (error "No such label: %s" label))
+ (pdf-view-goto-page (1+ index))))
+
;; * ================================================================== *
;; * Slicing
diff --git a/server/epdfinfo.c b/server/epdfinfo.c
index bf57ef9..cd43662 100644
--- a/server/epdfinfo.c
+++ b/server/epdfinfo.c
@@ -3201,6 +3201,29 @@ cmd_charlayout(const epdfinfo_t *ctx, const command_arg_t *args)
return;
}
+const command_arg_type_t cmd_pagelabels_spec[] =
+ {
+ ARG_DOC,
+ };
+
+static void
+cmd_pagelabels(const epdfinfo_t *ctx, const command_arg_t *args)
+{
+ PopplerDocument *doc = args[0].value.doc->pdf;
+ int i;
+
+ OK_BEGIN ();
+ for (i = 0; i < poppler_document_get_n_pages (doc); ++i)
+ {
+ PopplerPage *page = poppler_document_get_page(doc, i);
+ gchar *label = poppler_page_get_label (page);
+
+ print_response_string (label ? label : "", NEWLINE);
+ g_object_unref (page);
+ g_free (label);
+ }
+ OK_END ();
+}
@@ -3231,7 +3254,8 @@ static const command_t commands [] =
DEC_CMD (pagesize),
DEC_CMD (boundingbox),
DEC_CMD (charlayout),
-
+ DEC_CMD (pagelabels),
+
/* Annotations */
DEC_CMD (getannots),
DEC_CMD (getannot),