code / tomo

Lines41.3K C23.7K Markdown9.7K YAML5.0K Tomo2.3K
7 others 763
Python231 Shell230 make212 INI47 Text21 SVG16 Lua6
(1.0K lines)

% API

Builtins

Text

Text.as_c_string

Text.as_c_string : func(text: Text -> CString)

Converts a Text value to a C-style string.

Argument Type Description Default
text Text The text to be converted to a C-style string. -

Return: A C-style string (CString) representing the text.

Example:

assert "Hello".as_c_string() == CString("Hello")

Text.at

Text.at : func(text: Text, index: Int -> Text)

Get the graphical cluster at a given index. This is similar to str[i] with ASCII text, but has more correct behavior for unicode text.

Negative indices are counted from the back of the text, so -1 means the last cluster, -2 means the second-to-last, and so on.

Argument Type Description Default
text Text The text from which to get a cluster. -
index Int The index of the graphical cluster (1-indexed). -

Return: A Text with the single graphical cluster at the given index.

Example:

assert "Amélie".at(3) == "é"

Text.by_line

Text.by_line : func(text: Text -> func(->Text?))

Returns an iterator function that can be used to iterate over the lines in a text.

This function ignores a trailing newline if there is one. If you don't want this behavior, use text.by_split($/{1 nl}/) instead.

Argument Type Description Default
text Text The text to be iterated over, line by line. -

Return: An iterator function that returns one line at a time, until it runs out and returns none.

Example:

text := "
    line one
    line two
"
lines := [line for line in text.by_line()]
assert lines == ["line one", "line two"]

Text.by_split

Text.by_split : func(text: Text, delimiter: Text = "" -> func(->Text?))

Returns an iterator function that can be used to iterate over text separated by a delimiter.

To split based on a set of delimiters, use Text.by_split_any(). If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.

Argument Type Description Default
text Text The text to be iterated over in delimited chunks. -
delimiter Text An exact delimiter to use for splitting the text. ""

Return: An iterator function that returns one chunk of text at a time, separated by the given delimiter, until it runs out and returns none.

Example:

text := "one,two,three"
chunks := [chunk for chunk in text.by_split(",")]
assert chunks == ["one", "two", "three"]

Text.by_split_any

Text.by_split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> func(->Text?))

Returns an iterator function that can be used to iterate over text separated by one or more characters (grapheme clusters) from a given text of delimiters.

Splitting will occur on every place where one or more of the grapheme clusters in delimiters occurs. To split based on an exact delimiter, use Text.by_split().

Argument Type Description Default
text Text The text to be iterated over in delimited chunks. -
delimiters Text Grapheme clusters to use for splitting the text. " $\t\r\n"

Return: An iterator function that returns one chunk of text at a time, separated by the given delimiter characters, until it runs out and returns none.

Example:

text := "one,two,;,three"
chunks := [chunk for chunk in text.by_split_any(",;")]
assert chunks == ["one", "two", "three"]

Text.caseless_equals

Text.caseless_equals : func(a: Text, b: Text, language: Text = "C" -> Bool)

Checks whether two texts are equal, ignoring the casing of the letters (i.e. case-insensitive comparison).

Argument Type Description Default
a Text The first text to compare case-insensitively. -
b Text The second text to compare case-insensitively. -
language Text The ISO 639 language code for which casing rules to use. "C"

Return: yes if a and b are equal to each other, ignoring casing, otherwise no.

Example:

assert "A".caseless_equals("a") == yes

# Turkish lowercase "I" is "ı" (dotless I), not "i"
assert "I".caseless_equals("i", language="tr_TR") == no

Text.codepoint_names

Text.codepoint_names : func(text: Text -> [Text])

Returns a list of the names of each codepoint in the text.

Argument Type Description Default
text Text The text from which to extract codepoint names. -

Return: A list of codepoint names ([Text]).

Example:

assert "Amélie".codepoint_names() == [
    "LATIN CAPITAL LETTER A",
    "LATIN SMALL LETTER M",
    "LATIN SMALL LETTER E WITH ACUTE",
    "LATIN SMALL LETTER L",
    "LATIN SMALL LETTER I",
    "LATIN SMALL LETTER E",
]

Text.distance

Text.distance : func(a: Text, b: Text, language: Text = "C" -> Num)

Get an approximate distance between two texts, such that when the distance is small, the texts are similar and when the distance is large, the texts are dissimilar.

The exact distance algorithm is not specified and may be subject to change over time.

Argument Type Description Default
a Text The first text to compare. -
b Text The second text to compare. -
language Text The ISO 639 language code for which character width to use. "C"

Return: The distance between the two texts (larger means more dissimilar).

Example:

assert "hello".distance("hello") == 0
texts := &["goodbye", "hello", "hallo"]
texts.sort(func(a,b:&Text) a.distance("hello") <> b.distance("hello"))
assert texts == ["hello", "hallo", "goodbye"]

Text.ends_with

Text.ends_with : func(text: Text, suffix: Text, remainder: &Text? = none -> Bool)

Checks if the Text ends with a literal suffix text.

Argument Type Description Default
text Text The text to be searched. -
suffix Text The literal suffix text to check for. -
remainder &Text? If non-none, this value will be set to the rest of the text up to the trailing suffix. If the suffix is not found, this value will be set to the original text. none

Return: yes if the text has the target, no otherwise.

Example:

assert "hello world".ends_with("world") == yes
remainder : Text
assert "hello world".ends_with("world", &remainder) == yes
assert remainder == "hello "

Text.find

Text.find : func(text: Text, target: Text, start: Int = 1 -> Int)

Find a substring within a text and return its index, if found.

Argument Type Description Default
text Text The text to be searched. -
target Text The target text to find. -
start Int The index at which to begin searching. 1

Return: The index where the first occurrence of target appears, or none if it is not found.

Example:

assert "one two".find("one") == 1
assert "one two".find("two") == 5
assert "one two".find("three") == none
assert "one two".find("o", start=2) == 7

Text.from

Text.from : func(text: Text, first: Int -> Text)

Get a slice of the text, starting at the given position.

A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.

Argument Type Description Default
text Text The text to be sliced. -
first Int The index to begin the slice. -

Return: The text from the given grapheme cluster to the end of the text.

Example:

assert "hello".from(2) == "ello"
assert "hello".from(-2) == "lo"

Text.from_c_string

Text.from_c_string : func(str: CString -> Text)

Converts a C-style string to a Text value.

Argument Type Description Default
str CString The C-style string to be converted. -

Return: A Text value representing the C-style string.

Example:

assert Text.from_c_string(CString("Hello")) == "Hello"

Text.from_codepoint_names

Text.from_codepoint_names : func(codepoint_names: [Text] -> [Text])

Returns text that has the given codepoint names (according to the Unicode specification) as its codepoints.

The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.

Argument Type Description Default
codepoint_names [Text] The names of each codepoint in the desired text (case-insentive). -

Return: A new text with the specified codepoints after normalization has been applied. Any invalid names are ignored.

Example:

text := Text.from_codepoint_names([
    "LATIN CAPITAL LETTER A WITH RING ABOVE",
    "LATIN SMALL LETTER K",
    "LATIN SMALL LETTER E",
])
assert text == "Åke"

Text.from_utf16

Text.from_utf16 : func(bytes: [Int16] -> [Text])

Returns text that has been constructed from the given UTF16 sequence.

The text will be normalized, so the resulting text's UTF16 sequence may not exactly match the input.

Argument Type Description Default
bytes [Int16] The UTF-16 integers of the desired text. -

Return: A new text based on the input UTF16 sequence after normalization has been applied.

Example:

assert Text.from_utf16([197, 107, 101]) == "Åke"
assert Text.from_utf16([12371, 12435, 12395, 12385, 12399, 19990, 30028]) == "こんにちは世界"

Text.from_utf32

Text.from_utf32 : func(codepoints: [Int32] -> [Text])

Returns text that has been constructed from the given UTF32 codepoints.

The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.

Argument Type Description Default
codepoints [Int32] The UTF32 codepoints in the desired text. -

Return: A new text with the specified codepoints after normalization has been applied.

Example:

assert Text.from_utf32([197, 107, 101]) == "Åke"

Text.from_utf8

Text.from_utf8 : func(bytes: [Byte] -> [Text])

Returns text that has been constructed from the given UTF8 bytes.

The text will be normalized, so the resulting text's UTF8 bytes may not exactly match the input.

Argument Type Description Default
bytes [Byte] The UTF-8 bytes of the desired text. -

Return: A new text based on the input UTF8 bytes after normalization has been applied.

Example:

assert Text.from_utf8([195, 133, 107, 101]) == "Åke"

Text.has

Text.has : func(text: Text, target: Text -> Bool)

Checks if the Text contains some target text.

Argument Type Description Default
text Text The text to be searched. -
target Text The text to search for. -

Return: yes if the target text is found, no otherwise.

Example:

assert "hello world".has("wo") == yes
assert "hello world".has("xxx") == no

Text.join

Text.join : func(glue: Text, pieces: [Text] -> Text)

Joins a list of text pieces with a specified glue.

Argument Type Description Default
glue Text The text used to join the pieces. -
pieces [Text] The list of text pieces to be joined. -

Return: A single Text value with the pieces joined by the glue.

Example:

assert ", ".join(["one", "two", "three"]) == "one, two, three"

Text.left_pad

Text.left_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)

Pad some text on the left side so it reaches a target width.

Argument Type Description Default
text Text The text to pad. -
width Int The target width. -
pad Text The padding text. " "
language Text The ISO 639 language code for which character width to use. "C"

Return: Text with length at least width, with extra padding on the left as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.

Example:

assert "x".left_pad(5) == "    x"
assert "x".left_pad(5, "ABC") == "ABCAx"

Text.lines

Text.lines : func(text: Text -> [Text])

Splits the text into a list of lines of text, preserving blank lines, ignoring trailing newlines, and handling \r\n the same as \n.

Argument Type Description Default
text Text The text to be split into lines. -

Return: A list of substrings resulting from the split.

Example:

assert "one\ntwo\nthree".lines() == ["one", "two", "three"]
assert "one\ntwo\nthree\n".lines() == ["one", "two", "three"]
assert "one\ntwo\nthree\n\n".lines() == ["one", "two", "three", ""]
assert "one\r\ntwo\r\nthree\r\n".lines() == ["one", "two", "three"]
assert "".lines() == []

Text.lower

Text.lower : func(text: Text, language: Text = "C" -> Text)

Converts all characters in the text to lowercase.

Argument Type Description Default
text Text The text to be converted to lowercase. -
language Text The ISO 639 language code for which casing rules to use. "C"

Return: The lowercase version of the text.

Example:

assert "AMÉLIE".lower() == "amélie"
assert "I".lower(language="tr_TR") == "ı"

Text.matches_glob

Text.matches_glob : func(path: Text, glob: Text -> Bool)

Return whether or not the text matches the given glob.

Argument Type Description Default
path Text The text to check. -
glob Text The glob pattern to check. -

Return: Whether or not the text matches the given glob.

Example:

assert "hello world".matches_glob("h* *d")

Text.middle_pad

Text.middle_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)

Pad some text on the left and right side so it reaches a target width.

Argument Type Description Default
text Text The text to pad. -
width Int The target width. -
pad Text The padding text. " "
language Text The ISO 639 language code for which character width to use. "C"

Return: Text with length at least width, with extra padding on the left and right as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.

Example:

assert "x".middle_pad(6) == "  x   "
assert "x".middle_pad(10, "ABC") == "ABCAxABCAB"

Text.quoted

Text.quoted : func(text: Text, color: Bool = no, quotation_mark: Text = `"` -> Text)

Formats the text with quotation marks and escapes.

Argument Type Description Default
text Text The text to be quoted. -
color Bool Whether to add color formatting. no
quotation_mark Text The quotation mark to use. "

Return: The text formatted as a quoted text.

Example:

assert "one\ntwo".quoted() == "\"one\\ntwo\""

Text.repeat

Text.repeat : func(text: Text, count: Int -> Text)

Repeat some text multiple times.

Argument Type Description Default
text Text The text to repeat. -
count Int The number of times to repeat it. (Negative numbers are equivalent to zero). -

Return: The text repeated the given number of times.

Example:

assert "Abc".repeat(3) == "AbcAbcAbc"

Text.replace

Text.replace : func(text: Text, target: Text, replacement: Text -> Text)

Replaces occurrences of a target text with a replacement text.

Argument Type Description Default
text Text The text in which to perform replacements. -
target Text The target text to be replaced. -
replacement Text The text to replace the target with. -

Return: The text with occurrences of the target replaced.

Example:

assert "Hello world".replace("world", "there") == "Hello there"

Text.reversed

Text.reversed : func(text: Text -> Text)

Return a text that has the grapheme clusters in reverse order.

Argument Type Description Default
text Text The text to reverse. -

Return: A reversed version of the text.

Example:

assert "Abc".reversed() == "cbA"

Text.right_pad

Text.right_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)

Pad some text on the right side so it reaches a target width.

Argument Type Description Default
text Text The text to pad. -
width Int The target width. -
pad Text The padding text. " "
language Text The ISO 639 language code for which character width to use. "C"

Return: Text with length at least width, with extra padding on the right as needed. If pad has length greater than 1, it may be partially repeated to reach the exact desired length.

Example:

assert "x".right_pad(5) == "x    "
assert "x".right_pad(5, "ABC") == "xABCA"

Text.slice

Text.slice : func(text: Text, from: Int = 1, to: Int = -1 -> Text)

Get a slice of the text.

A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.

Argument Type Description Default
text Text The text to be sliced. -
from Int The index of the first grapheme cluster to include (1-indexed). 1
to Int The index of the last grapheme cluster to include (1-indexed). -1

Return: The text that spans the given grapheme cluster indices.

Example:

assert "hello".slice(2, 3) == "el"
assert "hello".slice(to=-2) == "hell"
assert "hello".slice(from=2) == "ello"

Text.split

Text.split : func(text: Text, delimiter: Text = "" -> [Text])

Splits the text into a list of substrings based on exact matches of a delimiter.

To split based on a set of delimiters, use Text.split_any(). If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.

Argument Type Description Default
text Text The text to be split. -
delimiter Text The delimiter used to split the text. ""

Return: A list of subtexts resulting from the split.

Example:

assert "one,two,,three".split(",") == ["one", "two", "", "three"]
assert "abc".split() == ["a", "b", "c"]

Text.split_any

Text.split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> [Text])

Splits the text into a list of substrings at one or more occurrences of a set of delimiter characters (grapheme clusters).

Splitting will occur on every place where one or more of the grapheme clusters in delimiters occurs. To split based on an exact delimiter, use Text.split().

Argument Type Description Default
text Text The text to be split. -
delimiters Text A text containing delimiters to use for splitting the text. " $\t\r\n"

Return: A list of subtexts resulting from the split.

Example:

assert "one, two,,three".split_any(", ") == ["one", "two", "three"]

Text.starts_with

Text.starts_with : func(text: Text, prefix: Text, remainder: &Text? = none -> Bool)

Checks if the Text starts with a literal prefix text.

Argument Type Description Default
text Text The text to be searched. -
prefix Text The literal prefix text to check for. -
remainder &Text? If non-none, this value will be set to the rest of the text after the prefix. If the prefix is not found, this value will be set to the original text. none

Return: yes if the text has the given prefix, no otherwise.

Example:

assert "hello world".starts_with("hello") == yes
remainder : Text
assert "hello world".starts_with("hello", &remainder) == yes
assert remainder == " world"

Text.title

Text.title : func(text: Text, language: Text = "C" -> Text)

Converts the text to title case (capitalizing the first letter of each word).

Argument Type Description Default
text Text The text to be converted to title case. -
language Text The ISO 639 language code for which casing rules to use. "C"

Return: The text in title case.

Example:

assert "amélie".title() == "Amélie"

# In Turkish, uppercase "i" is "İ"
assert "i".title(language="tr_TR") == "İ"

Text.to

Text.to : func(text: Text, last: Int -> Text)

Get a slice of the text, ending at the given position.

A negative index counts backwards from the end of the text, so -1 refers to the last cluster, -2 the second-to-last, etc. Slice ranges will be truncated to the length of the text.

Argument Type Description Default
text Text The text to be sliced. -
last Int The index of the last grapheme cluster to include (1-indexed). -

Return: The text up to and including the given grapheme cluster.

Example:

assert "goodbye".to(3) == "goo"
assert "goodbye".to(-2) == "goodby"

Text.translate

Text.translate : func(text: Text, translations: {Text:Text} -> Text)

Takes a table mapping target texts to their replacements and performs all the replacements in the table on the whole text. At each position, the first matching replacement is applied and the matching moves on to after the replacement text, so replacement text is not recursively modified. See Text.replace() for more information about replacement behavior.

Argument Type Description Default
text Text The text to be translated. -
translations {Text:Text} A table mapping from target text to its replacement. -

Return: The text with all occurrences of the targets replaced with their corresponding replacement text.

Example:

text := "A <tag> & an ampersand".translate({
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot",
    "'": "&#39;",
})
assert text == "A &lt;tag&gt; &amp; an ampersand"

Text.trim

Text.trim : func(text: Text, to_trim: Text = " $\t\r\n", left: Bool = yes, right: Bool = yes -> Text)

Trims the given characters (grapheme clusters) from the left and/or right side of the text.

Argument Type Description Default
text Text The text to be trimmed. -
to_trim Text The characters to remove from the left/right of the text. " $\t\r\n"
left Bool Whether or not to trim from the front of the text. yes
right Bool Whether or not to trim from the back of the text. yes

Return: The text without the trim characters at either end.

Example:

assert "   x y z    \n".trim() == "x y z"
assert "one,".trim(",") == "one"
assert "   xyz   ".trim(right=no) == "xyz   "

Text.upper

Text.upper : func(text: Text, language: Text = "C" -> Text)

Converts all characters in the text to uppercase.

Argument Type Description Default
text Text The text to be converted to uppercase. -
language Text The ISO 639 language code for which casing rules to use. "C"

Return: The uppercase version of the text.

Example:

assert "amélie".upper() == "AMÉLIE"

# In Turkish, uppercase "i" is "İ"
assert "i".upper(language="tr_TR") == "İ"

Text.utf16

Text.utf16 : func(text: Text -> [Int16])

Returns a list of Unicode code points for UTF16 encoding of the text.

Argument Type Description Default
text Text The text from which to extract Unicode code points. -

Return: A list of 16-bit integer Unicode code points ([Int16]).

Example:

assert "Åke".utf16() == [197, 107, 101]
assert "こんにちは世界".utf16() == [12371, 12435, 12395, 12385, 12399, 19990, 30028]

Text.utf32

Text.utf32 : func(text: Text -> [Int32])

Returns a list of Unicode code points for UTF32 encoding of the text.

Argument Type Description Default
text Text The text from which to extract Unicode code points. -

Return: A list of 32-bit integer Unicode code points ([Int32]).

Example:

assert "Amélie".utf32() == [65, 109, 233, 108, 105, 101]

Text.utf8

Text.utf8 : func(text: Text -> [Byte])

Converts a Text value to a list of bytes representing a UTF8 encoding of the text.

Argument Type Description Default
text Text The text to be converted to UTF8 bytes. -

Return: A list of bytes ([Byte]) representing the text in UTF8 encoding.

Example:

assert "Amélie".utf8() == [65, 109, 195, 169, 108, 105, 101]

Text.width

Text.width : func(text: Text -> Int)

Returns the display width of the text as seen in a terminal with appropriate font rendering. This is usually the same as the text's .length, but there are some characters like emojis that render wider than 1 cell.

This will not always be exactly accurate when your terminal's font rendering can't handle some unicode displaying correctly.

Argument Type Description Default
text Text The text whose length you want. -

Return: An integer representing the display width of the text.

Example:

assert "Amélie".width() == 6
assert "🤠".width() == 2

Text.without_prefix

Text.without_prefix : func(text: Text, prefix: Text -> Text)

Returns the text with a given prefix removed (if present).

Argument Type Description Default
text Text The text to remove the prefix from. -
prefix Text The prefix to remove. -

Return: A text without the given prefix (if present) or the unmodified text if the prefix is not present.

Example:

assert "foo:baz".without_prefix("foo:") == "baz"
assert "qux".without_prefix("foo:") == "qux"

Text.without_suffix

Text.without_suffix : func(text: Text, suffix: Text -> Text)

Returns the text with a given suffix removed (if present).

Argument Type Description Default
text Text The text to remove the suffix from. -
suffix Text The suffix to remove. -

Return: A text without the given suffix (if present) or the unmodified text if the suffix is not present.

Example:

assert "baz.foo".without_suffix(".foo") == "baz"
assert "qux".without_suffix(".foo") == "qux"

1 % API
3 # Builtins
5 # Text
6 ## Text.as_c_string
8 ```tomo
9 Text.as_c_string : func(text: Text -> CString)
10 ```
12 Converts a `Text` value to a C-style string.
14 Argument | Type | Description | Default
15 ---------|------|-------------|---------
16 text | `Text` | The text to be converted to a C-style string. | -
18 **Return:** A C-style string (`CString`) representing the text.
21 **Example:**
22 ```tomo
23 assert "Hello".as_c_string() == CString("Hello")
25 ```
26 ## Text.at
28 ```tomo
29 Text.at : func(text: Text, index: Int -> Text)
30 ```
32 Get the graphical cluster at a given index. This is similar to `str[i]` with ASCII text, but has more correct behavior for unicode text.
34 Negative indices are counted from the back of the text, so `-1` means the last cluster, `-2` means the second-to-last, and so on.
36 Argument | Type | Description | Default
37 ---------|------|-------------|---------
38 text | `Text` | The text from which to get a cluster. | -
39 index | `Int` | The index of the graphical cluster (1-indexed). | -
41 **Return:** A `Text` with the single graphical cluster at the given index.
44 **Example:**
45 ```tomo
46 assert "Amélie".at(3) == "é"
48 ```
49 ## Text.by_line
51 ```tomo
52 Text.by_line : func(text: Text -> func(->Text?))
53 ```
55 Returns an iterator function that can be used to iterate over the lines in a text.
57 This function ignores a trailing newline if there is one. If you don't want this behavior, use `text.by_split($/{1 nl}/)` instead.
59 Argument | Type | Description | Default
60 ---------|------|-------------|---------
61 text | `Text` | The text to be iterated over, line by line. | -
63 **Return:** An iterator function that returns one line at a time, until it runs out and returns `none`.
66 **Example:**
67 ```tomo
68 text := "
69 line one
70 line two
72 lines := [line for line in text.by_line()]
73 assert lines == ["line one", "line two"]
75 ```
76 ## Text.by_split
78 ```tomo
79 Text.by_split : func(text: Text, delimiter: Text = "" -> func(->Text?))
80 ```
82 Returns an iterator function that can be used to iterate over text separated by a delimiter.
84 To split based on a set of delimiters, use Text.by_split_any().
85 If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.
87 Argument | Type | Description | Default
88 ---------|------|-------------|---------
89 text | `Text` | The text to be iterated over in delimited chunks. | -
90 delimiter | `Text` | An exact delimiter to use for splitting the text. | `""`
92 **Return:** An iterator function that returns one chunk of text at a time, separated by the given delimiter, until it runs out and returns `none`.
95 **Example:**
96 ```tomo
97 text := "one,two,three"
98 chunks := [chunk for chunk in text.by_split(",")]
99 assert chunks == ["one", "two", "three"]
101 ```
102 ## Text.by_split_any
104 ```tomo
105 Text.by_split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> func(->Text?))
106 ```
108 Returns an iterator function that can be used to iterate over text separated by one or more characters (grapheme clusters) from a given text of delimiters.
110 Splitting will occur on every place where one or more of the grapheme clusters in `delimiters` occurs.
111 To split based on an exact delimiter, use Text.by_split().
113 Argument | Type | Description | Default
114 ---------|------|-------------|---------
115 text | `Text` | The text to be iterated over in delimited chunks. | -
116 delimiters | `Text` | Grapheme clusters to use for splitting the text. | `" $\t\r\n"`
118 **Return:** An iterator function that returns one chunk of text at a time, separated by the given delimiter characters, until it runs out and returns `none`.
121 **Example:**
122 ```tomo
123 text := "one,two,;,three"
124 chunks := [chunk for chunk in text.by_split_any(",;")]
125 assert chunks == ["one", "two", "three"]
127 ```
128 ## Text.caseless_equals
130 ```tomo
131 Text.caseless_equals : func(a: Text, b: Text, language: Text = "C" -> Bool)
132 ```
134 Checks whether two texts are equal, ignoring the casing of the letters (i.e. case-insensitive comparison).
136 Argument | Type | Description | Default
137 ---------|------|-------------|---------
138 a | `Text` | The first text to compare case-insensitively. | -
139 b | `Text` | The second text to compare case-insensitively. | -
140 language | `Text` | The ISO 639 language code for which casing rules to use. | `"C"`
142 **Return:** `yes` if `a` and `b` are equal to each other, ignoring casing, otherwise `no`.
145 **Example:**
146 ```tomo
147 assert "A".caseless_equals("a") == yes
149 # Turkish lowercase "I" is "ı" (dotless I), not "i"
150 assert "I".caseless_equals("i", language="tr_TR") == no
152 ```
153 ## Text.codepoint_names
155 ```tomo
156 Text.codepoint_names : func(text: Text -> [Text])
157 ```
159 Returns a list of the names of each codepoint in the text.
161 Argument | Type | Description | Default
162 ---------|------|-------------|---------
163 text | `Text` | The text from which to extract codepoint names. | -
165 **Return:** A list of codepoint names (`[Text]`).
168 **Example:**
169 ```tomo
170 assert "Amélie".codepoint_names() == [
171 "LATIN CAPITAL LETTER A",
172 "LATIN SMALL LETTER M",
173 "LATIN SMALL LETTER E WITH ACUTE",
174 "LATIN SMALL LETTER L",
175 "LATIN SMALL LETTER I",
176 "LATIN SMALL LETTER E",
179 ```
180 ## Text.distance
182 ```tomo
183 Text.distance : func(a: Text, b: Text, language: Text = "C" -> Num)
184 ```
186 Get an approximate distance between two texts, such that when the distance is small, the texts are similar and when the distance is large, the texts are dissimilar.
188 The exact distance algorithm is not specified and may be subject to change over time.
190 Argument | Type | Description | Default
191 ---------|------|-------------|---------
192 a | `Text` | The first text to compare. | -
193 b | `Text` | The second text to compare. | -
194 language | `Text` | The ISO 639 language code for which character width to use. | `"C"`
196 **Return:** The distance between the two texts (larger means more dissimilar).
199 **Example:**
200 ```tomo
201 assert "hello".distance("hello") == 0
202 texts := &["goodbye", "hello", "hallo"]
203 texts.sort(func(a,b:&Text) a.distance("hello") <> b.distance("hello"))
204 assert texts == ["hello", "hallo", "goodbye"]
206 ```
207 ## Text.ends_with
209 ```tomo
210 Text.ends_with : func(text: Text, suffix: Text, remainder: &Text? = none -> Bool)
211 ```
213 Checks if the `Text` ends with a literal suffix text.
215 Argument | Type | Description | Default
216 ---------|------|-------------|---------
217 text | `Text` | The text to be searched. | -
218 suffix | `Text` | The literal suffix text to check for. | -
219 remainder | `&Text?` | If non-none, this value will be set to the rest of the text up to the trailing suffix. If the suffix is not found, this value will be set to the original text. | `none`
221 **Return:** `yes` if the text has the target, `no` otherwise.
224 **Example:**
225 ```tomo
226 assert "hello world".ends_with("world") == yes
227 remainder : Text
228 assert "hello world".ends_with("world", &remainder) == yes
229 assert remainder == "hello "
231 ```
232 ## Text.find
234 ```tomo
235 Text.find : func(text: Text, target: Text, start: Int = 1 -> Int)
236 ```
238 Find a substring within a text and return its index, if found.
240 Argument | Type | Description | Default
241 ---------|------|-------------|---------
242 text | `Text` | The text to be searched. | -
243 target | `Text` | The target text to find. | -
244 start | `Int` | The index at which to begin searching. | `1`
246 **Return:** The index where the first occurrence of `target` appears, or `none` if it is not found.
249 **Example:**
250 ```tomo
251 assert "one two".find("one") == 1
252 assert "one two".find("two") == 5
253 assert "one two".find("three") == none
254 assert "one two".find("o", start=2) == 7
256 ```
257 ## Text.from
259 ```tomo
260 Text.from : func(text: Text, first: Int -> Text)
261 ```
263 Get a slice of the text, starting at the given position.
265 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.
267 Argument | Type | Description | Default
268 ---------|------|-------------|---------
269 text | `Text` | The text to be sliced. | -
270 first | `Int` | The index to begin the slice. | -
272 **Return:** The text from the given grapheme cluster to the end of the text.
275 **Example:**
276 ```tomo
277 assert "hello".from(2) == "ello"
278 assert "hello".from(-2) == "lo"
280 ```
281 ## Text.from_c_string
283 ```tomo
284 Text.from_c_string : func(str: CString -> Text)
285 ```
287 Converts a C-style string to a `Text` value.
289 Argument | Type | Description | Default
290 ---------|------|-------------|---------
291 str | `CString` | The C-style string to be converted. | -
293 **Return:** A `Text` value representing the C-style string.
296 **Example:**
297 ```tomo
298 assert Text.from_c_string(CString("Hello")) == "Hello"
300 ```
301 ## Text.from_codepoint_names
303 ```tomo
304 Text.from_codepoint_names : func(codepoint_names: [Text] -> [Text])
305 ```
307 Returns text that has the given codepoint names (according to the Unicode specification) as its codepoints.
309 The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.
311 Argument | Type | Description | Default
312 ---------|------|-------------|---------
313 codepoint_names | `[Text]` | The names of each codepoint in the desired text (case-insentive). | -
315 **Return:** A new text with the specified codepoints after normalization has been applied. Any invalid names are ignored.
318 **Example:**
319 ```tomo
320 text := Text.from_codepoint_names([
321 "LATIN CAPITAL LETTER A WITH RING ABOVE",
322 "LATIN SMALL LETTER K",
323 "LATIN SMALL LETTER E",
325 assert text == "Åke"
327 ```
328 ## Text.from_utf16
330 ```tomo
331 Text.from_utf16 : func(bytes: [Int16] -> [Text])
332 ```
334 Returns text that has been constructed from the given UTF16 sequence.
336 The text will be normalized, so the resulting text's UTF16 sequence may not exactly match the input.
338 Argument | Type | Description | Default
339 ---------|------|-------------|---------
340 bytes | `[Int16]` | The UTF-16 integers of the desired text. | -
342 **Return:** A new text based on the input UTF16 sequence after normalization has been applied.
345 **Example:**
346 ```tomo
347 assert Text.from_utf16([197, 107, 101]) == "Åke"
348 assert Text.from_utf16([12371, 12435, 12395, 12385, 12399, 19990, 30028]) == "こんにちは世界"
350 ```
351 ## Text.from_utf32
353 ```tomo
354 Text.from_utf32 : func(codepoints: [Int32] -> [Text])
355 ```
357 Returns text that has been constructed from the given UTF32 codepoints.
359 The text will be normalized, so the resulting text's codepoints may not exactly match the input codepoints.
361 Argument | Type | Description | Default
362 ---------|------|-------------|---------
363 codepoints | `[Int32]` | The UTF32 codepoints in the desired text. | -
365 **Return:** A new text with the specified codepoints after normalization has been applied.
368 **Example:**
369 ```tomo
370 assert Text.from_utf32([197, 107, 101]) == "Åke"
372 ```
373 ## Text.from_utf8
375 ```tomo
376 Text.from_utf8 : func(bytes: [Byte] -> [Text])
377 ```
379 Returns text that has been constructed from the given UTF8 bytes.
381 The text will be normalized, so the resulting text's UTF8 bytes may not exactly match the input.
383 Argument | Type | Description | Default
384 ---------|------|-------------|---------
385 bytes | `[Byte]` | The UTF-8 bytes of the desired text. | -
387 **Return:** A new text based on the input UTF8 bytes after normalization has been applied.
390 **Example:**
391 ```tomo
392 assert Text.from_utf8([195, 133, 107, 101]) == "Åke"
394 ```
395 ## Text.has
397 ```tomo
398 Text.has : func(text: Text, target: Text -> Bool)
399 ```
401 Checks if the `Text` contains some target text.
403 Argument | Type | Description | Default
404 ---------|------|-------------|---------
405 text | `Text` | The text to be searched. | -
406 target | `Text` | The text to search for. | -
408 **Return:** `yes` if the target text is found, `no` otherwise.
411 **Example:**
412 ```tomo
413 assert "hello world".has("wo") == yes
414 assert "hello world".has("xxx") == no
416 ```
417 ## Text.join
419 ```tomo
420 Text.join : func(glue: Text, pieces: [Text] -> Text)
421 ```
423 Joins a list of text pieces with a specified glue.
425 Argument | Type | Description | Default
426 ---------|------|-------------|---------
427 glue | `Text` | The text used to join the pieces. | -
428 pieces | `[Text]` | The list of text pieces to be joined. | -
430 **Return:** A single `Text` value with the pieces joined by the glue.
433 **Example:**
434 ```tomo
435 assert ", ".join(["one", "two", "three"]) == "one, two, three"
437 ```
438 ## Text.left_pad
440 ```tomo
441 Text.left_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
442 ```
444 Pad some text on the left side so it reaches a target width.
446 Argument | Type | Description | Default
447 ---------|------|-------------|---------
448 text | `Text` | The text to pad. | -
449 width | `Int` | The target width. | -
450 pad | `Text` | The padding text. | `" "`
451 language | `Text` | The ISO 639 language code for which character width to use. | `"C"`
453 **Return:** Text with length at least `width`, with extra padding on the left as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.
456 **Example:**
457 ```tomo
458 assert "x".left_pad(5) == " x"
459 assert "x".left_pad(5, "ABC") == "ABCAx"
461 ```
462 ## Text.lines
464 ```tomo
465 Text.lines : func(text: Text -> [Text])
466 ```
468 Splits the text into a list of lines of text, preserving blank lines, ignoring trailing newlines, and handling `\r\n` the same as `\n`.
470 Argument | Type | Description | Default
471 ---------|------|-------------|---------
472 text | `Text` | The text to be split into lines. | -
474 **Return:** A list of substrings resulting from the split.
477 **Example:**
478 ```tomo
479 assert "one\ntwo\nthree".lines() == ["one", "two", "three"]
480 assert "one\ntwo\nthree\n".lines() == ["one", "two", "three"]
481 assert "one\ntwo\nthree\n\n".lines() == ["one", "two", "three", ""]
482 assert "one\r\ntwo\r\nthree\r\n".lines() == ["one", "two", "three"]
483 assert "".lines() == []
485 ```
486 ## Text.lower
488 ```tomo
489 Text.lower : func(text: Text, language: Text = "C" -> Text)
490 ```
492 Converts all characters in the text to lowercase.
494 Argument | Type | Description | Default
495 ---------|------|-------------|---------
496 text | `Text` | The text to be converted to lowercase. | -
497 language | `Text` | The ISO 639 language code for which casing rules to use. | `"C"`
499 **Return:** The lowercase version of the text.
502 **Example:**
503 ```tomo
504 assert "AMÉLIE".lower() == "amélie"
505 assert "I".lower(language="tr_TR") == "ı"
507 ```
508 ## Text.matches_glob
510 ```tomo
511 Text.matches_glob : func(path: Text, glob: Text -> Bool)
512 ```
514 Return whether or not the text matches the given glob.
516 Argument | Type | Description | Default
517 ---------|------|-------------|---------
518 path | `Text` | The text to check. | -
519 glob | `Text` | The glob pattern to check. | -
521 **Return:** Whether or not the text matches the given glob.
524 **Example:**
525 ```tomo
526 assert "hello world".matches_glob("h* *d")
528 ```
529 ## Text.middle_pad
531 ```tomo
532 Text.middle_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
533 ```
535 Pad some text on the left and right side so it reaches a target width.
537 Argument | Type | Description | Default
538 ---------|------|-------------|---------
539 text | `Text` | The text to pad. | -
540 width | `Int` | The target width. | -
541 pad | `Text` | The padding text. | `" "`
542 language | `Text` | The ISO 639 language code for which character width to use. | `"C"`
544 **Return:** Text with length at least `width`, with extra padding on the left and right as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.
547 **Example:**
548 ```tomo
549 assert "x".middle_pad(6) == " x "
550 assert "x".middle_pad(10, "ABC") == "ABCAxABCAB"
552 ```
553 ## Text.quoted
555 ```tomo
556 Text.quoted : func(text: Text, color: Bool = no, quotation_mark: Text = `"` -> Text)
557 ```
559 Formats the text with quotation marks and escapes.
561 Argument | Type | Description | Default
562 ---------|------|-------------|---------
563 text | `Text` | The text to be quoted. | -
564 color | `Bool` | Whether to add color formatting. | `no`
565 quotation_mark | `Text` | The quotation mark to use. | ``"``
567 **Return:** The text formatted as a quoted text.
570 **Example:**
571 ```tomo
572 assert "one\ntwo".quoted() == "\"one\\ntwo\""
574 ```
575 ## Text.repeat
577 ```tomo
578 Text.repeat : func(text: Text, count: Int -> Text)
579 ```
581 Repeat some text multiple times.
583 Argument | Type | Description | Default
584 ---------|------|-------------|---------
585 text | `Text` | The text to repeat. | -
586 count | `Int` | The number of times to repeat it. (Negative numbers are equivalent to zero). | -
588 **Return:** The text repeated the given number of times.
591 **Example:**
592 ```tomo
593 assert "Abc".repeat(3) == "AbcAbcAbc"
595 ```
596 ## Text.replace
598 ```tomo
599 Text.replace : func(text: Text, target: Text, replacement: Text -> Text)
600 ```
602 Replaces occurrences of a target text with a replacement text.
604 Argument | Type | Description | Default
605 ---------|------|-------------|---------
606 text | `Text` | The text in which to perform replacements. | -
607 target | `Text` | The target text to be replaced. | -
608 replacement | `Text` | The text to replace the target with. | -
610 **Return:** The text with occurrences of the target replaced.
613 **Example:**
614 ```tomo
615 assert "Hello world".replace("world", "there") == "Hello there"
617 ```
618 ## Text.reversed
620 ```tomo
621 Text.reversed : func(text: Text -> Text)
622 ```
624 Return a text that has the grapheme clusters in reverse order.
626 Argument | Type | Description | Default
627 ---------|------|-------------|---------
628 text | `Text` | The text to reverse. | -
630 **Return:** A reversed version of the text.
633 **Example:**
634 ```tomo
635 assert "Abc".reversed() == "cbA"
637 ```
638 ## Text.right_pad
640 ```tomo
641 Text.right_pad : func(text: Text, width: Int, pad: Text = " ", language: Text = "C" -> Text)
642 ```
644 Pad some text on the right side so it reaches a target width.
646 Argument | Type | Description | Default
647 ---------|------|-------------|---------
648 text | `Text` | The text to pad. | -
649 width | `Int` | The target width. | -
650 pad | `Text` | The padding text. | `" "`
651 language | `Text` | The ISO 639 language code for which character width to use. | `"C"`
653 **Return:** Text with length at least `width`, with extra padding on the right as needed. If `pad` has length greater than 1, it may be partially repeated to reach the exact desired length.
656 **Example:**
657 ```tomo
658 assert "x".right_pad(5) == "x "
659 assert "x".right_pad(5, "ABC") == "xABCA"
661 ```
662 ## Text.slice
664 ```tomo
665 Text.slice : func(text: Text, from: Int = 1, to: Int = -1 -> Text)
666 ```
668 Get a slice of the text.
670 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.
672 Argument | Type | Description | Default
673 ---------|------|-------------|---------
674 text | `Text` | The text to be sliced. | -
675 from | `Int` | The index of the first grapheme cluster to include (1-indexed). | `1`
676 to | `Int` | The index of the last grapheme cluster to include (1-indexed). | `-1`
678 **Return:** The text that spans the given grapheme cluster indices.
681 **Example:**
682 ```tomo
683 assert "hello".slice(2, 3) == "el"
684 assert "hello".slice(to=-2) == "hell"
685 assert "hello".slice(from=2) == "ello"
687 ```
688 ## Text.split
690 ```tomo
691 Text.split : func(text: Text, delimiter: Text = "" -> [Text])
692 ```
694 Splits the text into a list of substrings based on exact matches of a delimiter.
696 To split based on a set of delimiters, use Text.split_any().
697 If an empty text is given as the delimiter, then each split will be the graphical clusters of the text.
699 Argument | Type | Description | Default
700 ---------|------|-------------|---------
701 text | `Text` | The text to be split. | -
702 delimiter | `Text` | The delimiter used to split the text. | `""`
704 **Return:** A list of subtexts resulting from the split.
707 **Example:**
708 ```tomo
709 assert "one,two,,three".split(",") == ["one", "two", "", "three"]
710 assert "abc".split() == ["a", "b", "c"]
712 ```
713 ## Text.split_any
715 ```tomo
716 Text.split_any : func(text: Text, delimiters: Text = " $\t\r\n" -> [Text])
717 ```
719 Splits the text into a list of substrings at one or more occurrences of a set of delimiter characters (grapheme clusters).
721 Splitting will occur on every place where one or more of the grapheme clusters in `delimiters` occurs.
722 To split based on an exact delimiter, use Text.split().
724 Argument | Type | Description | Default
725 ---------|------|-------------|---------
726 text | `Text` | The text to be split. | -
727 delimiters | `Text` | A text containing delimiters to use for splitting the text. | `" $\t\r\n"`
729 **Return:** A list of subtexts resulting from the split.
732 **Example:**
733 ```tomo
734 assert "one, two,,three".split_any(", ") == ["one", "two", "three"]
736 ```
737 ## Text.starts_with
739 ```tomo
740 Text.starts_with : func(text: Text, prefix: Text, remainder: &Text? = none -> Bool)
741 ```
743 Checks if the `Text` starts with a literal prefix text.
745 Argument | Type | Description | Default
746 ---------|------|-------------|---------
747 text | `Text` | The text to be searched. | -
748 prefix | `Text` | The literal prefix text to check for. | -
749 remainder | `&Text?` | If non-none, this value will be set to the rest of the text after the prefix. If the prefix is not found, this value will be set to the original text. | `none`
751 **Return:** `yes` if the text has the given prefix, `no` otherwise.
754 **Example:**
755 ```tomo
756 assert "hello world".starts_with("hello") == yes
757 remainder : Text
758 assert "hello world".starts_with("hello", &remainder) == yes
759 assert remainder == " world"
761 ```
762 ## Text.title
764 ```tomo
765 Text.title : func(text: Text, language: Text = "C" -> Text)
766 ```
768 Converts the text to title case (capitalizing the first letter of each word).
770 Argument | Type | Description | Default
771 ---------|------|-------------|---------
772 text | `Text` | The text to be converted to title case. | -
773 language | `Text` | The ISO 639 language code for which casing rules to use. | `"C"`
775 **Return:** The text in title case.
778 **Example:**
779 ```tomo
780 assert "amélie".title() == "Amélie"
782 # In Turkish, uppercase "i" is "İ"
783 assert "i".title(language="tr_TR") == "İ"
785 ```
786 ## Text.to
788 ```tomo
789 Text.to : func(text: Text, last: Int -> Text)
790 ```
792 Get a slice of the text, ending at the given position.
794 A negative index counts backwards from the end of the text, so `-1` refers to the last cluster, `-2` the second-to-last, etc. Slice ranges will be truncated to the length of the text.
796 Argument | Type | Description | Default
797 ---------|------|-------------|---------
798 text | `Text` | The text to be sliced. | -
799 last | `Int` | The index of the last grapheme cluster to include (1-indexed). | -
801 **Return:** The text up to and including the given grapheme cluster.
804 **Example:**
805 ```tomo
806 assert "goodbye".to(3) == "goo"
807 assert "goodbye".to(-2) == "goodby"
809 ```
810 ## Text.translate
812 ```tomo
813 Text.translate : func(text: Text, translations: {Text:Text} -> Text)
814 ```
816 Takes a table mapping target texts to their replacements and performs all the replacements in the table on the whole text. At each position, the first matching replacement is applied and the matching moves on to *after* the replacement text, so replacement text is not recursively modified. See Text.replace() for more information about replacement behavior.
818 Argument | Type | Description | Default
819 ---------|------|-------------|---------
820 text | `Text` | The text to be translated. | -
821 translations | `{Text:Text}` | A table mapping from target text to its replacement. | -
823 **Return:** The text with all occurrences of the targets replaced with their corresponding replacement text.
826 **Example:**
827 ```tomo
828 text := "A <tag> & an ampersand".translate({
829 "&": "&amp;",
830 "<": "&lt;",
831 ">": "&gt;",
832 '"': "&quot",
833 "'": "&#39;",
835 assert text == "A &lt;tag&gt; &amp; an ampersand"
837 ```
838 ## Text.trim
840 ```tomo
841 Text.trim : func(text: Text, to_trim: Text = " $\t\r\n", left: Bool = yes, right: Bool = yes -> Text)
842 ```
844 Trims the given characters (grapheme clusters) from the left and/or right side of the text.
846 Argument | Type | Description | Default
847 ---------|------|-------------|---------
848 text | `Text` | The text to be trimmed. | -
849 to_trim | `Text` | The characters to remove from the left/right of the text. | `" $\t\r\n"`
850 left | `Bool` | Whether or not to trim from the front of the text. | `yes`
851 right | `Bool` | Whether or not to trim from the back of the text. | `yes`
853 **Return:** The text without the trim characters at either end.
856 **Example:**
857 ```tomo
858 assert " x y z \n".trim() == "x y z"
859 assert "one,".trim(",") == "one"
860 assert " xyz ".trim(right=no) == "xyz "
862 ```
863 ## Text.upper
865 ```tomo
866 Text.upper : func(text: Text, language: Text = "C" -> Text)
867 ```
869 Converts all characters in the text to uppercase.
871 Argument | Type | Description | Default
872 ---------|------|-------------|---------
873 text | `Text` | The text to be converted to uppercase. | -
874 language | `Text` | The ISO 639 language code for which casing rules to use. | `"C"`
876 **Return:** The uppercase version of the text.
879 **Example:**
880 ```tomo
881 assert "amélie".upper() == "AMÉLIE"
883 # In Turkish, uppercase "i" is "İ"
884 assert "i".upper(language="tr_TR") == "İ"
886 ```
887 ## Text.utf16
889 ```tomo
890 Text.utf16 : func(text: Text -> [Int16])
891 ```
893 Returns a list of Unicode code points for UTF16 encoding of the text.
895 Argument | Type | Description | Default
896 ---------|------|-------------|---------
897 text | `Text` | The text from which to extract Unicode code points. | -
899 **Return:** A list of 16-bit integer Unicode code points (`[Int16]`).
902 **Example:**
903 ```tomo
904 assert "Åke".utf16() == [197, 107, 101]
905 assert "こんにちは世界".utf16() == [12371, 12435, 12395, 12385, 12399, 19990, 30028]
907 ```
908 ## Text.utf32
910 ```tomo
911 Text.utf32 : func(text: Text -> [Int32])
912 ```
914 Returns a list of Unicode code points for UTF32 encoding of the text.
916 Argument | Type | Description | Default
917 ---------|------|-------------|---------
918 text | `Text` | The text from which to extract Unicode code points. | -
920 **Return:** A list of 32-bit integer Unicode code points (`[Int32]`).
923 **Example:**
924 ```tomo
925 assert "Amélie".utf32() == [65, 109, 233, 108, 105, 101]
927 ```
928 ## Text.utf8
930 ```tomo
931 Text.utf8 : func(text: Text -> [Byte])
932 ```
934 Converts a `Text` value to a list of bytes representing a UTF8 encoding of the text.
936 Argument | Type | Description | Default
937 ---------|------|-------------|---------
938 text | `Text` | The text to be converted to UTF8 bytes. | -
940 **Return:** A list of bytes (`[Byte]`) representing the text in UTF8 encoding.
943 **Example:**
944 ```tomo
945 assert "Amélie".utf8() == [65, 109, 195, 169, 108, 105, 101]
947 ```
948 ## Text.width
950 ```tomo
951 Text.width : func(text: Text -> Int)
952 ```
954 Returns the display width of the text as seen in a terminal with appropriate font rendering. This is usually the same as the text's `.length`, but there are some characters like emojis that render wider than 1 cell.
956 This will not always be exactly accurate when your terminal's font rendering can't handle some unicode displaying correctly.
958 Argument | Type | Description | Default
959 ---------|------|-------------|---------
960 text | `Text` | The text whose length you want. | -
962 **Return:** An integer representing the display width of the text.
965 **Example:**
966 ```tomo
967 assert "Amélie".width() == 6
968 assert "🤠".width() == 2
970 ```
971 ## Text.without_prefix
973 ```tomo
974 Text.without_prefix : func(text: Text, prefix: Text -> Text)
975 ```
977 Returns the text with a given prefix removed (if present).
979 Argument | Type | Description | Default
980 ---------|------|-------------|---------
981 text | `Text` | The text to remove the prefix from. | -
982 prefix | `Text` | The prefix to remove. | -
984 **Return:** A text without the given prefix (if present) or the unmodified text if the prefix is not present.
987 **Example:**
988 ```tomo
989 assert "foo:baz".without_prefix("foo:") == "baz"
990 assert "qux".without_prefix("foo:") == "qux"
992 ```
993 ## Text.without_suffix
995 ```tomo
996 Text.without_suffix : func(text: Text, suffix: Text -> Text)
997 ```
999 Returns the text with a given suffix removed (if present).
1001 Argument | Type | Description | Default
1002 ---------|------|-------------|---------
1003 text | `Text` | The text to remove the suffix from. | -
1004 suffix | `Text` | The suffix to remove. | -
1006 **Return:** A text without the given suffix (if present) or the unmodified text if the suffix is not present.
1009 **Example:**
1010 ```tomo
1011 assert "baz.foo".without_suffix(".foo") == "baz"
1012 assert "qux".without_suffix(".foo") == "qux"
1014 ```