org-sbe-example-meta-programming.md 3.6 KB

Idea

This example shows how one can make use of any org-babel supported programming language inside org-mode tables/spreadsheets. This allows the user to use the most suitable programming language for the task at hand to process data and put results back into the spreadsheet.

Data

Define some data as output string. We can use whatever way we want to generate the data. All that matters is, that the data is output as a result of this source block.

(display 1) (newline)
(display 2) (newline)
(display 3) (newline)
(display 4) (newline)
(display 5) (newline)

Scheme value converter

Input is always a string, when it is given via :var in source block header arguments. It needs to be converted to a list first. The following defines a converter function, which splits a string into a list of strings, using any whitespace as a separator. If the input is for example a sloppily written bunch of numbers, they will be converted into a list of strings, each containing one number.

(define convert:string->list
  (λ (str)
    (filter (λ (str) (not (string-null? str)))
            (string-split str char-set:whitespace))))

Business logic function definition

We implement the actual business logic function to process the data. Here we make use of the :noweb header argument, to source the converter function.



(define mean
  (λ (lst)
    (let ([len (length lst)])
      (/ (apply + lst) len))))

(define mean-inexact
  (λ (lst)
    (exact->inexact (mean lst))))

(simple-format
 #t "~a\n"
 (mean-inexact
  (map string->number
       (convert:string->list x))))

Usage in org mode spreadsheet

Here we make use of org-sbe in the #+TBLFM: table formula. We name the source block we want to run and define values of variables for that source block. Important: The source block needs to accept/receive the variable via a :var header argument. In this case the variable is named x. The value of the variable can be retrieved from another named source block. In this case we call the source block scheme-data to generate our data.

mean
3.0

Use table as input for a source block

Possible syntaxes for referencing tables:

  • example-table[0,-1]
  • example-table[1:3] (range)
  • example-table[,0] (all of row or column)
  • example-table[1,,1] (multiple dimensions, for output of other source blocks, that would be tables or arrays or lists os …)

    Index referencing can be used for tables and code blocks. Index referencing can handle any number of dimensions. Commas delimit multiple dimensions, as shown below.

    https://orgmode.org/manual/Environment-of-a-Code-Block.html

id val
0 3
1 5
2 45
3 1
4 21
5 9

When taken from a table and given to scheme source blocks, values seem to be lists of integers without converting. (Maybe org-mode has some knowledge built-in?)

(define mean
  (λ (lst)
    (let ([len (length lst)])
      (/ (apply + lst) len))))

(define mean-inexact
  (λ (lst)
    (exact->inexact (mean lst))))

(simple-format
 #t "~a\n"
 (mean-inexact x))

Reference the whole val column of the data table:

mean
14.0