(import (Alpha Core)) (import (prefix (Alpha String) string.)) (import (srfi srfi-1)) (import (only (srfi srfi-19) date->string current-date)) (import (prefix (re) re.)) ;; general functions (import (only (ice-9 ftw) scandir)) (define (os.listdir path) (scandir path)) (define (os.path.expanduser path) (let ([home (getenv "HOME")]) (string.replace path "~" home))) (import (only (srfi srfi-1) remove)) (define (rm ls item) (remove (/. x (eq? x item)) ls)) (define (set.difference s1 s2) (cond [(null? s1) '()] [(not (member? (first s1) s2)) (cons (first s1) (set.difference (rest s1) s2))] [else (set.difference (rest s1) s2)])) (import (only (ice-9 rdelim) read-delimited)) (define (readlines fname) (call-with-input-file fname (lambda [p] (read-delimited "" p 'concat)))) ;; z program (define *zdir* (os.path.expanduser "~/test-z-wiki")) ;; A node 'id' is a monotonically increasing number. ;; It can be represented as a string, in which case it is encoded in ;; base 36. (define (id->string id) (number->string id 36)) (define (string->id s) (string->number s 36)) ;; It can be represented as a path, in which case it is ;; `<*zdir*>/.md' (define (path->id fname) "Given a path, parse out the node id." (-> fname (string.replace ".md" "") (string.replace *zdir* "") (string->id))) (define (id->path id) "Given an id, return the absolute path to the file." (fmt "~a/~a.md" *zdir* (id->string id))) ;; Manipulating nodes (define (list-nodes* dir) (->> dir (os.listdir) ;; remove '.' and '..' ((/. s (set.difference s '("." "..")))) (map path->id))) (define (list-nodes) (list-nodes* *zdir*)) (define (latest-node ls) (if (eq? ls '()) 0 (apply max ls))) (define (make-node title) (call-with-output-file (-> (list-nodes) latest-node inc id->path) (fn [file] (format file "title: ~a\n" title) (format file "created: ~a\n" (date->string (current-date) "~Y.~m.~d..~H.~M")) (format file "tags:\n") (display "---\n" file)))) (define (read-node id) (readlines (id->path id))) (define (cat-node id) (prn (read-node id))) ;; Metadata (define (get-title id) (-> id read-node (re.match "title: ([^\n]*)") (match:substring 1))) (define (get-by-title title) (let ([index (index-titles)]) (assoc title index))) (define (get-tags id) (-> id read-node (re.match "tags: ([^\n]*)") (re.group 1) (string.split #\space))) ;; Indexing (define (index-titles) (fold (/. node ls (acons (get-title node) node ls)) '() (list-nodes)))