diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/builders/replicant-blog-search.scm | 75 | ||||
| -rw-r--r-- | modules/builders/replicant-blog.scm | 214 | ||||
| -rw-r--r-- | modules/builders/wordpress-compatible-links.scm | 51 | ||||
| -rw-r--r-- | modules/readers/wordpress-markdown.scm | 59 |
4 files changed, 399 insertions, 0 deletions
diff --git a/modules/builders/replicant-blog-search.scm b/modules/builders/replicant-blog-search.scm new file mode 100644 index 0000000..694e3b5 --- /dev/null +++ b/modules/builders/replicant-blog-search.scm @@ -0,0 +1,75 @@ +;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org> +;;; Copyright © 2023-2024 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> +;;; +;;; This file is based on haunt/builder/blog.scm, +;;; haunt/reader/commonmark.scm and tests/post.scm and from Haunt +;;; 2.6.0. +;;; +;;; This file is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation; either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Haunt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Haunt. If not, see <http://www.gnu.org/licenses/>. + +(define-module (modules builders replicant-blog-search) + #:use-module (commonmark) + #:use-module (haunt artifact) + #:use-module (haunt builder assets) + #:use-module (haunt html) + #:use-module (haunt page) + #:use-module (haunt post) + #:use-module (haunt site) + #:use-module (haunt utils) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-19) + #:use-module (modules builders replicant-blog) + #:export (replicant-blog-search-page)) + +(fluid-set! %default-port-encoding "UTF-8") + +(define (guix-package name) + `(a + (@ (href ,(string-append "https://packages.guix.gnu.org/packages/" name))) + ,name)) + +(define replicant-blog-search-page-content + `((h1 (@ (id "title")) "Search") + + (p "This blog has no built-in search functionality. Instead users are +supposed to download the full blog source code and search inside +it. This way they are fully in control of the search and in most cases +it should not leak the search to a third party.") + + (p "Here is an example that works under a terminal in GNU/Linux with git installed:") + (p (@ (class "command")) "git clone https://git.replicant.us/contrib/GNUtoo/infrastructure/haunt-blog") + (p "And then you can search in it. For instance if you want to search for +FOSDEM in the blog articles, you can use the following commands:") + (p (@ (class "command")) "cd haunt-blog") + (p (@ (class "command")) "git grep -i fosdem -- posts") + + (p (string-append + "It is also possible to download the source code with graphical " + "software such as " + ,(guix-package "gitg") + " and then search inside the files with file managers such as " + ,(guix-package "nautilus") + ". " + "If you want to search inside the files, be sure to select the " + "\"Full text\" search as by default these file managers usually only " + "search the file names only.")))) + +(define (replicant-blog-search-page site posts) + (make-page + "search.html" + (replicant-layout site "Blog: Search" replicant-blog-search-page-content) + sxml->html)) diff --git a/modules/builders/replicant-blog.scm b/modules/builders/replicant-blog.scm new file mode 100644 index 0000000..ac84bba --- /dev/null +++ b/modules/builders/replicant-blog.scm @@ -0,0 +1,214 @@ +;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org> +;;; Copyright © 2023-2024 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> +;;; +;;; This file is based on haunt/builder/blog.scm, +;;; haunt/reader/commonmark.scm and tests/post.scm and from Haunt +;;; 2.6.0. +;;; +;;; This file is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation; either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Haunt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Haunt. If not, see <http://www.gnu.org/licenses/>. + +(define-module (modules builders replicant-blog) + #:use-module (commonmark) + #:use-module (haunt artifact) + #:use-module (haunt builder assets) + #:use-module (haunt html) + #:use-module (haunt post) + #:use-module (haunt site) + #:use-module (haunt utils) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (rnrs base) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-19) + #:export (theme-collection-template) + #:export (make-theme) + #:export (render-collection) + #:export (render-post) + #:export (replicant-blog-website) + #:export (replicant-default-post-template) + #:export (replicant-layout) + #:export (replicant-theme) + #:export (theme) + #:export (theme-layout) + #:export (theme-name) + #:export (theme-post-template) + #:export (theme?)) + +(fluid-set! %default-port-encoding "UTF-8") + +(define-record-type <theme> + (make-theme name layout post-template collection-template) + theme? + (name theme-name) + (layout theme-layout) + (post-template theme-post-template) + (collection-template theme-collection-template)) + +(define (replicant-layout site title body) + `((doctype "html") + (head + (meta (@ (charset "utf-8"))) + (link + (@ (rel "stylesheet") + (href "static/twentyeleven-style-20231107.css"))) + (title ,(string-append title " - " (site-title site)))) + (body + (header + (img (@ (id "banner") + (src "static/replicant_banner_white.png") + (alt "Replicant banner"))) + (nav + (@ (id "access")) + (ul + (li (a (@ (href "https://www.replicant.us")) + "Home")) + (li (a (@ (href "/") + (id "blog-link") + ) + "Blog")) + (li (a (@ (href "https://redmine.replicant.us/projects/replicant/wiki")) + "Wiki")) + (li (a (@ (href "https://redmine.replicant.us/projects/replicant/issues")) + "Tracker")) + (li (a (@ (href "https://redmine.replicant.us/projects/replicant/boards")) + "Forums")) + (li (a (@ (href "/search.html")) + "Blog: Search"))))) + ,body))) + +(define (replicant-default-post-template post) + `((h1 (@ (id "title")) ,(post-ref post 'title)) + ;; Metadata + (p (string-append + "Posted" + ,(if + (post-ref post 'authors) + (string-append " by " (post-ref post 'authors)) + "") + ,(if + (post-ref post 'date) + (string-append + " on the " + (date->string (post-ref post 'date) "~d ~B ~Y at ~kh~M")) + "") + ,(if (post-ref post 'licenses) + (string-append + " under the " + (post-ref post 'licenses) " license(s)") + "") + ".")) + (div (@ (id "post-content")) ,(post-sxml post)) + + ,(if + (and (post-ref post 'thread-link) + (post-ref post 'thread-name)) + `(div + (h1 "Comments") + (p "You can view replies on the Replicant mailing list, in the " + (a (@ (href ,(post-ref post 'thread-link))) + ,(post-ref post 'thread-name)) " thread.") + (p "If you also want to comment on this blog post, you can simply +reply to the " + (a (@ (href ,(post-ref post 'thread-link))) + ,(post-ref post 'thread-name)) " thread.") + + (p "If for some reasons you can't reply to this thread or you don't +know how to do it, simply write a mail to the mailing list instead.") + + (p "It is easier for everybody if you subscribe to the mailing list +to do that: if you don't your mail will probably still reach the mailing list +but it will require a moderator to approve it so it can take time. See " + (a (@ (href "https://redmine.replicant.us/projects/replicant/wiki/CommunityAndContact#Mailing-list")) + "the CommunityAndContact page") + " on the Replicant wiki for how to subscribe")) + ;; Empty div to avoid #<unspecified> showing up on the page when we have + ;; no comments. + `(div)))) + + +(define (sort-posts-by-most-recent-first a b) + (time>? + (date->time-utc (post-ref a 'date)) + (date->time-utc (post-ref b 'date)))) + +(define (replicant-default-collection-template site title posts prefix) + (define (post-uri post) + (string-append (or prefix "") "/" + (site-post-slug site post) ".html")) + + `((h3 ,title) + (ul + ,@(map (lambda (post) + `(li + (a (@ (href ,(post-uri post))) + ,(post-ref post 'title)))) + (sort posts sort-posts-by-most-recent-first))))) + +(define* (theme #:key + (name "Replicant") + (layout replicant-layout) + (post-template replicant-default-post-template) + (collection-template replicant-default-collection-template)) + (make-theme name layout post-template collection-template)) + +(define (with-layout theme site title body) + ((theme-layout theme) site title body)) + +(define (render-post theme site post) + (let ((title (post-ref post 'title)) + (body ((theme-post-template theme) post))) + (with-layout theme site title body))) + +(define (render-collection theme site title posts prefix) + (let ((body ((theme-collection-template theme) site title posts prefix))) + (with-layout theme site title body))) + +(define (date->string* date) + "Convert DATE to human readable string." + (date->string date "~a ~d ~B ~Y")) + +(define replicant-theme + (theme #:name "Replicant" + #:layout replicant-layout + #:post-template replicant-default-post-template + #:collection-template replicant-default-collection-template)) + +(define* (replicant-blog-website #:key (theme replicant-theme) prefix + (collections + `(("" "index.html" ,posts/reverse-chronological)))) + "Return a procedure that transforms a list of posts into pages +decorated by THEME, whose URLs start with PREFIX." + (define (make-file-name base-name) + (if prefix + (string-append prefix "/" base-name) + base-name)) + + (lambda (site posts) + (define (post->page post) + (let ((base-name (string-append (site-post-slug site post) + ".html"))) + (serialized-artifact (make-file-name base-name) + (render-post theme site post) + sxml->html))) + + (define collection->page + (match-lambda + ((title file-name filter) + (serialized-artifact (make-file-name file-name) + (render-collection theme site title (filter posts) prefix) + sxml->html)))) + + (append (map post->page posts) + (map collection->page collections)))) diff --git a/modules/builders/wordpress-compatible-links.scm b/modules/builders/wordpress-compatible-links.scm new file mode 100644 index 0000000..19c8076 --- /dev/null +++ b/modules/builders/wordpress-compatible-links.scm @@ -0,0 +1,51 @@ +;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org> +;;; Copyright © 2023-2025 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> +;;; +;;; This file is based on haunt/builder/blog.scm, +;;; haunt/reader/commonmark.scm and tests/post.scm and from Haunt +;;; 2.6.0. +;;; +;;; This file is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation; either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Haunt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Haunt. If not, see <http://www.gnu.org/licenses/>. + +(define-module (modules builders wordpress-compatible-links) + #:use-module (haunt builder redirects) + #:use-module (ice-9 rdelim) + #:export (make-wordpress-compatible-links)) + +(fluid-set! %default-port-encoding "UTF-8") + +(define (parse-line line) + (define parts (string-split line #\/)) + (define year (list-ref parts 3)) + (define month (list-ref parts 4)) + (define page (list-ref parts 5)) + (define input + (string-append "/" year "/" month "/" page "/index.html")) + (define output + (string-append "../../../" page ".html")) + `((,input ,output))) + +(define (make-read-file results) + (define (read-file port) + (define line (read-line port)) + (if (not (eof-object? line)) + ((lambda _ + (set! results (append results (parse-line line))) + (read-file port))) + results)) + read-file) + +(define (make-wordpress-compatible-links path) + (redirects (call-with-input-file path (make-read-file (list))))) diff --git a/modules/readers/wordpress-markdown.scm b/modules/readers/wordpress-markdown.scm new file mode 100644 index 0000000..54d64ab --- /dev/null +++ b/modules/readers/wordpress-markdown.scm @@ -0,0 +1,59 @@ +;;; Haunt --- Static site generator for GNU Guile +;;; Copyright © 2016 Erik Edrosa <erik.edrosa@gmail.com> +;;; +;;; This file is part of Haunt. +;;; +;;; Haunt is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; Haunt is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Haunt. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; +;; CommonMark post reader. +;; +;;; Code: + +(define-module (modules readers wordpress-markdown) + #:use-module (commonmark) + #:use-module (haunt post) + #:use-module (haunt reader) + #:use-module (haunt utils) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-19) + #:export (wordpress-markdown-reader)) + +(fluid-set! %default-port-encoding "UTF-8") + +(define (string->custom-date* str) + "Convert STR, a string in ISO 8601 format or the default format, into a +SRFI-19 date object." + (or (catch 'misc-error + (lambda _ (string->date str "~Y-~m-~dT~H:~M:~S~z")) + (const #f)) + (catch 'misc-error + (lambda _ (string->date str "~Y~m~d ~H:~M")) + (const #f)))) + +(define (string->string* str) str) +(register-metadata-parser! 'date string->custom-date*) +(register-metadata-parser! 'authors string->string*) +(register-metadata-parser! 'license string->string*) + +(define wordpress-markdown-reader + (make-reader (make-file-extension-matcher "md") + (lambda (file) + (call-with-input-file file + (lambda (port) + (values (read-metadata-headers port) + (commonmark->sxml port))))))) |
