Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Hi, Ihor Radchenko writes: Can you provide more concrete examples? Some drawbacks: + doesn't work for all languages (does work for LaTeX) Which languages do not work? Most languages do not work. Using your proposed solution, what I'm trying to do is #+name:javascript-header #+begin_src javascript :tangle no some javascript, with \ and " to be escaped #+end_src #+name: string-escape #+begin_src emacs-lisp :var str="" :tangle no (prin1-to-string (string-trim-right str)) #+end_src #+begin_src emacs-lisp :noweb yes :tangle yes (setq javascript-header <>) #+end_src If you replace javascript with latex, it happens to work, because when org executes a latex block, it prints its content. The goal is to tangle to some lisp code whose purpose is to generate LaTeX/javascript code. Quite niche admittedly, though as you showed, it could also be used to string-escape documentation. + the tangle gets very noisy: not only are the result of execution printed in the echo buffer, but emacs visits the tangling buffer and moves the point to each block. Perhaps this is a bug that can be fixed. Did you try to play with :results header argument to disable messages? What exactly went unexpected? I did. I might have missed something, but no combination of :results argument to both the latex block and the string-escape block silences the tangle (except for :results none, which doesn't tangle the content of the block). During tangle, the contents of the latex block are displayed (shortly) in the echo buffer (check *Messages*), and the point very briefly moves to the latex block. This isn't very noticeable with a single block. + src block execution also resets the noweb cache, slowing down tangle, though I have not tried to measure the effect. I am not sure what you are referring to here. Can you elaborate? Lines 2892-2893 of (my) ob-core.el, in org-babel-expand-noweb-references: ;; Evaluation can potentially modify the buffer ;; and invalidate the cache: reset it. Regards, -- Sébastien Miquel
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Sébastien Miquel writes: >> #+name: documentation >> This is a sample function documentation. >> Because there are "quotes", it must be escaped and cannot be directly >> used as noweb-reference. >> >> #+name: doc-escape >> #+begin_src emacs-lisp :var str="" :tangle no >> (prin1-to-string (string-trim-right str)) >> #+end_src >> >> #+begin_src emacs-lisp :tangle yes >> (defun test () >> <> >> t) >> #+end_src > I had converted my uses (tangling code, not text/documentation) to > this but I ended up reverting. Can you provide more concrete examples? > Some drawbacks: > + doesn't work for all languages (does work for LaTeX) Which languages do not work? > + the tangle gets very noisy: not only are the result of execution > printed in the echo buffer, but emacs visits the tangling buffer > and moves the point to each block. > Perhaps this is a bug that can be fixed. Did you try to play with :results header argument to disable messages? What exactly went unexpected? > + src block execution also resets the noweb cache, slowing down > tangle, though I have not tried to measure the effect. I am not sure what you are referring to here. Can you elaborate? Best, Ihor
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Hi, Ihor Radchenko writes: Thinking about the whole idea of :noweb-trans more, I see little benefit compared to something like: #+name: documentation This is a sample function documentation. Because there are "quotes", it must be escaped and cannot be directly used as noweb-reference. #+name: doc-escape #+begin_src emacs-lisp :var str="" :tangle no (prin1-to-string (string-trim-right str)) #+end_src #+begin_src emacs-lisp :tangle yes (defun test () <> t) #+end_src I had converted my uses (tangling code, not text/documentation) to this but I ended up reverting. Some drawbacks: + doesn't work for all languages (does work for LaTeX) + the tangle gets very noisy: not only are the result of execution printed in the echo buffer, but emacs visits the tangling buffer and moves the point to each block. Perhaps this is a bug that can be fixed. + src block execution also resets the noweb cache, slowing down tangle, though I have not tried to measure the effect. As stated in the OP, I find it unfortunate that org does not provide any way to tangle the content of a src block to a string representing this code. If anyone shows any interest, I've provided two possible implementations in this thread, that I can rebase. Regards, -- Sébastien Miquel
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Sébastien Miquel writes: >> Other than :noweb-trans, the patch looks good for me. > Here's a patch with only the :noweb-prefix part. If applied, we can mark > this thread resolved. Thanks! Applied on main as 2063596b9. > Ihor Radchenko writes: >> #+name: documentation >> This is a sample function documentation. >> Because there are "quotes", it must be escaped and cannot be directly >> used as noweb-reference. >> >> #+name: doc-escape >> #+begin_src emacs-lisp :var str="" :tangle no >> (prin1-to-string (string-trim-right str)) >> #+end_src >> >> #+begin_src emacs-lisp :tangle yes >> (defun test () >> <> >> t) >> #+end_src > > Nice ! Quite obscure and brittle (doesn't work if documentation is a > text src block) but I can use it nonetheless. Well. It looks natural for me. Depends on what you are used to when working with org babel. Things are a bit more tricky for latex source blocks, but you can still do #+name: nw #+BEGIN_SRC latex :tangle no \usepackage{…} \usepackage{…} #+END_SRC #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no (setq latex-header <>) #+END_SRC Of course, it would only work for source blocks with corresponding ob-*.el library. But then again, why would you need to wrap things into text source block when a simple paragraph is enough. Best, Ihor Applied.
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Ihor Radchenko writes: #+name: documentation This is a sample function documentation. Because there are "quotes", it must be escaped and cannot be directly used as noweb-reference. #+name: doc-escape #+begin_src emacs-lisp :var str="" :tangle no (prin1-to-string (string-trim-right str)) #+end_src #+begin_src emacs-lisp :tangle yes (defun test () <> t) #+end_src Nice ! Quite obscure and brittle (doesn't work if documentation is a text src block) but I can use it nonetheless. Other than :noweb-trans, the patch looks good for me. Here's a patch with only the :noweb-prefix part. If applied, we can mark this thread resolved. Thanks, -- Sébastien Miquel From 3fc3c3557b27026e2cfdb2a1973921c1baf3758a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Mon, 6 Sep 2021 18:45:42 +0200 Subject: [PATCH] ob-core.el: Add `:noweb-prefix` babel header argument * lisp/ob-core.el (org-babel-expand-noweb-references): Add support for `noweb-prefix' header argument, to not repeat the prefix characters when expanding a noweb reference. (org-babel-common-header-args-w-values): (org-babel-safe-header-args): Add `noweb-prefix' value. * doc/org-manual.org: Document `noweb-prefix' babel header argument. * etc/ORG-NEWS: Document `:noweb-prefix'. --- doc/org-manual.org | 17 + etc/ORG-NEWS | 6 +- lisp/ob-core.el| 17 - 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index 6768ca98d..c9c1c1298 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -18760,6 +18760,23 @@ else: print('do things when false') #+end_example +This prefix behavior can be turned off in a block by setting the +=noweb-prefix= header argument to =no=, as in: + +#+begin_example +,#+BEGIN_SRC elisp :noweb-prefix no + (setq example-data "<>") +,#+END_SRC +#+end_example + +#+texinfo: @noindent +which expands to: + +#+begin_example +(setq example-data "this is the +multi-line body of example") +#+end_example + When in doubt about the outcome of a source code block expansion, you can preview the results with the following command: diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 2b539d305..1e8558c7b 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -150,7 +150,7 @@ The entry points are ~org-persist-register~, ~org-persist-unregister~, ~org-persist-read~, and ~org-persist-read-all~. Storing circular structures is supported. Storing references between different variables is also supported (see =:inherit= key in -~org-persist-register~). +~org-persist-register~). The library permits storing buffer-local variables. Such variables are linked to the buffer text, file =inode=, and file path. @@ -175,6 +175,10 @@ the =compact-itemx= export option, or globally using the Items in a description list that begin with =Function:=, =Variable:= or certain related prefixes are converted using Texinfo definition commands. +*** New =:noweb-prefix= babel header argument + +=:noweb-prefix= can be set to =no= to prevent the prefix characters +from being repeated when expanding a multiline noweb reference. ** New functions and changes in function arguments diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 65907..09d6adfe0 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -413,6 +413,7 @@ then run `org-babel-switch-to-session'." (noweb . ((yes no tangle no-export strip-export))) (noweb-ref . :any) (noweb-sep . :any) +(noweb-prefix . ((no yes))) (output-dir . :any) (padline . ((yes no))) (post . :any) @@ -438,8 +439,8 @@ specific header arguments as well.") (defconst org-babel-safe-header-args '(:cache :colnames :comments :exports :epilogue :hlines :noeval - :noweb :noweb-ref :noweb-sep :padline :prologue :rownames - :sep :session :tangle :wrap + :noweb :noweb-ref :noweb-sep :noweb-prefix :padline + :prologue :rownames :sep :session :tangle :wrap (:eval . ("never" "query")) (:results . (lambda (str) (not (string-match "file" str) "A list of safe header arguments for babel source blocks. @@ -2827,6 +2828,10 @@ block but are passed literally to the \"example-block\"." (lang (nth 0 info)) (body (nth 1 info)) (comment (string= "noweb" (cdr (assq :comments (nth 2 info) + (noweb-prefix (let ((v (assq :noweb-prefix (nth 2 info + (or (not v) + (and (org-not-nil (cdr v)) + (not (equal (cdr v) "no")) (noweb-re (format "\\(.*?\\)\\(%s\\)" (with-current-buffer parent-buffer (org-babel-noweb-wrap @@ -2923,9 +2928,11 @@ block but are passed literally to the \"example-block\"." (push info (gethash ref cache)) (funcall expand-references id cache) ;; Interpose PREFIX between every line. - (mapconcat #'identity - (split-string expansion "[\n\r]") - (concat
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Sébastien Miquel writes: > at least as long as you're tangling to a programming language, that > can read lisp strings. >> Consider the following example: >> >> #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no :noweb-trans >> prin1-to-string >> <> >> (setq latex-header <>) >> #+END_SRC >> >> There are two noweb references here. Setting source block-wide >> :noweb-trans is not helpful because the first reference will be >> incorrectly filtered through prin1-to-string. > Indeed. Originally I had thought of adding a new syntax <<"nw">> to > insert a string representation. I've attached a new patch, that does > this instead of introducing :noweb-trans. Now that I think of the > universality of prin1-to-string, I actually like it slightly better > than :noweb-trans. It would break existing "nw"-like noweb references. This is too specific, as for me. Thinking about the whole idea of :noweb-trans more, I see little benefit compared to something like: #+name: documentation This is a sample function documentation. Because there are "quotes", it must be escaped and cannot be directly used as noweb-reference. #+name: doc-escape #+begin_src emacs-lisp :var str="" :tangle no (prin1-to-string (string-trim-right str)) #+end_src #+begin_src emacs-lisp :tangle yes (defun test () <> t) #+end_src Maybe we can instead distribute a library ob babel file containing useful functions together with Org. >>> [...] >> This sounds a bit confusing. I would also add an example where it is >> useful to set :noweb-prefix to no. > > I've added such an example in the revised patch attached. Other than :noweb-trans, the patch looks good for me. Best, Ihor
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Hi, Ihor Radchenko writes: prin1-to-string is too specific and only solves a single use-case. prin1-to-string is actually universal in a way, since any other manipulation can then be achieved with : (setq var (do-something <>)) at least as long as you're tangling to a programming language, that can read lisp strings. Consider the following example: #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no :noweb-trans prin1-to-string <> (setq latex-header <>) #+END_SRC There are two noweb references here. Setting source block-wide :noweb-trans is not helpful because the first reference will be incorrectly filtered through prin1-to-string. Indeed. Originally I had thought of adding a new syntax <<"nw">> to insert a string representation. I've attached a new patch, that does this instead of introducing :noweb-trans. Now that I think of the universality of prin1-to-string, I actually like it slightly better than :noweb-trans. It would break existing "nw"-like noweb references. Of course, one can work around this easily enough by using two blocks. I'd rather introduce a new syntax to transform the noweb reference inline. Something like #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no <> (setq latex-header <<(prin1-to-string nw)>>) #+END_SRC You'd need to only allow a single function call with only one argument, or use something like <<(prin1-to-string <>)>>. The change would be much more complex than what I propose, for maybe little benefit. [...] This sounds a bit confusing. I would also add an example where it is useful to set :noweb-prefix to no. I've added such an example in the revised patch attached. Thanks for the feedback. Regards, -- Sébastien Miquel From 99d043b9d837a2658e60fb4b4913454d9566519b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Mon, 6 Sep 2021 18:45:42 +0200 Subject: [PATCH] ob-core.el: Add `:noweb-prefix`, `:noweb-trans` babel header arguments * lisp/ob-core.el (org-babel-expand-noweb-references): Add support for `noweb-prefix' header argument, to not repeat the prefix characters when expanding a noweb reference. Add support for `noweb-trans' header argument, to apply a function to the noweb content upon expansion. (org-babel-common-header-args-w-values): (org-babel-safe-header-args): Add `noweb-prefix' and `noweb-trans' values. * doc/org-manual.org: Document `noweb-prefix' and `noweb-trans' babel header arguments. * etc/ORG-NEWS: Document `:noweb-prefix' and `:noweb-trans'. --- doc/org-manual.org | 42 ++ etc/ORG-NEWS | 10 +- lisp/ob-core.el| 26 -- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index 6768ca98d..5ef8e2f8b 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -18760,6 +18760,48 @@ else: print('do things when false') #+end_example +This prefix behavior can be turned off in a block by setting the +=noweb-prefix= header argument to =no=, as in: + +#+begin_example +,#+BEGIN_SRC elisp :noweb-prefix no + (setq example-data "<>") +,#+END_SRC +#+end_example + +#+texinfo: @noindent +which expands to: + +#+begin_example +(setq example-data "this is the +multi-line body of example") +#+end_example + +The header argument =noweb-trans= can be set to =prin1-to-string= to +insert a lisp string representing the content of the referenced src +block. With: + +#+begin_example +,#+NAME: latex-header +,#+BEGIN_SRC latex + \usepackage{amsmath} +,#+END_SRC +#+end_example + +#+texinfo: @noindent +this code block: + +#+begin_example +,#+BEGIN_SRC elisp :noweb yes :noweb-trans prin1-to-string + (setq header <>) +,#+END_SRC +#+end_example + +#+texinfo: @noindent +expands to: + +: (setq header "\\usepackage{amsmath}") + When in doubt about the outcome of a source code block expansion, you can preview the results with the following command: diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 2b539d305..70f7606db 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -150,7 +150,7 @@ The entry points are ~org-persist-register~, ~org-persist-unregister~, ~org-persist-read~, and ~org-persist-read-all~. Storing circular structures is supported. Storing references between different variables is also supported (see =:inherit= key in -~org-persist-register~). +~org-persist-register~). The library permits storing buffer-local variables. Such variables are linked to the buffer text, file =inode=, and file path. @@ -175,6 +175,14 @@ the =compact-itemx= export option, or globally using the Items in a description list that begin with =Function:=, =Variable:= or certain related prefixes are converted using Texinfo definition commands. +*** New =:noweb-prefix= and =:noweb-trans= babel header arguments + +=:noweb-prefix= can be set to =no= to prevent the prefix characters +from being repeated when expanding a multiline noweb reference. + +=:noweb-trans= can be set to
Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments
Sébastien Miquel writes: > The attached patch adds support for two new babel header arguments: > =:noweb-prefix= and =:noweb-trans=. > > =:noweb-prefix= can be set to =no= to disable the noweb prefix > behaviour, where prefix characters are repeated when expanding a > multiline noweb reference. Thanks for the patch! The idea about :noweb-prefix looks useful. > =:noweb-trans= can be set to =prin1-to-string= to insert a lisp string > representing the content of the referenced src block. > > The goal is to allow one to use, say, a LaTeX src block to represent > some LaTeX snippet to be tangled into a string in some lisp (or other) > code. This isn't possible currently, and one has to manually string > escape the LaTeX code. > ... > I've left undocumented the possibility of setting =:noweb-trans= to > another function. I wonder if anyone can think of some other use. prin1-to-string is too specific and only solves a single use-case. Consider the following example: #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no :noweb-trans prin1-to-string <> (setq latex-header <>) #+END_SRC There are two noweb references here. Setting source block-wide :noweb-trans is not helpful because the first reference will be incorrectly filtered through prin1-to-string. I'd rather introduce a new syntax to transform the noweb reference inline. Something like #+BEGIN_SRC emacs-lisp :noweb yes :tangle yes :noweb-prefix no <> (setq latex-header <<(prin1-to-string nw)>>) #+END_SRC > Noweb insertions honor prefix characters that appear before the noweb > -syntax reference. This behavior is illustrated in the following > -example. Because the =<>= noweb reference appears behind the > -SQL comment syntax, each line of the expanded noweb reference is > -commented. With: > +syntax reference. This behavior can be turned off by setting the > +=noweb-prefix= header argument to =no= and is illustrated in the > +following example. Because the =<>= noweb reference appears > +behind the SQL comment syntax, each line of the expanded noweb > +reference is commented. With: This sounds a bit confusing. I would also add an example where it is useful to set :noweb-prefix to no. Best, Ihor