diff --git a/org-transclusion-src-lines.el b/org-transclusion-src-lines.el index 4d431e7..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) @@ -54,8 +56,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) @@ -65,40 +68,26 @@ ;;; 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. 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. @@ -153,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 @@ -192,28 +181,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 (plist-member plist :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. @@ -305,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'. @@ -314,21 +324,61 @@ 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 (or (string= type "lines") (string= type "thing-at-point")) (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)) (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/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. 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.