Support via Liberapay


Org-babel support for interactive terminals


org-babel-screen is an extension to Org-babel and was inspired by Eduardo Ochs's eev.

org-babel-screen provides the ability to write interactive Makefiles that can be called from inside Emacs. Now before you get your hopes up: The whole point of Makefiles is that they should run automatic. org-babel-screen doesn't do that! I guess the only thing they have in common is that they both do certain things. And that they can be grouped.

I admit, the analogy is not great. But to explain why I still think it's useful I will go and show a few examples in this document.

First install org-babel according to the directions given in the org-babel manual. Then come back here.


Now that you've installed org-babel, add the following after the other org-babel related statements.

(require 'org-babel-screen)    ;; requires screen, terminal

There are two important variables that you might want to review before using org-babel-screen: org-babel-screen-location and org-babel-default-header-args:screen

If GNU Screen is installed and recognized by your PATH you can ignore org-babel-screen-location, otherwise change the value of that variable to the absolute path of the screen binary.

The default headers arguments are a bit more interesting. If you don't have XTerm installed or you don't wish to use it, you need to edit the value of org-babel-default-header-args:screen.

This is the default:

(defvar org-babel-default-header-args:screen
'((:results . "silent") (:session . "default") (:cmd . "sh") (:terminal . "xterm"))
"Default arguments to use when running screen source blocks.")

The :session, :cmd & :terminal keys are the only thing that matter in this mode.

You can test the default setup by executing M-x org-babel-screen-test RET. The minibuffer will echo if the test has succeeded or not. 1

Example 1: Creating a gif out of a video file

Let's get on with the examples though: I'm going to use MPlayer, QIV & ImageMagick for this. But you can follow this example without them.

Set the correct settings

I'm setting the session name of create-gif so I can have other interactive terminals running without interference. Example 2 will go further into this.

The :cmd is zsh, because that's my favorite shell and I know how to do globbing with it.

This example is very verbose, but here it goes:

#+begin_src screen :cmd zsh :session create-gif

Create TMPDIR and change directory to it

The :session parameter has to be the same as the one used in the first step, the :cmd parameter can be ignored though.

#+begin_src screen :session create-gif
  mkdir -p $TMPDIR
  cd $TMPDIR

Copy video to TMPDIR

#+begin_src screen :session create-gif
  cp -v $VIDEOFILE .

Skip through the video file to find the spot you want to extract

This is the first interactive step. Find the position in the video of the section you want to extract. This information will be used in the next step.

#+begin_src screen :session create-gif
  mplayer -ao null -osdlevel 3 $VIDEOFILE

Extract those frames from the video

Change the value of START and optionally SECS. For this video I've chosen 1:10 with a 10 seconds window.

#+begin_src screen :session create-gif

  mplayer -ao null -vo png $VIDEOFILE -ss $START -endpos $SECS

Delete the frames you don't want

This is the second interactive part.

You delete the frames by pressing 'd' in qiv.

#+begin_src screen :session create-gif
  qiv .

Resize pictures

256 x the corresponding aspect ratio is a good size.

#+begin_src screen :session create-gif

  mkdir Small/
  for img (*.png) { convert -scale $SCALE $img Small/$img }
  file Small/*.png([1])

Inspect down-scaled size

If the size isn't alright, redo the previous step with a different SCALE.

#+begin_src screen :session create-gif
  qiv Small/*.png

Generate gif file

The settings here are for an endless looping gif. If the gif plays to fast or too slow, you can just change the command line options as you normally would.

#+begin_src screen :session create-gif
  convert -delay 10 -loop 0 Small/* animation.gif

Look at the resulting gif

I use opera for this. If the gif is not satisfactory, repeat the above steps as necessary.

#+begin_src screen :session create-gif
  opera animation.gif

Example 2: Semi-parallel communication via netcat

This is a very small example2, but expands on the concept of sessions well. The objective is to send a message via TCP to someone else. (We fake this by doing everything via localhost The principle is the same.)

Listen for message

Set up netcat to listen to port 1234.

Notice the :session parameter. Specifying receiver here and sender below allows us to run this example from a single source but with two interactive seesions.

#+begin_src screen :session receiver
  netcat -l -p 1234

Send the message

Use the default shell (:cmd has been omitted.) to generate a message and send it to the port that is listening for it.

#+begin_src screen :session sender
   echo hi
   sleep 1
   echo bye
   sleep 1
  } | netcat -c localhost 1234

After you've invoked both examples, you can see how the receiver session sees the message send by sender.

How this might be useful: You could take this example further and test an app that communicated via a network interface. You wouldn't have a fully automatic setup yet, but the Reproducible Research concept still applies.

Header Arguments

Here's a general overview of header arguments:

session name that is used by screen
default value
argument must be a shell of some sort
default value
sh, zsh, irb, python, sqlite3
must support -T 'title' and -e 'command'
default value
xterm, urxvt, aterm, Eterm
argument currently ignored
default value



It does this by generating a random string, writing it via org-screen-babel to /tmp/testfile and reading it back via Emacs. If the validation fails, the setup is deemed broken.


The example is taken from Eev as well: channels.anim

Documentation from the website (either in its HTML format or in its Org format) is licensed under the GNU Free Documentation License version 1.3 or later. The code examples and css stylesheets are licensed under the GNU General Public License v3 or later.