Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Text.insert function #3311

Merged
merged 7 commits into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
- [Implemented initial `Table.group_by` function on Standard.Table][3305]
- [Implemented `Text.pad` and `Text.trim`][3309]
- [Updated `Text.repeat` and added `*` operator shorthand][3310]
- [Implemented new `Text.insert` method][3311]

[debug-shortcuts]:
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
Expand Down Expand Up @@ -94,6 +95,7 @@
[3305]: https://github.com/enso-org/enso/pull/3305
[3309]: https://github.com/enso-org/enso/pull/3309
[3310]: https://github.com/enso-org/enso/pull/3310
[3311]: https://github.com/enso-org/enso/pull/3311

#### Enso Compiler

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,44 @@ Text.is_empty = this == ""
Text.not_empty : Boolean
Text.not_empty = this.is_empty.not

## Inserts text value at the specified index.

Arguments:
- index: The position (0-based) in the text to inset text at.
When the index is non-negative the text is inserted before the
specified position.
When the index is negative, then the characters are counted from
the end of the text and the text is inserted after the specified
position, i.e. -1 will insert the text after the last character.

! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.

> Example
Insert text at a specified index

"Hello World!".insert 0 " Cruel" == " CruelHello World!"
"Hello World!".insert 5 " Cruel" == "Hello Cruel World!"
"Hello World!".insert -1 " Cruel" == "Hello World! Cruel"
hubertp marked this conversation as resolved.
Show resolved Hide resolved
Text.insert : Integer -> Text -> Text ! Index_Out_Of_Bounds_Error
Text.insert index that =
len = this.length
idx = if index < 0 then len + index + 1 else index
if (idx < 0) || (idx > len) then Error.throw (Index_Out_Of_Bounds_Error index len) else
if idx == 0 then that + this else
if idx == len then this + that else
pre = this.take (Range 0 idx)
post = this.take (Range idx len)
pre + that + post

## Returns if a character from the text at the specified index (0-based) is a
digit (0-9).

Arguments:
- index: The location in the text to get the character from. The
index is also allowed be negative, then the characters are
index is also allowed to be negative, then the characters are
counted from the end of the text, i.e. -1 will correspond to the
last character.

Expand Down
29 changes: 29 additions & 0 deletions test/Tests/src/Data/Text_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ spec =
things like decimal points (1.0314e3) and other language scripts as well
건반(Korean).
sentence_words = ['I', 'have', 'a', 'very', 'long', 'block', 'of', 'text', ',', 'here', '.', 'It', 'goes', 'on', 'and', 'on', ',', 'containing', 'things', 'like', 'decimal', 'points', '(', '1.0314e3', ')', 'and', 'other', 'language', 'scripts', 'as', 'well', '건반', '(', 'Korean', ')', '.']
hello_world = 'Hello World!'
cruel = ' Cruel'
hubertp marked this conversation as resolved.
Show resolved Hide resolved

Test.specify "should allow naive length computation over grapheme clusters" <|
kshi.length . should_equal 1
Expand Down Expand Up @@ -339,6 +341,33 @@ spec =
kshi_chars = [2325, 2381, 2359, 2367]
Text.from_utf_16 kshi_chars . should_equal kshi

Test.specify "should insert text at a positive index position" <|
hubertp marked this conversation as resolved.
Show resolved Hide resolved
hello_world.insert 0 cruel . should_equal " CruelHello World!"
hello_world.insert 5 cruel . should_equal "Hello Cruel World!"
hello_world.insert (hello_world.length - 1) cruel . should_equal "Hello World Cruel!"
hello_world.insert hello_world.length cruel . should_equal "Hello World! Cruel"
txt = kshi + facepalm + accent_1
txt.insert 1 cruel . should_equal (kshi + cruel + facepalm + accent_1)
txt.insert 3 cruel . should_equal (kshi + facepalm + accent_1 + cruel)
hubertp marked this conversation as resolved.
Show resolved Hide resolved

Test.specify "should report Index_Out_Of_Bounds_Error when inserting text at an invalid positive index position" <|
hello_world.insert (hello_world.length + 1) cruel . should_fail_with Index_Out_Of_Bounds_Error
(kshi + facepalm + accent_1).insert 4 cruel . should_fail_with Index_Out_Of_Bounds_Error

Test.specify "should insert text at a negative index position" <|
hello_world.insert -1 cruel . should_equal "Hello World! Cruel"
hello_world.insert -5 cruel . should_equal "Hello Wo Cruelrld!"
hello_world.insert -(hello_world.length) cruel . should_equal "H Cruelello World!"
hello_world.insert -(hello_world.length + 1) cruel . should_equal " CruelHello World!"
txt = kshi + facepalm + accent_1
txt.insert -1 cruel . should_equal (txt + cruel)
txt.insert -(txt.length) cruel . should_equal (kshi + cruel + facepalm + accent_1)

Test.specify "should report Index_Out_Of_Bounds_Error when inserting text at an invalid negative index position" <|
hello_world.insert -(hello_world.length + 2) cruel . should_fail_with Index_Out_Of_Bounds_Error
txt = kshi + facepalm + accent_1
txt.insert -(txt.length + 2) cruel . should_fail_with Index_Out_Of_Bounds_Error

Test.specify "should be able to check by index if is a digit" <|
str = kshi + "A12" + accent_2
str.is_digit . should_be_false
Expand Down