Skip to content
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ const count = stringzy.analyze.wordCount('Hello world'); // 2
### Analysis

- [wordCount](#wordcount) - Counts the number of words in a string
- [contentWordCount](#contentwordcount)- Counts the number of content words (nouns, verbs, adjectives, adverbs, etc.) in a string.
- [functionWordCount](#functionwordcount)- Counts the number of function words (prepositions, pronouns, conjunctions, articles, etc.) in a string.
- [readingDuration](#readingduration) - Calculates the reading duration of a given string
- [characterCount](#charactercount) - Counts the number of characters in a string
- [characterFrequency](#characterfrequency) - Analyzes character frequency in a string
Expand Down Expand Up @@ -871,6 +873,64 @@ complexity('');
- `uniqueness` (number): Measure of character uniqueness
- `length` (number): Length of the input string

feature/content-words

#### <a id="contentwordcount"></a>contentWordCount(text)

Counts the number of content words (nouns, verbs, adjectives, adverbs, etc.) in a string.

```javascript

import { contentWordCount } from 'stringzy';

contentWordCount("Learning JavaScript improves coding skills!");
// Returns: { count: 5 }

contentWordCount("The cat sleeps on the warm windowsill.");
// Returns: { count: 5 }

contentWordCount("Wow! Such a beautiful day.");
// Returns: { count: 4 }
```

| Parameter | Type | Default | Description |
| --------- | ------ | -------- | -------------------------------------- |
| text | string | required | The input string to analyze content words |

**Returns:** An object containing:

- `count` (number): Total number of content words in the string


#### <a id="functionwordcount"></a>functionWordCount(text)

Counts the number of function words (prepositions, pronouns, conjunctions, articles, etc.) in a string.

```javascript

import { functionWordCount } from 'stringzy';

functionWordCount("She and I are going to the park.");
// Returns: { count: 7 }

functionWordCount("It is an example of proper grammar usage.");
// Returns: { count: 8 }

functionWordCount("Can you see the stars tonight?");
// Returns: { count: 5 }
```

| Parameter | Type | Default | Description |
| --------- | ------ | -------- | -------------------------------------- |
| text | string | required | The input string to analyze function words |

**Returns:** An object containing:

- `count` (number): Total number of function words in the string




#### <a id="patterncount"></a>`patternCount(text, pattern)`

Counts the number of times a substring (pattern) occurs in a string, including overlapping occurrences.
Expand Down Expand Up @@ -908,6 +968,8 @@ vowelConsonantCount('');
| --------- | ------ | -------- | -------------------------------------------------- |
| str | string | required | The input string to count vowels and consonants in |

feature/content-words

#### <a id="checkmultiplepatterns"></a>checkMultiplePatterns(text, patterns)

Finds occurrences of multiple patterns within a given text using the Rabin–Karp algorithm. <br>
Expand All @@ -931,6 +993,7 @@ checkMultiplePatterns('hello world', ['xyz', '123']);
| text | string | required | The text to search within. |
| patterns | string\[ ] | required | An array of patterns to search for (each must be a string). |


---

### 🎨 Formatting
Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "npm run build && node --test",
"test": " npm run build && node --test",
"prepublishOnly": "npm run build",
"format": "prettier --write ."
},
Expand Down
23 changes: 23 additions & 0 deletions src/analyzing/contentWordCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { functionWordCount } from './functionWordCount';
import { wordCount } from './wordCount';

/**
* Counts the number of content words in a given text.
*
* Content words are words that carry lexical meaning (nouns, verbs, adjectives, adverbs),
* excluding function words such as prepositions, pronouns, and articles.
*
* @param {string} text - The text to analyze.
* @returns {number} The count of content words in the text.
* @throws {TypeError} If the input is not a string.
*/
export function contentWordCount(text: string): number {
if (typeof text !== 'string') {
throw new TypeError('Input must be a string');
}

const totalWords = wordCount(text);
const functionWords = functionWordCount(text);

return totalWords - functionWords;
}
34 changes: 34 additions & 0 deletions src/analyzing/functionWordCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Counts the number of function words in a given text.
*
* Function words are common words (e.g., prepositions, pronouns, conjunctions, articles, etc.)
* that carry grammatical meaning rather than lexical meaning.
*
* @param {string} text - The text to analyze.
* @returns {number} The count of function words in the text.
* @throws {TypeError} If the input is not a string.
*/
export function functionWordCount(text: string): number {
if (typeof text !== 'string') {
throw new TypeError('Input must be a string');
}

const functionWords = new Set([
'a', 'an', 'the', 'and', 'but', 'or', 'nor', 'so', 'yet',
'for', 'of', 'in', 'on', 'at', 'by', 'to', 'from', 'with', 'about',
'as', 'into', 'like', 'through', 'after', 'over', 'between', 'out',
'against', 'during', 'without', 'before', 'under', 'around', 'among',
'is', 'am', 'are', 'was', 'were', 'be', 'been', 'being',
'he', 'she', 'it', 'they', 'we', 'you', 'i', 'me', 'him', 'her',
'them', 'us', 'my', 'your', 'his', 'their', 'our',
'this', 'that', 'these', 'those',
'who', 'whom', 'which', 'what', 'when', 'where', 'why', 'how'
]);

// ✅ Normalize text: lowercase + remove punctuation
const cleanedText = text.toLowerCase().replace(/[^\w\s]/g, '');

const words = cleanedText.trim().split(/\s+/);

return words.filter(word => functionWords.has(word)).length;
}
6 changes: 6 additions & 0 deletions src/analyzing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export { patternCount } from './patternCount';
export { vowelConsonantCount } from './vowelConsonantCount';
export { checkMultiplePatterns } from './checkMultiplePatterns';

export { functionWordCount } from './functionWordCount';
export { contentWordCount } from './contentWordCount';


import { characterCount } from './characterCount';
import { characterFrequency } from './characterFrequency';
import { complexity } from './complexity';
Expand All @@ -18,6 +22,8 @@ import { patternCount } from './patternCount';
import { vowelConsonantCount } from './vowelConsonantCount';
import { checkMultiplePatterns } from './checkMultiplePatterns';



export const analyzing = {
characterCount,
characterFrequency,
Expand Down
19 changes: 19 additions & 0 deletions src/tests/analyzing/contentWordCount.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import test from "node:test";
import assert from "node:assert/strict";
import { contentWordCount } from "../../analyzing/contentWordCount.js";

test("counts content words in a normal sentence", () => {
assert.equal(contentWordCount("This is a test of the system"), 2);
});

test("returns 0 when there are no content words", () => {
assert.equal(contentWordCount("is the at of"), 0);
});

test("ignores case and punctuation", () => {
assert.equal(contentWordCount("Elephants, ELEPHANTS, elephants!"), 3);
});

test("returns 0 for empty string", () => {
assert.equal(contentWordCount(""), 0);
});
19 changes: 19 additions & 0 deletions src/tests/analyzing/functionWordCount.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import test from "node:test";
import assert from "node:assert/strict";
import { functionWordCount } from "../../analyzing/functionWordCount.js";

test("counts function words in a normal sentence", () => {
assert.equal(functionWordCount("This is a test of the system"), 5);
});

test("returns 0 when there are no function words", () => {
assert.equal(functionWordCount("Elephants run fast"), 0);
});

test("ignores case and punctuation", () => {
assert.equal(functionWordCount("The, THE, the!"), 3);
});

test("returns 0 for empty string", () => {
assert.equal(functionWordCount(""), 0);
});