source: project/wiki/format-modular @ 9260

Last change on this file since 9260 was 9260, checked in by Kon Lovett, 12 years ago

Updated doc to add entries for all exported procedures.

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