リスト2
(define (render path params)
(let* ((conn (dbi-connect "dbi:sqlite3:alih.db"))
(pos (cgi-get-parameter "pos" params))
(res
(if (and pos (rxmatch #/^[DFG]$/ pos))
(dbi-do conn "SELECT no, name, g FROM player where pos=? order by no"
'() pos)
(dbi-do conn "SELECT no, name, g FROM player order by no")))
(getter (relation-accessor res)))
(dbi-close conn)
(template "list.tmpl" res getter)))
(define-macro (template tmpl-file . args)
@(templ-render ,tmpl-file (quote ,args) (list ,@args)))
(define (templ-render templ-file vars args)
(apply (eval (read-from-string (templ-func templ-file vars)) (interaction-environment))
args))
(define (templ-func templ-file vars)
(read-from-string
#@"(lambda ,vars
(let1 port (open-output-string)
,(expand-templ (file->string templ-file))
(get-output-string port)))"))
(define (expand-templ templ)
(cond ((#/(.*?)<%=(.*?)%>(.*)/ templ)
=> (lambda(m)
#@",(expand-templ (m 1)) (display ,(m 2) port) ,(expand-templ (m 3))"))
((#/(.*?)<%(.*?)%>(.*)/ templ)
=> (lambda(m)
#@",(expand-templ (m 1)) ,(m 2) ,(expand-templ (m 3))"))
(else (format "(display ~s port)" templ))))