Add text padding functions: :left_pad(), :right_pad(), :middle_pad()
This commit is contained in:
parent
9b485be020
commit
2ebe7893fe
85
docs/text.md
85
docs/text.md
@ -290,6 +290,9 @@ pattern documentation](patterns.md) for more details.
|
||||
- [`func has(text: Text, pattern: Pattern -> Bool)`](#has)
|
||||
- [`func join(glue: Text, pieces: [Text] -> Text)`](#join)
|
||||
- [`func split(text: Text -> [Text])`](#lines)
|
||||
- [`func middle_pad(text: Text, width: Int, pad: Text = " " -> Text)`](#middle_pad)
|
||||
- [`func left_pad(text: Text, width: Int, pad: Text = " " -> Text)`](#left_pad)
|
||||
- [`func lines(text: Text, pattern: Pattern = "" -> [Text])`](#lines)
|
||||
- [`func lower(text: Text, language: Text = "C" -> Text)`](#lower)
|
||||
- [`func map(text: Text, pattern: Pattern, fn: func(text:Match)->Text -> Text, recursive: Bool = yes)`](#map)
|
||||
- [`func matches(text: Text, pattern: Pattern -> [Text])`](#matches)
|
||||
@ -298,8 +301,8 @@ pattern documentation](patterns.md) for more details.
|
||||
- [`func replace(text: Text, pattern: Pattern, replacement: Text, backref: Pattern = $/\/, recursive: Bool = yes -> Text)`](#replace)
|
||||
- [`func replace_all(replacements:{Pattern,Text}, backref: Pattern = $/\/, recursive: Bool = yes -> Text)`](#replace_all)
|
||||
- [`func reversed(text: Text -> Text)`](#reversed)
|
||||
- [`func right_pad(text: Text, width: Int, pad: Text = " " -> Text)`](#right_pad)
|
||||
- [`func slice(text: Text, from: Int = 1, to: Int = -1 -> Text)`](#slice)
|
||||
- [`func split(text: Text, pattern: Pattern = "" -> [Text])`](#split)
|
||||
- [`func starts_with(text: Text, prefix: Text -> Bool)`](#starts_with)
|
||||
- [`func title(text: Text, language: Text = "C" -> Text)`](#title)
|
||||
- [`func to(text: Text, last: Int -> Text)`](#to)
|
||||
@ -777,12 +780,64 @@ A single `Text` value with the pieces joined by the glue.
|
||||
|
||||
---
|
||||
|
||||
### `middle_pad`
|
||||
Pad some text on the left and right side so it reaches a target width.
|
||||
|
||||
```tomo
|
||||
func middle_pad(text: Text, width: Int, pad: Text = " " -> Text)
|
||||
```
|
||||
|
||||
- `text`: The text to pad.
|
||||
- `width`: The target width.
|
||||
- `pad`: The padding text (default: `" "`).
|
||||
|
||||
**Returns:**
|
||||
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:**
|
||||
```tomo
|
||||
>> "x":middle_pad(6)
|
||||
= " x "
|
||||
>> "x":middle_pad(10, "ABC")
|
||||
= "ABCAxABCAB"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `left_pad`
|
||||
Pad some text on the left side so it reaches a target width.
|
||||
|
||||
```tomo
|
||||
func left_pad(text: Text, width: Int, pad: Text = " " -> Text)
|
||||
```
|
||||
|
||||
- `text`: The text to pad.
|
||||
- `width`: The target width.
|
||||
- `pad`: The padding text (default: `" "`).
|
||||
|
||||
**Returns:**
|
||||
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:**
|
||||
```tomo
|
||||
>> "x":left_pad(5)
|
||||
= " x"
|
||||
>> "x":left_pad(5, "ABC")
|
||||
= "ABCAx"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `lines`
|
||||
Splits the text into an array of lines of text, preserving blank lines,
|
||||
ignoring trailing newlines, and handling `\r\n` the same as `\n`.
|
||||
|
||||
```tomo
|
||||
func split(text: Text -> [Text])
|
||||
func lines(text: Text -> [Text])
|
||||
```
|
||||
|
||||
- `text`: The text to be split into lines.
|
||||
@ -1052,6 +1107,32 @@ A reversed version of the text.
|
||||
|
||||
---
|
||||
|
||||
### `right_pad`
|
||||
Pad some text on the right side so it reaches a target width.
|
||||
|
||||
```tomo
|
||||
func right_pad(text: Text, width: Int, pad: Text = " " -> Text)
|
||||
```
|
||||
|
||||
- `text`: The text to pad.
|
||||
- `width`: The target width.
|
||||
- `pad`: The padding text (default: `" "`).
|
||||
|
||||
**Returns:**
|
||||
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:**
|
||||
```tomo
|
||||
>> "x":right_pad(5)
|
||||
= "x "
|
||||
>> "x":right_pad(5, "ABC")
|
||||
= "xABCA"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `slice`
|
||||
Get a slice of the text.
|
||||
|
||||
|
@ -409,15 +409,18 @@ env_t *new_compilation_unit(CORD libname)
|
||||
{"without_escaping", "Path$cleanup", "func(text:Text -> Path)"},
|
||||
{"has", "Text$has", "func(text:Text, pattern:Pattern -> Bool)"},
|
||||
{"join", "Text$join", "func(glue:Text, pieces:[Text] -> Text)"},
|
||||
{"left_pad", "Text$left_pad", "func(text:Text, count:Int, pad=\" \" -> Text)"},
|
||||
{"lines", "Text$lines", "func(text:Text -> [Text])"},
|
||||
{"lower", "Text$lower", "func(text:Text, language=\"C\" -> Text)"},
|
||||
{"map", "Text$map", "func(text:Text, pattern:Pattern, fn:func(match:Match -> Text), recursive=yes -> Text)"},
|
||||
{"matches", "Text$matches", "func(text:Text, pattern:Pattern -> [Text]?)"},
|
||||
{"middle_pad", "Text$middle_pad", "func(text:Text, count:Int, pad=\" \" -> Text)"},
|
||||
{"quoted", "Text$quoted", "func(text:Text, color=no -> Text)"},
|
||||
{"repeat", "Text$repeat", "func(text:Text, count:Int -> Text)"},
|
||||
{"replace", "Text$replace", "func(text:Text, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes -> Text)"},
|
||||
{"replace_all", "Text$replace_all", "func(text:Text, replacements:{Pattern,Text}, backref=$/\\/, recursive=yes -> Text)"},
|
||||
{"reversed", "Text$reversed", "func(text:Text -> Text)"},
|
||||
{"right_pad", "Text$right_pad", "func(text:Text, count:Int, pad=\" \" -> Text)"},
|
||||
{"slice", "Text$slice", "func(text:Text, from=1, to=-1 -> Text)"},
|
||||
{"split", "Text$split", "func(text:Text, pattern=$Pattern'' -> [Text])"},
|
||||
{"starts_with", "Text$starts_with", "func(text,prefix:Text -> Bool)"},
|
||||
|
@ -512,6 +512,47 @@ public Text_t Text$repeat(Text_t text, Int_t count)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Text_t Text$repeat_to_length(Text_t to_repeat, int64_t length)
|
||||
{
|
||||
if (length <= 0)
|
||||
return EMPTY_TEXT;
|
||||
|
||||
Text_t repeated = EMPTY_TEXT;
|
||||
while (repeated.length + to_repeat.length <= length)
|
||||
repeated = concat2(repeated, to_repeat);
|
||||
|
||||
if (repeated.length < length)
|
||||
repeated = concat2(repeated, Text$slice(to_repeat, I_small(1), I(length - repeated.length)));
|
||||
|
||||
assert(repeated.length == length);
|
||||
return repeated;
|
||||
}
|
||||
|
||||
public Text_t Text$left_pad(Text_t text, Int_t count, Text_t padding)
|
||||
{
|
||||
if (padding.length == 0)
|
||||
fail("Cannot pad with an empty text!");
|
||||
|
||||
return concat2(Text$repeat_to_length(padding, Int64$from_int(count, false) - text.length), text);
|
||||
}
|
||||
|
||||
public Text_t Text$right_pad(Text_t text, Int_t count, Text_t padding)
|
||||
{
|
||||
if (padding.length == 0)
|
||||
fail("Cannot pad with an empty text!");
|
||||
|
||||
return concat2(text, Text$repeat_to_length(padding, Int64$from_int(count, false) - text.length));
|
||||
}
|
||||
|
||||
public Text_t Text$middle_pad(Text_t text, Int_t count, Text_t padding)
|
||||
{
|
||||
if (padding.length == 0)
|
||||
fail("Cannot pad with an empty text!");
|
||||
|
||||
int64_t needed = Int64$from_int(count, false) - text.length;
|
||||
return Texts(Text$repeat_to_length(padding, needed/2), text, Text$repeat_to_length(padding, (needed+1)/2));
|
||||
}
|
||||
|
||||
public Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int)
|
||||
{
|
||||
int64_t first = Int64$from_int(first_int, false);
|
||||
|
@ -68,6 +68,9 @@ Array_t Text$lines(Text_t text);
|
||||
Closure_t Text$by_line(Text_t text);
|
||||
Text_t Text$join(Text_t glue, Array_t pieces);
|
||||
Text_t Text$repeat(Text_t text, Int_t count);
|
||||
Text_t Text$left_pad(Text_t text, Int_t count, Text_t padding);
|
||||
Text_t Text$right_pad(Text_t text, Int_t count, Text_t padding);
|
||||
Text_t Text$middle_pad(Text_t text, Int_t count, Text_t padding);
|
||||
int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index);
|
||||
uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index);
|
||||
void Text$serialize(const void *obj, FILE *out, Table_t *, const TypeInfo_t *);
|
||||
|
13
test/text.tm
13
test/text.tm
@ -361,3 +361,16 @@ func main():
|
||||
= 1
|
||||
>> concat4 == final
|
||||
= yes
|
||||
|
||||
>> "x":left_pad(5)
|
||||
= " x"
|
||||
>> "x":right_pad(5)
|
||||
= "x "
|
||||
>> "x":middle_pad(5)
|
||||
= " x "
|
||||
>> "1234":left_pad(8, "XYZ")
|
||||
= "XYZX1234" : Text
|
||||
>> "1234":right_pad(8, "XYZ")
|
||||
= "1234XYZX" : Text
|
||||
>> "1234":middle_pad(9, "XYZ")
|
||||
= "XY1234XYZ" : Text
|
||||
|
Loading…
Reference in New Issue
Block a user