source: project/wiki/format-modular @ 6454

Last change on this file since 6454 was 6454, checked in by Kon Lovett, 13 years ago

Doc update.

File size: 13.9 KB
Line 
1[[tags:eggs]]
2[[toc:]]
3
4== Introduction
5
6Code to generate format functions. It is relatively flexible, supporting inheritance and allowing you to extend your formatters. It is accompanied by an implementation of Common Lisp's format function which is thread safe and extendible (meaning you could define new format characters).
7
8== Example
9
10=== format
11
12<enscript highlight=scheme>
13(use format-modular)
14(format #f "Found: [~D]: ~A~%" 12 "objects")
15</enscript>
16
17=== make-format-function
18
19<enscript highlight=scheme>
20(use format-modular)
21
22(define fprintf
23  (make-format-function #f #\%
24    `(((#\d ,(formatter-padded display))
25       (#\s ,(formatter-padded write))))))
26
27(fprintf #t "Found: [%d]: %s\n" 12 "objects")
28</enscript>
29
30== Known limitations
31
32Chicken doesn't have support for output port column position. Since a new state is created upon each invocation
33the format output column position has no "memory", thus {{~&}} is accurate only within a single invocation.
34
35== make-format-function
36
37 [procedure] (make-format-function CASE-SENSITIVE ESCAPE FORMATTERS)
38
39Create and return a procedure that can be used as a format function. The
40resulting procedure receives a port, a format string and optional arguments. It
41parses the format string according to the {{FORMATTERS}} parameter and outputs
42a result to the port specified. If, instead of a port, {{#t}} is specified, the
43results will be sent to the current output port. If, on the other hand, {{#f}}
44is passed, the procedure will store its output on a new string and return it.
45
46{{CASE-SENSITIVE}} is a boolean. Are the format directives and modifiers
47case-sensitive?
48
49The returned procedure parses the format string looking for occurrences of the
50{{ESCAPE}} character (usually {{#\~}}); when one is found, a function from the
51{{formatters}} argument is called.
52
53{{FORMATTERS}} is a list of formatters. Each formatter is itself a list of
54(char function) pairs, where char is the character for the escape sequence
55being defined and function the function to call when the character, preceeded
56by escape, is found in the format string.
57
58To produce the functions included in the formatters, use {{(formatter-function
59PROC)}}, where {{PROC}} is a procedure that receives the following parameters:
60
61; state : A structure with internal information. You won't normally inspect this directly but rather pass it to other functions that require it (such as {{*formatter-out-char}} and {{*formatter-out-string}}).
62; start : The position in the format string where the beginning of the escape sequence was found. You'll normally just ignore this.
63; params : A list with paramters that occur between {{escape}} and {{char}} (for example, in a format string such as {{~23,33,12A}}).
64; colon, atsign : Booleans indicating whether those characters occur between {{escape}} and {{char}}.
65
66To output info at the current position, the formatter functions should use the
67{{*formatter-out-char}} and {{*formatter-out-string}} functions. They receive
68the {{state}} parameter (as passed to the formatter function) and a character
69and string respectively.
70
71For convenience, you can also use {{(formatter-padded PROC)}} when you
72want to create a function to display an object in some representation.
73In this case, {{PROC}} should be a procedure receiving one argument,
74an object, and write the desired representation to the current output
75port.
76
77== format
78
79 [procedure] (format PORT FORMAT-STRING . ARGS)
80
81{{PORT}} is {{#f}} or a string for an output to a string, {{#t}} for output to
82the current output port, or a port.
83
84{{FORMAT-STRING}} is a string composed of {{DIRECTIVE}}s and/or characters.
85
86{{ARGS}} are the data for the {{FORMAT-STRING}} {{DIRECTIVE}}s.
87
88 DIRECTIVE ::= ~{DIRECTIVE-PARAMETER,}[:][@]DIRECTIVE-CHARACTER
89
90 DIRECTIVE-PARAMETER ::= [ [-|+]{0-9}+ | 'CHARACTER | v | # ]
91
92This implementation supports directive parameters and modifiers (`:'
93and `@' characters). Multiple parameters must be separated by a comma
94(`,'). Parameters can be numerical parameters (positive or negative),
95character parameters (prefixed by a quote character (`''), variable
96parameters (`v'), number of rest arguments parameter (`#'), empty and
97default parameters. Directive characters are case independent.
98
99=== Implemented CL Format Control Directives
100
101Documentation syntax: Uppercase characters represent the corresponding
102control directive characters. Lowercase characters represent control
103directive parameter descriptions.
104
105==== ~A
106
107;{{~A}}: Aesthetic (print as `display' does).
108
109;{{~@A}}:left pad.
110
111;{{~mincol,colinc,minpad,padcharA}}: full padding.
112
113==== ~S
114
115;{{~S}}: S-expression (print as `write' does).
116
117;{{~@S}}: left pad.
118
119;{{~mincol,colinc,minpad,padcharS}}: full padding.
120
121==== ~D
122
123;{{~D}}: Decimal.
124
125;{{~@D}}: print number sign always.
126
127;{{~:D}}: print comma separated.
128
129;{{~mincol,padchar,commachar,commawidthD}}: padding.
130
131==== ~X
132
133;{{~X}}: Hexadecimal.
134
135;{{~@X}}: print number sign always.
136
137;{{~:X}}: print comma separated.
138
139;{{~mincol,padchar,commachar,commawidthX}}: padding.
140
141==== ~O
142
143;{{~O}}: Octal.
144
145;{{~@O}}: print number sign always.
146
147;{{~:O}}: print comma separated.
148
149;{{~mincol,padchar,commachar,commawidthO}}: padding.
150
151==== ~B
152
153;{{~B}}: Binary.
154
155;{{~@B}}: print number sign always.
156
157;{{~:B}}: print comma separated.
158
159;{{~mincol,padchar,commachar,commawidthB}}: padding.
160
161==== ~R
162
163;{{~nR}}: Radix N.
164
165;{{~n,mincol,padchar,commachar,commawidthR}}: padding.
166
167;{{~@R}}: print a number as a Roman numeral.
168
169;{{~:@R}}: print a number as an "old fashioned" Roman numeral.
170
171;{{~:R}}: print a number as an ordinal English number.
172
173;{{~R}}: print a number as a cardinal English number.
174
175==== ~P
176
177;{{~P}}: Plural.
178
179;{{~@P}}: prints `y' and `ies'.
180
181;{{~:P}}: as {{~P}} but jumps 1 argument backward.
182
183;{{~:@P}}: as {{~@P}} but jumps 1 argument backward.
184
185==== ~C
186
187;{{~C}}: Character.
188
189;{{~@C}}: prints a character as the reader can understand it (i.e. {{#\}} prefixing).
190
191;{{~:C}}: prints a character as emacs does (eg. `^C' for ASCII 03).
192
193==== ~F
194
195;{{~F}}: Fixed-format floating-point (prints a flonum like MMM.NNN).
196
197;{{~width,digits,scale,overflowchar,padcharF}}: padding.
198
199;{{~@F}}: If the number is positive a plus sign is printed.
200
201==== ~E
202
203;{{~E}}: Exponential floating-point (prints a flonum like MMM.NNN''E''EE).
204
205;{{~width,digits,exponentdigits,scale,overflowchar,padchar,exponentcharE}}: padding
206
207;{{~@E}}: If the number is positive a plus sign is printed.
208
209==== ~G
210
211;{{~G}}: General floating-point (prints a flonum either fixed or exponential).
212
213;{{~width,digits,exponentdigits,scale,overflowchar,padchar,exponentcharG}}: padding.
214
215;{{~@G}}: If the number is positive a plus sign is printed.
216
217==== ~$
218
219;{{~$}}: Dollars floating-point (prints a flonum in fixed with signs separated).
220
221;{{~digits,scale,width,padchar$}}: padding
222
223;{{~@$}}: If the number is positive a plus sign is printed.
224
225;{{~:@$}}: A sign is always printed and appears before the padding.
226
227;{{~:$}}: The sign appears before the padding.
228
229==== ~%
230
231;{{~%}}: Newline.
232
233;{{~n%}}: print ''N'' newlines.
234
235==== ~&
236
237;{{~&}}: print newline if not at the beginning of the output line.
238
239;{{~n&}}: prints `~&' and then N-1 newlines.
240
241==== ~|
242
243;{{~|}}: Page Separator.
244
245;{{~n|}}: print N page separators.
246
247==== ~~
248
249;{{~~}}: Tilde.
250
251;{{~n~}}: print N tildes.
252
253==== ~T
254
255;{{~T}}: Tabulation.
256
257;{{~@T}}: relative tabulation.
258
259;{{~colnum,colincT}}: full tabulation.
260
261==== ~?
262
263;{{~?}}: Indirection (expects indirect arguments as a list).
264
265;{{~@?}}: extracts indirect arguments from format arguments.
266
267==== ~( ... ~)
268
269;{{~(str~)}}: Case conversion (converts by `string-downcase').
270
271;{{~:(str~)}}: converts by `string-capitalize'.
272
273;{{~@(str~)}}: converts by `string-capitalize-first'.
274
275;{{~:@(str~)}}: converts by `string-upcase'.
276
277==== ~*
278
279;{{~*}}: Argument Jumping (jumps 1 argument forward).
280
281;{{~n*}}: jumps N arguments forward.
282
283;{{~:*}}: jumps 1 argument backward.
284
285;{{~n:*}}: jumps N arguments backward.
286
287;{{~@*}}: jumps to the 0th argument.
288
289;{{~n@*}}: jumps to the Nth argument (beginning from 0)
290
291==== ~[ ... ~]
292
293;{{~[str0~;str1~;...~;strn~]}}: Conditional Expression (numerical clause conditional).
294
295;{{~n[}}: take argument from N.
296
297;{{~@[}}: true test conditional.
298
299;{{~:[}}: if-else-then conditional.
300
301;{{~;}}: clause separator.
302
303;{{~:;}}: default clause follows.
304
305==== ~{ ... ~}
306
307;{{~{STR~}}}: Iteration (args come from the next argument (a list)). Iteration bounding is controlled by configuration variables {{format:iteration-bounded}} and {{format:max-iterations}}. With both variables default, a maximum of 100 iterations will be performed.
308
309;{{~n{}}: at most N iterations.
310
311;{{~:{}}: args from next arg (a list of lists).
312
313;{{~@{}}: args from the rest of arguments.
314
315;{{~:@{}}: args from the rest args (lists).
316
317==== ~^
318
319;{{~^}}: Up and out.
320
321;{{~n^}}: aborts if N = 0
322
323;{{~n,m^}}: aborts if N = M
324
325;{{~n,m,k^}}: aborts if N <= M <= K
326
327==== ~'<newline>
328
329;{{~'<newline>}}: Continuation Line.
330
331;{{~:'<newline>}}: newline is ignored, whitespace left.
332
333;{{~@'<newline>}}: newline is left, whitespace ignored.
334
335=== Extended, Replaced and Additional Control Directives
336
337;{{~...V...}}: Option maybe the character #\V, where the option value is from the argument list.
338
339;{{~colnum,colinc,tabcharT}}: TABCHAR may be specified.
340
341;{{~I}}: print a R4RS complex number as `~F~@Fi' with passed parameters for `~F'.
342
343;{{~Y}}: Pretty print formatting of an argument for scheme code lists.
344
345;{{~K}}: Same as `~?.'
346
347;{{~!}}: Flushes the output if format DESTINATION is a port.
348
349;{{~_}}: Print a `#\space' character
350
351;{{~n_}}: print N `#\space' characters.
352
353;{{~/}}: Print a `#\tab' character
354
355;{{~n/}}: print N `#\tab' characters.
356
357;{{~Q}}: Prints information and a copyright notice on the format implementation.
358
359;{{~:Q}}: prints format version.
360
361=== Not Implemented (Both Common LISP & SLIB)
362
363;{{~<~>}}: Justification.
364
365;{{~:^}}: Terminate the iteration process iff the command it would terminate is ~:{ or ~:@{.
366
367;{{~W}}: Pretty-print, with support for depth abbreviation, circularity, and sharing.
368
369;{{~:S}}: Print out readproof. Prints out internal objects represented as {{#<...>}} as strings {{"#<...>"}} so that the format output can always be processed by `read'.
370
371;{{~:A}}: Print out readproof. Prints out internal objects represented as `#<...>' as strings `"#<...>"' so that the format output can always be processed by `read'.
372
373;{{~... parameter-char ...}}: PARAMETER-CHAR maybe an integer representation for a character.
374
375;{{~C}}: Argument maybe an integer representation for a character.
376
377;{{~nC}}: Takes N as an integer representation for a character. No arguments are consumed. N is converted to a character by `integer->char'. N must be a positive decimal number.
378
379;{{~F, ~E, ~G, ~$, ~I}}: May also print number strings, i.e. passing a number as a string and format it accordingly.
380
381=== Configuration Variables
382
383Format has some configuration variables. There should be no modification
384necessary for the default configuration. If modification is
385desired the variable should be set after the format code is loaded.
386
387==== Implemented
388
389The following variables are supported by this {{format}} implementation:
390
391;{{format:floats}} (default {{#t}}): System has floating-point numbers.
392
393;{{format:complex-numbers}} (default {{#f}}): System has complex numbers.
394
395;{{format:expch}} (default {{#\E}}): The character prefixing the exponent value in ~E printing.
396
397;{{format:iteration-bounded}} (default {{#t}}): When {{#t}}, a {{~{...~} }} control will iterate no more than the number of times specified by {{format:max-iterations}} regardless of the number of iterations implied by modifiers and arguments. When {{#f}}, a {{ ~{...~} }} control will iterate the number of times implied by modifiers and arguments, unless termination is forced by language or system limitations.
398
399;{{format:max-iterations}} (default 100): The maximum number of iterations performed by a {{~{...~} }} control.  Has effect only when {{format:iteration-bounded}} is {{#t}}.
400
401==== Not Implemented
402
403The following variables are still not supported by this {{format}} implementation:
404
405;{{format:fn-max}} (default 200): Maximum number of number digits.
406
407;{{format:en-max}} (default 10): Maximum number of exponent digits.
408
409;{{format:radix-pref}}: Does number->string add a radix prefix?
410
411;{{format:symbol-case-conv}} (default #f): Symbols are converted by symbol->string so the case type of the printed symbols is implementation dependent.  format:symbol-case-conv is a one arg closure which is either #f (no conversion), string-upcase, string-downcase or string-capitalize.
412
413;{{format:iobj-case-conv}} (default #f): As format:symbol-case-conv but applies for the representation of implementation internal objects.
414
415;{{format:unprocessed-arguments-error?}} (default #f): Are superfluous arguments treated as an error.
416
417== Pre-defined Formatters
418
419Many predefined formatters that are used for the implementation of
420{{format}} are exported and can be reused to make new format functions:
421
422;{{*formatter-params*}}: Parameter escapes.
423;{{*formatter-iteration*}}: Iteration escapes.
424;{{*formatter-caseconv*}}: Case-conversion escapes.
425;{{*formatter-chars*}}: Character escapes.
426;{{*formatter-numbers*}}: Number escapes.
427;{{*formatter-cond*}}: Conditional escapes.
428;{{*formatter-indirection*}}: Indirection escapes.
429;{{*formatter-jump*}}: Jump escapes.
430;{{*formatter-objs*}}: Object escapes.
431;{{*formatter-flush*}}: Flush escapes.
432;{{*formatter-plural*}}: Plural escapes.
433;{{*formatter-tabulate*}}: Tabulate escapes.
434;{{*formatter-cl*}}: All of the above.
435
436== History
437
438; 1.7 : Restore optimization (build the vector of formatter characters when the formatter is built, not whenever it is called). Export {{formatter-padded}}. Use doc-from-wiki.
439
440; 1.6 : Added KY$I&\\n escapes, V parameter, commawidth, tabchar, localization, bugfixes [Kon Lovett]
441
442; 1.5 : Added support for static linking
443
444; 1.4 : Bug fix for numbers egg use & float/expon format, made port optional [Kon Lovett]
445
446; 1.3 : Minor doc fixes, rename out-* to *formatter-out-*, works with utf8, uses vectors & fixnum arithmetic where possible [Kon Lovett]
447
448; 1.2 : bugfix in formatter-jump
449
450; 1.1 : Small bug fixes, more annotations to the source code
451
452; 1.0 : First public release
453
Note: See TracBrowser for help on using the repository browser.