Browse code
Restructure to add conditional format chars
fiddlerwoaroof authored on 05/12/2016 23:44:07
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -1,7 +1,5 @@ |
1 | 1 |
(in-package #:format-string-builder) |
2 | 2 |
|
3 |
-(defvar *format-command-stream*) |
|
4 |
- |
|
5 | 3 |
(defclass format-string-command () |
6 | 4 |
((at-p :initarg :at-p :accessor at-p :initform nil) |
7 | 5 |
(colon-p :initarg :colon-p :accessor colon-p :initform nil))) |
... | ... |
@@ -16,6 +14,9 @@ |
16 | 14 |
(end-char :initarg :end-char :accessor end-char) |
17 | 15 |
(modifiers :initarg :modifiers :accessor modifiers :initform nil))) |
18 | 16 |
|
17 |
+(defclass sectioned-format-string-command (compound-format-string-command) |
|
18 |
+ ()) |
|
19 |
+ |
|
19 | 20 |
(defmethod print-object ((obj compound-format-string-command) s) |
20 | 21 |
(declare (optimize (debug 3))) |
21 | 22 |
(print-unreadable-object (obj s :type t :identity t) |
... | ... |
@@ -47,29 +48,30 @@ |
47 | 48 |
|
48 | 49 |
(defmethod print-format-representation :around ((command format-string-command) s) |
49 | 50 |
(princ #\~ s) |
50 |
- (call-next-method)) |
|
51 |
- |
|
52 |
-(defmethod print-format-representation :before ((command format-string-command) s) |
|
51 |
+ (print-format-modifiers command s) |
|
53 | 52 |
(when (colon-p command) |
54 | 53 |
(princ #\: s)) |
55 | 54 |
(when (at-p command) |
56 |
- (princ #\@ s))) |
|
57 |
- |
|
58 |
-(defmethod print-format-representation :before ((command simple-format-string-command) s) |
|
59 |
- (print-format-modifiers command s)) |
|
55 |
+ (princ #\@ s)) |
|
56 |
+ (call-next-method)) |
|
60 | 57 |
|
61 | 58 |
(defmethod print-format-representation ((command simple-format-string-command) s) |
62 | 59 |
(princ (format-char command) s)) |
63 | 60 |
|
64 | 61 |
(defmethod print-format-representation :before ((command compound-format-string-command) s) |
65 |
- (print-format-modifiers command s)) |
|
62 |
+ (princ (start-char command) s)) |
|
66 | 63 |
|
67 | 64 |
(defmethod print-format-representation ((command compound-format-string-command) s) |
68 |
- (princ (start-char command) s) |
|
69 |
- (print-format-representation (contents command) s) |
|
65 |
+ (print-format-representation (contents command) s)) |
|
66 |
+ |
|
67 |
+(defmethod print-format-representation :after ((command compound-format-string-command) s) |
|
70 | 68 |
(princ #\~ s) |
71 | 69 |
(princ (end-char command) s)) |
72 | 70 |
|
71 |
+(defmethod print-format-representation ((command sectioned-format-string-command) s) |
|
72 |
+ (mapcar (op (princ _ s)) |
|
73 |
+ (intersperse "~;" (contents command)))) |
|
74 |
+ |
|
73 | 75 |
;;; TODO: should this be a generic function? |
74 | 76 |
(defun convert-modifier (modifier) |
75 | 77 |
(flet ((validate-modifier (modifier) |
... | ... |
@@ -134,10 +136,18 @@ |
134 | 136 |
:at-p ,at-p |
135 | 137 |
:colon-p ,colon-p))) |
136 | 138 |
|
139 |
+(defun define-sectioned-format-char (name start-char end-char &key at-p colon-p) |
|
140 |
+ (setf (gethash (intern (string name) :keyword) |
|
141 |
+ *format-string-registry*) |
|
142 |
+ `(sectioned-format-string-command :start-char ,start-char |
|
143 |
+ :end-char ,end-char |
|
144 |
+ :at-p ,at-p |
|
145 |
+ :colon-p ,colon-p))) |
|
146 |
+ |
|
137 | 147 |
(defmacro define-compound-format-chars (&body specs) |
138 | 148 |
`(progn |
139 | 149 |
,@(loop for spec in specs |
140 |
- collect `(define-compound-format-char ,@spec)))) |
|
150 |
+ collect `(define-compound-format-char ,@spec)))) |
|
141 | 151 |
|
142 | 152 |
(defmacro define-simple-format-chars (&body specs) |
143 | 153 |
`(progn |
... | ... |
@@ -160,20 +170,26 @@ |
160 | 170 |
(list* 'progn |
161 | 171 |
(mapcar (lambda (spec) |
162 | 172 |
`(:compound ,@spec)) |
163 |
- specs)))) |
|
173 |
+ specs))) |
|
174 |
+ (:sectioned (name (start-char end-char) &key at-p colon-p) |
|
175 |
+ `(define-sectioned-format-char ,name ,start-char ,end-char |
|
176 |
+ :at-p ,at-p :colon-p ,colon-p))) |
|
164 | 177 |
,@body)) |
165 | 178 |
|
166 |
-(defmacro &format (stream format-spec &rest args) |
|
179 |
+(defmacro format* (stream format-spec &rest args) |
|
167 | 180 |
`(format ,stream |
168 |
- (make-format-string ',format-spec) |
|
181 |
+ ,(make-format-string format-spec) |
|
169 | 182 |
,@args)) |
170 | 183 |
|
171 |
-(defmacro define-message (name (&rest args) &body spec) |
|
172 |
- (with-gensyms (fs stream the-rest) |
|
173 |
- `(eval-when (:load-toplevel :compile-toplevel :execute) |
|
174 |
- (let ((,fs (make-format-string ',spec))) |
|
175 |
- (defun ,name (,stream ,@args &rest ,the-rest) |
|
176 |
- (apply #'format (list* ,stream ,fs ,@args ,the-rest))))))) |
|
184 |
+(defmacro define-message (name (stream-arg &rest args) &body spec) |
|
185 |
+ (flet ((get-argument-names (arg-list) |
|
186 |
+ (loop for s in arg-list |
|
187 |
+ when (and (symbolp s) (not (char= (elt (symbol-name s) 0) #\&))) collect s |
|
188 |
+ when (consp s) collect (car s)))) |
|
189 |
+ (with-gensyms (fs the-rest) |
|
190 |
+ `(let ((,fs ,(make-format-string spec))) |
|
191 |
+ (defun ,name (,stream-arg ,@args &rest ,the-rest) |
|
192 |
+ (apply #'format ,stream-arg ,fs ,@(get-argument-names args) ,the-rest)))))) |
|
177 | 193 |
|
178 | 194 |
(define-format-chars |
179 | 195 |
|
... | ... |
@@ -201,6 +217,9 @@ |
201 | 217 |
(:cjust (#\< #\>) :at-p t :colon-p t) |
202 | 218 |
(:center (#\< #\>) :at-p t :colon-p t)) |
203 | 219 |
|
220 |
+ ;; Conditional output |
|
221 |
+ (:sectioned :y-or-n (#\[ #\]) :colon-p t) |
|
222 |
+ |
|
204 | 223 |
;; Case printing characters. |
205 | 224 |
(:compounds |
206 | 225 |
(:lowercase (#\( #\))) |
... | ... |
@@ -223,12 +242,13 @@ |
223 | 242 |
(:exit (#\^)) |
224 | 243 |
(:go-to (#\*)) |
225 | 244 |
(:end-section (#\;)) |
245 |
+ (:fresh-line (#\&)) |
|
226 | 246 |
(:ensure-line (#\&)) |
227 | 247 |
(:new-line (#\%)))) |
228 | 248 |
|
229 |
-(define-message hello (name) |
|
249 |
+(define-message hello (stream name) |
|
230 | 250 |
(:titlecase () "hello" #\space :str)) |
231 | 251 |
|
232 |
-(define-message print-comma-separated () |
|
252 |
+(define-message print-comma-separated (stream) |
|
233 | 253 |
(:own-line () |
234 | 254 |
(:rest () :str :exit ", "))) |