16.11 Noweb Reference Syntax

Source code blocks can include references to other source code blocks, using a noweb145 style syntax:

<<CODE-BLOCK-ID>>

where CODE-BLOCK-ID refers to either the ‘NAME’ of a single source code block, or a collection of one or more source code blocks sharing the same ‘noweb-ref’ header argument (see Using Header Arguments). Org can replace such references with the source code of the block or blocks being referenced, or, in the case of a single source code block named with ‘NAME’, with the results of an evaluation of that block.

The ‘noweb’ header argument controls expansion of noweb syntax references. Expansions occur when source code blocks are evaluated, tangled, or exported.

no

Default. No expansion of noweb syntax references in the body of the code when evaluating, tangling, or exporting.

yes

Expansion of noweb syntax references in the body of the code block when evaluating, tangling, or exporting.

tangle

Expansion of noweb syntax references in the body of the code block when tangling. No expansion when evaluating or exporting.

strip-tangle

Expansion of noweb syntax references in the body of the code block when evaluating or exporting. Removes noweb syntax references when exporting.

no-export

Expansion of noweb syntax references in the body of the code block when evaluating or tangling. No expansion when exporting.

strip-export

Expansion of noweb syntax references in the body of the code block when expanding prior to evaluating or tangling. Removes noweb syntax references when exporting.

eval

Expansion of noweb syntax references in the body of the code block only before evaluating.

In the most simple case, the contents of a single source block is inserted within other blocks. Thus, in following example,

#+NAME: initialization
#+BEGIN_SRC emacs-lisp
  (setq sentence "Never a foot too far, even.")
#+END_SRC

#+BEGIN_SRC emacs-lisp :noweb yes
  <<initialization>>
  (reverse sentence)
#+END_SRC

the second code block is expanded as

#+BEGIN_SRC emacs-lisp :noweb yes
  (setq sentence "Never a foot too far, even.")
  (reverse sentence)
#+END_SRC

You may also include the contents of multiple blocks sharing a common ‘noweb-ref’ header argument, which can be set at the file, subtree, or code block level. In the example Org file shown next, the body of the source code in each block is extracted for concatenation to a pure code file when tangled.

#+BEGIN_SRC sh :tangle yes :noweb yes :shebang #!/bin/sh
  <<fullest-disk>>
#+END_SRC
* the mount point of the fullest disk
  :PROPERTIES:
  :header-args: :noweb-ref fullest-disk
  :END:

** query all mounted disks
#+BEGIN_SRC sh
  df \
#+END_SRC

** strip the header row
#+BEGIN_SRC sh
  |sed '1d' \
#+END_SRC

** output mount point of fullest disk
#+BEGIN_SRC sh
  |awk '{if (u < +$5) {u = +$5; m = $6}} END {print m}'
#+END_SRC

By default a newline separates each noweb reference concatenation. To use a different separator, edit the ‘noweb-sep’ header argument.

Alternatively, Org can include the results of evaluation of a single code block rather than its body. Evaluation occurs when parentheses, possibly including arguments, are appended to the code block name, as shown below.

<<NAME(optional arguments)>>

Note that in this case, a code block name set by ‘NAME’ keyword is required; the reference set by ‘noweb-ref’ will not work when evaluation is desired.

Here is an example that demonstrates how the exported content changes when noweb style references are used with parentheses versus without. Given:

#+NAME: some-code
#+BEGIN_SRC python :var num=0 :results output :exports none
  print(num*10)
#+END_SRC

this code block:

#+BEGIN_SRC text :noweb yes
  <<some-code>>
#+END_SRC

expands to:

print(num*10)

Below, a similar noweb style reference is used, but with parentheses, while setting a variable ‘num’ to 10:

#+BEGIN_SRC text :noweb yes
  <<some-code(num=10)>>
#+END_SRC

Note that the expansion now contains the results of the code block ‘some-code’, not the code block itself:

100

Noweb insertions honor prefix characters that appear before the noweb syntax reference. This behavior is illustrated in the following example. Because the ‘<<example>>’ noweb reference appears behind the SQL comment syntax, each line of the expanded noweb reference is commented. With:

#+NAME: example
#+BEGIN_SRC text
  this is the
  multi-line body of example
#+END_SRC

this code block:

#+BEGIN_SRC sql :noweb yes
 ---<<example>>
#+END_SRC

expands to:

#+BEGIN_SRC sql :noweb yes
 ---this is the
 ---multi-line body of example
#+END_SRC

Since this change does not affect noweb replacement text without newlines in them, inline noweb references are acceptable.

This feature can also be used for management of indentation in exported code snippets. With:

#+NAME: if-true
#+BEGIN_SRC python :exports none
  print('do things when true')
#+end_src

#+name: if-false
#+begin_src python :exports none
  print('do things when false')
#+end_src

this code block:

#+begin_src python :noweb yes :results output
  if true:
      <<if-true>>
  else:
      <<if-false>>
#+end_src

expands to:

if true:
    print('do things when true')
else:
    print('do things when false')

This prefix behavior can be turned off in a block by setting the ‘noweb-prefix’ header argument to ‘no’, as in:

#+BEGIN_SRC elisp :noweb-prefix no
  (setq example-data "<<example>>")
#+END_SRC

which expands to:

(setq example-data "this is the
multi-line body of example")

When in doubt about the outcome of a source code block expansion, you can preview the results with the following command:

C-c C-v v or C-c C-v C-v (org-babel-expand-src-block)

Expand the current source code block according to its header arguments and pop open the results in a preview buffer.


Footnotes

(145)

For noweb literate programming details, see https://www.cs.tufts.edu/~nr/noweb/.