;;;;
;;;; HTML stylesheet
;;;;
(define nl (string #\newline))
(define (make-html-header head-parms)
`(head
(title ,(or (lookup-def 'title head-parms) "multidoc"))
(meta (@ (http-equiv "Content-Style-Type") (content "text/css")))
(meta (@ (http-equiv "Content-Type")
(content ,(lookup-def 'Content-Type head-parms
"text/html; charset=UTF-8"))))
,(let ((style (lookup-def 'style head-parms))
(print-style (lookup-def 'print-style head-parms))
(canonical (lookup-def 'canonical head-parms)))
(list (if style `(link (@ (rel "stylesheet") (type "text/css") (href ,style))) '())
(if print-style `(link (@ (rel "stylesheet") (type "text/css")
(media "print") (href ,print-style))) '())
(if canonical `(link (@ (rel "canonical") (href ,canonical))) '())))
,(map
(lambda (key)
(let ((val (lookup-def key head-parms )))
(and val
`(meta (@ (name ,(symbol->string key)) (content ,val))))))
'(description Author keywords
Date-Revision-yyyymmdd Date-Creation-yyyymmdd))))
(define (internal-link r)
(post-order
r
`(
(*default* . ,(lambda (tag . elems) elems))
(*text* . ,(lambda (trigger str)
(string-substitute* (string-downcase str)
'(("^[^a-z]+" . "")
("[^a-z0-9_ \t-]" . "")
("[ \t]+" . "-")))))
)))
(define (html-transformation-rules content)
`((
(@ *preorder* . ,(lambda (tag elements) (cons tag elements)))
(Header
*preorder*
. ,(lambda (tag headers)
(make-html-header headers)))
(toc ;; Re-scan the content for "section" tags and generate
*macro*
. ,(lambda (tag rest) ;; the table of contents
`(div (@ (id "toc"))
,rest
(ol ,(let find-sections ((content content))
(cond
((not (pair? content)) '())
((pair? (car content))
(append (find-sections (car content))
(find-sections (cdr content))))
((eq? (car content) 'section)
(let* ((level (cadr content))
(head-word (caddr content))
(href (list "#" (internal-link head-word)))
(subsections (find-sections (cdddr content))))
(cond ((and (integer? level) head-word)
`((li (a (@ (href (,href))) ,head-word)
,@(if (null? subsections)
'()
`((ol ,subsections))))))
(else
(error 'html-transformation-rules
"section elements must be of the form (section level head-word . contents)")))))
(else (find-sections (cdr content)))))))))
(section
*macro*
. ,(lambda (tag elems)
(let ((level (car elems))
(head-word (cadr elems))
(contents (cddr elems)))
(cond ((and (integer? level) head-word)
`((,(string->symbol (string-append "h" (number->string level)))
(@ (id ,(internal-link head-word)))
,head-word ) . ,contents))
(else
(error 'html-transformation-rules
(conc "section elements must be of the form (section level head-word . contents), got " elems))))
)))
(section*
*macro*
. ,(lambda (tag elems)
(let ((level (car elems))
(head-word (cadr elems))
(contents (cddr elems)))
(cond ((and (integer? level) head-word)
`((,(string->symbol (string-append "h" (number->string level)))
,head-word ) . ,contents))
(else
(error 'html-transformation-rules
(conc "section elements must be of the form (section level head-word . contents), got " elems))))
)))
(def
((sig . ,(lambda (tag types)
(map (lambda (spec)
`(span (@ (class ,(conc "definition " (car spec))))
(em "[" ,(symbol->string (car spec)) "]")
" " (tt ,@(cdr spec)) (br)))
types))))
. ,(lambda (tag elems) elems))
(pre
. ,(lambda (tag elems)
`(pre (tt . ,elems))))
(image-link
*macro*
. ,(lambda (tag elems)
`(img (@ (src ,(car elems)) . ,(if (null? (cdr elems))
'()
`((alt ,(cadr elems))
(title ,(cadr elems))))))))
(int-link
*macro*
. ,(lambda (tag elems)
;; Normalize links so people can refer to sections by their proper name
(let* ((parts (string-split (car elems) "#" #t))
(nparts (intersperse
(cons (car parts) (internal-link (cdr parts)))
"#")))
`(a (@ (href ,@nparts) (class "internal"))
,(if (null? (cdr elems)) (car elems) (cadr elems))))))
(link
*macro*
. ,(lambda (tag elems)
`(a (@ (href ,(car elems)) (class "external"))
,(if (null? (cdr elems)) (car elems) (cadr elems)))))
,@alist-conv-rules*
)
(
(html:begin
. ,(lambda (tag elems)
(list
xhtml-1.0-strict
""
elems
"")))
(verbatim
*preorder*
. ,(lambda (tag elems)
elems))
,@universal-conversion-rules*)
)
)