diff --git a/scribble-lib/scribble/base-render.rkt b/scribble-lib/scribble/base-render.rkt index d73c0a3527..74586f10fe 100644 --- a/scribble-lib/scribble/base-render.rkt +++ b/scribble-lib/scribble/base-render.rkt @@ -2,6 +2,7 @@ (require "core.rkt" "private/render-utils.rkt" + racket/list mzlib/class mzlib/serialize scheme/file @@ -15,6 +16,8 @@ (provide render% render<%>) +(define current-part (make-parameter null)) + (define render<%> (interface () traverse @@ -413,7 +416,7 @@ ;; document-order traversal (define/public (traverse ds fns) - (let loop ([fp #hasheq()]) + (let loop ([fp #hasheq(('scribble:local . #hasheq()))]) (let ([fp2 (start-traverse ds fns fp)]) (if (equal? fp fp2) fp @@ -424,13 +427,14 @@ (traverse-part d fp))) (define/public (traverse-part d fp) - (let* ([fp (if (part-title-content d) - (traverse-content (part-title-content d) fp) - fp)] - [fp (traverse-content (part-to-collect d) fp)] - [fp (traverse-flow (part-blocks d) fp)]) - (for/fold ([fp fp]) ([p (in-list (part-parts d))]) - (traverse-part p fp)))) + (parameterize ([current-part d]) + (let* ([fp (if (part-title-content d) + (traverse-content (part-title-content d) fp) + fp)] + [fp (traverse-content (part-to-collect d) fp)] + [fp (traverse-flow (part-blocks d) fp)]) + (for/fold ([fp fp]) ([p (in-list (part-parts d))]) + (traverse-part p fp))))) (define/public (traverse-paragraph p fp) (traverse-content (paragraph-content p) fp)) @@ -488,14 +492,24 @@ (let ([v2 (v (lambda (key default) (if (eq? key 'scribble:current-render-mode) (current-render-mode) - (hash-ref fp key default))) - (lambda (key val) - (if (eq? key 'scribble:current-render-mode) - (raise-mismatch-error + (let* ([alll (hash-ref fp 'scribble:local #hasheq())] + [lp (hash-ref alll (current-part) #hasheq())]) + (hash-ref lp key + (lambda () (hash-ref fp key default)))))) + (lambda (key #:local [local #f] val) + (if (or (eq? key 'scribble:current-render-mode) + (eq? key 'scribble:local)) + (raise-mismatch-error 'traverse-info-set! "cannot set value for built-in key: " key) - (set! fp (hash-set fp key val)))))]) + (if local + (let* ([alll (hash-ref fp 'scribble:local #hasheq())] + [lp (hash-ref alll (current-part) #hasheq())]) + (set! lp (hash-set lp key val)) + (set! alll (hash-set alll (current-part) lp)) + (set! fp (hash-set fp 'scribble:local alll))) + (set! fp (hash-set fp key val))))))]) (let ([fp (hash-set fp p v2)]) (if (procedure? v2) fp diff --git a/scribble-lib/scribble/core.rkt b/scribble-lib/scribble/core.rkt index 9bb87319c5..9530aac07e 100644 --- a/scribble-lib/scribble/core.rkt +++ b/scribble-lib/scribble/core.rkt @@ -354,10 +354,16 @@ (or (current-load-relative-directory) (current-directory))) #:transparent) +(define element-traverse-get/c + (->* (symbol? any/c) () any/c)) + +(define element-traverse-set/c + (->* (symbol? any/c) (#:local boolean?) any/c)) + (define element-traverse-procedure/c (recursive-contract - ((symbol? any/c . -> . any/c) - (symbol? any/c . -> . any) + (element-traverse-get/c + element-traverse-set/c . -> . (or/c element-traverse-procedure/c content?))))