From 60bbde6b8ebc95b682585f01356c958e039ce9ea Mon Sep 17 00:00:00 2001 From: Noboru Ota Date: Mon, 8 May 2023 17:01:27 +0200 Subject: [PATCH 1/3] refactor: content-format-fns and src-lines The basic intent is to refactor -src-lines.el to separate the scope of src and lines more clearly. The hope is also to make thing-at-point separate from both. To do this, the first thing done in this commit is to separate out the function to wrap the content into src. This is now done by the abnormal function hook -content-format-functions. In order to do this, the hook's function call API has been changed. The last argument of the unction call in the hook used to be :current-indentation. This is anyway part of the keyword-values plist, so the function API now expects the plist instead of just :current-indentation. --- org-transclusion-src-lines.el | 79 +++++++++++++++++------------------ org-transclusion.el | 17 ++++---- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/org-transclusion-src-lines.el b/org-transclusion-src-lines.el index 4d431e7..a2491cc 100644 --- a/org-transclusion-src-lines.el +++ b/org-transclusion-src-lines.el @@ -54,8 +54,9 @@ ;; Transclusion content formating (add-hook 'org-transclusion-content-format-functions - #'org-transclusion-content-format-src-lines) - + #'org-transclusion-content-format-lines) +(add-hook 'org-transclusion-content-format-functions + #'org-transclusion-content-format-src) ;; Open source buffer (add-hook 'org-transclusion-open-source-marker-functions #'org-transclusion-open-source-marker-src-lines) @@ -86,19 +87,21 @@ Determine add function based on LINK and PLIST. Return nil if PLIST does not contain \":src\" or \":lines\" properties." - (cond - ((plist-get plist :src) - (append '(:tc-type "src") - (org-transclusion-content-src-lines link plist))) - ;; :lines needs to be the last condition to check because :src INCLUDE :lines - ((or (plist-get plist :lines) - (plist-get plist :end) - ;; Link contains a search-option :: - ;; and NOT for an Org file - (and (org-element-property :search-option link) - (not (org-transclusion-org-file-p (org-element-property :path link))))) - (append '(:tc-type "lines") - (org-transclusion-content-range-of-lines link plist))))) + (let ((type + (cond + ((plist-get plist :src) + (setq type "src")) + ;; :lines needs to be the last condition to check because :src INCLUDE :lines + ((or (plist-get plist :lines) + (plist-get plist :end) + ;; Link contains a search-option :: + ;; and NOT for an Org file + (and (org-element-property :search-option link) + (not (org-transclusion-org-file-p (org-element-property :path link))))) + (setq type "lines"))))) + (when type + (append (list :tc-type type) + (org-transclusion-content-range-of-lines link plist))))) (defun org-transclusion-content-range-of-lines (link plist) "Return a list of payload for a range of lines from LINK and PLIST. @@ -192,28 +195,24 @@ it means from line 10 to the end of file." :src-beg beg :src-end end))))))) -(defun org-transclusion-content-src-lines (link plist) - "Return a list of payload from LINK and PLIST in a src-block. -This function is also able to transclude only a certain range of -lines with using :lines n-m property. Refer to -`org-transclusion-content-range-of-lines' for how the notation -for the range works." - (let* ((payload (org-transclusion-content-range-of-lines link plist)) - (src-lang (plist-get plist :src)) - (rest (plist-get plist :rest))) - ;; Modify :src-content if applicable - (when src-lang - (setq payload - (plist-put payload :src-content - (let ((src-content (plist-get payload :src-content))) - (concat - (format "#+begin_src %s" src-lang) - (when rest (format " %s" rest)) - "\n" - (org-transclusion-ensure-newline src-content) - "#+end_src\n"))))) - ;; Return the payload either modified or unmodified - payload)) +(defun org-transclusion-content-format-src (type content plist) + "Format text CONTENT from source before transcluding. +Return content modified (or unmodified, if not applicable)." + (when (string= type "src") + (let ((content (org-transclusion-ensure-newline content)) + (src-lang (plist-get plist :src)) + (rest (plist-get plist :rest))) + ;; Modify :src-content if applicable + (when src-lang + (setq content + (concat + (format "#+begin_src %s" src-lang) + (when rest (format " %s" rest)) + "\n" + content + "#+end_src\n"))) + ;; Return the content either modified or unmodified + content))) (defun org-transclusion-keyword-value-lines (string) "It is a utility function used converting a keyword STRING to plist. @@ -314,16 +313,16 @@ match any valid elisp symbol (but please don't quote it)." (when (string-match ":thing-at-point \\([[:alnum:][:punct:]]+\\)" string) (list :thing-at-point (org-strip-quotes (match-string 1 string))))) -(defun org-transclusion-content-format-src-lines (type content indent) +(defun org-transclusion-content-format-lines (type content plist) "Format text CONTENT from source before transcluding. Return content modified (or unmodified, if not applicable). This is the default one. It only returns the content as is. INDENT is the number of current indentation of the #+transclude." - (when (org-transclusion-src-lines-p type) + (when (string= type "lines") (let ((content (org-transclusion-ensure-newline content))) - (org-transclusion-content-format type content indent)))) + (org-transclusion-content-format type content plist)))) (defun org-transclusion-ensure-newline (str) (if (not (string-suffix-p "\n" str)) diff --git a/org-transclusion.el b/org-transclusion.el index 6b6d0a8..0c1c45e 100644 --- a/org-transclusion.el +++ b/org-transclusion.el @@ -995,7 +995,7 @@ based on the following arguments: (insert (run-hook-with-args-until-success 'org-transclusion-content-format-functions - type content (plist-get keyword-values :current-indentation))) + type content keyword-values)) (setq end (point)) (setq end-mkr (set-marker (make-marker) end)) (unless copy @@ -1045,7 +1045,7 @@ This function sssumes the buffer is an Org buffer." (push (org-element-property :level h) list))) (when list (seq-min list)))) -(defun org-transclusion-content-format-org (type content _indent) +(defun org-transclusion-content-format-org (type content _plist) "Format text CONTENT from source before transcluding. Return content modified (or unmodified, if not applicable). @@ -1070,18 +1070,19 @@ content." ;; Return the temp-buffer's string (buffer-string))))) -(defun org-transclusion-content-format (_type content indent) +(defun org-transclusion-content-format (_type content plist) "Format text CONTENT from source before transcluding. Return content modified (or unmodified, if not applicable). This is the default one. It only returns the content as is. INDENT is the number of current indentation of the #+transclude." - (with-temp-buffer - (insert content) - ;; Return the temp-buffer's string - (set-left-margin (point-min)(point-max) indent) - (buffer-string))) + (let ((indent (plist-get plist :current-indentation))) + (with-temp-buffer + (insert content) + ;; Return the temp-buffer's string + (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. From c9d696ad08de02de7ef6814e01ffa392aafa94f7 Mon Sep 17 00:00:00 2001 From: Noboru Ota Date: Mon, 8 May 2023 17:16:39 +0200 Subject: [PATCH 2/3] refactor(src-lines.el): wrapping src is not a type --- org-transclusion-src-lines.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org-transclusion-src-lines.el b/org-transclusion-src-lines.el index a2491cc..f8d3cfe 100644 --- a/org-transclusion-src-lines.el +++ b/org-transclusion-src-lines.el @@ -198,7 +198,7 @@ it means from line 10 to the end of file." (defun org-transclusion-content-format-src (type content plist) "Format text CONTENT from source before transcluding. Return content modified (or unmodified, if not applicable)." - (when (string= type "src") + (when (plist-member plist :src) (let ((content (org-transclusion-ensure-newline content)) (src-lang (plist-get plist :src)) (rest (plist-get plist :rest))) From b0b493afb657c9459f856135361b3114890a8985 Mon Sep 17 00:00:00 2001 From: Noboru Ota Date: Mon, 8 May 2023 18:50:07 +0200 Subject: [PATCH 3/3] refactor(thing-at-point) WIP not working --- org-transclusion-src-lines.el | 87 +++++++++++++++++++++++------- test/things-at-point-dir/story.txt | 2 +- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/org-transclusion-src-lines.el b/org-transclusion-src-lines.el index f8d3cfe..041bbe1 100644 --- a/org-transclusion-src-lines.el +++ b/org-transclusion-src-lines.el @@ -37,6 +37,8 @@ ;; Add a new transclusion type (add-hook 'org-transclusion-add-functions #'org-transclusion-add-src-lines) +(add-hook 'org-transclusion-add-functions + #'org-transclusion-add-thing-at-point) ;; Keyword values (add-hook 'org-transclusion-keyword-value-functions #'org-transclusion-keyword-value-lines) @@ -66,22 +68,6 @@ ;;; Functions -(defun org-transclusion--bounds-of-n-things-at-point (thing count) - "Return the bounds of COUNT THING (s) -at-point." - (save-excursion - (let ((bounds (bounds-of-thing-at-point thing))) - (when bounds - (push-mark (car bounds) t t) - (goto-char (cdr bounds)) - (while (and (> count 1) bounds) - (setq bounds (bounds-of-thing-at-point thing)) - (when bounds - (if (> count 1) - (forward-thing thing) - (goto-char (cdr bounds))) - (setq count (1- count)))) - (car (region-bounds)))))) - (defun org-transclusion-add-src-lines (link plist) "Return a list for non-Org text and source file. Determine add function based on LINK and PLIST. @@ -156,7 +142,7 @@ it means from line 10 to the end of file." (save-excursion (goto-char start-pos) (back-to-indentation) - (org-transclusion--bounds-of-n-things-at-point thing-at-point count))))) + (org-transclusion-bounds-of-n-things-at-point thing-at-point count))))) (end-pos (cond ((when thing-at-point (cdr bounds))) ((when end-search-op (save-excursion @@ -304,6 +290,31 @@ for non-Org text files including program source files." (cons src-ov tc-ov)))) ;;; Thing-at-point + +(defun org-transclusion-bounds-of-n-things-at-point (thing count) + "Return the bounds of COUNT THING (s) -at-point." + (save-excursion + (let ((bounds (bounds-of-thing-at-point thing))) + (when bounds + (push-mark (car bounds) t t) + (goto-char (cdr bounds)) + (while (and (> count 1) bounds) + (setq bounds (bounds-of-thing-at-point thing)) + (when bounds + (if (> count 1) + (forward-thing thing) + (goto-char (cdr bounds))) + (setq count (1- count)))) + (car (region-bounds)))))) + +(defun org-transclusion-add-thing-at-point (link plist) + "Return a list for non-Org text and source file for a thing-at-point. +Determine add function based on LINK and PLIST." + (when (plist-member plist :thing-at-point) + (let ((type "thing-at-point")) + (append (list :tc-type type) + (org-transclusion-content-thing-at-point link plist))))) + (defun org-transclusion-keyword-value-thing-at-point (string) "It is a utility function used converting a keyword STRING to plist. It is meant to be used by `org-transclusion-get-string-to-plist'. @@ -320,7 +331,7 @@ Return content modified (or unmodified, if not applicable). This is the default one. It only returns the content as is. INDENT is the number of current indentation of the #+transclude." - (when (string= type "lines") + (when (or (string= type "lines") (string= type "thing-at-point")) (let ((content (org-transclusion-ensure-newline content))) (org-transclusion-content-format type content plist)))) @@ -329,5 +340,45 @@ INDENT is the number of current indentation of the #+transclude." (concat str "\n") str)) +(defun org-transclusion-content-thing-at-point (link plist) + "Return a list of payload for a thing-at-point from LINK and PLIST." + (let* ((path (org-element-property :path link)) + (search-option (org-element-property :search-option link)) + (type (org-element-property :type link)) + (entry-pos) (buf) + (thing-at-point (plist-get plist :thing-at-point)) + (thing-at-point (when thing-at-point (make-symbol thing-at-point)))) + (if (not (string= type "id")) (setq buf (find-file-noselect path)) + (let ((filename-pos (org-id-find path))) + (setq buf (find-file-noselect (car filename-pos))) + (setq entry-pos (cdr filename-pos)))) + (when buf + (with-current-buffer buf + (org-with-wide-buffer + (let* ((start-pos (cond + (entry-pos) + ((when search-option + (save-excursion + (ignore-errors + ;; FIXME `org-link-search' does not + ;; return postion when eithher + ;; ::/regex/ or ::number is used + (if (org-link-search search-option) + (line-beginning-position)))))) + ((point-min)))) + (end-search-op (plist-get plist :end)) + (bounds (let ((count (if end-search-op + (string-to-number end-search-op) 1))) + (save-excursion + (goto-char start-pos) + (back-to-indentation) + (org-transclusion-bounds-of-n-things-at-point thing-at-point count)))) + (end-pos (cdr bounds)) + (content (buffer-substring-no-properties start-pos end-pos))) + (list :src-content content + :src-buf (current-buffer) + :src-beg start-pos + :src-end end-pos))))))) + (provide 'org-transclusion-src-lines) ;;; org-transclusion-src-lines.el ends here diff --git a/test/things-at-point-dir/story.txt b/test/things-at-point-dir/story.txt index 3c9521d..4c8f890 100644 --- a/test/things-at-point-dir/story.txt +++ b/test/things-at-point-dir/story.txt @@ -1,6 +1,6 @@ This is a story -Once upon a time. This paragraph should be transcluded. This is a story. +This is a sentence before. Once upon a time. This paragraph should be transcluded. This is a story. And if I have a hard line break, I belive this line is still part of the paragraph as defined by ... thing-at-point I think.