diff --git a/file.rkt b/file.rkt index 0ecd318..d1cbbff 100644 --- a/file.rkt +++ b/file.rkt @@ -10,6 +10,18 @@ (define-values (dir name dir?) (split-path path)) dir) + +(define+provide/contract (find-upward-from source-path filename-to-find) + (coerce/path? coerce/path? . -> . (or/c #f path?)) + (parameterize ([current-directory (dirname (->complete-path source-path))]) + (let loop ([dir (current-directory)][path filename-to-find]) + (and dir ; dir is #f when it hits the top of the filesystem + (let ([completed-path (path->complete-path path)]) + (if (file-exists? completed-path) + (simplify-path completed-path) + (loop (dirname dir) (build-path 'up path)))))))) + + ;; for files like svg that are not source in pollen terms, ;; but have a textual representation separate from their display. (define+provide/contract (sourceish? x) diff --git a/render.rkt b/render.rkt index 03b6851..f4a7c1c 100644 --- a/render.rkt +++ b/render.rkt @@ -229,8 +229,8 @@ (define (get-default-template) (and output-path-ext - (build-path (world:current-project-root) - (add-ext (world:current-default-template-prefix) output-path-ext)))) + (let ([default-template-filename (add-ext (world:current-default-template-prefix) output-path-ext)]) + (find-upward-from source-path default-template-filename)))) (define (get-fallback-template) (and output-path-ext diff --git a/scribblings/render.scrbl b/scribblings/render.scrbl index ce393d5..e21664f 100644 --- a/scribblings/render.scrbl +++ b/scribblings/render.scrbl @@ -79,7 +79,7 @@ Find a template file for @racket[_source-path], with the following priority: @item{If the @racket[metas] for @racket[_source-path] have a key for @code[(format "~a" world:template-meta-key)], then use the value of this key.} -@item{If this key doesn't exist, or if it points to a nonexistent file, look for a default template in the project directory with the name @code[(format "~a.[output extension]" world:default-template-prefix)]. Meaning, if @racket[_source-path] is @code[(format "intro.html.~a" world:markup-source-ext)], the output path would be @code["intro.html"], so the default template would be @code[(format "~a.html" world:default-template-prefix)].} +@item{If this key doesn't exist, or refers to a nonexistent file, look for a default template with the name @code[(format "~a.[output extension]" world:default-template-prefix)]. Meaning, if @racket[_source-path] is @code[(format "intro.html.~a" world:markup-source-ext)], the output path would be @code["intro.html"], so the default template would be @code[(format "~a.html" world:default-template-prefix)]. Look for this default template in the same directory as the source file, and then search upwards within successive parent directories. (Corollary: a default template in the project root will apply to all files in the project unless overridden within a subdirectory.)} @item{If this file doesn't exist, use the fallback template as a last resort. (See @secref["Templates" #:tag-prefixes '("tutorial-2") diff --git a/test/data/subtemplate/one.txt b/test/data/subtemplate/one.txt new file mode 100644 index 0000000..50fc7ef --- /dev/null +++ b/test/data/subtemplate/one.txt @@ -0,0 +1 @@ +one in main template \ No newline at end of file diff --git a/test/data/subtemplate/one.txt.pm b/test/data/subtemplate/one.txt.pm new file mode 100644 index 0000000..7e78dd6 --- /dev/null +++ b/test/data/subtemplate/one.txt.pm @@ -0,0 +1,3 @@ +#lang pollen + +one \ No newline at end of file diff --git a/test/data/subtemplate/pollen.rkt b/test/data/subtemplate/pollen.rkt new file mode 100644 index 0000000..bc939b1 --- /dev/null +++ b/test/data/subtemplate/pollen.rkt @@ -0,0 +1,8 @@ +#lang racket/base +(require pollen/world) +(provide (all-defined-out)) + +(module config racket/base + (provide (all-defined-out)) + (define poly-targets '(html txt)) + (define compile-cache-active #f)) \ No newline at end of file diff --git a/test/data/subtemplate/subdir/subsubdir/template.txt b/test/data/subtemplate/subdir/subsubdir/template.txt new file mode 100644 index 0000000..04df01e --- /dev/null +++ b/test/data/subtemplate/subdir/subsubdir/template.txt @@ -0,0 +1 @@ +◊(cdr doc) in subsubdir template \ No newline at end of file diff --git a/test/data/subtemplate/subdir/subsubdir/three.txt b/test/data/subtemplate/subdir/subsubdir/three.txt new file mode 100644 index 0000000..4f4f773 --- /dev/null +++ b/test/data/subtemplate/subdir/subsubdir/three.txt @@ -0,0 +1 @@ +three in subsubdir template \ No newline at end of file diff --git a/test/data/subtemplate/subdir/subsubdir/three.txt.pm b/test/data/subtemplate/subdir/subsubdir/three.txt.pm new file mode 100644 index 0000000..d5e6e68 --- /dev/null +++ b/test/data/subtemplate/subdir/subsubdir/three.txt.pm @@ -0,0 +1,3 @@ +#lang pollen + +three \ No newline at end of file diff --git a/test/data/subtemplate/subdir/two.txt b/test/data/subtemplate/subdir/two.txt new file mode 100644 index 0000000..80ded6c --- /dev/null +++ b/test/data/subtemplate/subdir/two.txt @@ -0,0 +1 @@ +two in main template \ No newline at end of file diff --git a/test/data/subtemplate/subdir/two.txt.pm b/test/data/subtemplate/subdir/two.txt.pm new file mode 100644 index 0000000..3e6ede9 --- /dev/null +++ b/test/data/subtemplate/subdir/two.txt.pm @@ -0,0 +1,3 @@ +#lang pollen + +two \ No newline at end of file diff --git a/test/data/subtemplate/template.txt b/test/data/subtemplate/template.txt new file mode 100644 index 0000000..11505d2 --- /dev/null +++ b/test/data/subtemplate/template.txt @@ -0,0 +1 @@ +◊(cdr doc) in main template \ No newline at end of file diff --git a/test/test-subtemplate.rkt b/test/test-subtemplate.rkt new file mode 100644 index 0000000..d0ee0ca --- /dev/null +++ b/test/test-subtemplate.rkt @@ -0,0 +1,15 @@ +#lang at-exp racket/base +(require rackunit pollen/world racket/runtime-path pollen/render) + +;; define-runtime-path only allowed at top level +(define-runtime-path subtemplate-dir "data/subtemplate") +(define-runtime-path one-source "data/subtemplate/one.txt.pm") +(define-runtime-path two-source "data/subtemplate/subdir/two.txt.pm") +(define-runtime-path three-source "data/subtemplate/subdir/subsubdir/three.txt.pm") + +(parameterize ([current-directory subtemplate-dir] + [world:current-project-root subtemplate-dir] + [current-output-port (open-output-string)]) + (check-equal? (render one-source) "one in main template") + (check-equal? (render two-source) "two in main template") + (check-equal? (render three-source) "three in subsubdir template")) \ No newline at end of file