emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* org source block execute not working correctly with GNU Guile source block?
@ 2021-03-14 15:28 Zelphir Kaltstahl
  2021-03-14 15:32 ` Zelphir Kaltstahl
  0 siblings, 1 reply; 2+ messages in thread
From: Zelphir Kaltstahl @ 2021-03-14 15:28 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 7001 bytes --]

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
<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
<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


[-- Attachment #2: Type: text/html, Size: 7869 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: org source block execute not working correctly with GNU Guile source block?
  2021-03-14 15:28 org source block execute not working correctly with GNU Guile source block? Zelphir Kaltstahl
@ 2021-03-14 15:32 ` Zelphir Kaltstahl
  0 siblings, 0 replies; 2+ messages in thread
From: Zelphir Kaltstahl @ 2021-03-14 15:32 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 7665 bytes --]

Ah, I am sorry, I forgot to include basic information:

Emacs installed via GNU Guix:

GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.24, cairo version 1.16.0)

Org:

org, 9.3, built-in

On 3/14/21 4:28 PM, Zelphir Kaltstahl wrote:
>
> 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
> <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
> <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

-- 
repositories: https://notabug.org/ZelphirKaltstahl


[-- Attachment #2: Type: text/html, Size: 8727 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-03-14 15:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-14 15:28 org source block execute not working correctly with GNU Guile source block? Zelphir Kaltstahl
2021-03-14 15:32 ` Zelphir Kaltstahl

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).