branch: externals/org-transclusion
commit c910289f97441ce9a4751ece2d47ce0038b3bb90
Author: Noboru Ota <[email protected]>
Commit: Noboru Ota <[email protected]>

    fix(add): org-id with search option (::*heading) #237
    
    While fixing the issue, I am extending the "add" operation to allow for 
*any*
    link.  A lot is still under development and many things will change. But 
this
    seems to work without breaking any user-facing commands and function.
    
    Introduced a new function `org-transclusion-add-target-marker`, which helps
    transcluding *any* link (as long as Org can reach the link target and Emacs
    creates the link's target buffer -- tested with `notmuch` link 
successfully).
    
    Refactored the code for the "add" operation with this new approach.
---
 org-transclusion.el | 139 ++++++++++++++++++++++++----------------------------
 test/test-2.0.org   |  28 ++++++++++-
 2 files changed, 91 insertions(+), 76 deletions(-)

diff --git a/org-transclusion.el b/org-transclusion.el
index 1c66a38c81..6d539e35b7 100644
--- a/org-transclusion.el
+++ b/org-transclusion.el
@@ -942,40 +942,85 @@ hooks in `org-transclusion-add-functions'."
         (run-hook-with-args 'org-transclusion-after-add-functions beg end))
       t)))
 
-(defun org-transclusion-id-marker (link)
+(defun org-transclusion-add-target-marker (link)
   (save-selected-window
-    (org-link-open link)
-    ;; In the target buffer temporarily
-    (move-marker (make-marker) (point))))
+    ;; Don't ever prompt to create a headline when transcluding.
+    ;; t is a less surprising default than nil - fuzzy search.
+    (let ((org-link-search-must-match-exact-headline t))
+      (org-link-open link)
+      ;; In the target buffer temporarily
+      (move-marker (make-marker) (point)))))
 
 (defun org-transclusion-add-org-id (link plist)
   "Return a list for Org-ID LINK object and PLIST.
 Return nil if not found."
-  (when (string= "id" (org-element-property :type link))
-    ;; when type is id, the value of path is the id
-    (let* ((mkr (ignore-errors (org-transclusion-id-marker link)))
-           (payload '(:tc-type "org-id")))
-      (if mkr
-          (append payload (org-transclusion-content-org-marker mkr plist))
-        (message
-         "No transclusion done for this ID. Ensure it works at point %d, line 
%d"
-         (point) (org-current-line))
-        nil))))
+  (and-let*
+      ((_ (string= "id" (org-element-property :type link)))
+       (mkr (ignore-errors (org-transclusion-add-target-marker link)))
+       (buf (marker-buffer mkr))
+       (_ (buffer-live-p (marker-buffer mkr))))
+    (with-current-buffer buf
+      (org-with-wide-buffer
+       (goto-char mkr)
+       (append '(:tc-type "org-id")
+               (if (org-before-first-heading-p)
+                   (org-transclusion-content-org-filtered
+                    nil plist)
+                 (org-transclusion-content-org-filtered
+                  'only-element plist)))))))
 
 (defun org-transclusion-add-org-file (link plist)
   "Return a list for Org file LINK object and PLIST.
 Return nil if not found."
-  (and (string= "file" (org-element-property :type link))
-       (org-transclusion-org-file-p (org-element-property :path link))
+  (and-let* ((_ (string= "file" (org-element-property :type link)))
+             (_ (org-transclusion-org-file-p (org-element-property :path 
link)))
+  ;; The target needs to be carefully differentiated between the whole buffer 
or
+  ;; element at point.
+
+  ;; When the link is ID, the current logic to check the first section should
+  ;; work.
+
+  ;; For the normal file links pointing to an Org file, the target buffer may 
be
+  ;; already open with a point. If the search option is present, the point will
+  ;; move to the appropriate point and get the element. If the search option is
+  ;; not present, the whole buffer needs to be obtained.
+             (mkr (ignore-errors (org-transclusion-add-target-marker link)))
+             (buf (marker-buffer mkr)))
+    ;; FIXME `org-transclusion-add-target-marker'
+    ;;
+    ;; - Change name. It's not just for org file being targeted.
+
+    ;; - Silly to go back to the buffer here.
+
+    ;; - `org-transclusion-content-org-filtered' should not return other
+    ;;   properties -- confusing.
+    (with-current-buffer buf
+      (org-with-wide-buffer
        (append '(:tc-type "org-link")
-               (org-transclusion-content-org-link link plist))))
+               ;; If search-option present, get only the element at point;
+               ;; otherwise, get the whole buffer.
+               (if (org-element-property :search-option link)
+                   (progn
+                     (goto-char mkr)
+                     (org-transclusion-content-org-filtered
+                      'only-element plist))
+                 (org-transclusion-content-org-filtered
+                  nil plist)))))))
 
 (defun org-transclusion-add-other-file (link plist)
   "Return a list for non-Org file LINK object and PLIST.
 Return nil if not found."
-  (and (string= "file" (org-element-property :type link))
+  (and-let* (;; (_ (string= "file" (org-element-property :type link)))
+             (mkr (ignore-errors (org-transclusion-add-target-marker link)))
+             (buf (marker-buffer mkr)))
+    ;; FIXME It's silly to revisit the buffer when it was already visited.
+    (with-current-buffer buf
+      (org-with-wide-buffer
        (append '(:tc-type "others-default")
-               (org-transclusion-content-others-default link plist))))
+               (list :src-content (buffer-string)
+                     :src-buf buf
+                     :src-beg (point-min)
+                     :src-end (point-max)))))))
 
 ;;-----------------------------------------------------------------------------
 ;;;; Functions for inserting content
@@ -1122,50 +1167,6 @@ INDENT is the number of current indentation of the 
#+transclude."
     (set-left-margin (point-min)(point-max) indent)
     (buffer-string)))
 
-(defun org-transclusion-content-org-marker (marker plist)
-  "Return a list of payload from MARKER and PLIST.
-This function is intended to be used for Org-ID.  It delegates the
-work to
-`org-transclusion-content-org-filtered'."
-  (if (and marker (marker-buffer marker)
-           (buffer-live-p (marker-buffer marker)))
-      (progn
-        (with-current-buffer (marker-buffer marker)
-          (org-with-wide-buffer
-           (goto-char marker)
-           (if (org-before-first-heading-p)
-               (org-transclusion-content-org-filtered
-                nil plist)
-             (org-transclusion-content-org-filtered
-              'only-element plist)))))
-    (message "Nothing done. Cannot find marker for the ID.")))
-
-(defun org-transclusion-content-org-link (link plist)
-  "Return a list of payload from Org LINK object and PLIST.
-This function is intended to be used for Org-ID. It delegates the
-work to
-`org-transclusion-content-org-filtered'."
-  (save-excursion
-    ;; First visit the buffer and go to the relevant element if
-    ;; search-option is present.
-    (let* ((path (org-element-property :path link))
-           (search-option (org-element-property :search-option link))
-           (buf (find-file-noselect path))
-           (org-link-search-must-match-exact-headline
-            ;; Don't ever prompt to create a headline when transcluding
-            (if (eq 'query-to-create org-link-search-must-match-exact-headline)
-                t  ;; Less surprising default than nil - fuzzy search
-              org-link-search-must-match-exact-headline)))
-      (with-current-buffer buf
-        (org-with-wide-buffer
-         (if search-option
-             (progn
-               (org-link-search search-option)
-               (org-transclusion-content-org-filtered
-                'only-element plist))
-           (org-transclusion-content-org-filtered
-            nil plist)))))))
-
 (defvar org-transclusion-content-filter-org-functions '())
 
 (add-hook 'org-transclusion-content-filter-org-functions
@@ -1292,18 +1293,6 @@ is non-nil."
     data))
 
 ;;;;---------------------------------------------------------------------------
-;;;; Functions to support non-Org-mode link types
-
-(defun org-transclusion-content-others-default (link _plist)
-  "Use Org LINK element to return SRC-CONTENT, SRC-BEG, and SRC-END."
-  (let* ((path (org-element-property :path link))
-         (buf (find-file-noselect path)))
-    (with-current-buffer buf
-      (org-with-wide-buffer
-       (list :src-content (buffer-string)
-             :src-buf buf
-             :src-beg (point-min)
-             :src-end (point-max))))))
 
 ;;-----------------------------------------------------------------------------
 ;;; Utility Functions
diff --git a/test/test-2.0.org b/test/test-2.0.org
index 8292ce025e..fd5500c50c 100644
--- a/test/test-2.0.org
+++ b/test/test-2.0.org
@@ -1,5 +1,21 @@
 * Regression
-** make from link
+** notmuch
+
+   #+transclude: [[notmuch:id:[email protected]]]
+
+   [[notmuch:id:[email protected]]]
+** search option
+
+#+transclude: [[file:paragraph.org]]
+=> transclude entire buffer
+
+#+transclude: [[file:paragraph.org::Sub heading]]
+=> Sub heading only
+
+#+transclude: [[file:paragraph.org::non-exisitent]]
+=> Should not transclude anything
+
+** make from link -- id
 This is a link to a [[id:2022-05-30T203553][Bertrand Russell]] wikipedia 
excerpt
 #+transclude: [[id:2022-05-30T203553][Bertrand Russell]]
 
@@ -7,6 +23,16 @@ This is a link to a [[id:2022-05-30T203553][Bertrand 
Russell]] wikipedia excerpt
 
 [[id:2022-10-10T173507::*H2]]
 
+ID with "first section" [[id:2022-06-26T152831]]
+
+#+begin_src emacs-lisp
+  (setq org-transclusion-include-first-section nil)
+  (setq org-transclusion-include-first-section t)
+#+end_src
+
+#+transclude: [[id:2022-06-26T152831]]
+
+
 ** test empty file
 #+transclude: [[file:empty.txt::2][empty text file]]
 

Reply via email to