#lang racket/base
(require racket/promise
srfi/13/string
"ssax/ssax.rkt"
"lazy-xpath.rkt")
(provide (all-defined-out))
(define (lazy:force-descendants node)
(cond
((lazy:promise? node) (lazy:force-descendants (force node)))
((pair? node) (for-each lazy:force-descendants node))
(else #t )))
(define (lazy:except-last lst)
(if
(or (null? lst) (null? (cdr lst)))
'()
(cons (car lst) (lazy:except-last (cdr lst)))))
(define (lazy:seed-common seed)
((if (null? (cdr seed)) car caddr)
seed))
(define (lazy:replace-common seed new-common)
(if (null? (cdr seed)) (list new-common)
(list (car seed)
(cadr seed)
new-common
(cadddr seed))))
(define (lazy:xml->sxml port namespace-prefix-assig)
(let ((namespaces
(map (lambda (el)
(cons* #f (car el) (ssax:uri-string->symbol (cdr el))))
namespace-prefix-assig))
(RES-NAME->SXML
(lambda (res-name)
(string->symbol
(string-append
(symbol->string (car res-name))
":"
(symbol->string (cdr res-name)))))))
((lambda (result)
(if (null? namespace-prefix-assig)
(cons '*TOP* (lazy:except-last result))
(cons
'*TOP*
(cons
`(@@ (*NAMESPACES*
,@(map
(lambda (ns) (list (car ns) (cdr ns)))
namespace-prefix-assig)))
(lazy:except-last result)))))
(call-with-current-continuation (lambda (result-k)
((ssax:make-parser
NEW-LEVEL-SEED
(lambda (elem-gi attributes namespaces expected-content seed)
(if
(or (null? (cdr seed)) (> (cadddr seed) 3)) (list '()) (let ((attrs
(attlist-fold
(lambda (attr accum)
(cons (list
(if (symbol? (car attr)) (car attr)
(RES-NAME->SXML (car attr)))
(cdr attr)) accum))
'() attributes)))
(call-with-current-continuation
(lambda (new-level-k) ((car seed) (let ((elem-content
(call-with-current-continuation (lambda (elem-k)
(new-level-k
(list elem-k new-level-k '() (+ (cadddr seed) 1) ))))))
(append
(ssax:reverse-collect-str-drop-ws (caddr seed))
(list
(cons
(if (symbol? elem-gi) elem-gi
(RES-NAME->SXML elem-gi))
(if (null? attrs) elem-content
(cons (cons '@ attrs) elem-content)))
(delay
(call-with-current-continuation (lambda (foll-k)
(lazy:force-descendants elem-content)
((cadr seed) (list
foll-k (cadr seed)
'() (cadddr seed) ))))))))))))))
FINISH-ELEMENT
(lambda (elem-gi attributes namespaces parent-seed seed)
(if
(null? (cdr seed)) (let ((common (ssax:reverse-collect-str-drop-ws
(lazy:seed-common seed)))
(attrs
(attlist-fold
(lambda (attr accum)
(cons (list
(if (symbol? (car attr)) (car attr)
(RES-NAME->SXML (car attr)))
(cdr attr)) accum))
'() attributes)))
(lazy:replace-common
parent-seed
(cons
(cons
(if (symbol? elem-gi) elem-gi
(RES-NAME->SXML elem-gi))
(if (null? attrs) common
(cons (cons '@ attrs) common)))
(lazy:seed-common parent-seed))))
((car seed) (ssax:reverse-collect-str-drop-ws
(lazy:seed-common seed)))))
CHAR-DATA-HANDLER
(lambda (string1 string2 seed)
(lazy:replace-common
seed
(if (string-null? string2)
(cons string1 (lazy:seed-common seed))
(cons* string2 string1 (lazy:seed-common seed)))))
DOCTYPE
(lambda (port docname systemid internal-subset? seed)
(when internal-subset?
(ssax:warn port
"Internal DTD subset is not currently handled ")
(ssax:skip-internal-dtd port))
(ssax:warn port "DOCTYPE DECL " docname " "
systemid " found and skipped")
(values #f '() namespaces seed))
UNDECL-ROOT
(lambda (elem-gi seed)
(values #f '() namespaces seed))
PI
((*DEFAULT* .
(lambda (port pi-tag seed)
(lazy:replace-common
seed
(cons
(list '*PI* pi-tag (ssax:read-pi-body-as-string port))
(lazy:seed-common seed))))))
)
port
(list result-k (lambda (seed) ((car seed) '()))
'()
1 )))))))