@@ -9,10 +9,11 @@ "../dust.rkt" "../crystalize.rkt" racket/base racket/contract racket/string + deta txexpr pollen/template pollen/pagetree sugar/coerce)) @@ -20,86 +21,61 @@ @defmodule["crystalize.rkt" #:packages ()] “Crystalizing” is an extra layer in between docs and templates that destructures the doc and stores it in various pieces in a SQLite cache. Individual articles save chunks of rendered HTML to the -cache when their individual pages are rendered. The SQLite cache is then referenced by any page that -collects multiple articles and notes together. This is much faster than fetching docs and metas -through Pollen’s cache and re-converting them to HTML. - -@defproc[(spell-of-summoning!) void?] - -Initializes the SQLite database cache file. This involves creating the file -(@filepath{vitreous.sqlite}) if it does not exist, and running queries to create tables in the -database if they do not exist. +cache when their individual pages are rendered. When pulling together listings of articles in +different contexts that need to be filtered and sorted, a SQL query is much faster than trolling +through the Pollen cache for matching docs and regenerating the HTML. + +@defproc[(init-cache-db!) void?] + +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. (The +file itself is created at the module level.) This function is called automatically in @filepath{pollen.rkt} whenever HTML is the target output. -@defproc[(crystalize-article! [pagenode pagenode?] [doc txexpr?]) non-empty-string?] +@defproc[(parse-and-cache-article! [pagenode pagenode?] [doc txexpr?]) non-empty-string?] Returns a string containing the HTML of @racket[_doc]. @margin-note{This is one function that breaks -my convention of using a prefix of @tt{html$-} for functions that return strings of HTML.} -Privately, it does a lot of other work. The article is saved to the SQLite cache. 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 in the doc, they are parsed and saved -individually to the SQLite cache. 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[(crystalize-series!) void?] - -Saves metas for the current series page in the SQLite cache. Meant to be called from the HTML -template for “Series” pages (Pollen documents located in @racket[series-folder]). - -@defproc[(crystalize-index-entries! [pagenode pagenode?] [doc txexpr?]) void?] - -Saves any @racket[index] enries entries in @racket[_doc] to the SQLite cache. - -@margin-note{This function was originally private; I provided it out only so it could be called -manually from @tt{index.html.pp}.} - -@deftogether[(@defproc[(list/articles [type (or/c 'listing_full_html - 'listing_short_html - 'listing_excerpt_html)] - [#:series series (or/c string? boolean?) #t] - [#:limit limit stringish? -1] - [order string? "DESC"]) (listof string?)] - @defproc[(list/articles+notes [type (or/c 'listing_full_html - 'listing_short_html - 'listing_excerpt_html)] - [#:series series (or/c string? boolean?) #t] - [#:limit limit stringish? -1] - [order string? "DESC"]) (listof string?)])] - -Fetches the HTML for all articles from the SQLite cache and returns a list of strings containing the -HTML for each. The articles will be ordered by publish date according to @racket[_order] and -optionally limited to the series specified in @racket[_series]. - -If @racket[_series] expression evaluates to @racket[#f], articles will not be filtered by series. If -it evaluates to @racket[#t] (the default), articles will be filtered by those that specify the -current output of @racket[here-output-path] in their @tt{series_pagenode} column in the SQLite -cache. If a string is supplied, articles will be filtered by those containing that exact value in -their @tt{series_pagenode} column in the SQLite cache. - -The @racket[_order] expression must evaluate to either @racket["ASC"] or @racket["DESC"] and the -@racket[_limit] expressions must evaluate to a value suitable for use in the @tt{LIMIT} clause of -@ext-link["https://sqlite.org/lang_select.html"]{a SQLite @tt{SELECT} statement}. An expression that -evaluates to a negative integer (the default) is the same as having no limit. - -@deftogether[(@defproc[(listing<>-short/articles [#:series series (or/c string? boolean?) #t] - [#:limit limit stringish? -1] - [order string? "DESC"]) txexpr?] - @defproc[(listing<>-full/articles [#:series series (or/c string? boolean?) #t] - [#:limit limit stringish? -1] - [order string? "DESC"]) txexpr?])] - -@margin-note{Notice how the functions that start with @tt{list/} return lists and the functions that -start with @tt{listing<>} return fenced HTML strings. Maybe this is ugly, but it helps me keep these -otherwise too-similar sets of functions straight in my head.} - -Fetches the HTML for all articles from the SQLite cache and returns the HTML strings fenced inside -a @racket['style] tagged X-expression. The articles will be ordered by publish date according to +my convention of using a prefix of @tt{html$-} for functions that return a single string of HTML.} + +Privately, it does a lot of other work. The article is analyzed, additional metadata is constructed, +and it is saved to the SQLite cache. 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 +in the doc, they are parsed and saved individually to the SQLite cache. 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. + +@deftogether[(@defproc[( + [query-func (-> any/c query?)] + [#:series series (or/c string? (listof string? boolean?)) #t] + [#:limit limit integer? -1] + [order stringish? 'desc]) txexpr?] + @defproc[( + [query-func (-> any/c query?)] + [#:series series (or/c string? (listof string? boolean?)) #t] + [#:limit limit integer? -1] + [order stringish? 'desc]) txexpr?] + @defproc[( + [query-func (-> any/c query?)] + [#:series series (or/c string? (listof string? boolean?)) #t] + [#:limit limit integer? -1] + [order stringish? 'desc]) txexpr?])] + +Fetches the HTML for items from the SQLite cache and returns the HTML strings fenced inside +a @racket['style] tagged X-expression. The items will be ordered by publish date according to @racket[_order] and optionally limited to the series specified in @racket[_series]. + +The @racket[_query-func] should be either @racket[articles], which will create a listing of articles +only, or @racket[articles+notes], which will include notes intermingled with articles. + +@margin-note{Note that the signature shown for the @racket[_query-func] argument above is +incomplete. If you choose to pass a function other than @racket[articles] or +@racket[articles+notes], you must use a function with exactly the same signature as those +functions.} If @racket[_series] expression evaluates to @racket[#f], articles will not be filtered by series. If it evaluates to @racket[#t] (the default), articles will be filtered by those that specify the current output of @racket[here-output-path] in their @tt{series_pagenode} column in the SQLite cache. If a string is supplied, articles will be filtered by those containing that exact value in @@ -114,29 +90,38 @@ escaped by @racket[->html] in the template. This tag was picked for the job because there will generally never be a need to include any actual CSS information inside a @tt{"] removed. The contents of the style tags are left intact. -Use this with strings returned from @racket[->html] when called on docs containing -@racket[listing<>-full/articles] or its siblings. - -@defproc[(article-plain-title [pagenode pagenode?]) non-empty-string?] - -Fetches the “plain” title (i.e., with no HTML markup) for the given article from the SQLite cache. -If the article did not specify a title, a default title is supplied. If the article contained -a @racket[note] that used the @code{#:disposition} attribute, the disposition-mark may be included -in the title. - -Note that this needs to be called @emph{after} @racket[crystalize-article!] in order to get an +Use this with strings returned from @racket[->html] when called on docs that use the +@racket[] tag function or its siblings. + +@defparam[current-plain-title non-empty-string? #:value "void"] + +Contains (or sets) the “plain” title (i.e., with no HTML markup) for the current article based on +analysis done by @racket[parse-and-cache-article!]. If the article did not specify a title, +a default title is supplied. If the article contained a @racket[note] that used the +@code{#:disposition} attribute, the disposition-mark may be included in the title. + +Note that this needs to be called @emph{after} @racket[parse-and-cache-article!] in order to get an up-to-date value.