You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

12 KiB


[ Main Table Of Contents | Table Of Contents | Keyword Index ]

NAME

punkshell_module_punk::ansi - Ansi string functions

Table Of Contents

SYNOPSIS

package require punk::ansi

stripansi text
a? ?ansicode...?
a+ ?ansicode...?
a ?ansicode...?
get_code_name code
reset
reset_soft
reset_colour
clear
clear_above
clear_below
cursor_on
cursor_off
move row col
move_emit row col data ?row col data...?
move_forward n
move_back n
move_up n
move_down n
erase_line
erase_sol
erase_eol
cursor_pos
titleset windowtitles
detect text
detect_csi text
detect_sgr text
strip text
length text
index string index

DESCRIPTION

Ansi based terminal control string functions

See punk::ansi::console for related functions for controlling a console

Overview

overview of punk::ansi

punk::ansi functions return their values - no implicit emission to console/stdout

Concepts

Ansi codes can be used to control most terminals on most platforms in an 'almost' standard manner

There are many differences in terminal implementations - but most should support a core set of features

punk::ansi does not contain any code for direct terminal manipulation via the local system APIs.

Sticking to ansi codes where possible may be better for cross-platform and remote operation where such APIs are unlikely to be useable.

dependencies

packages used by punk::ansi

  • Tcl 8.6

API

Namespace punk::ansi

Core API functions for punk::ansi

  • stripansi text

    Return a string with ansi codes stripped out

  • a? ?ansicode...?

    Return an ansi string representing a table of codes and a panel showing the colours

  • a+ ?ansicode...?

    Returns the ansi code to apply those from the supplied list - without any reset being performed first

    e.g to set foreground red and bold

    punk::ansi::a red bold

    to set background red

    punk::ansi::a Red

    see punk::ansi::a? to display a list of codes

  • a ?ansicode...?

    Returns the ansi code to reset any current settings and apply those from the supplied list

    by calling punk::ansi::a with no arguments - the result is a reset to plain text

    e.g to set foreground red and bold

    punk::ansi::a red bold

    to set background red

    punk::ansi::a Red

    see punk::ansi::a? to display a list of codes

  • get_code_name code

    for example

    get_code_name red will return 31

    get_code_name 31 will return red

  • reset

    reset console

  • reset_soft

  • reset_colour

    reset colour only

  • clear

  • clear_above

  • clear_below

  • cursor_on

  • cursor_off

  • move row col

    Return an ansi sequence to move to row,col

    aka cursor home

  • move_emit row col data ?row col data...?

    Return an ansi string representing a move to row col with data appended

    row col data can be repeated any number of times to return a string representing the output of the data elements at all those points

    Compare to punk::console::move_emit which calls this function - but writes it to stdout

    punk::console::move_emit_return will also return the cursor to the original position

    There is no punk::ansi::move_emit_return because in a standard console there is no ansi string which can represent a jump back to starting position.

    There is an ansi code to write the current cursor position to stdin (which will generally display on the console) - this is not quite the same thing.

    punk::console::move_emit_return does it by emitting that code and starting a loop to read stdin

    punk::ansi could implement a move_emit_return using the punk::console mechanism - but the resulting string would capture the cursor position at the time the string is built - which is not necessarily when the string is used.

    The following example shows how to do this manually, emitting the string blah at screen position 10,10 and emitting DONE back at the line we started:

    punk::ansi::move_emit 10 10 blah {*}[punk::console::get_cursor_pos_list] DONE
    

    A string created by any move_emit_return for punk::ansi would not behave in an intuitive manner compared to other punk::ansi move functions - so is deliberately omitted.

  • move_forward n

  • move_back n

  • move_up n

  • move_down n

  • erase_line

  • erase_sol

    Erase to start of line, leaving cursor position alone.

  • erase_eol

  • cursor_pos

    cursor_pos unlikely to be useful on it's own like this as when written to the terminal, this sequence causes the terminal to emit the row;col sequence to stdin

    The output on screen will look something like ^[[47;3R

    Use punk::console::get_cursor_pos or punk::console::get_cursor_pos_list instead.

    These functions will emit the code - but read it in from stdin so that it doesn't display, and then return the row and column as a colon-delimited string or list respectively.

    The punk::ansi::cursor_pos function is used by punk::console::get_cursor_pos and punk::console::get_cursor_pos_list

  • titleset windowtitles

    Returns the code to set the title of the terminal window to windowtitle

    This may not work on terminals which have multiple panes/windows

Namespace punk::ansi::ta

text ansi functions

based on but not identical to the Perl Text Ansi module:

https://github.com/perlancar/perl-Text-ANSI-Util/blob/master/lib/Text/ANSI/BaseUtil.pm

  • detect text

    Return a boolean indicating whether Ansi codes were detected in text

  • detect_csi text

    Return a boolean indicating whether an Ansi Control Sequence Introducer (CSI) was detected in text

    The csi is often represented in code as \x1b or \033 followed by a left bracket [

    The initial byte or escape is commonly referenced as ESC in Ansi documentation

    There is also a multi-byte escape sequence \u009b

    This is less commonly used but is also detected here

    (This function is not in perl ta)

  • detect_sgr text

    Return a boolean indicating whether an ansi Select Graphics Rendition code was detected.

    This is the set of CSI sequences ending in 'm'

    This is most commonly an Ansi colour code - but also things such as underline and italics

    An SGR with empty or a single zero argument is a reset of the SGR features - this is also detected.

    (This function is not in perl ta)

  • strip text

    Return text stripped of Ansi codes

    This is a tailcall to punk::ansi::stripansi

  • length text

    Return the character length after stripping ansi codes - not the printing length

Namespace punk::ansi::ansistring

punk::ansi::string ensemble

  • index string index

    Takes a string that possibly contains ansi codes such as colour,underline etc (SGR codes)

    Returns the character (with applied ansi effect) at position index

    The string could contain non SGR ansi codes - and these will (mostly) be ignored, so shouldn't affect the output.

    Some terminals don't hide 'privacy message' and other strings within an ESC X ESC ^ or ESC _ sequence (terminated by ST)

    It's arguable some of these are application specific - but this function takes the view that they are probably non-displaying - so index won't see them.

    If the caller wants just the character - they should use a normal string index after calling stripansi, or call stripansi afterwards.

    As any operation using end-+ will need to strip ansi to precalculate the length anyway; the caller should probably just use stripansi and standard string index if the ansi coded output isn't required and they are using and end-based index.

    In fact, any operation where the ansi info isn't required in the output would probably be slightly more efficiently obtained by using stripansi and normal string operations on that.

    The returned character will (possibly) have a leading ansi escape sequence but no trailing escape sequence - even if the string was taken from a position immediately before a reset or other SGR ansi code

    The ansi-code prefix in the returned string is built up by concatenating previous SGR ansi codes seen - but it is optimised to re-start the process if any full SGR reset is encountered.

    The code sequence doesn't detect individual properties being turned on and then off again, only full resets; so in some cases the ansi-prefix may not be as short as it could be.

    This shouldn't make any difference to the visual output - but a possible future enhancement is something to produce the shortest ansi sequence possible

    Notes:

    This function has to split the whole string into plaintext & ansi codes even for a very low index

    Some sort of generator that parses more of the string as required might be more efficient for large chunks.

    For end-x operations we have to pre-calculate the content-length by stripping the ansi - which is also potentially sub-optimal

KEYWORDS

ansi, console, module, string, terminal

COPYRIGHT

Copyright © 2023