Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 3, the unsupported old release. You're almost certainly looking for [[/eggref/4/format-modular|the CHICKEN 4 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-4.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags:eggs]] [[toc:]] == format-modular === Introduction Code 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). === make-format-function [procedure] (make-format-function CASE-SENSITIVE ESCAPE FORMATTERS) Create and return a procedure that can be used as a format function. The resulting procedure receives a port, a format string and optional arguments. It parses the format string according to the {{FORMATTERS}} parameter and outputs a result to the port specified. If, instead of a port, {{#t}} is specified, the results will be sent to the current output port. If, on the other hand, {{#f}} is passed, the procedure will store its output on a new string and return it. {{CASE-SENSITIVE}} is a boolean. Are the format directives and modifiers case-sensitive? The returned procedure parses the format string looking for occurrences of the {{ESCAPE}} character (usually {{#\~}}); when one is found, a function from the {{formatters}} argument is called. {{FORMATTERS}} is a list of formatters. Each formatter is itself a list of (char function) pairs, where char is the character for the escape sequence being defined and function the function to call when the character, preceeded by escape, is found in the format string. To produce the functions included in the formatters, use the {{formatter-function}} procedure. To output info at the current position, the formatter functions should use the {{*formatter-out-foo}} procedures. To access an argument use the {{*formatter-next-argument}} procedure. For convenience, you can also use {{formatter-padded}} procedure when you want to create a function to display an object with padding. === formatter-function [procedure] (formatter-function PROC) {{PROC}} is a procedure that receives the following parameters: ; 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). ; start : The position in the format string where the beginning of the escape sequence was found. You'll normally just ignore this. ; params : A list with paramters that occur between {{escape}} and {{char}} (for example, in a format string such as {{~23,33,12A}}). ; colon, atsign : Booleans indicating whether those characters occur between {{escape}} and {{char}}. === formatter-padded [procedure] (formatter-padded SHOW-FUNC) {{SHOW-FUNC}} is a one-argument function, the object, which should write (to the current-output-port) a representation of the object. The object representation is padded according to the padding parameters - {{mincol,colinc,minpad,padchar}}. === *formatter-out-char [procedure] (*formatter-out-char STATE CHAR) Output the {{CHAR}}. {{STATE}} is the internal formatter state object as passed to a {{formatter-function}}. === *formatter-out-char-times [procedure] (*formatter-out-char-times STATE TIMES CHAR) Output the {{CHAR}} N {{TIMES}}. {{STATE}} is the internal formatter state object as passed to a {{formatter-function}}. === *formatter-out-char-list [procedure] (*formatter-out-char-list STATE LIST-OF-CHAR) Output the {{LIST-OF-CHAR}}. {{STATE}} is the internal formatter state object as passed to a {{formatter-function}}. === *formatter-out-string [procedure] (*formatter-out-string STATE STRING) Output the {{STRING}}. {{STATE}} is the internal formatter state object as passed to a {{formatter-function}}. === *formatter-next-argument [procedure] (*formatter-next-argument STATE [INCREMENT]) Consumes and returns the next argument. When {{INCREMENT}} is supplied it is the number of arguments to consume, the default is {{1}}. {{STATE}} is the internal formatter state object as passed to a {{formatter-function}}. === format [procedure] (format PORT FORMAT-STRING . ARGS) {{PORT}} is {{#f}} or a string for an output to a string, {{#t}} for output to the current output port, or a port. {{FORMAT-STRING}} is a string composed of {{DIRECTIVE}}s and/or characters. {{ARGS}} are the data for the {{FORMAT-STRING}} {{DIRECTIVE}}s. DIRECTIVE ::= ~{DIRECTIVE-PARAMETER,}[:][@]DIRECTIVE-CHARACTER DIRECTIVE-PARAMETER ::= [ [-|+]{0-9}+ | 'CHARACTER | v | # ] This implementation supports directive parameters and modifiers (`:' and `@' characters). Multiple parameters must be separated by a comma (`,'). Parameters can be numerical parameters (positive or negative), character parameters (prefixed by a quote character (`''), variable parameters (`v'), number of rest arguments parameter (`#'), empty and default parameters. Directive characters are case independent. ==== Implemented CL Format Control Directives Documentation syntax: Uppercase characters represent the corresponding control directive characters. Lowercase characters represent control directive parameter descriptions. ===== ~A ;{{~A}}: Aesthetic (print as `display' does). ;{{~@A}}:left pad. ;{{~mincol,colinc,minpad,padcharA}}: full padding. ===== ~S ;{{~S}}: S-expression (print as `write' does). ;{{~@S}}: left pad. ;{{~mincol,colinc,minpad,padcharS}}: full padding. ===== ~D ;{{~D}}: Decimal. ;{{~@D}}: print number sign always. ;{{~:D}}: print comma separated. ;{{~mincol,padchar,commachar,commawidthD}}: padding. ===== ~X ;{{~X}}: Hexadecimal. ;{{~@X}}: print number sign always. ;{{~:X}}: print comma separated. ;{{~mincol,padchar,commachar,commawidthX}}: padding. ===== ~O ;{{~O}}: Octal. ;{{~@O}}: print number sign always. ;{{~:O}}: print comma separated. ;{{~mincol,padchar,commachar,commawidthO}}: padding. ===== ~B ;{{~B}}: Binary. ;{{~@B}}: print number sign always. ;{{~:B}}: print comma separated. ;{{~mincol,padchar,commachar,commawidthB}}: padding. ===== ~R ;{{~nR}}: Radix N. ;{{~n,mincol,padchar,commachar,commawidthR}}: padding. ;{{~@R}}: print a number as a Roman numeral. ;{{~:@R}}: print a number as an "old fashioned" Roman numeral. ;{{~:R}}: print a number as an ordinal English number. ;{{~R}}: print a number as a cardinal English number. ===== ~P ;{{~P}}: Plural. ;{{~@P}}: prints `y' and `ies'. ;{{~:P}}: as {{~P}} but jumps 1 argument backward. ;{{~:@P}}: as {{~@P}} but jumps 1 argument backward. ===== ~C ;{{~C}}: Character. ;{{~@C}}: prints a character as the reader can understand it (i.e. {{#\}} prefixing). ;{{~:C}}: prints a character as emacs does (eg. `^C' for ASCII 03). ===== ~F ;{{~F}}: Fixed-format floating-point (prints a flonum like MMM.NNN). ;{{~width,digits,scale,overflowchar,padcharF}}: padding. ;{{~@F}}: If the number is positive a plus sign is printed. ===== ~E ;{{~E}}: Exponential floating-point (prints a flonum like MMM.NNN''E''EE). ;{{~width,digits,exponentdigits,scale,overflowchar,padchar,exponentcharE}}: padding ;{{~@E}}: If the number is positive a plus sign is printed. ===== ~G ;{{~G}}: General floating-point (prints a flonum either fixed or exponential). ;{{~width,digits,exponentdigits,scale,overflowchar,padchar,exponentcharG}}: padding. ;{{~@G}}: If the number is positive a plus sign is printed. ===== ~$ ;{{~$}}: Dollars floating-point (prints a flonum in fixed with signs separated). ;{{~digits,scale,width,padchar$}}: padding ;{{~@$}}: If the number is positive a plus sign is printed. ;{{~:@$}}: A sign is always printed and appears before the padding. ;{{~:$}}: The sign appears before the padding. ===== ~% ;{{~%}}: Newline. ;{{~n%}}: print ''N'' newlines. ===== ~& ;{{~&}}: print newline if not at the beginning of the output line. ;{{~n&}}: prints `~&' and then N-1 newlines. ===== ~| ;{{~|}}: Page Separator. ;{{~n|}}: print N page separators. ===== ~~ ;{{~~}}: Tilde. ;{{~n~}}: print N tildes. ===== ~T ;{{~T}}: Tabulation. ;{{~@T}}: relative tabulation. ;{{~colnum,colincT}}: full tabulation. ===== ~? ;{{~?}}: Indirection (expects indirect arguments as a list). ;{{~@?}}: extracts indirect arguments from format arguments. ===== ~( ... ~) ;{{~(str~)}}: Case conversion (converts by `string-downcase'). ;{{~:(str~)}}: converts by `string-capitalize'. ;{{~@(str~)}}: converts by `string-capitalize-first'. ;{{~:@(str~)}}: converts by `string-upcase'. ===== ~* ;{{~*}}: Argument Jumping (jumps 1 argument forward). ;{{~n*}}: jumps N arguments forward. ;{{~:*}}: jumps 1 argument backward. ;{{~n:*}}: jumps N arguments backward. ;{{~@*}}: jumps to the 0th argument. ;{{~n@*}}: jumps to the Nth argument (beginning from 0) ===== ~[ ... ~] ;{{~[str0~;str1~;...~;strn~]}}: Conditional Expression (numerical clause conditional). ;{{~n[}}: take argument from N. ;{{~@[}}: true test conditional. ;{{~:[}}: if-else-then conditional. ;{{~;}}: clause separator. ;{{~:;}}: default clause follows. ===== ~{ ... ~} ;{{~{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. ;{{~n{}}: at most N iterations. ;{{~:{}}: args from next arg (a list of lists). ;{{~@{}}: args from the rest of arguments. ;{{~:@{}}: args from the rest args (lists). ===== ~^ ;{{~^}}: Up and out. ;{{~n^}}: aborts if N = 0 ;{{~n,m^}}: aborts if N = M ;{{~n,m,k^}}: aborts if N <= M <= K ===== ~'<newline> ;{{~'<newline>}}: Continuation Line. ;{{~:'<newline>}}: newline is ignored, whitespace left. ;{{~@'<newline>}}: newline is left, whitespace ignored. ==== Extended, Replaced and Additional Control Directives ;{{~...V...}}: Option maybe the character #\V, where the option value is from the argument list. ;{{~colnum,colinc,tabcharT}}: TABCHAR may be specified. ;{{~I}}: print a R4RS complex number as `~F~@Fi' with passed parameters for `~F'. ;{{~Y}}: Pretty print formatting of an argument for scheme code lists. ;{{~K}}: Same as `~?.' ;{{~!}}: Flushes the output if format DESTINATION is a port. ;{{~_}}: Print a `#\space' character ;{{~n_}}: print N `#\space' characters. ;{{~/}}: Print a `#\tab' character ;{{~n/}}: print N `#\tab' characters. ;{{~Q}}: Prints information and a copyright notice on the format implementation. ;{{~:Q}}: prints format version. ==== Not Implemented (Both Common LISP & SLIB) ;{{~<~>}}: Justification. ;{{~:^}}: Terminate the iteration process iff the command it would terminate is ~:{ or ~:@{. ;{{~W}}: Pretty-print, with support for depth abbreviation, circularity, and sharing. ;{{~:S}}: Print out readproof. Prints out internal objects represented as {{#<...>}} as strings {{"#<...>"}} so that the format output can always be processed by `read'. ;{{~:A}}: Print out readproof. Prints out internal objects represented as `#<...>' as strings `"#<...>"' so that the format output can always be processed by `read'. ;{{~... parameter-char ...}}: PARAMETER-CHAR maybe an integer representation for a character. ;{{~C}}: Argument maybe an integer representation for a character. ;{{~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. ;{{~F, ~E, ~G, ~$, ~I}}: May also print number strings, i.e. passing a number as a string and format it accordingly. ==== Incompatible with Common LISP ;{{~/}}: Call Function {{~/FUNC/}}. ;{{~I}}: Indent. === Bugs There's a problem {{~F}} when the number of digits is specified and the number is large. For example, (format #t "~,2F~%" (expt 2 50)) produces the number "1.12", which is clearly wrong. ==== Configuration Variables Format has some configuration variables. There should be no modification necessary for the default configuration. If modification is desired the variable should be set after the format code is loaded. ===== Implemented The following variables are supported by this {{format}} implementation: ;{{format:floats}} (default {{#t}}): System has floating-point numbers. ;{{format:complex-numbers}} (default {{#f}}): System has complex numbers. ;{{format:expch}} (default {{#\E}}): The character prefixing the exponent value in ~E printing. ;{{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. ;{{format:max-iterations}} (default 100): The maximum number of iterations performed by a {{~{...~} }} control. Has effect only when {{format:iteration-bounded}} is {{#t}}. ===== Not Implemented The following variables are still not supported by this {{format}} implementation: ;{{format:fn-max}} (default 200): Maximum number of number digits. ;{{format:en-max}} (default 10): Maximum number of exponent digits. ;{{format:radix-pref}}: Does number->string add a radix prefix? ;{{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. ;{{format:iobj-case-conv}} (default #f): As format:symbol-case-conv but applies for the representation of implementation internal objects. ;{{format:unprocessed-arguments-error?}} (default #f): Are superfluous arguments treated as an error. === Pre-defined Formatters Many predefined formatters that are used for the implementation of {{format}} are exported and can be reused to make new format functions: ;{{*formatter-params*}}: Parameter escapes. ;{{*formatter-iteration*}}: Iteration escapes. ;{{*formatter-caseconv*}}: Case-conversion escapes. ;{{*formatter-chars*}}: Character escapes. ;{{*formatter-numbers*}}: Number escapes. ;{{*formatter-cond*}}: Conditional escapes. ;{{*formatter-indirection*}}: Indirection escapes. ;{{*formatter-jump*}}: Jump escapes. ;{{*formatter-objs*}}: Object escapes. ;{{*formatter-flush*}}: Flush escapes. ;{{*formatter-plural*}}: Plural escapes. ;{{*formatter-tabulate*}}: Tabulate escapes. ;{{*formatter-cl*}}: All of the above. === Example ==== format <enscript highlight=scheme> (use format-modular) (format #f "Found: [~D]: ~A~%" 12 "objects") </enscript> ==== make-format-function <enscript highlight=scheme> (use format-modular) (define fprintf (make-format-function #f #\% `(((#\d ,(formatter-padded display)) (#\s ,(formatter-padded write)))))) (fprintf #t "Found: [%d]: %s\n" 12 "objects") </enscript> === Known limitations Chicken doesn't have support for output port column position. Since a new state is created upon each invocation the format output column position has no "memory", thus {{~&}} is accurate only within a single invocation. === History ; 1.8 : Added '*formatter-next-argument' for argument access by an external formatter. [Kon Lovett] ; 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. ; 1.6 : Added KY$I&\\n escapes, V parameter, commawidth, tabchar, localization, bugfixes [Kon Lovett] ; 1.5 : Added support for static linking ; 1.4 : Bug fix for numbers egg use & float/expon format, made port optional [Kon Lovett] ; 1.3 : Minor doc fixes, rename out-* to *formatter-out-*, works with utf8, uses vectors & fixnum arithmetic where possible [Kon Lovett] ; 1.2 : bugfix in formatter-jump ; 1.1 : Small bug fixes, more annotations to the source code ; 1.0 : First public release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 0 to 12?