;; cite ;; quote ;; ;; ian-xhtml->xhtml: xexpr -> xexpr ;; (define (ian-xhtml->xhtml src) (let {[work-mostly-done (fold transforms apply-to-each-sub-expr src))] ;; transforms: (list-of (list tag xexpr-morpher)), ;; where tag is a symbol (a ian-xhtml tag), and xexpr-morpher ;; is a funciton which takes in a ian-xhtml element of that tag, ;; and returns xhtml. Other tags left intact. ;; (Since this only transforms tags specific to ian-xhtml, ;; and the output is xhtml, then there won't be any dependence ;; on the order of applications, if transforms are independent of the element-data. ;; That is, as long as the transform is only changing tag names and attributes, ;; and leaving the body unchanged, then there's not even potential for ambiguity... i think.) ;; (define transforms `{[keywords ,transform-keywords] [description ,transform-description] [footnote ,transform-footnote] [link ,transform-link] }) ;; Recur into the xexpr "src", and if we find an element in "transforms", ;; then replace it with the transformed element. ;; Notes: evaluation should be left-to-right. ;; (Both for the tag, and so if there are somehow two, say, "title" tags, ;; the second one overrides the first.) ;; Do we want to also guarantee pre-order traversal? ;; (that is, do the insides of an element, before doing the top-level element?) ;; Perhaps not -- for 'comment tags, we'd rather post-order it. ;; This question becomes: ;; consider the innards of a ian-xhtml tag; are they ian-xhtml or pure xhtml? ;; (define (traverse-n-morph src) (cond [(empty? src) empty] [(atom? (first src)) (cons (first src) (traverse-n-morph (rest src)))] [else (let* {[tag (first (first src))] [lookup (assoc tag transforms)] [morpher (if (empty? lookup) identity (rest lookup))]} ; Pre-order: recur *before* applying morpher: [new-element (morpher (traverse-n-morph (rest (first src))))] ; Left-to-right: we processed (first src), before doing (rest src): [the-rest (traverse-n-morph (rest src))] (cons new-element the-rest))) ;; transformers: ;; xhtml-ian ;; ;; link -> a ;; footnote ;; eval (first?, repeating?) ;; comments -- no need ;; footer ;; keywords, description ;; title (define (convert-title-tag titl) (set! the-window-name (define (transform-link link-xpr) link-xpr) (define (transform-keywords kwd-xpr) `(meta {[name "keywords"] [contents ,kwd-xpr]} )) (define (transform-description descr-xpr) `(meta {[name "description"] [contents ,descr-xpr]} )) ;; Global state: ;; title ;; footer ;; footnotes