factor/extra/http/server/templating/fhtml/fhtml.factor

107 lines
2.8 KiB
Factor
Raw Normal View History

2007-09-20 18:09:08 -04:00
! Copyright (C) 2005 Alex Chapman
! Copyright (C) 2006, 2007 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
USING: continuations sequences kernel parser namespaces io
io.files io.streams.lines io.streams.string html html.elements
2007-09-20 18:09:08 -04:00
source-files debugger combinators math quotations generic
2008-02-29 01:57:38 -05:00
strings splitting accessors http.server.static http.server
assocs ;
2007-09-20 18:09:08 -04:00
2008-03-05 22:38:15 -05:00
IN: http.server.templating.fhtml
2007-09-20 18:09:08 -04:00
: templating-vocab ( -- vocab-name ) "http.server.templating" ;
! See apps/http-server/test/ or libs/furnace/ for template usage
! examples
! We use a custom lexer so that %> ends a token even if not
! followed by whitespace
TUPLE: template-lexer ;
: <template-lexer> ( lines -- lexer )
<lexer> template-lexer construct-delegate ;
M: template-lexer skip-word
[
{
{ [ 2dup nth CHAR: " = ] [ drop 1+ ] }
{ [ 2dup swap tail-slice "%>" head? ] [ drop 2 + ] }
2008-02-01 23:47:01 -05:00
{ [ t ] [ f skip ] }
2007-09-20 18:09:08 -04:00
} cond
] change-column ;
DEFER: <% delimiter
: check-<% ( lexer -- col )
2008-02-06 20:23:39 -05:00
"<%" over lexer-line-text rot lexer-column start* ;
2007-09-20 18:09:08 -04:00
: found-<% ( accum lexer col -- accum )
[
2008-02-06 20:23:39 -05:00
over lexer-line-text
>r >r lexer-column r> r> subseq parsed
2007-09-20 18:09:08 -04:00
\ write-html parsed
] 2keep 2 + swap set-lexer-column ;
: still-looking ( accum lexer -- accum )
[
2008-02-06 20:23:39 -05:00
dup lexer-line-text swap lexer-column tail
2007-09-20 18:09:08 -04:00
parsed \ print-html parsed
] keep next-line ;
: parse-%> ( accum lexer -- accum )
dup still-parsing? [
dup check-<%
[ found-<% ] [ [ still-looking ] keep parse-%> ] if*
] [
drop
] if ;
: %> lexer get parse-%> ; parsing
: parse-template-lines ( lines -- quot )
<template-lexer> [
V{ } clone lexer get parse-%> f (parse-until)
] with-parser ;
: parse-template ( string -- quot )
[
use [ clone ] change
templating-vocab use+
string-lines parse-template-lines
] with-scope ;
: eval-template ( string -- ) parse-template call ;
: html-error. ( error -- )
<pre> error. </pre> ;
2007-09-20 18:09:08 -04:00
: run-template-file ( filename -- )
[
[
"quiet" on
2007-09-20 18:09:08 -04:00
parser-notes off
templating-vocab use+
2008-02-26 22:03:14 -05:00
! so that reload works properly
dup source-file file set
2008-02-29 01:57:38 -05:00
?resource-path file-contents
2008-02-26 22:03:14 -05:00
[ eval-template ] [ html-error. drop ] recover
2008-01-11 00:48:04 -05:00
] with-file-vocabs
2008-02-29 01:57:38 -05:00
] curry assert-depth ;
2007-09-20 18:09:08 -04:00
2007-09-21 16:55:39 -04:00
: run-relative-template-file ( filename -- )
2007-11-05 00:46:03 -05:00
file get source-file-path parent-directory
2007-09-21 16:55:39 -04:00
swap path+ run-template-file ;
2007-09-20 18:09:08 -04:00
: template-convert ( infile outfile -- )
[ run-template-file ] with-file-writer ;
2008-02-29 01:57:38 -05:00
! file responder integration
: serve-fhtml ( filename -- response )
"text/html" <content>
swap [ run-template-file ] curry >>body ;
: enable-fhtml ( responder -- responder )
[ serve-fhtml ]
"application/x-factor-server-page"
pick special>> set-at ;