From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id 2JhiItFSWmQqrQAASxT56A (envelope-from ) for ; Tue, 09 May 2023 16:04:01 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id CPxrIdFSWmTcKgEAG6o9tA (envelope-from ) for ; Tue, 09 May 2023 16:04:01 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 1626B81F4 for ; Tue, 9 May 2023 16:04:01 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pwNvr-0006IQ-Cg; Tue, 09 May 2023 10:03:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pwNvp-0006Ha-CP for emacs-orgmode@gnu.org; Tue, 09 May 2023 10:03:09 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pwNvn-0000Xt-Bp for emacs-orgmode@gnu.org; Tue, 09 May 2023 10:03:09 -0400 Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-306f2b42a86so3772311f8f.3 for ; Tue, 09 May 2023 07:03:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683640985; x=1686232985; h=mime-version:message-id:date:user-agent:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=W9AZOsK3Wyd2QKIO/0skvE4bqD97Kzn5/pCbl/MtVw4=; b=RqTG0sTtZvzckqSABZgfMY61rlqqVthWaD5VslWQ/ZlgW/6KGBsWNFCBa77gD5R6Uj wyXaIum0Kf0wNKYtv9mNQY+BdzXYQsum3kYG34wF/uwtpBsPLhrGBGerShY7/qtZ+LlV f2KCih1iMmiijtDfGu7u0nTH5y96cTDL/7wyjs8JX7tM7wK1wBallWJNEgSH625ViITF s+Vf2anAIgP8gA40kCoomN0x1BVnk4uz39MZjlfCmahaGbFM2UVOW3MEYKZyqjSHXCz3 HIxPCHyxZlkkZsuDjtwtWMbO1m2HI/YhV7TNIBBvCFiZ/havq19maVOI4QEXTqS9HLr3 2P2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683640985; x=1686232985; h=mime-version:message-id:date:user-agent:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=W9AZOsK3Wyd2QKIO/0skvE4bqD97Kzn5/pCbl/MtVw4=; b=I9DWxg+UNM2keC+Ls7gZbjyRvwEhRRrp3SvcwiSQ22alu5B3jJ2ui1G0eLXCZmN3VW VmkgKU3xFCP5oiOhkWwcZwEX5MvnAM2VIMCP+/EA56apldpRDtcPEVCOJTRq909a+nHu RbHqEB0Qb8Ec+CVkUhr0P8fVAMqPXz1tCoBR4FaXNljmveLPMuBNfpi8VK4wTHPn+vjs j0SxgGzthvOtxsSmO6TkVnryoHyolfp3Wm0P0vnCbxqp+PisPgzlBj7XaEb4q4rg/Yjq wRHvak4kAyryl9BsldfgELcArhDVPFDXDSDNZnqBbmIVqvTT9CRBqEST0+ntSCiYsfTN hBIg== X-Gm-Message-State: AC+VfDyMPGidhOCDzW4b8XrGL6um6bEizLguGUdqN00QSwxCqgGz6T+0 QjOLCXrrW0yt4m5M61VjGEavchHDHI4= X-Google-Smtp-Source: ACHHUZ4/LgDjpElO4Z/V9Pv8QhVnJzI73/2wd/9aGsjyW25mntcGWST/F7orI+s0cDfty5y/dS23iw== X-Received: by 2002:adf:f452:0:b0:306:8477:85d0 with SMTP id f18-20020adff452000000b00306847785d0mr9956331wrp.33.1683640984823; Tue, 09 May 2023 07:03:04 -0700 (PDT) Received: from hayvan (pharma2-70.w2k.pharmakol.uni-freiburg.de. [132.230.165.170]) by smtp.gmail.com with ESMTPSA id f4-20020adffcc4000000b003063d83a168sm14396532wrs.26.2023.05.09.07.03.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 May 2023 07:03:04 -0700 (PDT) From: Mehmet Tekman To: Ihor Radchenko Cc: emacs-orgmode@gnu.org Subject: Re: [ANN] lisp/ob-tangle-sync.el In-Reply-To: <87fs8duyae.fsf@localhost> (Ihor Radchenko's message of "Wed, 03 May 2023 17:20:41 +0000") References: <87r0rxabd4.fsf@localhost> <87sfcd78vw.fsf@gmail.com> <87r0rxv3t5.fsf@localhost> <87lei577g4.fsf@gmail.com> <87lei5v1fg.fsf@localhost> <87fs8duyae.fsf@localhost> User-Agent: Gnus/5.13 (Gnus v5.13) Date: Tue, 09 May 2023 16:03:03 +0200 Message-ID: <8735451u20.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2a00:1450:4864:20::429; envelope-from=mtekman89@gmail.com; helo=mail-wr1-x429.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN ARC-Seal: i=1; s=key1; d=yhetil.org; t=1683641041; a=rsa-sha256; cv=none; b=OoNjjFexMtYHloWgYYQJINJAtkEj6kJwXE4V2XjDRyHDY7agTxlWI/PBNYMrihIpX3dEKD FWTi/t3bGStvTLdpfKoph5/TCbIsJZRalaqnXmwfO+w0MPnmnMi+34/f6TJDbQnXkIbBxG LoglpZUwib+O0o+5axmhvthRhgU8sXHt7Y8tZO/7OS/90NRQjYZk47C6M9/w9mMQpoyS74 YvUOhtnjmF45VUbd0L1nYykGL0reHm8zZTqj4dBSJzarfObuCWMjNBVCRFbDOUMK1trbLr mhesv85majyNVp6veEiPWB9caEF6OMa56tHTum/M98V+jFptdMLYm9mAT+7IHg== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20221208 header.b=RqTG0sTt; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1683641041; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=W9AZOsK3Wyd2QKIO/0skvE4bqD97Kzn5/pCbl/MtVw4=; b=tvcI7lrkghT424s0/EaJPcwRD74IlahX8MJXfUKuBPAoz0L8Ir16aTvfy4/wCBXFXULCUS qMAb79xGsh2TK1pWB/ZzbmWLGXBCJno0Z4BZ7u5W3BIsLGkERwyKYkRi/qIZTstOjJYunI c0bQBVVHSqYOXn1xlTNXw3o21jlhNOtdWqNsk393Tqadoy8SH8ghKApBnF5L4Z23tjMYTf lyddl/axMEveYYyJ4oYtAjpzezUwyZ4i7URZuFwkT323TV0V12XN2gbGpB+UIqWrtWg6d8 HLkz5xtJ+HCpz1/1maM2UHQPEG4XZmvescQJOM9IrdKt2JcfmUHIIXsohCSAxg== X-Migadu-Spam-Score: -8.37 X-Spam-Score: -8.37 X-Migadu-Queue-Id: 1626B81F4 X-Migadu-Scanner: scn0.migadu.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20221208 header.b=RqTG0sTt; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-TUID: d8Y9Ok0l7rzH --=-=-= Content-Type: text/plain Ihor Radchenko writes: > Yes. See `org-babel-common-header-args-w-values'. In particular, take a > look at (results ...). Thanks, it took me some time to get my head around how to use this. > I now ported a bit of documentation from my refactor branch. > See https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=f268819d1 I'm having some problems getting: `:tangle > [import/export/both/skip]' to work nicely with the existing framework. The main issue lies in the `:any` keyword in `org-babel-common-header-args-w-values' for the tangle entry making it difficult to determine where one exclusionary group begins and where the other ends. e.g. (defconst org-babel-common-header-args-w-values ... (tangle . ((tangle yes no :any) (import export skip sync))) ... ) If I remove the :any keyword, these two groups work with the existing framework in `org-babel-merge-params', but this would then mean that the first tangle argument can't just be a filename string. I can get around it by changing `:any' to `file' and then letting users describe their tangle headers via e.g. `:tangle file import file: /some/file' but this would be a breaking change. In the meantime I put together a hacky solution that parses the tangle header independently (`org-babel--handle-tangle-args') with the aim that the first argument should ideally define a tangle filename action and the second argument should ideally define a tangle sync action. Please see the attached minor patch (diff) and a toy org example file. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=001_exlusive_groups.patch Content-Description: Exclusive values for TANGLE header arguments added to the `org-babel-common-header-args-w-values' constant, along with a dedicated function `org-babel--handle-tangle-args' which parses it to conform to a `:tangle ' format. diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 65fa47ab5..026788c00 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))) @@ -2802,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, @@ -2821,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 @@ -2872,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)")) @@ -2897,11 +2907,38 @@ 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 (org-babel--handle-tangle-args tangle))) params)) ;; Return merged params. (org-babel-eval-headers params))) +(defun org-babel--handle-tangle-args (tangle) + "Sanitize tangle arguments. +From the list of TANGLE parameters, assert that that there are at +maximum only two elements in the following preferential order: +the first element relates to a filename descriptor (such as a +path, `tangle', `yes', or `no'); the second element relates to a +valid sync direction." + (let* ((num-args (length tangle)) + ;; Extract valid mutex groups + (valid-tangle-headers (cdr (assoc 'tangle + org-babel-common-header-args-w-values))) + (valid-fname-args (seq-remove (lambda (x) (equal :any x)) (car valid-tangle-headers))) + (valid-sync-args (cadr valid-tangle-headers)) + ;; Attempt to split TANGLE by these mutex groups + (sync-arg (seq-filter (lambda (x) (member (intern x) valid-sync-args)) tangle)) + (fname-arg (seq-remove (lambda (x) (member x sync-arg)) tangle)) + ;; Search for a potential filename + (filename (seq-remove (lambda (x) (member (intern x) valid-fname-args)) fname-arg))) + (setq sync-arg (car sync-arg) + ;; Assumption: the last added tangle argument is more + ;; important than the one preceding it. + fname-arg (or (car filename) + (car fname-arg))) + (concat fname-arg (if sync-arg " " "" ) sync-arg))) + + (defun org-babel-noweb-p (params context) "Check if PARAMS require expansion in CONTEXT. CONTEXT may be one of :tangle, :export or :eval." --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=toy2.org Content-Description: Toy example file #+TITLE: Sync test #+PROPERTY: header-args :tangle /tmp/default_tangle.txt Running =(assoc :tangle (nth 2 (org-babel-get-src-block-info)))= on each of these should yield: #+begin_src conf (:tangle . /tmp/default_tangle.txt) #+end_src #+begin_src conf :tangle skip (:tangle . /tmp/default_tangle.txt skip) #+end_src #+begin_src conf :tangle randomfile sync (:tangle . randomfile sync) #+end_src #+begin_src conf :tangle randomfile (:tangle . randomfile) #+end_src #+begin_src conf :tangle import export ## Ignores import (:tangle . /tmp/default_tangle.txt export) #+end_src #+begin_src conf :tangle fname1 fname2 sync export ## Ignores fname1 and sync (:tangle . fname2 export) #+end_src --=-=-=--