💾 Archived View for cipay.ca › schini.scm captured on 2023-05-24 at 17:43:12.

View Raw

More Information

⬅️ Previous capture (2023-04-26)

🚧 View Differences

-=-=-=-=-=-=-

;; 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)
			(extract-title (pathify dir f))
      f) ;; the file without the date path attached onto it ig
		  list-of-dates)))) ))


;; make list of links from files in a dir, a link looks like
;; => file/path.gmi my title
(define (cadddar lst)
  (cadr (cddar lst)))
(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  (cadddar  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