feat: Added functions for shortening strings.

This commit is contained in:
Spencer Brower
2023-05-30 15:07:26 -04:00
parent 7b676b742e
commit 2f1c4c70ca
6 changed files with 304 additions and 28 deletions

View File

@@ -7,10 +7,17 @@
### Functions ### Functions
- [afterFirst](modules.md#afterfirst) - [afterFirst](modules.md#afterfirst)
- [afterFirstWord](modules.md#afterfirstword)
- [afterLast](modules.md#afterlast) - [afterLast](modules.md#afterlast)
- [beforeFirst](modules.md#beforefirst)
- [beforeFirstWord](modules.md#beforefirstword)
- [endsWith](modules.md#endswith) - [endsWith](modules.md#endswith)
- [ltrim](modules.md#ltrim) - [ltrim](modules.md#ltrim)
- [removeFirstWord](modules.md#removefirstword)
- [removeWordsFromBeginning](modules.md#removewordsfrombeginning)
- [rtrim](modules.md#rtrim) - [rtrim](modules.md#rtrim)
- [shorten](modules.md#shorten)
- [shorterThan](modules.md#shorterthan)
- [startsWith](modules.md#startswith) - [startsWith](modules.md#startswith)
- [trim](modules.md#trim) - [trim](modules.md#trim)
@@ -58,6 +65,26 @@ node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___ ___
### afterFirstWord
**afterFirstWord**(`str`): `string`
#### Parameters
| Name | Type |
| :------ | :------ |
| `str` | `string` |
#### Returns
`string`
#### Defined in
[src/index.ts:34](https://github.com/sbrow/strings/blob/7b676b7/src/index.ts#L34)
___
### afterLast ### afterLast
**afterLast**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\> **afterLast**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
@@ -100,6 +127,90 @@ node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___ ___
### beforeFirst
**beforeFirst**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
Curry a [[Function]]
**`Example`**
```ts
import {F} from 'ts-toolbelt'
/// If you are looking for creating types for `curry`
/// It handles placeholders and variable arguments
declare function curry<Fn extends F.Function>(fn: Fn): F.Curry<Fn>
```
#### Type parameters
| Name | Type |
| :------ | :------ |
| `P` | extends [separator: string \| typeof \_, str: string \| typeof \_] |
| `G` | extends readonly `any`[] = `GapsOf`<`P`, [separator: string, str: string]\> |
| `R` | extends `unknown` = `string` |
#### Parameters
| Name | Type |
| :------ | :------ |
| `...p` | `P` \| [separator: string \| typeof \_, str: string \| typeof \_] |
#### Returns
`RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
[[Function]]
#### Defined in
node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___
### beforeFirstWord
**beforeFirstWord**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
Curry a [[Function]]
**`Example`**
```ts
import {F} from 'ts-toolbelt'
/// If you are looking for creating types for `curry`
/// It handles placeholders and variable arguments
declare function curry<Fn extends F.Function>(fn: Fn): F.Curry<Fn>
```
#### Type parameters
| Name | Type |
| :------ | :------ |
| `P` | extends [str: string \| typeof \_] |
| `G` | extends readonly `any`[] = `GapsOf`<`P`, [str: string]\> |
| `R` | extends `unknown` = `string` |
#### Parameters
| Name | Type |
| :------ | :------ |
| `...p` | `P` \| [str: string \| typeof \_] |
#### Returns
`RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
[[Function]]
#### Defined in
node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___
### endsWith ### endsWith
**endsWith**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\> **endsWith**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
@@ -172,6 +283,68 @@ node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___ ___
### removeFirstWord
**removeFirstWord**(`str`): `string`
#### Parameters
| Name | Type |
| :------ | :------ |
| `str` | `string` |
#### Returns
`string`
#### Defined in
[src/index.ts:35](https://github.com/sbrow/strings/blob/7b676b7/src/index.ts#L35)
___
### removeWordsFromBeginning
**removeWordsFromBeginning**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
Curry a [[Function]]
**`Example`**
```ts
import {F} from 'ts-toolbelt'
/// If you are looking for creating types for `curry`
/// It handles placeholders and variable arguments
declare function curry<Fn extends F.Function>(fn: Fn): F.Curry<Fn>
```
#### Type parameters
| Name | Type |
| :------ | :------ |
| `P` | extends [maxChars: number \| typeof \_, str: string \| typeof \_] |
| `G` | extends readonly `any`[] = `GapsOf`<`P`, [maxChars: number, str: string]\> |
| `R` | extends `unknown` = `unknown` |
#### Parameters
| Name | Type |
| :------ | :------ |
| `...p` | `P` \| [maxChars: number \| typeof \_, str: string \| typeof \_] |
#### Returns
`RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
[[Function]]
#### Defined in
node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___
### rtrim ### rtrim
**rtrim**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\> **rtrim**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
@@ -214,6 +387,90 @@ node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___ ___
### shorten
**shorten**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
Curry a [[Function]]
**`Example`**
```ts
import {F} from 'ts-toolbelt'
/// If you are looking for creating types for `curry`
/// It handles placeholders and variable arguments
declare function curry<Fn extends F.Function>(fn: Fn): F.Curry<Fn>
```
#### Type parameters
| Name | Type |
| :------ | :------ |
| `P` | extends [maxChars: number \| typeof \_, strategy: any] |
| `G` | extends readonly `any`[] = `GapsOf`<`P`, [maxChars: number, strategy: any]\> |
| `R` | extends `unknown` = (`init`: `unknown`) => `unknown` |
#### Parameters
| Name | Type |
| :------ | :------ |
| `...p` | `P` \| [maxChars: number \| typeof \_, strategy: any] |
#### Returns
`RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
[[Function]]
#### Defined in
node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___
### shorterThan
**shorterThan**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
Curry a [[Function]]
**`Example`**
```ts
import {F} from 'ts-toolbelt'
/// If you are looking for creating types for `curry`
/// It handles placeholders and variable arguments
declare function curry<Fn extends F.Function>(fn: Fn): F.Curry<Fn>
```
#### Type parameters
| Name | Type |
| :------ | :------ |
| `P` | extends [maxChars: number \| typeof \_, str: string \| typeof \_] |
| `G` | extends readonly `any`[] = `GapsOf`<`P`, [maxChars: number, str: string]\> |
| `R` | extends `unknown` = `boolean` |
#### Parameters
| Name | Type |
| :------ | :------ |
| `...p` | `P` \| [maxChars: number \| typeof \_, str: string \| typeof \_] |
#### Returns
`RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>
[[Function]]
#### Defined in
node_modules/ts-toolbelt/out/Function/Curry.d.ts:77
___
### startsWith ### startsWith
**startsWith**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\> **startsWith**<`P`, `G`, `R`\>(`...p`): `RequiredKeys`<`ObjectOf`<`G`\>\> extends `never` ? `R` : `Curry`<(...`p`: `G`) => `R`\>

View File

@@ -1,7 +1,8 @@
import { describe, expect, it } from "vitest";
import fc from "fast-check"; import fc from "fast-check";
import { describe, expect, it } from "vitest";
import { import {
/*afterFirstWord, beforeFirstWord, */ afterFirst, afterFirst,
afterLast, afterLast,
endsWith, endsWith,
ltrim, ltrim,

View File

@@ -1,5 +1,6 @@
import { curry } from "./utils"; import { curry } from "./utils";
export * from "./shorten";
export * from "./trim"; export * from "./trim";
function escapeRegExp(str: string) { function escapeRegExp(str: string) {
@@ -32,27 +33,3 @@ export const beforeFirstWord = beforeFirst(" ");
// @todo Test // @todo Test
export const afterFirstWord: (str: string) => string = afterFirst(" "); export const afterFirstWord: (str: string) => string = afterFirst(" ");
export const removeFirstWord: (str: string) => string = afterFirstWord; export const removeFirstWord: (str: string) => string = afterFirstWord;
// /**
// * @param {Number} maxChars
// * @param {String} str
// * @return {Boolean} False if str is longer than maxChars characters.
// */
// const shorterThan = curry((maxChars, str) => str.length <= maxChars);
// /**
// * @param {Number} maxChars The maximum length of the desired output string.
// * @param strategy a function that accepts a string and returns a shorter string.
// * @return {String} The input string, shortened to maxChars by strategy.
// */
// const shortenString = (maxChars, strategy) => until(shorterThan(maxChars), strategy);
// /**
// * @param {Number} maxChars
// * @param {String} str The string to remove words from.
// * @return {String} the shortened string.
// */
// export const removeWordsFromStartOfString = uncurryN(
// 2,
// (maxChars) => shortenString(maxChars, removeFirstWord),
// );

19
src/shorten.spec.ts Normal file
View File

@@ -0,0 +1,19 @@
import { describe, it, expect } from "vitest";
import { removeWordsFromBeginning, shorten } from "./index";
describe("shorten", () => {
it("shortens a string to the desired length", () => {
expect(
shorten(6, (str) => str.substring(0, str.length - 1))("foobarbat")
).toBe("foobar");
expect(shorten(6, (str) => str.substring(1))("foobarbat")).toBe("barbat");
});
});
describe("removeWordsFromBeginning", () => {
it("removes words from the beginning of a string", () => {
expect(removeWordsFromBeginning(7, "foo bar bat")).toBe("bar bat");
expect(removeWordsFromBeginning(7, "foo bar bat baz")).toBe("bat baz");
});
});

16
src/shorten.ts Normal file
View File

@@ -0,0 +1,16 @@
import { removeFirstWord } from "./index";
import { curry, until } from "./utils";
export const shorterThan = curry((maxChars: number, str: string) => str.length <= maxChars);
export const shorten = curry((maxChars: number, strategy) => until(shorterThan(maxChars) as (str: string) => boolean, strategy));
export const removeWordsFromBeginning = curry((maxChars: number, str: string) => shorten(maxChars, removeFirstWord)(str));
/*
export const removeWordsFromBeginning = uncurryN(
2,
(maxChars: number) => shorten(maxChars, removeFirstWord),
);
*/

View File

@@ -1,4 +1,4 @@
import type { curry as _curry, when as _when } from "ramda"; import type { curry as _curry, until as _until, when as _when } from "ramda";
export const curry = function (fn) { export const curry = function (fn) {
return (...args) => { return (...args) => {
@@ -18,3 +18,9 @@ export const tail = (str: string) => str.substring(1);
export const when = curry((predicate, whenTrueFn, arg) => { export const when = curry((predicate, whenTrueFn, arg) => {
return predicate(arg) ? whenTrueFn(arg) : arg; return predicate(arg) ? whenTrueFn(arg) : arg;
}) as typeof _when; }) as typeof _when;
export const until = curry((predicate, fn, arg) => {
const loop = (a: typeof arg): typeof a => predicate(a) ? a : loop(fn(a));
return loop(arg);
}) as typeof _until;