From df3099cb61c3290c672050075082676ab8497ca8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 8 Dec 2022 17:11:54 -0800 Subject: [PATCH] Implement string.split() Closes #1821 See sass/sass#1950 --- CHANGELOG.md | 5 +++++ lib/src/functions/string.dart | 39 +++++++++++++++++++++++++++++++++++ pkg/sass_api/CHANGELOG.md | 4 ++++ pkg/sass_api/pubspec.yaml | 4 ++-- pubspec.yaml | 2 +- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e3a4a2a..aa71d4a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.57.0 + +* Add a `split($string, $separator, $limit: null)` function to `sass:string` + that splits a string into separate substrings based on a separator string. + ## 1.56.2 ### Embedded Sass diff --git a/lib/src/functions/string.dart b/lib/src/functions/string.dart index dc47a9977..99d1ee6d2 100644 --- a/lib/src/functions/string.dart +++ b/lib/src/functions/string.dart @@ -8,6 +8,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; import '../callable.dart'; +import '../exception.dart'; import '../module/built_in.dart'; import '../util/character.dart'; import '../utils.dart'; @@ -32,6 +33,44 @@ final global = UnmodifiableListView([ final module = BuiltInModule("string", functions: [ _unquote, _quote, _toUpperCase, _toLowerCase, _length, _insert, _index, // _slice, _uniqueId, + + _function("split", r"$string, $separator, $limit: null", (arguments) { + var string = arguments[0].assertString("string"); + var separator = arguments[1].assertString("separator"); + var limit = arguments[2].realNull?.assertNumber("limit").assertInt("limit"); + + if (limit != null && limit < 1) { + throw SassScriptException("\$limit: Must be 1 or greater, was $limit."); + } + + if (string.text.isEmpty) { + return const SassList.empty( + separator: ListSeparator.comma, brackets: true); + } else if (separator.text.isEmpty) { + return SassList( + string.text.runes.map((rune) => + SassString(String.fromCharCode(rune), quotes: string.hasQuotes)), + ListSeparator.comma, + brackets: true); + } + + var i = 0; + var lastEnd = 0; + var chunks = []; + for (var match in separator.text.allMatches(string.text)) { + chunks.add(string.text.substring(lastEnd, match.start)); + lastEnd = match.end; + + i++; + if (i == limit) break; + } + chunks.add(string.text.substring(lastEnd)); + + return SassList( + chunks.map((chunk) => SassString(chunk, quotes: string.hasQuotes)), + ListSeparator.comma, + brackets: true); + }), ]); final _unquote = _function("unquote", r"$string", (arguments) { diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index 8e8476613..a3dd2e76d 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.0 + +* No user-visible changes. + ## 4.1.2 * No user-visible changes. diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index e4a69ccaa..a2cae9e34 100644 --- a/pkg/sass_api/pubspec.yaml +++ b/pkg/sass_api/pubspec.yaml @@ -2,7 +2,7 @@ name: sass_api # Note: Every time we add a new Sass AST node, we need to bump the *major* # version because it's a breaking change for anyone who's implementing the # visitor interface(s). -version: 4.1.2 +version: 4.2.0 description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass @@ -10,7 +10,7 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - sass: 1.56.2 + sass: 1.57.0 dev_dependencies: dartdoc: ^5.0.0 diff --git a/pubspec.yaml b/pubspec.yaml index 36f86e43f..486bd9c26 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.56.2 +version: 1.57.0 description: A Sass implementation in Dart. homepage: https://github.com/sass/dart-sass