From 0933a96ed22c45e64bcdf029d6a22216802084a9 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sun, 16 Mar 2014 13:05:39 -0700 Subject: [PATCH] refactor template functions --- scribblings/template.scrbl | 46 ++++++++++---------- template.rkt | 86 ++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 62 deletions(-) diff --git a/scribblings/template.scrbl b/scribblings/template.scrbl index 15b8cde..db80215 100644 --- a/scribblings/template.scrbl +++ b/scribblings/template.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require scribble/eval pollen/cache pollen/world (for-label racket (except-in pollen #%module-begin) pollen/template pollen/render xml pollen/pagetree)) +@(require scribble/eval pollen/cache pollen/world (for-label racket (except-in pollen #%module-begin) pollen/template pollen/render xml pollen/pagetree sugar/coerce/value)) @(define my-eval (make-base-eval)) @(my-eval `(require pollen pollen/template xml)) @@ -11,6 +11,8 @@ Convenience functions for templates. These are automatically imported into the @racket[eval] environment when rendering with a template (see @racket[render]). +This module also provides everything from @racket[sugar/coerce/value]. + @defproc[ (->html [xexpr xexpr?]) @@ -34,52 +36,52 @@ Be careful not to pass existing HTML strings into this function, because the @co @deftogether[( @defproc[ -(from -[query symbolish?] -[pagenode pagenodeish?]) +(select +[key symbolish?] +[value-source (or/c hash? txexpr? pagenode? pathish?)]) (or/c #f txexpr-element?)] @defproc[ -(from* -[query symbolish?] -[pagenode pagenodeish?]) +(select* +[key symbolish?] +[value-source (or/c hash? txexpr? pagenode? pathish?)]) (or/c #f (listof txexpr-element?))] )] -Find matches for @racket[_query] in @racket[_pagenode], first by looking in its @code{metas} (using @racket[from-metas]) and then by looking in its @code{doc} (using @racket[from-doc]). With @racket[from], you get the first result; with @racket[from*], you get them all. In both cases, you get @racket[#f] if there are no matches. +Find matches for @racket[_key] in @racket[_value-source], first by looking in its @code{metas} (using @racket[select-from-metas]) and then by looking in its @code{doc} (using @racket[select-from-doc]). With @racket[select], you get the first result; with @racket[select*], you get them all. In both cases, you get @racket[#f] if there are no matches. @defproc[ -(from-metas -[query symbolish?] -[meta-source (or/c pagenodeish? hash?)]) +(select-from-metas +[key symbolish?] +[meta-source (or/c hash? pagenodeish? pathish?)]) (or/c #f txexpr-element?)] -Look up the value of @racket[_query] in @racket[_meta-source]. The @racket[_meta-source] argument can be either a set of metas (i.e., a @racket[hash]) or a @racket[pagenode?], from which metas are pulled. If no value exists for @racket[_query], you get @racket[#f]. +Look up the value of @racket[_key] in @racket[_meta-source]. The @racket[_meta-source] argument can be either a set of metas (i.e., a @racket[hash]) or a @racket[pagenode?], from which metas are pulled. If no value exists for @racket[_key], you get @racket[#f]. @examples[#:eval my-eval (define my-metas (hash 'template "sub.xml.pt" 'target "print")) -(from-metas 'template my-metas) -('target . from-metas . my-metas) -(from-metas 'nonexistent-key my-metas) +(select-from-metas 'template my-metas) +('target . select-from-metas . my-metas) +(select-from-metas 'nonexistent-key my-metas) ] @defproc[ -(from-doc -[query symbolish?] -[doc-source (or/c pagenodeish? txexpr?)]) +(select-from-doc +[key symbolish?] +[doc-source (or/c txexpr? pagenodeish? pathish?)]) (or/c #f txexpr-element?)] -Look up the value of @racket[_query] in @racket[_doc-source]. The @racket[_doc-source] argument can be either be a @code{doc} (i.e., a @racket[txexpr]) or a @racket[pagenode?], from which doc is pulled. If no value exists for @racket[_query], you get @racket[#f]. +Look up the value of @racket[_key] in @racket[_doc-source]. The @racket[_doc-source] argument can be either be a @code{doc} (i.e., a @racket[txexpr]) or a @racket[pagenode?], from which doc is pulled. If no value exists for @racket[_key], you get @racket[#f]. @examples[#:eval my-eval (define my-doc '(body (question "Gelato?") (answer "Nocciola") (answer "Pistachio"))) -(from-doc 'question my-doc) -('answer . from-doc . my-doc) -(from-doc 'nonexistent-key my-doc) +(select-from-doc 'question my-doc) +('answer . select-from-doc . my-doc) +(select-from-doc 'nonexistent-key my-doc) ] diff --git a/template.rkt b/template.rkt index d9bbce0..ba95a4c 100644 --- a/template.rkt +++ b/template.rkt @@ -10,60 +10,66 @@ (define/contract+provide (metas->here metas) (hash? . -> . pagenode?) - (path->pagenode ('here-path . from-metas . metas))) + (path->pagenode (select-from-metas 'here-path metas))) -(define/contract (get-doc pagenode-or-path) - ((or/c pagenode? pathish?) . -> . (or/c txexpr? string?)) - (define source-path (->source-path (cond - [(pagenode? pagenode-or-path) (pagenode->path pagenode-or-path)] - [else pagenode-or-path]))) - (if source-path - (cached-require source-path world:main-pollen-export) - (error (format "get-doc: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) +(define (pagenode->path pagenode) + (build-path (world:current-project-root) (symbol->string pagenode))) -(define/contract (get-metas pagenode-or-path) - ((or/c pagenode? pathish?) . -> . hash?) - (define source-path (->source-path (cond - [(pagenode? pagenode-or-path) (pagenode->path pagenode-or-path)] - [else pagenode-or-path]))) - (if source-path - (cached-require source-path world:meta-pollen-export) - (error (format "get-metas: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) +(define+provide/contract (select key value-source) + (coerce/symbol? (or/c hash? txexpr? pagenode? pathish?) . -> . (or/c #f txexpr-element?)) + (define metas-result (and (not (txexpr? value-source)) (select-from-metas key value-source))) + (or metas-result + (let ([doc-result (select-from-doc key value-source)]) + (and doc-result (car doc-result))))) -(define (pagenode->path pagenode) - (build-path (world:current-project-root) (symbol->string pagenode))) +(define+provide/contract (select* key value-source) + (coerce/symbol? (or/c hash? txexpr?) . -> . (or/c #f (listof txexpr-element?))) + (define metas-result (and (not (txexpr? value-source)) (select-from-metas key value-source))) + (define doc-result (select-from-doc key value-source)) + (define result (append (or (and metas-result (list metas-result)) null) (or doc-result null))) + (and (not (null? result)) result)) + +(define+provide/contract (select-from-metas key metas-source) + (coerce/symbol? (or/c hash? pagenode? pathish?) . -> . (or/c #f txexpr-element?)) + (define metas (cond + [(hash? metas-source) metas-source] + [else (get-metas metas-source)])) + (and (hash-has-key? metas key) (hash-ref metas key))) -(define+provide/contract (from query pagenode) - (coerce/symbol? coerce/symbol? . -> . (or/c #f txexpr-element?)) - (define result (from* query pagenode)) - (if (null? result) #f (car result))) +(define+provide/contract (select-from-doc key doc-source) + (coerce/symbol? (or/c txexpr? pagenode? pathish?) . -> . (or/c #f (listof txexpr-element?))) + (define doc (cond + [(txexpr? doc-source) doc-source] + [else (get-doc doc-source)])) + (define result (se-path*/list (list key) doc)) + (and (not (null? result)) result)) -(define+provide/contract (from* query pagenode) - (coerce/symbol? coerce/symbol? . -> . (or/c #f (listof txexpr-element?))) - (define meta-result (from-metas query pagenode)) - (define doc-result (from-doc query pagenode)) - (define combined-result (append (if meta-result (list meta-result) null) - (or doc-result null))) - (if (null? combined-result) #f combined-result)) +(define (get-metas pagenode-or-path) +; ((or/c pagenode? pathish?) . -> . hash?) + (define source-path (->source-path (cond + [(pagenode? pagenode-or-path) (pagenode->path pagenode-or-path)] + [else pagenode-or-path]))) + (if source-path + (cached-require source-path world:meta-pollen-export) + (error (format "get-metas: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) -(define/contract+provide (from-metas query meta-source) - (coerce/symbol? (or/c pagenode? hash?) . -> . (or/c #f txexpr-element?)) - (let ([metas (or (and (pagenode? meta-source) (get-metas meta-source)) meta-source)]) - (with-handlers ([exn:fail? (λ(e) #f)]) - (hash-ref metas query)))) + +(define (get-doc pagenode-or-path) +; ((or/c pagenode? pathish?) . -> . (or/c txexpr? string?)) + (define source-path (->source-path (cond + [(pagenode? pagenode-or-path) (pagenode->path pagenode-or-path)] + [else pagenode-or-path]))) + (if source-path + (cached-require source-path world:main-pollen-export) + (error (format "get-doc: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) -(define/contract+provide (from-doc query doc-source) - (coerce/symbol? (or/c pagenode? txexpr?) . -> . (or/c #f txexpr-elements?)) - (let ([doc (or (and (pagenode? doc-source) (get-doc doc-source)) doc-source)]) - (with-handlers ([exn:fail? (λ(e) #f)]) - (se-path*/list (list query) doc)))) (define+provide/contract (->html x)