pythonlib 0.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.
- package/README.md +183 -0
- package/dist/chunk-3CSEXTA7.js +376 -0
- package/dist/chunk-3CSEXTA7.js.map +1 -0
- package/dist/chunk-HA5Y7PKO.js +680 -0
- package/dist/chunk-HA5Y7PKO.js.map +1 -0
- package/dist/chunk-IVYYI2VR.js +261 -0
- package/dist/chunk-IVYYI2VR.js.map +1 -0
- package/dist/chunk-OMQNGE6T.js +245 -0
- package/dist/chunk-OMQNGE6T.js.map +1 -0
- package/dist/chunk-P3SGIF72.js +107 -0
- package/dist/chunk-P3SGIF72.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-TJFGYXBJ.js +310 -0
- package/dist/chunk-TJFGYXBJ.js.map +1 -0
- package/dist/chunk-TOI6IG3T.js +337 -0
- package/dist/chunk-TOI6IG3T.js.map +1 -0
- package/dist/chunk-UFMTN4T4.js +215 -0
- package/dist/chunk-UFMTN4T4.js.map +1 -0
- package/dist/chunk-V63LKSA3.js +423 -0
- package/dist/chunk-V63LKSA3.js.map +1 -0
- package/dist/chunk-WAONBJE5.js +236 -0
- package/dist/chunk-WAONBJE5.js.map +1 -0
- package/dist/collections-xN9Gi0TA.d.ts +113 -0
- package/dist/collections.d.ts +1 -0
- package/dist/collections.js +12 -0
- package/dist/collections.js.map +1 -0
- package/dist/datetime-DRwFAiGV.d.ts +139 -0
- package/dist/datetime.d.ts +1 -0
- package/dist/datetime.js +22 -0
- package/dist/datetime.js.map +1 -0
- package/dist/functools-St5GqpKG.d.ts +125 -0
- package/dist/functools.d.ts +1 -0
- package/dist/functools.js +32 -0
- package/dist/functools.js.map +1 -0
- package/dist/index.d.ts +624 -0
- package/dist/index.js +1332 -0
- package/dist/index.js.map +1 -0
- package/dist/itertools-Bj8XivI6.d.ts +138 -0
- package/dist/itertools.d.ts +1 -0
- package/dist/itertools.js +44 -0
- package/dist/itertools.js.map +1 -0
- package/dist/json-Xpk0kwSd.d.ts +77 -0
- package/dist/json.d.ts +1 -0
- package/dist/json.js +14 -0
- package/dist/json.js.map +1 -0
- package/dist/math-BrT4Aw3E.d.ts +147 -0
- package/dist/math.d.ts +1 -0
- package/dist/math.js +96 -0
- package/dist/math.js.map +1 -0
- package/dist/os-FRSJbEUH.d.ts +143 -0
- package/dist/os.d.ts +1 -0
- package/dist/os.js +58 -0
- package/dist/os.js.map +1 -0
- package/dist/random-D5S5iSV3.d.ts +72 -0
- package/dist/random.d.ts +1 -0
- package/dist/random.js +42 -0
- package/dist/random.js.map +1 -0
- package/dist/re-DSxiURqN.d.ts +148 -0
- package/dist/re.d.ts +1 -0
- package/dist/re.js +52 -0
- package/dist/re.js.map +1 -0
- package/dist/string.d.ts +166 -0
- package/dist/string.js +30 -0
- package/dist/string.js.map +1 -0
- package/package.json +85 -0
package/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# pythonlib
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/pythonlib)
|
|
4
|
+
[](https://github.com/sebastian-software/python2ts/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
**Python standard library for TypeScript** — itertools, functools, collections, and more.
|
|
7
|
+
|
|
8
|
+
Zero dependencies. Full TypeScript support. Tree-shakeable.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install pythonlib
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { range, enumerate, sorted, len } from "pythonlib"
|
|
20
|
+
import { combinations } from "pythonlib/itertools"
|
|
21
|
+
import { Counter } from "pythonlib/collections"
|
|
22
|
+
|
|
23
|
+
// Python-style iteration
|
|
24
|
+
for (const i of range(10)) {
|
|
25
|
+
console.log(i)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Combinatorics
|
|
29
|
+
for (const combo of combinations([1, 2, 3], 2)) {
|
|
30
|
+
console.log(combo) // [1,2], [1,3], [2,3]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Count occurrences
|
|
34
|
+
const counter = new Counter("mississippi")
|
|
35
|
+
console.log(counter.mostCommon(2)) // [["i", 4], ["s", 4]]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Import Structure
|
|
39
|
+
|
|
40
|
+
pythonlib uses subpath exports for tree-shakeable imports:
|
|
41
|
+
|
|
42
|
+
| Import Path | Contents |
|
|
43
|
+
| ----------------------- | -------------------------------------------------- |
|
|
44
|
+
| `pythonlib` | Builtins: `len`, `range`, `sorted`, `enumerate` |
|
|
45
|
+
| `pythonlib/itertools` | `chain`, `combinations`, `permutations`, `product` |
|
|
46
|
+
| `pythonlib/functools` | `partial`, `reduce`, `lru_cache`, `cache` |
|
|
47
|
+
| `pythonlib/collections` | `Counter`, `defaultdict`, `deque` |
|
|
48
|
+
| `pythonlib/math` | `sqrt`, `floor`, `ceil`, `factorial`, `pi`, `e` |
|
|
49
|
+
| `pythonlib/random` | `randint`, `choice`, `shuffle`, `sample` |
|
|
50
|
+
| `pythonlib/datetime` | `datetime`, `date`, `time`, `timedelta` |
|
|
51
|
+
| `pythonlib/json` | `loads`, `dumps`, `load`, `dump` |
|
|
52
|
+
| `pythonlib/re` | `search`, `match`, `findall`, `sub`, `compile` |
|
|
53
|
+
| `pythonlib/os` | `path`, `getcwd`, `sep` |
|
|
54
|
+
| `pythonlib/string` | `Template`, `capwords`, `ascii_lowercase` |
|
|
55
|
+
|
|
56
|
+
## Modules
|
|
57
|
+
|
|
58
|
+
### Builtins
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { range, enumerate, zip, len, sorted, reversed, sum, min, max } from "pythonlib"
|
|
62
|
+
|
|
63
|
+
for (const i of range(5)) {
|
|
64
|
+
} // 0, 1, 2, 3, 4
|
|
65
|
+
for (const i of range(1, 5)) {
|
|
66
|
+
} // 1, 2, 3, 4
|
|
67
|
+
for (const i of range(0, 10, 2)) {
|
|
68
|
+
} // 0, 2, 4, 6, 8
|
|
69
|
+
|
|
70
|
+
for (const [i, v] of enumerate(["a", "b", "c"])) {
|
|
71
|
+
} // [0,"a"], [1,"b"], [2,"c"]
|
|
72
|
+
for (const [a, b] of zip([1, 2], ["x", "y"])) {
|
|
73
|
+
} // [1,"x"], [2,"y"]
|
|
74
|
+
|
|
75
|
+
len([1, 2, 3]) // 3
|
|
76
|
+
sorted([3, 1, 2]) // [1, 2, 3]
|
|
77
|
+
reversed([1, 2, 3]) // [3, 2, 1]
|
|
78
|
+
sum([1, 2, 3]) // 6
|
|
79
|
+
min([1, 2, 3]) // 1
|
|
80
|
+
max([1, 2, 3]) // 3
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### itertools
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { chain, combinations, permutations, product, groupby } from "pythonlib/itertools"
|
|
87
|
+
|
|
88
|
+
chain([1, 2], [3, 4]) // [1, 2, 3, 4]
|
|
89
|
+
combinations([1, 2, 3], 2) // [[1,2], [1,3], [2,3]]
|
|
90
|
+
permutations([1, 2, 3], 2) // [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2]]
|
|
91
|
+
product([1, 2], ["a", "b"]) // [[1,"a"], [1,"b"], [2,"a"], [2,"b"]]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### functools
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { partial, reduce, lru_cache } from "pythonlib/functools"
|
|
98
|
+
|
|
99
|
+
const add5 = partial((a, b) => a + b, 5)
|
|
100
|
+
add5(3) // 8
|
|
101
|
+
|
|
102
|
+
reduce((a, b) => a + b, [1, 2, 3, 4, 5]) // 15
|
|
103
|
+
|
|
104
|
+
const cached = lru_cache((n: number) => expensiveComputation(n))
|
|
105
|
+
cached(5) // computes
|
|
106
|
+
cached(5) // returns cached result
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### collections
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { Counter, defaultdict, deque } from "pythonlib/collections"
|
|
113
|
+
|
|
114
|
+
const counter = new Counter("abracadabra")
|
|
115
|
+
counter.get("a") // 5
|
|
116
|
+
counter.mostCommon(2) // [["a", 5], ["b", 2]]
|
|
117
|
+
|
|
118
|
+
const dd = defaultdict(() => [])
|
|
119
|
+
dd.get("key").push(1) // auto-creates array
|
|
120
|
+
|
|
121
|
+
const d = new deque([1, 2, 3])
|
|
122
|
+
d.appendleft(0) // [0, 1, 2, 3]
|
|
123
|
+
d.pop() // 3
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### datetime
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { datetime, date, timedelta } from "pythonlib/datetime"
|
|
130
|
+
|
|
131
|
+
const now = datetime.now()
|
|
132
|
+
now.strftime("%Y-%m-%d %H:%M:%S")
|
|
133
|
+
|
|
134
|
+
const d = new date(2024, 6, 15)
|
|
135
|
+
d.isoformat() // "2024-06-15"
|
|
136
|
+
|
|
137
|
+
const delta = new timedelta({ days: 7 })
|
|
138
|
+
delta.total_seconds() // 604800
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### re
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { search, findall, sub, compile } from "pythonlib/re"
|
|
145
|
+
|
|
146
|
+
const m = search("(?P<name>\\w+)@(?P<domain>\\w+)", "user@example")
|
|
147
|
+
m?.group("name") // "user"
|
|
148
|
+
m?.groupdict() // { name: "user", domain: "example" }
|
|
149
|
+
|
|
150
|
+
findall("\\d+", "a1b2c3") // ["1", "2", "3"]
|
|
151
|
+
sub("\\d", "X", "a1b2") // "aXbX"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### math
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { sqrt, factorial, gcd, lcm, pi, e } from "pythonlib/math"
|
|
158
|
+
|
|
159
|
+
sqrt(16) // 4
|
|
160
|
+
factorial(5) // 120
|
|
161
|
+
gcd(12, 8) // 4
|
|
162
|
+
lcm(4, 6) // 12
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### random
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import { randint, choice, shuffle, sample } from "pythonlib/random"
|
|
169
|
+
|
|
170
|
+
randint(1, 10) // random integer 1-10
|
|
171
|
+
choice(["a", "b", "c"]) // random element
|
|
172
|
+
shuffle([1, 2, 3]) // shuffles in place
|
|
173
|
+
sample([1, 2, 3, 4, 5], 3) // 3 unique random elements
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Related
|
|
177
|
+
|
|
178
|
+
- [python2ts](https://www.npmjs.com/package/python2ts) — Transpile Python to TypeScript (uses
|
|
179
|
+
pythonlib as runtime)
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
// src/string.ts
|
|
2
|
+
function escapeRegex(str) {
|
|
3
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
|
+
}
|
|
5
|
+
var ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
|
|
6
|
+
var ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
7
|
+
var ascii_letters = ascii_lowercase + ascii_uppercase;
|
|
8
|
+
var digits = "0123456789";
|
|
9
|
+
var hexdigits = "0123456789abcdefABCDEF";
|
|
10
|
+
var octdigits = "01234567";
|
|
11
|
+
var punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
|
|
12
|
+
var whitespace = " \n\r\v\f";
|
|
13
|
+
var printable = digits + ascii_letters + punctuation + whitespace;
|
|
14
|
+
var Template = class {
|
|
15
|
+
template;
|
|
16
|
+
constructor(template) {
|
|
17
|
+
this.template = template;
|
|
18
|
+
}
|
|
19
|
+
/** Perform substitution, raising KeyError for missing keys */
|
|
20
|
+
substitute(mapping) {
|
|
21
|
+
const combined = { ...mapping };
|
|
22
|
+
return this.template.replace(
|
|
23
|
+
/\$\$|\$(\w+)|\$\{(\w+)\}/g,
|
|
24
|
+
(match, name1, name2) => {
|
|
25
|
+
if (match === "$$") return "$";
|
|
26
|
+
const name = name1 || name2;
|
|
27
|
+
if (!(name in combined)) {
|
|
28
|
+
throw new Error(`KeyError: '${name}'`);
|
|
29
|
+
}
|
|
30
|
+
return String(combined[name]);
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
/** Perform substitution, returning original placeholder for missing keys */
|
|
35
|
+
safe_substitute(mapping) {
|
|
36
|
+
const combined = { ...mapping };
|
|
37
|
+
return this.template.replace(
|
|
38
|
+
/\$\$|\$(\w+)|\$\{(\w+)\}/g,
|
|
39
|
+
(match, name1, name2) => {
|
|
40
|
+
if (match === "$$") return "$";
|
|
41
|
+
const name = name1 || name2;
|
|
42
|
+
if (!(name in combined)) {
|
|
43
|
+
return match;
|
|
44
|
+
}
|
|
45
|
+
return String(combined[name]);
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
/** Get identifiers in template */
|
|
50
|
+
get_identifiers() {
|
|
51
|
+
const identifiers = [];
|
|
52
|
+
const regex = /\$(\w+)|\$\{(\w+)\}/g;
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = regex.exec(this.template)) !== null) {
|
|
55
|
+
const name = match[1] || match[2];
|
|
56
|
+
if (name && !identifiers.includes(name)) {
|
|
57
|
+
identifiers.push(name);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return identifiers;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function capwords(s, sep) {
|
|
64
|
+
const separator = sep ?? " ";
|
|
65
|
+
return s.split(separator).map((word) => {
|
|
66
|
+
if (!word) return "";
|
|
67
|
+
const first = word[0];
|
|
68
|
+
return first ? first.toUpperCase() + word.slice(1).toLowerCase() : word;
|
|
69
|
+
}).join(separator);
|
|
70
|
+
}
|
|
71
|
+
var string = {
|
|
72
|
+
/**
|
|
73
|
+
* Python str.join()
|
|
74
|
+
*/
|
|
75
|
+
join(sep, iterable) {
|
|
76
|
+
return Array.from(iterable).join(sep);
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Python str.split()
|
|
80
|
+
*/
|
|
81
|
+
split(s, sep, maxsplit) {
|
|
82
|
+
if (sep === void 0) {
|
|
83
|
+
const result = s.trim().split(/\s+/);
|
|
84
|
+
if (maxsplit !== void 0 && maxsplit >= 0) {
|
|
85
|
+
if (result.length > maxsplit + 1) {
|
|
86
|
+
const limited = result.slice(0, maxsplit);
|
|
87
|
+
limited.push(result.slice(maxsplit).join(" "));
|
|
88
|
+
return limited;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
if (maxsplit !== void 0 && maxsplit >= 0) {
|
|
94
|
+
const parts = s.split(sep);
|
|
95
|
+
if (parts.length > maxsplit + 1) {
|
|
96
|
+
const limited = parts.slice(0, maxsplit);
|
|
97
|
+
limited.push(parts.slice(maxsplit).join(sep));
|
|
98
|
+
return limited;
|
|
99
|
+
}
|
|
100
|
+
return parts;
|
|
101
|
+
}
|
|
102
|
+
return s.split(sep);
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* Python str.rsplit()
|
|
106
|
+
*/
|
|
107
|
+
rsplit(s, sep, maxsplit) {
|
|
108
|
+
if (sep === void 0) {
|
|
109
|
+
const parts2 = s.trim().split(/\s+/);
|
|
110
|
+
if (maxsplit === void 0) return parts2;
|
|
111
|
+
if (maxsplit <= 0) return [s];
|
|
112
|
+
if (parts2.length <= maxsplit + 1) return parts2;
|
|
113
|
+
const keep2 = parts2.slice(-maxsplit);
|
|
114
|
+
const rest2 = parts2.slice(0, parts2.length - maxsplit).join(" ");
|
|
115
|
+
return [rest2, ...keep2];
|
|
116
|
+
}
|
|
117
|
+
const parts = s.split(sep);
|
|
118
|
+
if (maxsplit === void 0 || parts.length <= maxsplit + 1) return parts;
|
|
119
|
+
const keep = parts.slice(-maxsplit);
|
|
120
|
+
const rest = parts.slice(0, parts.length - maxsplit).join(sep);
|
|
121
|
+
return [rest, ...keep];
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Python str.strip()
|
|
125
|
+
*/
|
|
126
|
+
strip(s, chars) {
|
|
127
|
+
if (chars === void 0) {
|
|
128
|
+
return s.trim();
|
|
129
|
+
}
|
|
130
|
+
const regex = new RegExp(`^[${escapeRegex(chars)}]+|[${escapeRegex(chars)}]+$`, "g");
|
|
131
|
+
return s.replace(regex, "");
|
|
132
|
+
},
|
|
133
|
+
/**
|
|
134
|
+
* Python str.lstrip()
|
|
135
|
+
*/
|
|
136
|
+
lstrip(s, chars) {
|
|
137
|
+
if (chars === void 0) {
|
|
138
|
+
return s.trimStart();
|
|
139
|
+
}
|
|
140
|
+
const regex = new RegExp(`^[${escapeRegex(chars)}]+`);
|
|
141
|
+
return s.replace(regex, "");
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* Python str.rstrip()
|
|
145
|
+
*/
|
|
146
|
+
rstrip(s, chars) {
|
|
147
|
+
if (chars === void 0) {
|
|
148
|
+
return s.trimEnd();
|
|
149
|
+
}
|
|
150
|
+
const regex = new RegExp(`[${escapeRegex(chars)}]+$`);
|
|
151
|
+
return s.replace(regex, "");
|
|
152
|
+
},
|
|
153
|
+
/**
|
|
154
|
+
* Python str.upper()
|
|
155
|
+
*/
|
|
156
|
+
upper(s) {
|
|
157
|
+
return s.toUpperCase();
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* Python str.lower()
|
|
161
|
+
*/
|
|
162
|
+
lower(s) {
|
|
163
|
+
return s.toLowerCase();
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Python str.capitalize()
|
|
167
|
+
*/
|
|
168
|
+
capitalize(s) {
|
|
169
|
+
if (s.length === 0) return s;
|
|
170
|
+
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
171
|
+
},
|
|
172
|
+
/**
|
|
173
|
+
* Python str.title()
|
|
174
|
+
*/
|
|
175
|
+
title(s) {
|
|
176
|
+
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* Python str.swapcase()
|
|
180
|
+
*/
|
|
181
|
+
swapcase(s) {
|
|
182
|
+
return s.split("").map((c) => c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()).join("");
|
|
183
|
+
},
|
|
184
|
+
/**
|
|
185
|
+
* Python str.startswith()
|
|
186
|
+
*/
|
|
187
|
+
startswith(s, prefix, start, end) {
|
|
188
|
+
const substr = s.slice(start, end);
|
|
189
|
+
return substr.startsWith(prefix);
|
|
190
|
+
},
|
|
191
|
+
/**
|
|
192
|
+
* Python str.endswith()
|
|
193
|
+
*/
|
|
194
|
+
endswith(s, suffix, start, end) {
|
|
195
|
+
const substr = s.slice(start, end);
|
|
196
|
+
return substr.endsWith(suffix);
|
|
197
|
+
},
|
|
198
|
+
/**
|
|
199
|
+
* Python str.find()
|
|
200
|
+
*/
|
|
201
|
+
find(s, sub, start, end) {
|
|
202
|
+
const substr = s.slice(start, end);
|
|
203
|
+
const index = substr.indexOf(sub);
|
|
204
|
+
if (index === -1) return -1;
|
|
205
|
+
return (start ?? 0) + index;
|
|
206
|
+
},
|
|
207
|
+
/**
|
|
208
|
+
* Python str.rfind()
|
|
209
|
+
*/
|
|
210
|
+
rfind(s, sub, start, end) {
|
|
211
|
+
const substr = s.slice(start, end);
|
|
212
|
+
const index = substr.lastIndexOf(sub);
|
|
213
|
+
if (index === -1) return -1;
|
|
214
|
+
return (start ?? 0) + index;
|
|
215
|
+
},
|
|
216
|
+
/**
|
|
217
|
+
* Python str.index() - raises error if not found
|
|
218
|
+
*/
|
|
219
|
+
index(s, sub, start, end) {
|
|
220
|
+
const result = string.find(s, sub, start, end);
|
|
221
|
+
if (result === -1) {
|
|
222
|
+
throw new Error("substring not found");
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
},
|
|
226
|
+
/**
|
|
227
|
+
* Python str.rindex() - raises error if not found
|
|
228
|
+
*/
|
|
229
|
+
rindex(s, sub, start, end) {
|
|
230
|
+
const result = string.rfind(s, sub, start, end);
|
|
231
|
+
if (result === -1) {
|
|
232
|
+
throw new Error("substring not found");
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
},
|
|
236
|
+
/**
|
|
237
|
+
* Python str.count()
|
|
238
|
+
*/
|
|
239
|
+
count(s, sub, start, end) {
|
|
240
|
+
const substr = s.slice(start, end);
|
|
241
|
+
if (sub.length === 0) return substr.length + 1;
|
|
242
|
+
let count = 0;
|
|
243
|
+
let pos = 0;
|
|
244
|
+
while ((pos = substr.indexOf(sub, pos)) !== -1) {
|
|
245
|
+
count++;
|
|
246
|
+
pos += sub.length;
|
|
247
|
+
}
|
|
248
|
+
return count;
|
|
249
|
+
},
|
|
250
|
+
/**
|
|
251
|
+
* Python str.replace()
|
|
252
|
+
*/
|
|
253
|
+
replace(s, old, newStr, count) {
|
|
254
|
+
if (count === void 0 || count < 0) {
|
|
255
|
+
return s.split(old).join(newStr);
|
|
256
|
+
}
|
|
257
|
+
let result = s;
|
|
258
|
+
for (let i = 0; i < count; i++) {
|
|
259
|
+
const index = result.indexOf(old);
|
|
260
|
+
if (index === -1) break;
|
|
261
|
+
result = result.slice(0, index) + newStr + result.slice(index + old.length);
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
},
|
|
265
|
+
/**
|
|
266
|
+
* Python str.zfill()
|
|
267
|
+
*/
|
|
268
|
+
zfill(s, width) {
|
|
269
|
+
if (s.length >= width) return s;
|
|
270
|
+
const sign = s[0] === "-" || s[0] === "+" ? s[0] : "";
|
|
271
|
+
const digits2 = sign ? s.slice(1) : s;
|
|
272
|
+
return sign + digits2.padStart(width - sign.length, "0");
|
|
273
|
+
},
|
|
274
|
+
/**
|
|
275
|
+
* Python str.center()
|
|
276
|
+
*/
|
|
277
|
+
center(s, width, fillchar = " ") {
|
|
278
|
+
if (s.length >= width) return s;
|
|
279
|
+
const total = width - s.length;
|
|
280
|
+
const left = Math.floor(total / 2);
|
|
281
|
+
const right = total - left;
|
|
282
|
+
return fillchar.repeat(left) + s + fillchar.repeat(right);
|
|
283
|
+
},
|
|
284
|
+
/**
|
|
285
|
+
* Python str.ljust()
|
|
286
|
+
*/
|
|
287
|
+
ljust(s, width, fillchar = " ") {
|
|
288
|
+
if (s.length >= width) return s;
|
|
289
|
+
return s + fillchar.repeat(width - s.length);
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Python str.rjust()
|
|
293
|
+
*/
|
|
294
|
+
rjust(s, width, fillchar = " ") {
|
|
295
|
+
if (s.length >= width) return s;
|
|
296
|
+
return fillchar.repeat(width - s.length) + s;
|
|
297
|
+
},
|
|
298
|
+
/**
|
|
299
|
+
* Python str.partition()
|
|
300
|
+
*/
|
|
301
|
+
partition(s, sep) {
|
|
302
|
+
const index = s.indexOf(sep);
|
|
303
|
+
if (index === -1) return [s, "", ""];
|
|
304
|
+
return [s.slice(0, index), sep, s.slice(index + sep.length)];
|
|
305
|
+
},
|
|
306
|
+
/**
|
|
307
|
+
* Python str.rpartition()
|
|
308
|
+
*/
|
|
309
|
+
rpartition(s, sep) {
|
|
310
|
+
const index = s.lastIndexOf(sep);
|
|
311
|
+
if (index === -1) return ["", "", s];
|
|
312
|
+
return [s.slice(0, index), sep, s.slice(index + sep.length)];
|
|
313
|
+
},
|
|
314
|
+
/**
|
|
315
|
+
* Python str.isalpha()
|
|
316
|
+
*/
|
|
317
|
+
isalpha(s) {
|
|
318
|
+
return s.length > 0 && /^[a-zA-Z]+$/.test(s);
|
|
319
|
+
},
|
|
320
|
+
/**
|
|
321
|
+
* Python str.isdigit()
|
|
322
|
+
*/
|
|
323
|
+
isdigit(s) {
|
|
324
|
+
return s.length > 0 && /^[0-9]+$/.test(s);
|
|
325
|
+
},
|
|
326
|
+
/**
|
|
327
|
+
* Python str.isalnum()
|
|
328
|
+
*/
|
|
329
|
+
isalnum(s) {
|
|
330
|
+
return s.length > 0 && /^[a-zA-Z0-9]+$/.test(s);
|
|
331
|
+
},
|
|
332
|
+
/**
|
|
333
|
+
* Python str.isspace()
|
|
334
|
+
*/
|
|
335
|
+
isspace(s) {
|
|
336
|
+
return s.length > 0 && /^\s+$/.test(s);
|
|
337
|
+
},
|
|
338
|
+
/**
|
|
339
|
+
* Python str.isupper()
|
|
340
|
+
*/
|
|
341
|
+
isupper(s) {
|
|
342
|
+
return s.length > 0 && s === s.toUpperCase() && s !== s.toLowerCase();
|
|
343
|
+
},
|
|
344
|
+
/**
|
|
345
|
+
* Python str.islower()
|
|
346
|
+
*/
|
|
347
|
+
islower(s) {
|
|
348
|
+
return s.length > 0 && s === s.toLowerCase() && s !== s.toUpperCase();
|
|
349
|
+
},
|
|
350
|
+
/**
|
|
351
|
+
* Python str.format() - basic implementation
|
|
352
|
+
*/
|
|
353
|
+
format(s, ...args) {
|
|
354
|
+
let index = 0;
|
|
355
|
+
return s.replace(/\{(\d*)\}/g, (_, num) => {
|
|
356
|
+
const i = num === "" ? index++ : parseInt(num, 10);
|
|
357
|
+
return String(args[i]);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
export {
|
|
363
|
+
ascii_lowercase,
|
|
364
|
+
ascii_uppercase,
|
|
365
|
+
ascii_letters,
|
|
366
|
+
digits,
|
|
367
|
+
hexdigits,
|
|
368
|
+
octdigits,
|
|
369
|
+
punctuation,
|
|
370
|
+
whitespace,
|
|
371
|
+
printable,
|
|
372
|
+
Template,
|
|
373
|
+
capwords,
|
|
374
|
+
string
|
|
375
|
+
};
|
|
376
|
+
//# sourceMappingURL=chunk-3CSEXTA7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/string.ts"],"sourcesContent":["/**\n * Python string methods and constants for TypeScript\n * Usage: py.string.join(), py.string.split(), py.string.ascii_lowercase, etc.\n */\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n// ============================================================================\n// String constants (Python string module)\n// ============================================================================\n\n/** The lowercase letters 'abcdefghijklmnopqrstuvwxyz' */\nexport const ascii_lowercase = \"abcdefghijklmnopqrstuvwxyz\"\n\n/** The uppercase letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' */\nexport const ascii_uppercase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\n/** The concatenation of ascii_lowercase and ascii_uppercase */\nexport const ascii_letters = ascii_lowercase + ascii_uppercase\n\n/** The string '0123456789' */\nexport const digits = \"0123456789\"\n\n/** The string '0123456789abcdefABCDEF' */\nexport const hexdigits = \"0123456789abcdefABCDEF\"\n\n/** The string '01234567' */\nexport const octdigits = \"01234567\"\n\n/** String of ASCII characters which are considered punctuation */\nexport const punctuation = \"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\"\n\n/** String of ASCII characters which are considered whitespace */\nexport const whitespace = \" \\t\\n\\r\\x0b\\x0c\"\n\n/** String of ASCII characters which are considered printable */\nexport const printable = digits + ascii_letters + punctuation + whitespace\n\n// ============================================================================\n// Template class\n// ============================================================================\n\nexport class Template {\n readonly template: string\n\n constructor(template: string) {\n this.template = template\n }\n\n /** Perform substitution, raising KeyError for missing keys */\n substitute(mapping?: Record<string, unknown>): string {\n const combined = { ...mapping }\n return this.template.replace(\n /\\$\\$|\\$(\\w+)|\\$\\{(\\w+)\\}/g,\n (match, name1: string, name2: string) => {\n if (match === \"$$\") return \"$\"\n const name = name1 || name2\n if (!(name in combined)) {\n throw new Error(`KeyError: '${name}'`)\n }\n return String(combined[name])\n }\n )\n }\n\n /** Perform substitution, returning original placeholder for missing keys */\n safe_substitute(mapping?: Record<string, unknown>): string {\n const combined = { ...mapping }\n return this.template.replace(\n /\\$\\$|\\$(\\w+)|\\$\\{(\\w+)\\}/g,\n (match, name1: string, name2: string) => {\n if (match === \"$$\") return \"$\"\n const name = name1 || name2\n if (!(name in combined)) {\n return match\n }\n return String(combined[name])\n }\n )\n }\n\n /** Get identifiers in template */\n get_identifiers(): string[] {\n const identifiers: string[] = []\n const regex = /\\$(\\w+)|\\$\\{(\\w+)\\}/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(this.template)) !== null) {\n const name = match[1] || match[2]\n if (name && !identifiers.includes(name)) {\n identifiers.push(name)\n }\n }\n return identifiers\n }\n}\n\n/** Capitalize words in string */\nexport function capwords(s: string, sep?: string): string {\n const separator = sep ?? \" \"\n return s\n .split(separator)\n .map((word) => {\n if (!word) return \"\"\n const first = word[0]\n return first ? first.toUpperCase() + word.slice(1).toLowerCase() : word\n })\n .join(separator)\n}\n\nexport const string = {\n /**\n * Python str.join()\n */\n join(sep: string, iterable: Iterable<string>): string {\n return Array.from(iterable).join(sep)\n },\n\n /**\n * Python str.split()\n */\n split(s: string, sep?: string, maxsplit?: number): string[] {\n if (sep === undefined) {\n // Split on whitespace\n const result = s.trim().split(/\\s+/)\n if (maxsplit !== undefined && maxsplit >= 0) {\n if (result.length > maxsplit + 1) {\n const limited = result.slice(0, maxsplit)\n limited.push(result.slice(maxsplit).join(\" \"))\n return limited\n }\n }\n return result\n }\n\n if (maxsplit !== undefined && maxsplit >= 0) {\n const parts = s.split(sep)\n if (parts.length > maxsplit + 1) {\n const limited = parts.slice(0, maxsplit)\n limited.push(parts.slice(maxsplit).join(sep))\n return limited\n }\n return parts\n }\n\n return s.split(sep)\n },\n\n /**\n * Python str.rsplit()\n */\n rsplit(s: string, sep?: string, maxsplit?: number): string[] {\n if (sep === undefined) {\n const parts = s.trim().split(/\\s+/)\n if (maxsplit === undefined) return parts\n if (maxsplit <= 0) return [s]\n if (parts.length <= maxsplit + 1) return parts\n const keep = parts.slice(-maxsplit)\n const rest = parts.slice(0, parts.length - maxsplit).join(\" \")\n return [rest, ...keep]\n }\n\n const parts = s.split(sep)\n if (maxsplit === undefined || parts.length <= maxsplit + 1) return parts\n const keep = parts.slice(-maxsplit)\n const rest = parts.slice(0, parts.length - maxsplit).join(sep)\n return [rest, ...keep]\n },\n\n /**\n * Python str.strip()\n */\n strip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trim()\n }\n const regex = new RegExp(`^[${escapeRegex(chars)}]+|[${escapeRegex(chars)}]+$`, \"g\")\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.lstrip()\n */\n lstrip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trimStart()\n }\n const regex = new RegExp(`^[${escapeRegex(chars)}]+`)\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.rstrip()\n */\n rstrip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trimEnd()\n }\n const regex = new RegExp(`[${escapeRegex(chars)}]+$`)\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.upper()\n */\n upper(s: string): string {\n return s.toUpperCase()\n },\n\n /**\n * Python str.lower()\n */\n lower(s: string): string {\n return s.toLowerCase()\n },\n\n /**\n * Python str.capitalize()\n */\n capitalize(s: string): string {\n if (s.length === 0) return s\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()\n },\n\n /**\n * Python str.title()\n */\n title(s: string): string {\n return s.replace(/\\b\\w/g, (c) => c.toUpperCase())\n },\n\n /**\n * Python str.swapcase()\n */\n swapcase(s: string): string {\n return s\n .split(\"\")\n .map((c) => (c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()))\n .join(\"\")\n },\n\n /**\n * Python str.startswith()\n */\n startswith(s: string, prefix: string, start?: number, end?: number): boolean {\n const substr = s.slice(start, end)\n return substr.startsWith(prefix)\n },\n\n /**\n * Python str.endswith()\n */\n endswith(s: string, suffix: string, start?: number, end?: number): boolean {\n const substr = s.slice(start, end)\n return substr.endsWith(suffix)\n },\n\n /**\n * Python str.find()\n */\n find(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n const index = substr.indexOf(sub)\n if (index === -1) return -1\n return (start ?? 0) + index\n },\n\n /**\n * Python str.rfind()\n */\n rfind(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n const index = substr.lastIndexOf(sub)\n if (index === -1) return -1\n return (start ?? 0) + index\n },\n\n /**\n * Python str.index() - raises error if not found\n */\n index(s: string, sub: string, start?: number, end?: number): number {\n const result = string.find(s, sub, start, end)\n if (result === -1) {\n throw new Error(\"substring not found\")\n }\n return result\n },\n\n /**\n * Python str.rindex() - raises error if not found\n */\n rindex(s: string, sub: string, start?: number, end?: number): number {\n const result = string.rfind(s, sub, start, end)\n if (result === -1) {\n throw new Error(\"substring not found\")\n }\n return result\n },\n\n /**\n * Python str.count()\n */\n count(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n if (sub.length === 0) return substr.length + 1\n let count = 0\n let pos = 0\n while ((pos = substr.indexOf(sub, pos)) !== -1) {\n count++\n pos += sub.length\n }\n return count\n },\n\n /**\n * Python str.replace()\n */\n replace(s: string, old: string, newStr: string, count?: number): string {\n if (count === undefined || count < 0) {\n return s.split(old).join(newStr)\n }\n\n let result = s\n for (let i = 0; i < count; i++) {\n const index = result.indexOf(old)\n if (index === -1) break\n result = result.slice(0, index) + newStr + result.slice(index + old.length)\n }\n return result\n },\n\n /**\n * Python str.zfill()\n */\n zfill(s: string, width: number): string {\n if (s.length >= width) return s\n const sign = s[0] === \"-\" || s[0] === \"+\" ? s[0] : \"\"\n const digits = sign ? s.slice(1) : s\n return sign + digits.padStart(width - sign.length, \"0\")\n },\n\n /**\n * Python str.center()\n */\n center(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n const total = width - s.length\n const left = Math.floor(total / 2)\n const right = total - left\n return fillchar.repeat(left) + s + fillchar.repeat(right)\n },\n\n /**\n * Python str.ljust()\n */\n ljust(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n return s + fillchar.repeat(width - s.length)\n },\n\n /**\n * Python str.rjust()\n */\n rjust(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n return fillchar.repeat(width - s.length) + s\n },\n\n /**\n * Python str.partition()\n */\n partition(s: string, sep: string): [string, string, string] {\n const index = s.indexOf(sep)\n if (index === -1) return [s, \"\", \"\"]\n return [s.slice(0, index), sep, s.slice(index + sep.length)]\n },\n\n /**\n * Python str.rpartition()\n */\n rpartition(s: string, sep: string): [string, string, string] {\n const index = s.lastIndexOf(sep)\n if (index === -1) return [\"\", \"\", s]\n return [s.slice(0, index), sep, s.slice(index + sep.length)]\n },\n\n /**\n * Python str.isalpha()\n */\n isalpha(s: string): boolean {\n return s.length > 0 && /^[a-zA-Z]+$/.test(s)\n },\n\n /**\n * Python str.isdigit()\n */\n isdigit(s: string): boolean {\n return s.length > 0 && /^[0-9]+$/.test(s)\n },\n\n /**\n * Python str.isalnum()\n */\n isalnum(s: string): boolean {\n return s.length > 0 && /^[a-zA-Z0-9]+$/.test(s)\n },\n\n /**\n * Python str.isspace()\n */\n isspace(s: string): boolean {\n return s.length > 0 && /^\\s+$/.test(s)\n },\n\n /**\n * Python str.isupper()\n */\n isupper(s: string): boolean {\n return s.length > 0 && s === s.toUpperCase() && s !== s.toLowerCase()\n },\n\n /**\n * Python str.islower()\n */\n islower(s: string): boolean {\n return s.length > 0 && s === s.toLowerCase() && s !== s.toUpperCase()\n },\n\n /**\n * Python str.format() - basic implementation\n */\n format(s: string, ...args: unknown[]): string {\n let index = 0\n return s.replace(/\\{(\\d*)\\}/g, (_, num: string) => {\n const i = num === \"\" ? index++ : parseInt(num, 10)\n return String(args[i])\n })\n }\n}\n"],"mappings":"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","names":["parts","keep","rest","digits"]}
|