Kaynağa Gözat

*tweet-format* DSL

PuercoPop 11 yıl önce
ebeveyn
işleme
3b59ca1321
1 değiştirilmiş dosya ile 50 ekleme ve 3 silme
  1. 50 3
      plugins/twitter.lisp

+ 50 - 3
plugins/twitter.lisp

@@ -13,9 +13,56 @@
13 13
 
14 14
 (in-package :coleslaw-twitter)
15 15
 
16
-(defvar *tweet-format* '("~A by ~A" coleslaw::post-title coleslaw::post-author)
17
-  "Controls what the tweet annoucing the post looks like. It contains a format
18
-  control string followed with the accesors to evaluate for post.")
16
+(defvar *tweet-format* '(:title "by" :author)
17
+  "Controls what the tweet annoucing the post looks like.")
18
+
19
+(defvar *tweet-format-fn* nil "Function that expects an instance of
20
+coleslaw:post and returns the tweet content.")
21
+
22
+(defvar *tweet-format-dsl-mapping*
23
+  '((:title . coleslaw::post-title)
24
+    (:author . coleslaw::post-author)))
25
+
26
+(define-condition malformed-tweet-format (error)
27
+  ((item :initarg :item :reader item))
28
+  (:report
29
+   (lambda (condition stream)
30
+     (format stream "Malformed tweet format. Can't proccess: ~A"
31
+             (item condition)))))
32
+
33
+(defun compile-tweet-format (tweet-format)
34
+  (multiple-value-bind
35
+        (fmt-ctrl-str accesors) (%compile-tweet-format tweet-format nil nil)
36
+    (let
37
+        ((fmt-ctrl-str (format nil "~{~A~^ ~}" (reverse fmt-ctrl-str)))
38
+         (accesors (reverse accesors)))
39
+      (lambda (post)
40
+        (apply #'format nil fmt-ctrl-str
41
+               (loop
42
+                  :for accesor :in accesors
43
+                  :collect (funcall accesor post)))))))
44
+
45
+(defun %compile-tweet-format (tweet-format fmt-ctrl-str accesors)
46
+  "Transform tweet-format into a format control string and a list of values."
47
+  (if (null tweet-format)
48
+      (values fmt-ctrl-str accesors)
49
+      (let ((next (car tweet-format)))
50
+        (cond
51
+          ((keywordp next)
52
+           (if (assoc next *tweet-format-dsl-mapping*)
53
+               (%compile-tweet-format
54
+                (cdr tweet-format)
55
+                (cons "~A" fmt-ctrl-str)
56
+                (cons (cdr (assoc next *tweet-format-dsl-mapping*))
57
+                      accesors))
58
+               (error 'malformed-tweet-format :item next)))
59
+          ((stringp next)
60
+           (%compile-tweet-format (cdr tweet-format)
61
+                                  (cons next fmt-ctrl-str)
62
+                                  accesors))
63
+          (t (error 'malformed-tweet-format :item next))))))
64
+
65
+(setf *tweet-format-fn* (compile-tweet-format *tweet-format*))
19 66
 
20 67
 (defun enable (&key api-key api-secret access-token access-secret tweet-format)
21 68
   (if (and api-key api-secret access-token access-secret)