little optimization

pull/84/head
Matthew Butterick 10 years ago
parent 22528b59a2
commit 70695283b2

@ -41,12 +41,14 @@
(check-true (trivial-meta-element? '(meta "bar")))) (check-true (trivial-meta-element? '(meta "bar"))))
;; strictly speaking, this predicate isn't necessary (implied by txexpr-ness)
;; but it produces a helpful error
(define (valid-meta-attr? x) (define (valid-meta-attr? x)
(or (and (list? x) (symbol? (first x)) (string? (second x))) (or (and (list? x) (symbol? (first x)) (string? (second x)))
(error 'is-meta-element? "error: meta must be a symbol / string pair, instead got: ~v" x))) (error 'is-meta-element? "error: meta must be a symbol / string pair, instead got: ~v" x)))
;; all metas are converted into "atomic meta" format
;; which is '(meta (key value ...))
(define (make-atomic-meta key . values) (define (make-atomic-meta key . values)
`(meta (,key ,@values))) `(meta (,key ,@values)))
@ -54,16 +56,16 @@
(define (explode-meta-element me) (define (explode-meta-element me)
;; convert a meta with multiple key/value pairs into multiple metas with a single txexpr element ;; convert a meta with multiple key/value pairs into multiple metas with a single txexpr element
;; only gets nontrivial metas to start. ;; only gets nontrivial metas to start.
(let loop ([me me][acc empty]) (let loop ([me (make-txexpr (get-tag me) (get-attrs me) (filter txexpr? (get-elements me)))][acc empty])
(cond (cond
[(not (trivial-meta-element? me)) ; meta might become trivial during loop [(not (trivial-meta-element? me)) ; meta might become trivial during loop
(cond (cond
[(has-meta-attrs me) ; might have txexpr elements, so preserve them [(has-meta-attrs me) ; might have txexpr elements, so preserve them
(define attrs (get-attrs me)) (define attrs (get-attrs me))
(loop `(meta ,(cdr attrs) ,@(get-elements me)) (cons (apply make-atomic-meta (car attrs)) acc))] (loop (make-txexpr 'meta (cdr attrs) (get-elements me)) (cons (apply make-atomic-meta (car attrs)) acc))]
[else ; has txexpr elements, but not meta-attrs [else ; has txexpr elements, but not meta-attrs
(define txexpr-elements (filter txexpr? (get-elements me))) (define txexpr-elements (get-elements me)) ; elements were filtered for txexpr at loop entry
(loop `(meta () ,@(cdr txexpr-elements)) (cons (apply make-atomic-meta (car txexpr-elements)) acc))])] (loop (make-txexpr 'meta null (cdr txexpr-elements)) (cons (apply make-atomic-meta (car txexpr-elements)) acc))])]
[else (reverse acc)]))) [else (reverse acc)])))

Loading…
Cancel
Save