;;; rcd-template.el --- template ;; -*- lexical-binding: t; -*- ;;; Commentary: ;; ;;; Code: (defvar rcd-template-delimiter-open "⟦") (defvar rcd-template-delimiter-close "⟧") (defun rcd-template-eval (string &optional delimiters) "Evaluates Emacs Lisp enclosed by `rcd-template-delimiter-open' and `rcd-template-delimiter-close'. Optional DELIMITERS list may be provided to change default delimiters, first list member has to be the opening delimiter and second the closing delimiter. Space or new line has to follow `rcd-template-delimiter-open' and precede `rcd-template-delimiter-close' for evaluation to get invoked." (let* ((delimiters (or delimiters (list rcd-template-delimiter-open rcd-template-delimiter-close))) (open (car delimiters)) (close (cadr delimiters))) (with-temp-buffer (insert string) (goto-char 0) (while (re-search-forward (rx (literal open) (one-or-more (or blank "\n")) (group (minimal-match (one-or-more anything))) (one-or-more (or blank "\n")) (literal close)) nil t) ;;(message "Found match") (let* ((lisp (car (read-from-string (buffer-substring-no-properties (1+ (match-beginning 0)) (1- (match-end 0)))))) (value (condition-case nil (eval lisp) (error ""))) (value (string-or-empty-string value))) ;; (message "HELLO: %s" (eval (format "%s" hello-name))) (delete-region (match-beginning 0) (match-end 0)) (insert (format "%s" value)))) (buffer-string)))) (defun rcd-template-buffer-eval () (interactive) (let* ((buffer (buffer-string)) (mode major-mode) (point (point))) (pop-to-buffer-same-window "Preview") (insert (rcd-template-eval buffer)) (goto-char point) (funcall mode) (espeak "Preview"))) (defun string-or-empty-string (i) "Returns empty string for nil" (let* ((type (type-of i))) (cond ((or (eql type 'integer) (eql type 'float)) (number-to-string i)) ((null i) "") ((eql type 'symbol) (prin1-to-string i)) ((eql type 'string) i)))) (provide 'rcd-template) ;;; rcd-template.el ends here