💾 Archived View for cipay.ca › schini.scm captured on 2023-04-26 at 13:05:16.
-=-=-=-=-=-=-
;; schini, scheme gemini generator. ;; r7rs and very rigid, so read the doc. ;; run this code with "gauche schini.scm" ;; gauche scheme has all these modules ;; although i can't r7rs-style (import) srfi-13 ?? ;; so i'm doing this the gauche way. (use srfi-95) ; sorting (use srfi-13) ; strings (use srfi-170) ; posix file/dir management ;; consists of: ("dir-to-scan" "# title" "a description") (define dirs-to-scan '(("log" "log" "stuff i write about~") ("poems" "poems" "this is where i keep my poetry :3"))) ;; general variables for the uh atom file (define author "lin") (define atom-title "linen :3") (define atom-url "gemini://cipay.ca/atom.xml") (define site-url "gemini://cipay.ca") ;; extract the title of the file: ;; "# my title" -> "my title" (define (extract-title stream) (with-input-from-file stream (lambda () (string-trim (string-drop (read-line) 1))))) ;; extract the date of the file (define (extract-date file) (with-input-from-file file (lambda () (do ((stream (read-line) (read-line))) ; local val / what to iterate with ((eof-object? (peek-char)) stream))))) ; clause, return value ;; format the date to an integer ;; 2023-10-15 -> 20231015 (define (format-date f) (string-delete #\- (extract-date f))) ;; simply put a / between the two strings. ;; i'm lazy shut up (define (pathify dir file) (string-append dir "/" file)) ;; generate an alist from DIR with the format: ;; '(("date" "file/path.gmi" "my title")) ;; PROGRESS-BAR is a boolean denoting whether we want to print a dot (define (gen-list dir progress-bar) (let ((stream (open-directory dir))) ; the stream of files in the dir (do ((f (read-directory stream) (read-directory stream)) (list-of-dates '())) ((eof-object? f) list-of-dates) (if progress-bar (display ".")) (unless (string=? f "index.gmi") (set! list-of-dates (cons (list (format-date (pathify dir f)) ;; (pathify dir f) f (extract-title (pathify dir f))) list-of-dates)))) )) ;; make list of links from files in a dir, a link looks like ;; => file/path.gmi my title (define (make-links dir) (do ((dates-titles (sort (gen-list dir #t)) (cdr dates-titles)) (answer '())) ((null? dates-titles) answer) (let ((date (caar dates-titles)) (title (caddar dates-titles)) (file (cadar dates-titles))) (set! answer (cons (string-append "=> " file " " title) answer))))) ;; generate an index file from dir to dir/index.gmi (define (make-index dir) (let* ((mylist (assoc dir dirs-to-scan)) (links (make-links dir)) (desc (caddr mylist)) (title (car mylist))) (with-output-to-file (string-append dir "/index.gmi") (lambda () (display (string-append "# " title "\n\n" desc "\n\n")) (do ((my-links links (cdr my-links))) ((null? my-links) (display "")) (display (string-append (car my-links) "\n"))))))) (define (make-all-indexes) (do ((x dirs-to-scan (cdr x))) ((null? x) '()) (make-index (caar x)))) (define (collect-all-links) (do ((mylst dirs-to-scan (cdr mylst)) (answer '())) ((null? mylst) (reverse (sort answer))) ; new posts at top (set! answer (append (gen-list (caar mylst) #f) answer)))) ;; turn our extracted date string "20231015" ;; into an atom-compliant yyyy-mm-ddThh:mm:ss string (define (atomify-date date-string) (let* ((year (substring date-string 0 4)) ; yyyy (month (substring date-string 4 6)) ; mm (day (substring date-string 6 8))) ; dd (string-append year "-" month "-" day "T12:00:00"))) (define (make-atom-entries) (do ((mylst (collect-all-links) (cdr mylst)) (answer '())) ((null? mylst) answer) (set! answer (cons (make-atom-entry mylst) answer)))) (define (make-atom-entry list-of-links) (let* ((lst list-of-links) (date (caar lst)) (file (cadar lst)) (title (caddar lst))) (string-append "<entry> <id>" site-url "/" file "</id> <title>" title "</title> <updated>" (atomify-date date) "</updated> <link href='" site-url "/" file "' rel='alternate'/> </entry>\n\n"))) (define (stringify-atom-entries) (do ((mylst (make-atom-entries) (cdr mylst)) (answer "")) ((null? mylst) answer) (set! answer (string-append (car mylst) answer)))) ;; uh just find the newest post and atomify it uwu (define (last-update) (let* ((date (caar (collect-all-links)))) (atomify-date date))) ;; i was gonna do this in sxml but i'm sticking with uhhhhh ;; r7rs as much as i can so this is fine (define atom-layout (string-append "<?xml version='1.0' encoding='UTF-8'?> <feed xmlns='http://www.w3.org/2005/Atom'> <title>" atom-title "</title> <id>" site-url "</id> <author> <name>" author "</name> </author> <updated>" (last-update) "</updated> <link href='" atom-url "' rel='self'/>\n\n" (stringify-atom-entries) "</feed>")) (define (start) (display "------------") (newline) (display "schini, scheme gemini index generator") (newline);; print this (with-output-to-file "atom.xml" (lambda () (display atom-layout))) (display "printed atom.xml\n") (display "progress: ") (make-all-indexes) (display "\ndone!\n")) (start) ;; notes ;; so yeah yyyy-mm-dd is the best date format ;; cause i can just sort it as an int and it comes out right >:3