* noweb-start and noweb-end header args @ 2024-03-05 19:22 Amy Grinn 2024-03-05 22:41 ` termux ` (2 more replies) 0 siblings, 3 replies; 26+ messages in thread From: Amy Grinn @ 2024-03-05 19:22 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 716 bytes --] I would like to add support for setting 'org-babel-noweb-wrap-start and 'org-babel-noweb-wrap-end for each src block individually using the header args :noweb-start and :noweb-end: #+name: firewall-safe-mode #+begin_src sh echo "Firewall is now in safe mode." #+end_src #+name: firewall #+begin_src sh :noweb yes :noweb-start <<< :noweb-end >>> safe_mode () { echo "Error encountered, switching to safe mode." <<<firewall-safe-mode>>> exit 1 } setup-firewall || safe_mode #+end_src #+begin_src sh :noweb yes :noweb-start ":-) " :noweb-end " (-:" :tangle "test.sh" # Setup firewall :-) firewall (-: # Do other things #+end_src Here is a simple way to implement this feature. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: noweb extra header args --] [-- Type: text/x-patch, Size: 1480 bytes --] diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 4dcfbd3b0..0be19ff06 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -194,15 +194,17 @@ 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 info) "Return regexp matching a Noweb reference. Match any reference, or only those matching REGEXP, if non-nil. When matching, reference is stored in match group 1." - (concat (regexp-quote org-babel-noweb-wrap-start) + (concat (regexp-quote (or (cdr (assq :noweb-start (nth 2 info))) + org-babel-noweb-wrap-start)) (or regexp "\\([^ \t\n]\\(?:.*?[^ \t\n]\\)?\\)") - (regexp-quote org-babel-noweb-wrap-end))) + (regexp-quote (or (cdr (assq :noweb-end (nth 2 info))) + org-babel-noweb-wrap-end)))) (defvar org-babel-src-name-regexp "^[ \t]*#\\+name:[ \t]*" @@ -3116,7 +3118,7 @@ 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 info))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-05 19:22 noweb-start and noweb-end header args Amy Grinn @ 2024-03-05 22:41 ` termux 2024-03-06 11:21 ` Ihor Radchenko 2024-03-07 14:04 ` Ihor Radchenko 2 siblings, 0 replies; 26+ messages in thread From: termux @ 2024-03-05 22:41 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 790 bytes --] Amy Grinn <grinn.amy@gmail.com> writes: > I would like to add support for setting 'org-babel-noweb-wrap-start and > 'org-babel-noweb-wrap-end for each src block individually using the > header args :noweb-start and :noweb-end: Here's another possible syntax we could use: :noweb <context> [wrap-start] [wrap-end] #+name: message #+begin_src elisp "Firewall is now in safe mode." #+end_src #+name: firewall-safe-mode #+begin_src sh :noweb yes echo <<message>> #+end_src #+name: firewall #+begin_src sh :noweb yes <<< >>> safe_mode () { echo "Error encountered, switching to safe mode." <<<firewall-safe-mode>>> exit 1 } #+end_src #+begin_src sh :noweb yes ":-) " " (-:" :tangle "test.sh" # Setup firewall :-) firewall (-: # Do other things #+end_src [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Noweb header argument new syntax --] [-- Type: text/x-patch, Size: 1663 bytes --] diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 4dcfbd3b0..f60b4be12 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -194,15 +194,20 @@ 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 info) "Return regexp matching a Noweb reference. Match any reference, or only those matching REGEXP, if non-nil. 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))) + (let ((noweb (mapcar + (lambda (token) + (if (stringp token) token (symbol-name token))) + (org-babel-read + (format "'(%s)" (cdr (assq :noweb (nth 2 info)))))))) + (concat (regexp-quote (or (nth 1 noweb) org-babel-noweb-wrap-start)) + (or regexp "\\([^ \t\n]\\(?:.*?[^ \t\n]\\)?\\)") + (regexp-quote (or (nth 2 noweb) org-babel-noweb-wrap-end))))) (defvar org-babel-src-name-regexp "^[ \t]*#\\+name:[ \t]*" @@ -3116,7 +3121,7 @@ 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 info))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-05 19:22 noweb-start and noweb-end header args Amy Grinn 2024-03-05 22:41 ` termux @ 2024-03-06 11:21 ` Ihor Radchenko 2024-03-06 11:40 ` Amy Grinn 2024-03-07 14:04 ` Ihor Radchenko 2 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-03-06 11:21 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > I would like to add support for setting 'org-babel-noweb-wrap-start and > 'org-babel-noweb-wrap-end for each src block individually using the > header args :noweb-start and :noweb-end: > ... > #+name: firewall > #+begin_src sh :noweb yes :noweb-start <<< :noweb-end >>> May you please explain the use case when changing the default values is useful? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 11:21 ` Ihor Radchenko @ 2024-03-06 11:40 ` Amy Grinn 2024-03-06 11:47 ` Ihor Radchenko 2024-03-06 23:07 ` Amy Grinn 0 siblings, 2 replies; 26+ messages in thread From: Amy Grinn @ 2024-03-06 11:40 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >> I would like to add support for setting 'org-babel-noweb-wrap-start and >> 'org-babel-noweb-wrap-end for each src block individually using the >> header args :noweb-start and :noweb-end: >> ... >> #+name: firewall >> #+begin_src sh :noweb yes :noweb-start <<< :noweb-end >>> > > May you please explain the use case when changing the default values > is useful? Of course! Changing the default values can be useful to prevent syntax highlighting errors in a specific language. In the example I gave, <<< and >>> aren't recognized as the beginning of a heredoc in a shell script the way <<firewall-safe-mode>> would be. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 11:40 ` Amy Grinn @ 2024-03-06 11:47 ` Ihor Radchenko 2024-03-06 12:05 ` Amy Grinn 2024-03-06 23:07 ` Amy Grinn 1 sibling, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-03-06 11:47 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >>> #+name: firewall >>> #+begin_src sh :noweb yes :noweb-start <<< :noweb-end >>> >> >> May you please explain the use case when changing the default values >> is useful? > > Of course! Changing the default values can be useful to prevent syntax > highlighting errors in a specific language. In the example I gave, <<< > and >>> aren't recognized as the beginning of a heredoc in a shell > script the way <<firewall-safe-mode>> would be. This sounds like XY problem then. If the real problem you want to solve is fontification, we may instead adjust Org mode fontification of source blocks to exclude noweb references. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 11:47 ` Ihor Radchenko @ 2024-03-06 12:05 ` Amy Grinn 2024-03-06 13:33 ` Ihor Radchenko 0 siblings, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-03-06 12:05 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >>>> #+name: firewall >>>> #+begin_src sh :noweb yes :noweb-start <<< :noweb-end >>> >>> >>> May you please explain the use case when changing the default values >>> is useful? >> >> Of course! Changing the default values can be useful to prevent syntax >> highlighting errors in a specific language. In the example I gave, <<< >> and >>> aren't recognized as the beginning of a heredoc in a shell >> script the way <<firewall-safe-mode>> would be. > > This sounds like XY problem then. > If the real problem you want to solve is fontification, we may instead > adjust Org mode fontification of source blocks to exclude noweb > references. I see a problem with multiple possible solutions, some more involved than others. The org-babel-noweb-wrap-* variables are already customizeable and, in researching a solution to this problem, I have found users who set these variables on a file or directory-local level already. How much does org mode modify the fontification for an indirect buffer? Without having looked into it, I assume not much or at all. I think that approach could be more complex, especially when dealing with a theoretically infinite number of major modes. Both solutions could be implemented at the same time. We could build on the existing functionality of the wrap-end and wrap-start variables while also looking at ways to modify the syntax highlighting without user intervention. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 12:05 ` Amy Grinn @ 2024-03-06 13:33 ` Ihor Radchenko 2024-03-06 16:04 ` Amy Grinn 0 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-03-06 13:33 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >> This sounds like XY problem then. >> If the real problem you want to solve is fontification, we may instead >> adjust Org mode fontification of source blocks to exclude noweb >> references. > > I see a problem with multiple possible solutions, some more involved > than others. The org-babel-noweb-wrap-* variables are already > customizeable and, in researching a solution to this problem, I have > found users who set these variables on a file or directory-local level > already. Yup. And most of these customizations are aiming to solve the fontification problem. If we did not have the problem to start with, re-defining the noweb wrap syntax would be unnecessary in many cases. > How much does org mode modify the fontification for an indirect buffer? > Without having looked into it, I assume not much or at all. > ... I think > that approach could be more complex, especially when dealing with a > theoretically infinite number of major modes. Org mode does not _currently_ modify the code. But that's actually wrong - things like escaped ,* or indentation sometimes also stay on the way and produce incorrect fontification. So, rewriting the fontification of src blocks to cleanup the code before fontification is long due. noweb references is just another manifestation of this problem. > Both solutions could be implemented at the same time. We could build on > the existing functionality of the wrap-end and wrap-start variables > while also looking at ways to modify the syntax highlighting without > user intervention. I am not in favor of adding features that aim to serve as workarounds to Org mode. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 13:33 ` Ihor Radchenko @ 2024-03-06 16:04 ` Amy Grinn 2024-03-07 13:50 ` Ihor Radchenko 0 siblings, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-03-06 16:04 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >> How much does org mode modify the fontification for an indirect buffer? >> Without having looked into it, I assume not much or at all. >> ... I think >> that approach could be more complex, especially when dealing with a >> theoretically infinite number of major modes. > > Org mode does not _currently_ modify the code. But that's actually wrong > - things like escaped ,* or indentation sometimes also stay on the way > and produce incorrect fontification. So, rewriting the fontification of > src blocks to cleanup the code before fontification is long due. > noweb references is just another manifestation of this problem. I think we're talking past each other a little. I'm not talking about changing the text content of a src block, I'm talking about modifying the syntax table of a major mode such as sh-mode to ignore or handle <<noweb>> syntax in an "edit-special" buffer. That was my interpretation of your suggestion of using fontification to solve this issue. And if that's the case, I foresee a lot of edge cases for modifying the display of major modes. >> Both solutions could be implemented at the same time. We could build on >> the existing functionality of the wrap-end and wrap-start variables >> while also looking at ways to modify the syntax highlighting without >> user intervention. > > I am not in favor of adding features that aim to serve as workarounds to > Org mode. This discussion is not about whether to allow users to modify noweb syntax. That feature is already a part of Org, well documented, and utilized. The feature request I'm making is to allow that modification to be done on a per-block level. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 16:04 ` Amy Grinn @ 2024-03-07 13:50 ` Ihor Radchenko 0 siblings, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-03-07 13:50 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >> Org mode does not _currently_ modify the code. But that's actually wrong >> - things like escaped ,* or indentation sometimes also stay on the way >> and produce incorrect fontification. So, rewriting the fontification of >> src blocks to cleanup the code before fontification is long due. >> noweb references is just another manifestation of this problem. > > I think we're talking past each other a little. I'm not talking about > changing the text content of a src block, I'm talking about modifying > the syntax table of a major mode such as sh-mode to ignore or handle > <<noweb>> syntax in an "edit-special" buffer. That was my > interpretation of your suggestion of using fontification to solve this > issue. And if that's the case, I foresee a lot of edge cases for > modifying the display of major modes. That's not what I had in mind. I thought of resolving/replacing noweb references before fontifying the code. That way, the major mode for src block will simply not see <<noweb>> text and will not be confused. >> I am not in favor of adding features that aim to serve as workarounds to >> Org mode. > > This discussion is not about whether to allow users to modify noweb > syntax. That feature is already a part of Org, well documented, and > utilized. The feature request I'm making is to allow that modification > to be done on a per-block level. Sure, but I wanted to hear why such feature is useful in practice. Your example with fontification is not something I consider as a good justification for adding a new feature. You another email provides a better justification though. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 11:40 ` Amy Grinn 2024-03-06 11:47 ` Ihor Radchenko @ 2024-03-06 23:07 ` Amy Grinn 2024-03-07 13:58 ` Ihor Radchenko 1 sibling, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-03-06 23:07 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > Ihor Radchenko <yantar92@posteo.net> writes: > >> Amy Grinn <grinn.amy@gmail.com> writes: >> >>> I would like to add support for setting 'org-babel-noweb-wrap-start and >>> 'org-babel-noweb-wrap-end for each src block individually >> >> May you please explain the use case when changing the default values >> is useful? > > Of course! Changing the default values can be useful to prevent syntax > highlighting errors in a specific language. In the example I gave, <<< > and >>> aren't recognized as the beginning of a heredoc in a shell > script the way <<firewall-safe-mode>> would be. To expand on this, some major modes can fundamentally conflict with the default noweb syntax. Here is a valid shell script *and* a valid noweb reference to a block named EOF: cat <<EOF>> file.txt Hello EOF I hope this helps explain why the wrap-start and wrap-end options were necessary to include more than a decade ago. In terms of actually using them, it's a bit cumbersome, especially in Org mode buffers that use multiple languages. The second diff I sent (under the termux handle, accidentally) is my preferred solution (:noweb yes <<< >>>). This would avoid the need for new header arguments to be introduced while maintaining backwards compatibility. It also feels natural to specify the two options together: I can't think of a good reason to only need to specify the wrap-end option. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-06 23:07 ` Amy Grinn @ 2024-03-07 13:58 ` Ihor Radchenko 2024-03-07 14:33 ` Amy Grinn 0 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-03-07 13:58 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > To expand on this, some major modes can fundamentally conflict with the > default noweb syntax. Here is a valid shell script *and* a valid noweb > reference to a block named EOF: > > cat <<EOF>> file.txt > Hello > EOF > > I hope this helps explain why the wrap-start and wrap-end options were > necessary to include more than a decade ago. In terms of actually using > them, it's a bit cumbersome, especially in Org mode buffers that use > multiple languages. This makes sense. I agree that setting noweb reference syntax per-language is useful in some cases. > The second diff I sent (under the termux handle, accidentally) is my > preferred solution (:noweb yes <<< >>>). This would avoid the need for > new header arguments to be introduced while maintaining backwards > compatibility. It also feels natural to specify the two options > together: I can't think of a good reason to only need to specify the > wrap-end option. :noweb yes <<< >>> is actually backwards-incompatible. Consider third-party code that makes assumptions about possible values of :noweb header argument. If third-party code does a check like (equal noweb-value "yes"), the new syntax can break such code. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-07 13:58 ` Ihor Radchenko @ 2024-03-07 14:33 ` Amy Grinn 2024-03-07 14:49 ` Ihor Radchenko 0 siblings, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-03-07 14:33 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > :noweb yes <<< >>> is actually backwards-incompatible. Consider > third-party code that makes assumptions about possible values of > :noweb > header argument. If third-party code does a check like > (equal noweb-value "yes"), the new syntax can break such code. I kinda disagree with your reasoning but I agree with your conclusion. I think it would be strange for third party or user configuration to parse the value of a noweb header argument directly. Org provides a lublic api for this which should be backwards compatible: (org-babel-noweb-p (nth 2 (org-babel-get-src-block-info t)) :tangle) However, other parsers besides Emacs exist for Org mode and they may directly compare the entire noweb argument. The middle way is to create just one new header arg: :noweb-wrap <start> [end] ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-07 14:33 ` Amy Grinn @ 2024-03-07 14:49 ` Ihor Radchenko 0 siblings, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-03-07 14:49 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > I kinda disagree with your reasoning but I agree with your conclusion. > I think it would be strange for third party or user configuration to > parse the value of a noweb header argument directly. Org provides a > lublic api for this which should be backwards compatible: > > (org-babel-noweb-p (nth 2 (org-babel-get-src-block-info t)) :tangle) Yeah, but this API is not uniform. Most other header arguments must be retrieved using `assq'. So, it is very common to use `assq' for everything, even if there is a specific API. (Ideally, we need to implement a uniform API to retrieve header argument values) > The middle way is to create just one new header arg: > > :noweb-wrap <start> [end] Maybe <end> should be mandatory. Otherwise, LGTM. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-05 19:22 noweb-start and noweb-end header args Amy Grinn 2024-03-05 22:41 ` termux 2024-03-06 11:21 ` Ihor Radchenko @ 2024-03-07 14:04 ` Ihor Radchenko 2024-03-07 15:06 ` Amy Grinn 2024-04-08 14:04 ` [FR] :noweb-wrap header arg Amy Grinn 2 siblings, 2 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-03-07 14:04 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > Here is a simple way to implement this feature. > ... > -(defun org-babel-noweb-wrap (&optional regexp) > +(defun org-babel-noweb-wrap (&optional regexp info) > "Return regexp matching a Noweb reference. > > Match any reference, or only those matching REGEXP, if non-nil. > > When matching, reference is stored in match group 1." INFO argument needs to be documented. > - (org-babel-noweb-wrap))))) > + (org-babel-noweb-wrap nil info))))) Please, also update all other cases when `org-babel-noweb-wrap' is called. Also, `org-babel-goto-named-src-block' uses org-babel-noweb-wrap-start/end directly. It should be adjusted. Since you are adding a new feature, it should have (1) test coverage; (2) be documented in the manual; (3) be announced in etc/ORG-NEWS. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: noweb-start and noweb-end header args 2024-03-07 14:04 ` Ihor Radchenko @ 2024-03-07 15:06 ` Amy Grinn 2024-04-08 14:04 ` [FR] :noweb-wrap header arg Amy Grinn 1 sibling, 0 replies; 26+ messages in thread From: Amy Grinn @ 2024-03-07 15:06 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >> Here is a simple way to implement this feature. > > Since you are adding a new feature, it should have (1) test coverage; > (2) be documented in the manual; (3) be announced in etc/ORG-NEWS. Thank you for the tips, will do! ^ permalink raw reply [flat|nested] 26+ messages in thread
* [FR] :noweb-wrap header arg 2024-03-07 14:04 ` Ihor Radchenko 2024-03-07 15:06 ` Amy Grinn @ 2024-04-08 14:04 ` Amy Grinn 2024-04-11 14:03 ` Ihor Radchenko 1 sibling, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-04-08 14:04 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 1303 bytes --] 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 <<< >>> <<<foo>>> #+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 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: noweb-wrap header arg --] [-- Type: text/x-patch, Size: 10701 bytes --] From 1dc8aebcc45447d3b5b38ea3c7700ae2b2686c9d Mon Sep 17 00:00:00 2001 From: Amy Grinn <grinn.amy@gmail.com> 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 <<<message>>> +: #+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 <<< >>> + <<<foo>>> +#+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 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-04-08 14:04 ` [FR] :noweb-wrap header arg Amy Grinn @ 2024-04-11 14:03 ` Ihor Radchenko 2024-04-11 18:46 ` Amy Grinn 2024-05-11 16:01 ` Amy Grinn 0 siblings, 2 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-04-11 14:03 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: > 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. +1 You may even use obsolete alias (add it to lisp/org-compat.el) > 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. > """ Makes sense. Ideally, this function should try to follow the link and lookup code block headers, but it is already short of doing this. Improving `org-babel-tangle-clean' is out of scope of your patch. > +(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 Please, avoid creating throwaway buffers and work with strings instead. Creating buffers (even temporary buffers) may be costly for some users who heavily customized buffer hooks. > + (insert raw) > + (goto-char (point-min)) > + (while (< (point) (point-max)) > + (unless (looking-at " *\"\\([^\"]+\\)\" *") > + (looking-at " *\\([^ ]+\\)")) May you please explain the rationale behind this regexp? AFAIU, it implies that you want to allow whitespace characters inside :noweb-wrap boundaries. But I do not think that we need to complicate things so much. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-04-11 14:03 ` Ihor Radchenko @ 2024-04-11 18:46 ` Amy Grinn 2024-04-13 13:17 ` Ihor Radchenko 2024-05-11 16:01 ` Amy Grinn 1 sibling, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-04-11 18:46 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >> + (insert raw) >> + (goto-char (point-min)) >> + (while (< (point) (point-max)) >> + (unless (looking-at " *\"\\([^\"]+\\)\" *") >> + (looking-at " *\\([^ ]+\\)")) > > May you please explain the rationale behind this regexp? AFAIU, it > implies that you want to allow whitespace characters inside :noweb-wrap > boundaries. But I do not think that we need to complicate things so much. That is exactly what I was going for. I thought about the ways this could be used and the most general-purpose, non-syntax-breaking, easily-recognizable way I could think of was to use the language's line-comment construct followed by the standard << >> characters. # <<foo>> ;; <<bar>> // <<baz>> I can see how it might be harder to maintain to allow whitespace in the noweb-wrap header arg. I could create a separate org-parse-arg-list function to ease that burden somewhat. My opinion is that having the option to use the examples above is preferable to using non-standard wrappers, from a third-person point-of-view. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-04-11 18:46 ` Amy Grinn @ 2024-04-13 13:17 ` Ihor Radchenko 0 siblings, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-04-13 13:17 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >>> + (while (< (point) (point-max)) >>> + (unless (looking-at " *\"\\([^\"]+\\)\" *") >>> + (looking-at " *\\([^ ]+\\)")) >> >> May you please explain the rationale behind this regexp? AFAIU, it >> implies that you want to allow whitespace characters inside :noweb-wrap >> boundaries. But I do not think that we need to complicate things so much. > > That is exactly what I was going for. I thought about the ways this > could be used and the most general-purpose, non-syntax-breaking, > easily-recognizable way I could think of was to use the language's > line-comment construct followed by the standard << >> characters. > > # <<foo>> > ;; <<bar>> > // <<baz>> > > I can see how it might be harder to maintain to allow whitespace in the > noweb-wrap header arg. I could create a separate org-parse-arg-list > function to ease that burden somewhat. My opinion is that having the > option to use the examples above is preferable to using non-standard > wrappers, from a third-person point-of-view. Makes sense. Also, see a similar idea being discussed in https://list.orgmode.org/orgmode/87o7jlzxgn.fsf@localhost/ I recommend the following: If the value starts from ", use Elisp's `read': |"# <<" ">>" (read (current-buffer)) ; => "# <<" otherwise, consider read until the first whitespace. |#<<; >>; (re-search-forward (rx (1+ (not whitespace)))) #<<;| However, there may be edge cases like "<< >>" "<< >> << << >> << "asd" >> -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-04-11 14:03 ` Ihor Radchenko 2024-04-11 18:46 ` Amy Grinn @ 2024-05-11 16:01 ` Amy Grinn 2024-05-12 10:48 ` Ihor Radchenko 1 sibling, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-05-11 16:01 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 454 bytes --] Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >> 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. > > +1 > You may even use obsolete alias (add it to lisp/org-compat.el) Here's a patch to rename org-babel-noweb-wrap to org-babel-noweb-make-regexp. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Rename org-babel-noweb-wrap to org-babel-noweb-make-regexp --] [-- Type: text/x-patch, Size: 5677 bytes --] From b318fef6af8ae47b7e6d0371ccc87a01ed1a7755 Mon Sep 17 00:00:00 2001 From: Amy Grinn <grinn.amy@gmail.com> Date: Wed, 17 Apr 2024 16:01:40 -0400 Subject: [PATCH] lisp/ob-core.el: (org-babel-noweb-wrap): renamed to org-babel-noweb-make-regexp * etc/ORG-NEWS (~org-babel-noweb-wrap~ is now ~org-babel-noweb-make-regexp~): Announce the change. * lisp/org-compat.el: Declare org-babel-noweb-wrap to be an obselete function alias for org-babel-noweb-make-regexp. * lisp/ob-core.el (org-babel-noweb-make-regexp): Rename the function. (org-babel-goto-named-src-block): (org-babel-expand-noweb-references): * lisp/ob-exp.el (org-babel-exp-code): * lisp/ob-tangle.el (org-babel-tangle-clean): (org-babel-tangle-single-block): Use the new function name. --- etc/ORG-NEWS | 6 ++++++ lisp/ob-core.el | 8 ++++---- lisp/ob-exp.el | 2 +- lisp/ob-tangle.el | 5 +++-- lisp/org-compat.el | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 978882a7a..97e2f2e3f 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -1563,6 +1563,12 @@ optional argument =NEW-HEADING-CONTAINER= specifies where in the buffer it will be added. If not specified, new headings are created at level 1 at the end of the accessible part of the buffer, as before. +** Removed or renamed functions and variables +*** ~org-babel-noweb-wrap~ is now ~org-babel-noweb-make-regexp~ + +This is more in line with other functions that return a regular +expression. + ** Miscellaneous *** =org-crypt.el= now applies initial visibility settings to decrypted entries diff --git a/lisp/ob-core.el b/lisp/ob-core.el index c5dd20b0e..1518d7726 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -194,7 +194,7 @@ 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-make-regexp (&optional regexp) "Return regexp matching a Noweb reference. Match any reference, or only those matching REGEXP, if non-nil. @@ -1976,7 +1976,7 @@ src block, then return nil." (type (org-element-type context)) (noweb-ref (and (memq type '(inline-src-block src-block)) - (org-in-regexp (org-babel-noweb-wrap))))) + (org-in-regexp (org-babel-noweb-make-regexp))))) (cond (noweb-ref (buffer-substring @@ -3125,7 +3125,7 @@ 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-make-regexp))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) @@ -3175,7 +3175,7 @@ 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-make-regexp ,ref))) (_ "")))) (replace-regexp-in-string noweb-re diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el index 80eaeeb27..a61b26ed5 100644 --- a/lisp/ob-exp.el +++ b/lisp/ob-exp.el @@ -419,7 +419,7 @@ 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-make-regexp) "" (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..4427250ae 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -412,7 +412,7 @@ references." (interactive) (goto-char (point-min)) (while (or (re-search-forward "\\[\\[file:.*\\]\\[.*\\]\\]" nil t) - (re-search-forward (org-babel-noweb-wrap) nil t)) + (re-search-forward (org-babel-noweb-make-regexp) nil t)) (delete-region (save-excursion (forward-line) (point)) (save-excursion (end-of-line 1) (forward-char 1) (point))))) @@ -580,7 +580,8 @@ 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-make-regexp) + "" (nth 1 info)) (org-babel-expand-noweb-references info)) (nth 1 info)))) (with-temp-buffer diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 92cad3d6e..ce46fd399 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -433,7 +433,7 @@ This is a floating point number if the size is too large for an integer." (define-obsolete-function-alias 'org-show-context 'org-fold-show-context "9.6") (define-obsolete-function-alias 'org-show-entry 'org-fold-show-entry "9.6") (define-obsolete-function-alias 'org-show-children 'org-fold-show-children "9.6") - +(define-obsolete-function-alias 'org-babel-noweb-wrap 'org-babel-noweb-make-regexp "9.7") (defmacro org-re (s) "Replace posix classes in regular expression S." -- 2.39.2 [-- Attachment #3: Type: text/plain, Size: 15 bytes --] -- Best, Amy ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-05-11 16:01 ` Amy Grinn @ 2024-05-12 10:48 ` Ihor Radchenko 2024-05-22 23:17 ` Amy Grinn 0 siblings, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-05-12 10:48 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >> +1 >> You may even use obsolete alias (add it to lisp/org-compat.el) > > Here's a patch to rename org-babel-noweb-wrap to > org-babel-noweb-make-regexp. Thanks! News entry is not necessary here - we are just renaming a function. Otherwise, the patch looks good. I am not yet merging it though - let's have all the patches you plan for the new noweb-wrap argument first and then apply them together. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-05-12 10:48 ` Ihor Radchenko @ 2024-05-22 23:17 ` Amy Grinn 2024-05-23 11:27 ` Ihor Radchenko 0 siblings, 1 reply; 26+ messages in thread From: Amy Grinn @ 2024-05-22 23:17 UTC (permalink / raw) To: Ihor Radchenko; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 2803 bytes --] Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >>> +1 >>> You may even use obsolete alias (add it to lisp/org-compat.el) >> >> Here's a patch to rename org-babel-noweb-wrap to >> org-babel-noweb-make-regexp. > > Thanks! > News entry is not necessary here - we are just renaming a function. > Otherwise, the patch looks good. > I am not yet merging it though - let's have all the patches you plan for > the new noweb-wrap argument first and then apply them together. Got it, not a problem! I've attached both patches here. Regarding the other conversation, >>>> + (while (< (point) (point-max)) >>>> + (unless (looking-at " *\"\\([^\"]+\\)\" *") >>>> + (looking-at " *\\([^ ]+\\)")) >>> >>> May you please explain the rationale behind this regexp? AFAIU, it >>> implies that you want to allow whitespace characters inside :noweb-wrap >>> boundaries. But I do not think that we need to complicate things so much. >> >> That is exactly what I was going for. I thought about the ways this >> could be used and the most general-purpose, non-syntax-breaking, >> easily-recognizable way I could think of was to use the language's >> line-comment construct followed by the standard << >> characters. >> >> # <<foo>> >> ;; <<bar>> >> // <<baz>> >> >> I can see how it might be harder to maintain to allow whitespace in the >> noweb-wrap header arg. I could create a separate org-parse-arg-list >> function to ease that burden somewhat. My opinion is that having the >> option to use the examples above is preferable to using non-standard >> wrappers, from a third-person point-of-view. > > Makes sense. Also, see a similar idea being discussed in > https://list.orgmode.org/orgmode/87o7jlzxgn.fsf@localhost/ > > I recommend the following: > > If the value starts from ", use Elisp's `read': > |"# <<" ">>" > (read (current-buffer)) ; => "# <<" > otherwise, consider read until the first whitespace. > |#<<; >>; > (re-search-forward (rx (1+ (not whitespace)))) > #<<;| > > However, there may be edge cases like > > "<< >>" > "<< >> > << << >> > << "asd" >> I didn't implement this recommendation yet; I still think the regex is a more clear way of putting it, even without using a temporary buffer: ;; If a pair of " is found separated by one or more ;; characters, capture those characters as a group (unless (eq i (string-match (rx (* space) ?\" (group (+ (not ?\"))) ?\" (* space)) raw i)) ;; Otherwise, capture the next non-whitespace group of ;; characters (string-match (rx (* space) (group (* (not space))) (* space)) raw i)) Let me know what you think! [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: rename to org-babel-noweb-make-regexp --] [-- Type: text/x-patch, Size: 4910 bytes --] From 9442c029a7b2f1ec061e42a047b3d1bff88441d8 Mon Sep 17 00:00:00 2001 From: Amy Grinn <grinn.amy@gmail.com> Date: Wed, 17 Apr 2024 16:01:40 -0400 Subject: [PATCH 1/2] lisp/ob-core.el: (org-babel-noweb-wrap): renamed to org-babel-noweb-make-regexp * lisp/org-compat.el: Declare org-babel-noweb-wrap to be an obselete function alias for org-babel-noweb-make-regexp. * lisp/ob-core.el (org-babel-noweb-make-regexp): Rename the function. (org-babel-goto-named-src-block): (org-babel-expand-noweb-references): * lisp/ob-exp.el (org-babel-exp-code): * lisp/ob-tangle.el (org-babel-tangle-clean): (org-babel-tangle-single-block): Use the new function name. --- lisp/ob-core.el | 8 ++++---- lisp/ob-exp.el | 2 +- lisp/ob-tangle.el | 5 +++-- lisp/org-compat.el | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index c5dd20b0e..1518d7726 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -194,7 +194,7 @@ 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-make-regexp (&optional regexp) "Return regexp matching a Noweb reference. Match any reference, or only those matching REGEXP, if non-nil. @@ -1976,7 +1976,7 @@ src block, then return nil." (type (org-element-type context)) (noweb-ref (and (memq type '(inline-src-block src-block)) - (org-in-regexp (org-babel-noweb-wrap))))) + (org-in-regexp (org-babel-noweb-make-regexp))))) (cond (noweb-ref (buffer-substring @@ -3125,7 +3125,7 @@ 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-make-regexp))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) @@ -3175,7 +3175,7 @@ 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-make-regexp ,ref))) (_ "")))) (replace-regexp-in-string noweb-re diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el index 34f12fdcc..33de7a4aa 100644 --- a/lisp/ob-exp.el +++ b/lisp/ob-exp.el @@ -418,7 +418,7 @@ 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-make-regexp) "" (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..4427250ae 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -412,7 +412,7 @@ references." (interactive) (goto-char (point-min)) (while (or (re-search-forward "\\[\\[file:.*\\]\\[.*\\]\\]" nil t) - (re-search-forward (org-babel-noweb-wrap) nil t)) + (re-search-forward (org-babel-noweb-make-regexp) nil t)) (delete-region (save-excursion (forward-line) (point)) (save-excursion (end-of-line 1) (forward-char 1) (point))))) @@ -580,7 +580,8 @@ 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-make-regexp) + "" (nth 1 info)) (org-babel-expand-noweb-references info)) (nth 1 info)))) (with-temp-buffer diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 92cad3d6e..ce46fd399 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -433,7 +433,7 @@ This is a floating point number if the size is too large for an integer." (define-obsolete-function-alias 'org-show-context 'org-fold-show-context "9.6") (define-obsolete-function-alias 'org-show-entry 'org-fold-show-entry "9.6") (define-obsolete-function-alias 'org-show-children 'org-fold-show-children "9.6") - +(define-obsolete-function-alias 'org-babel-noweb-wrap 'org-babel-noweb-make-regexp "9.7") (defmacro org-re (s) "Replace posix classes in regular expression S." -- 2.39.2 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: new header argument :noweb-wrap --] [-- Type: text/x-patch, Size: 13399 bytes --] From aad9b3926c711dfed411e2f439ae8b0fe3db7d10 Mon Sep 17 00:00:00 2001 From: Amy Grinn <grinn.amy@gmail.com> Date: Wed, 17 Apr 2024 16:56:37 -0400 Subject: [PATCH 2/2] org-babel: New header argument :noweb-wrap * lisp/ob-core.el (org-babel-get-noweb-wrap): New API function that parses the :noweb-wrap parameter of a babel src block. (org-babel-noweb-make-regexp): Add a new optional parameter 'wrap' to control how noweb references are wrapped. (org-babel-goto-named-src-block): (org-babel-expand-noweb-references): * lisp/ob-exp.el (org-babel-exp-code): * lisp/ob-tangle.el (org-babel-tangle-single-block): Use the new org-babel-get-noweb-wrap function as the new optional parameter to org-babel-noweb-make-regexp. * lisp/ob-tangle.el (org-babel-tangle-clean): Add an additional warning about not being able to resolve noweb references if :noweb wrap was specified. * etc/ORG-NEWS (New =:noweb-wrap= babel header argument): Describe new argument. * testing/examples/babel.org: * testing/lisp/test-ob-exp.el: * testing/lisp/test-ob.el: Add tests which use alternate wrapping syntax for noweb references. --- etc/ORG-NEWS | 14 +++++++++ lisp/ob-core.el | 57 +++++++++++++++++++++++++++++++------ lisp/ob-exp.el | 3 +- lisp/ob-tangle.el | 12 +++++--- testing/examples/babel.org | 17 +++++++++++ testing/lisp/test-ob-exp.el | 55 +++++++++++++++++++++++++++++++++++ testing/lisp/test-ob.el | 32 +++++++++++++++++++++ 7 files changed, 176 insertions(+), 14 deletions(-) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 585b2b262..e1fb95744 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -589,6 +589,20 @@ Org mode provides 3 possible values for ~org-sort-function~: and on MacOS. 3. Custom function, if the above does not fit the needs. +*** 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 <<<message>>> +: #+end_src + *** =ob-latex= now uses a new option ~org-babel-latex-process-alist~ to generate png output Previously, =ob-latex= used ~org-preview-latex-default-process~ from diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 1518d7726..4f286c64c 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-make-regexp (&optional regexp) +(defun org-babel-noweb-make-regexp (&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,33 @@ 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)))) + (len (length raw))) + (let ((i 0) result) + (while (< i len) + ;; If a pair of " is found separated by one or more + ;; characters, capture those characters as a group + (unless (eq i (string-match (rx (* space) ?\" + (group (+ (not ?\"))) + ?\" (* space)) + raw i)) + ;; Otherwise, capture the next non-whitespace group of + ;; characters + (string-match (rx (* space) (group (* (not space))) (* space)) + raw i)) + (setq i (match-end 0)) + (push (match-string 1 raw) result)) + (reverse result)))) + ;;;###autoload (defun org-babel-goto-named-src-block (name) "Go to a source-code block with NAME." @@ -1974,14 +2007,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-make-regexp))))) + (org-in-regexp (org-babel-noweb-make-regexp + 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 +3162,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-make-regexp))))) + (org-babel-noweb-make-regexp + nil (org-babel-get-noweb-wrap info)))))) (unless (equal (cons parent-buffer (with-current-buffer parent-buffer (buffer-chars-modified-tick))) @@ -3175,7 +3213,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-make-regexp ,ref))) + (org-babel-noweb-make-regexp + ,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 33de7a4aa..14a32a8e6 100644 --- a/lisp/ob-exp.el +++ b/lisp/ob-exp.el @@ -418,7 +418,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-make-regexp) "" (nth 1 info)) + (org-babel-noweb-make-regexp 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 4427250ae..5fcb40443 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -406,9 +406,11 @@ Did you give the decimal value %1$d by mistake?" mode))) "Remove comments inserted by `org-babel-tangle'. Call this function inside of a source-code file generated by `org-babel-tangle' to remove all comments inserted automatically -by `org-babel-tangle'. Warning, this comment removes any lines +by `org-babel-tangle'. Warning, this command removes any lines containing constructs which resemble Org file links or noweb -references." +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." (interactive) (goto-char (point-min)) (while (or (re-search-forward "\\[\\[file:.*\\]\\[.*\\]\\]" nil t) @@ -580,8 +582,10 @@ 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-make-regexp) - "" (nth 1 info)) + (replace-regexp-in-string + (org-babel-noweb-make-regexp + 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 d029dadfb..abfda4368 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 544e68267..b0051d2a2 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -988,6 +988,38 @@ 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 <<< >>> + <<<foo>>> +#+end_src + +#+name: foo +#+begin_src sh + bar +#+end_src" + (org-babel-expand-noweb-references))))) + +(ert-deftest test-ob/get-noweb-wrap () + (should (equal '("<< >>") + (org-babel-get-noweb-wrap + '(nil nil ((:noweb-wrap . "\"<< >>\"")))))) + (should (equal '("\"<<" ">>") + (org-babel-get-noweb-wrap + '(nil nil ((:noweb-wrap . "\"<< >>")))))) + (should (equal '("<<" "<<" ">>") + (org-babel-get-noweb-wrap + '(nil nil ((:noweb-wrap . "<< << >>")))))) + (should (equal '("<<" "asd" ">>") + (org-babel-get-noweb-wrap + '(nil nil ((:noweb-wrap . "<< \"asd\" >>")))))) + (should (equal '("\"\"\"" ">>>") + (org-babel-get-noweb-wrap + '(nil nil ((:noweb-wrap . "\"\"\" >>>"))))))) + (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 [-- Attachment #4: Type: text/plain, Size: 14 bytes --] -- Best, Amy ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-05-22 23:17 ` Amy Grinn @ 2024-05-23 11:27 ` Ihor Radchenko 2024-07-01 9:56 ` Ihor Radchenko 2024-12-08 10:20 ` Ihor Radchenko 0 siblings, 2 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-05-23 11:27 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Amy Grinn <grinn.amy@gmail.com> writes: >> I recommend the following: >> >> If the value starts from ", use Elisp's `read': >> |"# <<" ">>" >> (read (current-buffer)) ; => "# <<" >> otherwise, consider read until the first whitespace. >> |#<<; >>; >> (re-search-forward (rx (1+ (not whitespace)))) >> #<<;| >> >> However, there may be edge cases like >> >> "<< >>" >> "<< >> >> << << >> >> << "asd" >> > > I didn't implement this recommendation yet; I still think the regex is a > more clear way of putting it, even without using a temporary buffer: > > ;; If a pair of " is found separated by one or more > ;; characters, capture those characters as a group > (unless (eq i (string-match (rx (* space) ?\" > (group (+ (not ?\"))) > ?\" (* space)) > raw i)) > ;; Otherwise, capture the next non-whitespace group of > ;; characters > (string-match (rx (* space) (group (* (not space))) (* space)) > raw i)) > > Let me know what you think! Consider cases like "< \"" "\" >" or "< >" -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-05-23 11:27 ` Ihor Radchenko @ 2024-07-01 9:56 ` Ihor Radchenko 2024-12-08 10:20 ` Ihor Radchenko 1 sibling, 0 replies; 26+ messages in thread From: Ihor Radchenko @ 2024-07-01 9:56 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: >> Let me know what you think! > > Consider cases like > ... It has been over a month since the last message in this thread. Amy, may I know if you are still working on the patch? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-05-23 11:27 ` Ihor Radchenko 2024-07-01 9:56 ` Ihor Radchenko @ 2024-12-08 10:20 ` Ihor Radchenko 2024-12-10 15:28 ` Suhail Singh 1 sibling, 1 reply; 26+ messages in thread From: Ihor Radchenko @ 2024-12-08 10:20 UTC (permalink / raw) To: Amy Grinn; +Cc: emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Amy Grinn <grinn.amy@gmail.com> writes: > >>> I recommend the following: >>> >>> If the value starts from ", use Elisp's `read': >>> |"# <<" ">>" >>> (read (current-buffer)) ; => "# <<" >>> otherwise, consider read until the first whitespace. >>> |#<<; >>; >>> (re-search-forward (rx (1+ (not whitespace)))) >>> #<<;| >>> >>> However, there may be edge cases like > ... Thinking about this more in the context of the past meetup discussion, maybe we can just go with two header arguments? :noweb-start :noweb-end? Or, alternatively, we can use a single string and a placeholder for the noweb reference name. Something like :noweb-wrap "# <<%s>>" -- Ihor Radchenko // yantar92, Org mode maintainer, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [FR] :noweb-wrap header arg 2024-12-08 10:20 ` Ihor Radchenko @ 2024-12-10 15:28 ` Suhail Singh 0 siblings, 0 replies; 26+ messages in thread From: Suhail Singh @ 2024-12-10 15:28 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Amy Grinn, emacs-orgmode Ihor Radchenko <yantar92@posteo.net> writes: > Thinking about this more in the context of the past meetup discussion, > maybe we can just go with two header arguments? :noweb-start :noweb-end? > Or, alternatively, we can use a single string and a placeholder for the > noweb reference name. Something like :noweb-wrap "# <<%s>>" FWIW, IMO, if the goal is for :noweb-start to always be provided with :noweb-end (and vice-versa), it would be better to use a format-string like approach, i.e., a single :noweb-wrap. -- Suhail ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-12-10 18:37 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-03-05 19:22 noweb-start and noweb-end header args Amy Grinn 2024-03-05 22:41 ` termux 2024-03-06 11:21 ` Ihor Radchenko 2024-03-06 11:40 ` Amy Grinn 2024-03-06 11:47 ` Ihor Radchenko 2024-03-06 12:05 ` Amy Grinn 2024-03-06 13:33 ` Ihor Radchenko 2024-03-06 16:04 ` Amy Grinn 2024-03-07 13:50 ` Ihor Radchenko 2024-03-06 23:07 ` Amy Grinn 2024-03-07 13:58 ` Ihor Radchenko 2024-03-07 14:33 ` Amy Grinn 2024-03-07 14:49 ` Ihor Radchenko 2024-03-07 14:04 ` Ihor Radchenko 2024-03-07 15:06 ` Amy Grinn 2024-04-08 14:04 ` [FR] :noweb-wrap header arg Amy Grinn 2024-04-11 14:03 ` Ihor Radchenko 2024-04-11 18:46 ` Amy Grinn 2024-04-13 13:17 ` Ihor Radchenko 2024-05-11 16:01 ` Amy Grinn 2024-05-12 10:48 ` Ihor Radchenko 2024-05-22 23:17 ` Amy Grinn 2024-05-23 11:27 ` Ihor Radchenko 2024-07-01 9:56 ` Ihor Radchenko 2024-12-08 10:20 ` Ihor Radchenko 2024-12-10 15:28 ` Suhail Singh
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.