@visulima/string 3.0.0-alpha.2 → 3.0.0-alpha.4
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.
- package/CHANGELOG.md +21 -0
- package/README.md +40 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/packem_shared/countOccurrences-CS9XprQN.js +22 -0
- package/dist/packem_shared/direction-BVhR8MOQ.js +10 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## @visulima/string [3.0.0-alpha.4](https://github.com/visulima/visulima/compare/@visulima/string@3.0.0-alpha.3...@visulima/string@3.0.0-alpha.4) (2025-12-13)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* add string analysis functions for counting occurrences and detecting text direction ([de84ab0](https://github.com/visulima/visulima/commit/de84ab072e36d3fc834dd8d971db46fd62be249a))
|
|
6
|
+
|
|
7
|
+
### Miscellaneous Chores
|
|
8
|
+
|
|
9
|
+
* fixed project.json names and schema path ([964722f](https://github.com/visulima/visulima/commit/964722f691db205c7edb9aa6db29e849a647500b))
|
|
10
|
+
|
|
11
|
+
## @visulima/string [3.0.0-alpha.3](https://github.com/visulima/visulima/compare/@visulima/string@3.0.0-alpha.2...@visulima/string@3.0.0-alpha.3) (2025-12-11)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* update package OG images across multiple packages ([f08e4dd](https://github.com/visulima/visulima/commit/f08e4dd2b105ccb29c8412020a9c2be36d6c1e9e))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
* **@visulima/colorize:** upgraded to 2.0.0-alpha.3
|
|
21
|
+
|
|
1
22
|
## @visulima/string [3.0.0-alpha.2](https://github.com/visulima/visulima/compare/@visulima/string@3.0.0-alpha.1...@visulima/string@3.0.0-alpha.2) (2025-12-08)
|
|
2
23
|
|
|
3
24
|
### Features
|
package/README.md
CHANGED
|
@@ -59,6 +59,10 @@
|
|
|
59
59
|
- Handles template literals and string inputs
|
|
60
60
|
- Normalizes newlines across platforms
|
|
61
61
|
- Configurable trimming behavior
|
|
62
|
+
- **String Analysis**:
|
|
63
|
+
- `countOccurrences`: Count occurrences of a substring in a string
|
|
64
|
+
- `direction`: Detect text direction (left-to-right, right-to-left, or neutral)
|
|
65
|
+
- Unicode-aware and handles multi-byte characters
|
|
62
66
|
- **String Width Calculation**:
|
|
63
67
|
- `getStringWidth`: Calculate visual width of strings with Unicode support
|
|
64
68
|
- `getStringTruncatedWidth`: Width calculation with smart truncation
|
|
@@ -392,6 +396,42 @@ splitByCase("🎉HappyBirthday🎂", {
|
|
|
392
396
|
// ['🎉', 'Happy', 'Birthday', '🎂']
|
|
393
397
|
```
|
|
394
398
|
|
|
399
|
+
### String Analysis
|
|
400
|
+
|
|
401
|
+
The `countOccurrences` function counts how many times a substring appears in a string, with full Unicode support:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
import { countOccurrences } from "@visulima/string";
|
|
405
|
+
|
|
406
|
+
// Basic counting
|
|
407
|
+
countOccurrences("foo", "o"); // 2
|
|
408
|
+
countOccurrences("fo fooo fo", "o"); // 5
|
|
409
|
+
|
|
410
|
+
// Unicode support
|
|
411
|
+
countOccurrences("a🤔b🤔c", "🤔"); // 2
|
|
412
|
+
|
|
413
|
+
// Empty string handling
|
|
414
|
+
countOccurrences("", "f"); // 0
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
The `direction` function detects text direction for internationalization:
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { direction } from "@visulima/string";
|
|
421
|
+
|
|
422
|
+
// Left-to-right languages
|
|
423
|
+
direction("english"); // 'ltr'
|
|
424
|
+
direction("Hello World"); // 'ltr'
|
|
425
|
+
|
|
426
|
+
// Right-to-left languages
|
|
427
|
+
direction("الجملة"); // 'rtl' (Arabic)
|
|
428
|
+
direction("נ"); // 'rtl' (Hebrew)
|
|
429
|
+
|
|
430
|
+
// Neutral (numbers, symbols, empty)
|
|
431
|
+
direction("123"); // 'neutral'
|
|
432
|
+
direction(""); // 'neutral'
|
|
433
|
+
```
|
|
434
|
+
|
|
395
435
|
### Case Conversion Functions
|
|
396
436
|
|
|
397
437
|
#### camelCase
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,10 @@ export { WordSimilaritySortOptions, wordSimilaritySort } from './word-similarity
|
|
|
36
36
|
export { WordWrapOptions, WrapMode, wordWrap } from './word-wrap.js';
|
|
37
37
|
import './packem_shared/lru-cache-B_t27XwI.js';
|
|
38
38
|
|
|
39
|
+
declare const countOccurrences: (value: string, substring: string) => number;
|
|
40
|
+
|
|
41
|
+
declare const direction: (value: string) => "rtl" | "ltr" | "neutral";
|
|
42
|
+
|
|
39
43
|
declare const excerpt: (html: string, limit: number, options?: ExcerptOptions) => string;
|
|
40
44
|
type ExcerptOptions = Omit<TruncateOptions, "position">;
|
|
41
45
|
|
|
@@ -48,5 +52,5 @@ declare const replaceString: (source: string, searches: OptionReplaceArray, igno
|
|
|
48
52
|
|
|
49
53
|
declare const transliterate: (source: string, options?: OptionsTransliterate) => string;
|
|
50
54
|
|
|
51
|
-
export { IntervalArray, OptionReplaceArray, OptionsTransliterate, TruncateOptions, closest, closestN, distance, excerpt, replaceString, transliterate };
|
|
55
|
+
export { IntervalArray, OptionReplaceArray, OptionsTransliterate, TruncateOptions, closest, closestN, countOccurrences, direction, distance, excerpt, replaceString, transliterate };
|
|
52
56
|
export type { ExcerptOptions };
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,8 @@ export { default as upperFirst } from './case/upper-first.js';
|
|
|
21
21
|
export { default as joinSegments } from './packem_shared/joinSegments-B4H6oZ9b.js';
|
|
22
22
|
export { closestString } from './closest-string.js';
|
|
23
23
|
export { compareSimilarity } from './compare-similarity.js';
|
|
24
|
+
export { countOccurrences } from './packem_shared/countOccurrences-CS9XprQN.js';
|
|
25
|
+
export { direction } from './packem_shared/direction-BVhR8MOQ.js';
|
|
24
26
|
export { excerpt } from './packem_shared/excerpt-GvmR4ESb.js';
|
|
25
27
|
export { getStringTruncatedWidth } from './get-string-truncated-width.js';
|
|
26
28
|
export { getStringWidth } from './get-string-width.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const countOccurrences = (value, substring) => {
|
|
2
|
+
const source = String(value);
|
|
3
|
+
if (typeof substring !== "string") {
|
|
4
|
+
throw new TypeError("Expected character");
|
|
5
|
+
}
|
|
6
|
+
if (substring.length === 0) {
|
|
7
|
+
throw new TypeError("Expected non-empty substring");
|
|
8
|
+
}
|
|
9
|
+
let count = 0;
|
|
10
|
+
let index = source.indexOf(substring);
|
|
11
|
+
while (index !== -1) {
|
|
12
|
+
count++;
|
|
13
|
+
const nextIndex = index + substring.length;
|
|
14
|
+
if (nextIndex <= index) {
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
index = source.indexOf(substring, nextIndex);
|
|
18
|
+
}
|
|
19
|
+
return count;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { countOccurrences };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const rtlRange = "֑-߿יִ-﷽ﹰ-ﻼ";
|
|
2
|
+
const ltrRange = "A-Za-zÀ-ÖØ-öø-ʸ̀-ࠀ-Ⰰ-︀--";
|
|
3
|
+
const rtl = new RegExp("^[^" + ltrRange + "]*[" + rtlRange + "]");
|
|
4
|
+
const ltr = new RegExp("^[^" + rtlRange + "]*[" + ltrRange + "]");
|
|
5
|
+
const direction = (value) => {
|
|
6
|
+
const source = String(value || "");
|
|
7
|
+
return rtl.test(source) ? "rtl" : ltr.test(source) ? "ltr" : "neutral";
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { direction };
|