Module: environment-reports Author: Andy Armstrong Synopsis: A wrapper stream for outputting HTML Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// HTML wrapper stream define class () end class ; define method read-element (stream :: , #key on-end-of-stream) => (character) read-element(stream.inner-stream, on-end-of-stream: on-end-of-stream) end method read-element; /*---*** Don't seem to need this as of yet... define method raw-write (stream :: , string :: ) => () write(stream.inner-stream, string) end method raw-write; */ define sealed method write (stream :: , string :: , #key start: start-index = 0, end: end-index) => () for (index :: from start-index | 0 below end-index | string.size) write-element(stream, string[index]) end end method write; define sealed method write (stream :: , string :: , #key start: start-index = 0, end: end-index) => () for (index :: from start-index | 0 below end-index | string.size) write-element(stream, string[index]) end end method write; define method write-element (stream :: , character :: ) => () let inner-stream = stream.inner-stream; select (character) '<' => write(inner-stream, "<"); '>' => write(inner-stream, ">"); '&' => write(inner-stream, "&"); '\n' => new-line(inner-stream); otherwise => write-element(inner-stream, character); end end method write-element; define method write-element (stream :: , string :: ) => () write(stream, string) end method write-element; define method write-element (stream :: , token :: ) => () let inner-stream = stream.inner-stream; with-stream-locked (stream) write-element(inner-stream, '<'); write(inner-stream, as-lowercase(as(, token))); write-element(inner-stream, '>') end end method write-element; define method write-element (stream :: , token :: ) => () write(stream.inner-stream, integer-to-string(token)) end method write-element; define method write-html (stream :: , #rest sequence) => () do(curry(write-element, stream), sequence) end method write-html; /// Some special tokens define class () sealed constant slot anchor-name :: , required-init-keyword: name:; end class ; define method write-element (stream :: , anchor :: ) => () let inner-stream = stream.inner-stream; with-stream-locked (stream) write(inner-stream, "") end end method write-element; define class () sealed constant slot reference-name :: , required-init-keyword: name:; end class ; define method write-element (stream :: , reference :: ) => () let inner-stream = stream.inner-stream; with-stream-locked (stream) write(inner-stream, "") end end method write-element; /// Useful macro define macro with-html-output { with-html-output (?streamn:name = ?streamv:expression, ?title:expression) ?body:body end } => { invoke-with-html-output(?streamv, ?title, method (?streamn) ?body end method) } { with-html-output (?stream:name, ?title:expression) ?body:body end } => { invoke-with-html-output(?stream, ?title, method (?stream) ?body end method) } end macro with-html-output; define method invoke-with-html-output (inner :: , title :: , body :: ) => () invoke-with-html-rubric(inner, title, body); end method; define method invoke-with-html-output (inner :: , title :: , body :: ) => () invoke-with-html-rubric(make(, inner-stream: inner), title, body) end method; define macro with-html-rubric { with-html-rubric (?streamn:name = ?streamv:expression, ?title:expression) ?body:body end } => { invoke-with-html-rubric (?streamv, ?title, method (?streamn) ?body end method) } { with-html-rubric (?stream:name, ?title:expression) ?body:body end } => { invoke-with-html-rubic (?stream, ?title, method (?stream) ?body end method) } end macro with-html-rubric; define method invoke-with-html-rubric (stream :: , title :: , body :: ) => () write-html-header(stream, title); body(stream); write-html-footer(stream) end method; define function write-html-header (stream :: , title :: ) => () write-html(stream, #"html", '\n', '\n', #"head", '\n', #"title", title, #"/title", '\n', #"/head", '\n', '\n', #"body", '\n', '\n') end function write-html-header; define function write-html-footer (stream :: ) => () write-html(stream, '\n', #"/body", '\n', #"/html", '\n') end function write-html-footer;