Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: yonkeltron <yonkeltron@gmail.com>
  • Loading branch information
yonkeltron committed Jul 22, 2012
0 parents commit addc4c0
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*~
74 changes: 74 additions & 0 deletions terrible-template-test.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
(require 'ert)
(require 'terrible-template)

(ert-deftest terrible-template-make-interpolation-token ()
"Test regex generation"
(should
(equal
(terrible-template-make-interpolation-token "panda")
"{{TERRIBLE_TEMPLATE_VARIABLE=< panda >=TERRIBLE_TEMPLATE_VARIABLE}}"))
(should
(equal
(terrible-template-make-interpolation-token "bamboo")
"{{TERRIBLE_TEMPLATE_VARIABLE=< bamboo >=TERRIBLE_TEMPLATE_VARIABLE}}"))
(should
(equal
(terrible-template-make-interpolation-token "curry-noodle")
"{{TERRIBLE_TEMPLATE_VARIABLE=< curry-noodle >=TERRIBLE_TEMPLATE_VARIABLE}}")))

(ert-deftest terrible-template-object-to-string-conversion ()
"Test object-to-string conversion"
(should
(equal
(terrible-template-convert-to-safe-string 'panda)
"panda"))
(should
(equal
(terrible-template-convert-to-safe-string :panda)
"panda"))
(should
(equal
(terrible-template-convert-to-safe-string "panda")
"panda"))
(should
(equal
(terrible-template-convert-to-safe-string 123)
"123")))

(ert-deftest terrible-template-substitution ()
(let ((test-template-string "{{TERRIBLE_TEMPLATE_VARIABLE=< panda >=TERRIBLE_TEMPLATE_VARIABLE}}"))
(should
(equal
(terrible-template-substitute test-template-string '("panda" "bamboo"))
"bamboo"))
(should
(equal
(terrible-template-substitute test-template-string '("panda" "amazing string"))
"amazing string"))))

(ert-deftest terrible-template-compile-template-test ()
(let ((name '("panda"))
(tags '("panda" "bamboo")))
(should
(equal
(plist-get (terrible-template-compile-template (list name tags)) :template-string)
"panda"))
(should
(equal
(plist-get (terrible-template-compile-template (list name tags)) :template-variables)
tags))))

(ert-deftest terrible-template-valid-template-variable-pair-p-test ()
(let ((valid-pair '(var "panda"))
(invalid-pair '(panda "crack"))
(another-invalid-pair '(panda)))
(should
(terrible-template-valid-template-variable-pair-p valid-pair))
(should
(not (terrible-template-valid-template-variable-pair-p invalid-pair)))
(should
(not (terrible-template-valid-template-variable-pair-p another-invalid-pair)))
(should
(not (terrible-template-valid-template-variable-pair-p "panda")))
(should
(not (terrible-template-valid-template-variable-pair-p '(var 1 2 3))))))
98 changes: 98 additions & 0 deletions terrible-template.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
(defvar *terrible-template-global-template-list* (make-hash-table :test 'equal))

(defconst terrible-template-config
'(:variable-start-string "{{TERRIBLE_TEMPLATE_VARIABLE=< "
:variable-end-string " >=TERRIBLE_TEMPLATE_VARIABLE}}"))

(defun terrible-template-make-interpolation-token (variable-name)
"Create and format interpolation token for variable-name"
(concat (plist-get terrible-template-config :variable-start-string)
(terrible-template-convert-to-safe-string variable-name)
(plist-get terrible-template-config :variable-end-string)))

(defun terrible-template-valid-template-variable-pair-p (pair)
"Determine whether or not a sexp constitutes a valid template variable pair"
(terrible-template-log (concat "Checking validity of variable pair " (prin1-to-string pair t)))
(and (listp pair)
(equal
(car pair)
'var)
(equal
(length pair)
2)))

(defun terrible-template-log (msg)
"Logs MSG to the *terrible-template-output* buffer"
(get-buffer-create "*terrible-template-output*")
(with-current-buffer "*terrible-template-output*"
(setq buffer-read-only nil)
(insert (concat (prin1-to-string msg) "\n"))
(setq buffer-read-only t)))

(defun terrible-template-error(message)
(terrible-template-log (concat "Error: " message))
(error message))

(defun terrible-template-convert-to-safe-string (obj)
"Turn whatever key (symbol keyword, number or string) into a regex-safe string"
(cond ((stringp obj) obj)
((keywordp obj) (substring (symbol-name obj) 1))
((symbolp obj) (symbol-name obj))
((numberp obj) (number-to-string obj))
(t (terrible-template-error
(concat "Unable to convert to string safely: "
(prin1-to-string obj))))))

(defun terrible-template-compile-template (structure)
"Transform macro-parsed structure into a safe-to-serialize "
(list :template-string (apply 'concat (reverse (car structure)))
:template-variables (cadr structure)))

(defun terrible-template-store-template (template-name template-structure)
"Store template object in global template store"
(puthash template-name
(terrible-template-compile-template template-structure)
*terrible-template-global-template-list*))

(defun terrible-template-substitute (template-string key-value-pair)
"Actually perform substitution on template-string with key-value-pair"
(replace-regexp-in-string (terrible-template-make-interpolation-token (car key-value-pair))
(cadr key-value-pair)
template-string))

(defun terrible-template-apply-template (template-string &rest key-value-pairs)
(terrible-template-log (concat "Key value pairs: " (prin1-to-string key-value-pairs t)))
(reduce 'terrible-template-substitute
(car key-value-pairs)
:initial-value (copy-sequence template-string)))

(defun terrible-template-insert (template-name)
(interactive "sTemplate Name: ")
(terrible-template-log (concat "Inserting template: " (prin1-to-string template-name t)))
(let ((template-object (gethash template-name *terrible-template-global-template-list*)))
(insert (terrible-template-apply-template
(plist-get template-object :template-string)
(terrible-template-prompt-for-variables
(plist-get template-object :template-variables))))))

(defun terrible-template-prompt-for-variables (template-variables)
"Prompt user for variables values"
(terrible-template-log (concat "Prompting for variables " (prin1-to-string template-variables t)))
(mapcar (lambda (variable)
(list variable (read-string (concat variable ": "))))
template-variables))

(defmacro defterrible (template-name &rest template-body)
(let ((contents nil)
(tags nil))
(mapcar (lambda (obj)
(cond ((stringp obj) (push obj contents))
((terrible-template-valid-template-variable-pair-p obj)
(let ((var-name (terrible-template-convert-to-safe-string (cadr obj))))
(push (terrible-template-make-interpolation-token var-name) contents)
(push var-name tags)))
(t (terrible-template-error (concat "Template Error" (prin1-to-string obj t))))))
template-body)
`(terrible-template-store-template ,template-name (list ',contents ',tags))))

(provide 'terrible-template)

0 comments on commit addc4c0

Please sign in to comment.