aboutsummaryrefslogtreecommitdiff
#lang typed/racket

(provide xexpr->text)

(require typed/xml)

(: xexpr->text (-> XExpr String))
(define (xexpr->text xexpr)
  (cond
    [(string? xexpr) xexpr]
    [(number? xexpr) (number->string xexpr)]
    [(symbol? xexpr) (symbol->string xexpr)]
    [(pair? xexpr)
     (let* ([fst (car xexpr)]
            [text (get-text xexpr->text xexpr)]
            [_attrs (get-attrs xexpr)])
       (case fst
         [(br) "\n"]
         [else text]))]
    [(cdata? xexpr) (cdata-string xexpr)]
    [(or (comment? xexpr) (p-i? xexpr)) ""]))

(define-predicate xexpr-attribute? XExpr-Attribute)

(: get-text (-> (-> XExpr String)
                (U (Pair Symbol (Pair (Listof XExpr-Attribute) (Listof XExpr)))
                   (Pair Symbol (Listof XExpr)))
                String))
(define (get-text f xexpr)
  (let ([rst (cdr xexpr)])
    (if (null? rst)
        (string-append* (map f rst))
        (let ([attrs (car rst)])
          (if (and (or (null? attrs) (pair? attrs))
                   (andmap xexpr-attribute? attrs))
              (string-append* (map f (cdr rst)))
              (string-append* (map f rst)))))))

(: get-attrs (-> (U (Pair Symbol (Pair (Listof XExpr-Attribute) (Listof XExpr)))
                    (Pair Symbol (Listof XExpr)))
                 (Listof XExpr-Attribute)))
(define (get-attrs xexpr)
  (let ([rst (cdr xexpr)])
    (if (null? rst)
        '()
        (let ([attrs (car rst)])
          (if (and (or (null? attrs) (pair? attrs))
                   (andmap xexpr-attribute? attrs))
              attrs
              '())))))