Browse code
Misc updates
Ed Langley authored on 07/04/2019 23:00:19
Showing 7 changed files
Showing 7 changed files
- blog.lisp
- decision-table.lisp
- gallery.lisp
- generic-fun-special-decl.lisp
- raft.lisp
- transform-ct.lisp
- zipfile.lisp
... | ... |
@@ -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 "~¶ms: ~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 "~¶ms: ~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 |