From 360938b43a9c6a731114840c9b6db7c79f786116 Mon Sep 17 00:00:00 2001 From: Phil Estival Date: Sat, 13 Jul 2024 14:46:08 +0200 Subject: [PATCH] add header-arg :tangle-directory declares a directory or a list of directories as parent(s) to the :tangle argument --- lisp/ob-tangle.el | 16 ++++++-- testing/lisp/test-ob-tangle.el | 72 +++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index c89763efa..c494571dc 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -269,11 +269,20 @@ matching a regular expression." (when (equal arg '(16)) (or (cdr (assq :tangle (nth 2 (org-babel-get-src-block-info 'no-eval)))) (user-error "Point is not in a source code block")))) + (dirs (cdr (assq :tangle-directory (nth 2 (org-babel-get-src-block-info))))) path-collector - (source-file buffer-file-name)) - (mapc ;; map over file-names + (source-file buffer-file-name)) + + (setq dirs (cl-case (type-of dirs) + (string (list dirs)) + (cons dirs) + (symbol '(nil)))) + + (dolist (dir dirs) ; iterate the n-tangle group + (progn + (mapc ; map over directories (lambda (by-fn) - (let ((file-name (car by-fn))) + (let ((file-name (concat dir (car by-fn)))) (when file-name (let ((lspecs (cdr by-fn)) (fnd (file-name-directory file-name)) @@ -354,6 +363,7 @@ matching a regular expression." (if (equal arg '(4)) (org-babel-tangle-single-block 1 t) (org-babel-tangle-collect-blocks lang-re tangle-file))) + )) (message "Tangled %d code block%s from %s" block-counter (if (= block-counter 1) "" "s") (file-name-nondirectory diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el index e13bca0cb..a725cdb14 100644 --- a/testing/lisp/test-ob-tangle.el +++ b/testing/lisp/test-ob-tangle.el @@ -27,6 +27,7 @@ (require 'subr-x) (require 'ob-tangle) +(require 'find-file) (require 'org) ;; TODO @@ -660,7 +661,13 @@ another block #+begin_src emacs-lisp :tangle ~/../../tmp/absolute.el \"H2: :tangle ~/../../tmp/absolute.el\" -#+end_src" +#+end_src + +#+begin_src emacs-lisp :tangle-directory '(\"/tmp/a/\" \"tmp/b/\") :tangle multiple.el +\"H2: :tangle /tmp/multiple.el\" +#+end_src + +" `((?a . ,el-file-abs) (?r . ,el-file-rel)))) ;; We check the collected blocks to tangle by counting equal @@ -699,6 +706,7 @@ another block (should (equal (funcall normalize-expected-targets-alist `(("/tmp/absolute.el" . 4) + ("/tmp/multiple.el" . 1) ("relative.el" . 5) ;; Default :tangle header now also ;; points to the file name derived from the name of @@ -707,6 +715,68 @@ another block (funcall count-blocks-in-target-files (org-babel-tangle-collect-blocks))))))))) +(ert-deftest ob-tangle/directory () + "Test if ob-tangle/directory works correctly for one directory." + (should + (equal '("1") + (let* ( + (dir (make-temp-file "org-tangle-dir-test-" t)) + (filename (md5(format "%s" (current-time)))) + (file (concat dir "/" filename)) + ) + (unwind-protect + (progn + (org-test-with-temp-text-in-file + (format " +#+begin_src elisp :tangle-directory %s :tangle /%s +1 +#+end_src +" dir filename) + (let ((org-babel-noweb-error-all-langs nil) + (org-babel-noweb-error-langs nil)) + (org-babel-tangle '(4)))) + + (with-temp-buffer + (insert-file-contents file) + (org-split-string (buffer-string)))) + + (delete-file file))) + ))) + + +(ert-deftest ob-tangle/multiple-directories () + "Test if ob-tangle/directory works correctly for multiple directory." + (should + (equal '("1" "1") + (let* ( + (dir1 (make-temp-file "org-tangle-dir-test-" t)) + (dir2 (make-temp-file "org-tangle-dir-test-" t)) + (filename (md5(format "%s" (current-time)))) + (file1 (concat dir1 "/" filename)) + (file2 (concat dir2 "/" filename)) + ) + (unwind-protect + (progn + (org-test-with-temp-text-in-file + (format " +#+begin_src elisp :tangle-directory '(\"%s\" \"%s\") :tangle /%s +1 +#+end_src +" dir1 dir2 filename) + (let ((org-babel-noweb-error-all-langs nil) + (org-babel-noweb-error-langs nil)) + (org-babel-tangle '(4)))) + + (with-temp-buffer + (insert-file-contents file1) + (insert-file-contents file2) + (org-split-string (buffer-string)))) + (progn + (delete-file file1) + (delete-file file2)))) + ))) + + (provide 'test-ob-tangle) ;;; test-ob-tangle.el ends here -- 2.39.2