From d3c3ae47a2937bf0ace994a4bc9928cd2f3605de Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Mon, 11 Jan 2021 18:18:48 +0100 Subject: Added make-index builtin --- README.md | 41 ++++++++++++++++++++++++++++++++++++++--- builtin.lisp | 18 ++++++++++++++++++ temper.lisp | 30 ++++++++++++++++++------------ 3 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 builtin.lisp diff --git a/README.md b/README.md index b317020..c8feed5 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,51 @@ # temper -Common Listp templating language. +Common Listp templating engine inspired by [ejs](https://ejs.co/). ## Usage +### From the command line + +```command +$ ./temper.lisp template.lisp.html > generated.html +``` + +```command +$ ./temper.lisp template_directory +``` + +### In the template + +You can put any Common lisp code between `<%` and `%>`. +Put the result of a form in the template with `<%=`. + ```html -<% (loop :for i in '(1 2 3)) %> + +``` + +Use the `render` function to include a template in another. + +```html +<% (render "header.lisp.html") %> +

that's pretty neat

+<% (render "footer.lisp.html") %> ``` ## TODO * [x] value interpolation (e.g `<%= link %>`) * [x] inject variable in local scope +* [x] auto index function from directory name + * [ ] add date support + * [ ] sort by date + * [ ] hook for setting link name +* [ ] relative path from the file and the current directory +* [ ] walk down a directory and generate all templates +* [ ] link generator `<%= (link 'about') %>` returns `about.html` + and check if `about.lisp.html` exists +* [ ] Makefile to compile and install +* [ ] escape interpolated value diff --git a/builtin.lisp b/builtin.lisp new file mode 100644 index 0000000..3da200e --- /dev/null +++ b/builtin.lisp @@ -0,0 +1,18 @@ +(load "/home/charles/.clisprc.lisp") +(ql:quickload "uiop") + + +(defun make-index (dirname &key (item-tag "li") (surrounding-tag "ul") (include-date nil)) + (setf filepaths (uiop:directory-files dirname)) + ; (when test (delete-if #'(lambda (x) (not (test x))) filenames)) + (format nil "<~A>~A" + surrounding-tag + (format nil "~{~A~%~}" + (mapcar #'(lambda (filepath) + (let* ((filename (file-namestring filepath)) + (name filename)) + (format nil "<~A>~A" item-tag dirname filename name item-tag))) + filepaths)) + surrounding-tag)) + +; (uiop:run-program (list "seq" "10" "20") :output t) diff --git a/temper.lisp b/temper.lisp index 2bd63cc..9f5350c 100755 --- a/temper.lisp +++ b/temper.lisp @@ -1,7 +1,8 @@ -#!/usr/bin/env clisp +#!/usr/bin/clisp (load "helper.lisp") (load "config.lisp") +(load "builtin.lisp") (defun lex (input) @@ -22,6 +23,9 @@ (lex input)))))) +; (defun temper-buf-push (&rest strings) +; (setf *temper-buf + (defun tokens-to-code-string (tokens) (apply #'concatenate 'string (map @@ -29,25 +33,26 @@ #'(lambda (token) (let ((token-type (first token)) (token-content (second token))) - (cond - ((eql token-type 'code) token-content) - ((eql token-type 'interpolation) + (ecase token-type + ('code token-content) + ('interpolation (format nil "~S" - `(setf buf + `(setf *temper-buf* (concatenate 'string - buf + *temper-buf* (format nil "~A" ,(read-from-string token-content)))))) - ((eql token-type 'string) + ('string (format nil "~S" - `(setf buf - (concatenate 'string buf ,(string-trim '(#\linefeed) token-content)))))))) + `(setf *temper-buf* + (concatenate 'string *temper-buf* ,(string-trim '(#\linefeed) token-content)))))))) tokens))) +(defvar *temper-buf* "") + (defun generate (tokens &rest args) `(let ,(apply #'rest-keys args) (progn - (setq buf "") (eval ,(read-from-string (concatenate 'string "(progn " @@ -63,7 +68,8 @@ (with-open-file (stream filename) (apply #'render-stream (cons stream args)))) +(princ (render-stream *standard-input* 'foo "bon" 'bar "jour")) -; (princ (render-stream *standard-input* 'foo "bon" 'bar "jour")) +; (princ (render "test.html" 'foo "bon" 'bar "jour")) -(princ (render "test.html" 'foo "bon" 'bar "jour")) +; (print (make-index "d")) -- cgit