[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org-remark 5fb747a419 9/9: Merge branch 'notes-sync'
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org-remark 5fb747a419 9/9: Merge branch 'notes-sync' |
Date: |
Tue, 27 Dec 2022 19:58:32 -0500 (EST) |
branch: externals/org-remark
commit 5fb747a419366a33e6659a992ada8a35aa8bd655
Merge: 00e56e12a6 854856059f
Author: Noboru Ota <me@nobiot.com>
Commit: Noboru Ota <me@nobiot.com>
Merge branch 'notes-sync'
---
README.org | 12 ++
org-remark-eww.el | 79 ++++++++++
org-remark-global-tracking.el | 58 ++++---
org-remark.el | 352 +++++++++++++++++++++++++++++++-----------
4 files changed, 391 insertions(+), 110 deletions(-)
diff --git a/README.org b/README.org
index 75d6efd284..e653ebf66c 100644
--- a/README.org
+++ b/README.org
@@ -110,3 +110,15 @@ This section is created by Org-remark for the source file.
It serves as an examp
** defmacro org-remark-create
This macro was inspired by
[[https://github.com/jkitchin/ov-highlight][Ov-highlight]]. It's by John
Kitchin (author of Org-ref). Great UX for markers with hydra. Saves the marker
info and comments directly within the Org file as Base64 encoded string. It
uses overlays with using ~ov~ package.
+
+* org-remark
+:PROPERTIES:
+:org-remark-file: org-remark.el
+:END:
+
+** org-remark-notes-send-data
+
+** org-remark-highlights-load
+
+** goto
+This is no longer empty.
diff --git a/org-remark-eww.el b/org-remark-eww.el
new file mode 100644
index 0000000000..f5a27c42e9
--- /dev/null
+++ b/org-remark-eww.el
@@ -0,0 +1,79 @@
+;;; org-remark-eww.el --- Enable Org-remark for EWW -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; Author: Vedang Manerikar <ved.manerikar@gmail.com>
+;; Noboru Ota <me@nobiot.com>
+;; URL: https://github.com/nobiot/org-remark
+;; Created: 23 December 2022
+;; Last modified: 24 December 2022
+;; Package-Requires: ((emacs "27.1") (org "9.4"))
+;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp
+
+;; This file is not part of GNU Emacs.
+
+;; 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:
+;; This file is part of org-remark.
+
+;; This feature to support for EWW was originally added by Vedang
+;; Manerika with commit 5e4b27ar feat: Support taking annotations in eww
+;; buffers. nobit has refactored it as a separate file.
+
+;;; Code:
+
+(require 'eww)
+(declare-function org-remark-auto-on "org-remark-global-tracking")
+
+;;;###autoload
+(define-minor-mode org-remark-eww-mode
+ "Enable Org-remark to work with EWW."
+ :global t
+ :group 'org-remark
+ (if org-remark-eww-mode
+ ;; Enable
+ (progn
+ (add-hook 'eww-after-render-hook #'org-remark-auto-on)
+ (add-hook 'org-remark-source-find-file-name-functions
+ #'org-remark-eww-find-file-name)
+ (add-hook 'org-remark-highlight-link-to-source-functions
+ #'org-remark-eww-highlight-link-to-source))
+ ;; Disable
+ (remove-hook 'eww-after-render-hook #'org-remark-auto-on)
+ (remove-hook 'org-remark-source-find-file-name-functions
+ #'org-remark-eww-find-file-name)
+ (remove-hook 'org-remark-highlight-link-to-source-functions
+ #'org-remark-eww-highlight-link-to-source)))
+
+(defun org-remark-eww-find-file-name ()
+ "Return URL without the protocol as the file name for the website.
+It assumes the buffer is the source website to be annotated.
+This function is meant to be set to hook
+`org-remark-source-find-file-name-functions'."
+ (when (eq major-mode 'eww-mode)
+ (let ((url-parsed (url-generic-parse-url (eww-current-url))))
+ (concat (url-host url-parsed) (url-filename url-parsed)))))
+
+(defun org-remark-eww-highlight-link-to-source (filename)
+ "Return URL pointinting to the source website (FILENAME).
+It assumes https:
+This function is meant to be set to hook
+`org-remark-highlight-link-to-source-functions'."
+ (when (eq major-mode 'eww-mode)
+ ;;; FIXME we shhould not assume https?
+ (concat "[[https://" filename "]]")))
+
+(provide 'org-remark-eww)
+;;; org-remark-eww.el ends here
diff --git a/org-remark-global-tracking.el b/org-remark-global-tracking.el
index 445db3d183..a2b70ea8fb 100644
--- a/org-remark-global-tracking.el
+++ b/org-remark-global-tracking.el
@@ -5,7 +5,7 @@
;; Author: Noboru Ota <me@nobiot.com>
;; URL: https://github.com/nobiot/org-remark
;; Created: 15 August 2021
-;; Last modified: 14 December 2022
+;; Last modified: 24 December 2022
;; Package-Requires: ((emacs "27.1") (org "9.4"))
;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp
@@ -55,6 +55,12 @@ suffix to the file name without the extension."
(file "marginalia.org")
(function org-remark-notes-file-name-function)))
+(defcustom org-remark-highlight-link-to-source-functions nil
+ "Abnormal hook called to create a link to source in notes file.
+Each one is called with FILENAME as an argument."
+ :group 'org-remark
+ :type '(repeat function))
+
;;;###autoload
(define-minor-mode org-remark-global-tracking-mode
"Automatically activates local minor mode `org-remark-mode'.
@@ -66,15 +72,13 @@ readable, the function automatically activates
`org-remark'."
:lighter " ormk-auto"
:global t
:group 'org-remark
- (cond
- (org-remark-global-tracking-mode
- ;; Activate
- (progn (add-hook 'find-file-hook #'org-remark-auto-on)
- (add-hook 'eww-after-render-hook #'org-remark-auto-on)))
- (t
- ;; Deactivate
- (remove-hook 'find-file-hook #'org-remark-auto-on))))
+ (if org-remark-global-tracking-mode
+ ;; Enable
+ (add-hook 'find-file-hook #'org-remark-auto-on)
+ ;; Disable
+ (remove-hook 'find-file-hook #'org-remark-auto-on)))
+;;; Functions
(defun org-remark-notes-file-name-function ()
"Return a marginal notes file name for the current buffer.
@@ -84,15 +88,22 @@ This is the default function for the customizing variable
When the current buffer is visiting a file, the name of marginal
notes file will be \"FILE-notes.org\", adding \"-notes.org\" as a
suffix to the file name without the extension."
- (concat (file-name-sans-extension
- (file-name-nondirectory (org-remark-source-find-file-name)))
- "-notes.org"))
+ (if buffer-file-name
+ (concat (file-name-sans-extension
+ (file-name-nondirectory (org-remark-source-find-file-name)))
+ "-notes.org")
+ ;; If buffer is not visiting a file, a default file name. If this
+ ;; file name is not suitable, either override the function or set
+ ;; the user option to a custom function.
+ (expand-file-name "marginalia.org" user-emacs-directory)))
(defalias
- 'org-remark-notes-file-path-function 'org-remark-notes-file-name-function)
+ 'org-remark-notes-file-path-function
+ 'org-remark-notes-file-name-function)
(make-obsolete
- 'org-remark-notes-file-path-function 'org-remark-notes-file-name-function
"0.2.0" )
+ 'org-remark-notes-file-path-function
+ 'org-remark-notes-file-name-function "0.2.0" )
;;;; Private Functions
@@ -109,18 +120,21 @@ This function is meant to be added to `find-file-hook' by
"Return the name of marginal notes file for current buffer."
(if (functionp org-remark-notes-file-name)
(funcall org-remark-notes-file-name)
- ;; If not function, assume string and return it as the file path.
- org-remark-notes-file-name))
+ ;; If not function, assume string and return it as the file name.
+ ;; TODO when buffer is not visitng a file, assume file resides in
+ ;; `user-emacs-directory'
+ (if buffer-file-name org-remark-notes-file-name
+ (expand-file-name org-remark-notes-file-name user-emacs-directory))))
(defun org-remark-source-find-file-name ()
"Assumes that we are currently in the source buffer.
-Returns the filename for the soure buffer. We use this filename
+Returns the filename for the source buffer. We use this filename
to identify the source buffer in all operations related to
-marginalia."
- (if (eq major-mode 'eww-mode)
- (let ((url-parsed (url-generic-parse-url (eww-current-url))))
- (concat (url-host url-parsed) (url-filename url-parsed)))
- (buffer-file-name)))
+marginal notes."
+ (let ((filename (or buffer-file-name
+ (run-hook-with-args-until-success
+ 'org-remark-source-find-file-name-functions))))
+ filename))
(provide 'org-remark-global-tracking)
diff --git a/org-remark.el b/org-remark.el
index 47905e731b..b764651e17 100644
--- a/org-remark.el
+++ b/org-remark.el
@@ -6,7 +6,7 @@
;; URL: https://github.com/nobiot/org-remark
;; Version: 1.0.5
;; Created: 22 December 2020
-;; Last modified: 14 December 2022
+;; Last modified: 26 December 2022
;; Package-Requires: ((emacs "27.1") (org "9.4"))
;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp,
@@ -128,6 +128,10 @@ returned by `org-remark-notes-get-file-name'.")
(defvar-local org-remark-highlights-hidden nil
"Keep hidden/shown state of the highlights in current buffer.")
+;; TODO org-remark-sync?
+(defvar-local org-remark-notes-setup-done nil)
+(defvar-local org-remark-source-setup-done nil)
+
(defvar org-remark-last-notes-buffer nil
"Stores the cloned indirect buffer visiting the notes file.
It is meant to exist only one of these in each Emacs session.")
@@ -177,6 +181,8 @@ text region:
%S
+Return the overlay.
+
When this function is used interactively, it will generate a new
ID, always assuming it is working on a new highlighted text
region, and Org-remark will start tracking the highlight's
@@ -184,7 +190,10 @@ location in the current buffer.
When this function is called from Elisp, ID can be optionally
passed, indicating to Org-remark that it is an existing
-highlight. In this case, no new ID gets generated."
+highlight. In this case, no new ID gets generated.
+
+When the pen itself defines the help-echo property, it will have
+the priority over the excerpt of the marginal notes."
(or face "`org-remark-highlighter'") properties)
(interactive (org-remark-region-or-word))
(org-remark-highlight-mark beg end id mode ,label ,face ,properties))
@@ -345,6 +354,8 @@ When this function is used interactively, it will generate
a new
ID, always assuming it is working on a new highlighted text
region.
+Return the highlight overlay.
+
A Org headline entry for the highlight will be created in the
marginal notes file specified by
`org-remark-notes-get-file-name'. If the file does not exist
@@ -371,11 +382,11 @@ marginal notes file. The expected values are nil, :load
and
(when org-remark-create-default-pen-set
;; Create default pen set.
(org-remark-create "red-line"
- '(:underline (:color "dark red" :style wave))
- '(CATEGORY "review" help-echo "Review this"))
+ `(:underline (:color "dark red" :style wave))
+ `(CATEGORY "review" help-echo "Review this"))
(org-remark-create "yellow"
- '(:underline "gold" :background "lemon chiffon")
- '(CATEGORY "important")))
+ `(:underline "gold" :background "lemon chiffon")
+ `(CATEGORY "important")))
(defun org-remark-save ()
"Save all the highlights tracked in current buffer to notes file.
@@ -390,9 +401,9 @@ in the current buffer. Each highlight is an overlay."
(org-remark-highlights-sort)
(let ((filename (org-remark-source-find-file-name)))
(dolist (h org-remark-highlights)
- (let ((beg (overlay-start h))
- (end (overlay-end h))
- (props (overlay-properties h)))
+ (let* ((beg (overlay-start h))
+ (end (overlay-end h))
+ (props (overlay-properties h)))
(org-remark-highlight-save filename beg end props)))))
(defun org-remark-open (point &optional view-only)
@@ -640,6 +651,26 @@ If there are more than one, return CAR of the list."
(setq overlays (cdr overlays)))
(car found)))
+(defun org-remark-find-overlay-in (beg end &optional id)
+ "Return one org-remark overlay between BEG and END.
+If there are more than one, return CAR of the list.
+Optioanlly ID can be passed to find the exacth ID match."
+ (let* ((overlays (overlays-in beg end))
+ found)
+ (while overlays
+ (let ((overlay (car overlays)))
+ (if (overlay-get overlay 'org-remark-id)
+ (setq found (cons overlay found))))
+ (setq overlays (cdr overlays)))
+ (when id (setq found
+ (seq-filter
+ (lambda (ov)
+ (equal (overlay-get ov 'org-remark-id) id))
+ found)))
+ (car found)))
+
+
+
;;;; org-remark-highlight
;; Work on a single highlight
@@ -654,6 +685,8 @@ nil, this function will use the default face
`org-remark-highlighter'
This function will add LABEL and PROPERTIES as overlay
properties. PROPERTIES is a plist of pairs of a symbol and value.
+Return the hightliht overlay.
+
When this function is used interactively, it will generate a new
ID, always assuming it is working on a new highlighted text
region, and Org-remark will start tracking the highlight's
@@ -677,35 +710,44 @@ to the database."
;; When highlights are toggled hidden, only the new one gets highlighted in
;; the wrong toggle state.
(when org-remark-highlights-hidden (org-remark-highlights-show))
- ;; Add highlight to the text
- (org-with-wide-buffer
- (let ((ov (make-overlay beg end nil :front-advance))
- ;; UUID is too long; does not have to be the full length
- (id (if id id (substring (org-id-uuid) 0 8))))
- (overlay-put ov 'face (if face face 'org-remark-highlighter))
- (while properties
- (let ((prop (pop properties))
- (val (pop properties)))
- (overlay-put ov prop val)))
- (when label (overlay-put ov 'org-remark-label label))
- (overlay-put ov 'org-remark-id id)
- ;; Keep track of the overlay in a local variable. It's a list that is
- ;; guaranteed to contain only org-remark overlays as opposed to the one
- ;; returned by `overlay-lists' that lists any overlays.
- (push ov org-remark-highlights)
- ;; for mode, nil and :change result in saving the highlight. :load
- ;; bypasses save.
- (unless (eq mode :load)
- (let ((filename (org-remark-source-find-file-name)))
- (if filename
- (org-remark-highlight-save filename
- beg end
- (overlay-properties ov)
- (org-remark-highlight-get-title))
- (message "org-remark: Highlights not saved; buffer is not visiting
a file"))))))
- (deactivate-mark)
- (org-remark-highlights-housekeep)
- (org-remark-highlights-sort))
+ (let ((ov (make-overlay beg end nil :front-advance))
+ ;; UUID is too long; does not have to be the full length
+ (id (if id id (substring (org-id-uuid) 0 8)))
+ (filename (org-remark-source-find-file-name))
+ (notes-props))
+ (if (not filename) (message "org-remark: Highlights not saved; buffer is
not supported")
+ (org-with-wide-buffer
+ (overlay-put ov 'face (if face face 'org-remark-highlighter))
+ (while properties
+ (let ((prop (pop properties))
+ (val (pop properties)))
+ (overlay-put ov prop val)))
+ (when label (overlay-put ov 'org-remark-label label))
+ (overlay-put ov 'org-remark-id id)
+ ;; Keep track of the overlay in a local variable. It's a list that is
+ ;; guaranteed to contain only org-remark overlays as opposed to the one
+ ;; returned by `overlay-lists' that lists any overlays.
+ (push ov org-remark-highlights)
+ ;; for mode, nil and :change result in saving the highlight. :load
+ ;; bypasses save.
+ (unless (eq mode :load)
+ (setq notes-props
+ (org-remark-highlight-save filename
+ beg end
+ (overlay-properties ov)
+ (org-remark-highlight-get-title)))
+ ;;; Get props for create and change any way
+ (when notes-props
+ ;; TODO. The function should be based on parameters
+ (unless (overlay-get ov 'help-echo)
+ (overlay-put ov 'help-echo (plist-get notes-props :body)))
+ (overlay-put ov '_org-remark-note-body
+ (plist-get notes-props :body)))))
+ (deactivate-mark)
+ (org-remark-highlights-housekeep)
+ (org-remark-highlights-sort)
+ ;; Return overlay
+ ov)))
(defun org-remark-highlight-get-title ()
"Return the title of the current buffer.
@@ -733,7 +775,7 @@ non-nil. Returns nil otherwise, or when no Org-ID is
found."
(defun org-remark-highlight-save (filename beg end props &optional title)
"Save a single HIGHLIGHT in the marginal notes file.
-Return t.
+Return the highlight's data properties list (TODO refer to ...).
FILENAME specifies the name of source file with which the marginal notes
file is associated.
@@ -766,35 +808,43 @@ buffer with search option \"::line-number\".
ORGID can be passed to this function. If user option
`org-remark-use-org-id' is non-nil, this function will add an
Org-ID link in the body text of the headline, linking back to the
-source with using ORGID."
+source with using ORGID.
+
+When a new notes file is created, add
+`org-remark-notes-sync-with-source' to `after-save-hook'."
(let* ((filename (org-remark-source-get-file-name filename))
(id (plist-get props 'org-remark-id))
(text (org-with-wide-buffer (buffer-substring-no-properties beg end)))
(notes-buf (find-file-noselect (org-remark-notes-get-file-name)))
(main-buf (current-buffer))
(line-num (org-current-line beg))
- (orgid (org-remark-highlight-get-org-id beg)))
+ (orgid (org-remark-highlight-get-org-id beg))
+ (link (if buffer-file-name
+ (concat "[[file:" filename
+ (when line-num (format "::%d" line-num)) "]]")
+ (run-hook-with-args-until-success
+ 'org-remark-highlight-link-to-source-functions filename)))
+ (notes-props))
+ ;;; Set up notes buffer for sync, etc.
+ (org-remark-notes-setup notes-buf (current-buffer) filename)
(with-current-buffer notes-buf
(when (featurep 'org-remark-convert-legacy)
(org-remark-convert-legacy-data))
;;`org-with-wide-buffer is a macro that should work for non-Org file'
(org-with-wide-buffer
- (let ((file-headline (or (org-find-property
- org-remark-prop-source-file filename)
- (progn
- ;; If file-headline does not exist, create
one at the bottom
- (goto-char (point-max))
- ;; Ensure to be in the beginning of line to
add a new headline
- (when (eolp) (open-line 1) (forward-line 1)
(beginning-of-line))
- (insert (concat "* " title "\n"))
- (org-set-property
org-remark-prop-source-file filename)
- (org-up-heading-safe) (point))))
+ (let ((file-headline
+ (or (org-find-property
+ org-remark-prop-source-file filename)
+ (progn
+ ;; If file-headline does not exist, create one at the
bottom
+ (goto-char (point-max))
+ ;; Ensure to be in the beginning of line to add a new
headline
+ (when (eolp) (open-line 1) (forward-line 1)
(beginning-of-line))
+ (insert (concat "* " title "\n"))
+ (org-set-property org-remark-prop-source-file filename)
+ (org-up-heading-safe) (point))))
(id-headline (org-find-property org-remark-prop-id id)))
;; Add org-remark-link with updated line-num as a property
- (plist-put props "org-remark-link" (concat
- "[[file:"
- filename
- (when line-num (format "::%d"
line-num))
- "]]"))
+ (when link (plist-put props "org-remark-link" link))
(if id-headline
(progn
(goto-char id-headline)
@@ -816,20 +866,34 @@ source with using ORGID."
(insert (concat "** " text "\n"))
(org-remark-notes-set-properties beg end props)
(when (and orgid org-remark-use-org-id)
- (insert (concat "[[id:" orgid "]" "[" title "]]"))))))
- (cond
- ;; fix GH issue #19
- ;; Temporarily remove `org-remark-save' from the `after-save-hook'
- ;; When the marginal notes buffer is the source buffer
- ((eq notes-buf main-buf)
+ (insert (concat "[[id:" orgid "]" "[" title "]]"))))
+ (setq notes-props (list :body (org-remark-notes-get-text)))))
+ ;; (cond
+ ;; ;; fix GH issue #19
+ ;; ;; Temporarily remove `org-remark-save' from the `after-save-hook'
+ ;; ;; When the marginal notes buffer is the source buffer
+ ;; ((eq notes-buf main-buf)
+ ;; (remove-hook 'after-save-hook #'org-remark-save t)
+ ;; (save-buffer)
+ ;; (add-hook 'after-save-hook #'org-remark-save nil t))
+ ;; ;; When marginal notes buffer is separate from the source buffer,
save the
+ ;; ;; notes buffer
+ ;; ((buffer-modified-p)
+
+ ;; Now that the notes-sync is put into after-save-buffer, we need
+ ;; to remove stop saving or remove 'after-save-hook temporarily
+ ;; to avoid (infinite) loop.
+
+ ;; (save-buffer)))
+ (when (eq notes-buf main-buf)
(remove-hook 'after-save-hook #'org-remark-save t)
- (save-buffer)
- (add-hook 'after-save-hook #'org-remark-save nil t))
- ;; When marginal notes buffer is separate from the source buffer, save
the
- ;; notes buffer
- ((buffer-modified-p)
- (save-buffer)))
- t)))
+ (remove-hook 'after-save-hook #'org-remark-notes-sync-with-source t)
+ ;;(save-buffer)
+ (set-buffer-modified-p nil)
+ ;;(add-hook 'after-save-hook #'org-remark-save t)
+ ;;(add-hook 'after-save-hook #'org-remark-notes-sync-with-source t))
+ )
+ notes-props)))
;;;;; org-remark-notes
@@ -911,10 +975,16 @@ And the following are also reserved for Org-remark:
For PROPS, if the property name is CATEGORY \(case-sensitive\) or
prefixed with \"org-remark-\" set them to to headline's property
drawer."
+
(org-set-property org-remark-prop-source-beg
(number-to-string beg))
(org-set-property org-remark-prop-source-end
(number-to-string end))
+
+ ;; Delete property
+ ;; `org-delete-property'
+ (org-entry-delete nil "CATEGORY")
+
(while props
(let ((p (pop props))
(v (pop props)))
@@ -925,10 +995,55 @@ drawer."
(org-set-property p v))))
t)
+(defun org-remark-notes-get-text ()
+ "Return the text body of a highlight in the notes buffer."
+ (let ((full-text
+ (save-excursion
+ (org-end-of-meta-data :full)
+ (if
+ ;; handle empty annotation
+ ;; (org-end-of-meta-data :full) took us to next org heading):
+ (or (looking-at org-heading-regexp)
+ (eobp)) ;; end of buffer
+ "[empty entry]"
+ (buffer-substring-no-properties
+ (point)
+ (org-end-of-subtree))))))
+ (if (< 200 (length full-text))
+ (substring-no-properties full-text 0 200)
+ full-text)))
+
+
;;;;; org-remark-highlights
;; Work on all the highlights in the current buffer
+(defvar-local org-remark-notes-source-buffers '()
+ "List of source buffers that have loaded the notes.
+Each note's buffer locally keeps track of the source buffers that
+have loaded notes from itself. Buffers in this list may be
+killed so that this needs to be checked with `buffer-live-p'.")
+
+(defun org-remark-highlight-load (highlight)
+ (let* ((id (plist-get highlight :id))
+ (location (plist-get highlight :location))
+ (beg (car location))
+ (end (cdr location))
+ (label (plist-get highlight :label))
+ (ov nil)
+ (props (plist-get highlight :props)))
+ (let ((fn (intern (concat "org-remark-mark-" label))))
+ (unless (functionp fn) (setq fn #'org-remark-mark))
+ (setq ov (funcall fn beg end id :load))
+ ;; TODO Generalize the part that updates properties.
+ ;; :body should not be the fixed property.
+ ;; '(:text (val . fn) :prop1 (val . fn) :prop2 (val .fn))
+ ;; (dolist list)
+ (unless (overlay-get ov 'help-echo)
+ (overlay-put ov 'help-echo (plist-get props :body)))
+ (overlay-put ov '*org-remark-note-body
+ (plist-get props :body)))))
+
(defun org-remark-highlights-load ()
"Visit `org-remark-notes-file' & load the saved highlights onto current
buffer.
If there is no highlights or annotations for current buffer,
@@ -942,27 +1057,81 @@ configuration. It automatically turns on
`org-remark-mode'.
Otherwise, do not forget to turn on `org-remark-mode' manually to
load the highlights"
;; Loop highlights and add them to the current buffer
- (dolist (highlight (org-remark-highlights-get))
- (let ((id (car highlight))
- (beg (caadr highlight))
- (end (cdadr highlight))
- (label (caddr highlight)))
- (let ((fn (intern (concat "org-remark-mark-" label))))
- (unless (functionp fn) (setq fn #'org-remark-mark))
- (funcall fn beg end id :load)))))
-
-(defun org-remark-highlights-get ()
+ (let ((notes-buf (find-file-noselect (org-remark-notes-get-file-name)))
+ (source-file-name (org-remark-source-get-file-name
+ (org-remark-source-find-file-name)))
+ (source-buf (current-buffer)))
+ (dolist (highlight (org-remark-highlights-get notes-buf source-file-name))
+ (org-remark-highlight-load highlight))
+ (org-remark-notes-setup notes-buf source-buf source-file-name)
+ (setq org-remark-source-setup-done t))
+ t)
+
+(defun org-remark-notes-setup (notes-buf source-buf source-file-name)
+ ;;; Start tracking the source buffer in the notes buffer as local variable.
+ ;;; This adds variable only to the base-buffer and not to the indrect buffer.
+ (let ((source-setup-done org-remark-source-setup-done))
+ (with-current-buffer notes-buf
+ (unless (and org-remark-notes-setup-done source-setup-done)
+ (cl-pushnew (cons source-buf source-file-name)
+ org-remark-notes-source-buffers)
+ (add-hook 'after-save-hook #'org-remark-notes-sync-with-source nil
:local)
+ (setq org-remark-notes-setup-done t)))))
+
+(defun org-remark-notes-housekeep ()
+ "Remove killed buffers from `org-remark-notes-source-buffers'."
+ (setq org-remark-notes-source-buffers
+ (seq-filter #'(lambda (pair) (buffer-live-p (car pair)))
+ org-remark-notes-source-buffers)))
+
+(defun org-remark-notes-update-source (source-buffer source-file-name)
+ "Update source with notes props.
+Trigger by on-save of the notes."
+ ;; Assume the current buffer is the notes file (indrect or base).
+ (let* ((new-highlights
+ (org-remark-highlights-get (current-buffer) source-file-name)))
+ (with-current-buffer source-buffer
+ (dolist (highlight new-highlights)
+ (let* ((location (plist-get highlight :location))
+ (beg (car location))
+ (end (cdr location))
+ (id (plist-get highlight :id))
+ (ov (org-remark-find-overlay-in beg end id)))
+ ;; FIXME Currently the when clause is used to guard against
+ ;; the case where a highlight overlay is not found. It should
+ ;; be an edge case but the highlight could have moved to a
+ ;; completely new location where the old location does not
+ ;; overlap with the new location at all.
+ (when ov (delete-overlay ov))
+ (org-remark-highlight-load highlight))))))
+
+(defun org-remark-notes-sync-with-source ()
+ "
+It is meant to be used in `after-save-hook'.
+Look at the base buffer for org-remark-notes-source-buffers."
+ ;;; Assume the current buffer is either the indirect or notes buffer
+ ;;; in question.
+ (let* ((notes-buffer (or (buffer-base-buffer) (current-buffer))))
+ (with-current-buffer notes-buffer
+ (org-remark-notes-housekeep)
+ (dolist (pair org-remark-notes-source-buffers)
+ ;; pair is (SOURCE-BUF . SOURCE-FILE-NAME)
+ ;; SOUCE-FILE-NAME is the reference used in notes file
+ (let ((source-buf (car pair))
+ (source-file-name (cdr pair)))
+ (org-remark-notes-update-source source-buf source-file-name))))))
+
+(defun org-remark-highlights-get (notes-buf source-file-name)
"Return a list of highlights from the marginal notes file.
The file name is returned by `org-remark-notes-get-file-name'.
-Each highlight is a list in the following structure:
- (ID (BEG . END) LABEL)"
+Each highlight is a property list in the following properties:
+ (:id ID :location (BEG . END) :label LABEL :props '(PROPERTIES)"
;; Set source-file-name first, as `find-file-noselect' will set the
;; current-buffer to source-file-name. Issue #39 FIXME: A way to make
;; this sequence agnostic is preferred, if there is a function that
;; visit file but not set the current buffer
- (when-let ((source-file-name (org-remark-source-get-file-name
- (org-remark-source-find-file-name)))
- (notes-buf (find-file-noselect (org-remark-notes-get-file-name))))
+ (when-let ((source-file-name source-file-name)
+ (notes-buf notes-buf))
;; TODO check if there is any relevant notes for the current file
;; This can be used for adding icon to the highlight
(let ((highlights))
@@ -990,10 +1159,12 @@ Each highlight is a list in the following structure:
org-remark-prop-source-beg)))
(end (string-to-number
(org-entry-get (point)
- org-remark-prop-source-end))))
- (push (list id
- (cons beg end)
- (org-entry-get (point) "org-remark-label"))
+ org-remark-prop-source-end)))
+ (text (org-remark-notes-get-text)))
+ (push (list :id id
+ :location (cons beg end)
+ :label (org-entry-get (point)
"org-remark-label")
+ :props (list :body text))
highlights))))
highlights))))))
@@ -1077,6 +1248,11 @@ Case 1. Both start and end of an overlay are identical
region. A typical cause of this case is when you delete a
region that contains a highlight overlay.
+ This also happens when EWW reloads the buffer or
+ re-renders any part of the buffer. This is because it
+ removes overlays on re-render by calling
+ `remove-overlays'.
+
Case 2. The overlay points to no buffer
This case happens when overlay is deleted by
- [elpa] externals/org-remark updated (a6b79194d8 -> 5fb747a419), ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark 854856059f 8/9: fix: issue #44 change CATEGORY, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark 47918fa751 2/9: feat: sync notes with source, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark cc69b0359b 6/9: fix: inifinate loop when notes = source for notes-sync, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark b6fa1bea1a 4/9: fix: notes-update-source to allow for beg end adjustment, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark f0a4f23911 3/9: feat: notes-source sync setup, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark 2b0ccad245 1/9: refactor: org-remark-highlight-get-text -> notes-get-text, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark 5fb747a419 9/9: Merge branch 'notes-sync',
ELPA Syncer <=
- [elpa] externals/org-remark eb6456d7f9 5/9: docs(notes-sync): add FIXME comment for the previous commit, ELPA Syncer, 2022/12/27
- [elpa] externals/org-remark 00e56e12a6 7/9: fix: text-property org-remark-label to be symbol, ELPA Syncer, 2022/12/27