|
@@ -1,5 +1,7 @@
|
1
|
1
|
(in-package :coleslaw)
|
2
|
2
|
|
|
3
|
+;; Tagging
|
|
4
|
+
|
3
|
5
|
(defclass tag ()
|
4
|
6
|
((name :initform nil :initarg :name :accessor tag-name)
|
5
|
7
|
(slug :initform nil :Initarg :slug :accessor tag-slug)))
|
|
@@ -13,21 +15,27 @@
|
13
|
15
|
"Test if the slugs for tag A and B are equal."
|
14
|
16
|
(string= (tag-slug a) (tag-slug b)))
|
15
|
17
|
|
|
18
|
+;; Slugs
|
|
19
|
+
|
|
20
|
+(defun slug-char-p (char)
|
|
21
|
+ "Determine if CHAR is a valid slug (i.e. URL) character."
|
|
22
|
+ (or (char<= #\0 char #\9)
|
|
23
|
+ (char<= #\a char #\z)
|
|
24
|
+ (char<= #\A char #\Z)
|
|
25
|
+ (member char '(#\_ #\-))))
|
|
26
|
+
|
|
27
|
+(defun slugify (string)
|
|
28
|
+ "Return a version of STRING suitable for use as a URL."
|
|
29
|
+ (remove-if-not #'slug-char-p (substitute #\- #\Space string)))
|
|
30
|
+
|
|
31
|
+;; Content Types
|
|
32
|
+
|
16
|
33
|
(defclass content ()
|
17
|
34
|
((tags :initform nil :initarg :tags :accessor content-tags)
|
18
|
35
|
(slug :initform nil :initarg :slug :accessor content-slug)
|
19
|
36
|
(date :initform nil :initarg :date :accessor content-date)
|
20
|
37
|
(text :initform nil :initarg :text :accessor content-text)))
|
21
|
38
|
|
22
|
|
-(defun tag-p (tag obj)
|
23
|
|
- "Test if OBJ is tagged with TAG."
|
24
|
|
- (let ((tag (if (typep tag 'tag) tag (make-tag tag))))
|
25
|
|
- (member tag (content-tags obj) :test #'tag-slug=)))
|
26
|
|
-
|
27
|
|
-(defun month-p (month obj)
|
28
|
|
- "Test if OBJ was written in MONTH."
|
29
|
|
- (search month (content-date obj)))
|
30
|
|
-
|
31
|
39
|
(defun read-content (file)
|
32
|
40
|
"Returns a plist of metadata from FILE with :text holding the content as a string."
|
33
|
41
|
(flet ((slurp-remainder (stream)
|
|
@@ -52,17 +60,15 @@
|
52
|
60
|
(setf (getf meta :tags) (read-tags (getf meta :tags)))
|
53
|
61
|
(append meta (list :text content))))))
|
54
|
62
|
|
|
63
|
+(defun tag-p (tag obj)
|
|
64
|
+ "Test if OBJ is tagged with TAG."
|
|
65
|
+ (let ((tag (if (typep tag 'tag) tag (make-tag tag))))
|
|
66
|
+ (member tag (content-tags obj) :test #'tag-slug=)))
|
|
67
|
+
|
|
68
|
+(defun month-p (month obj)
|
|
69
|
+ "Test if OBJ was written in MONTH."
|
|
70
|
+ (search month (content-date obj)))
|
|
71
|
+
|
55
|
72
|
(defun by-date (content)
|
56
|
73
|
"Sort CONTENT in reverse chronological order."
|
57
|
74
|
(sort content #'string> :key #'content-date))
|
58
|
|
-
|
59
|
|
-(defun slug-char-p (char)
|
60
|
|
- "Determine if CHAR is a valid slug (i.e. URL) character."
|
61
|
|
- (or (char<= #\0 char #\9)
|
62
|
|
- (char<= #\a char #\z)
|
63
|
|
- (char<= #\A char #\Z)
|
64
|
|
- (member char '(#\_ #\-))))
|
65
|
|
-
|
66
|
|
-(defun slugify (string)
|
67
|
|
- "Return a version of STRING suitable for use as a URL."
|
68
|
|
- (remove-if-not #'slug-char-p (substitute #\- #\Space string)))
|