Overview
Context
Changes
Modified cache.rkt
from [cd0a6087]
to [22c08e42].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
(require deta
db/base
db/sqlite3
threading
pollen/setup
racket/match
(rename-in racket/list
(group-by group-list-by))
"dust.rkt"
(except-in pollen/core select))
(provide init-cache-db!
cache-conn ; The most eligible bachelor in Neo Yokyo
(schema-out cache:article)
(schema-out cache:note)
(schema-out cache:series)
(schema-out cache:index-entry)
(schema-out listing)
delete-article!
delete-notes!
articles
articles+notes
listing-htmls
fenced-listing
unfence
preheat-series!
series-grouped-list)
;; Cache DB and Schemas
(define DBFILE (build-path (current-project-root) "vitreous.sqlite"))
(define cache-conn (make-parameter (sqlite3-connect #:database DBFILE #:mode 'create)))
(define-schema cache:article #:table "articles"
([id id/f #:primary-key #:auto-increment]
[page symbol/f]
[title-plain string/f]
[title-html-flow string/f]
[title-specified? boolean/f]
[published string/f]
[updated string/f]
[author string/f]
[conceal string/f]
[series-page symbol/f]
[noun-singular string/f]
[note-count integer/f]
[content-html string/f]
[disposition string/f]
[disp-html-anchor string/f]
[listing-full-html string/f] ; full content but without notes
[listing-excerpt-html string/f] ; Not used for now
[listing-short-html string/f])) ; Date and title only
(define-schema cache:note #:table "notes"
|
<
<
<
|
<
<
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
(require deta
db/base
db/sqlite3
threading
pollen/setup
racket/match
"dust.rkt"
(except-in pollen/core select))
(provide init-cache-db!
cache-conn ; The most eligible bachelor in Neo Yokyo
(schema-out cache:article)
(schema-out cache:note)
(schema-out cache:index-entry)
(schema-out listing)
delete-article!
delete-notes!
articles
articles+notes
listing-htmls
fenced-listing
unfence)
;; Cache DB and Schemas
(define DBFILE (build-path (current-project-root) "vitreous.sqlite"))
(define cache-conn (make-parameter (sqlite3-connect #:database DBFILE #:mode 'create)))
(define-schema cache:article #:table "articles"
([id id/f #:primary-key #:auto-increment]
[page symbol/f]
[title-plain string/f]
[title-html-flow string/f]
[title-specified? boolean/f]
[published string/f]
[updated string/f]
[author string/f]
[conceal string/f]
[series-page symbol/f]
[noun-singular string/f]
[note-count integer/f]
[content-html string/f]
[disposition string/f]
[disp-html-anchor string/f]
[listing-full-html string/f] ; full content but without notes
[listing-excerpt-html string/f] ; Not used for now
[listing-short-html string/f])) ; Date and title only
(define-schema cache:note #:table "notes"
|
︙ | | | ︙ | |
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
[content-html string/f]
[series-page symbol/f]
[conceal string/f]
[listing-full-html string/f]
[listing-excerpt-html string/f] ; Not used for now
[listing-short-html string/f])) ; Date and title only
(define-schema cache:series #:table "series"
([id id/f #:primary-key #:auto-increment]
[page symbol/f]
[title string/f]
[published string/f]
[noun-plural string/f]
[noun-singular string/f]))
(define-schema cache:index-entry #:table "index_entries"
([id id/f #:primary-key #:auto-increment]
[entry string/f]
[subentry string/f]
[page symbol/f]
[html-anchor string/f]))
(define-schema listing
#:virtual
([path string/f]
[title string/f]
[author string/f]
[published string/f]
[updated string/f]
[html string/f]))
(define (init-cache-db!)
(create-table! (cache-conn) 'cache:article)
(create-table! (cache-conn) 'cache:note)
(create-table! (cache-conn) 'cache:series)
(create-table! (cache-conn) 'cache:index-entry))
(define (delete-article! page)
(query-exec (cache-conn)
(~> (from cache:article #:as a)
(where (= a.page ,(format "~a" page)))
delete)))
|
<
<
<
<
<
<
<
<
<
|
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
[content-html string/f]
[series-page symbol/f]
[conceal string/f]
[listing-full-html string/f]
[listing-excerpt-html string/f] ; Not used for now
[listing-short-html string/f])) ; Date and title only
(define-schema cache:index-entry #:table "index_entries"
([id id/f #:primary-key #:auto-increment]
[entry string/f]
[subentry string/f]
[page symbol/f]
[html-anchor string/f]))
(define-schema listing
#:virtual
([path string/f]
[title string/f]
[author string/f]
[published string/f]
[updated string/f]
[html string/f]))
(define (init-cache-db!)
(create-table! (cache-conn) 'cache:article)
(create-table! (cache-conn) 'cache:note)
(create-table! (cache-conn) 'cache:index-entry))
(define (delete-article! page)
(query-exec (cache-conn)
(~> (from cache:article #:as a)
(where (= a.page ,(format "~a" page)))
delete)))
|
︙ | | | ︙ | |
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
(define (fenced-listing q)
`(style ,@(listing-htmls q)))
;; Remove "<style>" and "</style>" introduced by using ->html on docs containing output from
;; listing functions
(define (unfence html-str)
(regexp-replace* #px"<[\\/]{0,1}style>" html-str ""))
;;
;; ~~~ Fetching series ~~~
;;
(define (series-grouped-list)
(~> (for/list ([row (in-entities (cache-conn)
(order-by (from cache:series #:as s)
([s.noun-plural #:asc])))]) row)
(group-list-by cache:series-noun-plural _ string-ci=?)))
;; Preloads the SQLite cache with info about each series.
;; I may not actually need this but I’m leaving it for now.
(define (preheat-series!)
(query-exec (cache-conn)
(~> (from cache:series #:as s)
(where 1)
delete))
(define series-rows
(for/list ([series-pagenode (in-list (cdr (series-pagetree)))])
(define series-metas (get-metas series-pagenode))
(make-cache:series
#:page series-pagenode
#:title (hash-ref series-metas 'title)
#:published (hash-ref series-metas 'published "")
#:noun-plural (hash-ref series-metas 'noun-plural "")
#:noun-singular (hash-ref series-metas 'noun-singular ""))))
(void (apply insert! (cache-conn) series-rows)))
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
192
193
194
195
196
197
198
|
(define (fenced-listing q)
`(style ,@(listing-htmls q)))
;; Remove "<style>" and "</style>" introduced by using ->html on docs containing output from
;; listing functions
(define (unfence html-str)
(regexp-replace* #px"<[\\/]{0,1}style>" html-str ""))
|
Modified code-docs/cache.scrbl
from [bc87f6f5]
to [ed5e44d9].
︙ | | | ︙ | |
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
Creates and initializes the SQLite database cache file (named @filepath{vitreous.sqlite} and located
in the project root folder) by running queries to create tables in the database if they do not
exist.
}
@defproc[(preheat-series!) void?]{
Save info about each series in @racket[series-folder] to the cache.
}
@section{Retrieving cached data}
Some of this looks a little wacky, but it’s a case of putting a little extra complextity into the
back end to make things simple on the front end. These functions are most commonly used inside the
@emph{body} of a Pollen document (i.e., series pages).
@filebox["series/my-series.poly.pm"
|
<
<
<
<
<
<
|
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
Creates and initializes the SQLite database cache file (named @filepath{vitreous.sqlite} and located
in the project root folder) by running queries to create tables in the database if they do not
exist.
}
@section{Retrieving cached data}
Some of this looks a little wacky, but it’s a case of putting a little extra complextity into the
back end to make things simple on the front end. These functions are most commonly used inside the
@emph{body} of a Pollen document (i.e., series pages).
@filebox["series/my-series.poly.pm"
|
︙ | | | ︙ | |
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
The contents of the style tags are left intact.
Use this in templates with strings returned from @racket[->html] when called on docs that use the
@racket[fenced-listing] tag function.
}
@defproc[(series-grouped-list) (listof (listof cache:series?))]{
Return a list of lists of all @racket[cache:series] in the cache database. The series are grouped so
that series using the same value in the @tt{noun_plural} column appear together.
}
@section{Deleting records}
@deftogether[(@defproc[(delete-article! [page stringish?]) void?]
@defproc[(delete-notes! [page stringish?]) void?])]{
Delete a particular article, or all notes for a particular article, respectively.
|
<
<
<
<
<
<
<
|
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
The contents of the style tags are left intact.
Use this in templates with strings returned from @racket[->html] when called on docs that use the
@racket[fenced-listing] tag function.
}
@section{Deleting records}
@deftogether[(@defproc[(delete-article! [page stringish?]) void?]
@defproc[(delete-notes! [page stringish?]) void?])]{
Delete a particular article, or all notes for a particular article, respectively.
|
︙ | | | ︙ | |
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
[listing-full-html string/f]
[listing-excerpt-html string/f]
[listing-short-html string/f])
#:constructor-name make-cache:note]{
Table holding cached information on notes.
}
@defstruct*[cache:series ([id id/f]
[page symbol/f]
[title string/f]
[published string/f]
[noun-plural string/f]
[noun-singular string/f])
#:constructor-name make-cache:series]{
Table holding cached information on series.
}
@defstruct*[cache:index-entry ([id id/f]
[entry string/f]
[subentry string/f]
[page symbol/f]
[html-anchor string/f])
|
<
<
<
<
<
<
<
<
<
<
<
<
|
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
[listing-full-html string/f]
[listing-excerpt-html string/f]
[listing-short-html string/f])
#:constructor-name make-cache:note]{
Table holding cached information on notes.
}
@defstruct*[cache:index-entry ([id id/f]
[entry string/f]
[subentry string/f]
[page symbol/f]
[html-anchor string/f])
|
︙ | | | ︙ | |
Modified code-docs/crystalize.scrbl
from [ca8a0906]
to [d002cd00].
︙ | | | ︙ | |
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
and saved to the SQLite cache and saved using @racket[make-cache:article]. If the article specifies
a @racket['series] meta, information about that series is fetched and used in the rendering of the
article. If there are @racket[note]s or @racket[index] tags in the doc, they are parsed and saved
individually to the SQLite cache (using @racket[make-cache:note] and
@racket[make-cache:index-entry]). If any of the notes use the @code{#:disposition} attribute,
information about the disposition is parsed out and used in the rendering of the article.
}
@defproc[(cache-series!) void?]{
Attempts to look up certain values in @racket[current-metas] which we expect to be defined on
a typical series page, and saves them to the cache using @racket[make-cache:series]. If @tt{title}
is not defined in the current metas, you’ll get an error. If any of the others are missing, an empty
string is used.
}
|
<
<
<
<
<
<
<
<
<
|
41
42
43
44
45
46
47
48
|
and saved to the SQLite cache and saved using @racket[make-cache:article]. If the article specifies
a @racket['series] meta, information about that series is fetched and used in the rendering of the
article. If there are @racket[note]s or @racket[index] tags in the doc, they are parsed and saved
individually to the SQLite cache (using @racket[make-cache:note] and
@racket[make-cache:index-entry]). If any of the notes use the @code{#:disposition} attribute,
information about the disposition is parsed out and used in the rendering of the article.
}
|
Modified code-docs/dust.scrbl
from [ed5349c7]
to [6b21bda7].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#lang scribble/manual
@; SPDX-License-Identifier: BlueOak-1.0.0
@; This file is licensed under the Blue Oak Model License 1.0.0.
@(require "scribble-helpers.rkt"
scribble/example)
@(require (for-label "../pollen.rkt"
"../dust.rkt"
"../cache.rkt"
racket/base
racket/contract
txexpr
sugar/coerce
pollen/tag
pollen/setup
pollen/pagetree
|
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#lang scribble/manual
@; SPDX-License-Identifier: BlueOak-1.0.0
@; This file is licensed under the Blue Oak Model License 1.0.0.
@(require "scribble-helpers.rkt"
scribble/example)
@(require (for-label "../pollen.rkt"
"../dust.rkt"
"../cache.rkt"
"../series-list.rkt"
racket/base
racket/contract
txexpr
sugar/coerce
pollen/tag
pollen/setup
pollen/pagetree
|
︙ | | | ︙ | |
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
(define doc
'(root (p "If I had been astonished at first catching a glimpse of so outlandish an "
"individual as Queequeg circulating among the polite society of a civilized "
"town, that astonishment soon departed upon taking my first daylight "
"stroll through the streets of New Bedford…")))
(default-title (get-elements doc))]
@defproc[(metas-series-pagenode) pagenode?]
If @code{(current-metas)} has the key @racket['series], converts its value to the pagenode pointing to
that series, otherwise returns @racket['||].
@defproc[(series-metas-noun) string?]
If @code{(current-metas)} has the key @racket['series], and if the corresponding series defines a meta
value for @racket['noun-singular], then return it, otherwise return @racket[""].
@defproc[(series-metas-title) string?]
If @code{(current-metas)} has the key @racket['series], and if the corresponding series defines a meta
value for @racket['title], then return it, otherwise return @racket[""].
@defproc[(invalidate-series) (or/c void? boolean?)]
If the current article specifies a @racket['series] meta, and if a corresponding @filepath{.poly.pm}
file exists in @racket[series-folder], attempts to “touch” the last-modified timestamp on that file,
returning @racket[#t] on success or @racket[#f] on failure. If either precondition is not true,
returns @|void-const|.
|
|
>
>
>
>
|
>
|
>
|
|
|
>
|
|
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
(define doc
'(root (p "If I had been astonished at first catching a glimpse of so outlandish an "
"individual as Queequeg circulating among the polite society of a civilized "
"town, that astonishment soon departed upon taking my first daylight "
"stroll through the streets of New Bedford…")))
(default-title (get-elements doc))]
@defproc[(current-series-pagenode) pagenode?]
If @code{(current-metas)} has the key @racket['series], converts its value to the pagenode pointing to
that series, otherwise returns @racket['||].
@examples[#:eval dust-eval
(require pollen/core)
(parameterize ([current-metas (hash 'series "marquee-fiction")])
(current-series-pagenode))]
@defproc[(current-series-noun) string?]
If @code{(current-metas)} has the key @racket['series] and if there is a corresponding
@racket[series] in the @racket[series-list], return its @racket[series-noun-singular] value;
otherwise return @racket[""].
@defproc[(current-series-title) string?]
If @code{(current-metas)} has the key @racket['series] and if there is a corresponding
@racket[series] in the @racket[series-list], return its @racket[series-title] value;
otherwise return @racket[""].
@defproc[(invalidate-series) (or/c void? boolean?)]
If the current article specifies a @racket['series] meta, and if a corresponding @filepath{.poly.pm}
file exists in @racket[series-folder], attempts to “touch” the last-modified timestamp on that file,
returning @racket[#t] on success or @racket[#f] on failure. If either precondition is not true,
returns @|void-const|.
|
︙ | | | ︙ | |
Modified code-docs/main.scrbl
from [d030a01e]
to [1cad1ba1].
︙ | | | ︙ | |
47
48
49
50
51
52
53
54
55
56
57
58
|
cached metas of every article looking for matching articles.
@local-table-of-contents[]
@include-section["tour.scrbl"]
@include-section["design.scrbl"]
@include-section["pollen.scrbl"] @; pollen.rkt
@include-section["dust.scrbl"] @; dust.rkt
@include-section["snippets-html.scrbl"] @; you get the idea
@include-section["cache.scrbl"]
@include-section["crystalize.scrbl"]
@include-section["other-files.scrbl"]
|
>
|
47
48
49
50
51
52
53
54
55
56
57
58
59
|
cached metas of every article looking for matching articles.
@local-table-of-contents[]
@include-section["tour.scrbl"]
@include-section["design.scrbl"]
@include-section["pollen.scrbl"] @; pollen.rkt
@include-section["series.scrbl"]
@include-section["dust.scrbl"] @; dust.rkt
@include-section["snippets-html.scrbl"] @; you get the idea
@include-section["cache.scrbl"]
@include-section["crystalize.scrbl"]
@include-section["other-files.scrbl"]
|
Added code-docs/series.scrbl version [09dae3f6].
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#lang scribble/manual
@; SPDX-License-Identifier: BlueOak-1.0.0
@; This file is licensed under the Blue Oak Model License 1.0.0.
@(require "scribble-helpers.rkt"
scribble/example)
@(require (for-label "../pollen.rkt"
"../series-list.rkt"
"../dust.rkt"
"../cache.rkt"
pollen/core
racket/base
racket/contract))
@title{Defining Series}
To create a new series:
@itemlist[#:style 'ordered
@item{Create a file @filepath{my-key.poly.pm} inside @racket[series-folder] and include a call
to @racket[fenced-listing] to list all the articles and notes that will be included in the series:
@codeblock|{
#lang pollen
◊(define-meta title "My New Series")
◊block{Here’s what we call a bunch of similar articles:
◊(fenced-listing (articles 'short))
}
}|
}
@item{Add an entry for @racket[_my-key] to @racket[series-list] in @filepath{series-list.rkt}}
@item{Use @racket[(define-meta series "my-key")] in articles to add them to the series.}
@item{If @racket[series-ptree-ordered?] is @racket[#t], create a @seclink["Pagetree" #:doc '(lib
"pollen/scribblings/pollen.scrbl")]{pagetree} file in @racket[series-folder] named
@filepath{my-key.ptree}.}
]
@section{Series list}
@defmodule["series-list.rkt" #:packages ()]
This module contains the most commonly used bits of meta-info about @tech{series}. Storing these
bits in a hash table of structs makes them faster to retrieve than when they are stored inside the
metas of the Pollen documents for the series themselves.
@defthing[series-list hash?]{
An immutable hash containing all the title and noun info for each @tech{series}. Each key is
a string and each value is a @racket[series] struct.
}
@defstruct[series ([key string?]
[title string?]
[noun-plural string?]
[noun-singular string?]
[ptree-ordered? boolean?])]{
Struct for holding metadata for a @tech{series}. The @racket[_ptree-ordered?] value should be
@racket[#t] if there is a @filepath{@italic{key}.ptree} file in @racket[series-folder] that provides
information on how articles in the series are ordered.
}
|
Modified crystalize.rkt
from [121eb65c]
to [7aa92528].
︙ | | | ︙ | |
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
pollen/template
pollen/decode
(except-in pollen/core select) ; avoid conflict with deta
)
(require "dust.rkt" "cache.rkt" "snippets-html.rkt")
(provide parse-and-cache-article!
cache-series!)
(define current-title (make-parameter #f))
(define current-excerpt (make-parameter #f))
(define current-notes (make-parameter '()))
(define current-disposition (make-parameter ""))
(define current-disp-id (make-parameter ""))
|
|
<
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
pollen/template
pollen/decode
(except-in pollen/core select) ; avoid conflict with deta
)
(require "dust.rkt" "cache.rkt" "snippets-html.rkt")
(provide parse-and-cache-article!)
(define current-title (make-parameter #f))
(define current-excerpt (make-parameter #f))
(define current-notes (make-parameter '()))
(define current-disposition (make-parameter ""))
(define current-disp-id (make-parameter ""))
|
︙ | | | ︙ | |
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
title-val
body-txpr
(current-disposition)
(current-disp-id))]
[title-html (->html title-tx #:splice? #t)]
[title-plain (tx-strs title-tx)]
[header (html$-article-open pagenode title-specified? title-tx pubdate)]
[series-node (metas-series-pagenode)]
[footertext (make-article-footertext pagenode
series-node
(current-disposition)
(current-disp-id)
(length (current-notes)))]
[footer (html$-article-close footertext)]
[listing-short (html$-article-listing-short pagenode pubdate title-html)]
|
|
|
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
title-val
body-txpr
(current-disposition)
(current-disp-id))]
[title-html (->html title-tx #:splice? #t)]
[title-plain (tx-strs title-tx)]
[header (html$-article-open pagenode title-specified? title-tx pubdate)]
[series-node (current-series-pagenode)]
[footertext (make-article-footertext pagenode
series-node
(current-disposition)
(current-disp-id)
(length (current-notes)))]
[footer (html$-article-close footertext)]
[listing-short (html$-article-listing-short pagenode pubdate title-html)]
|
︙ | | | ︙ | |
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#:title-html-flow title-html
#:title-specified? title-specified?
#:published pubdate
#:updated (maybe-meta 'updated)
#:author (maybe-meta 'author default-authorname)
#:conceal (maybe-meta 'conceal)
#:series-page series-node
#:noun-singular (maybe-meta 'noun (series-metas-noun))
#:note-count (length (current-notes))
#:content-html doc-html
#:disposition (current-disposition)
#:disp-html-anchor (current-disp-id)
#:listing-full-html listing-full
#:listing-excerpt-html listing-excerpt
#:listing-short-html listing-short))
|
|
|
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#:title-html-flow title-html
#:title-specified? title-specified?
#:published pubdate
#:updated (maybe-meta 'updated)
#:author (maybe-meta 'author default-authorname)
#:conceal (maybe-meta 'conceal)
#:series-page series-node
#:noun-singular (maybe-meta 'noun (current-series-noun))
#:note-count (length (current-notes))
#:content-html doc-html
#:disposition (current-disposition)
#:disp-html-anchor (current-disp-id)
#:listing-full-html listing-full
#:listing-excerpt-html listing-excerpt
#:listing-short-html listing-short))
|
︙ | | | ︙ | |
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
[else ""]))
;; Returns a txexpr, the tag will be discarded by the template/snippets
`(title ,@title-elems ,disposition-part))
;; Convert a bunch of information about an article into some nice English and links.
(define (make-article-footertext pagenode series disposition disp-note-id note-count)
(define series-part
(match (series-metas-title)
[(? non-empty-string? s-title)
(format "<span class=\"series-part\">This is ~a, part of <a href=\"/~a\">‘~a’</a>.</span>"
(series-metas-noun)
series
s-title)]
[_ ""]))
(define disp-part
(cond [(non-empty-string? disposition)
(define-values (mark verb) (disposition-values disposition))
(format "Now considered <a href=\"/~a#~a\">~a</a>."
|
|
|
|
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
[else ""]))
;; Returns a txexpr, the tag will be discarded by the template/snippets
`(title ,@title-elems ,disposition-part))
;; Convert a bunch of information about an article into some nice English and links.
(define (make-article-footertext pagenode series disposition disp-note-id note-count)
(define series-part
(match (current-series-title)
[(? non-empty-string? s-title)
(format "<span class=\"series-part\">This is ~a, part of <a href=\"/~a\">‘~a’</a>.</span>"
(current-series-noun)
series
s-title)]
[_ ""]))
(define disp-part
(cond [(non-empty-string? disposition)
(define-values (mark verb) (disposition-values disposition))
(format "Now considered <a href=\"/~a#~a\">~a</a>."
|
︙ | | | ︙ | |
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
#:html-anchor note-id
#:title-html-flow title-html
#:title-plain (tx-strs title-tx)
#:published note-date
#:author author
#:author-url author-url
#:disposition disposition-attr
#:series-page (metas-series-pagenode)
#:conceal (or (maybe-attr 'conceal attrs #f) (maybe-meta 'conceal))
#:content-html content-html
#:listing-full-html listing-full
#:listing-excerpt-html listing-full
#:listing-short-html ""))
(html$-note-in-article note-id note-date content-html author author-url)))
|
|
|
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
#:html-anchor note-id
#:title-html-flow title-html
#:title-plain (tx-strs title-tx)
#:published note-date
#:author author
#:author-url author-url
#:disposition disposition-attr
#:series-page (current-series-pagenode)
#:conceal (or (maybe-attr 'conceal attrs #f) (maybe-meta 'conceal))
#:content-html content-html
#:listing-full-html listing-full
#:listing-excerpt-html listing-full
#:listing-short-html ""))
(html$-note-in-article note-id note-date content-html author author-url)))
|
︙ | | | ︙ | |
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
(query-exec (cache-conn) (delete (~> (from cache:index-entry #:as entry)
(where (= entry.page ,(symbol->string pagenode))))))
(unless (null? entry-txs)
(void
(apply insert! (cache-conn)
(for/list ([etx (in-list entry-txs)])
(txexpr->index-entry etx pagenode))))))
;; Save the current article to the `series` table of the SQLite cache
;; Should be called from a template for series pages
(define (cache-series!)
(define here-page (path->string (here-output-path)))
(query-exec (cache-conn)
(delete (~> (from cache:series #:as s)
(where (= s.page ,here-page)))))
(void
(insert-one! (cache-conn)
(make-cache:series
#:page (string->symbol here-page)
#:title (hash-ref (current-metas) 'title)
#:published (hash-ref (current-metas) 'published "")
#:noun-plural (hash-ref (current-metas) 'noun-plural "")
#:noun-singular (hash-ref (current-metas) 'noun-singular "")))))
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
250
251
252
253
254
255
256
|
(query-exec (cache-conn) (delete (~> (from cache:index-entry #:as entry)
(where (= entry.page ,(symbol->string pagenode))))))
(unless (null? entry-txs)
(void
(apply insert! (cache-conn)
(for/list ([etx (in-list entry-txs)])
(txexpr->index-entry etx pagenode))))))
|
Modified dust.rkt
from [eb603279]
to [aa082dfb].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
(require pollen/core
pollen/pagetree
pollen/setup
pollen/file
net/uri-codec
file/sha1
gregor
txexpr
racket/list
racket/match
racket/port
racket/system
racket/string)
;; Provides common helper functions used throughout the project
(provide maybe-meta ; Select from (current-metas) or default value ("") if not available
maybe-attr ; Return an attribute’s value or a default ("") if not available
here-output-path
here-source-path
here-id
listing-context
series-metas-noun ; Retrieve noun-singular from current 'series meta, or ""
series-metas-title ; Retrieve title of series in current 'series meta, or ""
metas-series-pagenode
invalidate-series
checked-in?
make-tag-predicate
tx-strs
ymd->english
ymd->dateformat
default-authorname
|
>
>
|
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
(require pollen/core
"series-list.rkt"
pollen/pagetree
pollen/setup
pollen/file
net/uri-codec
threading
file/sha1
gregor
txexpr
racket/list
racket/match
racket/port
racket/system
racket/string)
;; Provides common helper functions used throughout the project
(provide maybe-meta ; Select from (current-metas) or default value ("") if not available
maybe-attr ; Return an attribute’s value or a default ("") if not available
here-output-path
here-source-path
here-id
listing-context
current-series-noun ; Retrieve noun-singular from current 'series meta, or #f
current-series-title ; Retrieve title of series in current 'series meta, or #f
current-series-pagenode
invalidate-series
checked-in?
make-tag-predicate
tx-strs
ymd->english
ymd->dateformat
default-authorname
|
︙ | | | ︙ | |
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
(define (here-output-path)
(->output-path (here-source-path)))
(define listing-context (make-parameter ""))
;; Checks current-metas for a 'series meta and returns the pagenode of that series,
;; or '|| if no series is specified.
(define (metas-series-pagenode)
(define maybe-series (or (select-from-metas 'series (current-metas)) ""))
(cond
[(non-empty-string? maybe-series)
(->pagenode (format "~a/~a.html" series-folder maybe-series))]
[else '||]))
(define (series-metas-noun)
(define series-pnode (metas-series-pagenode))
(case series-pnode
['|| ""] ; no series specified
[else (or (select-from-metas 'noun-singular series-pnode) "")]))
(define (series-metas-title)
(define series-pnode (metas-series-pagenode))
(case series-pnode
['|| ""] ; no series specified
[else (or (select-from-metas 'title series-pnode) "")]))
(define article-ids (make-hash))
;; Generates a short ID for the current article
(define (here-id [suffix #f])
(define maybe-hash (hash-ref article-ids (here-output-path) #f))
(define here-hash
|
|
|
<
|
|
>
|
|
|
|
|
|
>
|
|
>
|
|
|
|
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
(define (here-output-path)
(->output-path (here-source-path)))
(define listing-context (make-parameter ""))
;; Checks current-metas for a 'series meta and returns the pagenode of that series,
;; or '|| if no series is specified.
(define (current-series-pagenode)
(or (and~> (current-metas)
(hash-ref 'series #f)
(format "~a/~a.html" series-folder _)
->pagenode)
'||))
(define (current-series-noun)
(or (and~> (current-metas)
(hash-ref 'series #f)
(hash-ref series-list _ #f)
series-noun-singular)
""))
(define (current-series-title)
(or (and~> (current-metas)
(hash-ref 'series #f)
(hash-ref series-list _ #f)
series-title)
""))
(define article-ids (make-hash))
;; Generates a short ID for the current article
(define (here-id [suffix #f])
(define maybe-hash (hash-ref article-ids (here-output-path) #f))
(define here-hash
|
︙ | | | ︙ | |
Modified makefile
from [fae17d31]
to [7107d1ff].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# SPDX-License-Identifier: BlueOak-1.0.0
# This file is licensed under the Blue Oak Model License 1.0.0.
SHELL = /bin/bash
# ~~~ Variables used by rules ~~~
#
core-files := pollen.rkt dust.rkt
html-deps := snippets-html.rkt tags-html.rkt crystalize.rkt cache.rkt
article-sources := $(wildcard articles/*.poly.pm)
articles-html := $(patsubst %.poly.pm, %.html, $(article-sources))
articles-pdf := $(patsubst %.poly.pm, %.pdf, $(article-sources))
series-sources := $(wildcard series/*.poly.pm)
series-html := $(patsubst %.poly.pm, %.html, $(series-sources))
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# SPDX-License-Identifier: BlueOak-1.0.0
# This file is licensed under the Blue Oak Model License 1.0.0.
SHELL = /bin/bash
# ~~~ Variables used by rules ~~~
#
core-files := pollen.rkt dust.rkt
html-deps := snippets-html.rkt tags-html.rkt crystalize.rkt cache.rkt series-list.rkt
article-sources := $(wildcard articles/*.poly.pm)
articles-html := $(patsubst %.poly.pm, %.html, $(article-sources))
articles-pdf := $(patsubst %.poly.pm, %.pdf, $(article-sources))
series-sources := $(wildcard series/*.poly.pm)
series-html := $(patsubst %.poly.pm, %.html, $(series-sources))
|
︙ | | | ︙ | |
Modified pollen.rkt
from [ecc1875a]
to [0c603aac].
︙ | | | ︙ | |
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
(define block-tags (append '(title style dt note) default-block-tags))
(define-runtime-path tags-html.rkt "tags-html.rkt")
(define-runtime-path snippets-html.rkt "snippets-html.rkt")
(define-runtime-path dust.rkt "dust.rkt")
(define-runtime-path crystalize.rkt "crystalize.rkt")
(define-runtime-path cache.rkt "cache.rkt")
(define cache-watchlist
(map resolve-module-path
(list tags-html.rkt
snippets-html.rkt
dust.rkt
cache.rkt
crystalize.rkt))))
;; Macro for defining tag functions that automatically branch based on the
;; current output format and the list of poly-targets in the setup module.
;; Use this macro when you know you will need keyword arguments.
;;
(define-syntax (poly-branch-kwargs-tag stx)
|
>
>
|
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
(define block-tags (append '(title style dt note) default-block-tags))
(define-runtime-path tags-html.rkt "tags-html.rkt")
(define-runtime-path snippets-html.rkt "snippets-html.rkt")
(define-runtime-path dust.rkt "dust.rkt")
(define-runtime-path crystalize.rkt "crystalize.rkt")
(define-runtime-path cache.rkt "cache.rkt")
(define-runtime-path series-list.rkt "series-list.rkt")
(define cache-watchlist
(map resolve-module-path
(list tags-html.rkt
snippets-html.rkt
dust.rkt
cache.rkt
series-list.rkt
crystalize.rkt))))
;; Macro for defining tag functions that automatically branch based on the
;; current output format and the list of poly-targets in the setup module.
;; Use this macro when you know you will need keyword arguments.
;;
(define-syntax (poly-branch-kwargs-tag stx)
|
︙ | | | ︙ | |
Added series-list.rkt version [88c1de55].
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
;; Provides fast metadata for series.
;; TO MAKE A NEW SERIES:
;; 1. Create series/my-key.poly.pm
;; 2. Add an entry for my-key to series-list below
;; 3. Use ◊define-meta[series "my-key"] in articles to add them to the series.
;; 4. If ptree-ordered is #t, also create series/my-key.ptree
(require racket/list)
(struct series (key title noun-plural noun-singular ptree-ordered?))
(define series-list
(make-immutable-hash
(list
;; ------- DEFINE SERIES HERE -----------
; Key Title plural noun singular noun phrase
(+series "marquee-fiction" "Marquee Fiction" "inventions" "an invention" #f)
)))
(define (series-grouped-list)
(group-by series-noun-plural (hash-values series-list)))
;; Quick macro to save a little typing
(define-syntax-rule (+series key title plural singular ptree)
(cons key (series key title plural singular ptree)))
(provide (struct-out series)
series-list
series-grouped-list)
|
Modified series/template.html.p
from [7a674800]
to [7e883695].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!DOCTYPE html>
<html lang="en">
◊cache-series![]
◊html$-page-head[(select-from-metas 'title metas)]
◊html$-page-body-open["series-page"]
◊(unfence (->html doc #:splice? #t))
◊html$-page-body-close[]
</html>
|
<
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!DOCTYPE html>
<html lang="en">
◊html$-page-head[(select-from-metas 'title metas)]
◊html$-page-body-open["series-page"]
◊(unfence (->html doc #:splice? #t))
◊html$-page-body-close[]
</html>
|
Modified snippets-html.rkt
from [79ce1a10]
to [9c1944e9].
︙ | | | ︙ | |
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
pollen/decode
pollen/private/version
racket/string
racket/function
racket/list
txexpr
"cache.rkt"
"dust.rkt")
(provide html$-page-head
html$-page-body-open
html$-series-list
html$-article-open
html$-article-close
|
>
|
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
pollen/decode
pollen/private/version
racket/string
racket/function
racket/list
txexpr
"cache.rkt"
"series-list.rkt"
"dust.rkt")
(provide html$-page-head
html$-page-body-open
html$-series-list
html$-article-open
html$-article-close
|
︙ | | | ︙ | |
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
(if (eq? pagecount pagenum)
"<li class=\"nav-text inactive-link\">Older→</li>"
(page-func (+ pagenum 1) "Older →" "nav-text")))
(string-join `(,prev-link ,@page-group ,next-link)))
(define (series->txpr s)
`(li (a [[href ,(string-append web-root (symbol->string (cache:series-page s)))]]
(i ,(cache:series-title s)))))
(define (html$-series-list)
(define series-list-items
(for/list ([group (in-list (series-grouped-list))])
`(div (h2 ,(cache:series-noun-plural (first group))) (ul ,@(map series->txpr group)))))
(->html `(section [[class "column-list"] [style "margin-top: 1.3rem"]] ,@series-list-items)))
|
|
|
|
|
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
(if (eq? pagecount pagenum)
"<li class=\"nav-text inactive-link\">Older→</li>"
(page-func (+ pagenum 1) "Older →" "nav-text")))
(string-join `(,prev-link ,@page-group ,next-link)))
(define (series->txpr s)
`(li (a [[href ,(string-append web-root (format "~a/~a.html" series-folder (series-key s)))]]
(i ,(series-title s)))))
(define (html$-series-list)
(define series-list-items
(for/list ([group (in-list (series-grouped-list))])
`(div (h2 ,(series-noun-plural (first group))) (ul ,@(map series->txpr group)))))
(->html `(section [[class "column-list"] [style "margin-top: 1.3rem"]] ,@series-list-items)))
|
Modified util/init.rkt
from [41c57f81]
to [ae86fdec].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#lang racket/base
(require racket/file
pollen/setup
"../cache.rkt"
"../snippets-html.rkt")
(provide main)
(define (main)
(init-cache-db!)
(preheat-series!)
(display-to-file (html$-page-footer)
(build-path (current-project-root) "scribbled" "site-footer.html")
#:exists 'replace))
|
<
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#lang racket/base
(require racket/file
pollen/setup
"../cache.rkt"
"../snippets-html.rkt")
(provide main)
(define (main)
(init-cache-db!)
(display-to-file (html$-page-footer)
(build-path (current-project-root) "scribbled" "site-footer.html")
#:exists 'replace))
|