From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms1.migadu.com with LMTPS id 8MNYEZP5E2alKAAAe85BDQ:P1 (envelope-from ) for ; Mon, 08 Apr 2024 16:05:07 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id 8MNYEZP5E2alKAAAe85BDQ (envelope-from ) for ; Mon, 08 Apr 2024 16:05:07 +0200 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=hMt5Vp+6; 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"; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1712585107; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to: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=zY5eaS53Xf54Un/V+Qa27+1PGdSca+2+jbHSnLzfFvk=; b=AMqRKuNrQ/iEW9El8Ltm3Cp5BeSdSWnv/Dbe5giJbiLXNLU8Uqe07nfjZqifEZlCd8lMeV hGYvGM9vPQ61GIg1XYK1IqGZDbWPvrK15NuD3ECHkUaCqSZJ2TxRczsVLLeZEH6+4FEd/q OAMGmbkiguIfCkA4rgBWs/0f+18TWPImgZmnrSxRSUAQ2mDvD2ORl/JnbXCexpdQzm2EeJ opl17X4tOc6QTItE+c061Ga4EWopyGYE+lfl4PgVjnBTmydFQneTs8wsiBE+gK9XUq5V0q dZkLZBcbiQASqfskFCgid0FmLItXBes6wGA4wX2CQPFXujC9WFTpmd/Pn3eI+A== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1712585107; a=rsa-sha256; cv=none; b=nbVzcUjnA9z5/hVxVj6awgMzseykNeH8ipvSlIBXXXIzNq7aJOBCKmqfNACN94KQm8GWV2 1PEdm4ve5HALS5fyaBJT4YCbHzMh3BRoaZo/Lq1j+I8FeQIJn7Lbt4caax0hDQ8GC4PB37 2mM3dRk+sqR5Mzo4wfAXZKNlQqCukdu6TNIaJkCTEaQmjoPeiEDl+OPeyuz15vjqcy6DBC EKm7Fq8dlFlY/sRO8CRZYpgXEHk4kvWedvWORnBrNmEVAR9OGj5qHOkWRyUaAQDoGnV26S JFXASsX3Fzr3IDMWQdYh/xAt9rsQrsUNDVol/gYmP/pY99f6jfIntX9zABC6FQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=hMt5Vp+6; 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"; dmarc=pass (policy=none) header.from=gmail.com 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 DFE9C61853 for ; Mon, 8 Apr 2024 16:05:06 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rtpbh-0004k5-G0; Mon, 08 Apr 2024 10:04:21 -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 1rtpbe-0004jg-6A for emacs-orgmode@gnu.org; Mon, 08 Apr 2024 10:04:18 -0400 Received: from mail-qt1-x832.google.com ([2607:f8b0:4864:20::832]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rtpbb-0000e9-JJ for emacs-orgmode@gnu.org; Mon, 08 Apr 2024 10:04:17 -0400 Received: by mail-qt1-x832.google.com with SMTP id d75a77b69052e-434a76386feso4657261cf.1 for ; Mon, 08 Apr 2024 07:04:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712585052; x=1713189852; darn=gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:to:from:from:to:cc:subject:date:message-id:reply-to; bh=zY5eaS53Xf54Un/V+Qa27+1PGdSca+2+jbHSnLzfFvk=; b=hMt5Vp+6X01TkOPV5q6BQ1Q5irrK+rEFfQYOfltuAstQWMNFAQ8wEmhfJWHsRiCyFO 4QGAj5tUbbMLEOxWeR9HRT9bN22lK0FF+FZs1KiGk+bUjQ4xkF0/9ulpyzPYaJtsZd2C 9Pp0iBG5bKbCb8ciZZr6K99nltYOHORZUFUJ4mll4QuXdpnq7M+AHq7eT/HOWF944aep aMaXc9JfgZR3WI+MLvsst4FVqFISWWms//IkJy9Q7gd6qOEWATGOydRcXmDNA6WiYSdY SlWkzo79mDh2O5DGIDWIw9A9EIDFild/rFz6HdiSsAFmeGD+sT+hPWa0A9Oe4GeDWMnC Ll2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712585052; x=1713189852; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=zY5eaS53Xf54Un/V+Qa27+1PGdSca+2+jbHSnLzfFvk=; b=Roa2IgE8riZfy5YJAqPgvFHRCigfweHf6kyGgyhdfy5GyXLJTr7hjf43GZpHA56Duh VFX3sftJB3UiQKMVE2j6TsVjCiGrgjCvKo2FMj0wxry4Il1J9al0SwtZ5DcQPE5PHt2w 2Jb4WAiys41YRUOczByA0ykSsj6q2S77J7Knlc9MxLvMvFjy1yAEI92KlNdgepiVV5Y9 qgd2anIkvEJ/HQ7LfwOWB54PrnHZxXc9dpj7tN2ZUQlrZDxr7OlU1F52D/XjR+9aPR77 5lz4EVISS9ku+3d1xijvXnBrD7SGh2XGN8Arv0kVT5qUwQObp669GHBG8YsVwFvjt2b+ JhmQ== X-Gm-Message-State: AOJu0Yx/OAQqtOOnrd8M/So1rsdqExNXj7hRjxD7HoHlejvmpcoCzd/k GZz5dwepw1wLKlVv07CiPYnbILwaUHG595GBg75lDhAI+VvlXHUeQrV7co8N X-Google-Smtp-Source: AGHT+IFN0r776XBT92OqYqVkvq5ondY2OsdN4ekmt1PoIcyi49JK54RiOg82JgYbwsiRG1lNvbECOg== X-Received: by 2002:a05:622a:30a:b0:434:b593:2d25 with SMTP id q10-20020a05622a030a00b00434b5932d25mr1435021qtw.66.1712585052240; Mon, 08 Apr 2024 07:04:12 -0700 (PDT) Received: from Asus (024-236-139-114.res.spectrum.com. [24.236.139.114]) by smtp.gmail.com with ESMTPSA id b10-20020ac8754a000000b00434b1f4e371sm675823qtr.13.2024.04.08.07.04.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Apr 2024 07:04:11 -0700 (PDT) From: Amy Grinn To: emacs-orgmode@gnu.org Subject: [FR] :noweb-wrap header arg In-Reply-To: <87h6hixhnw.fsf@localhost> (Ihor Radchenko's message of "Thu, 07 Mar 2024 14:04:03 +0000") References: <87h6hixhnw.fsf@localhost> Date: Mon, 08 Apr 2024 10:04:05 -0400 Message-ID: <85wmp82boq.fsf_-_@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2607:f8b0:4864:20::832; envelope-from=grinn.amy@gmail.com; helo=mail-qt1-x832.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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 X-Migadu-Spam-Score: -9.67 X-Spam-Score: -9.67 X-Migadu-Queue-Id: DFE9C61853 X-Migadu-Scanner: mx13.migadu.com X-TUID: fEpvwpetZbDT --=-=-= Content-Type: text/plain Hi! I'm working on the :noweb-wrap header argument which controls the syntax of noweb references in a babel src block. For example: #+name: foo #+begin_src elisp :foo #+end_src #+begin_src elisp :noweb yes :noweb-wrap <<< >>> <<>> #+end_src And I would like some feedback... First of all, I would like to change (defalias) the function name org-babel-noweb-wrap to org-babel-noweb-make-regexp. I think this in more in line with other functions which create regular expressions. The new way to retrieve the regular expression matching a noweb reference in the source block at point would be: (org-babel-noweb-make-regexp nil (org-babel-get-noweb-wrap info)) Where info can be nil or the result of calling (org-babel-get-src-block-info). Second, the command org-babel-tangle-clean is not able to determine which noweb syntax is being used in any tangled source file because the header arguments are not tangled along with the source code. My proposal is to add an additional warning to this command, stating: """ Warning, this command removes any lines containing constructs which resemble Org file links or noweb references. It also cannot determine which noweb syntax is being used for any given source file, if :noweb-wrap was specified in the original Org file. """ Best, Amy --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-WIP-lisp-ob-core.el-New-noweb-wrap-header-arg.patch Content-Description: noweb-wrap header arg >From 1dc8aebcc45447d3b5b38ea3c7700ae2b2686c9d Mon Sep 17 00:00:00 2001 From: Amy Grinn Date: Mon, 8 Apr 2024 09:05:02 -0400 Subject: [PATCH] (WIP) lisp/ob-core.el: New :noweb-wrap header arg * lisp/ob-core: (org-babel-noweb-wrap): Add optional third parameter 'wrap'. * lisp/ob-core: (org-babel-get-noweb-wrap): New function for parsing :noweb-wrap header arg. * etc/ORG-NEWS (New =:noweb-wrap= babel header argument): Describe new argument. * others... --- etc/ORG-NEWS | 14 ++++++++++ lisp/ob-core.el | 51 ++++++++++++++++++++++++++++------ lisp/ob-exp.el | 3 +- lisp/ob-tangle.el | 6 +++- testing/examples/babel.org | 17 ++++++++++++ testing/lisp/test-ob-exp.el | 55 +++++++++++++++++++++++++++++++++++++ testing/lisp/test-ob.el | 15 ++++++++++ 7 files changed, 150 insertions(+), 11 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index aeb7ffd4b..162e7f035 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -621,6 +621,20 @@ link when storing any type of external link type in an Org file, not just =id:= links. ** New and changed options +*** New =:noweb-wrap= babel header argument + +This argument changes the default noweb reference syntax by masking +the options ~org-babel-noweb-wrap-start~ and +~org-babel-noweb-wrap-end~. + +=:noweb-wrap= takes two parameters, start and end, corresponding to +each option. + +For example: +: #+begin_src sh :noweb-wrap <<< >>> +: echo <<>> +: #+end_src + *** =.avif= images are now recognized in ~org-html-inline-image-rules~ In =ox-html=, =.avif= image links are now inlined by default. diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 8dfc07a4e..843794322 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -194,15 +194,21 @@ This string must include a \"%s\" which will be replaced by the results." :package-version '(Org . "9.1") :safe #'booleanp) -(defun org-babel-noweb-wrap (&optional regexp) +(defun org-babel-noweb-wrap (&optional regexp wrap) "Return regexp matching a Noweb reference. Match any reference, or only those matching REGEXP, if non-nil. +If WRAP is provided, it should be a list of 2 strings describing +the start and end of a noweb reference, such as that returned by +`org-babel-get-noweb-wrap'. Otherwise +`org-babel-noweb-wrap-start' and `org-babel-noweb-wrap-end' will +be used. + When matching, reference is stored in match group 1." - (concat (regexp-quote org-babel-noweb-wrap-start) - (or regexp "\\([^ \t\n]\\(?:.*?[^ \t\n]\\)?\\)") - (regexp-quote org-babel-noweb-wrap-end))) + (concat (regexp-quote (or (car wrap) org-babel-noweb-wrap-start)) + (or regexp "\\([^ \t\n]\\(?:.*?[^ \t\n]\\)?\\)") + (regexp-quote (or (cadr wrap) org-babel-noweb-wrap-end)))) (defvar org-babel-src-name-regexp "^[ \t]*#\\+name:[ \t]*" @@ -1963,6 +1969,27 @@ src block, then return nil." (let ((head (org-babel-where-is-src-block-head))) (if head (goto-char head) (error "Not currently in a code block")))) +(defun org-babel-get-noweb-wrap (&optional info) + "Retrieve a description the :noweb-wrap header arg from INFO. + +The description will be in the form of a list of two of strings +for the start and end of a reference. INFO can be the result of +`org-babel-get-src-block-info' otherwise this function will parse +info at point." + (unless info + (setq info (org-babel-get-src-block-info 'no-eval))) + (when-let ((raw (cdr (assq :noweb-wrap (nth 2 info))))) + (let (result) + (with-temp-buffer + (insert raw) + (goto-char (point-min)) + (while (< (point) (point-max)) + (unless (looking-at " *\"\\([^\"]+\\)\" *") + (looking-at " *\\([^ ]+\\)")) + (goto-char (match-end 0)) + (push (match-string 1) result))) + (reverse result)))) + ;;;###autoload (defun org-babel-goto-named-src-block (name) "Go to a source-code block with NAME." @@ -1974,14 +2001,18 @@ src block, then return nil." "source-block name: " all-block-names nil t (let* ((context (org-element-context)) (type (org-element-type context)) + (noweb-wrap (org-babel-get-noweb-wrap)) (noweb-ref (and (memq type '(inline-src-block src-block)) - (org-in-regexp (org-babel-noweb-wrap))))) + (org-in-regexp (org-babel-noweb-wrap + nil noweb-wrap))))) (cond (noweb-ref (buffer-substring - (+ (car noweb-ref) (length org-babel-noweb-wrap-start)) - (- (cdr noweb-ref) (length org-babel-noweb-wrap-end)))) + (+ (car noweb-ref) (length (or (car noweb-wrap) + org-babel-noweb-wrap-start))) + (- (cdr noweb-ref) (length (or (cadr noweb-wrap) + org-babel-noweb-wrap-end))))) ((memq type '(babel-call inline-babel-call)) ;#+CALL: (org-element-property :call context)) ((car (org-element-property :results context))) ;#+RESULTS: @@ -3125,7 +3156,8 @@ block but are passed literally to the \"example-block\"." (not (equal (cdr v) "no")))))) (noweb-re (format "\\(.*?\\)\\(%s\\)" (with-current-buffer parent-buffer - (org-babel-noweb-wrap))))) + (org-babel-noweb-wrap + nil (org-babel-get-noweb-wrap info)))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) @@ -3175,7 +3207,8 @@ block but are passed literally to the \"example-block\"." ((guard (or org-babel-noweb-error-all-langs (member lang org-babel-noweb-error-langs))) (error "Cannot resolve %s (see `org-babel-noweb-error-langs')" - (org-babel-noweb-wrap ,ref))) + (org-babel-noweb-wrap + ,ref (org-babel-get-noweb-wrap)))) (_ "")))) (replace-regexp-in-string noweb-re diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el index af726dc2c..1311813c5 100644 --- a/lisp/ob-exp.el +++ b/lisp/ob-exp.el @@ -414,7 +414,8 @@ replaced with its value." (setf (nth 1 info) (if (string= "strip-export" (cdr (assq :noweb (nth 2 info)))) (replace-regexp-in-string - (org-babel-noweb-wrap) "" (nth 1 info)) + (org-babel-noweb-wrap nil (org-babel-get-noweb-wrap info)) + "" (nth 1 info)) (if (org-babel-noweb-p (nth 2 info) :export) (org-babel-expand-noweb-references info org-babel-exp-reference-buffer) diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index 79fe6448b..17c4e7096 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -580,7 +580,11 @@ non-nil, return the full association list to be used by ;; Run the tangle-body-hook. (let ((body (if (org-babel-noweb-p params :tangle) (if (string= "strip-tangle" (cdr (assq :noweb (nth 2 info)))) - (replace-regexp-in-string (org-babel-noweb-wrap) "" (nth 1 info)) + (replace-regexp-in-string + (org-babel-noweb-wrap + nil (org-babel-get-noweb-wrap info)) + "" + (nth 1 info)) (org-babel-expand-noweb-references info)) (nth 1 info)))) (with-temp-buffer diff --git a/testing/examples/babel.org b/testing/examples/babel.org index d46afeb5e..680d4bf3e 100644 --- a/testing/examples/babel.org +++ b/testing/examples/babel.org @@ -346,6 +346,23 @@ Here is a call line with more than just the results exported. echo "1$i" #+END_SRC +* strip noweb references with alternative wrap + :PROPERTIES: + :ID: da9bcfdd-c1bd-47b4-b520-67974b9f9856 + :END: + +#+name: strip-export-2 +#+BEGIN_SRC sh :exports none + i="10" +#+END_SRC + +#+RESULTS: strip-export-2 + +#+BEGIN_SRC sh :noweb strip-export :noweb-wrap #[[ ]] :exports code :results silent + #[[strip-export-2]] + echo "1$i" +#+END_SRC + * use case of reading entry properties :PROPERTIES: :ID: cc5fbc20-bca5-437a-a7b8-2b4d7a03f820 diff --git a/testing/lisp/test-ob-exp.el b/testing/lisp/test-ob-exp.el index e6fbf14a1..8c4f4e9a1 100644 --- a/testing/lisp/test-ob-exp.el +++ b/testing/lisp/test-ob-exp.el @@ -394,6 +394,61 @@ be evaluated." (regexp-quote " :foo :bar \n") ascii)))))) +(ert-deftest ob-exp/noweb-wrap-header-arg () + (let ((org-export-use-babel t)) + (org-test-with-temp-text + " +#+Title: exporting from a temporary buffer + +#+name: foo +#+BEGIN_SRC emacs-lisp + :foo +#+END_SRC + +#+BEGIN_SRC emacs-lisp :noweb yes :noweb-wrap {{ }} :exports results + (list {{foo}}) +#+END_SRC +" + (let* ((ascii (org-export-as 'ascii))) + (should (string-match + (regexp-quote " :foo \n") + ascii)))))) + +(ert-deftest ob-exp/noweb-strip-export-with-wrap () + (org-test-at-id "da9bcfdd-c1bd-47b4-b520-67974b9f9856" + (org-narrow-to-subtree) + (org-babel-next-src-block 1) + (org-babel-execute-src-block) + (let ((result (org-test-with-expanded-babel-code (buffer-string)))) + (should-not (string-match (regexp-quote "#[[strip-export-2]]") result)) + (should-not (string-match (regexp-quote "i=\"10\"") result))))) + +(ert-deftest ob-exp/noweb-wrap-strip-export () + (let ((org-export-use-babel t)) + (org-test-with-temp-text + " +#+Title: exporting from a temporary buffer + +#+name: foo +#+BEGIN_SRC emacs-lisp + :foo +#+END_SRC + +#+name: bar +#+BEGIN_SRC emacs-lisp + :bar +#+END_SRC + +#+BEGIN_SRC emacs-lisp :noweb yes :noweb-wrap {{ }} :exports results + (list {{foo}} {{bar}}) +#+END_SRC +" + (let* ((ascii (org-export-as 'ascii))) + + (should (string-match + (regexp-quote ":foo :bar") + ascii)))))) + (ert-deftest ob-export/export-with-results-before-block () "Test export when results are inserted before source block." (let ((org-export-use-babel t)) diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el index c088af7c8..bd143be8b 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -988,6 +988,21 @@ x (search-forward "begin_src") (org-babel-expand-noweb-references))))) +(ert-deftest test-ob/noweb-wrap () + ;; Standard test. + (should + (string= + "bar" + (org-test-with-temp-text "#+begin_src sh :results output :tangle yes :noweb-wrap <<< >>> + <<>> +#+end_src + +#+name: foo +#+begin_src sh + bar +#+end_src" + (org-babel-expand-noweb-references))))) + (ert-deftest test-ob/splitting-variable-lists-in-references () (org-test-with-temp-text "" (should (= 1 (length (org-babel-ref-split-args -- 2.39.2 --=-=-=--