#lang racket/base
(require (for-syntax racket/base
"html-template-generate-helpers.rkt"
"planet-neil-html-writing.rkt")
(for-template racket/base
"html-template-generate-helpers.rkt"
"planet-neil-html-writing.rkt")
"html-template-generate-helpers.rkt"
"planet-neil-html-writing.rkt")
(provide compress-html-template-irep)
(define (compress-html-template-irep irep)
(let loop ((irep irep)
(reverse-byteses '())
(reverse-result '()))
(if (null? irep)
(begin
(if (null? reverse-byteses)
(reverse reverse-result)
(reverse (cons (apply bytes-append (reverse reverse-byteses))
reverse-result))))
(let* ((item (car irep))
(item (if (and (pair? item)
(eq? 'verbatim (car item)))
(let ((item-args (cdr (cdr item))))
(if (and (not (null? item-args))
(null? (cdr item-args)))
(let* ((first-arg-stx (car item-args))
(first-arg-e (syntax-e first-arg-stx)))
(cond ((bytes? first-arg-e) first-arg-e)
((string? first-arg-e) (string->bytes/utf-8 first-arg-e))
(else item)))
item))
item)))
(if (bytes? item)
(loop (cdr irep)
(cons item reverse-byteses)
reverse-result)
(loop (cdr irep)
'()
(cons item
(if (null? reverse-byteses)
reverse-result
(cons (apply bytes-append (reverse reverse-byteses))
reverse-result)))))))))
(provide %html-template:begin-stx)
(define (%html-template:begin-stx ctxt body-stxes)
(cond ((null? body-stxes) (quasisyntax/loc ctxt
(void)))
((not (list? body-stxes)) (raise-type-error '%html-template:begin-stx
"list"
1
(list ctxt body-stxes)))
((null? (cdr body-stxes)) (car body-stxes))
(else (quasisyntax/loc ctxt
(begin #,@body-stxes)))))
(provide %html-template:reverse-lvs-and-body-stxes->stx)
(define (%html-template:reverse-lvs-and-body-stxes->stx ctxt reverse-lvs body-stxes)
(if (null? reverse-lvs)
(%html-template:begin-stx ctxt body-stxes)
(quasisyntax/loc ctxt
(let-values (#,@(reverse reverse-lvs))
#,@(cond ((null? body-stxes) (list (quasisyntax/loc ctxt
(void))))
((not (list? body-stxes)) (raise-type-error '%html-template:reverse-lvs-and-body-stxes->stxes
"list"
2
(list ctxt reverse-lvs body-stxes)))
((null? (cdr body-stxes)) (list (car body-stxes)))
(else body-stxes))))))
(provide expand-html-template)
(define (expand-html-template #:error-name error-name
#:stx stx
#:ordering ordering
#:reverse-lvs reverse-lvs
#:irep irep
#:port-stx port-stx)
(let*-values (((reverse-lvs port-var-stx)
(if (identifier? port-stx)
(values reverse-lvs port-stx)
(let ((out-var-stx (quasisyntax/loc stx
out)))
(values (cons (quasisyntax/loc stx
((#,out-var-stx) #,port-stx))
reverse-lvs)
out-var-stx))))
((write-stxes)
(html-template-irep->write-stxes error-name
stx
port-var-stx
irep)))
(%html-template:reverse-lvs-and-body-stxes->stx
stx
reverse-lvs
(list (quasisyntax/loc stx
(parameterize ((current-output-port html-template-error-catching-output-port))
#,@write-stxes))))))
(provide html-template-irep->write-stxes)
(define (html-template-irep->write-stxes error-name entire-stx port-var-stx irep)
(let loop ((irep irep)
(need-void? #t))
(if (null? irep)
(if need-void?
(cons (quasisyntax/loc entire-stx
(void))
'())
'())
(let ((item (car irep)))
(if (bytes? item)
(cons (if (equal? #" " item)
(quasisyntax/loc entire-stx
(write-char #\space #,port-var-stx))
(quasisyntax/loc entire-stx
(write-bytes #,item #,port-var-stx)))
(loop (cdr irep) #t))
(apply (lambda (item-opcode item-stx . item-args)
(case item-opcode
((format/attribute-value)
(cons (quasisyntax/loc item-stx
(%html-template:format/attribute-value/write
#,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
((format/content)
(cons (quasisyntax/loc item-stx
(%html-template:format/content/write
#,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
((verbatim)
(cons (quasisyntax/loc item-stx
(%html-template:write-verbatim
#,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
((void)
(append item-args (loop (cdr irep) #t)))
((write)
(cons (quasisyntax/loc item-stx
(parameterize ((current-output-port #,port-var-stx))
#,@item-args))
(loop (cdr irep) #t)))
((write/port)
(cons (apply (lambda (local-var-stx . body-stxes)
(or (identifier? local-var-stx)
(raise-syntax-error error-name
"expected identifier"
local-var-stx))
(quasisyntax/loc item-stx
(let ((#,local-var-stx #,port-var-stx))
#,@body-stxes)))
item-args)
(loop (cdr irep) #t)))
((xexp/attributes)
(cons (quasisyntax/loc item-stx
(write-html-attributes #,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
((xexp/attribute-value)
(cons (quasisyntax/loc item-stx
(write-html-attribute-value-part #,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
((xexp/content)
(cons (quasisyntax/loc item-stx
(write-html #,(%html-template:begin-stx item-stx item-args)
#,port-var-stx))
(loop (cdr irep) #t)))
(else (error 'html-template-irep->write-stx-list
"invalid opcode: ~S"
item-opcode))))
item))))))