feat: Added words and sentences.

This commit is contained in:
Spencer Brower
2023-06-20 17:04:49 -04:00
parent fd15af85cb
commit 1485791367
11 changed files with 189 additions and 0 deletions

2
lib/index.d.ts vendored
View File

@@ -1,5 +1,7 @@
export * from "./sentences";
export * from "./shorten";
export * from "./trim";
export * from "./words";
export declare const startsWith: import("ts-toolbelt/out/Function/Curry").Curry<(needle: string, haystack: string) => boolean>;
export declare const endsWith: import("ts-toolbelt/out/Function/Curry").Curry<(needle: string, haystack: string) => boolean>;
export declare const afterFirst: import("ts-toolbelt/out/Function/Curry").Curry<(separator: string, str: string) => string>;

View File

@@ -16,8 +16,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeFirstWord = exports.afterFirstWord = exports.beforeFirstWord = exports.beforeFirst = exports.afterLast = exports.afterFirst = exports.endsWith = exports.startsWith = void 0;
const utils_1 = require("./utils");
__exportStar(require("./sentences"), exports);
__exportStar(require("./shorten"), exports);
__exportStar(require("./trim"), exports);
__exportStar(require("./words"), exports);
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

3
lib/sentences.d.ts vendored Normal file
View File

@@ -0,0 +1,3 @@
export declare function sentencesLazy(str: string, pattern?: RegExp): Generator<string>;
export declare function sentences(str: string, pattern?: RegExp): string[];
export declare function countSentences(str: string, pattern?: RegExp): number;

26
lib/sentences.js Normal file
View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.countSentences = exports.sentences = exports.sentencesLazy = void 0;
const matchSentenceEnd = /[!?]|(?<!\be|\be\.g|\betc)\./;
function* sentencesLazy(str, pattern = matchSentenceEnd) {
if (str.trim() !== '') {
const match = str.match(pattern);
const index = (match === null || match === void 0 ? void 0 : match.index) ? match.index + 1 : undefined;
if (index) {
yield str.substring(0, index);
yield* sentencesLazy(str.substring(index));
}
else {
yield str;
}
}
}
exports.sentencesLazy = sentencesLazy;
function sentences(str, pattern = matchSentenceEnd) {
return Array.from(sentencesLazy(str, pattern));
}
exports.sentences = sentences;
function countSentences(str, pattern = matchSentenceEnd) {
return sentences(str, pattern).length;
}
exports.countSentences = countSentences;

3
lib/words.d.ts vendored Normal file
View File

@@ -0,0 +1,3 @@
export declare function wordsLazy(str: string, pattern?: RegExp): Generator<string, void, unknown>;
export declare function words(str: string, pattern?: RegExp): string[];
export declare function wordCount(str: string, pattern?: RegExp): number;

21
lib/words.js Normal file
View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wordCount = exports.words = exports.wordsLazy = void 0;
const matchWord = /\S+/g;
function* wordsLazy(str, pattern = matchWord) {
for (const match of str.matchAll(pattern)) {
yield match[0];
}
}
exports.wordsLazy = wordsLazy;
function words(str, pattern = matchWord) {
return Array.from(wordsLazy(str, pattern));
}
exports.words = words;
function wordCount(str, pattern = matchWord) {
let count = 0;
for (const {} of str.matchAll(pattern))
count++;
return count;
}
exports.wordCount = wordCount;

View File

@@ -1,7 +1,9 @@
import { curry } from "./utils";
export * from "./sentences";
export * from "./shorten";
export * from "./trim";
export * from "./words";
function escapeRegExp(str: string) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string

48
src/sentences.spec.ts Normal file
View File

@@ -0,0 +1,48 @@
import fc from "fast-check";
import { describe, expect, it } from "vitest";
import { countSentences, sentences } from "./sentences";
describe("sentences", () => {
describe("sentences", () => {
it("returns '[]' for empty strings", () => {
expect(sentences("")).toEqual([]);
});
it.each([
[" "],
[" "],
[" \r "],
["\n "],
])("returns '[]' for strings with only whitespace characters", (str) => {
expect(sentences(str)).toEqual([]);
});
it.each([
["Hello, World!"],
["Hello, World."],
["Hello, World?"],
])("wraps the input in an array if it has only one sentence", (str) => {
expect(sentences(str)).toEqual([str]);
});
it('passes', () => {
fc.assert(
fc.property(fc.string(), (str) => {
if (str === '' || str.trim() === '') {
expect(sentences(str).length).toEqual(0)
} else if (!str.match(/[!?.]/)){
expect(sentences(str).length).toEqual(1)
// expect(se??tences(str).length).toEqual(str.split(/\s+/).filter(complement(isEmpty)).length)
}
})
);
})
});
describe("countSentences", () => {
it("matches the length of the output from sentences", () => {
fc.assert(
fc.property(fc.string(), (str) => {
expect(countSentences(str)).toBe(sentences(str).length);
})
);
});
});
});

23
src/sentences.ts Normal file
View File

@@ -0,0 +1,23 @@
const matchSentenceEnd = /[!?]|(?<!\be|\be\.g|\betc)\./
export function* sentencesLazy(str: string, pattern = matchSentenceEnd): Generator<string> {
if (str.trim() !== '') {
const match = str.match(pattern)
const index = match?.index ? match.index + 1 : undefined
if (index) {
yield str.substring(0, index)
yield* sentencesLazy(str.substring(index))
} else {
yield str
}
}
}
export function sentences(str: string, pattern = matchSentenceEnd) {
return Array.from(sentencesLazy(str, pattern))
}
export function countSentences(str: string, pattern = matchSentenceEnd) {
return sentences(str, pattern).length
}

39
src/words.spec.ts Normal file
View File

@@ -0,0 +1,39 @@
import fc from "fast-check";
import { describe, expect, it } from "vitest";
import { wordCount, words } from "./words";
import { complement, isEmpty } from "ramda";
describe("words", () => {
describe("words", () => {
it("returns '[]' for empty strings", () => {
expect(words("")).toEqual([]);
});
it("returns '[]' for strings with only whitespace characters", () => {
expect(words(" ")).toEqual([]);
expect(words(" ")).toEqual([]);
expect(words(" \r ")).toEqual([]);
expect(words("\n ")).toEqual([]);
});
it('passes', () => {
fc.assert(
fc.property(fc.string(), (str) => {
if (str === '' || str.trim() === '') {
expect(words(str).length).toEqual(0)
} else {
expect(words(str).length).toEqual(str.split(/\s+/).filter(complement(isEmpty)).length)
}
})
);
})
});
describe("wordCount", () => {
it("matches the length of the output from words", () => {
fc.assert(
fc.property(fc.string(), (str) => {
expect(wordCount(str)).toBe(words(str).length);
})
);
});
});
});

20
src/words.ts Normal file
View File

@@ -0,0 +1,20 @@
const matchWord = /\S+/g
export function* wordsLazy(str: string, pattern: RegExp = matchWord) {
for (const match of str.matchAll(pattern)) {
yield match[0]
}
}
export function words(str: string, pattern: RegExp = matchWord) {
return Array.from(wordsLazy(str, pattern))
}
export function wordCount(str: string, pattern: RegExp = matchWord) {
let count = 0
for (const {} of str.matchAll(pattern))
count++
return count;
}