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

Proposal for string.split #3284

Merged
merged 16 commits into from
Aug 29, 2022
Merged
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
109 changes: 109 additions & 0 deletions proposal/string-split.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Add split function to Strings Module: Draft 1

*([Issue](https://github.com/sass/sass/issues/1950))*

This proposal adds `string.split()` to the `sass:string` module.

## Table of Contents

* [Background](#background)
* [Summary](#summary)
* [Semantics](#semantics)
* [`split()`](#split)

## Background

> This section is non-normative.

The `sass:string` module contains several functions for manipulating and finding
out information about strings. Currently, though, there is no built-in function
that splits one string into a list of substrings, and authors have been creating
their own versions of functions that achieve this functionality.

## Summary

> This section is non-normative.

This proposal adds the `string.split()` function to the `sass:string` module.
The function takes a string, splits it based on a provided separator, and
returns a space-separated list of substrings.

This could be used to take a string and repurpose parts of it for some other
use. For example, fonts contained in a font stack list could be split into
segments and then used as keys in a new map.

Examples:

```scss
$fonts: "Helvetica Neue, Helvetica, Arial";
string.split($fonts, ', '); // "Helvetica Neue" "Helvetica" "Arial"
```

A third argument can limit the number of strings
returned in the list:

```scss
string.split($fonts, ', ', 2); // "Helvetica Neue" "Helvetica"
```


An empty `$separator` returns all Unicode code points in the original string:

```scss
$font: "Helvetica"
string.split($font, ''); // "H" "e" "l" "v" "e" "t" "i" "c" "a"
```


## Semantics

### `split()`

```
split($string, $separator, $limit: null)
dvdherron marked this conversation as resolved.
Show resolved Hide resolved
```

* If `$string` is not a string, throw an error.
jathak marked this conversation as resolved.
Show resolved Hide resolved

* If `$separator` is `null` or is not a string, throw an error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* If `$separator` is `null` or is not a string, throw an error.
* If `$separator` is not a string, throw an error.

null is already not a string, so we don't need to specifically call it out here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the null reference here.


* If `$limit` is a value other than an integer or `null`, throw an error.

* If `$limit` is a negative number, throw an error.

* If `$string` is an empty string, return a list with `$string` as the only
item.

* If `$limit` is 0, return an empty list.

* Let `split-list` be an empty list.

* Let `length` be the result of calling `string.length($string)`.

* Let `limit` be the value of `$limit`.

* Otherwise, if `$limit` is `null`, set `limit` to the value of `length`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably simpler to just say:

* If `$limit` is `null`, set `$limit` to the value of `length`.

and then refer to $limit below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


* While `list.length(split-list)` is `<=` `limit` and
`string.length($string) > 0`:

* If `$separator` is empty (`''`),

* Let `code-point` be the value of calling `string.slice($string, 1, 1)`.

* Append `code-point` to the end of `split-list`.

* Set `$string` to `string.slice($string, 2)`.

* Otherwise, let `index` be the result of calling
`string.index($string, $separator)`.

* Let `current-substring` be the result of calling
`string.slice($string, 1, index - 1)`.

* Append `current-substring` to the end of `split-list`.

* Set `$string` to
`string.slice($string, index + string.length($separator))`.

* Return `split-list`.