pull/9/head
Matthew Butterick 11 years ago
parent 8ba87de8b3
commit a4c2e92186

@ -43,10 +43,10 @@
;; because hash key needs to be a list ;; because hash key needs to be a list
;; so it's convenient to use a rest argument ;; so it's convenient to use a rest argument
;; therefore, use function by just listing out the paths ;; therefore, use function by just listing out the paths
(define/contract (store-refresh-in-mod-dates . rest-paths) (define/contract (store-render-in-mod-dates . rest-paths)
(() #:rest (listof path?) . ->* . void?) (() #:rest (listof path?) . ->* . void?)
;; project require files are appended to the mod-date key. ;; project require files are appended to the mod-date key.
;; Why? So a change in a require file will trigger a refresh ;; Why? So a change in a require file will trigger a render
;; (which is the right thing to do, since pollen files are ;; (which is the right thing to do, since pollen files are
;; dependent on those requires) ;; dependent on those requires)
;; It's convenient for development, because otherwise ;; It's convenient for development, because otherwise
@ -58,7 +58,7 @@
(module+ test (module+ test
(reset-mod-dates) (reset-mod-dates)
(store-refresh-in-mod-dates (build-path (current-directory) (->path "render.rkt"))) (store-render-in-mod-dates (build-path (current-directory) (->path "render.rkt")))
(check-true (= (len mod-dates) 1)) (check-true (= (len mod-dates) 1))
(reset-mod-dates)) (reset-mod-dates))
@ -71,12 +71,12 @@
(module+ test (module+ test
(reset-mod-dates) (reset-mod-dates)
(store-refresh-in-mod-dates (build-path (current-directory) (->path "render.rkt"))) (store-render-in-mod-dates (build-path (current-directory) (->path "render.rkt")))
(reset-mod-dates) (reset-mod-dates)
(check-true (= (len mod-dates) 0))) (check-true (= (len mod-dates) 0)))
;; how to know whether a certain combination of paths needs a refresh ;; how to know whether a certain combination of paths needs a render
;; use rest argument here so calling pattern matches store-refresh ;; use rest argument here so calling pattern matches store-render
(define/contract (mod-date-expired? . rest-paths) (define/contract (mod-date-expired? . rest-paths)
(() #:rest (listof path?) . ->* . boolean?) (() #:rest (listof path?) . ->* . boolean?)
(define key (make-mod-dates-key rest-paths)) (define key (make-mod-dates-key rest-paths))
@ -86,7 +86,7 @@
(module+ test (module+ test
(reset-mod-dates) (reset-mod-dates)
(let ([path (build-path (current-directory) (->path "render.rkt"))]) (let ([path (build-path (current-directory) (->path "render.rkt"))])
(store-refresh-in-mod-dates path) (store-render-in-mod-dates path)
(check-false (mod-date-expired? path)) (check-false (mod-date-expired? path))
(reset-mod-dates) (reset-mod-dates)
(check-true (mod-date-expired? path)))) (check-true (mod-date-expired? path))))
@ -105,7 +105,7 @@
(for-each render xs)) (for-each render xs))
;; dispatches path to the right rendering function ;; dispatches path to the right rendering function
;; use #:force to refresh regardless of cached state ;; use #:force to render regardless of cached state
(define/contract (render #:force [force #f] . xs) (define/contract (render #:force [force #f] . xs)
(() (#:force boolean?) #:rest (listof pathish?) . ->* . void?) (() (#:force boolean?) #:rest (listof pathish?) . ->* . void?)
(define (&render x) (define (&render x)
@ -113,7 +113,7 @@
; (message "Dispatching render for" (->string (file-name-from-path path))) ; (message "Dispatching render for" (->string (file-name-from-path path)))
(cond (cond
;; this will catch preprocessor files ;; this will catch preprocessor files
[(needs-preproc? path) (render-with-preproc path #:force force)] [(needs-preproc? path) (render-preproc-source path #:force force)]
;; this will catch pollen source files, ;; this will catch pollen source files,
;; and files without extension that correspond to p files ;; and files without extension that correspond to p files
[(needs-template? path) (render-with-template path #:force force)] [(needs-template? path) (render-with-template path #:force force)]
@ -144,7 +144,7 @@
(message (->string (file-name-from-path path)) "is up to date, using cached copy")) (message (->string (file-name-from-path path)) "is up to date, using cached copy"))
(define/contract (render-with-preproc x #:force [force #f]) (define/contract (render-preproc-source x #:force [force #f])
(((and/c pathish? (((and/c pathish?
(flat-named-contract 'file-exists (flat-named-contract 'file-exists
(λ(x) (file-exists? (->complete-path (->preproc-source-path x))))))) (#:force boolean?) . ->* . void?) (λ(x) (file-exists? (->complete-path (->preproc-source-path x))))))) (#:force boolean?) . ->* . void?)
@ -169,21 +169,22 @@
;; 4) source had to be reloaded (some other change) ;; 4) source had to be reloaded (some other change)
source-reloaded?) source-reloaded?)
;; how we render: import 'text from preproc source file and write to output path ;; how we render: import 'text from preproc source file,
;; which is rendered during source parsing,
;; and write that to output path
(begin (begin
(rendering-message (format "~a from ~a" (rendering-message (format "~a from ~a"
(file-name-from-path output-path) (file-name-from-path output-path)
(file-name-from-path source-path))) (file-name-from-path source-path)))
(store-refresh-in-mod-dates source-path) (store-render-in-mod-dates source-path)
(parameterize ([current-directory source-dir] (parameterize ([current-directory source-dir])
[current-output-port nowhere-port])
(let ([text (dynamic-require source-path 'text)]) (let ([text (dynamic-require source-path 'text)])
(display-to-file text output-path #:exists 'replace))) (display-to-file text output-path #:exists 'replace)))
(rendered-message output-path)) (rendered-message output-path))
;; otherwise, skip file because there's no trigger for refresh ;; otherwise, skip file because there's no trigger for render
(up-to-date-message output-path))) (up-to-date-message output-path)))
;; todo: write tests ;; todo: write tests
@ -200,7 +201,7 @@
(define-values (source-dir source-name _) (split-path source-path)) (define-values (source-dir source-name _) (split-path source-path))
;; need to require source file (to retrieve template name, which is in metas) ;; need to require source file (to retrieve template name, which is in metas)
;; but use dynamic-rerequire now to force refresh for dynamic-require later, ;; but use dynamic-rerequire now to force render for dynamic-require later,
;; otherwise the source file will cache ;; otherwise the source file will cache
;; by default, rerequire reports reloads to error port. ;; by default, rerequire reports reloads to error port.
;; set up a port to catch messages from dynamic-rerequire ;; set up a port to catch messages from dynamic-rerequire
@ -257,10 +258,10 @@
(build-path source-dir (add-ext DEFAULT_TEMPLATE_PREFIX (get-ext (->output-path source-path))))))) (build-path source-dir (add-ext DEFAULT_TEMPLATE_PREFIX (get-ext (->output-path source-path)))))))
;; if none of these work, make fallback template file ;; if none of these work, make fallback template file
(let ([ft-path (build-path source-dir FALLBACK_TEMPLATE_NAME)]) (let ([ft-path (build-path source-dir FALLBACK_TEMPLATE_NAME)])
(display-to-file #:exists 'replace fallback-template-data ft-path) (display-to-file fallback-template-data ft-path #:exists 'replace)
ft-path))) ft-path)))
;; refresh template (it might have its own preprocessor file) ;; render template (it might have its own preprocessor file)
(render template-path #:force force) (render template-path #:force force)
;; calculate new path for generated file ;; calculate new path for generated file
@ -271,15 +272,16 @@
;; Four conditions where we render: ;; Four conditions where we render:
(if (or force ; a) it's explicitly demanded (if (or force ; a) it's explicitly demanded
(not (file-exists? output-path)) ; b) output file does not exist (not (file-exists? output-path)) ; b) output file does not exist
;; c) mod-dates indicates refresh is needed ;; c) mod-dates indicates render is needed
(mod-date-expired? source-path template-path) (mod-date-expired? source-path template-path)
;; d) dynamic-rerequire indicates the source had to be reloaded ;; d) dynamic-rerequire indicates the source had to be reloaded
source-reloaded?) source-reloaded?)
(begin (begin
(store-refresh-in-mod-dates source-path template-path) (store-render-in-mod-dates source-path template-path)
(message "Rendering source" (->string (file-name-from-path source-path)) "with template" (->string (file-name-from-path template-path))) (message "Rendering source" (->string (file-name-from-path source-path))
"with template" (->string (file-name-from-path template-path)))
(let ([page-result (render-source-with-template source-path template-path)]) (let ([page-result (render-source-with-template source-path template-path)])
(display-to-file #:exists 'replace page-result output-path) (display-to-file page-result output-path #:exists 'replace)
(rendered-message output-path))) (rendered-message output-path)))
(up-to-date-message output-path)) (up-to-date-message output-path))

Loading…
Cancel
Save