New Publication in International Journal of Greenhouse Gas Control

| categories: publication, news | tags:

We have published a new paper on CO2 capture in aqueous amino acid solvents! In this collaborative effort with the Anna Research group and NETL, we show that potassium lysinate solvents show potential for CO2 capture applications using a microfluidic characterization device and a continuously stirred tank reactor. We also examined the aqueous potassium salts of glycine, taurine and proline. Raman spectroscopy was used to characterize the speciation of CO2 in the solvent. Congratulations Alex!

@article{hallenbeck-2015-compar-co2,
  author =       "Alexander P. Hallenbeck and Adefemi Egbebi and Kevin P. Resnik
                  and David Hopkinson and Shelley L. Anna and John R. Kitchin",
  title =        {Comparative Microfluidic Screening of Amino Acid Salt
                  Solutions for Post-Combustion \ce{CO2} Capture},
  journal =      "International Journal of Greenhouse Gas Control ",
  volume =       43,
  pages =        "189 - 197",
  year =         2015,
  doi =          {10.1016/j.ijggc.2015.10.026},
  url =
                  "http://www.sciencedirect.com/science/article/pii/S1750583615301134",
  issn =         "1750-5836",
}

See it here: http://www.sciencedirect.com/science/article/pii/S1750583615301134

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter

Clickable telephone numbers in mu4e messages

| categories: emacs | tags:

We recently updated our university phone system to a VoIP system that uses Cisco Jabber. I am excited about that because finally I can make phone calls from Emacs with a little applescript automation! So, spoiler alert, this post mostly only applies to Macs, unless you know how to automate a Jabber client to make calls. How to make the telephone numbers clickable is general though, and could be used to do other things as well.

(defun cisco-call (phone-number)
  (interactive "sPhone number: ")
  (do-applescript
   (format "tell application \"Cisco Jabber\"
        activate
        tell application \"System Events\" to keystroke \"n\" using {shift down, command down}
        tell application \"System Events\" to keystroke \"%s\"
        tell application \"System Events\" to key code 36 #return
end tell" phone-number)))
cisco-call

I would like to go a step further, and make clickable phone numbers in my Emacs buffers. Let's take a look at some options.

1 org-mode phone link

This is a no-brainer approach. We can define an org-mode link that runs the cisco-call function.

(org-add-link-type
 "phone"
 (lambda (phone-number)
   (cisco-call phone-number)))
lambda (phone-number) (cisco-call phone-number)

This makes simple link that just calls the number in the path of the link.

2 Clickable text with button-lock

I have used the button-lock package very often to make clickable text. Here we use it to highlight phone numbers matching a regular expression that seems to match most US numbers. This seems to work great in org-mode buffers.

(require 'rx)

(defvar highlight-phone-numbers nil
 "Button for `highlight-phone-numbers'")

(defun highlight-phone-numbers ()
  "Make phone numbers of the following types clickable:
  (xxx) xxx-xxxx
  xxx.xxx.xxx
  xxxxxxxxxx
  xxx-xxx-xxxx"
  (interactive)
  (let ((inhibit-read-only t))
    (setq highlight-phone-numbers
          (button-lock-set-button
           (rx
            ;; optional () around area code
            (optional "(")
            (= 3 digit)
            (optional ")")
            ;; delimiters
            (or (optional "-")
                (optional ".")
                (optional " "))
            (= 3 digit)
            (or (optional "-")
                (optional ".")
                (optional " "))
            (= 4 digit))
           (lambda ()
             (interactive)
             (cisco-call (get-surrounding-text-with-property 'phone-number)))
           :face '((:background "Darkolivegreen2")
                   (:underline t))
           :help-echo "click to call"
           :keyboard-binding (kbd "RET")
           :additional-property 'phone-number))))

(add-hook 'text-mode 'highlight-phone-numbers)
highlight-phone-numbers

3 Phone numbers in mu4e messages

For some reason, the button-lock package doesn't seem to work in mu4e message buffers, Maybe it is because . The highlight-regexp package does work though, so for these special buffers we use a new approach. We will just put text properties where we want them, and use those properties to make the text clickable.

The messages are in read-only buffers, but we can inhibit that so we can modify the properties. All we need to do is create a little key map as a copy of the existing map, define some keys on it, then search through the buffer adding properties to every phone number we find. I wrote a function that does that, and put that function in a hook to run each time I open a message. Whammo, now I have clickable phone numbers in email! It works pretty well for me.

(defface mu4e-phone-face
  '((t (:foreground "SteelBlue4" :background "Darkolivegreen2" :underline t)))
  "Phone number directive face.")

(defun mu4e-highlight-phone-numbers ()
  "Make phone numbers clickable in mu4e-view buffers."
  (interactive)
  (let ((phone-regex (rx
                      ;; optional () around area code
                      (optional "(")
                      (= 3 digit)
                      (optional ")")
                      ;; delimiters
                      (or (optional "-")
                          (optional ".")
                          (optional " "))
                      (= 3 digit)
                      (or (optional "-")
                          (optional ".")
                          (optional " "))
                      (= 4 digit))))
    (save-excursion
      (let ((inhibit-read-only t))
        (goto-char (point-min))
        (while (re-search-forward phone-regex nil t)
          (let ((map (copy-keymap mu4e-view-mode-map))
                (start (match-beginning 0))
                (end (match-end 0)))

            ;; set file to be clickable to open the source
            (define-key map [mouse-1]
              `(lambda ()
                 (interactive)
                 (cisco-call ,(match-string 0))))

            ;; let letter c also make the call
            (define-key map "c"
               `(lambda ()
                 (interactive)
                 (cisco-call ,(match-string 0))))

            (set-text-properties
             start end
             `(local-map, map
                          face mu4e-phone-face
                          mouse-face highlight
                          help-echo "mouse-1: click to call"))))))))

(add-hook 'mu4e-view-mode-hook 'mu4e-highlight-phone-numbers)

4 Summary

That works pretty well for me overall. The phone number regex is not perfect, e.g. it makes any 10 digit number clickable, and it doesn't recognize international numbers. I am not sure I can call those through the Jabber client anyway. This is purely convenience for me to easily make calls from emails, or other kinds of documents I might read in Emacs.

I don't use phone calls very often, but an interesting thing might be to open a phone log in org-mode, or open the contact that has that phone number to log that you called them, and provide some notes for them. Alternatively, open a new capture for a phone log that could be refiled later.

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter

YAT - yet another template strategy

| categories: orgmode, emacs | tags:

I have another need for a template that is dynamically evaluated. I previously wrote about this here , and today I am going to do a variation of the theme. We will still use a syntax of $(expression), but a new approach to evaluating the expression. I saw this interesting function to evaluate and replace an s-expression in a buffer Eval and Replace - Emacs Redux . I am going use that to replace a template expression in a string, with a little variation to avoid replacing non-sexp variations, e.g. $(. Here we go.

(defun eval-and-replace ()
  "Replace the preceding sexp with its value."
  (interactive)
  (backward-kill-sexp)
  (condition-case nil
      (princ (eval (read (current-kill 0)))
             (current-buffer))
    (error (message "Invalid expression")
           (insert (concat "$" (current-kill 0))))))

(defun j-format (s)
  "Replace all instances of $(expression) in S with the evaluated
expression."
  (with-temp-buffer
    (insert s)
    (goto-char (point-min))
    (while (re-search-forward "$(" nil t)
      (backward-char)
      (when (sexp-at-point)
        ;; get rid of the $
        (delete-char -1)
        ;; go to the end of the sexp and then eval-and-replace it.
        (end-of-sexp)
        (eval-and-replace)))
    ;; return the formatted text.
    (buffer-string)))


(let ((some-var "You got me"))
  (j-format "Test of 4 + 5 = $(+ 4 5). $(  $(foobar). $(progn (setq x 5) \"\")
and then we have 2x=$(prin1 (* 2 x)).

some-var = $(print some-var)"))
Test of 4 + 5 = 9. $(  $(foobar).
and then we have 2x=10.

some-var = You got me

That seems pretty ok. I obviously have not tested it extensively, but it looks pretty promising.

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter

Saving the current restriction and restoring it while following links

| categories: orgmode, emacs | tags:

On the org-mode mailing list there has been some discussion about following id links. The issue is that if your buffer is narrowed, clicking on the link does not change the restriction to actually take you to the entry. This is debatably desirable. If I click on a link, I want it to go where it points. But, I might also like to go back to my narrowed view. So here consider how to save the state of narrowing, and restore it. We modify the function that opens an id link to save the restriction, and widen the buffer if necessary.

Saving the restriction seems easy, we just save a marker to point, and the point-min and point-max. We save the marker for a convenient way to get the buffer, and perhaps the actual point. We advise the C-c & function to restore the restriction after we leave it. This should fix the restriction in whatever buffer we undid it in.

Here is the code that seems to work for me. Thanks to Rasmus for the idea on saving the restriction data.

(defvar *saved-restriction* nil
 "A global var containing the current restriction.
Returns (current-buffer point-min point-max")

(defun save-current-restriction ()
  "Save the current restriction at point."
  (setq *saved-restriction*
        (if (buffer-narrowed-p)
            (list (current-buffer) (point-min) (point-max))
          nil)))

(defun restore-saved-restriction ()
  "Restore the last saved restriction."
  (when *saved-restriction*
    (set-buffer (car *saved-restriction*))
    (narrow-to-region (nth 1 *saved-restriction*)
                      (nth 2 *saved-restriction*)))
  (setq *saved-restriction* nil))

;' actually modify this function to save the restriction, and widen if needed.
(defun org-id-open (id)
  "Go to the entry with id ID."
  (org-mark-ring-push)
  (let ((m (org-id-find id 'marker))
        cmd)
    (unless m
      (error "Cannot find entry with ID \"%s\"" id))
    ;; Use a buffer-switching command in analogy to finding files
    (setq cmd
          (or
           (cdr
            (assq
             (cdr (assq 'file org-link-frame-setup))
             '((find-file . switch-to-buffer)
               (find-file-other-window . switch-to-buffer-other-window)
               (find-file-other-frame . switch-to-buffer-other-frame))))
           'switch-to-buffer-other-window))
    (if (not (equal (current-buffer) (marker-buffer m)))
        (funcall cmd (marker-buffer m)))
    (save-current-restriction)
    (when (> m (point-max))
      (widen))
    (goto-char m)
    (move-marker m nil)
    (org-show-context)))


;; And we advise the function going back to restore the restriction.
(defadvice org-mark-ring-goto (after restore-my-restriction () activate)
  "Restore narrowing."
  (restore-saved-restriction))
org-mark-ring-goto

This seems to preserve restrictions in the current buffer and in other buffers, as long as I use C-c & to invoke org-mark-ring goto. I am not sure how easy it would be to make this work for all links. Each link has its own function for following so I am not sure we can easily get them all to do this unless there is some high level function to advise like org-mouse-down-mouse or something similar. It also has the limitation that the restoration only occurs using org-mark-ring-goto, unless you specifically run the (restore-saved-restriction) function yourself. That could be made an interactive function for that purpose. Otherwise, this seems like a reasonable approach.

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter

Line numbers in org-mode code blocks

| categories: orgmode, emacs | tags:

Some of my students have wanted to show line numbers in code blocks. This is especially useful for when you run a Python block, and you get an error message with a line number in it. Right now, to figure out which line that is, you have to into the code block, type C-c ' to get into edit mode, and turn line numbers on. We look into how to achieve that here.

You may want to see the video here: https://www.youtube.com/watch?v=kinWijGzXms .

First, we need to get the region that is the code block. We can find some info in the org-element, but, the :begin and :end include lines we don't want, like the header lines, and the results. But, we can get the beginning, and maybe from there search forward to the block. Run this code block to see where the point goes.

;; a boring comment

(progn
  (+ 40 2))

(goto-char (org-element-property :begin (org-element-context)))
(re-search-forward (regexp-quote (org-element-property :value (org-element-context))))
(goto-char (match-beginning 0))
;; number of lines in block. The last carriage return doesn't count.
(1- (length (s-split "\n" (org-element-property :value (org-element-context)))))
9

So, we can get the number of lines, and move the point to the first line. For numbers, we will use overlays. Here is a simple way to put a number at the beginning of a line.

(let (ov)
  (beginning-of-line)
  (setq ov (make-overlay (point) (point)))
  (overlay-put ov 'before-string "1"))
1

The next thing to do is make a function that puts a number at the beginning of a line. We might as well store these overlays in a variable, so they are easy to remove later. This is just for exploration of how to do it. Later we combine all these pieces together.

(defvar number-line-overlays '()
  "List of overlays for line numbers.")

(make-variable-buffer-local 'number-line-overlays)

(defun number-line (N)
 "Put an overlay at the beginning of a line."
  (beginning-of-line)
  (let (ov)
    (setq ov (make-overlay (point) (point)))
    (overlay-put ov 'before-string (format "%3s" (number-to-string N)))
    (add-to-list 'number-line-overlays ov)))

(number-line 4)
#<overlay from 1782 to 1782 in blog.org>

That looks promising. Let's make a function to clear those overlays. It is so easy it may not even be worth writing.

(defun number-line-clear ()
  (mapc 'delete-overlay number-line-overlays)
  (setq number-line-overlays '()))

(number-line-clear)

Finally, we are ready to hack up the code block numbering code. The numbers will not automatically update, so we will write a function that numbers the block, but only temporarily. Any key press will get rid of the numbers so we can get back to work. I am going to go ahead and make this a stand-alone function and block.

(defvar number-line-overlays '()
  "List of overlays for line numbers.")

(make-variable-buffer-local 'number-line-overlays)

(defun number-line-src-block ()
  (interactive)
  (save-excursion
    (let* ((src-block (org-element-context))
           (nlines (- (length
                       (s-split
                        "\n"
                        (org-element-property :value src-block)))
                      1)))
      (goto-char (org-element-property :begin src-block))
      (re-search-forward (regexp-quote (org-element-property :value src-block)))
      (goto-char (match-beginning 0))

      (loop for i from 1 to nlines
            do
            (beginning-of-line)
            (let (ov)
              (setq ov (make-overlay (point) (point)))
              (overlay-put ov 'before-string (format "%3s" (number-to-string i)))
              (add-to-list 'number-line-overlays ov))
            (next-line))))

  ;; now read a char to clear them
  (read-key "Press a key to clear numbers.")
  (mapc 'delete-overlay number-line-overlays)
  (setq number-line-overlays '()))

(number-line-src-block)

I am not sure how to get the numbers to automatically update smoothly like they do in linum-mode. That code uses a lot of hooks to make updates work, and embeds them in a minor mode to get rid of them. It also puts them in the fringe I think, but it is not clear how that is done.

We could modify what happens after the numbers are put on, e.g. pressing numbers might jump to a line, or some other kind of functionality. I don't have a critical need for this right now, so I didn't explore it more. Let me know if you have any good ideas for it!

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter
« Previous Page -- Next Page »