YAT - yet another template strategy

| categories: emacs, orgmode | 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