Archives | Categories

An approach to references from code to text in Orgmode.

<2018-05-17 Thu>

A few days ago, I made a proposal for implementing references from code to text in Orgmode, and posted it on the Orgmode mail list. Thanks to the community, I got an approach from John Kitchin. Within this approach, we achieve the target by including the results of another named code block rather than its body into the code block which we want to embed the named text in as its docstring, and we cloud do it without touching the source of Orgmode:

  1. Write a piece of code in elisp to get named text as a string, put it into a named code block so that it can be called in other code blocks.
  2. Write the text which will be used as docstring with a NAME(#+NAME:<NAME>).
  3. In the target code block, turn on the noweb flag, and refer to the result of the named code block we wrote in step 1, i.e. <<name-of-code(args...)>>.
  4. Tangle the code block, it will have the docstring in it.

Now I'll depict this process detailedly.

The code block to get named text

I name that block as get-named-text, the code is mainly from Join Kitchin, and with minor changes of mine. It parses the whole Org file, finds the element which is named with the string we given as the only argument, takes out the content of the found element, escapes double quotes in it add surrounds it with a pair of double quotes, then returns that string.

#+NAME: get-named-text
#+BEGIN_SRC elisp :var name="docstring"
  (let* ((named-element (org-element-map (org-element-parse-buffer) org-element-all-elements
                          (lambda (element)
                            (when (string= (org-element-property :name element) name)
                          nil t))
         (result (buffer-substring (org-element-property :contents-begin named-element)
                                   (org-element-property :contents-end named-element))))
    (format "\"%s\"" (replace-regexp-in-string "\\\"" "\\\\\"" result))) ;; escape quote

Name the text(docstring)

In the same Org file, name your text(docstring):

#+NAME: doc-for-add
This is a sample docstring for the function "add".

Put the named text into the target code block

#+BEGIN_SRC elisp :noweb yes :tangle yes
(defun add (x y)
  (+ x y))

Notice: turn on the :noweb flag.

This code block will be tangled as:

(defun add (x y)
  "This is a sample docstring for the function \"add\"."
  (+ x y))

And a step further

With the help of The Library of Babel, we don't have to include the code block get-named-text into every Org file. I put the block into an Org file under my .emacs.d directory, $HOME/.emacs.d/src/resources/ Then put this line into my .emacs:

(org-babel-lob-ingest (expand-file-name "~/.emacs.d/src/resources/"))

This makes the code block get-named-text a predefined and callable code block that can be seen and called in any Org file.


Discuss and Comment

Have few questions or feedback? Feel free to send me(zhuoql📧 an email!


Built with Emacs 25.2.2 (Org mode 9.5.3).

Last updated: 2022-01-28 Fri 13:42.

Green Web Hosting! This site hosted by DreamHost.