|
| From: | Zelphir Kaltstahl |
| Subject: | org source block execute not working correctly with GNU Guile source block? |
| Date: | Sun, 14 Mar 2021 16:28:23 +0100 |
| User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 |
Hello!
I have an org-mode spreadsheet, in which I calculate durations from timestamps like "[2021-03-14 Sun 03:50]" for example. Recently I saw, that using org-sbe (org source block execute) in combination with the :var header argument can be used to run arbitrary code for calculating values to put as result of spreadsheet formulas (on https://home.fnal.gov/~neilsen/notebook/orgExamples/org-examples.html). So I went trying it out. The following is some GNU Guile code for calculating time differences in hours:
~~~~
#+NAME: allinone
#+begin_src scheme :noweb yes :var org-timestamp-1="[2021-01-01 Fri 00:00]", org-timestamp-2="[2021-01-01 Fri 01:00]" :results output drawer replace :exports none
(import (srfi srfi-19))
(define SECOND 1)
(define MINUTE (* 60 SECOND))
(define HOUR (* 60 MINUTE))
(define org-timestamp-format "[~Y-~m-~d ~a ~H:~M]")
(define duration->time-utc
(λ (duration)
(make-time time-utc
(time-nanosecond duration)
(time-second duration))))
(define org-timestamp->time-utc
(λ (timestamp-string)
(let ([parsed-date (string->date timestamp-string org-timestamp-format)])
(date->time-utc parsed-date))))
(define org-time-duration
(λ (org-timestamp-1 org-timestamp-2)
(time-difference (org-timestamp->time-utc org-timestamp-2)
(org-timestamp->time-utc org-timestamp-1))))
(define duration->org-timestamp
(λ (duration)
(time-utc->date
(duration->time-utc duration)
;; timezone offset, assume all with no offset
0)))
(define duration->hours
(λ (duration)
(/ (time-second duration) HOUR)))
(number->string
(duration->hours
(org-time-duration org-timestamp-1
org-timestamp-2)))
#+end_src
~~~~
The source block is named "allinone", because I tried previously with :noweb yes and referencing other code blocks to be included, but thought that perhaps org-sbe does not deal well with :noweb yes, so I wanted to make sure to keep everything in one source block.
The variables org-timestamp-1 and org-timestamp-2 are referenced at the bottom of the code.
The code runs find in run-guile for example, when I replace the 2 variables with the default values of the variables, given in the header argument :var, as you can see in this transcript:
~~~~
GNU Guile 3.0.5
Copyright (C) 1995-2021 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
scheme@(guile-user)> (import (srfi srfi-19))
(define SECOND 1)
(define MINUTE (* 60 SECOND))
(define HOUR (* 60 MINUTE))
(define org-timestamp-format "[~Y-~m-~d ~a ~H:~M]")
(define duration->time-utc
(λ (duration)
(make-time time-utc
(time-nanosecond duration)
(time-second duration))))
(define org-timestamp->time-utc
(λ (timestamp-string)
(let ([parsed-date (string->date timestamp-string org-timestamp-format)])
(date->time-utc parsed-date))))
(define org-time-duration
(λ (org-timestamp-1 org-timestamp-2)
(time-difference (org-timestamp->time-utc org-timestamp-2)
(org-timestamp->time-utc org-timestamp-1))))
(define duration->org-timestamp
(λ (duration)
(time-utc->date
(duration->time-utc duration)
;; timezone offset, assume all with no offset
0)))
(define duration->hours
(λ (duration)
(/ (time-second duration) HOUR)))
scheme@(guile-user)> (define org-timestamp-1 "[2021-01-01 Fri 00:00]")
scheme@(guile-user)> (define org-timestamp-2 "[2021-01-01 Fri 01:00]")
scheme@(guile-user)> (number->string
(duration->hours
(org-time-duration org-timestamp-1
org-timestamp-2)))
$2 = "1"
scheme@(guile-user)>
~~~~
This code assumes, that I have to convert to a string at the end, to make a good return value for org-mode spreadsheets.
Then I have this table in my document:
~~~~ | | timestamp 1 | timestamp 2 | result | |---+------------------------+------------------------+--------| | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:55] | | | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | nil | | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | | #+TBLFM: $4='(org-sbe "allinone" (org-timestamp-1 $2) (org-timestamp-2 $3)) ~~~~
The one nil is from one time, when I answered "no" to the question, whether I want to run the associated source block:
~~~~ Evaluate this emacs-lisp code block on your system? (yes or no) ~~~~
What is weird is, that it asks about an emacs-lisp code block, while my block is a scheme block, which is set to GNU Guile on my Emacs.
When I answer "yes" instead, I get an error pasted into my table, destroying its structure:
~~~~
| | timestamp 1 | timestamp 2 | result |
|---+------------------------+------------------------+---------------------------------------------------------|
| # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:55] | ice-9/boot-9.scm:1669:16: In procedure raise-exception: |
In procedure open-input-string: Wrong type argument in position 1: (#{2021-03-14}# Sun #{03:55}#)
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> |
| # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | nil |
| # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | |
#+TBLFM: $4='(org-sbe "allinone" (org-timestamp-1 $2) (org-timestamp-2 $3))
~~~~
Knowing, that the code worked just fime in Geiser, I wonder what the problem is. I also only get that output, when I set the header arg :results of the source block to `output`. When I set :results to `value`, then I get simply no result at all.
To check, whether the same version of GNU Guile is running in whatever org-sbe runs as is running in Geiser, I replace the whole source block code with the following:
~~~~ (version) ~~~~
And it fills in the following:
~~~~ | | timestamp 1 | timestamp 2 | result | |---+------------------------+------------------------+---------| | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:55] | "3.0.5" | | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | nil | | # | [2021-03-14 Sun 03:50] | [2021-03-14 Sun 03:50] | | #+TBLFM: $4='(org-sbe "allinone" (org-timestamp-1 $2) (org-timestamp-2 $3)) ~~~~
I have put the minimal org file with my code on https://notabug.org/ZelphirKaltstahl/guile-examples/raw/488b4a73c3fc4c505a95c904402cbaeeeddd330c/time/minimal.org
How can I get my time calculating code working?
What am I doing wrong?
Best regards,
Zelphir
-- repositories: https://notabug.org/ZelphirKaltstahl
| [Prev in Thread] | Current Thread | [Next in Thread] |