From 1e523376c90c1483c88ba8a3a7e4c64cd6728b6e Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sat, 15 Mar 2014 19:12:54 -0700 Subject: [PATCH] updates --- command.rkt | 6 +- file.rkt | 4 +- main.rkt | 4 +- pagemap.rkt | 121 --------------- pagetree.rkt | 121 +++++++++++++++ {pagemap => pagetree}/lang/reader.rkt | 2 +- render.rkt | 24 +-- scribblings/module-reference.scrbl | 3 +- scribblings/pagemap.scrbl | 213 -------------------------- scribblings/pagetree.scrbl | 213 ++++++++++++++++++++++++++ scribblings/pollen.scrbl | 7 +- scribblings/render.scrbl | 6 +- scribblings/template.scrbl | 63 +++++++- server-routes.rkt | 14 +- server.rkt | 2 +- template.rkt | 72 ++++----- tests/test-file-tools.rkt | 6 +- tests/test-ptree.rkt | 92 +++++------ world.rkt | 10 +- 19 files changed, 520 insertions(+), 463 deletions(-) delete mode 100644 pagemap.rkt create mode 100644 pagetree.rkt rename {pagemap => pagetree}/lang/reader.rkt (51%) delete mode 100644 scribblings/pagemap.scrbl create mode 100644 scribblings/pagetree.scrbl diff --git a/command.rkt b/command.rkt index 6f0a184..194307f 100644 --- a/command.rkt +++ b/command.rkt @@ -30,9 +30,9 @@ clone copies rendered files to desktop #| [("render") `(begin ;; todo: take extensions off the comand line - (displayln "Render preproc & pagemap files ...") + (displayln "Render preproc & pagetree files ...") (require "render.rkt" "file-tools.rkt" "world.rkt") - (apply render-batch (append-map project-files-with-ext (list world:preproc-source-ext world:pagemap-source-ext))))] + (apply render-batch (append-map project-files-with-ext (list world:preproc-source-ext world:pagetree-source-ext))))] [("clone") (let ([target-path (if (> (len args) 1) (->path (get args 1)) @@ -47,7 +47,7 @@ clone copies rendered files to desktop markup-source? preproc-source? template-source? - pagemap-source? + pagetree-source? pollen-script? magic-directory? racket-file?))) diff --git a/file.rkt b/file.rkt index ee7a5c0..b1b1ddf 100644 --- a/file.rkt +++ b/file.rkt @@ -21,7 +21,7 @@ -;; helper function for pagemap +;; helper function for pagetree ;; make paths absolute to test whether files exist, ;; then convert back to relative (define+provide/contract (visible? path) @@ -87,7 +87,7 @@ (make-source-utility-functions preproc) (make-source-utility-functions null) -(make-source-utility-functions pagemap) +(make-source-utility-functions pagetree) (make-source-utility-functions markup) (make-source-utility-functions template) (make-source-utility-functions scribble) diff --git a/main.rkt b/main.rkt index 617fd29..6ba4a2c 100644 --- a/main.rkt +++ b/main.rkt @@ -30,7 +30,7 @@ (let* ([file-ext-pattern (pregexp "\\w+$")] [here-ext (string->symbol (car (regexp-match file-ext-pattern here-path)))]) (cond - [(equal? here-ext world:pagemap-source-ext) world:reader-mode-pagemap] + [(equal? here-ext world:pagetree-source-ext) world:reader-mode-pagetree] [(equal? here-ext world:markup-source-ext) world:reader-mode-markup] [(equal? here-ext world:markdown-source-ext) world:reader-mode-markdown] [else world:reader-mode-preproc])) @@ -63,7 +63,7 @@ ;; set up the 'doc export (require pollen/decode) (define doc (apply (cond - [(equal? parser-mode world:reader-mode-pagemap) (λ xs ((dynamic-require 'pollen/pagemap 'decode-pagemap) xs))] + [(equal? parser-mode world:reader-mode-pagetree) (λ xs ((dynamic-require 'pollen/pagetree 'decode-pagetree) xs))] ;; 'root is the hook for the decoder function. ;; If it's not a defined identifier, it just hits #%top and becomes `(root ,@body ...) [(or (equal? parser-mode world:reader-mode-markup) diff --git a/pagemap.rkt b/pagemap.rkt deleted file mode 100644 index 6ffb9dd..0000000 --- a/pagemap.rkt +++ /dev/null @@ -1,121 +0,0 @@ -#lang racket/base -(require racket/path) -(require "tools.rkt" "world.rkt" "decode.rkt" sugar txexpr "cache.rkt") - - -(define+provide current-pagemap (make-parameter #f)) - - -(define+provide (node? x) - (->boolean (and (symbol? x) (try (not (whitespace/nbsp? (->string x))) - (except [exn:fail? (λ(e) #f)]))))) - - -(define+provide (nodeish? x) - (try (node? (->symbol x)) - (except [exn:fail? (λ(e) #f)]))) - - -(define/contract+provide (->node x) - (nodeish? . -> . node?) - (->symbol x)) - - -(define+provide/contract (decode-pagemap xs) - (txexpr-elements? . -> . any/c) ; because pagemap is being explicitly validated - (validate-pagemap - (decode (cons world:pagemap-root-node xs) - #:txexpr-elements-proc (λ(xs) (filter (compose1 not whitespace?) xs)) - #:string-proc string->symbol))) ; because faster than ->node - - -(define+provide (validate-pagemap x) - (let ([nodes (pagemap->list x)]) - (and - (andmap (λ(p) (or (node? p) (error (format "validate-pagemap: \"~a\" is not a valid node" p)))) nodes) - (try (members-unique?/error nodes) - (except [exn:fail? (λ(e) (error (format "validate-pagemap: ~a" (exn-message e))))])) - x))) - - -(define+provide (pagemap? x) - (try (->boolean (validate-pagemap x)) - (except [exn:fail? (λ(e) #f)]))) - - -;; Try loading from pagemap file, or failing that, synthesize pagemap. -(define+provide/contract (make-project-pagemap project-dir) - (pathish? . -> . pagemap?) - (define pagemap-source (build-path project-dir world:default-pagemap)) - (cached-require pagemap-source world:main-pollen-export)) - - -(define+provide/contract (parent-node p [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f node?)) - (and pagemap p - (let ([node (->node p)]) - (if (member node (map (λ(x) (if (list? x) (car x) x)) (cdr pagemap))) - (car pagemap) - (ormap (λ(x) (parent-node node x)) (filter list? pagemap)))))) - - -(define+provide/contract (child-nodes p [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f (listof node?))) - (and pagemap p - (let ([node (->node p)]) - (if (equal? node (car pagemap)) - (map (λ(x) (if (list? x) (car x) x)) (cdr pagemap)) - (ormap (λ(x) (child-nodes node x)) (filter list? pagemap)))))) - - -(define+provide/contract (sibling-nodes p [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f (listof node?))) - (child-nodes (parent-node p pagemap) pagemap)) - - -;; flatten tree to sequence -(define+provide/contract (pagemap->list pagemap) - (pagemap? . -> . (listof node?)) - ; use cdr to get rid of root tag at front - (cdr (flatten pagemap))) - - -(define (adjacent-nodes side p [pagemap (current-pagemap)]) - ; ((symbol? (or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f (listof node?))) - (and pagemap p - (let* ([node (->node p)] - [proc (if (equal? side 'left) takef takef-right)] - [result (proc (pagemap->list pagemap) (λ(x) (not (equal? node x))))]) - (and (not (empty? result)) result)))) - - -(define+provide/contract (previous-nodes node [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f (listof node?))) - (adjacent-nodes 'left node pagemap)) - - -(define+provide/contract (next-nodes node [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f (listof node?))) - (adjacent-nodes 'right node pagemap)) - - -(define+provide/contract (previous-node node [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f node?)) - (let ([result (previous-nodes node pagemap)]) - (and result (last result)))) - - -(define+provide/contract (next-node node [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . (or/c #f node?)) - (let ([result (next-nodes node pagemap)]) - (and result (first result)))) - - -(define/contract+provide (path->node path) - (coerce/path? . -> . coerce/symbol?) - (->output-path (find-relative-path (world:current-project-root) (->complete-path path)))) - - -(define+provide/contract (node-in-pagemap? node [pagemap (current-pagemap)]) - (((or/c #f nodeish?)) (pagemap?) . ->* . boolean?) - (->boolean (and node (member node (pagemap->list pagemap))))) diff --git a/pagetree.rkt b/pagetree.rkt new file mode 100644 index 0000000..064c49f --- /dev/null +++ b/pagetree.rkt @@ -0,0 +1,121 @@ +#lang racket/base +(require racket/path) +(require "tools.rkt" "world.rkt" "decode.rkt" sugar txexpr "cache.rkt") + + +(define+provide current-pagetree (make-parameter #f)) + + +(define+provide (pagenode? x) + (->boolean (and (symbol? x) (try (not (whitespace/nbsp? (->string x))) + (except [exn:fail? (λ(e) #f)]))))) + + +(define+provide (pagenodeish? x) + (try (pagenode? (->symbol x)) + (except [exn:fail? (λ(e) #f)]))) + + +(define/contract+provide (->pagenode x) + (pagenodeish? . -> . pagenode?) + (->symbol x)) + + +(define+provide/contract (decode-pagetree xs) + (txexpr-elements? . -> . any/c) ; because pagetree is being explicitly validated + (validate-pagetree + (decode (cons world:pagetree-root-node xs) + #:txexpr-elements-proc (λ(xs) (filter (compose1 not whitespace?) xs)) + #:string-proc string->symbol))) ; because faster than ->pagenode + + +(define+provide (validate-pagetree x) + (let ([pagenodes (pagetree->list x)]) + (and + (andmap (λ(p) (or (pagenode? p) (error (format "validate-pagetree: \"~a\" is not a valid pagenode" p)))) pagenodes) + (try (members-unique?/error pagenodes) + (except [exn:fail? (λ(e) (error (format "validate-pagetree: ~a" (exn-message e))))])) + x))) + + +(define+provide (pagetree? x) + (try (->boolean (validate-pagetree x)) + (except [exn:fail? (λ(e) #f)]))) + + +;; Try loading from pagetree file, or failing that, synthesize pagetree. +(define+provide/contract (make-project-pagetree project-dir) + (pathish? . -> . pagetree?) + (define pagetree-source (build-path project-dir world:default-pagetree)) + (cached-require pagetree-source world:main-pollen-export)) + + +(define+provide/contract (parent pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f pagenode?)) + (and pt pnish + (let ([pagenode (->pagenode pnish)]) + (if (member pagenode (map (λ(x) (if (list? x) (car x) x)) (cdr pt))) + (car pt) + (ormap (λ(x) (parent pagenode x)) (filter list? pt)))))) + + +(define+provide/contract (children p [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f (listof pagenode?))) + (and pt p + (let ([pagenode (->pagenode p)]) + (if (equal? pagenode (car pt)) + (map (λ(x) (if (list? x) (car x) x)) (cdr pt)) + (ormap (λ(x) (children pagenode x)) (filter list? pt)))))) + + +(define+provide/contract (siblings pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f (listof pagenode?))) + (children (parent pnish pt) pt)) + + +;; flatten tree to sequence +(define+provide/contract (pagetree->list pt) + (pagetree? . -> . (listof pagenode?)) + ; use cdr to get rid of root tag at front + (cdr (flatten pt))) + + +(define (adjacents side pnish [pt (current-pagetree)]) + ; ((symbol? (or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f (listof pagenode?))) + (and pt pnish + (let* ([pagenode (->pagenode pnish)] + [proc (if (equal? side 'left) takef takef-right)] + [result (proc (pagetree->list pt) (λ(x) (not (equal? pagenode x))))]) + (and (not (empty? result)) result)))) + + +(define+provide/contract (previous* pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f (listof pagenode?))) + (adjacents 'left pnish pt)) + + +(define+provide/contract (next* pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f (listof pagenode?))) + (adjacents 'right pnish pt)) + + +(define+provide/contract (previous pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f pagenode?)) + (let ([result (previous* pnish pt)]) + (and result (last result)))) + + +(define+provide/contract (next pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . (or/c #f pagenode?)) + (let ([result (next* pnish pt)]) + (and result (first result)))) + + +(define/contract+provide (path->pagenode path) + (coerce/path? . -> . coerce/symbol?) + (->output-path (find-relative-path (world:current-project-root) (->complete-path path)))) + + +(define+provide/contract (in-pagetree? pnish [pt (current-pagetree)]) + (((or/c #f pagenodeish?)) (pagetree?) . ->* . boolean?) + (->boolean (and pnish (member pnish (pagetree->list pt))))) diff --git a/pagemap/lang/reader.rkt b/pagetree/lang/reader.rkt similarity index 51% rename from pagemap/lang/reader.rkt rename to pagetree/lang/reader.rkt index 8d7a841..cf16d87 100644 --- a/pagemap/lang/reader.rkt +++ b/pagetree/lang/reader.rkt @@ -1,4 +1,4 @@ #lang racket/base (require pollen/lang/reader-base) -(make-reader-with-mode world:reader-mode-pagemap) \ No newline at end of file +(make-reader-with-mode world:reader-mode-pagetree) \ No newline at end of file diff --git a/render.rkt b/render.rkt index ccb8678..2096bb2 100644 --- a/render.rkt +++ b/render.rkt @@ -1,6 +1,6 @@ #lang racket/base (require racket/file racket/rerequire racket/path racket/match) -(require sugar "file.rkt" "cache.rkt" "world.rkt" "debug.rkt" "pagemap.rkt" "project-requires.rkt") +(require sugar "file.rkt" "cache.rkt" "world.rkt" "debug.rkt" "pagetree.rkt" "project-requires.rkt") ;; when you want to generate everything fresh, @@ -49,12 +49,12 @@ (for-each render-to-file-if-needed xs)) -(define/contract+provide (render-pagemap pagemap-or-path) - ((or/c pagemap? pathish?) . -> . void?) - (define pagemap (if (pagemap? pagemap-or-path) - pagemap-or-path - (cached-require pagemap-or-path world:main-pollen-export))) - (apply render-batch (pagemap->list pagemap))) +(define/contract+provide (render-pagetree pagetree-or-path) + ((or/c pagetree? pathish?) . -> . void?) + (define pagetree (if (pagetree? pagetree-or-path) + pagetree-or-path + (cached-require pagetree-or-path world:main-pollen-export))) + (apply render-batch (pagetree->list pagetree))) (define/contract+provide (render-for-dev-server so-pathish #:force [force #f]) @@ -64,7 +64,7 @@ [(ormap (λ(test) (test so-path)) (list has/is-null-source? has/is-preproc-source? has/is-markup-source? has/is-scribble-source?)) (let-values ([(source-path output-path) (->source+output-paths so-path)]) (render-to-file-if-needed source-path output-path #:force force))] - [(pagemap-source? so-path) (render-pagemap so-path)])) + [(pagetree-source? so-path) (render-pagetree so-path)])) (void)) @@ -163,7 +163,7 @@ ,(require-project-require-files source-path) (let ([doc (cached-require ,source-path ',world:main-pollen-export)] [metas (cached-require ,source-path ',world:meta-pollen-export)]) - (local-require pollen/pagemap pollen/template pollen/top) + (local-require pollen/pagetree pollen/template pollen/top) (define here (metas->here metas)) (include-template #:command-char ,world:template-field-delimiter ,(->string (find-relative-path source-dir template-path)))))) @@ -224,7 +224,7 @@ pollen/decode pollen/file pollen/main - pollen/pagemap + pollen/pagetree pollen/cache sugar txexpr @@ -244,7 +244,7 @@ (list? . -> . bytes?) (parameterize ([current-namespace (make-base-namespace)] [current-output-port (current-error-port)] - [current-pagemap (make-project-pagemap (world:current-project-root))]) + [current-pagetree (make-project-pagetree (world:current-project-root))]) (for-each (λ(mod-name) (namespace-attach-module cache-ns mod-name)) `(web-server/templates xml @@ -257,7 +257,7 @@ pollen/debug pollen/decode pollen/file - pollen/pagemap + pollen/pagetree pollen/cache sugar txexpr diff --git a/scribblings/module-reference.scrbl b/scribblings/module-reference.scrbl index 06681cf..552d706 100644 --- a/scribblings/module-reference.scrbl +++ b/scribblings/module-reference.scrbl @@ -7,5 +7,6 @@ @include-section["cache.scrbl"] @include-section["decode.scrbl"] @include-section["file.scrbl"] -@include-section["pagemap.scrbl"] +@include-section["pagetree.scrbl"] @include-section["render.scrbl"] +@include-section["template.scrbl"] diff --git a/scribblings/pagemap.scrbl b/scribblings/pagemap.scrbl deleted file mode 100644 index 8d4fe67..0000000 --- a/scribblings/pagemap.scrbl +++ /dev/null @@ -1,213 +0,0 @@ -#lang scribble/manual - -@(require scribble/eval pollen/cache pollen/world (for-label racket (except-in pollen #%module-begin) pollen/world pollen/pagemap txexpr pollen/decode pollen/file)) - -@(define my-eval (make-base-eval)) -@(my-eval `(require pollen pollen/pagemap txexpr)) - -@title{Pagemaps} - -@defmodule[pollen/pagemap] - -A @italic{pagemap} is a hierarchical list of Pollen output files. A pagemap source file has the extension @code[(format ".~a" world:pagemap-source-ext)]. A pagemap provides a convenient way of separating the structure of the pages from the page sources, and navigating around this structure. - -Pagemaps are made of @italic{nodes}. Usually these nodes will be names of output files in your project. (If you think it would've been more logical to call them ``pages,'' perhaps. When I think of a web page, I think of a file on a disk. Whereas nodes may — and often do — refer to files that don't yet exist.) - -Books and other long documents are usually organized in a structured way — at minimum they have a sequence of pages, but more often they have sections with subsequences within. Individual Pollen source files don't know anything about how they're connected to other files. In theory, you could maintain this information within each source file. This would be a poor use of human energy. Let the pagemap figure it out. - -@defproc[ -(pagemap? -[possible-pagemap any/c]) -boolean?] -Test whether @racket[_possible-pagemap] is a valid pagemap. It must be a @racket[txexpr?] where all elements are @racket[node?] and unique within @racket[_possible-pagemap] (not counting the root node). - -@examples[#:eval my-eval -(pagemap? '(root index.html)) -(pagemap? '(root index.html index.html)) -(pagemap? '(root index.html "index.html")) -(define nested-pmap '(root 1.html 2.html (3.html 3a.html 3b.html))) -(pagemap? nested-pmap) -(pagemap? `(root index.html ,nested-pmap (subsection.html more.html))) -(pagemap? `(root index.html ,nested-pmap (subsection.html ,nested-pmap))) -] - -@defproc[ -(validate-pagemap -[possible-pagemap any/c]) -pagemap?] -Like @racket[pagemap?], but raises a descriptive error if @racket[_possible-pagemap] is invalid, and otherwise returns @racket[_possible-pagemap] itself. - -@examples[#:eval my-eval -(validate-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(validate-pagemap `(root (,+ son.html daughter.html) uncle.html)) -(validate-pagemap '(root (mama.html son.html son.html) mama.html)) -] - - -@defproc[ -(node? -[possible-node any/c]) -boolean?] -Test whether @racket[_possible-node] is a valid node (short for ``pagemap node''). A node can be any @racket[symbol?] that is not @racket[whitespace/nbsp?] Every leaf of a pagemap is a node. In practice, your nodes will likely be names of output files. - -@margin-note{Nodes are symbols (rather than strings) so that pagemaps will be valid tagged X-expressions, which is a more convenient format for validation & processing.} - -@examples[#:eval my-eval -(map node? '(symbol index.html | silly |)) -(map node? '(9.999 "index.html" (p "Hello") | |)) -] - - -@defproc[ -(nodeish? -[v any/c]) -boolean?] -Return @racket[#t] if @racket[_v] can be converted with @racket[->node]. - -@examples[#:eval my-eval -(map nodeish? '(9.999 "index.html" | |)) -] - - -@defproc[ -(->node -[v nodeish?]) -node?] -Convert @racket[_v] to a node. - -@examples[#:eval my-eval -(map nodeish? '(symbol 9.999 "index.html" | silly |)) -(map ->node '(symbol 9.999 "index.html" | silly |)) -] - - - -@section{Navigation} - - -@defparam[current-pagemap pagemap pagemap? - #:value #f]{ -A parameter that defines the default pagemap used by pagemap navigation functions (e.g., @racket[parent-node], @racket[chidren], et al.) if another is not explicitly specified. Initialized to @racket[#f].} - - -@defproc[ -(parent-node -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f node?)] -Find the parent-node node of @racket[_p] within @racket[_pagemap]. Return @racket[#f] if there isn't one. - -@examples[#:eval my-eval -(current-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(parent-node 'son.html) -(parent-node "mama.html") -(parent-node (parent-node 'son.html)) -(parent-node (parent-node (parent-node 'son.html))) -] - -@defproc[ -(child-nodes -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f node?)] -Find the child nodes of @racket[_p] within @racket[_pagemap]. Return @racket[#f] if there aren't any. - -@examples[#:eval my-eval -(current-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(child-nodes 'mama.html) -(child-nodes 'uncle.html) -(child-nodes 'root) -(map child-nodes (child-nodes 'root)) -] - - -@defproc[ -(sibling-nodes -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f node?)] -Find the sibling nodes of @racket[_p] within @racket[_pagemap]. The list will include @racket[_p] itself. But the function will still return @racket[#f] if @racket[_pagemap] is @racket[#f]. - -@examples[#:eval my-eval -(current-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(sibling-nodes 'son.html) -(sibling-nodes 'daughter.html) -(sibling-nodes 'mama.html) -] - - -@deftogether[( - -@defproc[ -(previous-node -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f node?)] - -@defproc[ -(previous-nodes -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f (listof node?))] -)] -Return the node immediately before @racket[_p]. For @racket[previous-nodes], return all the nodes before @racket[_p], in sequence. In both cases, return @racket[#f] if there aren't any nodes. The root node is ignored. - -@examples[#:eval my-eval -(current-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(previous-node 'daughter.html) -(previous-node 'son.html) -(previous-node (previous-node 'daughter.html)) -(previous-node 'mama.html) -(previous-nodes 'daughter.html) -(previous-nodes 'uncle.html) -] - -@deftogether[( - -@defproc[ -(next-node -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f node?)] - -@defproc[ -(next-nodes -[p (or/c #f nodeish?)] -[pagemap pagemap? (current-pagemap)]) -(or/c #f (listof node?))] -)] -Return the node immediately after @racket[_p]. For @racket[next-nodes], return all the nodes after @racket[_p], in sequence. In both cases, return @racket[#f] if there aren't any nodes. The root node is ignored. - -@examples[#:eval my-eval -(current-pagemap '(root (mama.html son.html daughter.html) uncle.html)) -(next-node 'son.html) -(next-node 'daughter.html) -(next-node (next-node 'son.html)) -(next-node 'uncle.html) -(next-nodes 'mama.html) -(next-nodes 'daughter.html) -] - -@section{Utilities} - -@defproc[ -(pagemap->list -[pagemap pagemap?]) -list? -] -Convert @racket[_pagemap] to a simple list, preserving order. - -@defproc[ -(node-in-pagemap? -[node node?] -[pagemap pagemap? (current-pagemap)]) -boolean? -] -Report whether @racket[_node] is in @racket[_pagemap]. - -@defproc[ -(path->node -[p pathish?]) -node? -] -Convert path @racket[_p] to a node — meaning, make it relative to @racket[world:current-project-root], run it through @racket[->output-path], and convert it to a symbol. Does not tell you whether the resultant node actually exists in the current pagemap (for that, use @racket[node-in-pagemap?]). \ No newline at end of file diff --git a/scribblings/pagetree.scrbl b/scribblings/pagetree.scrbl new file mode 100644 index 0000000..348a131 --- /dev/null +++ b/scribblings/pagetree.scrbl @@ -0,0 +1,213 @@ +#lang scribble/manual + +@(require scribble/eval pollen/cache pollen/world (for-label racket (except-in pollen #%module-begin) pollen/world pollen/pagetree txexpr pollen/decode pollen/file)) + +@(define my-eval (make-base-eval)) +@(my-eval `(require pollen pollen/pagetree txexpr)) + +@title{Pagetrees} + +@defmodule[pollen/pagetree] + +A @italic{pagetree} is a hierarchical list of Pollen output files. A pagetree source file has the extension @code[(format ".~a" world:pagetree-source-ext)]. A pagetree provides a convenient way of separating the structure of the pages from the page sources, and navigating around this structure. + +Pagetrees are made of @italic{pagenodes}. Usually these pagenodes will be names of output files in your project. (If you think it would've been more logical to just call them ``pages,'' perhaps. When I think of a web page, I think of a file on a disk. Whereas pagenodes may — and often do — refer to files that don't yet exist.) + +Books and other long documents are usually organized in a structured way — at minimum they have a sequence of pages, but more often they have sections with subsequences within. Individual Pollen source files don't know anything about how they're connected to other files. In theory, you could maintain this information within each source file. This would be a poor use of human energy. Let the pagetree figure it out. + +@defproc[ +(pagetree? +[possible-pagetree any/c]) +boolean?] +Test whether @racket[_possible-pagetree] is a valid pagetree. It must be a @racket[txexpr?] where all elements are @racket[pagenode?] and unique within @racket[_possible-pagetree] (not counting the root node). + +@examples[#:eval my-eval +(pagetree? '(root index.html)) +(pagetree? '(root index.html index.html)) +(pagetree? '(root index.html "index.html")) +(define nested-ptree '(root 1.html 2.html (3.html 3a.html 3b.html))) +(pagetree? nested-ptree) +(pagetree? `(root index.html ,nested-ptree (subsection.html more.html))) +(pagetree? `(root index.html ,nested-ptree (subsection.html ,nested-ptree))) +] + +@defproc[ +(validate-pagetree +[possible-pagetree any/c]) +pagetree?] +Like @racket[pagetree?], but raises a descriptive error if @racket[_possible-pagetree] is invalid, and otherwise returns @racket[_possible-pagetree] itself. + +@examples[#:eval my-eval +(validate-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(validate-pagetree `(root (,+ son.html daughter.html) uncle.html)) +(validate-pagetree '(root (mama.html son.html son.html) mama.html)) +] + + +@defproc[ +(pagenode? +[possible-pagenode any/c]) +boolean?] +Test whether @racket[_possible-pagenode] is a valid pagenode. A pagenode can be any @racket[symbol?] that is not @racket[whitespace/nbsp?] Every leaf of a pagetree is a pagenode. In practice, your pagenodes will likely be names of output files. + +@margin-note{Pagenodes are symbols (rather than strings) so that pagetrees will be valid tagged X-expressions, which is a more convenient format for validation & processing.} + +@examples[#:eval my-eval +(map pagenode? '(symbol index.html | silly |)) +(map pagenode? '(9.999 "index.html" (p "Hello") | |)) +] + + +@defproc[ +(pagenodeish? +[v any/c]) +boolean?] +Return @racket[#t] if @racket[_v] can be converted with @racket[->pagenode]. + +@examples[#:eval my-eval +(map pagenodeish? '(9.999 "index.html" | |)) +] + + +@defproc[ +(->pagenode +[v pagenodeish?]) +pagenode?] +Convert @racket[_v] to a pagenode. + +@examples[#:eval my-eval +(map pagenodeish? '(symbol 9.999 "index.html" | silly |)) +(map ->pagenode '(symbol 9.999 "index.html" | silly |)) +] + + + +@section{Navigation} + + +@defparam[current-pagetree pagetree pagetree? + #:value #f]{ +A parameter that defines the default pagetree used by pagetree navigation functions (e.g., @racket[parent-pagenode], @racket[chidren], et al.) if another is not explicitly specified. Initialized to @racket[#f].} + + +@defproc[ +(parent +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f pagenode?)] +Find the parent pagenode of @racket[_p] within @racket[_pagetree]. Return @racket[#f] if there isn't one. + +@examples[#:eval my-eval +(current-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(parent 'son.html) +(parent "mama.html") +(parent (parent 'son.html)) +(parent (parent (parent 'son.html))) +] + +@defproc[ +(children +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f pagenode?)] +Find the child pagenodes of @racket[_p] within @racket[_pagetree]. Return @racket[#f] if there aren't any. + +@examples[#:eval my-eval +(current-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(children 'mama.html) +(children 'uncle.html) +(children 'root) +(map children (children 'root)) +] + + +@defproc[ +(siblings +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f pagenode?)] +Find the sibling pagenodes of @racket[_p] within @racket[_pagetree]. The list will include @racket[_p] itself. But the function will still return @racket[#f] if @racket[_pagetree] is @racket[#f]. + +@examples[#:eval my-eval +(current-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(siblings 'son.html) +(siblings 'daughter.html) +(siblings 'mama.html) +] + + +@deftogether[( + +@defproc[ +(previous +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f pagenode?)] + +@defproc[ +(previous* +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f (listof pagenode?))] +)] +Return the pagenode immediately before @racket[_p]. For @racket[previous*], return all the pagenodes before @racket[_p], in sequence. In both cases, return @racket[#f] if there aren't any pagenodes. The root pagenode is ignored. + +@examples[#:eval my-eval +(current-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(previous 'daughter.html) +(previous 'son.html) +(previous (previous 'daughter.html)) +(previous 'mama.html) +(previous* 'daughter.html) +(previous* 'uncle.html) +] + +@deftogether[( + +@defproc[ +(next +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f pagenode?)] + +@defproc[ +(next* +[p (or/c #f pagenodeish?)] +[pagetree pagetree? (current-pagetree)]) +(or/c #f (listof pagenode?))] +)] +Return the pagenode immediately after @racket[_p]. For @racket[next*], return all the pagenodes after @racket[_p], in sequence. In both cases, return @racket[#f] if there aren't any pagenodes. The root pagenode is ignored. + +@examples[#:eval my-eval +(current-pagetree '(root (mama.html son.html daughter.html) uncle.html)) +(next 'son.html) +(next 'daughter.html) +(next (next 'son.html)) +(next 'uncle.html) +(next* 'mama.html) +(next* 'daughter.html) +] + +@section{Utilities} + +@defproc[ +(pagetree->list +[pagetree pagetree?]) +list? +] +Convert @racket[_pagetree] to a simple list, preserving order. + +@defproc[ +(in-pagetree? +[pagenode pagenode?] +[pagetree pagetree? (current-pagetree)]) +boolean? +] +Report whether @racket[_pagenode] is in @racket[_pagetree]. + +@defproc[ +(path->pagenode +[p pathish?]) +pagenode? +] +Convert path @racket[_p] to a pagenode — meaning, make it relative to @racket[world:current-project-root], run it through @racket[->output-path], and convert it to a symbol. Does not tell you whether the resultant pagenode actually exists in the current pagetree (for that, use @racket[pagenode-in-pagetree?]). \ No newline at end of file diff --git a/scribblings/pollen.scrbl b/scribblings/pollen.scrbl index 3c5806e..806e271 100644 --- a/scribblings/pollen.scrbl +++ b/scribblings/pollen.scrbl @@ -6,7 +6,9 @@ @(my-eval `(require pollen)) -@title{Pollen: the book is a program} +@title[#:style 'toc]{Pollen: the book is a program} + + @author[(author+email "Matthew Butterick" "mb@mbtype.com")] @@ -22,6 +24,9 @@ That language is Racket. I chose Racket because while the idea for Pollen had be Or, if you can find a better digital book-publishing tool, use that. Personally, I'm never going back to the way I used to work. +@local-table-of-contents[] + + @section{Installation} Install Racket, which includes DrRacket. diff --git a/scribblings/render.scrbl b/scribblings/render.scrbl index 2d3789d..a215f87 100644 --- a/scribblings/render.scrbl +++ b/scribblings/render.scrbl @@ -66,9 +66,9 @@ Render multiple @racket[_source-paths] in one go. This can be faster than @racke @defproc*[ ( -[(render-pagemap [pagemap pagemap?]) void?] -[(render-pagemap [pagemap-source pathish?]) void?])] -Using @racket[_pagemap], or a pagemap loaded from @racket[_pagemap-source], render the files included in that pagemap using @racket[render-batch]. +[(render-pagetree [pagetree pagetree?]) void?] +[(render-pagetree [pagetree-source pathish?]) void?])] +Using @racket[_pagetree], or a pagetree loaded from @racket[_pagetree-source], render the files included in that pagetree using @racket[render-batch]. @defproc[ (get-template-for diff --git a/scribblings/template.scrbl b/scribblings/template.scrbl index 2dbc0cc..15b8cde 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)) +@(require scribble/eval pollen/cache pollen/world (for-label racket (except-in pollen #%module-begin) pollen/template pollen/render xml pollen/pagetree)) @(define my-eval (make-base-eval)) @(my-eval `(require pollen pollen/template xml)) @@ -22,3 +22,64 @@ Convert @racket[_xexpr] to an HTML string. Similar to @racket[xexpr->string], bu (xexpr->string tx) (->html tx) ] + +Be careful not to pass existing HTML strings into this function, because the @code{<} and @code{>} symbols will be escaped. Fine if that's what you want, but you probably don't. + +@examples[#:eval my-eval +(define tx '(p "You did" (em "what?"))) +(->html tx) +(->html (->html tx)) +] + +@deftogether[( + +@defproc[ +(from +[query symbolish?] +[pagenode pagenodeish?]) +(or/c #f txexpr-element?)] + +@defproc[ +(from* +[query symbolish?] +[pagenode pagenodeish?]) +(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. + + + + +@defproc[ +(from-metas +[query symbolish?] +[meta-source (or/c pagenodeish? hash?)]) +(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]. + +@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) +] + + + +@defproc[ +(from-doc +[query symbolish?] +[doc-source (or/c pagenodeish? txexpr?)]) +(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]. + +@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) +] + + diff --git a/server-routes.rkt b/server-routes.rkt index b2340e0..7c3e48e 100644 --- a/server-routes.rkt +++ b/server-routes.rkt @@ -5,7 +5,7 @@ (require web-server/http/request-structs) (require web-server/http/response-structs) (require 2htdp/image) -(require "world.rkt" "render.rkt" sugar txexpr "file.rkt" "debug.rkt" "pagemap.rkt" "cache.rkt") +(require "world.rkt" "render.rkt" sugar txexpr "file.rkt" "debug.rkt" "pagetree.rkt" "cache.rkt") (module+ test (require rackunit)) @@ -173,12 +173,12 @@ (cond ; in cell [source (cons (format "in/~a" source) "in")] - [(or (pagemap-source? filename) (sourceish? filename)) (cons (format "in/~a" filename) "in")] + [(or (pagetree-source? filename) (sourceish? filename)) (cons (format "in/~a" filename) "in")] [else empty-cell]) (cond ; out cell [(directory-exists? (build-path dashboard-dir filename)) (cons #f #f)] - [(pagemap-source? filename) empty-cell] + [(pagetree-source? filename) empty-cell] [else (cons (format "out/~a" filename) "out")])))))) (define (ineligible-path? x) (or (not (visible? x)) (member x world:reserved-paths))) @@ -190,16 +190,16 @@ (define path-is-directory? (λ(f) (directory-exists? (build-path dashboard-dir f)))) (define subdirectories (filter path-is-directory? all-paths)) (define files (filter-not path-is-directory? all-paths)) - (define pagemap-sources (filter pagemap-source? files)) - (define other-files (filter-not pagemap-source? files)) + (define pagetree-sources (filter pagetree-source? files)) + (define other-files (filter-not pagetree-source? files)) (define (sort-names xs) (sort xs #:key ->string stringpath (pagemap->list (cached-require (->path dashboard-pmap) world:main-pollen-export))) + (map ->path (pagetree->list (cached-require (->path dashboard-pmap) world:main-pollen-export))) (unique-sorted-output-paths (directory-list dashboard-dir))))) (body-wrapper diff --git a/server.rkt b/server.rkt index 5962fbc..1164914 100755 --- a/server.rkt +++ b/server.rkt @@ -13,7 +13,7 @@ (define-values (pollen-servlet _) (dispatch-rules - [((string-arg) ... (? pagemap-source?)) route-dashboard] + [((string-arg) ... (? pagetree-source?)) route-dashboard] [((string-arg) ... "in" (string-arg)) route-in] [((string-arg) ... "out" (string-arg)) route-out] [((string-arg) ... "xexpr" (string-arg)) route-xexpr] diff --git a/template.rkt b/template.rkt index aeb9614..d9bbce0 100644 --- a/template.rkt +++ b/template.rkt @@ -1,7 +1,7 @@ #lang racket/base (require (for-syntax racket/base)) (require racket/string xml xml/path sugar/define sugar/container sugar/coerce/contract) -(require "tools.rkt" txexpr "world.rkt" "cache.rkt" "pagemap.rkt") +(require "tools.rkt" txexpr "world.rkt" "cache.rkt" "pagetree.rkt") (require sugar/coerce/value) @@ -9,73 +9,63 @@ (define/contract+provide (metas->here metas) - (hash? . -> . node?) - (path->node ('here-path . from-metas . metas))) + (hash? . -> . pagenode?) + (path->pagenode ('here-path . from-metas . metas))) -(define/contract (get-doc node-or-path) - ((or/c node? pathish?) . -> . (or/c txexpr? string?)) +(define/contract (get-doc pagenode-or-path) + ((or/c pagenode? pathish?) . -> . (or/c txexpr? string?)) (define source-path (->source-path (cond - [(node? node-or-path) (node->path node-or-path)] - [else node-or-path]))) + [(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" node-or-path (current-directory))))) + (error (format "get-doc: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) -(define/contract (get-metas node-or-path) - ((or/c node? pathish?) . -> . hash?) +(define/contract (get-metas pagenode-or-path) + ((or/c pagenode? pathish?) . -> . hash?) (define source-path (->source-path (cond - [(node? node-or-path) (node->path node-or-path)] - [else node-or-path]))) + [(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" node-or-path (current-directory))))) + (error (format "get-metas: no source found for '~a' in directory ~a" pagenode-or-path (current-directory))))) -(define (node->path node) - (build-path (world:current-project-root) (symbol->string node))) +(define (pagenode->path pagenode) + (build-path (world:current-project-root) (symbol->string pagenode))) -(define+provide/contract (from-node query node) +(define+provide/contract (from query pagenode) (coerce/symbol? coerce/symbol? . -> . (or/c #f txexpr-element?)) - (define result (from-node* query node)) + (define result (from* query pagenode)) (if (null? result) #f (car result))) -(define+provide/contract (from-node* query node) - (coerce/symbol? coerce/symbol? . -> . (listof txexpr-element?)) - (define meta-result (from-metas query node)) - (append (if meta-result (list meta-result) null) (from-doc query node))) +(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/contract+provide (from-metas query node-or-metas) - (coerce/symbol? (or/c node? hash?) . -> . (or/c #f txexpr-element?)) - (let ([metas (or (and (node? node-or-metas) (get-metas node-or-metas)) node-or-metas)]) +(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/contract+provide (from-doc query node-or-doc) - (coerce/symbol? (or/c node? txexpr?) . -> . (or/c #f txexpr-elements?)) - (let ([doc (or (and (node? node-or-doc) (get-doc node-or-doc)) node-or-doc)]) - (with-handlers ([exn:fail? (λ(e) null)]) +(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)))) -;; 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) (xexpr? . -> . string?) (xexpr->html x)) diff --git a/tests/test-file-tools.rkt b/tests/test-file-tools.rkt index 3dce0e4..c886c5e 100644 --- a/tests/test-file-tools.rkt +++ b/tests/test-file-tools.rkt @@ -71,9 +71,9 @@ (check-false (preproc-source? #f))) (module+ test - (check-true (pagemap-source? (format "foo.~a" world:pagemap-source-ext))) - (check-false (pagemap-source? (format "~a.foo" world:pagemap-source-ext))) - (check-false (pagemap-source? #f))) + (check-true (pagetree-source? (format "foo.~a" world:pagetree-source-ext))) + (check-false (pagetree-source? (format "~a.foo" world:pagetree-source-ext))) + (check-false (pagetree-source? #f))) (module+ test (check-true (markup-source? "foo.pm")) (check-false (markup-source? "foo.p")) diff --git a/tests/test-ptree.rkt b/tests/test-ptree.rkt index ba9c661..e363e9b 100644 --- a/tests/test-ptree.rkt +++ b/tests/test-ptree.rkt @@ -1,69 +1,69 @@ #lang racket/base (require rackunit) -(require "../pagemap.rkt" "../world.rkt") +(require "../pagetree.rkt" "../world.rkt") -(check-false (node? "foo-bar")) -(check-false (node? "Foo_Bar_0123")) -(check-true (node? 'foo-bar)) -(check-false (node? "foo-bar.p")) -(check-false (node? "/Users/MB/foo-bar")) -(check-false (node? #f)) -(check-false (node? "")) -(check-false (node? " ")) +(check-false (pagenode? "foo-bar")) +(check-false (pagenode? "Foo_Bar_0123")) +(check-true (pagenode? 'foo-bar)) +(check-false (pagenode? "foo-bar.p")) +(check-false (pagenode? "/Users/MB/foo-bar")) +(check-false (pagenode? #f)) +(check-false (pagenode? "")) +(check-false (pagenode? " ")) -(check-true (pagemap? '(foo))) -(check-true (pagemap? '(foo (hee)))) -(check-true (pagemap? '(foo (hee (uncle foo))))) -(check-false (pagemap? '(foo (hee hee (uncle foo))))) +(check-true (pagetree? '(foo))) +(check-true (pagetree? '(foo (hee)))) +(check-true (pagetree? '(foo (hee (uncle foo))))) +(check-false (pagetree? '(foo (hee hee (uncle foo))))) -(define test-pagemap-main `(pagemap-main foo bar (one (two three)))) -(define test-pagemap (pagemap-root->pagemap test-pagemap-main)) -(check-equal? (parent 'three test-pagemap) 'two) -(check-equal? (parent "three" test-pagemap) 'two) -(check-false (parent #f test-pagemap)) -(check-false (parent 'nonexistent-name test-pagemap)) +(define test-pagetree-main `(pagetree-main foo bar (one (two three)))) +(define test-pagetree (pagetree-root->pagetree test-pagetree-main)) +(check-equal? (parent 'three test-pagetree) 'two) +(check-equal? (parent "three" test-pagetree) 'two) +(check-false (parent #f test-pagetree)) +(check-false (parent 'nonexistent-name test-pagetree)) -(check-equal? (children 'one test-pagemap) '(two)) -(check-equal? (children 'two test-pagemap) '(three)) -(check-false (children 'three test-pagemap)) -(check-false (children #f test-pagemap)) -(check-false (children 'fooburger test-pagemap)) +(check-equal? (children 'one test-pagetree) '(two)) +(check-equal? (children 'two test-pagetree) '(three)) +(check-false (children 'three test-pagetree)) +(check-false (children #f test-pagetree)) +(check-false (children 'fooburger test-pagetree)) -(check-equal? (siblings 'one test-pagemap) '(foo bar one)) -(check-equal? (siblings 'foo test-pagemap) '(foo bar one)) -(check-equal? (siblings 'two test-pagemap) '(two)) -(check-false (siblings #f test-pagemapap)) -(check-false (siblings 'invalid-key test-pagemap)) +(check-equal? (siblings 'one test-pagetree) '(foo bar one)) +(check-equal? (siblings 'foo test-pagetree) '(foo bar one)) +(check-equal? (siblings 'two test-pagetree) '(two)) +(check-false (siblings #f test-pagetree)) +(check-false (siblings 'invalid-key test-pagetree)) -(check-equal? (previous* 'one test-pagemap) '(foo bar)) -(check-equal? (previous* 'three test-pagemap) '(foo bar one two)) -(check-false (previous* 'foo test-pagemap)) +(check-equal? (previous* 'one test-pagetree) '(foo bar)) +(check-equal? (previous* 'three test-pagetree) '(foo bar one two)) +(check-false (previous* 'foo test-pagetree)) -(check-equal? (previous 'one test-pagemap) 'bar) -(check-equal? (previous 'three test-pagemap) 'two) -(check-false (previous 'foo test-pagemap)) +(check-equal? (previous 'one test-pagetree) 'bar) +(check-equal? (previous 'three test-pagetree) 'two) +(check-false (previous 'foo test-pagetree)) -(check-equal? (next 'foo test-pagemap) 'bar) -(check-equal? (next 'one test-pagemap) 'two) -(check-false (next 'three test-pagemap)) +(check-equal? (next 'foo test-pagetree) 'bar) +(check-equal? (next 'one test-pagetree) 'two) +(check-false (next 'three test-pagetree)) -(check-equal? (pagemap->list test-pagemap) '(foo bar one two three)) +(check-equal? (pagetree->list test-pagetree) '(foo bar one two three)) (let ([sample-main `(world:pollen-tree-root-name foo bar (one (two three)))]) - (check-equal? (pagemap-root->pagemap sample-main) + (check-equal? (pagetree-root->pagetree sample-main) `(world:pollen-tree-root-name foo bar (one (two three))))) (define files '("foo.html" "bar.html" "bar.html.p" "zap.html" "zap.xml")) -(check-equal? (node->url/paths 'foo.html files) "foo.html") -(check-equal? (node->url/paths 'bar.html files) "bar.html") +(check-equal? (pagenode->url/paths 'foo.html files) "foo.html") +(check-equal? (pagenode->url/paths 'bar.html files) "bar.html") ;; (check-equal? (name->url 'zap files) 'error) ;; todo: how to test error? -(check-false (node->url/paths 'hee files)) +(check-false (pagenode->url/paths 'hee files)) -(set! test-pagemap-main `(,world:pagemap-root-node foo bar (one (two three)))) -(check-equal? (pagemap-root->pagemap test-pagemap-main) - `(,world:pagemap-root-node foo bar (one (two three)))) \ No newline at end of file +(set! test-pagetree-main `(,world:pagetree-root-node foo bar (one (two three)))) +(check-equal? (pagetree-root->pagetree test-pagetree-main) + `(,world:pagetree-root-node foo bar (one (two three)))) \ No newline at end of file diff --git a/world.rkt b/world.rkt index e2699be..da9bc45 100644 --- a/world.rkt +++ b/world.rkt @@ -8,7 +8,7 @@ (define markup-source-ext 'pm) (define markdown-source-ext 'pmd) (define null-source-ext 'p) -(define pagemap-source-ext 'pmap) +(define pagetree-source-ext 'ptree) (define template-source-ext 'pt) (define scribble-source-ext 'scrbl) @@ -17,12 +17,12 @@ (define reader-mode-preproc 'pre) (define reader-mode-markup 'markup) (define reader-mode-markdown 'markdown) -(define reader-mode-pagemap 'pmap) +(define reader-mode-pagetree 'ptree) -(define decodable-extensions (list markup-source-ext pagemap-source-ext)) +(define decodable-extensions (list markup-source-ext pagetree-source-ext)) -(define default-pagemap "index.pmap") -(define pagemap-root-node 'pagemap-root) +(define default-pagetree "index.ptree") +(define pagetree-root-node 'pagetree-root) (define template-source-prefix "-") (define expression-delimiter #\◊)