From 2ff9bcfdd2d22781206d2f32f6ff650e4beeaaf3 Mon Sep 17 00:00:00 2001 From: Vasilij Schneidermann Date: Sun, 3 May 2020 22:18:19 +0200 Subject: Add Imenu interop Closes #69 --- nov.el | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'nov.el') diff --git a/nov.el b/nov.el index 54c5828..9347897 100644 --- a/nov.el +++ b/nov.el @@ -858,5 +858,49 @@ See also `nov-bookmark-make-record'." :follow 'nov-org-link-follow :store 'nov-org-link-store) + +;;; Imenu interop + +(defun nov-imenu-goto-function (_name filename target) + "Visit imenu item using FILENAME and TARGET." + (nov-visit-relative-file filename target)) + +(defun nov--imenu-create-epub2-index (toc-path) + (let ((toc (with-temp-buffer + (insert-file-contents toc-path) + (libxml-parse-xml-region (point-min) (point-max))))) + (mapcar + (lambda (node) + (-let* ((label-node (esxml-query "navLabel>text" node)) + (content-node (esxml-query "content" node)) + (href (nov-urldecode (esxml-node-attribute 'src content-node))) + (label (car (esxml-node-children label-node))) + ((filename target) (nov-url-filename-and-target href))) + (list label filename 'nov-imenu-goto-function target))) + (esxml-query-all "navPoint" toc)))) + +(defun nov--imenu-create-epub3-index (toc-path) + (let ((toc (with-temp-buffer + (insert-file-contents toc-path) + (libxml-parse-html-region (point-min) (point-max))))) + (mapcar + (lambda (node) + (-let* ((href (esxml-node-attribute 'href node)) + (label (car (esxml-node-children node))) + ((filename target) (nov-url-filename-and-target href))) + (list label filename 'nov-imenu-goto-function target))) + (esxml-query-all "a" toc)))) + +(defun nov-imenu-create-index () + "Generate Imenu index." + (let ((toc-path (cdr (aref nov-documents 0)))) + (if (version< nov-epub-version "3.0") + (nov--imenu-create-epub2-index toc-path) + (nov--imenu-create-epub3-index toc-path)))) + +(defun nov-imenu-setup () + (setq imenu-create-index-function 'nov-imenu-create-index)) +(add-hook 'nov-mode-hook 'nov-imenu-setup) + (provide 'nov) ;;; nov.el ends here -- cgit v1.2.3