Ihor Radchenko <yanta...@posteo.net> writes: > It will be great if you could do it. > I have other things to work on.
Of course! I'm just a little unfamiliar on how one coordinates active collaboration via mailing list :-) Anyways - I did it, and it took less time than I thought > We should modify it. For example like the following: > > 1. We will assume that :any can only occur one time in the exclusive > groups. (Otherwise, there is no single definite way to parse header > arguments) > 2. Merge function will treat :any specially - when parameter does not > match any of the argument values from all the groups combined, it is > considered as :any and replace the previous corresponding values in > its exclusive group, if any; > In other words, we will need a special match for :any - "anything not > equal to other values in all the groups combined". I've modified the `merge' function within `org-babel-merge-params' so that the main logic now accumulates a list of potential candidates that could be the :any keyword, and selects the last added candidate as the match. The first two patches are very minor, simply adding tangle-exclusive-groups using the existing code templates. The last patch is the merge function rewrite. It all seems to be passing tests, though I would like to add my toy.org file to the org testing framework at some point. Best, Mehmet
>From eeb3f165498fcc420b862f67fb616b474a14b684 Mon Sep 17 00:00:00 2001 From: MT <mtekma...@gmail.com> Date: Wed, 10 May 2023 17:38:22 +0200 Subject: [PATCH 1/3] * lisp/ob-core.el (org-babel-common-header-args-w-values): Added mutually exclusive tangle groups relating to desired tangle sync actions (e.g. :tangle (yes|no|<filename>) [(import|export|sync)]) --- lisp/ob-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 65fa47ab5..013a37ce5 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -431,7 +431,8 @@ then run `org-babel-switch-to-session'." (sep . :any) (session . :any) (shebang . :any) - (tangle . ((tangle yes no :any))) + (tangle . ((tangle yes no :any) + (import export skip sync))) (tangle-mode . ((#o755 #o555 #o444 :any))) (var . :any) (wrap . :any))) -- 2.40.1
>From 366a120a394d7783bf1640037ade31f826ef0277 Mon Sep 17 00:00:00 2001 From: MT <mtekma...@gmail.com> Date: Wed, 10 May 2023 17:41:37 +0200 Subject: [PATCH 2/3] * lisp/ob-core.el (org-babel-merge-params): Tangle header with exclusive parameters can now be parsed, following the template of :exports and :results --- lisp/ob-core.el | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 013a37ce5..ed31a9de1 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -2803,6 +2803,9 @@ parameters when merging lists." (exports-exclusive-groups (mapcar (lambda (group) (mapcar #'symbol-name group)) (cdr (assq 'exports org-babel-common-header-args-w-values)))) + (tangle-exclusive-groups + (mapcar (lambda (group) (mapcar #'symbol-name group)) + (cdr (assq 'tangle org-babel-common-header-args-w-values)))) (merge (lambda (exclusive-groups &rest result-params) ;; Maintain exclusivity of mutually exclusive parameters, @@ -2822,7 +2825,7 @@ parameters when merging lists." params ;Final parameters list. ;; Some keywords accept multiple values. We need to treat ;; them specially. - vars results exports) + vars results exports tangle) (dolist (plist plists) (dolist (pair plist) (pcase pair @@ -2873,6 +2876,12 @@ parameters when merging lists." (cond ((and value (functionp value)) (funcall value)) (value value) (t "")))))) + (`(:tangle . ,value) + (setq tangle (funcall merge + tangle-exclusive-groups + tangle + (split-string + (or value ""))))) ((or '(:dir . attach) '(:dir . "'attach")) (unless (org-attach-dir nil t) (error "No attachment directory for element (add :ID: or :DIR: property)")) @@ -2898,7 +2907,8 @@ parameters when merging lists." params))))) ;; Handle other special keywords, which accept multiple values. (setq params (nconc (list (cons :results (mapconcat #'identity results " ")) - (cons :exports (mapconcat #'identity exports " "))) + (cons :exports (mapconcat #'identity exports " ")) + (cons :tangle (mapconcat #'identity tangle " "))) params)) ;; Return merged params. (org-babel-eval-headers params))) -- 2.40.1
>From 6ce5313b7d3f0ab718072942f082bc259dccbae6 Mon Sep 17 00:00:00 2001 From: MT <mtekma...@gmail.com> Date: Wed, 10 May 2023 17:44:42 +0200 Subject: [PATCH 3/3] * lisp/ob-core.el (org-babel-merge-params): Major rewrite of the `merge' function, which adds the capability to process the :any keyword when merging parameters with exclusive groups. --- lisp/ob-core.el | 60 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index ed31a9de1..3d9000efc 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -2811,15 +2811,61 @@ parameters when merging lists." ;; Maintain exclusivity of mutually exclusive parameters, ;; as defined in EXCLUSIVE-GROUPS while merging lists in ;; RESULT-PARAMS. - (let (output) + (let (output group-any) (dolist (new-params result-params (delete-dups output)) (dolist (new-param new-params) - (dolist (exclusive-group exclusive-groups) - (when (member new-param exclusive-group) - (setq output (cl-remove-if - (lambda (o) (member o exclusive-group)) - output)))) - (push new-param output)))))) + (let (matched-param potential-any-param) + ;; new-param may be an :any value, so we check + ;; across all exclusive-groups. + ;; - If new-param matches one of groups, we + (dolist (exclusive-group exclusive-groups) + (if (member new-param exclusive-group) + (setq output (cl-remove-if + (lambda (o) (member o exclusive-group)) + output) + ;; Cancel any potential matches if it's caught + matched-param t + potential-any-param nil) + ;; If not a direct match, flag it as a potential + ;; :any match This can happen multiple times for + ;; each new-param, but only once for each + ;; exclusive-group. + (if (and (not matched-param) + (member ":any" exclusive-group)) + ;; At this point, the new-param has not yet matched + ;; anything in the N exclusive groups + ;; - We also assume that only 1 of these N groups + ;; has the :any keyword. + ;; - This point in the code can therefore be only + ;; reached once under this assumption. + ;; - We therefore setq instead of push + (setq potential-any-param (cons new-param + exclusive-group))))) + + ;; At this point we know whether new-param and 1 + ;; of the exclusive groups have an :any keyword - + ;; - Due to multiple new-params potentially being + ;; matches in the same group, we push these to a + ;; super group of "any" keywords, and process them + ;; later. + (if potential-any-param + (setq group-any potential-any-param) + ;; If the param isn't :any, add it to the output + ;; as a regular keyword + (push new-param output))))) + + (when group-any + ;; Whatever is leftover at this point are :any candidates. + ;; - We assume that last added is the most relevant and + ;; that everything else should be ignored + ;; - We add the first, and reject everything else in that + ;; exclusion group. + (push (car group-any) output) + (setq output (cl-remove-if + (lambda (o) (member o (cdr group-any))) + output))) + output))) + (variable-index 0) ;Handle positional arguments. clearnames params ;Final parameters list. -- 2.40.1