Rand Stats

Gzz::Text::Utils

zef:grizzlysmit

Table of Contents

NAME

Gzz::Text::Utils

AUTHOR

Francis Grizzly Smit (grizzly@smit.id.au)

VERSION

v0.1.23

TITLE

Gzz::Text::Utils

SUBTITLE

A Raku module to provide text formatting services to Raku programs.

COPYRIGHT

LGPL V3.0+ LICENSE

Introduction

A Raku module to provide text formatting services to Raku programs.

Including a sprintf front-end Sprintf that copes better with Ansi highlighted text and implements %U and does octal as 0o123 or 0O123 if you choose %O as I hate ambiguity like 0123 is it an int with leading zeros or an octal number. Also there is %N for a new line and %T for a tab helpful when you want to use single quotes to stop the $ specs needing back slashes.

And a printf alike Printf.

Also it does centring and there is a max-width field in the % spec i.e. %*.*.*E, and more.

Top of Document

Motivations

When you embed formatting information into your text such as bold, italics, etc ... and colours standard text formatting will not work e.g. printf, sprintf etc also those functions don't do centring.

Another important thing to note is that even these functions will fail if you include such formatting in the text field unless you supply a copy of the text with out the formatting characters in it in the :ref field i.e. left($formatted-text, $width, :ref($unformatted-text)) or text($formatted-text, $width, :$ref) if the reference text is in a variable called $ref or you can write it as left($formatted-text, $width, ref => $unformatted-text)

Top of Document

Update

Fixed the proto type of left etc is now

sub left(Str:D $text, Int:D $width is copy, Str:D $fill = ' ',
            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &left-global-number-of-chars,
               Str:D :$ref = strip-ansi($text), Int:D
                                :$max-width = 0, Str:D :$ellipsis = '' --> Str) is export

Where sub strip-ansi(Str:D $text --> Str:D) is export is my new function for striping out ANSI escape sequences so we don't need to supply :$ref unless it contains codes that sub strip-ansi(Str:D $text --> Str:D) is export cannot strip out, if so I would like to know so I can update it to cope with these new codes.

Top of Document

Exceptions

BadArg

class BadArg is Exception is export

BadArg is a exception type that Sprintf will throw in case of badly specified arguments.

Top of Document

ArgParityMissMatch

class ArgParityMissMatch is Exception is export

ArgParityMissMatch is an exception class that Sprintf throws if the number of arguments does not match what the number the format string says there should be.

NB: if you use num$ argument specs these will not count as they grab from the args add hoc, * width and precision spec however do count as they consume argument.

Top of Document

FormatSpecError

class FormatSpecError is Exception is export

FormatSpecError is an exception class that Format (used by Sprintf) throws if there is an error in the Format specification (i.e. %n instead of %N as %n is already taken, the same with using %t instead of %T).

Or anything else wrong with the Format specifier.

NB: %N introduces a \n character and %T a tab (i.e. \t).

Top of Document

Format and FormatActions

Format & FormatActions are a grammar and Actions pair that parse out the % spec and normal text chunks of a format string.

For use by Sprintf a sprintf alternative that copes with ANSI highlighted text.

Top of Document

UnhighlightBase & UnhighlightBaseActions and Unhighlight & UnhighlightActions

UnhighlightBase & UnhighlightBaseActions are a grammar & role pair that does the work required to to parse apart ansi highlighted text into ANSI highlighted and plain text.

Unhighlight & UnhighlightActions are a grammar & class pair which provide a simple TOP for applying an application of UnhighlightBase & UnhighlightBaseActions for use by sub strip-ansi(Str:D $text -- Str:D) is export> to strip out the plain text from a ANSI formatted string

Top of Document

The Functions Provided

Top of Document

Here are 4 functions provided to centre, left and right justify text even when it is ANSI formatted.

centre

Top of Document

left

Top of Document

right

Top of Document

Sprintf

Top of Document

Printf

Top of Document

MultiT

A lot of types but not Any.

subset MultiT is export of Any where * ~~  Str | Int | Rat | Num | Bool | Array;

menu

Display a text based menu.

sub menu(@candidates is copy, Str:D $message = "",
                              :&row:(Int:D $c, Int:D $p, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$highlight-bg-colour = '',
                                     Str:D :$highlight-fg-colour = '',
                                     Str:D :$bg-colour0 = '',
                                     Str:D :$fg-colour0 = '', 
                                     Str:D :$bg-colour1 = '',
                                     Str:D :$fg-colour1 = '' --> Str:D) = &default-row, 
                              :&value:(Int:D $c, @a --> MultiT) = &default-value, 
                              Bool:D :c(:color(:$colour)) is copy = False,
                              Bool:D :s(:$syntax) = False, 
                              Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold, 
                              Str:D :$highlight-fg-colour = t.bright-yellow, 
                              Str:D :$bg-colour0 = t.bg-yellow ~ t.bold, 
                              Str:D :$fg-colour0 = t.bright-blue, 
                              Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold, 
                              Str:D :$fg-colour1 = t.bright-blue,  
                              Str:D :$bg-prompt = t.bg-green ~ t.bold, 
                              Str:D :$fg-prompt = t.bright-blue, 
                              Bool:D :$wrap-around = False --> MultiT) is export

Top of Document

input-menu(…)

sub input-menu(@candidates is copy, Str:D $message = "",
                              :&row:(Int:D $c, Int:D $p, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$highlight-bg-colour = '', Str:D :$highlight-fg-colour = '',
                                     Str:D :$bg-colour0 = '', Str:D :$fg-colour0 = '', 
                                     Str:D :$bg-colour1 = '', Str:D :$fg-colour1 = '' --> Str:D) = &default-row-input-menu, 
                              :&value:(Int:D $c, @a --> MultiT) = &default-value, 
                              :&elt-prompt:(Int:D $c, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$bg-prompt = '', Str:D :$fg-prompt = '' --> Str:D)  = &default-prompt,
                              :&edit:(Int:D $c, @a is copy, Str:D $e --> Bool:D) = &default-edit, 
                              Bool:D :c(:color(:$colour)) is copy = False,
                              Bool:D :s(:$syntax) = False, 
                              Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold, 
                              Str:D :$highlight-fg-colour = t.bright-yellow, 
                              Str:D :$bg-colour0 = t.bg-yellow ~ t.bold, 
                              Str:D :$fg-colour0 = t.bright-blue, 
                              Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold, 
                              Str:D :$fg-colour1 = t.bright-blue,  
                              Str:D :$bg-prompt = t.bg-green ~ t.bold, 
                              Str:D :$fg-prompt = t.bright-blue, 
                              Bool:D :$wrap-around = False --> MultiT) is export

Top of Document

dropdown(…)

A text based dropdown/list or menu with ANSI colours.

sub dropdown(MultiT:D $id, Int:D $window-height is copy, Str:D $id-name,
                        &setup-option-str:(Int:D $c, Int:D $p, @a --> Str:D),
                        &find-pos:(MultiT $r, Int:D $p, @a --> Int:D),
                        &get-result:(MultiT:D $res, Int:D $p, Int:D $l, @a --> MultiT:D),
                        @array,
                        Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold, 
                        Str:D :$highlight-fg-colour = t.bright-yellow, 
                        Str:D :$bg-colour0 = t.bg-yellow ~ t.bold, 
                        Str:D :$fg-colour0 = t.bright-blue, 
                        Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold, 
                        Str:D :$fg-colour1 = t.bright-blue,  
                        Str:D :$bg-prompt = t.bg-green ~ t.bold, 
                        Str:D :$fg-prompt = t.bright-blue, 
                        Bool:D :$wrap-around = False --> MultiT) is export

Here is an example of use.

Top of Document

my &setup-option-str = sub (Int:D $cnt, Int:D $p, @array --> Str:D ) {
    my Str $name;
    my Str $cc;
    my Str $flag;
    my Str $prefix;
    if $cnt < 0 {
        $name   = "No country selected yet.";
        $cc     = "";
        $flag   = "";
        $prefix = "you must choose one";
    } else {
        my %row = @array[$cnt];
        $name   = %row«_name»;
        $cc     = %row«cc»;
        try {
            CATCH {
                default {
                    my $Name = $name;
                    $Name ~~ s:g/ <wb> 'and' <wb> /\&/;
                    try {
                        CATCH {
                            default { $flag = uniparse 'PENGUIN'}
                        }
                        $flag = uniparse $Name;
                    }
                }
            }
            $flag   = uniparse $name;
        }
        $prefix = %row«prefix»;
    }
    return "$flag $name: $cc ($prefix)"
};
my &find-pos = sub (MultiT $result, Int:D $pos, @array --> Int:D) {
    for @array.kv -> $idx, %r {
        if %r{$id-name} == $result {
            $pos = $idx;
            last; # found so don't waste resources #
        }
    }
    return $pos;
}
my &get-result = sub (MultiT:D $result, Int:D $pos, Int:D $length, @array --> MultiT:D ) {
    my $res = $result;
    if $pos ~~ 0..^$length {
      my %row = |%(@array[$pos]);
      $res = %row«id» if %row«id»:exists;
    }
    return $res
};
my Int:D $cc-id        = dropdown($cc_id, 20, 'id',
                                    &setup-option-str, &find-pos, &get-result, @_country);
while !valid-country-cc-id($cc-id, %countries) {
    $cc-id             = dropdown($cc-id, 20, 'id',
                                    &setup-option-str, &find-pos, &get-result, @_country);
}

Or using a much simpler array. NB: from menu

Top of Document

my &setup-option-str = sub (Int:D $cnt, Int:D $pos, @array --> Str:D ) {
    return @array[$cnt];
};
my &get-result = sub (MultiT:D $result, Int:D $pos, Int:D $length, @array --> MultiT:D ) {
    my $res = $result;
    if $pos ~~ 0..^$length {
      $res = @array[$pos];
    }
    return $res
};
my &find-pos = sub (MultiT $result, Int:D $pos, @array --> Int:D) {
    for @array.kv -> $idx, $r {
        if $r eq $result {
            $pos = $idx;
            last; # found so don't waste resources #
        }
    }
    return $pos;
}
my Str:D $result = dropdown(@candidates[@candidates.elems - 1], 40, 'backup',
                                    &setup-option-str, &find-pos, &get-result, @candidates);

Top of Document

lead-dots(…)

Returns $text in a field of $width with a line of dots preceding it. Sort of like left with $fill defaulting to . but with a single space between the text and the padding.

sub lead-dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

Top of Document

trailing-dots(…)

Returns $text in a field of $width with a line of dots trailing after it. Sort of like right with $fill defaulting to . but with a single space between the text and the padding.

sub trailing-dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

Top of Document

dots(…)

Returns $text in a field of $width with a line of dots preceding it. Sort of like left with $fill defaulting to ..

sub dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

Top of Document