Re: [PATCH] Add :noweb-prefix and :noweb-trans babel header arguments

2022-05-31 Thread Sébastien Miquel

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

2022-05-30 Thread Ihor Radchenko
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

2022-05-30 Thread Sébastien Miquel

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

2022-04-30 Thread Ihor Radchenko
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

2022-04-30 Thread Sébastien Miquel


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

2022-04-30 Thread Ihor Radchenko
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

2022-04-29 Thread Sébastien Miquel

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

2022-04-28 Thread Ihor Radchenko
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