UP | HOME

感谢那些照顾过我的人,也谢谢那些伤害过我的人,让我成为这样一个人。

Literate Programming with Org Mode

1. Why Literate Programming?

ID: fe22d012-f3a5-4d86-81aa-5d94a7456dee
PUBDATE: <2019-08-14 Wed 19:08>

There are lot of data on internet about "Literate Programming" already, I blog about this just for personal opinion.

It can organize things better with literal document style. Code is just another kind of text or meta-text used to generate other data like text results, tables, images, JSON, XML data etc.

Anyway, the start point is that I like Emacs and Org-mode very much, they are powerful, organize anything with them can be very flexible. I use Org-mode as the ultimate tool to organize knowledge and data as my external brain database, and my other applications of Org Mode.

2. How to Literate Programming with Org Mode?

ID: 9436231d-4932-4749-9bb0-7785af55becf
PUBDATE: <2019-08-14 Wed 19:08>

2.1. LP: organize things in text and code

ID: 7e07417f-cef1-49bd-8703-0ef845001ec2

2.2. LP: organize logic with "headlines" and "tags"

ID: 06d74faa-da70-407a-a202-77b0f61748ab

You can navigation and filter Literate Programming document logic with headlines and tags. When a file grows large, organize your document with clear structure and better tags group is very necessary.

2.3. LP: write code with Org Babel source code blocks

ID: 05476eca-8292-44f8-b2d1-ed6802148604

Org Mode Babel are technology that can evaluate source code blocks and insert result into Org buffer. Babel is powerful by backend with many different programming languages and tools. On essention, Babel is send source code block text to another binary to be evaluated, then return the result to be inserted in Org buffer.

2.3.1. LP: support many different languages with Babel languages

ID: b1eac9c7-333f-4b25-98a8-5381a0b50ba9

For now, Org Babel has many languages supported now. Official support in Org-mode packages has a lot. Here is my loaded languages alist. They are many more, and you can search in Org source code, and GitHub, and maybe somewhere else.

org-babel-load-languages
- (sclang . t)
- (spice . t)
- (lilypond . t)
- (smiles . t)
- (coq . t)
- (arduino . t)
- (http . t)
- (restclient . t)
- (elasticsearch . t)
- (prolog . t)
- (matlab . t)
- (octave . t)
- (gnuplot . t)
- (julia . t)
- (R . t)
- (haskell . t)
- (redis . t)
- (mongo . t)
- (sqlite . t)
- (sql . t)
- (js . t)
- (css . t)
- (php . t)
- (java . t)
- (swift . t)
- (lua . t)
- (rust . t)
- (go . t)
- (C . t)
- (ruby . t)
- (python . t)
- (clojurescript . t)
- (scheme . t)
- (lisp . t)
- (emacs-lisp . t)
- (makefile . t)
- (ledger . t)
- (blockdiag . t)
- (ditaa . t)
- (dot . t)
- (clojure . t)
- (asymptote . t)
- (translate . t)
- (latex . t)
- (org . t)
- (shell . t)
- (calc . t)
  1. LP: use different languages to processing data in mixture
    ID: 94039fc1-8a02-4ccf-a5d2-0ec54c0c7b47
    

    You can process JSON data with JavaScript, then pass result data to Python to process to generate XML data, then pass the XML data to gnuplot to generate image result.

2.3.2. LP: Babel header arguments

ID: 2a8f8ec9-e4e0-4002-aa56-069a342f480e

There are many source code block header arguments, you can check out Org Mode Info document. And I after some years usage of Org Mode, I found there are some merely used header arguments are not mentioned in Org Mode Manual. And some header arguments are language specific only.

2.4. LP: separate code logic and reference with "noweb"

ID: daada930-a7fb-4a06-9839-4420a47a6712

Tangling functionality is controlled by the tangle family of tangle header arguments. These arguments can be used to turn tangling on or off (the default), either for the code block or the Org-mode heading level.

The following code blocks demonstrate how to tangle them into a single source code file using org-babel-tangle.

The following two code blocks have no tangle header arguments and so will not, by themselves, create source code files. They are included in the source code file by the third code block, which does have a tangle header argument.

In the Org-mode file:

#+name: hello-world-prefix
#+begin_src shell :exports none
  echo "/-----------------------------------------------------------\\"
#+end_src

HTML export of code: In the Org-mode file

#+name: hello-world-postfix
#+begin_src shell :exports none
  echo "\-----------------------------------------------------------/"
#+end_src

HTML export of code: The third code block does have a tangle header argument indicating the name of the file to which the tangled source code will be written. It also has Noweb style references to the two previous code blocks. These references will be expanded during tangling to include them in the output file as well.

In the Org-mode file:

#+name: hello-world
#+begin_src shell :tangle hello.sh :exports none :noweb yes
  <<hello-world-prefix>>
  echo "|                       hello world                         |"
  <<hello-world-postfix>>
#+end_src

HTML export of code: Calling org-babel-tangle will result in the following shell source code being written to the hello.sh file:

echo "/-----------------------------------------------------------\\"
echo "|                       hello world                         |"
echo "\-----------------------------------------------------------/"
#!/usr/bin/env sh

# [[file:~/org/temp/index.org::*Noweb test][hello-world]]

echo "/-----------------------------------------------------------\\"
echo "|                       hello world                         |"
echo "\-----------------------------------------------------------/"
# hello-world ends here

In addition, the following syntax can be used to insert the results of evaluating a code block, in this case one named example-block.

# <<example-block()>>

Any optional arguments can be passed to example-block() by placing the arguments inside the parentheses following the convention defined when calling source block functions (see the Library of babel). For example,

# <<example-block(a=9)>>

sets the value of argument a equal to 9. Note that these arguments are not evaluated in the current source-code block but are passed literally to example-block().

2.5. LP: export to source code with "tangling"

ID: 83350f14-12bb-4ede-b8b1-b2c4ec1b7fdb

2.5.1. LP: tangle single source code block

ID: f7cf5698-02bb-4afe-96b2-eefbc668c3cc

2.5.2. LP: tangle the section of headline

ID: 1d430a6a-dc4d-44d3-9692-d7c305a8f6a3

2.5.3. LP: tangle whole file

ID: 582436f3-89cc-44c1-aef6-44498833925d

2.6. LP: display result

ID: 6bb1c422-9ba9-4b57-aeab-8474aad9ae66

2.6.1. LP: display image result with Org inline image display

ID: c39df5f2-4a3b-4acf-a2e2-ec02ab17b97f

You can manually insert a file link to image file as inline image. You also can let source code block generate a file link to plot image file. Toggle inline image display in Org-mode with [M-x org-display-inline-images].

2.6.2. LP: display table result with Org table

ID: 2d248cb5-fdb4-4b1c-be72-720e47dd96b1

Org-mode supports table. Support many manipulations. Also there are many advanced usage of Org table, like use table as data input for source code block, radio table, etc.

2.7. LP: reference to text, code and each other

ID: 1e1bd0e0-06c8-4617-87e3-83f407b38555

2.7.1. text->code with coderef

ID: baf81c8a-cf61-4971-90b3-cf77acc5b10f
(defun hello (name)                               ; (define function hello)
  (print (format "Hello, %s" name)))

define function hello

2.7.2. text->text with link

ID: 9b5015bb-b446-4578-9dd7-601889f28a38

2.7.3. code->code with noweb

ID: 502e7979-5746-4596-be87-257a4882c947
<<hello>>

(hello "stardiviner")
Hello, stardiviner

2.7.4. code->text with link

ID: 3b51bf70-f94b-4c51-b19c-97c11aff13eb
  1. org-link in source code block comment
    ID: 6d6d31f4-58a0-4ac2-a84b-735622708875
    

2.8. LP: navigation in text and code

ID: c2e0e53d-01c3-40f7-9081-6ecd7c0f20c7
  • org-babel-goto-named-src-block
  • org-babel-goto-named-result
  • org-babel-goto-src-block-head

You can jump back in mark ring with [M-,] / org-mark-ring-goto.

3. TODO complete this post

ID: 62431107-1dd5-4e78-ac34-514ed3bed771
PUBDATE: <2019-08-14 Wed 19:08>

Still there are many things need to write. But temporary like this for now.