Skip to content
Kavachकवच

Text and Collections

● Intermediate3 minBefore this: Strings, ListsSpec 14.9

std.text and std.collections hold small helpers for text and lists: padding, words, chunks, pairs, counts. They are written in Kavach itself.

Text

use std.text

fn main() {
    print("[{text.pad_left("42", 6, '0')}]")
    print("[{text.pad_right("pens", 8, '.')}]")
    print(text.words("  red\tgreen\n blue "))
    print(text.capitalize("asha"))
    print(text.truncate("a very long title", 6))
    print(text.is_blank(" \t\n"))
}

The program ran and printed:

kavach run helpers.kav

[000042][pens....]["red", "green", "blue"]Ashaa verytrue
helpers.kav: Kavach code, then what running it prints

To find numbers inside text, see Strings to numbers.

Text that looks the same

One letter can be written with different code points: é as one, or as e and an accent that joins it. Text typed on one machine and pasted from another can look the same and still not be equal. A Unicode normal form writes it one way, so both compare equal:

use std.text

fn main() {
    const typed = "caf\u{E9}"          // é as one code point
    const pasted = "cafe\u{301}"       // e, then an accent that joins it
    print(typed == pasted)
    print(text.nfc(typed) == text.nfc(pasted))
    print("{typed.len()} {pasted.len()}")
    print(text.nfkc("\u{FB01}le \u{FF11}\u{FF12}"))
}

The program ran and printed:

kavach run normal-forms.kav

falsetrue4 5file 12
normal-forms.kav: Kavach code, then what running it prints
  • len counts code points, so the two spellings of café have 4 and 5.
  • nfc joins a letter and its accent; nfd splits them.
  • nfkc and nfkd also turn look-alike characters into plain ones: fi into fi, the full-width 12 into 12.
  • To compare what people type, such as user names, passwords and searches, normalise both sides first.

Lists

use std.collections

fn main() {
    const items = ["pen", "ink", "pen", "pad", "pen"]
    print(collections.chunks([1, 2, 3, 4, 5], 2))
    print(collections.zip(["a", "b", "c"], [1, 2]))
    print(collections.unique(items))
    print(collections.counts(items))
    print(collections.flatten([[1, 2], [], [3]]))
}

The program ran and printed:

kavach run helpers.kav

[[1, 2], [3, 4], [5]][("a", 1), ("b", 2)]["pen", "ink", "pad"]["pen": 3, "ink": 1, "pad": 1][1, 2, 3]
helpers.kav: Kavach code, then what running it prints
  • zip stops at the shorter list, so "c" has no pair.
  • unique and counts keep the order in which items were first seen.

Every function

FunctionGives
text.pad_left(s, width, fill), text.pad_right(s, width, fill)s filled with fill (a Char, default ' ') up to width characters
text.words(s)The words of s: the parts between runs of spaces, tabs and line breaks
text.capitalize(s)s with its first character in upper case
text.truncate(s, max)At most max characters of s
text.is_blank(s)Whether s has only spaces, tabs and line breaks
text.find_ints(s)Every whole number written inside s, in order: "a12b34" gives [12, 34]
text.find_int(s)The first of them, or none: "sd23" gives 23
text.find_float(s)The first number with its fraction, or none: "pi is 3.14!" gives 3.14
text.nfc(s), text.nfd(s), text.nfkc(s), text.nfkd(s)s in a Unicode normal form (UAX #15), so texts written with different code points compare equal: nfc joins a letter and its accent into one code point, nfd splits them, and the k forms also turn compatibility characters into plain ones (fi into fi, full-width 1 into 1). The runtime gives these four (decision 0102); the rest of std.text is written in Kavach
collections.chunks(items, size)The items in lists of size (the last may be shorter)
collections.zip(a, b)Pairs of items at the same position, as long as the shorter list
collections.unique(items)Each item once, in the order first seen
collections.counts(items)How many times each item appears, in the order first seen
collections.flatten(lists)The items of all the lists, in order

Both modules are written in Kavach, with contracts and examples like any other code, so kavach test checks them too. The four normal forms are the exception: the runtime gives them, from Unicode's own tables.

spec 14.9 · std.text and std.collections