-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: yonkeltron <yonkeltron@gmail.com>
- Loading branch information
0 parents
commit addc4c0
Showing
3 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |