hackerbase/doc/modules.md

1234 lines
37 KiB
Markdown

BrmBuro Modules
===============
This file contains documentation of all exported symbols of all
modules used. Modules are grouped according to their specificity to
this project.
Functional Modules
------------------
These modules are specific to this project and their generic usage is
questionable.
### Configuration
The exact behavior of some algorithms in other modules can be changed
via configuration parameters in this global configuration module.
(*current-month* [month])
* ```month``` - valid month structure as specified in the ```month``` module
Configuration parameter specifying the current month. Defaults to the
current month derived from the current system time.
(*member-file-context* [lines])
* ```lines``` - number of context lines
How many lines of context are to be shown in source file
listing. Mainly used by the member file module parser and processor.
(*member-suspend-max-months* [number])
* ```number``` - number of months (nonnegative integer)
Determines how many months the member can be suspended before any
action is required.
### Member Record
This module encapsulates the data structure representing a single
member record.
(make-member-record file-name file-path symlinks . args)
* ```file-name``` - a symbol representing the primary filename
* ```file-path``` - a string representing the path to the file
* ```symlinks``` - a list of symbols representing symlinks
* ```args``` - optional keyword arguments
Creates a new member record dictionary. The three mandatory arguments
are stored under respective keys and any keyword arguments are stored
as keys obtained by converting the keyword to symbol with values
following the keyword.
The ```'id``` key is filled with any four-digit file-name or symlink
converted to a number. Preferably the four-digit symbol should be the
file-name but it is not required.
(member-file-path mr)
* ```mr``` - a member record structure
Returns the path used for accessing this member's file.
(member-record-input-file mr)
* ```mr``` - a member record structure
Returns an open file port to given member record underlying file. This
function should be used by the parser to get the member file contents.
(member-record-set mr . args)
* ```mr``` - a member record structure
* ```args``` - optional keyword arguments
Any keyword arguments are stored in the member record dictionary as
keys obtained by converting the keyword to symbol with values
following the keyword.
(member-record-add-highlight mr line message pass type)
* ```mr``` - a member record structure
* ```line``` - line number in the source file
* ```message``` - a string with message for highlight
* ```pass``` - parsing stage
* ```type``` - symbol representing the highlight type
Adds a new highlight to member record to be used when displaying the
source file listing.
Known types are:
* ```'error``` - to denote fatal problem in the source
* ```'warning``` - to signal known problem which does not make the record invalid
* ```'info``` - supplemental information
The structure is perfectly suited for ```print-source-listing``` function.
(member-record-sub-ref mr sec key [default])
* ```mr``` - a member record structure
* ```sec``` - section symbol
* ```key``` - key symbol
* ```default``` - optional default value
Retrieves given ```key``` from dictionary stored as section ```sec```
in given ```mr``` structure. If no ```default``` is provided and the
```key``` does not exist it raises an exception.
(member-record-sub-set mr sec key value)
* ```mr``` - a member record structure
* ```sec``` - section symbol
* ```key``` - key symbol
* ```value``` - value to set
Sets the value of given ```key``` in dictionary stored as section
```sec``` in given ```mr``` structure to the new ```value``` possibly
overwriting previous one.
(member-record-sub-prepend mr sec key value)
* ```mr``` - a member record structure
* ```sec``` - section symbol
* ```key``` - key symbol
* ```value``` - value to prepend (cons) to the key current value
Prepends (cons) new the ```value``` to current value of given ```key``` in
dictionary stored as section ```sec``` in given ```mr``` structure
replacing the original value.
(member-record-sub-has-key? mr sec key)
* ```mr``` - a member record structure
* ```sec``` - section symbol
* ```key``` - key symbol
Returns ```#t``` if given section ```sec``` contains the ```key```.
(member-record-sub-ensure mr sec key value)
* ```mr``` - a member record structure
* ```sec``` - section symbol
* ```key``` - key symbol
* ```value``` - value to set
Sets the value of given ```key``` in dictionary stored as section
```sec``` in given ```mr``` structure to the new ```value``` if and
only if it is not already present.
(member-source mr)
* ```mr``` - a member record structure
Returns a list of strings representing the source file of this member
record.
(member-record-info mr key [default])
* ```mr``` - a member record structure
* ```key``` - key (symbol) to retrieve
* ```default``` - optional default value
Like ```dict-ref``` returns the value associated with ```key``` in
section ```'info```. If ```default``` is provided, it is passed on to
the underlying ```dict-ref```.
(member-missing-keys mr)
* ```mr``` - a member record structure
Returns a list of keys (symbols) from within the ```'info``` section
of given ```mr``` that have ```#f``` values (indicating they are
missing mandatory fields in the source).
(member-has-highlights? mr)
* ```mr``` - a member record structure
Returns ```#t``` if given ```mr``` has at least one source highlight.
(member-record-usable? mr)
* ```mr``` - a member record structure
Returns ```#t``` if it is possible to work with this member - mainly
that the ```'info``` section contains the ```'member``` key.
(member-has-problems? mr)
* ```mr``` - a member record structure
Returns ```#t``` if there are any ```'error``` type highlights in
```mr```, or it is not ```member-record-usable?``` or the
```member-id``` is not 4-digit prime number.
(member-destroyed? mr)
* ```mr``` - a member record structure
Returns ```#t``` if the member is not existing and already has existed
in the past.
(member-suspended? mr)
* ```mr``` - a member record structure
Returns ```#t``` if the current month falls within any of given member's
suspended periods.
(member-active? mr)
* ```mr``` - a member record structure
Returns ```#t``` if given member exists, is a member and is currently
not suspended.
(member-student? mr)
* ```mr``` - a member record structure
Returns ```#t``` if given member exists, is a member, is currently not
suspended and current month falls within any member's suspended
periods.
(member-existing? mr)
* ```mr``` - a member record structure
Returns ```#t``` if given member exists - that is the current month is
within any of the member (membership) periods.
(member-flags mr)
* ```mr``` - a member record structure
Returns a list of member flags which can be any of the following:
* ```'student```
* ```'suspended```
* ```'active```
* ```'destroyed```
* ```'existing```
The ```'existing``` and ```'destroyed``` are mutually exclusive. Also
```'active``` and ```'suspended``` are mutually exclusive.
(member-nick mr)
* ```mr``` - a member record structure
Returns member's nick from its ```'info``` section.
(member-id mr)
* ```mr``` - a member record structure
Returns given member's id.
(member-suspended-months mr)
* ```mr``` - a member record structure
Returns the number of months this member is suspended in
```(*current-month*)```. If the member is not suspended, returns
```0```.
(member-format fmt mr)
* ```fmt``` - format string
* ```mr``` - a member record structure
Fills the following template substitutions in the ```fmt``` string:
* ```~N``` - member's nick
* ```~I``` - member's id
* ```~S``` - number of months this member has been suspended
* ```~E``` - number of highlights in square brackets if there is at least one
* ```~~``` - literal ```~```
Other parts of the string are retained.
(member<? a b)
* ```a``` - a member record structure
* ```b``` - a member record structure
Returns true if member ```a```'s nick comes before ```b```'s nick in
the lexicographical order.
(member-record-add-payment mr pt)
* ```mr``` - a member record structure
* ```pt``` - bank transaction of the payment
Adds (prepends) given transaction ```pt``` to given member record
```mr```'s ```'payments'``` key list.
(member-payments mr)
* ```mr``` - a member record structure
Returns the payments (bank transactions) list of given member record
```mr``` defaulting to an empty list.
### Member Parser
This module exports only one function - the ```load-member-file```
which loads and parses given file as member file. The specification of
this file format is in a separate document ```MEMBERS.md```.
The module implements this specification as multi-pass parser with
important definitions being at the top of the module.
mandatory-keys
A list of symbols containing keys which must be present in the
file. If any of them is missing, it is added to the resulting
structure with the ```#f``` value.
optional-keys
A list of symbols of keys which the parser recognizes and adds them to
the resulting data structure.
ignored-keys
A list of symbols with keys that are parsed, and albeit not added to
the result they do not generate warnings.
known-multikeys
A list of keys that can appear multiple times and in the 2nd pass they
are collected as lists of values.
start-stop-markers-lookup
A list of start/stop specifications - each key is paired with given
key and start/stop tag.
(load-member-file mr)
* ```mr``` - (almost) empty member record structure
It must be possible to get the member file using
```member-record-input-file``` function. Loads the file as a list of
lines, processes these lines with 1st and 2nd pass parsers, interprets
the result using 3rd passes and finalizes the result in the 4th pass.
### Members Directory
This module encapsulates the members base directory format as
documented in ```MEMBERS.md``` document.
Each member file should have a 4-digit name identical to member id and
optional symlinks with human-known names of the members. The module
can correctly handle a situation where the 4-digit id is a symlink to
arbitrarily named file.
In first pass it extracts all files and symlinks to them, binds them
together and makes sure the 4-digit name is used as id and the regular
file is read when loading its contents.
(load-members-dir dn)
* ```dn``` - directory name (path)
Scans given directory and returns a dictionary of canonical names as
keys and lists of alias symlinks as values.
(members-dir-load-member mdir fname symlinks)
* ```mdir``` - members directory name (path)
* ```fname``` - file name inside ```mdir``` (without path)
* ```symlinks``` - a list of symlinks to ```fname```
Creates an initial member record and uses ```load-member-file``` to
load, parse and interpret its contents.
### Members Base
This module uses the members directory module to load and parse all
members files and provides a simple interface for accessing the data.
(load-members dn [progress?])
* ```dn``` - directory with member files
* ```progress?``` - if ```#t```, displays loading progress
Loads all member files and creates a members base data structure.
(members-base-members mb)
* ```mb``` - members base structure
Returns the list of all member records loaded.
(find-member-by-id mb id)
* ```mb``` - members base structure
* ```id``` - member identifier (4-digit prime number)
Returns the member record associated with the provided ```id```.
(find-member-by-nick mb nick)
* ```mb``` - members base structure
* ```nick``` - member nick
Returns the member record identified by its ```nick```.
(find-members-by-nick mb nick)
* ```mb``` - members base structure
* ```nick``` - member nick
Returns the list of all member records with substring matching of
```nick```. May return empty list, list with one member or multiple
member records.
(list-members-ids mb)
* ```mb``` - members base structure
Returns a list of all members' ids.
(filter-members-by-predicate mb pred)
* ```mb``` - members base structure
* ```pred``` - predicate procedure
Returns a list of all member records matching the given predicate.
(list-members-nicks mb)
* ```mb``` - members base structure
Returns a list of all member nicks.
(members-base-info mb)
* ```mb``` - members base structure
Returns a dictionary with basic information about given members
base. The dictionary contains the following keys:
* ```'invalid``` - a list of all invalid member records
* ```'active``` - a list of all active member records
* ```'suspended``` - a list of all suspended member records
* ```'students``` - a list of all student member records
* ```'destroyed``` - a list of all destroyed member records
* ```'month``` - the current month for this info dictionary
* ```'total``` - a list of all member records contained
This procedure is used for further printing of information about given
members base.
(members-base-stats mb)
* ```mb``` - members base structure
Creates a list of lists of statistical information about given members
base through time. The first row of the resulting list contains column
headers and the rows are sorted chronologically by month.
(get-free-members-ids mb)
* ```mb``` - members base structure
Returns a list of valid member ids which are not already used in given
members base.
(gen-member-id mb)
* ```mb``` - members base structure
Generates a random 4-digit prime number which is not yet used as a
member id.
(members-base-update mb pred? proc)
* ```mb``` - members base structure
* ```pred?``` - member record predicate
* ```proc``` - processing procedure
Updates given members base by applying ```proc``` to all member
records matching ```pred?```.
### Bank Account
This module creates a thin abstraction layer for bank accounts and
transactions.
(make-bank-account number bank [transactions])
* ```number``` - account number
* ```bank``` - bank code
* ```transactions``` - optional list of initial transactions
Creates a new bank account data structure.
The data structure has the following accessors:
* ```(bank-account-transactions ba)``` - returns the transactions list
* ```(bank-account-number ba)```- retrieves the bank account number
* ```(bank-account-bank ba)``` - returns the bank account bank code
The underlying implementation is currently a plain list but is subject
to change in the future.
(bank-account-insert account transaction)
* ```account``` - bank account structure
* ```transaction``` - transaction structure to add
Adds (prepends) given ```transaction``` to the list of transactions of
given bank ```account```.
(make-bank-transaction i d a c v m t)
* ```i``` - transaction id
* ```d``` - date
* ```a``` - amount
* ```c``` - currency
* ```v``` - variable symbol
* ```m``` - message
* ```t``` - transaction type
Creates new bank transaction data structure. The underlying
implementation is currently a record.
The following accessors are provided:
* ```bank-transaction-id```
* ```bank-transaction-date```
* ```bank-transaction-amount```
* ```bank-transaction-currency```
* ```bank-transaction-varsym```
* ```bank-transaction-message```
* ```bank-transaction-type```
More fields with accessors will be added as other modules will need
them.
### Bank Fio
### Members Payments Processor
### Members Info Printer
### Cards
### Web Static
Specific Support Modules
------------------------
### Month
Module for handling months algebra to be used in period construction
and matching.
(make-month y m)
* ```y``` - a number representing valid year
* ```m``` - a number between 1 and 12 inclusive
Constructs a new month value with ```y``` number as the year component
and ```m``` number as the month component.
(month-valid? m)
* ```m``` - constructed month value
Checks whether given value is structurally valid month value, the year
is between 1000 and 9999 inclusive and the month is between 1 and 12
inclusive. Returns boolean value.
(string->month s)
* ```s``` - a string in "YYYY-MM" format
Parses given string ```s``` as month and constructs a month value from
the YYYY and MM components parsed. The resulting month value is
returned only if it is valid. Otherwise ```#f``` is returned.
(month->string m)
* ```m``` - valid month value or ```#f```
Converts given month value to a string in ```"YYYY-MM"``` format.
If ```#f```, returns a special empty month result ```"____-__"```.
Raises an error if ```m``` is not a valid month.
(month=? m n)
* ```m``` - first valid month value
* ```n``` - second valid month value
Returns ```#t``` if both month values are valid and ```equal?```.
(month<? m n)
* ```m``` - first valid month value
* ```n``` - second valid month value
Returns ```#t``` if both month values are valud and ```m``` comes
before ```n``` in the calendar.
(month<=? m n)
* ```m``` - first valid month value
* ```n``` - second valid month value
Returns ```#t``` if both month values are valud and ```m``` comes
before ```n``` in the calendar or they are ```equal?```.
(month>=? m n)
* ```m``` - first valid month value
* ```n``` - second valid month value
Returns ```#t``` if both month values are valud and ```m``` comes
after ```n``` in the calendar or they are ```equal?```.
(month>? m n)
* ```m``` - first valid month value
* ```n``` - second valid month value
Returns ```#t``` if both month values are valud and ```m``` comes
after ```n``` in the calendar.
(month-diff f t)
* ```f``` - valid month (from)
* ```t``` - valid month (to)
Returns the difference in months from month ```f``` to month
```t```. If both months are the same, the result is zero. If ```t```
is before ```f```, the result is negative.
(month-add m [n])
* ```m``` - valid month
* ```n``` - an integer, defaults to 1
Returns a new valid month that comes ```n``` months after ```m```. If
```n``` is negative, it correctly subtracts the months.
### Period
This module implements simple calendar period handling with month
granularity. The period contains fields ```since``` which is the first
month of the period and ```before``` which is the first month just
after the period.
(period-since p)
* ```p``` - valid period
Returns the ```since``` part of given period.
(period-before p)
Returns the ```since``` part of given period.
Returns the ```before``` part of given period.
(period-markers->periods l)
* ```l``` - list of sorted (list tag month)
Converts a list of period markers ```l``` into actual periods where
each period is represented by ```(list start-month end-month)```.
The ```end-month``` may be ```#f``` in which case it is an open-ended
period which has not ended yet.
(periods-duration l)
* ```l``` - list of periods
Returns the total duration in months of the periods given in the list
```l```. Each period is represented as ```(list start-month
end-month)```.
(month-in-periods p [m (*current-month*)])
* ```p``` - a periods
* ```m``` - a valid month - defaults to ```(*current-month*)```
Returns ```#t``` if given month ```m``` lies within the period
```p```.
(month-in-periods? ps [m (*current-month*)])
* ```ps``` - a list of periods
* ```m``` - a valid month - defaults to ```(*current-month*)```
Returns ```#t``` if given month ```m``` lies within any of the periods
given in the list of periods ```ps```.
(periods->string ps)
* ```ps``` - a list of periods
Returns a string representing all the periods given in the list of
periods ```ps```. The periods are represented as
````"YYYY-MM..YYYY-MM"``` and an open end is substituded with
```"____-__"```.
(periods-match ps [m (*current-month*)])
* ```ps``` - a list of periods
Returns the period from the list of periods ```ps``` the given month
```m``` falls into. If no period matches, returns ```#f```.
### Primes
A very simple module for generating and checking 4-digit prime numbers.
(is-4digit-prime? n)
* ```n``` - a number
Returns true if the given number ```n``` has four digits and it is a
prime number.
(gen-all-4digit-primes)
Returns a list of all 4-digit prime numbers.
Generic Support Modules
-----------------------
These modules are not specific to this project but had to be
implemented anyway to not require any external dependencies.
### 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
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.
### Dictionary
Simple key/value dictionary with most operations implemented in linear
time. The dictionary is internally represented as ```assq``` list and
is best suitable for symbols and numbers as keys.
(make-dict)
Creates an empty dictionary.
(dict-has-key? d k)
* ```d``` - the dictionary
* ```k``` - key to check
Returns ```#t``` (true) if the dictionary ```d``` contains the key
```k```.
(dict-ref d k [v])
* ```d``` - the dictionary
* ```k``` - the key to retrieve
* ```v``` - optional default value
Retrieves given key ```k``` from the dictionary ```d```.
If the key is not stored in the dictionary an error is raised unless
an optional value ```v``` is provided which is then returned in that
case.
(dict-remove d k)
* ```d``` - the dictionary
* ```k``` - the key to remove
Removes the key ```k``` from the given dictionary ```d``` raising an
exception if the key is not stored in the dictionary.
(dict-set d k v)
* ```d``` - the dictionary
* ```k``` - key to (re)set
* ```v``` - the value to set
If the dictionary ```d``` does not contain the key ```k```, adds the
value ```v``` into it under the given key. If the key is present, its
value is then replaced.
(dict-keys d)
* ```d``` - the dictionary
Returns the list of keys contained in the dictionary ```d```.
(dict-map proc d)
* ```proc``` - procedure for processing
* ```d``` - the dictionary
Returns a dictionary created by processing all elements of the
dictionary ```d``` using the procedure ```proc```.
If the procedure accepts just one argument, only values are passed to
it. If the procedure accepts two arguments, both the key and value are
passed to it. In both cases, the procedure must produce only the value.
(dict-filter pred? d)
* ```pred?``` - predicate procedure
* ```d``` - the dictionary
Returns a new dictionary created by keeping only the key/value pairs
from the dictionary ```d``` matching the predicate ```pred?```.
If the procedure accepts just one argument, only values are passed to
it. If the procedure accepts two arguments, both the key and value are
passed to it.
(dict-reduce init proc d)
* ```init``` - arbitrary initial value
* ```proc``` - procedure for performing the reducing step
* ```d``` - the dictionary to reduce
Iterates over the key/value pairs of given dictionary ```d```
initializing the algorithm with the ```init``` value given. In each
step the procedure ```proc``` is called with three arguments: the
value accumulated so far, key and value.
### 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
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%.
### 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.
### 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.
### Environment