Support Modules =============== These modules are not specific to this project but had to be implemented anyway to not require any external dependencies. The Modules ----------- The modules have no unified naming convention as the modules have not much in common. ### ANSI (import ansi) A simple module for creating ANSI (ECMA-48) sequence strings. (ansi . args) * ```args``` - a list of color/style keywords Produces an ANSI CSI (Control Sequence Introducer) SGR (Select Graphic Rendition) strings with given attributes (re)set. It understands the following keywords: * ```#:black``` - black text foreground color * ```#:red``` - red text foreground color * ```#:green``` - green text foreground color * ```#:yellow``` - yellow text foreground color * ```#:blue``` - blue text foreground color * ```#:magenta``` - magenta text foreground color * ```#:cyan``` - cyan text foreground color * ```#:white``` or ```#:grey``` - white (grey) text foreground color * ```#:brightblack``` or ```#:darkgrey```- dark grey (bright black) text foreground color * ```#:brightred``` - bright red text foreground color * ```#:brightgreen``` - bright green text foreground color * ```#:brightyellow``` - bright yellow text foreground color * ```#:brightblue``` - bright blue text foreground color * ```#:brightmagenta``` or ```#:pink``` - pink (bright magenta) text foreground color * ```#:brightcyan``` - bright cyan text foreground color * ```#:brightwhite``` - bright white (real white) text foreground color * ```#:bgblack``` - black text background color * ```#:bgred``` - red text background color * ```#:bggreen``` - green text background color * ```#:bgyellow``` - yellow text background color * ```#:bgblue``` - blue text background color * ```#:bgmagenta``` - magenta text background color * ```#:bgcyan``` - cyan text background color * ```#:bgwhite``` or ```#:bggrey``` - white (grey) text background color * ```#:bgbrightblack``` or ```#:darkgrey```- dark grey (bright black) text background color * ```#:bgbrightred``` - bright red text background color * ```#:bgbrightgreen``` - bright green text background color * ```#:bgbrightyellow``` - bright yellow text background color * ```#:bgbrightblue``` - bright blue text background color * ```#:bgbrightmagenta``` or ```#:pink``` - pink (bright magenta) text background color * ```#:bgbrightcyan``` - bright cyan text background color * ```#:bgbrightwhite``` - bright white (real white) text background color * ```#:default``` - reset all attributes to terminal defaults * ```#:bold``` - bold font (and/or bright foreground color on some terminals) The order is important as the ```#:default``` resets all attributes given even in the same attribute list. a:error Used to signal errors. Defaults to red bold text. a:warning Used to signal non-fatal warnings. Defaults to regular yellow text. a:success Signals success of an operation. Defaults to bold green text. a:neutral Used for generic text. Defaults to regular white (grey) text. a:default Special style which just resets the terminal output attributes to terminal defaults. a:muted Used for displaying the text "muted" (dimmed). Defaults to bold/bright black text. a:highlight Generic highlight of given text. Defaults to bold blue text. (ansi-string-length str) * ```str``` - string that may contain ANSI CSI SGR sequences Returns the string length in characters without any ANSI CSI SGR sequences contained. (ansi-paragraph-format str width) * ```str``` - a string that may contain ANSI CSI SGR sequences * ```width``` - a number representing themaximum number of characters per line If the string ```str``` is longer than the supplied ```width```, splits it into multiple lines on word boundaries to wrap it nicely. The resulting string is free of ANSI CSI SGR sequences and may contain newline characters. (ansi-string . args) * ```args``` - a list of strings and/or ANSI keywords Returns a string created by appending all the strings given and ```ansi``` function produced ones with consecutive keywords passed to single ```ansi``` evaluation. (clrscr) Clears the terminal screen and places the cursor in the top left corner. ### Command Line parsing (import command-line) Generic syntax-based implementation of command-line options parsing with focus on generated help and ergonomic binding of option arguments. (command-line print-help (opt (args ...) help body ...) ...) * ```print-help``` - identifier binding for the help printing procedure * ```opt``` - command-line option name as identifier (unquoted symbol) * ```args ...``` - optional arguments of given option * ```help``` - help string for this option * ```body ...``` - expressions to be evaluated upon option match Parses command-line arguments based on the specification given. If evaluated inside ```csi``` script, only options and arguments after the ```--``` meta-option are parsed. If evaluated inside compiled binary, all arguments are parsed as usual. Each option is represented by the ```opt``` option identifier (unquoted symbol), optional arguments ```args``` which become bound in the option specification ```body ...``` expressions, help string and the actual expressions to be evaluated when the option (and possibly its arguments) match. If an option is encountered on the command-line and not enough arguments (according to the option specification) are provided for it, an exception is raised. Within any of the ```body ...``` expressions the ```print-help``` procedure can be used to print the options, their argument names and help strings in a nice, human-readable format. ### Listing (import listing) This module implements listing a text file with line numbers and optional highlights of given source lines, optionally with comments for those lines. (print-source-listing lines highlights [#:highligh-rules `((error ,(ansi #:bold #:red) ,(ansi #:default)) (warning ,(ansi #:yellow) ,(ansi #:default)) (info ,(ansi #:cyan) ,(ansi #:default)))] [#:ellipsis "..."] [#:context 3] [#:hl-pre ""] [#:hl-post ""] [#:ctx-pre ""] [#:ctx-post ""]) * ```lines``` - list of string representing lines of the text file * ```highlights``` - list of highlights (see below) * ```highlight-rules``` - assq rules for highlight types pre and post * ```context``` - number of context lines to be shown around highlighted lies * ```hl-pre``` - string introducing highlighted lines * ```hl-post``` - string terminating highlighted lines * ```ctx-pre``` - string introducing context lines * ```ctx-post``` - string terminating context lines * ```ellipsis``` - string representing lines omitted from the output Prints given text file represented by the ```lines``` list of strings. Lines to be highlighted can be specified in the ```highlights``` list. The highlight specification a list containing the following: * line number (number) * message (string) * pass stage (number) * type (symbol) By default the lines are actually highlighted by prepending them with ```hl-pre``` string and the highlight is finished by appending ```hl-post``` to them. Usually some constants from the ```ansi``` module are used. If the highlight type is found in ```highlight-rules```, given pre/post strings are used instead. If some lines are highlighted a number of ```context``` lines surrounding them may be printed as well. If this argument is negative, all non-highlighted lines are printed as context lines. Context lines are prepended with ```ctx-pre``` string and terminated by ```ctx-post``` string. If some lines between highlight and/or context lines are omitted, ```ellipsis``` string is printed on single line as a substitute. ### Progress (import progress) Provides syntax forms and procedures for showing progress of a process. (with-progress echo? pre post body ...) * ```echo?``` - flag enabling progress output * ```pre``` - string to be printed at start * ```post``` - string to be printed after finish * ```body ...``` - expressions of the process tracked Displays process progress starting with the ```pre``` string, adding arbitrary string to the output using the ```progress-advance``` during each and every step. If the process reaches its finish, the output line is finished with the ```post``` string and cursor is moved to new line. During the steps, the whole line is always refreshed when the progress gets updated. If ```echo?``` is ```#f``` (false), nothing is output. (progress-advance [str]) * ```str``` - string to add to progress, defaults to "." Adds given string to current progress and refreshes the progress line. Must be evaluated within ```with-progress``` expression. (progress-break body ...) * ```body ...``` - arbitrary expressions to be evaluated Evaluates the ```body ...``` expressions. Hides current progress line before the evaluation and redisplays it when finished. (*progress%-width* [width]) * ```width``` - width of the progress bar Parameter configuring the progress% bar size. (*progress%-step* [step]) * ```step``` - minimal step before re-drawing the bar Parameter configuring the minimal step before the current progress% bar is redrawn. The progress value is a number from 0 to 1 and the step must be specified on the same scale. (with-progress% echo? name body ...) * ```echo?``` - flag enabling progress output * ```name``` - name to be used at the end of progress line * ```body ...``` - expressions to be evaluated while tracking progress% Displays progress while the ```body ...``` is evaluated. Current progress% value must be updated with ```progress%-advance```. (progress%-advance new-value) * ```new-value``` - new value of progress If the new-value differs from last value shown more than ```(*progress%-step*)```, redisplays the current progress%. ### Table (import table) This module provides moderately complex terminal table rendering. (*table-border-style* [style]) * ```style``` - symbol representing the style Valid styles are: * ```'debug``` - special style to see any rendering problems * ```'ascii``` - plain ASCII (7-bit) * ```'unicode``` - nice box-drawing table (UTF-8) If invalid style is provided, ```'debug``` style is automatically substituted. (table->string tbl [#:table-border #f] [#:row-border #f] [#:col-border #f] [#:row0-border #f] [#:col0-border #f] [#:border-style (*table-border-style*)] [#:ansi #f]) * ```tbl``` - list of lists with cell data * ```#:table-border``` - if ```#t```, the table has outer border * ```#:row-border``` - if ```#t```, the rows are separated by borders * ```#:col-border``` - if ```#t```, the columns are separated by borders * ```#:row0-border``` - if ```#t```, the first row is separated by border * ```#:col0-border``` - if ```#t```, the first column is separated by border * ```#:border-style``` - which border style to use (see ```*table-border-style*``` which is the default) * ```#:ansi``` - if ```#t```, all cell line strings are terminated with ```a:default``` The table ```tbl``` is represented as a list of rows where each row is a list of cells that hold arbitrary values that are converted to string when rendering the table. Before rendering the table, the following steps are performed: * The table is made rectangular - that is all rows are extended by empty strings to have the same length. * All non-string cells are converted to string using ```sprintf``` * All cells are split into list of strings representing the lines of text inside them. * For each row, all cells are extended by empty strings to have matching number of lines of text inside them. * For each column, all lines of text inside all of the cells are padded with spaces to have uniform width. Then each table row is converted to list of strings adding column separators and table borders as required. These lists are then joined with row separators and possibly prefixed and suffixed by top and bottom table border. The resulting list of strings is joined with newline character as the separator. ### Testing (import testing) This module provides simple syntax forms for (unit) testing of other modules. (run-tests name body ...) * ```name``` - identifier describing the module being tested * ```body ...``` - test expressions Runs all tests specified on the ```body ...```. Firstly it prints "[test] name " at the beginning of the line. Secondly it runs all tests, printing "." for each test successfully passed. If all tests pass, prints " ok." and moves the cursor to the next line. In case any of the tests fails, exception is raised and program terminates. (test-eq? name expression expected-result) * ```name``` - identifier representing the name of the test * ```expression``` - expression to be evaluated * ```expected-result``` - expected result of the test expression Evaluates the test ```expression``` and compares the result with ```expected-result``` using ```eq?```. If the comparison fails, an exception is raised with the ```name``` of the test added to the exception. If the test passes, prints "." like all tests from this module do. (test-equal? name expression expected-result) * ```name``` - identifier representing the name of the test * ```expression``` - expression to be evaluated * ```expected-result``` - expected result of the test expression Evaluates the test ```expression``` and compares the result with ```expected-result``` using ```equal?```. If the comparison fails, an exception is raised with the ```name``` of the test added to the exception. If the test passes, prints "." like all tests from this module do. (test-true name expression) * ```name``` - identifier representing the name of the test * ```expression``` - expression to be evaluated Evaluates the test ```expression``` and checks whether the result is ```#t``` (true). An exception is raised if it is not with the ```name``` of the test added to the exception. If the test passes, prints "." like all tests from this module do. (test-false name expression) * ```name``` - identifier representing the name of the test * ```expression``` - expression to be evaluated Evaluates the test ```expression``` and checks whether the result is ```#f``` (false). An exception is raised if it is not with the ```name``` of the test added to the exception. If the test passes, prints "." like all tests from this module do. (test-exn name expression) * ```name``` - identifier representing the name of the test * ```expression``` - expression to be evaluated Evaluates the test ```expression``` and checks whether it raised an exception. An exception is raised if no exception was raised during the evaluation. If the test passes, prints "." like all tests from this module do. ### Environment (import environment) Basic UNIX environment support. (edit-file file-path) * ```file-path``` - path to file to edit Runs the editor specified by the environment variable EDITOR or - if unset - the editor binary.