From 008a7bc2426861127e9d2784ecce2cfcf13f02d8 Mon Sep 17 00:00:00 2001 From: driftcrow Date: Sun, 2 Jan 2022 21:27:01 +0800 Subject: [PATCH 1/2] create plus addon --- org-transclusion-plus.el | 161 +++++++++++++++++++++++++++++++++++++++ test/test-plus.org | 56 ++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 org-transclusion-plus.el create mode 100644 test/test-plus.org diff --git a/org-transclusion-plus.el b/org-transclusion-plus.el new file mode 100644 index 0000000..869eee4 --- /dev/null +++ b/org-transclusion-plus.el @@ -0,0 +1,161 @@ +;;; org-transclusion-src-lines.el --- Extension -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(require 'org-element) +;; (declare-function text-clone-make-overlay 'text-clone) +;; (declare-function org-transclusion-live-sync-buffers-others-default +;; 'org-transclusion) + +;;;; Customization +(defcustom org-transclusion-plus-enable-cache t + "Define whether to enable plus use cache file." + :type 'boolean + :group 'org-transclusion) + +;;;; Setting up the extension + +;; Add a new transclusion type +(add-hook 'org-transclusion-add-functions + #'org-transclusion-add-plus) +;; Keyword values +(add-hook 'org-transclusion-keyword-value-functions + #'org-transclusion-keyword-value-plus) +(add-hook 'org-transclusion-keyword-plist-to-string-functions + #'org-transclusion-keyword-plist-to-string-plus) + +;; Transclusion content formating +;; Not needed. Default works for text files. + + +;;; Functions + +(defun org-transclusion-add-plus (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 \":plus\" properties." + (cond + ((plist-get plist :plus) + (append '(:tc-type "plus") + (org-transclusion-plus-payload link plist))) + ) + ) + +(defun org-transclusion-plus-payload (link plist) + "Return a payload processed with default procedure use the file +that created by plus ." + (let* ((work-file (org-transclusion-plus-content link plist)) + (new-link (concat "[[file:" work-file "]]")) + (plist (plist-put plist :cache-file work-file)) ;; reserve for live edit + (new-plist (copy-sequence plist)) + (new-plist (plist-put new-plist :link new-link)) + (new-link (org-transclusion-wrap-path-to-link new-link)) + (org-transclusion-add-functions + (remove 'org-transclusion-add-plus org-transclusion-add-functions )) + (payload (run-hook-with-args-until-success + 'org-transclusion-add-functions new-link new-plist))) + + payload + )) + + +(defun org-transclusion-plus-content (link plist) + "Return a list of payload for a range of lines from LINK and PLIST. + +You can specify a range of lines to transclude by adding the :line +property to a transclusion keyword like this: + + #+transclude: [[file:path/to/file.ext]] :lines 1-10 + +This is taken from Org Export (function +`org-export--inclusion-absolute-lines' in ox.el) with one +exception. Instead of :lines 1-10 to exclude line 10, it has +been adjusted to include line 10. This should be more intuitive +when it comes to including lines of code. + +In order to transclude a single line, have the the same number in +both places (e.g. 10-10, meaning line 10 only). + +One of the numbers can be omitted. When the first number is +omitted (e.g. -10), it means from the beginning of the file to +line 10. Likewise, when the second number is omitted (e.g. 10-), +it means from line 10 to the end of file." + (let* ((path (org-element-property :path link)) + (r-file (if (file-name-absolute-p path) path (expand-file-name path))) + (work-file-name (file-name-nondirectory r-file)) + (plus (string-trim (plist-get plist :plus))) + (cache-id (md5 (concat path plus))) + (work-dir (concat (temporary-file-directory) cache-id "/")) + (work-file (expand-file-name work-file-name work-dir)) + (src (cond + ((string-match "\(.*\)" plus) plus) + ((string-match "^[^\(\)]+$" plus) (org-babel-expand-noweb-references (org-babel-lob--src-info plus))) + (t "()") + )) + ) + (unless (and org-transclusion-plus-enable-cache + (file-exists-p! work-file-name work-dir) + (time-less-p + (file-attribute-modification-time (file-attributes r-file)) + (file-attribute-modification-time (file-attributes work-file))) + ) + (make-directory work-dir t) + (copy-file r-file work-dir t) + (let* ((buf (find-file-noselect work-file))) + (when buf + (with-current-buffer buf + + (goto-char (point-min)) + (eval (car (read-from-string (format "(progn %s)" src)))) + (save-buffer) + )) + ) + ) + + work-file) + ) + + + +(defun org-transclusion-keyword-value-plus (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'. +It needs to be set in +`org-transclusion-get-keyword-values-hook'. +Double qutations are mandatory." + (when (string-match ":plus +\\([^:]*\\)" string) + (list :plus (org-strip-quotes (match-string 1 string))))) + +(defun org-transclusion-keyword-plist-to-string-plus (plist) + "Convert a keyword PLIST to a string. +This function is meant to be used as an extension for function +`org-transclusion-keyword-plist-to-string'. Add it to the +abnormal hook +`org-transclusion-keyword-plist-to-string-functions'." + (let ((string nil) + (plus (plist-get plist :plus)) + ) + (concat string + (when plus (format ":plus %s" plus)) + ))) + + +(defun org-transclusion-plus-get-content () + + ) + + +(defun org-transclusion-expand-all () + "Expand all in transclusion buffer." + + ;; get absolute path + ;; (expand-file-name "relative/path" (file-name-directory load-file-name)) + ) + +(provide 'org-transclusion-plus) +;;; org-transclusion-plus.el ends here + +;; (add-to-list 'org-transclusion-extensions 'org-transclusion-plus) diff --git a/test/test-plus.org b/test/test-plus.org new file mode 100644 index 0000000..00bb169 --- /dev/null +++ b/test/test-plus.org @@ -0,0 +1,56 @@ +#+TITLE: Test Plus + + + + +# Test REGEXP select and :lines together +#+transclude: [[file:test-2.0.org]] :plus (keep-lines "link") :lines 3-10 :src org + +#+transclude: [[file:test-2.0.org]] :plus (insert "test for plus\n") :lines 1-10 :src org + +# Test plus with code define in doc +#+transclude: [[file:test-2.0.org]] :plus test-1 :src org + +# Test transclude self with +#+transclude: [[file:test-plus.org]] :plus (flush-lines "|.*| xs") :lines 30- :src org + +* Test code + +#+NAME: test-1 +#+begin_src emacs-lisp +(goto-line 5 ) +(kill-line 3) + +(goto-line 12 ) +(kill-line 3) + +;; Do anything ..... +#+end_src + +* Test table +| Operator | Type(A) | Type(B) | Function | +|----------+----------------------+----------------------+---------------------------------------------------| +| A + B | numeric | numeric | op:numeric-add(A, B) | +| A + B | xs:date | xs:yearMonthDuration | op:add-yearMonthDuration-to-date(A, B) | +| A + B | xs:yearMonthDuration | xs:date | op:add-yearMonthDuration-to-date(B, A) | +| A + B | xs:date | xs:dayTimeDuration | op:add-dayTimeDuration-to-date(A, B) | +| A + B | xs:dayTimeDuration | xs:date | op:add-dayTimeDuration-to-date(B, A) | +| A + B | xs:time | xs:dayTimeDuration | op:add-dayTimeDuration-to-time(A, B) | +| A + B | xs:dayTimeDuration | xs:time | op:add-dayTimeDuration-to-time(B, A) | +| A + B | xs:dateTime | xs:yearMonthDuration | op:add-yearMonthDuration-to-dateTime(A, B) | +| A + B | xs:yearMonthDuration | xs:dateTime | op:add-yearMonthDuration-to-dateTime(B, A) | +| A + B | xs:dateTime | xs:dayTimeDuration | op:add-dayTimeDuration-to-dateTime(A, B) | +| A + B | xs:dayTimeDuration | xs:dateTime | op:add-dayTimeDuration-to-dateTime(B, A) | +| A + B | xs:yearMonthDuration | xs:yearMonthDuration | op:add-yearMonthDurations(A, B) | +| A + B | xs:dayTimeDuration | xs:dayTimeDuration | op:add-dayTimeDurations(A, B) | +| A - B | numeric | numeric | op:numeric-subtract(A, B) | +| A - B | xs:date | xs:date | op:subtract-dates(A, B) | +| A - B | xs:date | xs:yearMonthDuration | op:subtract-yearMonthDuration-from-date(A, B) | +| A - B | xs:date | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-date(A, B) | +| A - B | xs:time | xs:time | op:subtract-times(A, B) | +| A - B | xs:time | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-time(A, B) | +| A - B | xs:dateTime | xs:dateTime | op:subtract-dateTimes(A, B) | +| A - B | xs:dateTime | xs:yearMonthDuration | op:subtract-yearMonthDuration-from-dateTime(A, B) | +| A - B | xs:dateTime | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-dateTime(A, B) | +| A - B | xs:yearMonthDuration | xs:yearMonthDuration | op:subtract-yearMonthDurations(A, B) | +| A - B | xs:dayTimeDuration | xs:dayTimeDuration | op:subtract-dayTimeDurations(A, B) | From 402220082c176459691830befdb767143f76d206 Mon Sep 17 00:00:00 2001 From: driftcrow Date: Sun, 2 Jan 2022 22:09:29 +0800 Subject: [PATCH 2/2] clean code --- org-transclusion-plus.el | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/org-transclusion-plus.el b/org-transclusion-plus.el index 869eee4..a5b8b8f 100644 --- a/org-transclusion-plus.el +++ b/org-transclusion-plus.el @@ -1,7 +1,8 @@ ;;; org-transclusion-src-lines.el --- Extension -*- lexical-binding: t; -*- ;;; Commentary: - +;; (add-to-list 'org-transclusion-extensions 'org-transclusion-plus) +;; ;;; Code: (require 'org-element) @@ -63,26 +64,7 @@ that created by plus ." (defun org-transclusion-plus-content (link plist) - "Return a list of payload for a range of lines from LINK and PLIST. - -You can specify a range of lines to transclude by adding the :line -property to a transclusion keyword like this: - - #+transclude: [[file:path/to/file.ext]] :lines 1-10 - -This is taken from Org Export (function -`org-export--inclusion-absolute-lines' in ox.el) with one -exception. Instead of :lines 1-10 to exclude line 10, it has -been adjusted to include line 10. This should be more intuitive -when it comes to including lines of code. - -In order to transclude a single line, have the the same number in -both places (e.g. 10-10, meaning line 10 only). - -One of the numbers can be omitted. When the first number is -omitted (e.g. -10), it means from the beginning of the file to -line 10. Likewise, when the second number is omitted (e.g. 10-), -it means from line 10 to the end of file." + "Return a temp file processed with plus eval." (let* ((path (org-element-property :path link)) (r-file (if (file-name-absolute-p path) path (expand-file-name path))) (work-file-name (file-name-nondirectory r-file)) @@ -143,19 +125,5 @@ abnormal hook ))) -(defun org-transclusion-plus-get-content () - - ) - - -(defun org-transclusion-expand-all () - "Expand all in transclusion buffer." - - ;; get absolute path - ;; (expand-file-name "relative/path" (file-name-directory load-file-name)) - ) - (provide 'org-transclusion-plus) ;;; org-transclusion-plus.el ends here - -;; (add-to-list 'org-transclusion-extensions 'org-transclusion-plus)