hackerbase/MODULES.md

21 KiB

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-file-check-syntax* [mode])
  • mode - mode symbol

Configures syntax error handling when parsing member files. Known modes are:

  • 'error - raises an error upon encountering error
  • 'warning - displays warning and displays relevant part of member file source with the offending line highlighted.
  • 'quiet - supresses any error reporting

Other values are invalid.

(*member-default-joined* [month])
  • month - valid month as produced by the month module

If the member file does not contain the joined key, this value is substituted as a default.

(*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 File

Member Record

Member Base

Cards

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

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? 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 - white (grey) text foreground 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.

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 context hl-pre hl-post ctx-pre ctx-post ellipsis)
  • lines - list of string representing lines of the text file
  • highlights - list of highlights (see below)
  • 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 is either a number or a list containing the line number and string comment.

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 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.

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.

Utils

To ensure there are no external dependencies (including chicken eggs), this module re-implements any basic procedures which are required for any algorithms used.

(filter pred? lst)
  • pred? - procedure accepting any value and returning #t or #f
  • lst - list to be filtered

Returns a list containing only elements matching given pred? predicate.

(string-repeat str rep)
  • str - string to repeat
  • rep - number of repeats

Returns a string created by repeating the string str exactly rep number of times.

(string-first+rest str)
  • str - a string to split

Returns a pair of strings where the car of the pair is the first token in the str given and cdr is a string with the remainder with leading whitespace removed.

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]
               [#: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
  • #: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.