git.fiddlerwoaroof.com
Browse code

Misc updates

Ed Langley authored on 07/04/2019 23:00:19
Showing 7 changed files
... ...
@@ -3,29 +3,6 @@
3 3
   (:export ))
4 4
 (in-package :fwoar.blog)
5 5
 
6
-(defmacro new (class &rest initializer-syms)
7
-  (multiple-value-bind (required optional rest) (parse-ordinary-lambda-list initializer-syms)
8
-    (when optional
9
-      (error "new doesn't handle optional arguments"))
10
-    (if rest
11
-        `(make-instance ,class
12
-                        ,@(mapcan (serapeum:op (list (alexandria:make-keyword _1) _1))
13
-                                  required)
14
-                        ,(make-keyword rest) ,rest)
15
-        `(make-instance ,class
16
-                        ,@(mapcan (serapeum:op (list (alexandria:make-keyword _1) _1))
17
-                                  initializer-syms)))))
18
-
19
-(defun-ct %constructor-name (class)
20
-  (format nil "~a-~a" '#:make class))
21
-
22
-(defmacro make-constructor (class &rest args)
23
-  (destructuring-bind (class &optional (constructor-name (intern (%constructor-name class))))
24
-      (ensure-list class)
25
-    `(defgeneric ,constructor-name (,@args)
26
-       (:method (,@args)
27
-         (new ',class ,@args)))))
28
-
29 6
 (defclass blog ()
30 7
   ((%posts :initarg :posts :accessor posts))
31 8
   (:default-initargs :posts ()))
... ...
@@ -34,7 +11,6 @@
34 11
   (format s "#.(make-blog ~{~s~^ ~})"
35 12
           (posts o)))
36 13
 
37
-
38 14
 (defclass post ()
39 15
   ((%content :initarg :content :accessor content)))
40 16
 
... ...
@@ -85,15 +61,13 @@
85 61
 (defclass blog-route ()
86 62
   ((%blog :initarg :blog :reader blog)))
87 63
 
88
-(defclass index (blog-route)
64
+(defclass index-route (blog-route)
89 65
   ())
90
-(make-constructor (index make-blog-index))
91 66
 
92 67
 (defclass post-route (blog-route)
93 68
   ((%post :initarg :post :reader post)))
94
-(make-constructor (post make-blog-post))
95 69
 
96
-(defmethod controller ((route index) params &key)
70
+(defmethod controller ((route index-route) params &key)
97 71
   (posts (blog route)))
98 72
 
99 73
 (defmethod controller ((route post-route) params &key)
... ...
@@ -106,7 +80,7 @@
106 80
      (:div
107 81
       (content post)))))
108 82
 
109
-(defmethod view ((name index) posts)
83
+(defmethod view ((name index-route) posts)
110 84
   (spinneret:with-html-string
111 85
     (:section
112 86
      (:h* "Blog Index")
... ...
@@ -114,13 +88,13 @@
114 88
       (loop for post in posts
115 89
             do (call-current-view post))))))
116 90
 
117
-(defmethod view ((name index) (post micropost))
91
+(defmethod view ((name index-route) (post micropost))
118 92
   (spinneret:with-html
119 93
     (:section.post.micropost
120 94
      (content post))))
121 95
 
122 96
 
123
-(defmethod view ((name index) (post macropost))
97
+(defmethod view ((name index-route) (post macropost))
124 98
   (spinneret:with-html
125 99
     (:section.post.macropost
126 100
      (:h* (:a :href (format nil "/~a" (slugify (title post)))
... ...
@@ -128,12 +102,15 @@
128 102
 
129 103
 (defun setup-routes (app blog)
130 104
   (defroutes app
131
-    (("/" :method :GET) (as-route (make-instance 'index :blog blog)))
132
-    (("/:post" :method :GET) (lambda (params)
133
-                               (format t "~&params: ~s~%" params)
134
-                               (let* ((post-name (cdr (assoc :post params)))
135
-                                      (route (make-instance 'post-route :post (find-post post-name blog))))
136
-                                 (run-route route params))))))
105
+    (("/" :method :GET)
106
+     (as-route
107
+      (make-instance 'index-route :blog blog)))
108
+    (("/:post" :method :GET)
109
+     (lambda (params)
110
+       (format t "~&params: ~s~%" params)
111
+       (let* ((post-name (cdr (assoc :post params)))
112
+              (route (make-instance 'post-route :post (find-post post-name blog))))
113
+         (run-route route params))))))
137 114
 
138 115
 (defvar *blog*
139 116
   (make-blog (make-micropost "first post")
140 117
new file mode 100644
... ...
@@ -0,0 +1,62 @@
1
+(defpackage :fwoar.decision-table
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.decision-table)
5
+
6
+(defun array= (array1 array2 &optional (element-compare 'eql))
7
+  (and (= (length array1)
8
+          (length array2))
9
+       (every element-compare array1 array2)))
10
+
11
+(defun apply-decision-table (table inputs)
12
+  (destructuring-bind (row col) (array-dimensions table)
13
+    (loop with input-length = (length inputs)
14
+          for cur-row from 0 below row
15
+          for array-accessor = (make-array input-length
16
+                                           :displaced-to table
17
+                                           :displaced-index-offset (array-row-major-index table cur-row 0))
18
+            then (adjust-array array-accessor input-length
19
+                               :displaced-to table
20
+                               :displaced-index-offset (array-row-major-index table cur-row 0))
21
+          while (not (array= inputs array-accessor))
22
+          finally (return
23
+                    (aref table cur-row (1- col))))))
24
+
25
+(defmacro let-order ((min max) (a b) &body body)
26
+  (alexandria:once-only (a b)
27
+    `(destructuring-bind (,min ,max) (if (<= (length ,a) (length ,b))
28
+                                         (list ,a ,b)
29
+                                         (list ,b ,a))
30
+       ,@body)))
31
+
32
+(defmacro let-by-length ((a b) &body body)
33
+  `(let-order (,a ,b) (,a ,b)
34
+     ,@body))
35
+
36
+;; 
37
+;;
38
+;;
39
+;;
40
+
41
+(defun levehnstein-1-p (a b)
42
+  (let-by-length (a b)
43
+    (if (equal a b)
44
+        t
45
+        (cond ((= (length b)
46
+                  (length a))
47
+               (= (loop
48
+                    for x from 0 below (length a)
49
+                    when (not (eql (elt a x)
50
+                                   (elt b x)))
51
+                      count 1)
52
+                  1))
53
+              ((= (- (length b)
54
+                     (length a))
55
+                  1)
56
+               (some 'identity
57
+                     (map 'list
58
+                          (op (equal a
59
+                                     (remove _1 b
60
+                                             :start _2
61
+                                             :count 1)))
62
+                          b (alexandria:iota (length b)))))))))
... ...
@@ -98,7 +98,7 @@
98 98
      (format nil "~a.mp4"
99 99
              (puri:render-uri
100 100
               (fw.lu:prog1-bind (uri (puri:copy-uri uri))
101
-                (setf (puri:uri-host uri) "gfycat.com"))
101
+                (setf (puri:uri-host uri) "giant.gfycat.com"))
102 102
               nil))))
103 103
   (:method ((site (eql :imgur)) uri)
104 104
     (make-image
... ...
@@ -244,7 +244,7 @@
244 244
 (define-view root ((model video))
245 245
   (spinneret:with-html
246 246
     (:div.image
247
-     (:video :autoplay "autoplay" (:source :src (url model) :type "video/mp4")))))
247
+     (:video :autoplay "autoplay" :loop "loop" (:source :src (url model) :type "video/mp4")))))
248 248
 
249 249
 (defun initialize-app (app gallery)
250 250
   (defroutes app
251 251
new file mode 100644
... ...
@@ -0,0 +1,93 @@
1
+(defpackage :fwoar.generic-fun-special-decl
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.generic-fun-special-decl)
5
+
6
+(defgeneric foo (arg))
7
+(let (*arg*)
8
+  (declare (special *arg*))
9
+  (defmethod foo :around (*arg*)
10
+             (declare (special *arg*))
11
+             (format t "~&*ARG* in :around: ~s~%" *arg*)
12
+             (call-next-method))
13
+  (defmethod foo :before (arg)
14
+             (declare (ignore arg))
15
+             (format t "~&*ARG* in :before: ~s~%" *arg*))
16
+  (defmethod foo :after (arg)
17
+             (declare (ignore arg))
18
+             (format t "~&*ARG* in :after: ~s~%" *arg*))
19
+  (defmethod foo ((arg string))
20
+    (format t "~&*ARG* in method for string: ~s~%" *arg*)
21
+    (let ((*arg* (parse-integer *arg*)))
22
+      (declare (special *arg*))
23
+      (format t "~&*ARG* in method for string, after rebinding: ~s~%" *arg*)
24
+      (call-next-method)))
25
+  (defmethod foo (arg)
26
+    (declare (ignore arg))
27
+    (format t "~&*ARG* in method for t: ~s~%" *arg*)))
28
+
29
+
30
+#|
31
+FWOAR.GENERIC-FUN-SPECIAL-DECL> (foo "4")
32
+*ARG* in :around: "4"
33
+*ARG* in :before: "4"
34
+*ARG* in method for string: "4"
35
+*ARG* in method for string, after rebinding: 4
36
+*ARG* in method for t: 4
37
+*ARG* in :after: "4"
38
+|#
39
+
40
+;; in: DEFMETHOD FOO :AROUND (T)
41
+;;     (DEFMETHOD FWOAR.GENERIC-FUN-SPECIAL-DECL::FOO :AROUND
42
+;;                (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
43
+;;       (DECLARE (SPECIAL FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*))
44
+;;       (FORMAT T "~&*ARG* in :around: ~s~%" FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
45
+;;       (CALL-NEXT-METHOD))
46
+;; --> PROGN EVAL-WHEN SB-PCL::%DEFMETHOD-EXPANDER 
47
+;; --> SB-PCL::LOAD-DEFMETHOD LIST* LET* SB-INT:NAMED-LAMBDA FUNCTION 
48
+;; --> SYMBOL-MACROLET SB-PCL::FAST-LEXICAL-METHOD-FUNCTIONS 
49
+;; --> SB-PCL::BIND-FAST-LEXICAL-METHOD-FUNCTIONS FLET CALL-NEXT-METHOD 
50
+;; --> BLOCK SB-PCL::FAST-CALL-NEXT-METHOD-BODY IF IF SB-PCL::BIND-ARGS 
51
+;; ==>
52
+;;   (LET* ((SB-PCL::.ARGS-TAIL. SB-PCL::CNM-ARGS)
53
+;;          (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG* (POP SB-PCL::.ARGS-TAIL.))
54
+;;          (SB-PCL::.DUMMY0.))
55
+;;     (DECLARE (IGNORABLE SB-PCL::.ARGS-TAIL. SB-PCL::.DUMMY0.))
56
+;;     (SB-PCL::INVOKE-NARROW-EFFECTIVE-METHOD-FUNCTION SB-PCL::.NEXT-METHOD-CALL.
57
+;;                                                      NIL :REQUIRED-ARGS
58
+;;                                                      (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
59
+;;                                                      :REST-ARG NIL))
60
+;; 
61
+;; caught STYLE-WARNING:
62
+;;   using the lexical binding of the symbol (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*), not the
63
+;;   dynamic binding, even though the name follows
64
+;;   the usual naming convention (names like *FOO*) for special variables
65
+
66
+;; in: DEFMETHOD FOO :AROUND (T)
67
+;;     (DEFMETHOD FWOAR.GENERIC-FUN-SPECIAL-DECL::FOO :AROUND
68
+;;                (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
69
+;;       (DECLARE (SPECIAL FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*))
70
+;;       (FORMAT T "~&*ARG* in :around: ~s~%" FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
71
+;;       (CALL-NEXT-METHOD))
72
+;; --> PROGN EVAL-WHEN SB-PCL::%DEFMETHOD-EXPANDER 
73
+;; --> SB-PCL::LOAD-DEFMETHOD LIST* LET* SB-INT:NAMED-LAMBDA FUNCTION 
74
+;; --> SYMBOL-MACROLET SB-PCL::FAST-LEXICAL-METHOD-FUNCTIONS 
75
+;; --> SB-PCL::BIND-FAST-LEXICAL-METHOD-FUNCTIONS FLET CALL-NEXT-METHOD 
76
+;; --> BLOCK SB-PCL::FAST-CALL-NEXT-METHOD-BODY IF IF SB-PCL::BIND-ARGS 
77
+;; ==>
78
+;;   (LET* ((SB-PCL::.ARGS-TAIL. SB-PCL::CNM-ARGS)
79
+;;          (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG* (POP SB-PCL::.ARGS-TAIL.))
80
+;;          (SB-PCL::.DUMMY0.))
81
+;;     (DECLARE (IGNORABLE SB-PCL::.ARGS-TAIL. SB-PCL::.DUMMY0.))
82
+;;     (SB-PCL::INVOKE-NARROW-EFFECTIVE-METHOD-FUNCTION SB-PCL::.NEXT-METHOD-CALL.
83
+;;                                                      NIL :REQUIRED-ARGS
84
+;;                                                      (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*)
85
+;;                                                      :REST-ARG NIL))
86
+;; 
87
+;; caught STYLE-WARNING:
88
+;;   using the lexical binding of the symbol (FWOAR.GENERIC-FUN-SPECIAL-DECL::*ARG*), not the
89
+;;   dynamic binding, even though the name follows
90
+;;   the usual naming convention (names like *FOO*) for special variables
91
+;; 
92
+;; compilation unit finished
93
+;;   caught 2 STYLE-WARNING conditions
0 94
new file mode 100644
... ...
@@ -0,0 +1,103 @@
1
+(defpackage :fwoar.raft
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.raft)
5
+
6
+(defun take-keys (h-t &rest keys)
7
+  (mapcar (lambda (key)
8
+            (gethash key h-t))
9
+          keys))
10
+
11
+(defclass node ()
12
+  ((%current-term :accessor term :initform 0 :initarg :current-term)
13
+   (%voted-for    :accessor voted-for    :initform nil :initarg :leader-id)
14
+   (%e-log        :accessor e-log
15
+                  :initform (make-array 100 :adjustable t :fill-pointer 0))
16
+   (%client-id    :accessor id)
17
+   (%committed-index :accessor commit-index :initform 0)
18
+   (%last-applied :accessor last-applied :initform 0)))
19
+
20
+
21
+(defclass leader (node)
22
+  ((%next-index  :accessor next-index  :initform ())
23
+   (%match-index :accessor match-index :initform ())))
24
+
25
+(defclass append-entry-arguments ()
26
+  ((%term :initarg :term :reader term)
27
+   (%leader-id :initarg :leader-id :reader leader-id)
28
+   (%prev-log-index :initarg :prev-log-index :reader prev-log-index)
29
+   (%prev-log-term :initarg :prev-log-term :reader prev-log-term)
30
+   (%entries :initarg :entries :reader entries)
31
+   (%leader-commit :initarg :leader-commit :reader leader-commit)))
32
+
33
+(defclass entry ()
34
+  ((%term :initarg :term :accessor term)
35
+   (%data :initarg :data :accessor data)))
36
+
37
+(defmethod print-object ((o entry) s)
38
+  (print-unreadable-object (o s :type t :identity t)
39
+    (format s "term: ~s data: ~s"
40
+            (term o)
41
+            (data o))))
42
+
43
+(defun entry (term data)
44
+  (make-instance 'entry
45
+                 :term term
46
+                 :data data))
47
+
48
+(defun add-log-entry (node entry)
49
+  (assert (= (term entry) (term node))
50
+          (entry node)
51
+          "term-mismatch ~s ~s"
52
+          (term entry)
53
+          (term node))
54
+  (vector-push-extend entry (e-log node)))
55
+
56
+(defun get-log-entry (follower idx)
57
+  (elt (e-log follower)
58
+       idx))
59
+
60
+(defgeneric append-entries (follower args)
61
+  (:method ((follower node) (args append-entry-arguments))
62
+    (with-accessors ((term term)
63
+                     (leader-id leader-id)
64
+                     (prev-log-index prev-log-index)
65
+                     (prev-log-term prev-log-term)
66
+                     (entries entries)
67
+                     (leader-commit leader-commit)) args
68
+      
69
+      (when (< term (term follower))
70
+        (return-from append-entries
71
+          (values term nil)))
72
+
73
+      (when (/= (term (get-log-entry follower prev-log-index))
74
+                prev-log-term)
75
+        (return-from append-entries
76
+          (values term nil)))
77
+
78
+      #|If an existing entry conflicts with a new one (same index but|#
79
+      #|   different terms), delete the existing entry and all that  |#
80
+      #|   follow it (§5.3)                                          |#
81
+
82
+      (loop for new-entries-index from (1+ prev-log-index)
83
+            for (entry . rest-entries) on entries
84
+            for existing-entry in (subseq (e-log follower) (1+ prev-log-index))
85
+            until (/= (term entry)
86
+                      (term existing-entry))
87
+            finally
88
+               (when (< new-entries-index (length (e-log follower)))
89
+                 (setf (fill-pointer (e-log follower)) new-entries-index))
90
+
91
+               (map nil
92
+                    (lambda (el)
93
+                      (vector-push-extend el (e-log follower)))
94
+                    rest-entries))
95
+
96
+      (when (> leader-commit (commit-index follower))
97
+        (setf (commit-index follower)
98
+              (min leader-commit
99
+                   (1- (length (e-log follower))))))
100
+
101
+      (values (term follower)
102
+              t))))
103
+
... ...
@@ -1,21 +1,21 @@
1 1
 (ql:quickload '(:plump
2
-		:lquery
3
-		:serapeum
4
-		:alexandria
5
-		:flexi-streams
6
-		:chipz
7
-		:babel
8
-		:net.didierverna.clon))
2
+                :lquery
3
+                :serapeum
4
+                :alexandria
5
+                :flexi-streams
6
+                :chipz
7
+                :babel
8
+                :net.didierverna.clon))
9 9
 
10 10
 (in-package #:org.shirakumo.plump.parser)
11 11
 (define-tag-dispatcher (script *tag-dispatchers* *html-tags*)
12 12
     (name)
13
-    (string-equal name "script")
13
+  (string-equal name "script")
14 14
   (let* ((closing (consume))
15 15
          (attrs
16
-          (if (char= closing #\ )
17
-              (prog1 (read-attributes) (setf closing (consume)))
18
-              (make-attribute-map))))
16
+           (if (char= closing #\ )
17
+               (prog1 (read-attributes) (setf closing (consume)))
18
+               (make-attribute-map))))
19 19
     (case closing
20 20
       (#\/ (advance) (make-element *root* "script" :attributes attrs))
21 21
       (#\>
... ...
@@ -34,11 +34,11 @@
34 34
 
35 35
 (defvar *version* "0.001")
36 36
 (defsynopsis (:postfix "FILE")
37
-  (group (:header "Generic options")
38
-         (flag :short-name "v" :long-name "version"
39
-               :description "Show the program version")
40
-         (flag :short-name "h" :long-name "help"
41
-               :description "Show this help")))
37
+    (group (:header "Generic options")
38
+           (flag :short-name "v" :long-name "version"
39
+                 :description "Show the program version")
40
+           (flag :short-name "h" :long-name "help"
41
+                 :description "Show this help")))
42 42
 
43 43
 
44 44
 (defvar *txt* nil "The parsed HTML")
... ...
@@ -50,14 +50,14 @@
50 50
 (defun call-with-decompressed-text (fn cb &optional (encoding :iso-8859-1))
51 51
   (with-input-from-file (s fn :element-type '(unsigned-byte 8))
52 52
     (let* ((decompressing-stream (chipz:make-decompressing-stream 'chipz:bzip2 s))
53
-	   (flexi-stream (flexi-streams:make-flexi-stream decompressing-stream :external-format encoding)))
53
+           (flexi-stream (flexi-streams:make-flexi-stream decompressing-stream :external-format encoding)))
54 54
       (unwind-protect (funcall cb flexi-stream)
55
-	(close flexi-stream)
56
-	(close decompressing-stream)))))
55
+        (close flexi-stream)
56
+        (close decompressing-stream)))))
57 57
 
58 58
 (defun lookup-ref (p q a &rest r)
59 59
   (gethash (format nil "~aq.~da.~d~{~a~}" (string-upcase p) q a r)
60
-	   *lookup-table*))
60
+           *lookup-table*))
61 61
 
62 62
 (defun translate-book-ref (ref)
63 63
   (string-case ref
... ...
@@ -68,13 +68,13 @@
68 68
 (defun normalize-ref (ref)
69 69
   (destructuring-bind (book . ref) (split-sequence #\, ref)
70 70
     (if ref
71
-	(setf ref (string-join ref ","))
72
-	(setf ref book
73
-	      book ""))
71
+        (setf ref (string-join ref ","))
72
+        (setf ref book
73
+              book ""))
74 74
     (values (string-join (split-sequence #\space ref
75
-					 :remove-empty-subseqs t))
76
-	    (translate-book-ref (remove-if-not #'upper-case-p
77
-					       (string-capitalize book))))))
75
+                                         :remove-empty-subseqs t))
76
+            (translate-book-ref (remove-if-not #'upper-case-p
77
+                                               (string-capitalize book))))))
78 78
 
79 79
 
80 80
 (defun help ())
... ...
@@ -86,46 +86,46 @@
86 86
 (defmacro mark-start (&body body)
87 87
   (with-gensyms (start)
88 88
     `(tagbody
89
-	,start
90
-	(flet ((to-top () (go ,start)))
91
-	  ,@body))))
89
+        ,start
90
+        (flet ((to-top () (go ,start)))
91
+          ,@body))))
92 92
 
93 93
 (defun transform-ct-main ()
94 94
   (make-context)
95 95
   (mark-start
96
-    (restart-case
97
-	(cond
98
-	  ((getopt :long-name "help") (help))
99
-	  ((getopt :long-name "version") (show-version))
100
-	  (t (let ((file (car (remainder)))
101
-		   (ofile (cadr (remainder)))
102
-		   (*package* (find-package 'ct-transform)))
103
-	       (lquery:initialize (call-with-decompressed-text file #'plump:parse))
104
-	       (map 'list
105
-		    (op (destructuring-bind (ref el) _
106
-			  (setf (gethash (multiple-value-list (normalize-ref ref))
107
-					 *lookup-table*)
108
-				(plump:text el))))
109
-		    ($ "p[title]" (combine (attr :title) (node))))
110
-
111
-	       (let ((*print-case* :downcase))
112
-		 (alexandria:with-output-to-file (*standard-output* ofile)
113
-		   (loop for (ref book) being the hash-keys in *lookup-table* using (hash-value text)
114
-		      do (print `(ref ,book ,ref
115
-				      ,text)))))
116
-	       ;; (alexandria:with-input-from-file (s *fn* :external-format :iso-8859-1)
117
-	       ;;   (setf *txt* (plump:parse s)))
118
-
119
-	       ;; (uiop:directory-files "." (uiop:merge-pathnames* (make-pathname :type "bz2") uiop:*wild-file*))
120
-	       ;; (car *)
121
-	       ;; (plump:parse *)
122
-	       ;; (lquery:initialize *)
123
-	       ;; ($ "p[title]" (combine (attr :title)
124
-	       ;; 			    (text)))
125
-
126
-	       )))
127
-      (retry () (to-top))
128
-      (abort ()))))
96
+   (restart-case
97
+       (cond
98
+         ((getopt :long-name "help") (help))
99
+         ((getopt :long-name "version") (show-version))
100
+         (t (let ((file (car (remainder)))
101
+                  (ofile (cadr (remainder)))
102
+                  (*package* (find-package 'ct-transform)))
103
+              (lquery:initialize (call-with-decompressed-text file #'plump:parse))
104
+              (map 'list
105
+                   (op (destructuring-bind (ref el) _
106
+                         (setf (gethash (multiple-value-list (normalize-ref ref))
107
+                                        *lookup-table*)
108
+                               (plump:text el))))
109
+                   ($ "p[title]" (combine (attr :title) (node))))
110
+
111
+              (let ((*print-case* :downcase))
112
+                (alexandria:with-output-to-file (*standard-output* ofile)
113
+                  (loop for (ref book) being the hash-keys in *lookup-table* using (hash-value text)
114
+                        do (print `(ref ,book ,ref
115
+                                        ,text)))))
116
+              ;; (alexandria:with-input-from-file (s *fn* :external-format :iso-8859-1)
117
+              ;;   (setf *txt* (plump:parse s)))
118
+
119
+              ;; (uiop:directory-files "." (uiop:merge-pathnames* (make-pathname :type "bz2") uiop:*wild-file*))
120
+              ;; (car *)
121
+              ;; (plump:parse *)
122
+              ;; (lquery:initialize *)
123
+              ;; ($ "p[title]" (combine (attr :title)
124
+              ;;          (text)))
125
+
126
+              )))
127
+     (retry () (to-top))
128
+     (abort ()))))
129 129
 
130 130
 (defun make-executable ()
131 131
   (dump "transform-ct" transform-ct-main
... ...
@@ -8,7 +8,7 @@
8 8
     `(defun ,name ,args
9 9
        (flet (,@defs)
10 10
          ,@(loop for form in body until (and (consp form) (eql :where (car form)))
11
-                collect form)))))
11
+                 collect form)))))
12 12
 
13 13
 (defun make-zipfile-stream (fn)
14 14
   (open fn :element-type '(unsigned-byte 8)))