ADDED blog.rkt Index: blog.rkt ================================================================== --- blog.rkt +++ blog.rkt @@ -0,0 +1,72 @@ +#lang pollen/mode racket/base + +;; Copyright (c) 2019 Joel Dueck. +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; A copy of the License is included with this source code, in the +;; file "LICENSE.txt". +;; You may also obtain a copy of the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, +;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;; See the License for the specific language governing permissions and +;; limitations under the License. +;; +;; Author contact information: +;; joel@jdueck.net +;; https://joeldueck.com +;; ------------------------------------------------------------------------- + +;; Builds the paginated “blog” HTML files (blog-pg1.html ...) from the SQLite cache +;; The files will be written out every time this module is evaluated! (see end) + +(require "crystalize.rkt" + "snippets-html.rkt" + racket/file + sugar/list) + +;; How many items per blog page +(define per-page 1) + +;; Returns a string containing the entire HTML contents of a given blog page +(define (blog-page posts-str pagenum total-pages) + (define page-nav (html$-paginate-navlinks pagenum total-pages "blog")) + ◊string-append{ + + +◊html$-page-head[(format "The Local Yarn: Blog, p. ~a" pagenum)] +◊html$-page-body-open[] + + + + + +◊posts-str + + + +◊html$-page-body-close[] +}) + +;; Grabs all the articles+notes from the cache and writes out all the blog page files +(define (build-blog) + (spell-of-summoning!) ; Turn on the DB + + (define articles+notes (slice-at (list/articles+notes 'listing_full_html #:series #f) per-page)) + (define pagecount (length articles+notes)) + + (for ([pagenum (in-range 1 (+ 1 pagecount))] + [page (in-list articles+notes)]) + (define filename (format "blog-pg~a.html" pagenum)) + (println (format "Writing: ~a" filename)) + (display-to-file (blog-page (apply string-append page) pagenum pagecount) + filename + #:mode 'text + #:exists 'replace))) + +;; Do it! +(build-blog) Index: code-docs/crystalize.scrbl ================================================================== --- code-docs/crystalize.scrbl +++ code-docs/crystalize.scrbl @@ -46,10 +46,38 @@ 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[(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[(list-short/articles [#:series series (or/c string? boolean?) #t] [#:limit limit stringish? -1] [order string? "DESC"]) txexpr?] @defproc[(list-full/articles [#:series series (or/c string? boolean?) #t] [#:limit limit stringish? -1] Index: code-docs/snippets-html.scrbl ================================================================== --- code-docs/snippets-html.scrbl +++ code-docs/snippets-html.scrbl @@ -131,6 +131,15 @@ @defproc[(html$-notes-section [note-htmls string?]) non-empty-string?] Returns the complete HTML for the @italic{Further Notes} section of an article. +@defproc[(html$-paginate-navlinks [current-page exact-positive-integer?] + [pagecount exact-positive-integer?] + [basename string?]) string?] + +On the “blog”, the articles are split across multiple files: @filepath{blog-pg1.html}, +@filepath{blog-pg2.html}, etc. This function provides a string containing HTML for a group of links +that can be given within each file, to link to the pages that come before/after it. +The links are enclosed within @tt{
  • } tags. It’s up to the calling site to provide the enclosing +@tt{