git.fiddlerwoaroof.com
Browse code

Document and add aliases

fiddlerwoaroof authored on 06/12/2016 00:43:47
Showing 2 changed files
... ...
@@ -1,5 +1,11 @@
1 1
 A simple package implementing a DSL for generating format strings.
2 2
 
3
+- [Introduction](#introduction)
4
+- [Api Reference](#api-reference)
5
+- [DSL Reference](#dsl-reference)
6
+
7
+# Introduction
8
+
3 9
 ```lisp
4 10
 
5 11
 (make-format-string '(:str)) #| ==> "~a" |#
... ...
@@ -11,3 +17,113 @@ A simple package implementing a DSL for generating format strings.
11 17
   (:map () :str))
12 18
 
13 19
 ```
20
+
21
+# Api Reference
22
+
23
+```lisp
24
+(make-format-string spec) #| function |#
25
+```
26
+
27
+Takes a format string specification and turns it into a string.
28
+
29
+```lisp
30
+(format* stream spec &rest args) #| macro |#
31
+```
32
+
33
+Use like CL:FORMAT, except translate a format specification to a string at macroexpansion time.
34
+
35
+```lisp
36
+(define-message (stream-symbol &rest format-args) &body spec) #| macro |#
37
+```
38
+
39
+Defines a function that takes a stream and the arguments to be
40
+formatted and then formats the arguments to the stream. The spec is
41
+compiled to a string at macroexpansion time, so this should be
42
+reasonably efficient.
43
+
44
+TODO: document the API for defining directives.
45
+
46
+# DSL Reference
47
+
48
+A spec consists of operators and literals.  Literals are either
49
+strings, characters or integers and they are formatted as-is via
50
+princ. There are two kinds of operators: simple operators and compound
51
+ones. Simple operators correspond to format control directives and
52
+represented in the spec by keywords  such as `~A` or by lists
53
+`(keyword . modifiers)` and they expand to the corresponding
54
+directives. Compound operators correspond to format directives that
55
+can contain other directives such as `~{~}`.  In a spec, these are
56
+formatted like flet function definitions:
57
+
58
+```lisp
59
+(keyword (&rest modifiers) &body spec)
60
+```
61
+
62
+Compound operators are further divided into sectioned operators and
63
+non-sectioned ones.  The difference is that, in non sectioned
64
+operators, the body is treated just as a normal spec. In sectioned
65
+ones, the body is treated as a list of items to be divided with `~;`.
66
+See CLHS 22.3 for a full guide to the modifiers for the various format
67
+directives.
68
+
69
+## Simple Format Operations
70
+
71
+- :str --- Translates to ~a, format a lisp value for humans
72
+- :repr --- Translates to ~s, format a lisp value in a way that can be read by the reader (?)
73
+- :float --- Translates to ~f, format a float.
74
+- :dec --- Translates to ~d, format a number as a base 10 number.
75
+- :decimal --- Translates to ~d, format a number as a base 10 number.
76
+- :hex --- Translates to ~x, format a number as a base 16 number.
77
+- :hexadecimal --- Translates to ~x, format a number as a base 16 number.
78
+- :oct --- Translates to ~o, format a number as a base 8 number.
79
+- :octal --- Translates to ~o, format a number as a base 8 number.
80
+- :currency --- Translates to ~$, format a number in a manner suitable for currency
81
+- :exit --- Translates to ~^, leaves a iteration construct
82
+- :end-section --- Translates to ~;, divides sections of a construct (TODO: maybe this will go away?)
83
+- :goto --- Translates to ~*, moves within the list of arguments
84
+- :fresh-line --- Translates to ~&, ensures we're at the beginning of a line and, possibly adds Modifier-1 linebreaks
85
+- :ensure-line --- Translates to ~7, alias for :fresh-line
86
+- :new-line --- Adds a linebreak
87
+
88
+## Compound Format Operations
89
+
90
+### Iteration
91
+
92
+- :map --- Translates to ~{~}, iterate over a list passed in
93
+- :rest ---  Translates to ~@{~}, iterate over the rest of the arguments
94
+- :ap --- Translates to ~:{~}, apply a list to the corresponding enclosed format directives
95
+- :apply --- Alias for :ap
96
+- :aprest --- Translates to ~:@{~}, apply the rest of the arguments to the corresponding enclosed format directives
97
+- :apply-rest --- Translates to ~:@{~}, apply the rest of the arguments to the corresponding enclosed format directives
98
+
99
+### Conditional Output (Sectioned Operators)
100
+
101
+- :y-or-n --- Translates to ~:[~], if the argument is nil, print first spec otherwise print second
102
+- TODO: add others here...
103
+
104
+### Case Control
105
+
106
+- :lowercase --- Translates to ~(~), lowercase all alphabetic characters.
107
+- :downcase --- Translates to ~(~), alias for :lowercase
108
+- :uppercase --- Translates to ~:@(~), uppercase all alphabetic characters.
109
+- :upcase --- Translates to ~:@(~), alias for :uppercase
110
+- :titlecase --- Translates to ~:(~), titlecase all alphabetic characters.
111
+- :capitalize --- Translates to ~:(~), alias for :titlecase
112
+- :initialcap --- Translates to ~@(~), uppercase first character
113
+
114
+### Justification
115
+TODO: finish documenting this and switch them to sectioned operators.
116
+
117
+- :spread --- Translates to ~<~>
118
+- :ljust --- Translates to ~@<~>
119
+- :left --- Translates to ~@<~>
120
+- :rjust --- Translates to ~:<~>
121
+- :right --- Translates to ~:<~>
122
+- :cjust --- Translates to ~:@<~>
123
+- :center --- Translates to ~:@<~>
124
+
125
+### Miscellaneous
126
+
127
+These are not part of Format, but are defined just to be helpful
128
+
129
+- :own-line --- Translates to ~&~%, ensure that the included text is on its own line, without unnecessary gaps.
... ...
@@ -43,6 +43,9 @@
43 43
 (defmethod print-format-representation ((literal character) s)
44 44
   (princ literal s))
45 45
 
46
+(defmethod print-format-representation ((literal integer) s)
47
+  (princ literal s))
48
+
46 49
 (defmethod print-format-representation ((literal string) s)
47 50
   (princ literal s))
48 51
 
... ...
@@ -182,6 +185,9 @@
182 185
            ,@args))
183 186
 
184 187
 (defmacro define-message (name (stream-arg &rest args) &body spec)
188
+  "Define a function called NAME that takes a stream argument and a
189
+variable argument list that formats the arguments according to the
190
+spec passed as the body."
185 191
   (flet ((get-argument-names (arg-list)
186 192
            (loop for s in arg-list
187 193
                  when (and (symbolp s) (not (char= (elt (symbol-name s) 0) #\&))) collect s
... ...
@@ -223,8 +229,11 @@
223 229
   ;; Case printing characters.
224 230
   (:compounds
225 231
     (:lowercase (#\( #\)))
232
+    (:downcase (#\( #\)))
226 233
     (:uppercase (#\( #\)) :at-p t :colon-p t)
234
+    (:upcase (#\( #\)) :at-p t :colon-p t)
227 235
     (:titlecase (#\( #\)) :colon-p t)
236
+    (:capitalize (#\( #\)) :colon-p t)
228 237
     (:initialcap (#\( #\)) :at-p t))
229 238
 
230 239
   (:compounds
... ...
@@ -237,7 +246,9 @@
237 246
     (:dec (#\d))
238 247
     (:decimal (#\d))
239 248
     (:hex (#\x))
249
+    (:hexadecimal (#\d))
240 250
     (:oct (#\o))
251
+    (:octal (#\o))
241 252
     (:currency (#\$))
242 253
     (:exit (#\^))
243 254
     (:go-to (#\*))