(index ("fmt" 0) ("dsp" 692) ("wrt" 1176) ("wrt/unshared" 1367) ("pretty" 1618) ("pretty/unshared" 1928) ("slashified" 2035) ("maybe-slashified" 2632) ("num" 3303) ("num/comma" 4562) ("num/si" 4773) ("num/fit" 5473) ("num/roman" 5833) ("num/old-roman" 5999) ("nl" 6237) ("fl" 6298) ("space-to" 6434) ("tab-to" 6623) ("fmt-null" 6959) ("cat" 7092) ("apply-cat" 7205) ("fmt-join" 7342) ("fmt-join/prefix" 7710) ("fmt-join/suffix" 7710) ("fmt-join/last" 8069) ("fmt-join/dot" 8292) ("pad" 8529) ("pad/left" 8529) ("pad/both" 8529) ("trim" 9336) ("trim/left" 9336) ("trim/both" 9336) ("trim/length" 10517) ("fit" 10739) ("fit/left" 10739) ("fit/both" 10739) ("fmt-let" 11094) ("fmt-bind" 11094) ("fmt-if" 11483) ("radix" 11988) ("fix" 11988) ("decimal-align" 13374) ("comma-char" 13967) ("decimal-char" 13967) ("pad-char" 14196) ("ellipse" 15276) ("with-width" 15438) ("columnar" 15605) ("tabular" 18170) ("fmt-columns" 18788) ("wrap-lines" 19402) ("justify" 19634) ("fmt-file" 20730) ("line-numbers" 21032) ("c-if" 21796) ("c-for" 22004) ("c-while" 22004) ("c-fun" 22177) ("c-prototype" 22177) ("c-var" 23053) ("c-begin" 23237) ("c-switch" 23417) ("c-case" 23417) ("c-case/fallthrough" 23417) ("c-default" 23417) ("c-label" 23862) ("c-goto" 23862) ("c-return" 23862) ("c-break" 23862) ("c-continue" 23862) ("c-const" 24206) ("c-static" 24206) ("c-volatile" 24206) ("c-restrict" 24206) ("c-register" 24206) ("c-auto" 24206) ("c-inline" 24206) ("c-extern" 24206) ("c-extern/C" 24636) ("c-cast" 24779) ("c-typedef" 24922) ("c-struct" 25057) ("c-union" 25057) ("c-class" 25057) ("c-attribute" 25057) ("c-enum" 25875) ("c-comment" 26063) ("cpp-include" 26276) ("cpp-define" 26624) ("cpp-if" 27140) ("cpp-ifdef" 27140) ("cpp-ifndef" 27140) ("cpp-elif" 27140) ("cpp-else" 27140) ("cpp-line" 27519) ("cpp-pragma" 27616) ("cpp-error" 27616) ("cpp-warning" 27616) ("cpp-stringify" 27832) ("cpp-sym-cat" 27976) ("cpp-wrap-header" 28144) ("fmt-color" 28463) ("fmt-in-html" 28692))
(def (sig (procedure "(fmt <output-dest> <format> ...)" (id fmt))) (p "where " (tt "<output-dest>") " has the same semantics as with " (tt "format") " - specifically it can be an output-port, " (tt "#t") " to indicate the current output port, or " (tt "#f") " to accumulate output into a string.") (p "Each " (tt "<format>") " should be a format closure as discussed below. As a convenience, non-procedure arguments are also allowed and are formatted similar to display, so that") (highlight scheme "(fmt #f \"Result: \" res nl)") (p "would return the string " (tt "\"Result: 42n\"") ", assuming " (tt "res") " is bound to " (tt "42") ".") (p (tt "nl") " is the newline format combinator."))
(def (sig (procedure "(dsp <obj>)" (id dsp))) (p "Outputs " (tt "<obj>") " using " (tt "display") " semantics. Specifically, strings are output without surrounding quotes or escaping and characters are written as if by " (tt "write-char") ". Other objects are written as with " (tt "write") " (including nested strings and chars inside " (tt "<obj>") "). This is the default behavior for top-level formats in " (tt "fmt") ", " (tt "cat") " and most other higher-order combinators."))
(def (sig (procedure "(wrt <obj>)" (id wrt))) (p "Outputs " (tt "<obj>") " using write semantics. Handles shared structures as in " (link "http://srfi.schemers.org/srfi-38/" "SRFI-38") "."))
(def (sig (procedure "(wrt/unshared <obj>)" (id wrt/unshared))) (p "As above, but doesn't handle shared structures. Infinite loops can still be avoided if used inside a combinator that truncates data (see " (tt "trim") " and " (tt "fit") " below)."))
(def (sig (procedure "(pretty <obj>)" (id pretty))) (p "Pretty-prints " (tt "<obj>") ". Also handles shared structures. Unlike many other pretty printers, vectors and data lists (lists that don't begin with a (nested) symbol), are printed in tabular format when there's room, greatly saving vertical space."))
(def (sig (procedure "(pretty/unshared <obj>)" (id pretty/unshared))) (p "As above but without sharing."))
(def (sig (procedure "(slashified <str> [<quote-ch> <esc-ch> <renamer>])" (id slashified))) (p "Outputs the string " (tt "<str>") ", escaping any quote or escape characters. If " (tt "<esc-ch>") " is " (tt "#f") " escapes only the " (tt "<quote-ch>") " by doubling it, as in SQL strings and CSV values. If " (tt "<renamer>") " is provided, it should be a procedure of one character which maps that character to its escape value, e.g. " (tt "#\\newline => #\\n") ", or " (tt "#f") " if there is no escape value.") (highlight scheme "(fmt #f (slashified \"hi, \"bob!\"\"))\n\n=> \"hi, \"bob!\"\""))
(def (sig (procedure "(maybe-slashified <str> <pred> [<quote-ch> <esc-ch> <renamer>])" (id maybe-slashified))) (p "Like " (tt "slashified") ", but first checks if any quoting is required (by the existence of either any quote or escape characters, or any character matching " (tt "<pred>") "), and if so outputs the string in quotes and with escapes. Otherwise outputs the string as is.") (highlight scheme "(fmt #f (maybe-slashified \"foo\" char-whitespace? #\\\"))\n\n=> \"foo\"\n\n(fmt #f (maybe-slashified \"foo bar\" char-whitespace? #\\\"))\n\n=> \"\"foo bar\"\"\n\n(fmt #f (maybe-slashified \"foo\"bar\"baz\" char-whitespace? #\\\"))\n\n=> \"\"foo\"bar\"baz\"\""))
(def (sig (procedure "(num <n> [<radix> <precision> <sign> <comma> <comma-sep> <decimal-sep>])" (id num))) (p "Formats a single number " (tt "<n>") ". You can optionally specify any " (tt "<radix>") " from " (tt "2") " to " (tt "36") " (even if " (tt "<n>") " isn't an integer). " (tt "<precision>") " forces a fixed-point format.") (p "A " (tt "<sign>") " of " (tt "#t") " indicates to output a plus sign (" (tt "+") ") for positive integers. However, if " (tt "<sign>") " is a character, it means to wrap the number with that character and its mirror opposite if the number is negative. For example, " (tt "#\\(") " prints negative numbers in parenthesis, financial style: " (tt "-3.14 => (3.14)") ".") (p (tt "<comma>") " is an integer specifying the number of digits between commas. Variable length, as in subcontinental-style, is not yet supported.") (p (tt "<comma-sep>") " is the character to use for commas, defaulting to " (tt "#\\,") ".") (p (tt "<decimal-sep>") " is the character to use for decimals, defaulting to " (tt "#\\.") ", or to " (tt "#\\") ", (European style) if " (tt "<comma-sep>") " is already " (tt "#\\.") ".") (p "These parameters may seem unwieldy, but they can also take their defaults from state variables, described below."))
(def (sig (procedure "(num/comma <n> [<base> <precision> <sign>])" (id num/comma))) (p "Shortcut for " (tt "num") " to print with commas.") (highlight scheme "(fmt #f (num/comma 1234567))\n\n=> \"1,234,567\""))
(def (sig (procedure "(num/si <n> [<base> <suffix>])" (id num/si))) (p "Abbreviates " (tt "<n>") " with an SI suffix as in the -h or --si option to many GNU commands. The base defaults to " (tt "1024") ", using suffix names like Ki, Mi, Gi, etc. Other bases (e.g. the standard 1000) have the suffixes k, M, G, etc.") (p "The " (tt "<suffix>") " argument is appended only if an abbreviation is used.") (highlight scheme "(fmt #f (num/si 608))\n\n=> \"608\"\n\n(fmt #f (num/si 3986))\n\n=> \"3.9Ki\"\n\n(fmt #f (num/si 3986 1000 \"B\"))\n\n=> \"4kB\"") (p "See " (link "http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.html" "http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.html") "."))
(def (sig (procedure "(num/fit <width> <n> . <ARGS>)" (id num/fit))) (p "Like " (tt "num") ", but if the result doesn't fit in " (tt "<width>") ", output instead a string of hashes (with the current " (tt "<precision>") ") rather than showing an incorrectly truncated number. For example") (highlight scheme "(fmt #f (fix 2 (num/fit 4 12.345))) => \"#.##\""))
(def (sig (procedure "(num/roman <n>)" (id num/roman))) (p "Formats the number as a Roman numeral:") (highlight scheme "(fmt #f (num/roman 1989)) => \"MCMLXXXIX\""))
(def (sig (procedure "(num/old-roman <n>)" (id num/old-roman))) (p "Formats the number as an old-style Roman numeral, without the subtraction abbreviation rule:") (highlight scheme "(fmt #f (num/old-roman 1989)) => \"MDCCCCLXXXVIIII\""))
(def (sig (constant "nl" (id nl))) (p "Outputs a newline."))
(def (sig (constant "fl" (id fl))) (p "Short for \"fresh line,\" outputs a newline only if we're not already at the start of a line."))
(def (sig (procedure "(space-to <column>)" (id space-to))) (p "Outputs spaces up to the given " (tt "<column>") ". If the current column is already >= " (tt "<column>") ", does nothing."))
(def (sig (procedure "(tab-to [<tab-width>])" (id tab-to))) (p "Outputs spaces up to the next tab stop, using tab stops of width " (tt "<tab-width>") ", which defaults to " (tt "8") ". If already on a tab stop, does nothing. If you want to ensure you always tab at least one space, you can use " (tt "(cat \" \" (tab-to width))") "."))
(def (sig (constant "fmt-null" (id fmt-null))) (p "Outputs nothing (useful in combinators and as a default noop in conditionals)."))
(def (sig (procedure "(cat <format> ...)" (id cat))) (p "Concatenates the output of each " (tt "<format>") "."))
(def (sig (procedure "(apply-cat <list>)" (id apply-cat))) (p "Equivalent to " (tt "(apply cat <list>)") " but may be more efficient."))
(def (sig (procedure "(fmt-join <formatter> <list> [<sep>])" (id fmt-join))) (p "Formats each element " (tt "<elt>") " of " (tt "<list>") " with " (tt "(<formatter> <elt>)") ", inserting " (tt "<sep>") " in between. " (tt "<sep>") " defaults to the empty string, but can be any format.") (highlight scheme "(fmt #f (fmt-join dsp '(a b c) \", \"))\n\n=> \"a, b, c\""))
(def (sig (procedure "(fmt-join/prefix <formatter> <list> [<sep>])" (id fmt-join/prefix)) (procedure "(fmt-join/suffix <formatter> <list> [<sep>])" (id fmt-join/suffix))) (highlight scheme "(fmt #f (fmt-join/prefix dsp '(usr local bin) \"/\"))\n\n=> \"/usr/local/bin\"") (p "As " (tt "fmt-join") ", but inserts " (tt "<sep>") " before/after every element."))
(def (sig (procedure "(fmt-join/last <formatter> <last-formatter> <list> [<sep>])" (id fmt-join/last))) (p "As " (tt "fmt-join") ", but the last element of the list is formatted with " (tt "<last-formatter>") " instead."))
(def (sig (procedure "(fmt-join/dot <formatter> <dot-formatter> <list> [<sep>])" (id fmt-join/dot))) (p "As " (tt "fmt-join") ", but if the list is a dotted list, then formats the dotted value with " (tt "<dot-formatter>") " instead."))
(def (sig (procedure "(pad <width> <format> ...)" (id pad)) (procedure "(pad/left <width> <format> ...)" (id pad/left)) (procedure "(pad/both <width> <format> ...)" (id pad/both))) (p "Analogs of " (link "http://srfi.schemers.org/srfi-13/srfi-13.html" "SRFI-13") " " (tt "string-pad") ", these add extra space to the left, right or both sides of the output generated by the " (tt "<format>") "s to pad it to " (tt "<width>") ". If " (tt "<width>") " is exceeded has no effect. " (tt "pad/both") " will include an extra space on the right side of the output if the difference is odd.") (p (tt "pad") " does not accumulate any intermediate data.") (p "Note these are column-oriented padders, so won't necessarily work with multi-line output (padding doesn't seem a likely operation for multi-line output)."))
(def (sig (procedure "(trim <width> <format> ...)" (id trim)) (procedure "(trim/left <width> <format> ...)" (id trim/left)) (procedure "(trim/both <width> <format> ...)" (id trim/both))) (p "Analogs of " (link "http://srfi.schemers.org/srfi-13/srfi-13.html" "SRFI-13") " " (tt "string-trim") ", truncates the output of the " (tt "<format>") "s to force it in under " (tt "<width>") " columns. As soon as any of the " (tt "<format>") "s exceed " (tt "<width>") ", stop formatting and truncate the result, returning control to whoever called " (tt "trim") ". If " (tt "<width>") " is not exceeded has no effect.") (p "If a truncation ellipse is set (e.g. with the " (tt "ellipses") " procedure below), then when any truncation occurs " (tt "trim") " and " (tt "trim/left") " will append and prepend the ellipse, respectively. " (tt "trim/both") " will both prepend and append. The length of the ellipse will be considered when truncating the original string, so that the total width will never be longer than " (tt "<width>") ".") (highlight scheme "(fmt #f (ellipses \"...\" (trim 5 \"abcde\")))\n\n=> \"abcde\"\n\n(fmt #f (ellipses \"...\" (trim 5 \"abcdef\")))\n\n=> \"ab...\""))
(def (sig (procedure "(trim/length <width> <format> ...)" (id trim/length))) (p "A variant of " (tt "trim") " which acts on the actual character count rather than columns, useful for truncating potentially cyclic data."))
(def (sig (procedure "(fit <width> <format> ...)" (id fit)) (procedure "(fit/left <width> <format> ...)" (id fit/left)) (procedure "(fit/both <width> <format> ...)" (id fit/both))) (p "A combination of " (tt "pad") " and " (tt "trunc") ", ensures the output width is exactly " (tt "<width>") ", truncating if it goes over and padding if it goes under."))
(def (sig (procedure "(fmt-let <name> <value> <format> ...)" (id fmt-let)) (procedure "(fmt-bind <name> <value> <format> ...)" (id fmt-bind))) (p (tt "fmt-let") " sets the name for the duration of the " (tt "<format>") "s, and restores it on return. " (tt "fmt-bind") " sets it without restoring it.") (p "A convenience control structure can be useful in combination with these states:"))
(def (sig (procedure "(fmt-if <pred> <pass> [<fail>])" (id fmt-if))) (p (tt "<pred>") " takes one argument (the format state) and returns a boolean result. If true, the " (tt "<pass>") " format is applied to the state, otherwise " (tt "<fail>") " (defaulting to the identity) is applied.") (p "Many of the previously mentioned combinators have behavior which can be altered with state variables. Although " (tt "fmt-let") " and " (tt "fmt-bind") " could be used, these common variables have shortcuts:"))
(def (sig (procedure "(radix <k> <format> ...)" (id radix)) (procedure "(fix <k> <format> ...)" (id fix))) (p "These alter the radix and fixed point precision of numbers output with " (tt "dsp") ", " (tt "wrt") ", " (tt "pretty") " or " (tt "num") ". These settings apply recursively to all output data structures, so that") (highlight scheme "(fmt #f (radix 16 '(70 80 90)))") (p "will return the string " (tt "\"(#x46 #x50 #x5a)\"") ". Note that read/write invariance is essential, so for " (tt "dsp") ", " (tt "wrt") " and " (tt "pretty") " the radix prefix is always included when not decimal. Use " (tt "num") " if you want to format numbers in alternate bases without this prefix. For example,") (highlight scheme "(fmt #f (radix 16 \"(\" (fmt-join num '(70 80 90) \" \") \")\"))") (p "would return " (tt "\"(46 50 5a)\"") ", the same output as above without the " (tt "\"#x\"") " radix prefix.") (p "Note that fixed point formatting supports arbitrary precision in implementations with exact non-integral rationals. When trying to print inexact numbers more than the machine precision you will typically get results like") (highlight scheme "(fmt #f (fix 30 #i2/3))\n\n=> \"0.666666666666666600000000000000\"") (p "but with an exact rational it will give you as many digits as you request:") (highlight scheme "(fmt #f (fix 30 2/3))\n\n=> \"0.666666666666666666666666666667\""))
(def (sig (procedure "(decimal-align <k> <format> ...)" (id decimal-align))) (p "Specifies an alignment for the decimal place when formatting numbers, useful for outputting tables of numbers.") (highlight scheme "  (define (print-angles x)\n     (fmt-join num (list x (sin x) (cos x) (tan x)) \" \"))\n\n  (fmt #t (decimal-align 5 (fix 3 (fmt-join/suffix print-angles (iota 5) nl))))") (p "would output") (pre "  0.000    0.000    1.000    0.000\n  1.000    0.842    0.540    1.557\n  2.000    0.909   -0.416   -2.185\n  3.000    0.141   -0.990   -0.142\n  4.000   -0.757   -0.654    1.158"))
(def (sig (procedure "(comma-char <k> <format> ...)" (id comma-char)) (procedure "(decimal-char <k> <format> ...)" (id decimal-char))) (p (tt "comma-char") " and " (tt "decimal-char") " set the defaults for number formatting."))
(def (sig (procedure "(pad-char <k> <format> ...)" (id pad-char))) (p "The " (tt "pad-char") " sets the character used by " (tt "space-to") ", " (tt "tab-to") ", " (tt "pad/*") ", and " (tt "fit/*") ", and defaults to " (tt "#\\space") ".") (highlight scheme "  (define (print-table-of-contents alist)\n    (define (print-line x)\n      (cat (car x) (space-to 72) (pad/left 3 (cdr x))))\n    (fmt #t (pad-char #\\. (fmt-join/suffix print-line alist nl))))\n\n  (print-table-of-contents\n   '((\"An Unexpected Party\" . 29)\n     (\"Roast Mutton\" . 60)\n     (\"A Short Rest\" . 87)\n     (\"Over Hill and Under Hill\" . 100)\n     (\"Riddles in the Dark\" . 115)))") (p "would output") (pre " An Unexpected Party.....................................................29\n Roast Mutton............................................................60\n A Short Rest............................................................87\n Over Hill and Under Hill...............................................100\n Riddles in the Dark....................................................115"))
(def (sig (procedure "(ellipse <ell> <format> ...)" (id ellipse))) (p "Sets the truncation ellipse to " (tt "<ell>") ", would should be a string or character."))
(def (sig (procedure "(with-width <width> <format> ...)" (id with-width))) (p "Sets the maximum column width used by some formatters. The default is " (tt "78") "."))
(def (sig (procedure "(columnar <column> ...)" (id columnar))) (p "Formats each " (tt "<column>") " side-by-side, i.e. as though each were formatted separately and then the individual lines concatenated together. The current column width is divided evenly among the columns, and all but the last column are right-padded. For example") (highlight scheme "(fmt #t (columnar (dsp \"abc\\ndef\\n\") (dsp \"123\\n456\\n\")))") (p "outputs") (pre "    abc     123\n    def     456") (p "assuming a 16-char width (the left side gets half the width, or 8 spaces, and is left aligned). Note that we explicitly use DSP instead of the strings directly. This is because " (tt "columnar") " treats raw strings as literals inserted into the given location on every line, to be used as borders, for example:") (highlight scheme "  (fmt #t (columnar \"/* \" (dsp \"abc\\ndef\\n\")\n                    \" | \" (dsp \"123\\n456\\n\")\n                    \" */\"))") (p "would output") (pre " /* abc | 123 */\n /* def | 456 */") (p "You may also prefix any column with any of the symbols " (tt "'left") ", " (tt "'right") " or " (tt "'center") " to control the justification. The symbol " (tt "'infinite") " can be used to indicate the column generates an infinite stream of output.") (p "You can further prefix any column with a width modifier. Any positive integer is treated as a fixed width, ignoring the available width. Any real number between 0 and 1 indicates a fraction of the available width (after subtracting out any fixed widths). Columns with unspecified width divide up the remaining width evenly.") (p "Note that " (tt "columnar") " builds its output incrementally, interleaving calls to the generators until each has produced a line, then concatenating that line together and outputting it. This is important because as noted above, some columns may produce an infinite stream of output, and in general you may want to format data larger than can fit into memory. Thus columnar would be suitable for line numbering a file of arbitrary size, or implementing the Unix " (tt "yes(1)") " command, etc.") (p "As an implementation detail, " (tt "columnar") " uses first-class continuations to interleave the column output. The core " (tt "fmt") " itself has no knowledge of or special support for " (tt "columnar") ", which could complicate and potentially slow down simpler " (tt "fmt") " operations. This is a testament to the power of " (tt "call/cc") " - it can be used to implement coroutines or arbitrary control structures even where they were not planned for."))
(def (sig (procedure "(tabular <column> ...)" (id tabular))) (p "Equivalent to columnar except that each column is padded at least to the minimum width required on any of its lines. Thus") (highlight scheme "(fmt #t (tabular \"|\" (dsp \"a\\nbc\\ndef\\n\") \"|\" (dsp \"123\\n45\\n6\\n\") \"|\"))") (p "outputs") (pre "|a  |123|\n|bc |45 |\n|def|6  |") (p "This makes it easier to generate tables without knowing widths in advance. However, because it requires generating the entire output in advance to determine the correct column widths, " (tt "tabular") " cannot format a table larger than would fit in memory."))
(def (sig (procedure "(fmt-columns <column> ...)" (id fmt-columns))) (p "The low-level formatter on which " (tt "columnar") " is based. Each " (tt "<column>") " must be a list of 2-3 elements:") (pre "(<line-formatter> <line-generator> [<infinite?>])") (p "where " (tt "<line-generator>") " is the column generator as above, and the <line-formatter> is how each line is formatted. Raw concatenation of each line is performed, without any spacing or width adjustment. " (tt "<infinite?>") ", if true, indicates this generator produces an infinite number of lines and termination should be determined without it."))
(def (sig (procedure "(wrap-lines <format> ...)" (id wrap-lines))) (p "Behaves like " (tt "cat") ", except text is accumulated and lines are optimally wrapped to fit in the current width as in the Unix " (tt "fmt(1)") " command."))
(def (sig (procedure "(justify <format> ...)" (id justify))) (p "Like wrap-lines except the lines are full-justified.") (highlight scheme "  (define func\n    '(define (fold kons knil ls)\n       (let lp ((ls ls) (acc knil))\n         (if (null? ls) acc (lp (cdr ls) (kons (car ls) acc))))))\n\n  (define doc\n    (string-append\n      \"The fundamental list iterator.  Applies KONS to each element \"\n      \"of LS and the result of the previous application, beginning \"\n      \"with KNIL.  With KONS as CONS and KNIL as '(), equivalent to REVERSE.\"))\n\n  (fmt #t (columnar (pretty func) \" ; \" (justify doc)))") (p "outputs") (pre " (define (fold kons knil ls)          ; The   fundamental   list   iterator.\n   (let lp ((ls ls) (acc knil))       ; Applies  KONS  to  each  element  of\n     (if (null? ls)                   ; LS  and  the  result of the previous\n         acc                          ; application,  beginning  with  KNIL.\n         (lp (cdr ls)                 ; With  KONS  as CONS and KNIL as '(),\n             (kons (car ls) acc)))))  ; equivalent to REVERSE."))
(def (sig (procedure "(fmt-file <pathname>)" (id fmt-file))) (p "Simply displays the contents of the file " (tt "<pathname>") " a line at a time, so that in typical formatters such as " (tt "columnar") " only constant memory is consumed, making this suitable for formatting files of arbitrary size."))
(def (sig (procedure "(line-numbers [<start>])" (id line-numbers))) (p "A convenience utility, just formats an infinite stream of numbers (in the current radix) beginning with " (tt "<start>") ", which defaults to " (tt "1") ".") (p "The Unix " (tt "nl(1)") " utility could be implemented as:") (highlight scheme "  (fmt #t (columnar 6 'right 'infinite (line-numbers)\n                    \" \" (fmt-file \"read-line.scm\")))") (pre "    1 \n    2 (define (read-line . o)\n    3   (let ((port (if (pair? o) (car o) (current-input-port))))\n    4     (let lp ((res '()))\n    5       (let ((c (read-char port)))\n    6         (if (or (eof-object? c) (eqv? c #\\newline))\n    7             (list->string (reverse res))\n    8             (lp (cons c res)))))))"))
(def (sig (procedure "(c-if <condition> <pass> [<fail> [<condition2> <pass2> ...]])" (id c-if))) (p "Print a chain of if/else conditions. Use a final condition of " (tt "'else") " for a final else clause."))
(def (sig (procedure "(c-for <init> <condition> <update> <body> ...)" (id c-for)) (procedure "(c-while <condition> <body> ...)" (id c-while))) (p "Basic loop constructs."))
(def (sig (procedure "(c-fun <type> <name> <params> <body> ...)" (id c-fun)) (procedure "(c-prototype <type> <name> <params>)" (id c-prototype))) (p "Output a function or function prototype. The parameters should be a list 2-element lists of the form " (tt "(<param-type> <param-name>)") ", which are output with DSP. A parameter can be abbreviated as just the symbol name, or " (tt "#f") " can be passed as the type, in which case the 'default-type state variable is used. The parameters may be a dotted list, in which case ellipses for a C variadic are inserted - the actual name of the dotted value is ignored.") (p "Types are just typically just symbols, or lists of symbols such as " (tt "'(const char)") ". A complete description is given below in section \"C Types\".") (p "These can also accessed as " (tt "%fun") " and " (tt "%prototype") " at the head of a list."))
(def (sig (procedure "(c-var <type> <name> [<init-value>])" (id c-var))) (p "Declares and optionally initializes a variable. Also accessed as " (tt "%var") " at the head of a list."))
(def (sig (procedure "(c-begin <expr> ...)" (id c-begin))) (p "Outputs each of the " (tt "<expr>") "s, separated by semi-colons if in a statement or commas if in an expression."))
(def (sig (procedure "(c-switch <clause> ...)" (id c-switch)) (procedure "(c-case <values> <body> ...)" (id c-case)) (procedure "(c-case/fallthrough <values> <body> ...)" (id c-case/fallthrough)) (procedure "(c-default <body> ...)" (id c-default))) (p "Switch statements. In addition to using the clause formatters, clauses inside a switch may be handled with a Scheme CASE-like list, with the car a list of case values and the cdr the body."))
(def (sig (procedure "(c-label <name>)" (id c-label)) (procedure "(c-goto <name>)" (id c-goto)) (procedure "(c-return [<result>])" (id c-return)) (constant "c-break" (id c-break)) (constant "c-continue" (id c-continue))) (p "Manual labels and jumps. Labels can also be accessed as a list beginning with a colon, e.g. " (tt "'(: label1)") "."))
(def (sig (procedure "(c-const <expr>)" (id c-const)) (procedure "(c-static <expr>)" (id c-static)) (procedure "(c-volatile <expr>)" (id c-volatile)) (procedure "(c-restrict <expr>)" (id c-restrict)) (procedure "(c-register <expr>)" (id c-register)) (procedure "(c-auto <expr>)" (id c-auto)) (procedure "(c-inline <expr>)" (id c-inline)) (procedure "(c-extern <expr>)" (id c-extern))) (p "Declaration modifiers. May be nested."))
(def (sig (procedure "(c-extern/C <body> ...)" (id c-extern/C))) (p "Wraps body in an") (pre " extern \"C\" { ... }") (p "for use with C++."))
(def (sig (procedure "(c-cast <type> <expr>)" (id c-cast))) (p "Casts an expression to a type. Also " (tt "%cast") " at the head of a list."))
(def (sig (procedure "(c-typedef <type> <new-name> ...)" (id c-typedef))) (p "Creates a new type definition with one or more names."))
(def (sig (procedure "(c-struct [<name>] <field-list> [<attributes>])" (id c-struct)) (procedure "(c-union [<name>] <field-list> [<attributes>])" (id c-union)) (procedure "(c-class [<name>] <field-list> [<attributes>])" (id c-class)) (procedure "(c-attribute <values> ...)" (id c-attribute))) (p "Composite type constructors. Attributes may be accessed as " (tt "%attribute") " at the head of a list.") (highlight scheme "  (fmt #f (c-struct 'employee\n                      '((short age)\n                        ((char *) name)\n                        ((struct (year month day)) dob))\n                      (c-attribute 'packed)))") (pre " struct employee {\n     short age;\n     char* name;\n     struct {\n         int year;\n         int month;\n         int day;\n     } dob;\n } __attribute__ ((packed));"))
(def (sig (procedure "(c-enum [<name>] <enum-list>)" (id c-enum))) (p "Enumerated types. <enum-list> may be strings, symbols, or lists of string or symbol followed by the enum's value."))
(def (sig (procedure "(c-comment <formatter> ...)" (id c-comment))) (p "Outputs the <formatter>s wrapped in C's " (tt "/* ... */") " comment. Properly escapes nested comments inside in an Emacs-friendly style."))
(def (sig (procedure "(cpp-include <file>)" (id cpp-include))) (p "If file is a string, outputs in it \"quotes\", otherwise (as a symbol or arbitrary formatter) it outputs it in brackets.") (highlight scheme "(fmt #f (cpp-include 'stdio.h))\n\n=> \"#include <stdio.h>\\n\"\n\n(fmt #f (cpp-include \"config.h\"))\n\n=> \"#include \"config.h\\n\""))
(def (sig (procedure "(cpp-define <macro> [<value>])" (id cpp-define))) (p "Defines a preprocessor macro, which may be just a name or a list of name and parameters. Properly wraps the value in parenthesis and escapes newlines. A dotted parameter list will use the C99 variadic macro syntax, and will also substitute any references to the dotted name with __VA_ARGS__:") (highlight scheme "(fmt #t (cpp-define '(eprintf . args) '(fprintf stderr args)))") (pre " #define eprintf(...) (fprintf(stderr, __VA_ARGS__))"))
(def (sig (procedure "(cpp-if <condition> <pass> [<fail> ...])" (id cpp-if)) (procedure "(cpp-ifdef <condition> <pass> [<fail> ...])" (id cpp-ifdef)) (procedure "(cpp-ifndef <condition> <pass> [<fail> ...])" (id cpp-ifndef)) (procedure "(cpp-elif <condition> <pass> [<fail> ...])" (id cpp-elif)) (procedure "(cpp-else <body> ...)" (id cpp-else))) (p "Conditional compilation."))
(def (sig (procedure "(cpp-line <num> [<file>])" (id cpp-line))) (p "Line number information."))
(def (sig (procedure "(cpp-pragma <args> ...)" (id cpp-pragma)) (procedure "(cpp-error <args> ...)" (id cpp-error)) (procedure "(cpp-warning <args> ...)" (id cpp-warning))) (p "Additional preprocessor directives."))
(def (sig (procedure "(cpp-stringify <expr>)" (id cpp-stringify))) (p "Stringifies " (tt "<expr>") " by prefixing the " (tt "#") " operator."))
(def (sig (procedure "(cpp-sym-cat <args> ...)" (id cpp-sym-cat))) (p "Joins the " (tt "<args>") " into a single preprocessor token with the " (tt "##") " operator."))
(def (sig (procedure "(cpp-wrap-header <name> <body> ...)" (id cpp-wrap-header))) (p "Wrap an entire header to only be included once.") (p "Operators:") (pre " c++ c-- c+ c- c* c/ c% c& c^ c~ c! c&& c<< c>> c== c!=\n c< c> c<= c>= c= c+= c-= c*= c/= c%= c&= c^= c<<= c>>=\n c++/post c--/post c-or c-bit-or c-bit-or="))
(def (sig (procedure "(fmt-color <color> <formatter> ...)" (id fmt-color))) (p "where " (tt "<color>") " can be a symbol name or " (tt "#xRRGGBB") " numeric value. Outputs the formatters colored with ANSI escapes. In addition"))
(def (sig (procedure "(fmt-in-html <formatter> ...)" (id fmt-in-html))) (p "can be used to mark the format state as being inside HTML, which the above color formats will understand and output HTML " (tt "<span>") " tags with the appropriate style colors, instead of ANSI escapes."))
