@visulima/string 3.0.0-alpha.9 → 3.1.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 (128) hide show
  1. package/CHANGELOG.md +305 -0
  2. package/LICENSE.md +68 -3
  3. package/README.md +80 -2
  4. package/dist/align-text.d.ts +35 -0
  5. package/dist/align-text.js +2 -34
  6. package/dist/case/camel-case.d.ts +17 -3
  7. package/dist/case/camel-case.js +1 -55
  8. package/dist/case/capital-case.d.ts +14 -3
  9. package/dist/case/capital-case.js +1 -47
  10. package/dist/case/constant-case.d.ts +14 -3
  11. package/dist/case/constant-case.js +1 -7
  12. package/dist/case/dot-case.d.ts +14 -3
  13. package/dist/case/dot-case.js +1 -7
  14. package/dist/case/flat-case.d.ts +12 -3
  15. package/dist/case/flat-case.js +1 -7
  16. package/dist/case/flip-case.d.ts +16 -3
  17. package/dist/case/flip-case.js +1 -82
  18. package/dist/case/identify-case.d.ts +15 -3
  19. package/dist/case/identify-case.js +1 -66
  20. package/dist/case/index.d.ts +8 -3
  21. package/dist/case/index.js +1 -20
  22. package/dist/case/kebab-case.d.ts +25 -3
  23. package/dist/case/kebab-case.js +1 -55
  24. package/dist/case/lower-first.d.ts +13 -3
  25. package/dist/case/lower-first.js +1 -9
  26. package/dist/case/no-case.d.ts +14 -3
  27. package/dist/case/no-case.js +1 -7
  28. package/dist/case/pascal-case.d.ts +17 -3
  29. package/dist/case/pascal-case.js +1 -48
  30. package/dist/case/pascal-snake-case.d.ts +14 -3
  31. package/dist/case/pascal-snake-case.js +1 -28
  32. package/dist/case/path-case.d.ts +14 -3
  33. package/dist/case/path-case.js +1 -7
  34. package/dist/case/sentence-case.d.ts +14 -3
  35. package/dist/case/sentence-case.js +1 -54
  36. package/dist/case/snake-case.d.ts +14 -3
  37. package/dist/case/snake-case.js +1 -7
  38. package/dist/case/split-by-case.d.ts +29 -3
  39. package/dist/case/split-by-case.js +1 -763
  40. package/dist/case/title-case.d.ts +12 -3
  41. package/dist/case/title-case.js +1 -40
  42. package/dist/case/train-case.d.ts +14 -3
  43. package/dist/case/train-case.js +1 -40
  44. package/dist/case/upper-first.d.ts +13 -3
  45. package/dist/case/upper-first.js +1 -9
  46. package/dist/closest-string.d.ts +32 -0
  47. package/dist/closest-string.js +1 -22
  48. package/dist/compare-similarity.d.ts +37 -0
  49. package/dist/compare-similarity.js +1 -12
  50. package/dist/count-occurrences.d.ts +9 -0
  51. package/dist/count-occurrences.js +1 -0
  52. package/dist/direction.d.ts +7 -0
  53. package/dist/direction.js +1 -0
  54. package/dist/east-asian-width.d.ts +58 -0
  55. package/dist/east-asian-width.js +1 -0
  56. package/dist/excerpt.d.ts +25 -0
  57. package/dist/excerpt.js +53 -0
  58. package/dist/get-string-truncated-width.d.ts +151 -0
  59. package/dist/get-string-truncated-width.js +1 -332
  60. package/dist/get-string-width.d.ts +58 -0
  61. package/dist/get-string-width.js +1 -5
  62. package/dist/indent.d.ts +88 -0
  63. package/dist/indent.js +1 -0
  64. package/dist/index.d.ts +12 -20
  65. package/dist/index.js +1 -44
  66. package/dist/is-fullwidth-code-point.d.ts +7 -0
  67. package/dist/is-fullwidth-code-point.js +1 -0
  68. package/dist/levenshtein.d.ts +25 -0
  69. package/dist/levenshtein.js +1 -0
  70. package/dist/native-string-types.d.ts +241 -18
  71. package/dist/outdent.d.ts +74 -0
  72. package/dist/outdent.js +1 -109
  73. package/dist/packem_shared/_isFullWidth-Dqc3MWgl.js +1 -0
  74. package/dist/packem_shared/closest-C6YDQs4m.js +1 -0
  75. package/dist/packem_shared/constants-aPzGW29R.js +1 -0
  76. package/dist/packem_shared/dedent-CPjAYUXh.js +1 -0
  77. package/dist/packem_shared/eastAsianWidth-DJV8Kqd-.js +1 -0
  78. package/dist/packem_shared/generate-cache-key-B_0X7MKm.js +1 -0
  79. package/dist/packem_shared/indent-cz8WMI0e.js +1 -0
  80. package/dist/packem_shared/joinSegments-CaHT-45s.js +1 -0
  81. package/dist/packem_shared/lru-cache-BtMSrYQJ.js +1 -0
  82. package/dist/packem_shared/normalize-german-eszett-hNMwtGjd.js +1 -0
  83. package/dist/packem_shared/redent-ByOoJ6fN.js +1 -0
  84. package/dist/packem_shared/strip-vt-control-characters-BW1RglLp.js +1 -0
  85. package/dist/packem_shared/types.d-CMNqA5bi.d.ts +402 -0
  86. package/dist/packem_shared/types.d-LgsTR37y.d.ts +360 -0
  87. package/dist/replace-string.d.ts +10 -0
  88. package/dist/replace-string.js +1 -0
  89. package/dist/slice.d.ts +42 -0
  90. package/dist/slice.js +1 -415
  91. package/dist/slugify.d.ts +10 -1
  92. package/dist/slugify.js +1 -46
  93. package/dist/test/utils.d.ts +17 -0
  94. package/dist/test/utils.js +13 -88
  95. package/dist/test/vitest.d.ts +3 -0
  96. package/dist/test/vitest.js +1 -5
  97. package/dist/transliterate.d.ts +10 -0
  98. package/dist/transliterate.js +5 -0
  99. package/dist/truncate.d.ts +43 -0
  100. package/dist/truncate.js +1 -112
  101. package/dist/utilities.d.ts +28 -2
  102. package/dist/utilities.js +1 -52
  103. package/dist/word-similarity-sort.d.ts +34 -0
  104. package/dist/word-similarity-sort.js +1 -22
  105. package/dist/word-wrap.d.ts +44 -0
  106. package/dist/word-wrap.js +8 -639
  107. package/package.json +70 -36
  108. package/dist/packem_shared/LRUCache-3r3SovvR.js +0 -46
  109. package/dist/packem_shared/closest-IHuSvnSn.js +0 -139
  110. package/dist/packem_shared/closestN-DUsjgiXb.js +0 -25
  111. package/dist/packem_shared/constants-BsZS5f0z.js +0 -95
  112. package/dist/packem_shared/countOccurrences-CS9XprQN.js +0 -22
  113. package/dist/packem_shared/direction-C9gfWWTK.js +0 -16
  114. package/dist/packem_shared/eastAsianWidthType-SD3YniiT.js +0 -20
  115. package/dist/packem_shared/excerpt-COsVNttN.js +0 -1502
  116. package/dist/packem_shared/generate-cache-key-DdayDfjV.js +0 -6
  117. package/dist/packem_shared/indent-D3DSCa6s.js +0 -33
  118. package/dist/packem_shared/isFullwidthCodePoint-IFXZxNjq.js +0 -10
  119. package/dist/packem_shared/joinSegments-CvxSgKz0.js +0 -44
  120. package/dist/packem_shared/lookup-BE8lEqy4.js +0 -104
  121. package/dist/packem_shared/lru-cache.d-BsP6kbVJ.d.ts +0 -13
  122. package/dist/packem_shared/normalize-german-eszett-4p3yKEzn.js +0 -8
  123. package/dist/packem_shared/redent-DSb1IJWn.js +0 -8
  124. package/dist/packem_shared/replaceString-Ce8X2ZQ-.js +0 -192
  125. package/dist/packem_shared/stripIndent-D_TRjxZ_.js +0 -20
  126. package/dist/packem_shared/transliterate-CKt9VK7D.js +0 -47756
  127. package/dist/packem_shared/types.d-BVNv675q.d.ts +0 -61
  128. package/dist/packem_shared/types.d-DfgbcNKh.d.ts +0 -57
package/dist/word-wrap.js CHANGED
@@ -1,639 +1,8 @@
1
- import { O as ESCAPES, P as ANSI_ESCAPE_LINK, Q as ANSI_SGR_TERMINATOR, S as ANSI_ESCAPE_BELL, T as ANSI_CSI, U as RE_ESCAPE_PATTERN, V as ANSI_RESET_CODES, W as END_CODE, X as RE_ZERO_WIDTH } from './packem_shared/constants-BsZS5f0z.js';
2
- import { getStringWidth } from './get-string-width.js';
3
-
4
- const RE_ANSI_CODE = /\x1B\[(\d+)m/;
5
- class AnsiStateTracker {
6
- activeForeground = void 0;
7
- activeBackground = void 0;
8
- // Track other formatting (bold, italic, etc.)
9
- activeFormatting = [];
10
- /**
11
- * Processes an escape sequence and updates the internal state
12
- * @param sequence The escape sequence to process
13
- */
14
- processEscape(sequence) {
15
- const match = RE_ANSI_CODE.exec(sequence);
16
- if (!match) {
17
- return;
18
- }
19
- const code = Number.parseInt(match[1], 10);
20
- switch (code) {
21
- case 0: {
22
- this.activeForeground = void 0;
23
- this.activeBackground = void 0;
24
- this.activeFormatting = [];
25
- break;
26
- }
27
- case 39: {
28
- this.activeForeground = void 0;
29
- break;
30
- }
31
- case 49: {
32
- this.activeBackground = void 0;
33
- break;
34
- }
35
- default: {
36
- if (code >= 30 && code <= 37 || code >= 90 && code <= 97) {
37
- this.activeForeground = sequence;
38
- } else if (code >= 40 && code <= 47 || code >= 100 && code <= 107) {
39
- this.activeBackground = sequence;
40
- } else if ([1, 2, 3, 4, 7, 8, 9].includes(code)) {
41
- this.activeFormatting.push(sequence);
42
- } else if ([22, 23, 24, 27, 28, 29].includes(code)) {
43
- const formatResetMap = {
44
- 22: "[1m",
45
- // Reset bold
46
- 23: "[3m",
47
- // Reset italic
48
- 24: "[4m",
49
- // Reset underline
50
- 27: "[7m",
51
- // Reset inverse
52
- 28: "[8m",
53
- // Reset hidden
54
- 29: "[9m"
55
- // Reset strikethrough
56
- };
57
- const formatToRemove = formatResetMap[code];
58
- if (formatToRemove) {
59
- this.activeFormatting = this.activeFormatting.filter((fmt) => !fmt.includes(formatToRemove));
60
- }
61
- }
62
- }
63
- }
64
- }
65
- /**
66
- * Gets all active escape sequences to apply.
67
- * @returns String with all active escapes
68
- */
69
- getStartEscapesForAllActiveAttributes() {
70
- return [this.activeBackground, this.activeForeground, ...this.activeFormatting].filter(Boolean).join("");
71
- }
72
- /**
73
- * Gets all closing escape sequences for the currently active attributes.
74
- * The order is generally reverse of application: formatting, foreground, background.
75
- * @returns String with all necessary closing escapes.
76
- */
77
- getEndEscapesForAllActiveAttributes() {
78
- const closingEscapes = [];
79
- if (this.activeFormatting.length > 0) {
80
- const formatResetMap = {
81
- "\x1B[1m": "\x1B[22m",
82
- // Bold
83
- "\x1B[2m": "\x1B[22m",
84
- // Faint/Dim (also reset by 22)
85
- "\x1B[3m": "\x1B[23m",
86
- // Italic
87
- "\x1B[4m": "\x1B[24m",
88
- // Underline
89
- "\x1B[7m": "\x1B[27m",
90
- // Inverse
91
- "\x1B[8m": "\x1B[28m",
92
- // Hidden/Conceal
93
- "\x1B[9m": "\x1B[29m"
94
- // Strikethrough
95
- };
96
- [...this.activeFormatting].toReversed().forEach((formatCode) => {
97
- const resetCode = formatResetMap[formatCode];
98
- if (resetCode) {
99
- closingEscapes.push(resetCode);
100
- }
101
- });
102
- }
103
- if (this.activeForeground) {
104
- closingEscapes.push("\x1B[39m");
105
- }
106
- if (this.activeBackground) {
107
- closingEscapes.push("\x1B[49m");
108
- }
109
- return closingEscapes.join("");
110
- }
111
- }
112
-
113
- const checkEscapeSequence = (chars, index) => {
114
- if (!ESCAPES.has(chars[index])) {
115
- return { isInsideEscape: false, isInsideLinkEscape: false };
116
- }
117
- const isInsideEscape = true;
118
- const possibleLink = chars.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("");
119
- const isInsideLinkEscape = possibleLink === ANSI_ESCAPE_LINK;
120
- return { isInsideEscape, isInsideLinkEscape };
121
- };
122
- const processAnsiString = (string, options = {}) => {
123
- const stateTracker = new AnsiStateTracker();
124
- let currentText = "";
125
- let isInsideEscape = false;
126
- let escapeBuffer = "";
127
- let currentUrl = "";
128
- let isInHyperlink = false;
129
- const chars = [...string];
130
- for (let index = 0; index < chars.length; index++) {
131
- const character = chars[index];
132
- if (character && ESCAPES.has(character)) {
133
- if (currentText) {
134
- const width2 = options.getWidth?.(currentText) ?? 0;
135
- const segment2 = {
136
- isEscapeSequence: false,
137
- isGrapheme: true,
138
- text: currentText,
139
- width: width2
140
- };
141
- if (isInHyperlink) {
142
- segment2.isHyperlink = true;
143
- segment2.hyperlinkUrl = currentUrl;
144
- }
145
- if (options.onSegment?.(segment2, stateTracker) === false) {
146
- return;
147
- }
148
- currentText = "";
149
- }
150
- isInsideEscape = true;
151
- escapeBuffer = character;
152
- const escapeInfo = checkEscapeSequence(chars, index);
153
- const { isInsideLinkEscape } = escapeInfo;
154
- if (isInsideLinkEscape) {
155
- let urlEnd = index + 1;
156
- currentUrl = "";
157
- while (urlEnd < chars.length) {
158
- const nextChar = chars[urlEnd];
159
- if (nextChar === ANSI_ESCAPE_BELL) {
160
- break;
161
- }
162
- currentUrl += nextChar;
163
- urlEnd += 1;
164
- }
165
- currentUrl = currentUrl.slice(4);
166
- const segment2 = {
167
- hyperlinkUrl: currentUrl,
168
- isEscapeSequence: true,
169
- isGrapheme: false,
170
- isHyperlink: true,
171
- isHyperlinkStart: true,
172
- width: 0
173
- };
174
- if (options.onSegment?.(segment2, stateTracker) === false) {
175
- return;
176
- }
177
- index = urlEnd;
178
- isInHyperlink = true;
179
- isInsideEscape = false;
180
- escapeBuffer = "";
181
- continue;
182
- }
183
- if (index + 1 < chars.length && chars[index + 1] === "\\" && isInHyperlink) {
184
- const segment2 = {
185
- isEscapeSequence: true,
186
- isGrapheme: false,
187
- isHyperlink: true,
188
- isHyperlinkEnd: true,
189
- width: 0
190
- };
191
- if (options.onSegment?.(segment2, stateTracker) === false) {
192
- return;
193
- }
194
- isInHyperlink = false;
195
- currentUrl = "";
196
- index += 1;
197
- isInsideEscape = false;
198
- escapeBuffer = "";
199
- continue;
200
- }
201
- }
202
- if (isInsideEscape) {
203
- if (escapeBuffer !== character) {
204
- escapeBuffer += character;
205
- }
206
- if (character === ANSI_SGR_TERMINATOR) {
207
- isInsideEscape = false;
208
- stateTracker.processEscape(escapeBuffer);
209
- const segment2 = {
210
- isEscapeSequence: true,
211
- isGrapheme: false,
212
- text: escapeBuffer,
213
- width: 0
214
- };
215
- if (options.onSegment?.(segment2, stateTracker) === false) {
216
- return;
217
- }
218
- escapeBuffer = "";
219
- }
220
- continue;
221
- }
222
- currentText += character;
223
- const width = options.getWidth?.(currentText) ?? 0;
224
- const segment = {
225
- isEscapeSequence: false,
226
- isGrapheme: true,
227
- text: currentText,
228
- width
229
- };
230
- if (isInHyperlink) {
231
- segment.isHyperlink = true;
232
- segment.hyperlinkUrl = currentUrl;
233
- }
234
- if (options.onSegment?.(segment, stateTracker) === false) {
235
- return;
236
- }
237
- currentText = "";
238
- }
239
- if (currentText) {
240
- const width = options.getWidth?.(currentText) ?? 0;
241
- const segment = {
242
- isEscapeSequence: false,
243
- isGrapheme: true,
244
- text: currentText,
245
- width
246
- };
247
- if (isInHyperlink) {
248
- segment.isHyperlink = true;
249
- segment.hyperlinkUrl = currentUrl;
250
- }
251
- options.onSegment?.(segment, stateTracker);
252
- }
253
- if (escapeBuffer) {
254
- const segment = {
255
- isEscapeSequence: true,
256
- isGrapheme: false,
257
- text: escapeBuffer,
258
- width: 0
259
- };
260
- options.onSegment?.(segment, stateTracker);
261
- }
262
- };
263
-
264
- const wrapAnsiCode = (code) => {
265
- const escapeChar = ESCAPES.values().next().value;
266
- return `${escapeChar}${ANSI_CSI}${String(code)}${ANSI_SGR_TERMINATOR}`;
267
- };
268
-
269
- const wrapAnsiHyperlink = (url) => {
270
- const escapeChar = ESCAPES.values().next().value;
271
- return `${escapeChar}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
272
- };
273
-
274
- const preserveAnsi = (rawLines) => {
275
- if (rawLines.length === 0) {
276
- return "";
277
- }
278
- if (rawLines.length === 1) {
279
- return rawLines[0];
280
- }
281
- let returnValue = "";
282
- let escapeCode;
283
- let escapeUrl;
284
- const preString = rawLines.join("\n");
285
- const pre = [...preString];
286
- let preStringIndex = 0;
287
- for (const [index, character] of pre.entries()) {
288
- returnValue += character;
289
- if (ESCAPES.has(character)) {
290
- const match = RE_ESCAPE_PATTERN.exec(preString.slice(preStringIndex));
291
- const groups = match?.groups ?? {};
292
- if (groups.code !== void 0) {
293
- const code2 = Number.parseFloat(groups.code);
294
- escapeCode = code2 === END_CODE ? void 0 : code2;
295
- } else if (groups.uri !== void 0) {
296
- escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
297
- }
298
- }
299
- const code = ANSI_RESET_CODES.get(Number(escapeCode));
300
- if (pre[index + 1] === "\n") {
301
- if (escapeUrl) {
302
- returnValue += wrapAnsiHyperlink("");
303
- }
304
- if (escapeCode && code) {
305
- returnValue += wrapAnsiCode(code);
306
- }
307
- } else if (character === "\n") {
308
- if (escapeCode && code) {
309
- returnValue += wrapAnsiCode(escapeCode);
310
- }
311
- if (escapeUrl) {
312
- returnValue += wrapAnsiHyperlink(escapeUrl);
313
- }
314
- }
315
- preStringIndex += character.length;
316
- }
317
- return returnValue;
318
- };
319
-
320
- const RE_SPLIT_WHITESPACE = /(?=\s)|(?<=\s)/;
321
- const RE_WHITESPACE_ONLY = /^\s+$/;
322
- const resetAnsiAtLineBreak = (currentLine) => {
323
- if (!currentLine.includes("\x1B")) {
324
- return currentLine;
325
- }
326
- let result = currentLine;
327
- if (currentLine.includes("\x1B[30m")) {
328
- result += "\x1B[39m";
329
- }
330
- if (currentLine.includes("\x1B[42m")) {
331
- result += "\x1B[49m";
332
- }
333
- return result;
334
- };
335
- const stringVisibleTrimSpacesRight = (string) => {
336
- const words = string.split(" ");
337
- let last = words.length;
338
- while (last > 0 && getStringWidth(words[last - 1]) === 0) {
339
- last--;
340
- }
341
- if (last === words.length) {
342
- return string;
343
- }
344
- return words.slice(0, last).join(" ") + words.slice(last).join("");
345
- };
346
- const wrapWithBreakAtWidth = (string, width, trim) => {
347
- if (string.length === 0) {
348
- return [""];
349
- }
350
- if (width <= 0) {
351
- return [string];
352
- }
353
- const rows = [];
354
- const ansiTracker = new AnsiStateTracker();
355
- let currentLine = "";
356
- let currentWidth = 0;
357
- let isInsideEscape = false;
358
- let isInsideLinkEscape = false;
359
- let escapeBuffer = "";
360
- let index = 0;
361
- while (index < string.length) {
362
- const char = string[index];
363
- if (ESCAPES.has(char)) {
364
- isInsideEscape = true;
365
- escapeBuffer = char;
366
- currentLine += char;
367
- const escapeInfo = checkEscapeSequence([...string], index);
368
- isInsideLinkEscape = escapeInfo.isInsideLinkEscape;
369
- index += 1;
370
- continue;
371
- }
372
- if (isInsideEscape) {
373
- escapeBuffer += char;
374
- currentLine += char;
375
- if (isInsideLinkEscape) {
376
- if (char === ANSI_ESCAPE_BELL) {
377
- isInsideEscape = isInsideLinkEscape = false;
378
- }
379
- } else if (char === ANSI_SGR_TERMINATOR) {
380
- isInsideEscape = false;
381
- ansiTracker.processEscape(escapeBuffer);
382
- }
383
- index += 1;
384
- continue;
385
- }
386
- const charWidth = getStringWidth(char);
387
- const isSpace = char === " ";
388
- if (charWidth === 0) {
389
- currentLine += char;
390
- index += 1;
391
- continue;
392
- }
393
- if (currentWidth + charWidth > width) {
394
- if (currentLine) {
395
- rows.push(currentLine + ansiTracker.getEndEscapesForAllActiveAttributes());
396
- }
397
- currentLine = ansiTracker.getStartEscapesForAllActiveAttributes();
398
- currentWidth = getStringWidth(currentLine);
399
- if (isSpace && trim) {
400
- while (index < string.length && string[index] === " ") {
401
- index += 1;
402
- }
403
- continue;
404
- }
405
- }
406
- currentLine += char;
407
- currentWidth += charWidth;
408
- if (currentWidth === width && index < string.length - 1) {
409
- rows.push(currentLine + ansiTracker.getEndEscapesForAllActiveAttributes());
410
- currentLine = ansiTracker.getStartEscapesForAllActiveAttributes();
411
- currentWidth = getStringWidth(currentLine);
412
- if (index + 1 < string.length && string[index + 1] === " " && trim) {
413
- index += 1;
414
- while (index < string.length && string[index] === " ") {
415
- index += 1;
416
- }
417
- continue;
418
- }
419
- }
420
- index += 1;
421
- }
422
- if (currentLine) {
423
- rows.push(currentLine + ansiTracker.getEndEscapesForAllActiveAttributes());
424
- }
425
- return trim ? rows.map((element) => stringVisibleTrimSpacesRight(element)) : rows;
426
- };
427
- const wrapCharByChar = (string, width, trim) => {
428
- if (string.length === 0) {
429
- return [];
430
- }
431
- const inputToProcess = trim ? string.trim() : string;
432
- if (inputToProcess.length === 0) {
433
- return [];
434
- }
435
- const rows = [];
436
- let currentLine = "";
437
- let currentWidth = 0;
438
- processAnsiString(inputToProcess, {
439
- getWidth: getStringWidth,
440
- // eslint-disable-next-line sonarjs/cognitive-complexity,sonarjs/no-invariant-returns
441
- onSegment: (segment, stateTracker) => {
442
- const segText = segment.text ?? "";
443
- if (segment.isEscapeSequence) {
444
- currentLine += segText;
445
- } else {
446
- const isSpace = segText === " ";
447
- if (segment.width === 0) {
448
- currentLine += segText;
449
- return true;
450
- }
451
- if (currentWidth + segment.width > width) {
452
- if (currentLine) {
453
- rows.push(currentLine);
454
- }
455
- currentLine = stateTracker.getStartEscapesForAllActiveAttributes();
456
- currentWidth = 0;
457
- if (isSpace) {
458
- if (trim) {
459
- return true;
460
- }
461
- rows.push(stateTracker.getStartEscapesForAllActiveAttributes() + segText);
462
- return true;
463
- }
464
- }
465
- currentLine += segText;
466
- currentWidth += segment.width;
467
- }
468
- return true;
469
- }
470
- });
471
- if (currentLine) {
472
- rows.push(currentLine);
473
- }
474
- return trim ? rows.map((row) => stringVisibleTrimSpacesRight(row)) : rows;
475
- };
476
- const wrapWithWordBoundaries = (string, width, trim) => {
477
- if (string.length === 0) {
478
- return [];
479
- }
480
- const inputToProcess = trim ? string.trim() : string;
481
- if (inputToProcess.length === 0) {
482
- return [];
483
- }
484
- const tokens = inputToProcess.split(RE_SPLIT_WHITESPACE);
485
- const rows = [];
486
- let currentLine = "";
487
- let currentWidth = 0;
488
- let index = 0;
489
- while (index < tokens.length) {
490
- const token = tokens[index];
491
- const isSpace = RE_WHITESPACE_ONLY.test(token);
492
- const tokenVisibleWidth = getStringWidth(token);
493
- if (token.length === 0) {
494
- index += 1;
495
- continue;
496
- }
497
- if (trim && isSpace && currentWidth === 0) {
498
- index += 1;
499
- continue;
500
- }
501
- if (currentWidth + tokenVisibleWidth > width && currentWidth > 0) {
502
- if (trim) {
503
- rows.push(stringVisibleTrimSpacesRight(currentLine));
504
- } else {
505
- rows.push(currentLine);
506
- }
507
- currentLine = "";
508
- currentWidth = 0;
509
- continue;
510
- }
511
- currentLine += token;
512
- currentWidth += tokenVisibleWidth;
513
- index += 1;
514
- }
515
- if (currentLine) {
516
- if (trim) {
517
- rows.push(stringVisibleTrimSpacesRight(currentLine));
518
- } else {
519
- rows.push(currentLine);
520
- }
521
- }
522
- return rows;
523
- };
524
- const wrapAndBreakWords = (string, width, trim) => {
525
- if (string.length === 0) {
526
- return [];
527
- }
528
- const inputToProcess = trim ? string.trim() : string;
529
- if (inputToProcess.length === 0) {
530
- return [];
531
- }
532
- const tokens = inputToProcess.split(RE_SPLIT_WHITESPACE);
533
- const rows = [];
534
- let currentLine = "";
535
- let currentWidth = 0;
536
- let index = 0;
537
- while (index < tokens.length) {
538
- const token = tokens[index];
539
- const isSpace = RE_WHITESPACE_ONLY.test(token);
540
- const tokenVisibleWidth = getStringWidth(token);
541
- if (token.length === 0) {
542
- index += 1;
543
- continue;
544
- }
545
- if (trim && isSpace && currentWidth === 0) {
546
- index += 1;
547
- continue;
548
- }
549
- if (tokenVisibleWidth > width) {
550
- if (currentLine) {
551
- rows.push(resetAnsiAtLineBreak(trim ? stringVisibleTrimSpacesRight(currentLine) : currentLine));
552
- }
553
- const brokenLines = wrapWithBreakAtWidth(token, width, trim);
554
- if (brokenLines.length > 0) {
555
- for (let brokenLineIndex = 0; brokenLineIndex < brokenLines.length - 1; brokenLineIndex += 1) {
556
- rows.push(brokenLines[brokenLineIndex]);
557
- }
558
- currentLine = brokenLines.at(-1);
559
- currentWidth = getStringWidth(currentLine);
560
- } else {
561
- currentLine = "";
562
- currentWidth = 0;
563
- }
564
- index += 1;
565
- continue;
566
- }
567
- if (currentWidth + tokenVisibleWidth > width && currentWidth > 0) {
568
- rows.push(resetAnsiAtLineBreak(trim ? stringVisibleTrimSpacesRight(currentLine) : currentLine));
569
- currentLine = "";
570
- currentWidth = 0;
571
- if (trim && isSpace) {
572
- index += 1;
573
- continue;
574
- }
575
- }
576
- currentLine += token;
577
- currentWidth += tokenVisibleWidth;
578
- index += 1;
579
- }
580
- if (currentLine) {
581
- rows.push(resetAnsiAtLineBreak(trim ? stringVisibleTrimSpacesRight(currentLine) : currentLine));
582
- }
583
- return rows;
584
- };
585
- const WrapMode = {
586
- /**
587
- * Breaks words at character boundaries to fit the width
588
- */
589
- BREAK_AT_CHARACTERS: "BREAK_AT_CHARACTERS",
590
- /**
591
- * Breaks lines at word boundaries. If a word is longer than the width, it will be broken.
592
- */
593
- BREAK_WORDS: "BREAK_WORDS",
594
- /**
595
- * Preserves word boundaries, words are kept intact even if they exceed width
596
- */
597
- PRESERVE_WORDS: "PRESERVE_WORDS",
598
- /**
599
- * Enforces strict adherence to the width limit by breaking at exact width
600
- */
601
- STRICT_WIDTH: "STRICT_WIDTH"
602
- };
603
- const wordWrap = (string, options = {}) => {
604
- const { removeZeroWidthCharacters = true, trim = true, width = 80, wrapMode = WrapMode.PRESERVE_WORDS } = options;
605
- if (trim && string.trim() === "") {
606
- return "";
607
- }
608
- let normalizedString = string.normalize("NFC").replaceAll("\r\n", "\n");
609
- if (removeZeroWidthCharacters) {
610
- normalizedString = normalizedString.replaceAll(RE_ZERO_WIDTH, "");
611
- }
612
- const result = normalizedString.split("\n").map((line) => {
613
- if (trim && line.trim() === "") {
614
- return "";
615
- }
616
- let wrappedLines;
617
- switch (wrapMode) {
618
- case WrapMode.BREAK_AT_CHARACTERS: {
619
- wrappedLines = wrapCharByChar(line, width, trim);
620
- break;
621
- }
622
- case WrapMode.BREAK_WORDS: {
623
- wrappedLines = wrapAndBreakWords(line, width, trim);
624
- break;
625
- }
626
- case WrapMode.STRICT_WIDTH: {
627
- wrappedLines = wrapWithBreakAtWidth(line, width, trim);
628
- break;
629
- }
630
- default: {
631
- wrappedLines = wrapWithWordBoundaries(line, width, trim);
632
- }
633
- }
634
- return preserveAnsi(wrappedLines);
635
- });
636
- return result.join("\n");
637
- };
638
-
639
- export { WrapMode, wordWrap };
1
+ import{O as m,P as x,Q as R,S as _,T as D,U as H,V as $,W as N,X as y}from"./packem_shared/constants-aPzGW29R.js";import{getStringWidth as E}from"./get-string-width.js";const O=/\x1B\[(\d+)m/;class W{activeForeground=void 0;activeBackground=void 0;activeFormatting=[];processEscape(t){const s=O.exec(t);if(!s)return;const i=Number.parseInt(s[1],10);switch(i){case 0:{this.activeForeground=void 0,this.activeBackground=void 0,this.activeFormatting=[];break}case 39:{this.activeForeground=void 0;break}case 49:{this.activeBackground=void 0;break}default:if(i>=30&&i<=37||i>=90&&i<=97)this.activeForeground=t;else if(i>=40&&i<=47||i>=100&&i<=107)this.activeBackground=t;else if([1,2,3,4,7,8,9].includes(i))this.activeFormatting.push(t);else if([22,23,24,27,28,29].includes(i)){const u={22:"[1m",23:"[3m",24:"[4m",27:"[7m",28:"[8m",29:"[9m"}[i];u&&(this.activeFormatting=this.activeFormatting.filter(n=>!n.includes(u)))}}}getStartEscapesForAllActiveAttributes(){return[this.activeBackground,this.activeForeground,...this.activeFormatting].filter(Boolean).join("")}getEndEscapesForAllActiveAttributes(){const t=[];if(this.activeFormatting.length>0){const s={"\x1B[1m":"\x1B[22m","\x1B[2m":"\x1B[22m","\x1B[3m":"\x1B[23m","\x1B[4m":"\x1B[24m","\x1B[7m":"\x1B[27m","\x1B[8m":"\x1B[28m","\x1B[9m":"\x1B[29m"};[...this.activeFormatting].toReversed().forEach(i=>{const u=s[i];u&&t.push(u)})}return this.activeForeground&&t.push("\x1B[39m"),this.activeBackground&&t.push("\x1B[49m"),t.join("")}}const P=(e,t)=>{if(!m.has(e[t]))return{isInsideEscape:!1,isInsideLinkEscape:!1};const s=!0,i=e.slice(t+1,t+1+R.length).join("")===R;return{isInsideEscape:s,isInsideLinkEscape:i}},q=(e,t={})=>{const s=new W;let i="",u=!1,n="",r="",o=!1;const a=[...e];for(let l=0;l<a.length;l++){const c=a[l];if(c&&m.has(c)){if(i){const g=t.getWidth?.(i)??0,A={isEscapeSequence:!1,isGrapheme:!0,text:i,width:g};if(o&&(A.isHyperlink=!0,A.hyperlinkUrl=r),t.onSegment?.(A,s)===!1)return;i=""}u=!0,n=c;const p=P(a,l),{isInsideLinkEscape:S}=p;if(S){let g=l+1;for(r="";g<a.length;){const k=a[g];if(k===_)break;r+=k,g+=1}r=r.slice(4);const A={hyperlinkUrl:r,isEscapeSequence:!0,isGrapheme:!1,isHyperlink:!0,isHyperlinkStart:!0,width:0};if(t.onSegment?.(A,s)===!1)return;l=g,o=!0,u=!1,n="";continue}if(l+1<a.length&&a[l+1]==="\\"&&o){const g={isEscapeSequence:!0,isGrapheme:!1,isHyperlink:!0,isHyperlinkEnd:!0,width:0};if(t.onSegment?.(g,s)===!1)return;o=!1,r="",l+=1,u=!1,n="";continue}}if(u){if(n!==c&&(n+=c),c===x){u=!1,s.processEscape(n);const p={isEscapeSequence:!0,isGrapheme:!1,text:n,width:0};if(t.onSegment?.(p,s)===!1)return;n=""}continue}i+=c;const f=t.getWidth?.(i)??0,h={isEscapeSequence:!1,isGrapheme:!0,text:i,width:f};if(o&&(h.isHyperlink=!0,h.hyperlinkUrl=r),t.onSegment?.(h,s)===!1)return;i=""}if(i){const l=t.getWidth?.(i)??0,c={isEscapeSequence:!1,isGrapheme:!0,text:i,width:l};o&&(c.isHyperlink=!0,c.hyperlinkUrl=r),t.onSegment?.(c,s)}if(n){const l={isEscapeSequence:!0,isGrapheme:!1,text:n,width:0};t.onSegment?.(l,s)}},F=e=>`${m.values().next().value}${D}${String(e)}${x}`,T=e=>`${m.values().next().value}${R}${e}${_}`,G=e=>{if(e.length===0)return"";if(e.length===1)return e[0];let t="",s,i;const u=e.join(`
2
+ `),n=[...u];let r=0;for(const[o,a]of n.entries()){if(t+=a,m.has(a)){const c=H.exec(u.slice(r))?.groups??{};if(c.code!==void 0){const f=Number.parseFloat(c.code);s=f===N?void 0:f}else c.uri!==void 0&&(i=c.uri.length===0?void 0:c.uri)}const l=$.get(Number(s));n[o+1]===`
3
+ `?(i&&(t+=T("")),s&&l&&(t+=F(l))):a===`
4
+ `&&(s&&l&&(t+=F(s)),i&&(t+=T(i))),r+=a.length}return t},b=/(?=\s)|(?<=\s)/,C=/^\s+$/,I=new Map,j=e=>{const t=I.get(e);if(t!==void 0)return t;const s=E(e);return I.set(e,s),s},B=e=>{if(!e.includes("\x1B"))return e;let t=e;return e.includes("\x1B[30m")&&(t+="\x1B[39m"),e.includes("\x1B[42m")&&(t+="\x1B[49m"),t},d=e=>{const t=e.split(" ");let s=t.length;for(;s>0&&E(t[s-1])===0;)s--;return s===t.length?e:t.slice(0,s).join(" ")+t.slice(s).join("")},w=(e,t,s)=>{if(e.length===0)return[""];if(t<=0)return[e];const i=[],u=new W;let n="",r=0,o=!1,a=!1,l="",c=0;for(;c<e.length;){const f=e.codePointAt(c),h=String.fromCodePoint(f),p=h.length;if(m.has(h)){o=!0,l=h,n+=h,a=e.startsWith(R,c+1),c+=1;continue}if(o){l+=h,n+=h,a?h===_&&(o=a=!1):h===x&&(o=!1,u.processEscape(l)),c+=1;continue}const S=j(h),g=h===" ";if(S===0){n+=h,c+=p;continue}if(r+S>t&&(n&&i.push(n+u.getEndEscapesForAllActiveAttributes()),n=u.getStartEscapesForAllActiveAttributes(),r=E(n),g&&s)){for(;c<e.length&&e[c]===" ";)c+=1;continue}if(n+=h,r+=S,r===t&&c+p<e.length&&(i.push(n+u.getEndEscapesForAllActiveAttributes()),n=u.getStartEscapesForAllActiveAttributes(),r=E(n),c+p<e.length&&e[c+p]===" "&&s)){for(c+=p;c<e.length&&e[c]===" ";)c+=1;continue}c+=p}return n&&i.push(n+u.getEndEscapesForAllActiveAttributes()),s?i.map(f=>d(f)):i},K=(e,t,s)=>{if(e.length===0)return[];const i=s?e.trim():e;if(i.length===0)return[];const u=[];let n="",r=0;return q(i,{getWidth:E,onSegment:(o,a)=>{const l=o.text??"";if(o.isEscapeSequence)n+=l;else{const c=l===" ";if(o.width===0)return n+=l,!0;if(r+o.width>t&&(n&&u.push(n),n=a.getStartEscapesForAllActiveAttributes(),r=0,c))return s||u.push(a.getStartEscapesForAllActiveAttributes()+l),!0;n+=l,r+=o.width}return!0}}),n&&u.push(n),s?u.map(o=>d(o)):u},L=(e,t,s)=>{if(e.length===0)return[];const i=s?e.trim():e;if(i.length===0)return[];const u=i.split(b),n=[];let r="",o=0,a=0;for(;a<u.length;){const l=u[a],c=C.test(l),f=E(l);if(l.length===0){a+=1;continue}if(s&&c&&o===0){a+=1;continue}if(o+f>t&&o>0){s?n.push(d(r)):n.push(r),r="",o=0;continue}r+=l,o+=f,a+=1}return r&&(s?n.push(d(r)):n.push(r)),n},U=(e,t,s)=>{if(e.length===0)return[];const i=s?e.trim():e;if(i.length===0)return[];const u=i.split(b),n=[];let r="",o=0,a=0;for(;a<u.length;){const l=u[a],c=C.test(l),f=E(l);if(l.length===0){a+=1;continue}if(s&&c&&o===0){a+=1;continue}if(f>t){r&&n.push(B(s?d(r):r));const h=w(l,t,s);if(h.length>0){for(let p=0;p<h.length-1;p+=1)n.push(h[p]);r=h.at(-1),o=E(r)}else r="",o=0;a+=1;continue}if(o+f>t&&o>0&&(n.push(B(s?d(r):r)),r="",o=0,s&&c)){a+=1;continue}r+=l,o+=f,a+=1}return r&&n.push(B(s?d(r):r)),n},v={BREAK_AT_CHARACTERS:"BREAK_AT_CHARACTERS",BREAK_WORDS:"BREAK_WORDS",PRESERVE_WORDS:"PRESERVE_WORDS",STRICT_WIDTH:"STRICT_WIDTH"},Z=(e,t={})=>{const{removeZeroWidthCharacters:s=!0,trim:i=!0,width:u=80,wrapMode:n=v.PRESERVE_WORDS}=t;if(i&&e.trim()==="")return"";let r=e.normalize("NFC").replaceAll(`\r
5
+ `,`
6
+ `);return s&&(r=r.replaceAll(y,"")),r.split(`
7
+ `).map(o=>{if(i&&o.trim()==="")return"";let a;switch(n){case v.BREAK_AT_CHARACTERS:{a=K(o,u,i);break}case v.BREAK_WORDS:{a=U(o,u,i);break}case v.STRICT_WIDTH:{a=w(o,u,i);break}default:a=L(o,u,i)}return G(a)}).join(`
8
+ `)};export{v as WrapMode,Z as wordWrap};