git.m455.casa

repo2html

clone url: git://git.m455.casa/repo2html


utils.scm

1
2 ;; small utilities ---------------------------------
3
4 (module utils *
5 (import
6 scheme
7 (chicken base)
8 (chicken pathname)
9 (clojurian syntax)
10 srfi-1 ;; list utils
11 )
12 ;; (bail [message [exit-status]])
13 ;; end the program immediately.
14 ;; if a message is provided, print it to the screen.
15 ;; exit-status defaults to 1.
16 (define (bail #!optional msg (status 1))
17 (when msg (print msg))
18 (exit status))
19
20 ;; clojureish "debugging by print statement" tool since i still haven't reached
21 ;; lisp enlightenment
22 (define ((inspect #!optional label #!rest args) s)
23 (display (list label ":" args " => " s) (current-error-port))
24 (newline (current-error-port))
25 s)
26
27 ;; decompose a path s into its constituent parts. returns values:
28 ;;
29 ;; root: "/" if it's an absolute path, "" if relative directory-elements: a list
30 ;; of each directory from root, () if none basename: the filename with extension
31 ;; removed like "readme" or ".bashrc" extension: the file extension with the
32 ;; dot, like ".txt" or "" if none relative-root: the relative path from the
33 ;; given path to the root
34 ;; e.g foo/bar/baz.html -> ../../
35 ;;
36 ;; this is intended to provide default values that make for easier reassembly
37 ;; into filenames.
38 ;;
39 ;; typical use:
40 ;; (->> source-file
41 ;; (pathparts)
42 ;; (define-values (root elements basename extension relative-root)))
43 ;;
44 (define (pathparts s)
45 (define-values (dirname basename extension)
46 (decompose-pathname s))
47 (define-values (origin root directory-elements)
48 (decompose-directory (or dirname "")))
49 ;; discarding origin because idgaf about windows
50 (values (or root "")
51 (or directory-elements '())
52 basename
53 (if extension (string-append "." extension) "")
54 (->>
55 (or directory-elements '())
56 (map (constantly "../"))
57 (apply string-append))))
58
59 ;; like (substring) but doesn't break if start and end are too big/small
60 (define (substring* s start end)
61 (substring s (max start 0) (min end (string-length s))))
62
63 ;; merge alists a and b. values in b "win"
64 (define (alist-merge a b)
65 (lset-union (lambda (x y) (eq? (car x) (car y))) a b))
66
67 ;; like alist-ref but works on nested alists by specifying a path (list of keys)
68 (define (alist-ref-in keys alist #!optional (test eqv?))
69 (if (null? (cdr keys))
70 (alist-ref (car keys) alist test)
71 (alist-ref-in (cdr keys) (alist-ref (car keys) alist test) test)))
72
73 ;; like alist-update, but works on nested alists by specifying a path (list of
74 ;; keys)
75 (define (alist-update-in keys value alist #!optional (test eqv?))
76 (cond
77 ((not alist) #f)
78 ((null? (cdr keys))
79 (alist-update (car keys) value alist test))
80 (else
81 (alist-update (car keys)
82 (alist-update-in (cdr keys) value (alist-ref (car keys) alist test) test)
83 alist test))))
84
85 (define (unless-equals s1 s2)
86 ;; if s1 == s2, then s1, otherwise #f
87 (and (equal? s1 s2) s1))
88 )