0

I'm trying to transform the data from one table to another however I can't do it with built in functions so I have to use org-sbe to call some elisp:

#+tblname: clues
|  02a8 |  0050 |  5012 |  2225 |  9555 |

#+name: hex-word-to-bitmap
#+begin_src emacs-lisp :var hex='02a8
  (let ((res "")
        (number (string-to-number (prin1-to-string hex) 16)))
      (while (not (= number 0))
        (setq res (concat (if (= 1 (logand number 1)) "1" "0") res))
        (setq number (lsh number -1)))
      (if (string= res "")
          (setq res "0"))
      res))
#+end_src

The end result is not every number is converted when I apply the following table formula:

#+tblname: hex-to-bitmap
| #ERROR | 1010000 | 101000000010010 | 10001000100101 | 1011110 |
#+TBLFM: @<$<..@>$>='(org-sbe hex-word-to-bitmap (hex (identity remote(clues,@@#$$#))))

I thought identity should pass along the data unmolested but I don't seem to be able to get it to work. What am I doing wrong?

  • It's no coincidence that the numbers causing this failure contain the hex digits a-f. – NickD Sep 24 '18 at 18:22
1

The problem is that prin1-to-string doesn't know what to do with 02a8: it thinks it's a variable. Any hex digit other than 0-9 would cause the same problem. If you quote it, it works.

Obviously, the transformations that happen when you take a string out of a buffer and mangle it through org-sbe and in various other unnatural ways to produce another string that will be inserted somewhere else, are not obvious :-)

In this particular case, instead of using org-sbe with a code block, I would write a lisp function to do the transformation and evaluate the code block to add the function to the interpreter. Then reevaluate the formulas. Something like this:

#+tblname: clues
|  02a8  |  0050 |  5012 |  2225 |  9555 | abcd |

#+begin_src emacs-lisp
  (defun hex-to-bin (hex)
    (let ((res "")
          (number (string-to-number hex 16)))
      (while (not (= number 0))
        (setq res (concat (if (= 1 (logand number 1)) "1" "0") res))
        (setq number (lsh number -1)))
      (if (string= res "")
          (setq res "0"))
      res))
#+end_src

#+RESULTS:
: hex-to-bin

#+tblname: hex-to-bitmap-table
| 1010101000 | 1010000 | 101000000010010 | 10001000100101 | 1001010101010101 | 1010101111001101 |
#+TBLFM: @<$<..@>$>='(hex-to-bin remote(clues,@@#$$#))

You can debug the function independently, use a debugger on it if things get hairy and when it's ready, you can use it in the table formula without worrying (too much) about hidden conversions.

  • In the end I gave up on forcing org-sbe to do the inplace thing and instead fed the table directly to an org-babel code block (as I was transforming the whole table). In previous exercises like this I usually had a cell which was a copy of the remote cell and then operated on that. I'm not sure if that would have made a difference. – stsquad Sep 25 '18 at 14:54

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.