Common Lisp embedded template engine
#include <stdio.h>
int main(void) {
#{ :indent
(loop :for i :from 0 :below 10
:do (format t "printf(\"Loop: %d\", ~D);~%" i)) #}
return 0;
}
(lisp-preprocessor:run-template-into-file #p"input" #p"output")
#include <stdio.h>
int main(void) {
printf("Loop: %d", 0);
printf("Loop: %d", 1);
printf("Loop: %d", 2);
printf("Loop: %d", 3);
printf("Loop: %d", 4);
printf("Loop: %d", 5);
printf("Loop: %d", 6);
printf("Loop: %d", 7);
printf("Loop: %d", 8);
printf("Loop: %d", 9);
return 0;
}
(let ((compiland (compile-template "#{ (princ (string-capitalize $arg)) #}" :arguments '($arg))))
(run-template-into-string compiland "test"))
; => "Test"
compiland is a string or pathname, or a compiled template function.
* (compile-template "foo #{ (princ \"bar\") #} baz") ; => #<FUNCTION (LAMBDA (#:STREAM)) {...}>
* (run-template-into-stream * *standard-output*)
foo bar baz
* (compile-template "foo {{{ (princ \"bar\" }}} baz" :template-begin "{{{" :template-end "}}}")
* (run-template-into-stream * *standard-output*)
foo bar baz
* (run-template-into-stream (compile-template "#{ (princ (list ? ??)) #}" :arguments '(? ??)) *standard-output* "foo" "bar")
(foo bar)
#{ template #}
Keep indentation of start position
#{ :indent [offset]
...
#}
// input
int main(void) {
#{ :indent
(loop :for i :from 0 :below 10
:do (format t "printf(\"Loop: %d\", ~D);~%" i)) #}
return 0;
}
// output
int main(void) {
printf("Loop: %d", 0);
printf("Loop: %d", 1);
printf("Loop: %d", 2);
printf("Loop: %d", 3);
printf("Loop: %d", 4);
printf("Loop: %d", 5);
printf("Loop: %d", 6);
printf("Loop: %d", 7);
printf("Loop: %d", 8);
printf("Loop: %d", 9);
return 0;
}
Chop whitespace before and after the template
#{ :chop #}
;;; input
(defun foo (#{ (format t "~{~(~A~)~^ ~}" (loop :for symbol :in '(a b c) :collect symbol)) #}
#{ :chop #}
#{ (format t " ~{~(~A~)~^ ~}" (loop :for symbol :in '(x y z) :collect symbol)) #})
(values a b c x y z))
;;; output
(defun foo (a b c x y z)
(values a b c x y z))
MIT