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 =prin1-to-string=. Noweb reference +therein will be expanded to an elisp string representation of their +content. ** New functions and changes in function arguments diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 6590eeee7..b5fb68661 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -413,6 +413,8 @@ 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))) + (noweb-trans . ((prin1-to-string))) (output-dir . :any) (padline . ((yes no))) (post . :any) @@ -438,9 +440,10 @@ 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")) + (:noweb-trans . ("prin1-to-string")) (:results . (lambda (str) (not (string-match "file" str))))) "A list of safe header arguments for babel source blocks. @@ -2827,6 +2830,12 @@ 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-trans (when (cdr (assq :noweb-trans (nth 2 info))) + (intern (cdr (assq :noweb-trans (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)))) @@ -2921,11 +2930,16 @@ block but are passed literally to the \"example-block\"." (let* ((info (org-babel-get-src-block-info t)) (ref (cdr (assq :noweb-ref (nth 2 info))))) (push info (gethash ref cache)))))) - (funcall expand-references id cache))))) + (funcall expand-references id cache)))) + (expansion (if (functionp noweb-trans) + (funcall noweb-trans expansion) + expansion))) ;; Interpose PREFIX between every line. - (mapconcat #'identity - (split-string expansion "[\n\r]") - (concat "\n" prefix)))))) + (if noweb-prefix + (mapconcat #'identity + (split-string expansion "[\n\r]") + (concat "\n" prefix)) + expansion))))) body t t 2))) (defun org-babel--script-escape-inner (str) -- 2.36.0