aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md41
-rw-r--r--builtin.lisp18
-rwxr-xr-xtemper.lisp30
3 files changed, 74 insertions, 15 deletions
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)) %>
+<ul>
+ <% (dotimes (_ 10)) %>
<li> <%= i %> </li>
-<% ) %>
+ <% ) %>
+</ul>
+```
+
+Use the `render` function to include a template in another.
+
+```html
+<% (render "header.lisp.html") %>
+<p>that's pretty neat</p>
+<% (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</~A>"
+ surrounding-tag
+ (format nil "~{~A~%~}"
+ (mapcar #'(lambda (filepath)
+ (let* ((filename (file-namestring filepath))
+ (name filename))
+ (format nil "<~A><a href=\"~A/~A\">~A</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"))