429c8025 |
1 | ;; (((author name as symbols) |
2 | ;; "description" |
3 | ;; ("book name" :fiction-or-nonfiction rating/10 "description"))) |
4 | |
5 | (asdf:oos 'asdf:load-op :split-sequence) |
6 | |
7 | (in-package :cl-user) |
8 | |
9 | (defparameter *book-pathname* |
10 | #p"/home/clinton/html/muse/src/unknownlamer.org/book-list.lisp") |
11 | |
12 | (defparameter *muse-pathname* |
13 | #p"/home/clinton/html/muse/site/unknownlamer.org-repo/Book List.muse") |
14 | |
15 | ;; need to collapse whitespace in descriptions |
16 | |
17 | ;; (defun collapse-whitespace (string) |
18 | ;; (format nil "~{~A ~}" |
19 | ;; (split-sequence:split-sequence-if |
20 | ;; (lambda (char) (member char '(#\space #\newline))) string |
21 | ;; :remove-empty-subseqs t))) |
22 | |
23 | (defun collapse-whitespace (string) |
24 | string) |
25 | |
26 | |
27 | (defun print-book-entry (book &optional (stream t)) |
28 | (labels ((ratings-stars (rating) |
29 | (labels ((stars (rating) |
30 | (if (> rating 0) |
31 | (make-string rating :initial-element #\bullet) |
32 | nil))) |
33 | (when rating |
34 | (format nil "<class name=\"rating-good\">~A</class>~@[<class name=\"rating-bad\">~A</class>~] (~A)" |
35 | (stars rating) (stars (- 10 rating)) rating))))) |
36 | (destructuring-bind (title fiction? rating description) |
37 | book |
38 | (format stream "** ~A~%~%~@[*Rating:* ~A / ~]*~A*~%~%~A~%~%" |
39 | title |
40 | (ratings-stars rating) |
41 | (case fiction? |
42 | (:fiction "Fiction") |
43 | (:nonfiction "Nonfiction")) |
44 | (collapse-whitespace description))))) |
45 | |
46 | (defun print-author-entry (entry &optional (stream t)) |
47 | (destructuring-bind (author description &rest books) |
48 | entry |
49 | (format stream "* ~{~A ~}~%~%~A~%~%" |
50 | author (collapse-whitespace description)) |
51 | (mapc (lambda (book) (print-book-entry book stream)) books))) |
52 | |
53 | (defun print-book-database (all-books &optional (stream t)) |
54 | (format stream "#title A Not So Fancy Listing of Books~%~%") |
55 | (mapc (lambda (author) (print-author-entry author stream)) |
56 | all-books)) |
57 | |
58 | (defun print-sorted-book-database (all-books &optional (stream t)) |
59 | (print-book-database (sort (copy-list all-books) |
60 | (lambda (name-1 name-2) |
61 | ;; obviously fails to sort properly |
62 | ;; when two authors have the same last |
63 | ;; name |
64 | (string< (symbol-name name-1) |
65 | (symbol-name name-2))) |
66 | :key (lambda (entry) (car (last (car entry))))) |
67 | stream)) |
68 | |
69 | (defun dump-muse-books-file (&optional (muse-path *muse-pathname*) |
70 | (book-path *book-pathname*)) |
71 | (with-open-file (muse-stream muse-path |
72 | :direction :output |
73 | :element-type 'extended-char |
74 | :if-exists :overwrite |
75 | :if-does-not-exist :create) |
76 | (print-sorted-book-database |
77 | (with-open-file (book-stream book-path :element-type 'extended-char) |
78 | (read book-stream)) |
79 | muse-stream))) |