@omnisass/library 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +120 -3
  2. package/README.md +94 -0
  3. package/index.scss +6 -0
  4. package/modules/utilities/converters/_convert-camel2kebab.scss +5 -4
  5. package/modules/utilities/converters/_convert-em2px.scss +5 -3
  6. package/modules/utilities/converters/_convert-hex2rgb.scss +4 -0
  7. package/modules/utilities/converters/_convert-hex2rgba.scss +5 -0
  8. package/modules/utilities/converters/_convert-kebab2camel.scss +5 -4
  9. package/modules/utilities/converters/_convert-kebab2snake.scss +4 -4
  10. package/modules/utilities/converters/_convert-px2em.scss +5 -4
  11. package/modules/utilities/converters/_convert-px2rem.scss +5 -4
  12. package/modules/utilities/converters/_convert-rem2px.scss +5 -3
  13. package/modules/utilities/converters/_convert-snake2kebab.scss +4 -4
  14. package/modules/utilities/getters/color/_get-color-brightness.scss +4 -0
  15. package/modules/utilities/getters/color/_get-color-darkest.scss +5 -1
  16. package/modules/utilities/getters/list/_get-list-item-end.scss +4 -2
  17. package/modules/utilities/getters/list/_get-list-item-start.scss +4 -2
  18. package/modules/utilities/getters/list/_get-list-item.scss +6 -4
  19. package/modules/utilities/getters/misc/_get-uid.scss +135 -0
  20. package/modules/utilities/getters/number/_get-number-from-percent.scss +6 -2
  21. package/modules/utilities/getters/number/_get-number-height-by-ratio.scss +5 -0
  22. package/modules/utilities/getters/number/_get-number-max.scss +4 -0
  23. package/modules/utilities/getters/number/_get-number-min.scss +4 -0
  24. package/modules/utilities/getters/number/_get-number-percentage-of.scss +6 -1
  25. package/modules/utilities/getters/number/_get-number-unit.scss +4 -2
  26. package/modules/utilities/getters/number/_get-number-width-by-ratio.scss +5 -0
  27. package/modules/utilities/getters/string/_get-string-hash.scss +143 -0
  28. package/modules/utilities/helpers/color/_color-blend-steps.scss +6 -0
  29. package/modules/utilities/helpers/color/_color-blend.scss +6 -0
  30. package/modules/utilities/helpers/color/_color-hue-shift.scss +5 -0
  31. package/modules/utilities/helpers/color/_color-scale.scss +5 -0
  32. package/modules/utilities/helpers/color/_color-shade.scss +5 -0
  33. package/modules/utilities/helpers/color/_color-tint.scss +5 -0
  34. package/modules/utilities/helpers/color/_color-triad.scss +4 -1
  35. package/modules/utilities/helpers/list/_list-dedupe.scss +4 -0
  36. package/modules/utilities/helpers/list/_list-insert-at.scss +5 -0
  37. package/modules/utilities/helpers/list/_list-merge.scss +54 -8
  38. package/modules/utilities/helpers/list/_list-remove-at.scss +5 -0
  39. package/modules/utilities/helpers/list/_list-sum-numbers-safe.scss +3 -0
  40. package/modules/utilities/helpers/list/_list-sum-numbers.scss +3 -0
  41. package/modules/utilities/helpers/misc/_url-encode.scss +7 -8
  42. package/modules/utilities/helpers/number/_number-ceil-to.scss +56 -4
  43. package/modules/utilities/helpers/number/_number-clamp-max.scss +65 -10
  44. package/modules/utilities/helpers/number/_number-clamp-min.scss +65 -10
  45. package/modules/utilities/helpers/number/_number-clamp.scss +88 -12
  46. package/modules/utilities/helpers/number/_number-denormalize.scss +87 -9
  47. package/modules/utilities/helpers/number/_number-fibonacci.scss +62 -9
  48. package/modules/utilities/helpers/number/_number-floor-to.scss +57 -3
  49. package/modules/utilities/helpers/number/_number-format-with-separator.scss +99 -16
  50. package/modules/utilities/helpers/number/_number-normalize.scss +88 -10
  51. package/modules/utilities/helpers/number/_number-random-between-int.scss +74 -13
  52. package/modules/utilities/helpers/number/_number-random-between.scss +76 -15
  53. package/modules/utilities/helpers/number/_number-range.scss +105 -12
  54. package/modules/utilities/helpers/number/_number-round-to-nearest.scss +58 -1
  55. package/modules/utilities/helpers/number/_number-round-to.scss +65 -2
  56. package/modules/utilities/helpers/number/_number-strip-unit.scss +43 -9
  57. package/modules/utilities/helpers/string/_string-capitalize.scss +46 -5
  58. package/modules/utilities/helpers/string/_string-count.scss +173 -0
  59. package/modules/utilities/helpers/string/_string-lorips.config.scss +81 -0
  60. package/modules/utilities/helpers/string/_string-lorips.scss +198 -0
  61. package/modules/utilities/helpers/string/_string-repeat.scss +147 -0
  62. package/modules/utilities/helpers/string/_string-replace.scss +82 -4
  63. package/modules/utilities/helpers/string/_string-reverse.scss +139 -0
  64. package/modules/utilities/helpers/string/_string-trim-end.scss +49 -6
  65. package/modules/utilities/helpers/string/_string-trim-start.scss +49 -6
  66. package/modules/utilities/helpers/string/_string-trim.scss +56 -11
  67. package/modules/utilities/loggers/_log-invalid-type.scss +1 -1
  68. package/modules/utilities/loggers/_log-invalid-value.scss +1 -1
  69. package/modules/utilities/validators/color/_is-color-light.scss +61 -4
  70. package/modules/utilities/validators/color/_is-color-list.scss +41 -9
  71. package/modules/utilities/validators/list/_is-list-contained.scss +42 -3
  72. package/modules/utilities/validators/misc/_is-time.scss +29 -0
  73. package/modules/utilities/validators/number/_is-int-even.scss +50 -8
  74. package/modules/utilities/validators/number/_is-int-odd.scss +51 -9
  75. package/modules/utilities/validators/number/_is-int.scss +71 -12
  76. package/modules/utilities/validators/number/_is-number-has-unit.scss +55 -13
  77. package/modules/utilities/validators/number/_is-number-negative.scss +53 -11
  78. package/modules/utilities/validators/number/_is-number-positive.scss +52 -10
  79. package/modules/utilities/validators/number/_is-number-unitless.scss +53 -12
  80. package/modules/utilities/validators/number/_is-number-zero.scss +54 -10
  81. package/modules/utilities/validators/string/_is-string-contained.scss +59 -4
  82. package/modules/utilities/validators/string/_is-string-empty.scss +48 -8
  83. package/modules/utilities/validators/string/_is-string-ending-with.scss +64 -5
  84. package/modules/utilities/validators/string/_is-string-starting-with.scss +60 -8
  85. package/package.json +1 -1
  86. package/package.scss +9 -8
  87. package/test2.sh +158 -0
  88. package/modules/utilities/setters/_index.scss +0 -3
@@ -0,0 +1,81 @@
1
+ /// Глобальная переменная с набором слов Lorem Ipsum.
2
+ ///
3
+ /// Список содержит 35 стандартных слов классического текста-
4
+ /// заполнителя Lorem Ipsum в нижнем регистре. Переменная
5
+ /// используется функциями для генерации текста-заполнителя
6
+ /// и может быть переопределена для использования кастомного
7
+ /// набора слов или другого языка.
8
+ ///
9
+ /// - Переменная объявлена с флагом `!default`, что
10
+ /// позволяет переопределить ее в проекте перед импортом
11
+ /// библиотеки. Это полезно для локализации или
12
+ /// использования кастомного набора слов.
13
+ /// - Для генерации корректного текста-заполнителя
14
+ /// рекомендуется использовать функции, которые учитывают
15
+ /// капитализацию первого слова и добавление пунктуации.
16
+ /// - Многострочное форматирование списка улучшает
17
+ /// читаемость кода, но не влияет на содержимое переменной.
18
+ /// Каждое слово находится на отдельной строке для удобства
19
+ /// просмотра и редактирования.
20
+ /// - Все слова приведены к нижнему регистру.
21
+ /// Функции, использующие эту переменную, должны сами
22
+ /// заботиться о капитализации при необходимости.
23
+ /// ---
24
+ /// @name set-lorem-ipsum-words
25
+ /// @group utilities-helpers
26
+ /// @since 2026.01.18
27
+ /// @access public
28
+ /// @author Murad Rustamov (therteenten)
29
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
30
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
31
+ /// @link https://sass-lang.com/documentation/values/lists См. также: Официальная документация Sass - Тип данных "Списки"
32
+ /// @link https://sass-lang.com/documentation/values/strings См. также: Официальная документация Sass - Тип данных "Строки"
33
+ /// @link https://en.wikipedia.org/wiki/Lorem_ipsum См. также: Wikipedia - Lorem ipsum
34
+ /// @link https://en.wikipedia.org/wiki/Latin См. также: Wikipedia - Латинский язык
35
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/content См. также: MDN Web Docs - CSS свойство content
36
+ /// @link https://css-tricks.com/snippets/sass/lorem-ipsum-generator/ См. также: CSS-Tricks - Генератор Lorem Ipsum на Sass
37
+ /// @link https://css-tricks.com/design-systems-with-sass-placeholders/ См. также: CSS-Tricks - Дизайн-системы с заполнителями
38
+ /// @link https://sass-guidelin.es/ru/#section-23 См. также: Sass Guidelines - Раздел про переменные
39
+ /// @link https://loremipsum.io/generator/ См. также: Lorem Ipsum - Генератор с настройками
40
+ /// @link https://www.lipsum.com/feed/html См. также: Lipsum.com - Генератор HTML Lorem Ipsum
41
+ /// @link https://github.com/sass/sass/issues/2871 См. также: GitHub - Обсуждение текстовых утилит в Sass
42
+ /// @see string-lorips - Функция для генерации текста-
43
+ /// заполнителя на основе этого набора слов.
44
+ /// @type List
45
+ $set-lorem-ipsum-words: "lorem"
46
+ "ipsum"
47
+ "dolor"
48
+ "sit"
49
+ "amet"
50
+ "consectetur"
51
+ "adipiscing"
52
+ "elit"
53
+ "sed"
54
+ "do"
55
+ "eiusmod"
56
+ "tempor"
57
+ "incididunt"
58
+ "ut"
59
+ "labore"
60
+ "et"
61
+ "dolore"
62
+ "magna"
63
+ "aliqua"
64
+ "ut"
65
+ "enim"
66
+ "ad"
67
+ "minim"
68
+ "veniam"
69
+ "quis"
70
+ "nostrud"
71
+ "exercitation"
72
+ "ullamco"
73
+ "laboris"
74
+ "nisi"
75
+ "ut"
76
+ "aliquip"
77
+ "ex"
78
+ "ea"
79
+ "commodo"
80
+ "consequat"
81
+ !default;
@@ -0,0 +1,198 @@
1
+ @forward './string-lorips.config';
2
+
3
+ @use 'sass:list';
4
+ @use './string-capitalize' as *;
5
+ @use './string-lorips.config' as configs;
6
+ @use '../../loggers/log-invalid-type' as *;
7
+ @use '../../validators/type-of/is-list' as *;
8
+ @use '../../validators/type-of/is-number' as *;
9
+
10
+ /// Генерирует текст-заполнитель на основе указанного списка слов.
11
+ ///
12
+ /// Функция создает текст-заполнитель указанной длины (в словах)
13
+ /// путем циклического повторения слов из предоставленного списка.
14
+ /// По умолчанию используется классический набор слов Lorem Ipsum.
15
+ /// Результат автоматически капитализируется (первая буква становится
16
+ /// заглавной) и завершается точкой для грамматической корректности.
17
+ ///
18
+ /// Важные особенности функции:
19
+ /// - Поддерживает кастомные списки слов через параметр `$words-list`
20
+ /// - Использует классический набор слов Lorem Ipsum по умолчанию
21
+ /// - Поддерживает указание произвольного количества слов
22
+ /// - Автоматически циклически повторяет слова при превышении длины списка
23
+ /// - Капитализирует первую букву результата
24
+ /// - Добавляет завершающую точку для грамматической правильности
25
+ /// - Разделяет слова одиночными пробелами
26
+ /// - Выполняет строгую проверку типов входных параметров
27
+ /// - Возвращает строку, готовую к использованию как текст-заполнитель
28
+ /// - Полезна для создания макетов, прототипов и тестирования типографики
29
+ /// - Обеспечивает единообразный заполнитель во всем проекте
30
+ /// - Позволяет легко локализовать текст-заполнитель
31
+ /// - Сохраняет детерминированность результата
32
+ /// - Функция использует циклический доступ к словам.
33
+ /// При запросе количества слов, превышающего длину списка,
34
+ /// последовательность начинается заново с первого слова.
35
+ /// Это реализовано через операцию модуля (%).
36
+ /// - Все слова в списке должны быть в нижнем регистре
37
+ /// для корректной работы функции `string-capitalize()`.
38
+ /// Капитализация применяется только к первой букве
39
+ /// итоговой строки.
40
+ /// - При передаче пустого списка и ненулевого значения
41
+ /// `$word-count` произойдет ошибка при попытке обращения к
42
+ /// `list.nth()` с индексом. Рекомендуется проверять список
43
+ /// на пустоту в вызывающем коде.
44
+ /// - Функция не проверяет, являются ли все элементы
45
+ /// списка строками. Передача списка с нестроковыми
46
+ /// элементами может привести к непредсказуемому поведению.
47
+ /// ---
48
+ /// @name string-lorips
49
+ /// @group utilities-helpers
50
+ /// @since 2026.01.18
51
+ /// @access public
52
+ /// @author Murad Rustamov (therteenten)
53
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
54
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
55
+ /// @link https://sass-lang.com/documentation/modules/string См. также: Официальная документация Sass - Модуль String
56
+ /// @link https://sass-lang.com/documentation/modules/list См. также: Официальная документация Sass - Модуль List
57
+ /// @link https://sass-lang.com/documentation/values/strings См. также: Официальная документация Sass - Тип данных "Строки"
58
+ /// @link https://en.wikipedia.org/wiki/Lorem_ipsum См. также: Wikipedia - Lorem ipsum
59
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/content См. также: MDN Web Docs - CSS свойство content
60
+ /// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat См. также: MDN Web Docs - Метод String.repeat()
61
+ /// @link https://css-tricks.com/snippets/sass/lorem-ipsum-generator/ См. также: CSS-Tricks - Генератор Lorem Ipsum на Sass
62
+ /// @link https://css-tricks.com/design-systems-with-sass-placeholders/ См. также: CSS-Tricks - Дизайн-системы с заполнителями
63
+ /// @link https://sass-guidelin.es/ru/#section-44 См. также: Sass Guidelines - Раздел про функции
64
+ /// @link https://loremipsum.io/ См. также: Lorem Ipsum - Генератор текста-заполнителя
65
+ /// @link https://www.lipsum.com/ См. также: Lipsum.com - Классический генератор Lorem Ipsum
66
+ /// @link https://github.com/sass/sass/issues/2871 См. также: GitHub - Обсуждение текстовых утилит в Sass
67
+ /// @link https://www.30secondsofcode.org/sass/p/1/string-repeat См. также: 30 seconds of code - Функция string-repeat
68
+ /// @example scss - Генерация текста с набором по умолчанию
69
+ /// @debug string-lorips(5); // "Lorem ipsum dolor sit amet."
70
+ /// @debug string-lorips(10); // "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do."
71
+ /// @debug string-lorips(3); // "Lorem ipsum dolor."
72
+ /// @debug string-lorips(1); // "Lorem."
73
+ /// @debug string-lorips(); // "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do."
74
+ /// @example scss - Генерация длинного текста (циклическое повторение)
75
+ /// @debug string-lorips(15); // "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore."
76
+ /// @debug string-lorips(20); // "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua ut."
77
+ /// @debug string-lorips(40); // "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut."
78
+ /// @example scss - Использование кастомного списка слов
79
+ /// $my-words: "hello" "world" "test" "example";
80
+ /// @debug string-lorips(5, $my-words); // "Hello world test example hello."
81
+ /// @debug string-lorips(3, $my-words); // "Hello world test."
82
+ /// @debug string-lorips(7, $my-words); // "Hello world test example hello world test."
83
+ /// @example scss - Граничные случаи
84
+ /// @debug string-lorips(0, ()); // Error: $n: calc(NaN) is not an int.
85
+ /// @debug string-lorips(5, ("single",)); // "Single single single single single."
86
+ /// @param {Number} $word-count [10] - Количество слов в
87
+ /// генерируемом тексте. Должно быть целым неотрицательным
88
+ /// числом. При значении 0 возвращается только точка.
89
+ /// При значении 1 возвращается одно слово с точкой.
90
+ /// Значение по умолчанию - 10 слов.
91
+ /// @param {List} $words-list [configs.$set-lorem-ipsum-words] -
92
+ /// Список слов для генерации текста. По умолчанию используется
93
+ /// глобальная переменная с классическим набором слов
94
+ /// Lorem Ipsum. Может быть передан любой список строк
95
+ /// (слов), которые будут использоваться циклически.
96
+ /// При пустом списке и ненулевом $word-count будет ошибка
97
+ /// выполнения при обращении к list.nth().
98
+ /// @return {String} - Текст-заполнитель указанной длины,
99
+ /// начинающийся с заглавной буквы и заканчивающийся точкой.
100
+ /// Если запрошено больше слов, чем в списке, набор слов
101
+ /// циклически повторяется с начала списка.
102
+ /// @throws {Error} - Выбрасывает ошибку, если в параметр передано
103
+ /// значение, не соответствующее необходимому типу:
104
+ ///
105
+ /// - `$word-count` → `number`
106
+ /// - `$words-list` → `list`
107
+ @function string-lorips($word-count: 10, $words-list: configs.$set-lorem-ipsum-words) {
108
+
109
+ // Проверка типа первого параметра: ожидается числовое значение.
110
+ // Количество слов должно быть числом для использования в цикле
111
+ // и математических операциях с модулем.
112
+ @if not is-number($word-count) {
113
+
114
+ // Если $word-count не является числом, возвращаем ошибку через
115
+ // стандартную функцию логирования. Это предотвращает
116
+ // некорректные операции с нечисловыми типами данных.
117
+ @return log-invalid-type(
118
+ 'string-lorips',
119
+ $word-count,
120
+ '$word-count',
121
+ 'number'
122
+ );
123
+
124
+ }
125
+
126
+ // Проверка типа второго параметра: ожидается список (list).
127
+ // Список слов должен быть именно типом list для работы с
128
+ // функциями list.length() и list.nth().
129
+ @if not is-list($words-list) {
130
+
131
+ // Если $words-list не является списком, возвращаем ошибку.
132
+ // Проверка выполняется только если $word-count прошел валидацию.
133
+ @return log-invalid-type(
134
+ 'string-lorips',
135
+ $words-list,
136
+ '$words-list',
137
+ 'list'
138
+ );
139
+
140
+ }
141
+
142
+ // Все параметры прошли валидацию - генерируем текст-заполнитель.
143
+ @else {
144
+
145
+ // Использование предоставленного списка слов.
146
+ // Локальная переменная создается для удобства работы
147
+ // и лучшей читаемости кода.
148
+ $-words: $words-list;
149
+
150
+ // Инициализация переменной результата.
151
+ // Начальное значение null позволяет начать конкатенацию
152
+ // с первого слова без специальной обработки первого элемента.
153
+ $-result: null;
154
+
155
+ // Цикл генерации указанного количества слов.
156
+ // Цикл выполняется от 1 до $word-count включительно.
157
+ // Каждая итерация добавляет очередное слово из списка.
158
+ @for $i from 1 through $word-count {
159
+
160
+ // Вычисление индекса текущего слова в списке.
161
+ // Формула ($i - 1) % list.length($-words) + 1 обеспечивает:
162
+ // 1. Циклический доступ к словам при превышении длины списка
163
+ // 2. Корректную индексацию (от 1 до длины списка)
164
+ // 3. Последовательное прохождение по всему списку
165
+ $-word-index: ($i - 1) % list.length($-words) + 1;
166
+
167
+ // Получение слова по вычисленному индексу.
168
+ // list.nth() возвращает элемент списка по заданной позиции.
169
+ // Если список пустой и $word-count > 0, здесь будет ошибка.
170
+ $-word: list.nth($-words, $-word-index);
171
+
172
+ // Добавление слова к результату.
173
+ // Конкатенация накапливает слова в итоговой строке.
174
+ // При первой итерации $-result равен null, что приводит
175
+ // к начальному значению, равному $-word.
176
+ $-result: $-result + $-word;
177
+
178
+ // Добавление пробела после слова, если это не последнее слово.
179
+ // Условие $i != $word-count проверяет, не достигли ли мы
180
+ // запрошенного количества слов, чтобы не добавлять лишний пробел
181
+ // в конце строки перед точкой.
182
+ @if $i != $word-count {
183
+ $-result: $-result + " ";
184
+ }
185
+
186
+ }
187
+
188
+ // Возвращаем отформатированный результат.
189
+ // string-capitalize() делает первую букву заглавной,
190
+ // а добавление точки завершает предложение.
191
+ // Если $word-count = 0, $-result будет null, что после
192
+ // string-capitalize() станет пустой строкой, и результат
193
+ // будет просто ".".
194
+ @return string-capitalize($-result) + ".";
195
+
196
+ }
197
+
198
+ }
@@ -0,0 +1,147 @@
1
+ @use '../../loggers/log-invalid-type' as *;
2
+ @use '../../validators/type-of/is-string' as *;
3
+ @use '../../validators/type-of/is-number' as *;
4
+
5
+ /// Повторяет строку указанное количество раз.
6
+ ///
7
+ /// Функция создает новую строку путем конкатенации исходной
8
+ /// строки с собой заданное количество раз. Это полезно для
9
+ /// генерации повторяющихся паттернов, заполнителей, рамок
10
+ /// или любых других конструкций, требующих дублирования
11
+ /// строковых элементов.
12
+ ///
13
+ /// Важные особенности функции:
14
+ /// - Выполняет строгую проверку типов обоих параметров
15
+ /// - Возвращает пустую строку при нулевом количестве повторов
16
+ /// - Обрабатывает целые положительные числа повторений
17
+ /// - Использует эффективный цикл для построения результата
18
+ /// - Сохраняет исходную строку без изменений
19
+ /// - Полезна для создания визуальных разделителей
20
+ /// - Может использоваться для генерации тестовых данных
21
+ /// - Подходит для построения ASCII-графики или рамок
22
+ /// - Обеспечивает детерминированный результат
23
+ /// - Совместима с многострочными строками и Unicode
24
+ /// - Функция использует простой цикл `for` для
25
+ /// конкатенации строк. Для большого количества повторов
26
+ /// (>1000) производительность может снижаться.
27
+ /// - Для работы с очень большими строками или
28
+ /// количеством повторов рекомендуется использовать
29
+ /// рекурсивную реализацию или мемоизацию.
30
+ /// ---
31
+ /// @name string-repeat
32
+ /// @group utilities-helpers
33
+ /// @since 2026.01.18
34
+ /// @access public
35
+ /// @author Murad Rustamov (therteenten)
36
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
37
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
38
+ /// @link https://sass-lang.com/documentation/modules/string См. также: Официальная документация Sass - Модуль String
39
+ /// @link https://sass-lang.com/documentation/values/strings См. также: Официальная документация Sass - Тип данных "Строки"
40
+ /// @link https://sass-lang.com/documentation/values/numbers См. также: Официальная документация Sass - Тип данных "Числа"
41
+ /// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat См. также: MDN Web Docs - Метод String.repeat()
42
+ /// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat См. также: MDN Web Docs - Метод String.concat()
43
+ /// @link https://en.wikipedia.org/wiki/String_(computer_science)#Concatenation См. также: Wikipedia - Конкатенация строк
44
+ /// @link https://en.wikipedia.org/wiki/Iteration См. также: Wikipedia - Итерация (программирование)
45
+ /// @link https://css-tricks.com/snippets/sass/string-repetition-function/ См. также: CSS-Tricks - Функция повторения строк в Sass
46
+ /// @link https://css-tricks.com/sass-string-manipulation-functions/ См. также: CSS-Tricks - Функции для работы со строками в Sass
47
+ /// @link https://sass-guidelin.es/ru/#section-44 См. также: Sass Guidelines - Раздел про функции
48
+ /// @link https://github.com/sass/sass/issues/1402 См. также: GitHub - Обсуждение строковых операций в Sass
49
+ /// @link https://www.30secondsofcode.org/sass/p/1/string-repeat См. также: 30 seconds of code - Функция string-repeat
50
+ /// @example scss - Базовое повторение строк
51
+ /// @debug string-repeat('a', 5); // "aaaaa"
52
+ /// @debug string-repeat('ab', 3); // "ababab"
53
+ /// @debug string-repeat('test', 2); // "testtest"
54
+ /// @debug string-repeat('', 10); // ""
55
+ /// @example scss - Создание разделителей и рамок
56
+ /// @debug string-repeat('-', 20); // "--------------------"
57
+ /// @debug string-repeat('* ', 10); // "* * * * * * * * * * "
58
+ /// @debug string-repeat('=-', 8); // "-=-=-=-=-=-=-=-=-=-="
59
+ /// @debug string-repeat('▮', 5); // "▮▮▮▮▮"
60
+ /// @example scss - Граничные случаи
61
+ /// @debug string-repeat('abc', 0); // ""
62
+ /// @debug string-repeat('abc', 1); // "abc"
63
+ /// @debug string-repeat(' ', 10); // " "
64
+ /// @debug string-repeat('\n', 3); // "nnn"
65
+ /// @param {String} $string - Исходная строка для повторения.
66
+ /// Может быть любой строкой, включая пустую строку,
67
+ /// многострочные строки, строки с пробелами и Unicode-
68
+ /// символами. Каждое повторение будет точной копией
69
+ /// исходной строки.
70
+ /// @param {Number} $repetitions - Количество повторений
71
+ /// строки. Должно быть целым неотрицательным числом.
72
+ /// При значении 0 возвращается пустая строка. При
73
+ /// значении 1 возвращается исходная строка без изменений.
74
+ /// @return {String} - Новая строка, состоящая из исходной
75
+ /// строки, повторенной указанное количество раз. Если
76
+ /// $repetitions равно 0, возвращается пустая строка.
77
+ /// Если $repetitions равно 1, возвращается исходная
78
+ /// строка. Для отрицательных чисел поведение не определено.
79
+ /// @throws {Error} - Выбрасывает ошибку, если в параметр передано
80
+ /// значение, не соответствующее необходимому типу:
81
+ ///
82
+ /// - `$string` → `string`
83
+ /// - `$repetitions` → `number`
84
+ @function string-repeat($string, $repetitions) {
85
+
86
+ // Проверка типа первого параметра: ожидается строковое значение.
87
+ // Функция предназначена для повторения именно строк, так как
88
+ // операция конкатенации определена только для строковых значений.
89
+ @if not is-string($string) {
90
+
91
+ // Если $string не является строкой, возвращаем ошибку через
92
+ // стандартную функцию логирования. Это предотвращает
93
+ // попытки конкатенации нестроковых значений.
94
+ @return log-invalid-type(
95
+ 'string-repeat',
96
+ $string,
97
+ '$string',
98
+ 'string'
99
+ );
100
+
101
+ }
102
+
103
+ // Проверка типа второго параметра: ожидается числовое значение.
104
+ // Количество повторений должно быть числом, чтобы можно было
105
+ // использовать его в цикле for.
106
+ @else if not is-number($repetitions) {
107
+
108
+ // Если $repetitions не является числом, возвращаем ошибку.
109
+ // Проверка выполняется только если $string прошел валидацию.
110
+ @return log-invalid-type(
111
+ 'string-repeat',
112
+ $repetitions,
113
+ '$repetitions',
114
+ 'number'
115
+ );
116
+
117
+ }
118
+
119
+ // Все параметры прошли валидацию - выполняем повторение строки.
120
+ @else {
121
+
122
+ // Инициализация переменной результата.
123
+ // Начальное значение null позволяет начать конкатенацию
124
+ // с первой итерации цикла без специальной обработки.
125
+ $-result: null;
126
+
127
+ // Цикл повторения строки заданное количество раз.
128
+ // Цикл выполняется от 1 до $repetitions включительно.
129
+ // Каждая итерация добавляет исходную строку к результату.
130
+ @for $i from 1 through $repetitions {
131
+
132
+ // Конкатенация текущего результата с исходной строкой.
133
+ // При первой итерации $-result равен null, что приводит
134
+ // к начальному значению, равному $string.
135
+ $-result: $-result + $string;
136
+
137
+ }
138
+
139
+ // Возвращаем итоговую строку после всех повторений.
140
+ // Если $repetitions было 0, цикл не выполнится ни разу,
141
+ // и функция вернет null, который в контексте строки
142
+ // преобразуется в пустую строку.
143
+ @return $-result;
144
+
145
+ }
146
+
147
+ }
@@ -1,4 +1,6 @@
1
1
  @use 'sass:string';
2
+ @use '../../loggers/log-invalid-type' as *;
3
+ @use '../../validators/type-of/is-string' as *;
2
4
 
3
5
  /// Заменяет все вхождения подстроки в строке на другую подстроку.
4
6
  ///
@@ -56,14 +58,90 @@
56
58
  /// `$replaceable` не найдена, возвращается оригинальная строка.
57
59
  /// @throws {Error} - Может вызвать ошибку глубины рекурсии при очень
58
60
  /// длинных строках с множественными заменами.
61
+ /// @throws {Error} - Выбрасывает ошибку, если в параметры передано
62
+ /// значение, не соответствующее типу `string`. Компиляция Sass
63
+ /// будет остановлена с ошибкой.
59
64
  @function string-replace($string, $replaceable, $replacement: '') {
60
65
 
61
- $-index: string.index($string, $replaceable);
66
+ // Проверка типа первого параметра: ожидается исходная строка.
67
+ // Функция is-string() проверяет, является ли $string строкой.
68
+ // В этой строке будут заменяться все вхождения подстроки.
69
+ @if not is-string($string) {
70
+
71
+ // Если $string не является строкой, возвращаем ошибку через
72
+ // стандартную функцию логирования. Это предотвращает
73
+ // некорректные операции замены с нестроковыми данными.
74
+ @return log-invalid-type(
75
+ 'string-replace',
76
+ $string,
77
+ '$string',
78
+ 'string'
79
+ );
80
+
81
+ }
82
+
83
+ // Проверка типа второго параметра: ожидается строка для поиска.
84
+ // $replaceable определяет подстроку, которую нужно найти и заменить.
85
+ @else if not is-string($replaceable) {
86
+
87
+ // Если $replaceable не является строкой, возвращаем ошибку.
88
+ // Проверка выполняется только если $string прошел валидацию.
89
+ @return log-invalid-type(
90
+ 'string-replace',
91
+ $replaceable,
92
+ '$replaceable',
93
+ 'string'
94
+ );
95
+
96
+ }
97
+
98
+ // Проверка типа третьего параметра: ожидается строка-замена.
99
+ // $replacement определяет подстроку, на которую будет заменено
100
+ // каждое вхождение $replaceable. По умолчанию - пустая строка.
101
+ @else if not is-string($replacement) {
102
+
103
+ // Если $replacement не является строкой, возвращаем ошибку.
104
+ // Проверка выполняется только если $string и $replaceable
105
+ // прошли валидацию.
106
+ @return log-invalid-type(
107
+ 'string-replace',
108
+ $replacement,
109
+ '$replacement',
110
+ 'string'
111
+ );
62
112
 
63
- @if $-index {
64
- @return string.slice($string, 1, $-index - 1) + $replacement + string-replace(string.slice($string, $-index + string.length($replaceable)), $replaceable, $replacement);
65
113
  }
66
114
 
67
- @return $string;
115
+ // Все параметры прошли валидацию - выполняем замену подстрок.
116
+ @else {
117
+
118
+ // Поиск первого вхождения искомой подстроки в исходной строке.
119
+ // string.index() возвращает позицию первого вхождения $replaceable
120
+ // в $string или null, если подстрока не найдена.
121
+ $-index: string.index($string, $replaceable);
122
+
123
+ // Проверка: найдено ли хотя бы одно вхождение подстроки.
124
+ @if $-index {
125
+
126
+ // Рекурсивная замена всех вхождений подстроки.
127
+ // Алгоритм:
128
+ // 1. string.slice($string, 1, $-index - 1) - часть строки
129
+ // до первого вхождения заменяемой подстроки
130
+ // 2. + $replacement - добавляем строку-замену
131
+ // 3. + string-replace(string.slice($string, $-index + string.length($replaceable)), ...)
132
+ // - рекурсивный вызов функции для оставшейся части строки
133
+ // (после первого вхождения заменяемой подстроки)
134
+ //
135
+ // Рекурсия продолжается до тех пор, пока в строке
136
+ // не останется вхождений заменяемой подстроки.
137
+ @return string.slice($string, 1, $-index - 1) + $replacement + string-replace(string.slice($string, $-index + string.length($replaceable)), $replaceable, $replacement);
138
+
139
+ }
140
+
141
+ // Если подстрока не найдена, возвращаем исходную строку без изменений.
142
+ // Это базовый случай рекурсии.
143
+ @return $string;
144
+
145
+ }
68
146
 
69
147
  }