HSS Cascading Style Sheet == Description == //HOP Cascading Style Sheet// (HSS) is a strict super set of regular W3C's [[http://www.w3.org/TR/CSS2|CSS, level2]]. That is, HSS supports all the features of CSS level 2 and, in addition, it offers some facilities for: * improving the integration within HOP. * adding abstraction to cascade style sheets. == Syntactic extension == HSS brings one syntactic extension to CSS. It enables to introduce HOP expressions in cascade style sheets. These are introduced by the ++$++ escape character. That is, when the HOP HSS parser encounters a ++$++ character, it parsers the following characters according to the HOP syntax. In the rest of this text these expressions are referred to as //escape expressions//. These escape expressions are evaluated by a regular HOP evaluator. == Adding abstractions == The frequent use of escape expressions is to add abstractions to cascade style sheet. For that, generally, a HSS file starts with a list of global bindings. Then, these defined variables are then used in the attribute fields of the cascade style sheets. For instance: $(define font-family "Lucida Grande, Verdana, Lucida, Helvetica, Arial") $(define button-margin "margin-left: 4px; margin-top: 2px;") input[type=text] { font-family: $font-family; } button { font-family: $font-family; margin: $button-margin; } == Adding shorthands == The function ,( "define-hss-type" "hss.wiki") binds //aliases// for CSS descriptors. That is, it gives a name to a descriptor that can be used as any other descriptors. For instance $(define-hss-type lframe "div[hssclass=hop-lframe]" :body "div[hssclass=hop-lfbody]" (define-hss-property (-hop-label-margin v) (format "padding: ~l;" v)) (define-hss-property (-hop-label-border v) (format "div[hssclass=hop-lfborder] { border: ~l; }" v)) (define-hss-property (padding v) (format "div[hssclass=hop-lfbody] { padding: ~l; }" v)) (define-hss-property (-hop-label-border-radius v) (format "div[hssclass=hop-lfborder] { border-radius: ~l; }" v)) (define-hss-property (-hop-label-align v) (format "div[hssclass=hop-lflabel] { text-align: ~l; }" v)) (define-hss-property (-hop-label-offset v) (format "div[hssclass=hop-lflabel] { top: -~l; }" v)) (define-hss-property (background v) (list (format "background: ~a;" (car v)) (format "div[hssclass=hop-lflabel] > span { background: ~a; }" (car v))))) $(define-hss-type lflabel "div[hssclass=hop-lflabel] span") names ++lframe++ the compound descriptor ++div[hssclass=hop-lframe]++. This name can be used as any regular descriptor. For instance: lframe span.foo { border: 1px solid red; } is turned equivalent to: div[hssclass=hop-lframe] span.foo { border: 1px solid red; } by the aliasing declared above. == Evaluation and caching == HSS files could be cached by HOP servers. Hence, the HOP expressions embedded inside such files should not be excepted to be evaluated more than once. The execution should be insensitive to multiple evaluations. == Complete example == For the sake of the example, here is the HSS file used for the HOP document center. ,(let ((path (make-file-name (doc-dir) "doc.hss"))) (if (file-exists? path) ( ( ( path) (with-input-from-file path (lambda () (
		       :style "max-width: 80em; overflow: auto"
		       :class "source"
		       (decorate-api-code
			(read-string (current-input-port))))))))
	path))