Skip to content

Instantly share code, notes, and snippets.

@suckerSlayer
Created October 11, 2022 20:46
Show Gist options
  • Save suckerSlayer/6a755c83160c0469d961d781b49b1a55 to your computer and use it in GitHub Desktop.
Save suckerSlayer/6a755c83160c0469d961d781b49b1a55 to your computer and use it in GitHub Desktop.
Emacs pdf-tools/ org-noter setting and modifier
;; -------------------------
;;Installing pdf-tools
(use-package pdf-tools
:ensure t
:init
(add-hook 'after-init-hook 'pdf-tools-install)
:config
(progn
(setq pdf-view-continuous nil)
)
:bind (:map pdf-view-mode-map
("j" . (lambda () (interactive) (image-next-line 10)))
("k" . (lambda () (interactive) (pdf-view-previous-line-or-previous-page 10)))
("n" . 'pdf-view-scroll-up-or-next-page)
("p" . 'pdf-view-scroll-down-or-previous-page)
;; ("d" . 'org-noter-sync-current-note-embed-heading-into-pdf)
("d" . 'org-noter-embed-all-org-note-to-pdf)
)
)
;;Disable linum-mode to improve performance in PDFView mode
(add-hook 'pdf-view-mode-hook
(lambda ()
(linum-mode 0)))
;; Install org-noter
(use-package org-noter
:ensure t
:bind (:map org-noter-doc-mode-map
("M-i" . 'org-noter-insert-selected-text-inside-note-content)
)
)
;; define function: insert-selected-text-inside-note-content
(require 'org-noter_modifer)
(defun org-noter-insert-selected-text-inside-note-content ()
(interactive)
(progn (setq currenb (buffer-name))
(org-noter-insert-precise-note-modify)
(set-buffer currenb)
(org-noter-insert-note-to-quote)
))
;; copied from "org-noter.el"
(require 'org-noter)
;;=> modified line
;; (defun org-noter--insert-heading-with-region-property (level title &optional newlines-number location)
(defun org-noter--insert-heading-with-region-property (level title &optional newlines-number location region-property)
"Insert a new heading at LEVEL with TITLE.
The point will be at the start of the contents, after any
properties, by a margin of NEWLINES-NUMBER."
(setq newlines-number (or newlines-number 1))
(org-insert-heading nil t)
(let* ((initial-level (org-element-property :level (org-element-at-point)))
(changer (if (> level initial-level) 'org-do-demote 'org-do-promote))
(number-of-times (abs (- level initial-level))))
(dotimes (_ number-of-times) (funcall changer))
(insert (org-trim (replace-regexp-in-string "\n" " " title)))
(org-end-of-subtree)
(unless (bolp) (insert "\n"))
(org-N-empty-lines-before-current (1- newlines-number))
(when location
(org-entry-put nil org-noter-property-note-location (org-noter--pretty-print-location location))
(org-entry-put nil "REGION" region-property)
(when org-noter-doc-property-in-notes
(org-noter--with-valid-session
(org-entry-put nil org-noter-property-doc-file (org-noter--session-property-text session))
(org-entry-put nil org-noter--property-auto-save-last-location "nil"))))
(run-hooks 'org-noter-insert-heading-hook)))
;;=> modified line
;; (defun org-noter-insert-note (&optional precise-info)
(defun org-noter-insert-note-to-quote (&optional precise-info)
"Insert note associated with the current location.
This command will prompt for a title of the note and then insert
it in the notes buffer. When the input is empty, a title based on
`org-noter-default-heading-title' will be generated.
If there are other notes related to the current location, the
prompt will also suggest them. Depending on the value of the
variable `org-noter-closest-tipping-point', it may also
suggest the closest previous note.
PRECISE-INFO makes the new note associated with a more
specific location (see `org-noter-insert-precise-note' for more
info).
When you insert into an existing note and have text selected on
the document buffer, the variable `org-noter-insert-selected-text-inside-note'
defines if the text should be inserted inside the note."
(interactive)
(org-noter--with-valid-session
(let* ((ast (org-noter--parse-root)) (contents (org-element-contents ast))
(window (org-noter--get-notes-window 'force))
(selected-text
(cond
((eq (org-noter--session-doc-mode session) 'pdf-view-mode)
(when (pdf-view-active-region-p)
(mapconcat 'identity (pdf-view-active-region-text) ? )))
((eq (org-noter--session-doc-mode session) 'nov-mode)
(when (region-active-p)
(buffer-substring-no-properties (mark) (point))))))
force-new
(location (org-noter--doc-approx-location (or precise-info 'interactive) (gv-ref force-new)))
(view-info (org-noter--get-view-info (org-noter--get-current-view) location))
;; ==> modify: add
(region-property (format "%S" (pdf-view-active-region)))
;; <== modify
)
(let ((inhibit-quit t))
(with-local-quit
(select-frame-set-input-focus (window-frame window))
(select-window window)
;; IMPORTANT(nox): Need to be careful changing the next part, it is a bit
;; complicated to get it right...
(let ((point (point))
(minibuffer-local-completion-map org-noter--completing-read-keymap)
collection default default-begin title selection
(empty-lines-number (if org-noter-separate-notes-from-heading 2 1)))
(cond
;; NOTE(nox): Both precise and without questions will create new notes
((or precise-info force-new)
(setq default (and selected-text (replace-regexp-in-string "\n" " " selected-text))))
(org-noter-insert-note-no-questions)
(t
(dolist (note-cons (org-noter--view-info-notes view-info))
(let ((display (org-element-property :raw-value (car note-cons)))
(begin (org-element-property :begin (car note-cons))))
(push (cons display note-cons) collection)
(when (and (>= point begin) (> begin (or default-begin 0)))
(setq default display
default-begin begin))))))
(setq collection (nreverse collection)
title (if org-noter-insert-note-no-questions
default
(completing-read "Note: " collection nil nil nil nil default))
selection (unless org-noter-insert-note-no-questions (cdr (assoc title collection))))
(if selection
;; NOTE(nox): Inserting on an existing note
(let* ((note (car selection))
(insert-before-element (cdr selection))
(has-content
(eq (org-element-map (org-element-contents note) org-element-all-elements
(lambda (element)
(if (org-noter--check-location-property element)
'stop
(not (memq (org-element-type element) '(section property-drawer)))))
nil t)
t)))
(when has-content (setq empty-lines-number 2))
(if insert-before-element
(goto-char (org-element-property :begin insert-before-element))
(goto-char (org-element-property :end note)))
(if (org-at-heading-p)
(progn
(org-N-empty-lines-before-current empty-lines-number)
(forward-line -1))
(unless (bolp) (insert "\n"))
(org-N-empty-lines-before-current (1- empty-lines-number)))
;; => modified line
;; (when (and org-noter-insert-selected-text-inside-note selected-text) (insert selected-text)))
(when (and org-noter-insert-selected-text-inside-note selected-text) (insert (concat "#+begin_quote\n" selected-text "\n#+end_quote"))))
;; NOTE(nox): Inserting a new note
(let ((reference-element-cons (org-noter--view-info-reference-for-insertion view-info))
level)
(when (zerop (length title))
(setq title (replace-regexp-in-string (regexp-quote "$p$") (number-to-string (car location))
org-noter-default-heading-title)))
(if reference-element-cons
(progn
(cond
((eq (car reference-element-cons) 'before)
(goto-char (org-element-property :begin (cdr reference-element-cons))))
((eq (car reference-element-cons) 'after)
(goto-char (org-element-property :end (cdr reference-element-cons)))))
;; NOTE(nox): This is here to make the automatic "should insert blank" work better.
(when (org-at-heading-p) (backward-char))
(setq level (org-element-property :level (cdr reference-element-cons))))
(goto-char (org-element-map contents 'section
(lambda (section) (org-element-property :end section))
nil t org-element-all-elements))
(setq level (1+ (org-element-property :level ast))))
;; NOTE(nox): This is needed to insert in the right place
(outline-show-entry)
;; => modified line
;; (org-noter--insert-heading level title empty-lines-number location)
(org-noter--insert-heading-with-region-property level title empty-lines-number location region-property)
(when (org-noter--session-hide-other session) (org-overview))
(setf (org-noter--session-num-notes-in-view session)
(1+ (org-noter--session-num-notes-in-view session)))))
(org-show-set-visibility t)
(org-cycle-hide-drawers 'all)
(org-cycle-show-empty-lines t)))
(when quit-flag
;; NOTE(nox): If this runs, it means the user quitted while creating a note, so
;; revert to the previous window.
(select-frame-set-input-focus (org-noter--session-frame session))
(select-window (get-buffer-window (org-noter--session-doc-buffer session))))))))
;;=> modified line
;; (defun org-noter-insert-precise-note (&optional toggle-no-questions)
(defun org-noter-insert-precise-note-modify (&optional toggle-no-questions)
"Insert note associated with a specific location.
This will ask you to click where you want to scroll to when you
sync the document to this note. You should click on the top of
that part. Will always create a new note.
When text is selected, it will automatically choose the top of
the selected text as the location and the text itself as the
title of the note (you may change it anyway!).
See `org-noter-insert-note' docstring for more."
(interactive "P")
(org-noter--with-valid-session
(let ((org-noter-insert-note-no-questions (if toggle-no-questions
(not org-noter-insert-note-no-questions)
org-noter-insert-note-no-questions)))
(org-noter-insert-note-to-quote (org-noter--get-precise-info)))))
;;=> modified line
;; (defun org-noter-sync-current-note ()
(defun org-noter-embed-heading-into-pdf ()
"Go the location of the selected note, in relation to where the point is.
As such, it will only work when the notes window exists."
(interactive)
;; (print (org-element-at-point))
(let* ((page)
(region-property)
(anno-content))
(let ((location (org-noter--parse-location-property (org-element-at-point))))
(if location
(setq page location)
;;(user-error "No location selected"))
))
(let ((region (org-noter--parse-region-property (org-element-at-point))))
(if region
(setq region-property region)
;; (user-error "No region in this heading")
))
(let ((title (org-noter--parse-title-property (org-element-at-point))))
(if title
(setq anno-content title)
;; (user-error "No region in this heading")
))
(with-selected-window
(org-noter--get-doc-window)
;;(print anno-content)
(let (( prolist '((color . "yellow") (label . "emacs-orgNoter")) ))
(add-to-list 'prolist `(contents . ,anno-content))
(if region-property
(pdf-annot-add-annotation
'highlight
;;(pdf-view-active-region)
;;'((0.3173160173160173 0.3704013377926421 0.854978354978355 0.3712374581939799))
region-property
;;'((color . "yellow") (label . "emacs-orgNoter") (contents . anno-content))
prolist
(car page)
)
;; (user-error "No region-property selected")
)
)
)
)
)
;; ==> modify
(defun org-noter--parse-region-property (arg)
(let ((region (if (stringp arg) arg
(org-element-property (intern (concat ":" "REGION")) arg))))
(if region
(read region)
)
)
)
;; <== modify
(defun org-noter--parse-title-property (arg)
(let ((title (if (stringp arg) arg
(org-element-property (intern (concat ":" "title")) arg))))
(if title
;;(print title)
title
)
)
)
;; ==> copied from org-noter-pdftools.el
(defun org-noter-embed-all-org-note-to-pdf ()
(interactive)
(org-noter--with-valid-session
(with-selected-window (org-noter--get-notes-window)
(save-excursion
(org-map-entries #'org-noter-embed-heading-into-pdf "REGION={.}")
(print "✅ org-noter Embed Heading into PDF file Complete")
))))
;; <== modify
;; provide module for use in init-org.el
(provide 'org-noter_modifer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment