1 Text Output
These modules deal with the low-level terminal text output.
Any text, that is sent to the terminal is scanned for any control codes and their sequences which may alter the visual properties of characted printed later, move cursor on the screen, insert or erase characters, lines or whole screen and many other actions given terminal supports. What remains after processing these control codes and sequences is the text to be shown on the screen.
The ECMA-48 standard specifies many control codes which can be divided - with respect to this implementation - into the following categories:
General control codes,
Control Sequence Introducer (CSI), and
CSI Select Graphic Rendition (SGR).
Always remember that the CSI SGR processing does not perform any actual character rendering and only allows for easier formatting of strings with these sequences. In the end they are passed to the actual terminal the program is running in. If in doubt, try your sequences without any processing first!
Only a very limited subset of the whole terminal capabilities as specified in the ECMA-48 standard is supported by these modules. Anything non-CSI gets passed through and any CSI except SGR gets filtered. All SGR codes are processed and most of the standard - or commonly used - features are captured and properly processed. Unknown parts of SGR sequences are discarded though.
The actual cell borders are drawn using Unicode character from the Box Drawing Unicode block #x2500-#x257F. All the possible combinations of light and heavy border junctions are supported - there are 81 of them (including blank space). Because not all combinations of double-line characters are present in Unicode, general doubly-lined borders cannot be properly supported.
1.1 ECMA-48 CSI
(require uni-table/private/ecma-csi) | package: uni-table |
This module implements a subset of ECMA-48 CSI (Control Sequence Introducer) decoding, allowing for capturing plain text and SGR (Select Graphic Rendition) state snapshots anytime SGR control sequence is found in the text. Other control sequences are discarded as they would interfere with table output.
The SGR module uses ecma-csi-tokenize from this module to tokenize input strings into a list of plain strings and string containing only the control sequences starting with CSI. For further processing ecma-csi-type is used to determine which type of CSI sequence it is.
procedure
(ecma-csi-tokenize str) → (listof string?)
str : string?
procedure
(ecma-csi-start? str) → boolean?
str : string?
procedure
(ecma-csi-remove str) → string?
str : string?
procedure
(ecma-csi-type str) → char?
str :
(and/c non-empty-string? ecma-csi-start?)
1.2 ECMA-48 SGR
(require uni-table/private/ecma-sgr) | package: uni-table |
This module implements the internal SGR (Select Graphic Rendition) state machine of ECMA-48 terminals. The following features are implemented:
bold and half-bright intensity,
italic font,
single and double underline,
text blinking,
reverse video,
strike-through (crossed-out) text, and
- foreground and background colors including
16-color,
256-color,
and 16M-color extensions.
Other features are not (yet) supported.
Use ecma-csi-sgr-parse-lines to conver a string possibly containing CSI SGR sequences into a list of sgr-list?s - list of plain strings and snapshots of sgr-states. Each line will become one sgr-list? in the resulting list.
Conversion from sgr-list? to string with CSI sequences can be done using sgr-list->csi-string. The table cell renderer then uses sgr-line-fill-block to ensure the lists of sgr-list? are rectangular.
struct
(struct sgr-rgb (r g b) #:transparent) r : (integer-in 0 255) g : (integer-in 0 255) b : (integer-in 0 255)
struct
(struct sgr-state ( intensity italic underline blink reverse-video crossed-out foreground background) #:transparent) intensity : (or/c #f 'bold 'half-bright) italic : boolean? underline : (or/c #f 1 2) blink : boolean? reverse-video : boolean? crossed-out : boolean?
foreground :
(or/c #f (integer-in 0 255) sgr-rgb?)
background :
(or/c #f (integer-in 0 255) sgr-rgb?)
value
value
value
procedure
(ecma-csi-sgr-parse str [ #:initial-state initial-state #:reset-state reset-state #:prepend-initial-state prepend-inititial-state]) → sgr-list? str : string? initial-state : sgr-state? = empty-sgr-state reset-state : sgr-state? = initial-state prepend-inititial-state : boolean? = #f
procedure
(sgr-list-compact lst) → sgr-list?
lst : sgr-list?
procedure
(sgr-list->csi-string lst [ #:initial-state initial-state]) → string? lst : sgr-list? initial-state : sgr-state? = empty-sgr-state
procedure
(ecma-csi-sgr-parse-lines str [ #:initial-state initial-state]) → sgr-lines? str : string? initial-state : sgr-state? = empty-sgr-state
procedure
(sgr-list-last-state lst [ #:initial-state initial-state]) → sgr-state? lst : sgr-list? initial-state : sgr-state? = empty-sgr-state
1.3 Box Drawing
(require uni-table/private/box-drawing) | package: uni-table |
This module implements two-dimensional orthogonal grid box drawing using two possible line weights: light and heavy lines.
The Unicode Box Drawing Characters block contains all 80 combinations (81 including generic space character) for independently drawing no, light or heavy line from the center of the character box in each of four major grid directions.
As general support for double lines is not possible with current Unicode specification, double lines box drawing is not implemented.
Straight lines can be solid or dashed. Lines in junctions are too short and therefore can only be solid.
value
'hidden - not drawn but takes space,
'light - thin (light) line
'heavy - thick (heavy) line
value
value
'dashed - dashed line
'solid - solid line always
value
value
struct
(struct line-style (weight type) #:transparent) weight : line-weight/c type : line-type/c
value
procedure
(merge-line-weight orig over) → line-weight/c
orig : line-weight/c over : line-weight/c
procedure
(merge-line-style orig over [ #:relaxed relaxed]) → line-style? orig : line-style? over : line-style? relaxed : boolean? = #f
The strength of the values is as follows:
weight: #f < 'hidden < 'light < 'heavy
type: #f < 'dashed < 'solid
Type is overriden only if over contains non-#f weight. This behaviour can be disabled by specifying #:relaxed #t.
procedure
(parse-line-style-spec token/s) → line-style?
token/s : line-style-spec/c
value
procedure
(straight-line-char ls [dir]) → char?
ls : line-style? dir : line-direction/c = 'horizontal
struct
(struct junction (up left right down) #:transparent) up : line-weight/c left : line-weight/c right : line-weight/c down : line-weight/c
procedure
(merge-junction orig over) → junction?
orig : junction? over : junction?
procedure
(junction->char j) → char?
j : junction?