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 version = 8.2.10