|
|
|
#lang racket/base
|
|
|
|
(require (for-syntax racket/base))
|
|
|
|
(require racket/string xml xml/path sugar/define sugar/container)
|
|
|
|
(require "tools.rkt" txexpr "world.rkt" "cache.rkt")
|
|
|
|
|
|
|
|
|
|
|
|
(require sugar/coerce/value)
|
|
|
|
(provide (all-from-out sugar/coerce/value))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (puttable-item? x)
|
|
|
|
(any/c . -> . boolean?)
|
|
|
|
(or (txexpr? x) (has-markup-source? x)))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (query-key? x)
|
|
|
|
(any/c . -> . boolean?)
|
|
|
|
(or (string? x) (symbol? x)))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (put x)
|
|
|
|
(puttable-item? . -> . txexpr?)
|
|
|
|
(cond
|
|
|
|
;; Using put has no effect on txexprs. It's here to make the idiom smooth.
|
|
|
|
[(txexpr? x) x]
|
|
|
|
[(has-markup-source? x) (cached-require (->markup-source-path x) world:main-pollen-export)]))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (find query px)
|
|
|
|
(query-key? (or/c #f puttable-item?) . -> . (or/c #f txexpr-element?))
|
|
|
|
(define result (and px (or (find-in-metas px query) (find-in-doc px query))))
|
|
|
|
(and result (car result))) ;; return false or first element
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (find-in-metas px key)
|
|
|
|
(puttable-item? query-key? . -> . (or/c #f txexpr-elements?))
|
|
|
|
(and (has-markup-source? px)
|
|
|
|
(let ([metas (cached-require (->markup-source-path px) 'metas)]
|
|
|
|
[key (->string key)])
|
|
|
|
(and (key . in? . metas ) (->list (get metas key))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (find-in-doc px query)
|
|
|
|
(puttable-item? (or/c query-key? (listof query-key?))
|
|
|
|
. -> . (or/c #f txexpr-elements?))
|
|
|
|
(let* ([px (put px)]
|
|
|
|
;; make sure query is a list of symbols (required by se-path*/list)
|
|
|
|
[query (map ->symbol (->list query))]
|
|
|
|
[results (se-path*/list query px)])
|
|
|
|
;; if results exist, send back xexpr as output
|
|
|
|
(and (not (empty? results)) results)))
|
|
|
|
|
|
|
|
|
|
|
|
;; turns input into xexpr-elements so they can be spliced into template
|
|
|
|
;; (as opposed to dropped in as a full txexpr)
|
|
|
|
;; by returning a list, pollen rules will automatically merge into main flow
|
|
|
|
;; todo: explain why
|
|
|
|
;; todo: do I need this?
|
|
|
|
(define+provide/contract (splice x)
|
|
|
|
((or/c txexpr? txexpr-elements? string?) . -> . txexpr-elements?)
|
|
|
|
(cond
|
|
|
|
[(txexpr? x) (get-elements x)]
|
|
|
|
[(txexpr-elements? x) x]
|
|
|
|
[(string? x) (->list x)]))
|
|
|
|
|
|
|
|
|
|
|
|
(define+provide/contract (->html x)
|
|
|
|
(txexpr? . -> . string?)
|
|
|
|
(txexpr->html x))
|
|
|
|
|
|
|
|
|
|
|
|
(provide when/block)
|
|
|
|
(define-syntax (when/block stx)
|
|
|
|
(syntax-case stx ()
|
|
|
|
[(_ condition body ...)
|
|
|
|
#'(if condition (string-append*
|
|
|
|
(with-handlers ([exn:fail? (λ(exn) (error (format "when/block: ~a" (exn-message exn))))])
|
|
|
|
(map ->string (list body ...))))
|
|
|
|
"")]))
|