devkits-text-counter 1.0.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 +138 -0
- package/index.js +158 -0
- package/package.json +48 -0
- package/test.js +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# devkits-text-counter
|
|
2
|
+
|
|
3
|
+
> Count words, characters, lines, paragraphs, and reading time
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g devkits-text-counter
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use without installation:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx devkits-text-counter [args]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Count text argument
|
|
21
|
+
dk-count "Hello World"
|
|
22
|
+
|
|
23
|
+
# Count file content
|
|
24
|
+
dk-count < file.txt
|
|
25
|
+
dk-count < README.md
|
|
26
|
+
|
|
27
|
+
# Count from stdin
|
|
28
|
+
echo "Hello World" | dk-count
|
|
29
|
+
cat article.md | dk-count
|
|
30
|
+
|
|
31
|
+
# Specific counts
|
|
32
|
+
dk-count -w < file.txt # Words only
|
|
33
|
+
dk-count -c < file.txt # Characters only
|
|
34
|
+
dk-count -l < file.txt # Lines only
|
|
35
|
+
dk-count --json < file.txt # JSON output
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Characters: 1234 (1100 without spaces)
|
|
42
|
+
Words: 200
|
|
43
|
+
Lines: 15
|
|
44
|
+
Paragraphs: 5
|
|
45
|
+
Reading time: 1 min
|
|
46
|
+
Speaking time: 1 min 32 sec
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Why @devkits/text-counter?
|
|
50
|
+
|
|
51
|
+
- ✅ Fast - Instant counting
|
|
52
|
+
- ✅ Zero dependencies - Pure Node.js
|
|
53
|
+
- ✅ Offline - Works without internet
|
|
54
|
+
- ✅ Free - Open source (MIT)
|
|
55
|
+
- ✅ CLI - Use in your terminal
|
|
56
|
+
- ✅ Multiple metrics - words, chars, lines, paragraphs, reading time
|
|
57
|
+
|
|
58
|
+
## Metrics
|
|
59
|
+
|
|
60
|
+
- **Characters** - Total characters (with and without spaces)
|
|
61
|
+
- **Words** - Word count
|
|
62
|
+
- **Lines** - Line count
|
|
63
|
+
- **Paragraphs** - Paragraph count
|
|
64
|
+
- **Reading time** - Estimated at 200 words per minute
|
|
65
|
+
- **Speaking time** - Estimated at 130 words per minute
|
|
66
|
+
|
|
67
|
+
## Web Version
|
|
68
|
+
|
|
69
|
+
Prefer a GUI? Check out the web version: **https://devkits-tools.surge.sh/tools/text-counter**
|
|
70
|
+
|
|
71
|
+
- 84 developer tools in one PWA
|
|
72
|
+
- Works offline
|
|
73
|
+
- No signup required
|
|
74
|
+
|
|
75
|
+
## Pro Features
|
|
76
|
+
|
|
77
|
+
Upgrade to Pro for advanced features:
|
|
78
|
+
|
|
79
|
+
- 📦 Batch Processing
|
|
80
|
+
- 🔗 API Access (1000 req/day free)
|
|
81
|
+
- ☁️ Cloud Sync
|
|
82
|
+
- 🎨 Custom Themes
|
|
83
|
+
- 📊 Advanced Analytics
|
|
84
|
+
- 💬 Priority Support
|
|
85
|
+
|
|
86
|
+
**Price:** $9 one-time payment
|
|
87
|
+
**Upgrade:** https://devkits-tools.surge.sh/pro
|
|
88
|
+
**Discount:** Use code `EARLYBIRD-2026` for 20% off
|
|
89
|
+
|
|
90
|
+
## See Also
|
|
91
|
+
|
|
92
|
+
Part of the **[DevKits Tools](https://devkits-tools.surge.sh)** collection — 80+ free developer tools:
|
|
93
|
+
|
|
94
|
+
### Popular Tools
|
|
95
|
+
|
|
96
|
+
| Tool | npm Package | Description |
|
|
97
|
+
|------|-------------|-------------|
|
|
98
|
+
| **[Base64](https://devkits-tools.surge.sh/tools/base64)** | `@devkits/base64` | Encode/decode Base64 |
|
|
99
|
+
| **[JSON Formatter](https://devkits-tools.surge.sh/tools/json-formatter)** | `@devkits/json-formatter` | Format and validate JSON |
|
|
100
|
+
| **[Color Converter](https://devkits-tools.surge.sh/tools/color-converter)** | `@devkits/color-converter` | HEX/RGB/HSL conversion |
|
|
101
|
+
| **[UUID Generator](https://devkits-tools.surge.sh/tools/uuid-generator)** | `@devkits/uuid-generator` | Generate unique UUIDs |
|
|
102
|
+
| **[Hash Generator](https://devkits-tools.surge.sh/tools/hash-generator)** | `@devkits/hash-generator` | MD5, SHA1, SHA256, SHA512 |
|
|
103
|
+
| **[Regex Tester](https://devkits-tools.surge.sh/tools/regex-tester)** | `@devkits/regex-tester` | Test regex patterns |
|
|
104
|
+
|
|
105
|
+
### Other DevKits Tools
|
|
106
|
+
|
|
107
|
+
- **[HTML Tools](https://devkits-tools.surge.sh/tools/html-entities)** — HTML entity encode/decode
|
|
108
|
+
- **[CSS Tools](https://devkits-tools.surge.sh/tools/css-minifier)** — CSS minify/format
|
|
109
|
+
- **[Cron Parser](https://devkits-tools.surge.sh/tools/cron-parser)** — Parse cron expressions
|
|
110
|
+
- **[Case Convert](https://devkits-tools.surge.sh/tools/text-case)** — camelCase, snake_case, etc.
|
|
111
|
+
- **[Slugify](https://devkits-tools.surge.sh/tools/slug-generator)** — Create URL-friendly slugs
|
|
112
|
+
- **[Lorem Ipsum](https://devkits-tools.surge.sh/tools/lorem-ipsum)** — Generate placeholder text
|
|
113
|
+
- **[Password Generator](https://devkits-tools.surge.sh/tools/password-generator)** — Secure passwords
|
|
114
|
+
- **[Timestamp](https://devkits-tools.surge.sh/tools/timestamp)** — Unix timestamp converter
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### More from DevKits
|
|
119
|
+
|
|
120
|
+
- **[Invoicely](https://invoicely-app.surge.sh)** — Free invoice generator for freelancers
|
|
121
|
+
- **[SnapOG](https://snapog.surge.sh)** — Free OG image generator with 20+ templates
|
|
122
|
+
- **[API Monitor](https://api-monitor-saas.surge.sh)** — Real-time API monitoring
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
👉 **Explore all 80+ developer tools at [DevKits Tools](https://devkits-tools.surge.sh)**
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT © [DevKits Team](https://devkits-tools.surge.sh)
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 🚀 API Monitoring for Developers
|
|
135
|
+
|
|
136
|
+
Build better APIs with **API Monitor SaaS** — real-time monitoring, alerting, and analytics.
|
|
137
|
+
|
|
138
|
+
👉 **Early Access: $1 pre-order (50% off for life)** → https://api-monitor-saas.surge.sh?utm_source=npm&utm_medium=readme&utm_campaign=phase0
|
package/index.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @devkits/text-counter - Count words, characters, lines, and reading time
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* dk-count "Hello World" # Count text
|
|
8
|
+
* dk-count < file.txt # Count file
|
|
9
|
+
* echo "text" | dk-count # Count from stdin
|
|
10
|
+
*
|
|
11
|
+
* Web version: https://devkits-tools.surge.sh/tools/text-counter
|
|
12
|
+
* Pro features: https://devkits-tools.surge.sh/pro
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
function countText(text) {
|
|
16
|
+
const chars = text.length;
|
|
17
|
+
const charsNoSpaces = text.replace(/\s/g, '').length;
|
|
18
|
+
const words = text.trim() ? text.trim().split(/\s+/).length : 0;
|
|
19
|
+
const lines = text.split('\n').length;
|
|
20
|
+
const paragraphs = text.split(/\n\s*\n/).filter(p => p.trim()).length;
|
|
21
|
+
|
|
22
|
+
// Reading time: average 200 words per minute
|
|
23
|
+
const readingTimeMinutes = words / 200;
|
|
24
|
+
const readingTimeSeconds = Math.round(readingTimeMinutes * 60);
|
|
25
|
+
|
|
26
|
+
// Speaking time: average 130 words per minute
|
|
27
|
+
const speakingTimeMinutes = words / 130;
|
|
28
|
+
const speakingTimeSeconds = Math.round(speakingTimeMinutes * 60);
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
characters: chars,
|
|
32
|
+
charactersNoSpaces: charsNoSpaces,
|
|
33
|
+
words: words,
|
|
34
|
+
lines: lines,
|
|
35
|
+
paragraphs: paragraphs || (words > 0 ? 1 : 0),
|
|
36
|
+
readingTime: formatTime(readingTimeSeconds),
|
|
37
|
+
speakingTime: formatTime(speakingTimeSeconds),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function formatTime(seconds) {
|
|
42
|
+
if (seconds < 60) {
|
|
43
|
+
return `${seconds} sec`;
|
|
44
|
+
}
|
|
45
|
+
const mins = Math.floor(seconds / 60);
|
|
46
|
+
const secs = seconds % 60;
|
|
47
|
+
return secs > 0 ? `${mins} min ${secs} sec` : `${mins} min`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function showHelp() {
|
|
51
|
+
console.log(`
|
|
52
|
+
@devkits/text-counter - Count words, characters, lines, and reading time
|
|
53
|
+
|
|
54
|
+
Usage:
|
|
55
|
+
dk-count "Hello World" # Count text argument
|
|
56
|
+
dk-count < file.txt # Count file
|
|
57
|
+
echo "text" | dk-count # Count from stdin
|
|
58
|
+
|
|
59
|
+
Options:
|
|
60
|
+
-w, --words Show only word count
|
|
61
|
+
-c, --chars Show only character count
|
|
62
|
+
-l, --lines Show only line count
|
|
63
|
+
-j, --json Output as JSON
|
|
64
|
+
-h, --help Show this help message
|
|
65
|
+
|
|
66
|
+
Output includes:
|
|
67
|
+
- Characters (with and without spaces)
|
|
68
|
+
- Words
|
|
69
|
+
- Lines
|
|
70
|
+
- Paragraphs
|
|
71
|
+
- Reading time (at 200 wpm)
|
|
72
|
+
- Speaking time (at 130 wpm)
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
dk-count "Hello World"
|
|
76
|
+
dk-count < README.md
|
|
77
|
+
dk-count -w < file.txt
|
|
78
|
+
dk-count --json < article.md
|
|
79
|
+
|
|
80
|
+
Web version: https://devkits-tools.surge.sh/tools/text-counter
|
|
81
|
+
Pro features: https://devkits-tools.surge.sh/pro
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Main entry point
|
|
86
|
+
const args = process.argv.slice(2);
|
|
87
|
+
|
|
88
|
+
if (!args.length || args.includes('-h') || args.includes('--help')) {
|
|
89
|
+
showHelp();
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Parse options
|
|
94
|
+
let wordsOnly = false;
|
|
95
|
+
let charsOnly = false;
|
|
96
|
+
let linesOnly = false;
|
|
97
|
+
let jsonOutput = false;
|
|
98
|
+
let text = '';
|
|
99
|
+
const remainingArgs = [];
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < args.length; i++) {
|
|
102
|
+
if (args[i] === '-w' || args[i] === '--words') {
|
|
103
|
+
wordsOnly = true;
|
|
104
|
+
} else if (args[i] === '-c' || args[i] === '--chars') {
|
|
105
|
+
charsOnly = true;
|
|
106
|
+
} else if (args[i] === '-l' || args[i] === '--lines') {
|
|
107
|
+
linesOnly = true;
|
|
108
|
+
} else if (args[i] === '-j' || args[i] === '--json') {
|
|
109
|
+
jsonOutput = true;
|
|
110
|
+
} else {
|
|
111
|
+
remainingArgs.push(args[i]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Read from stdin if no text provided
|
|
116
|
+
const processText = (text) => {
|
|
117
|
+
const result = countText(text);
|
|
118
|
+
|
|
119
|
+
if (wordsOnly) {
|
|
120
|
+
console.log(result.words);
|
|
121
|
+
} else if (charsOnly) {
|
|
122
|
+
console.log(result.characters);
|
|
123
|
+
} else if (linesOnly) {
|
|
124
|
+
console.log(result.lines);
|
|
125
|
+
} else if (jsonOutput) {
|
|
126
|
+
console.log(JSON.stringify(result, null, 2));
|
|
127
|
+
} else {
|
|
128
|
+
console.log(`Characters: ${result.characters} (${result.charactersNoSpaces} without spaces)`);
|
|
129
|
+
console.log(`Words: ${result.words}`);
|
|
130
|
+
console.log(`Lines: ${result.lines}`);
|
|
131
|
+
console.log(`Paragraphs: ${result.paragraphs}`);
|
|
132
|
+
console.log(`Reading time: ${result.readingTime}`);
|
|
133
|
+
console.log(`Speaking time: ${result.speakingTime}`);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
if (remainingArgs.length === 0 && !process.stdin.isTTY) {
|
|
138
|
+
let stdin = '';
|
|
139
|
+
process.stdin.setEncoding('utf8');
|
|
140
|
+
process.stdin.on('readable', () => {
|
|
141
|
+
let chunk;
|
|
142
|
+
while ((chunk = process.stdin.read()) !== null) {
|
|
143
|
+
stdin += chunk;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
process.stdin.on('end', () => {
|
|
147
|
+
if (stdin) {
|
|
148
|
+
processText(stdin);
|
|
149
|
+
} else {
|
|
150
|
+
showHelp();
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
} else if (remainingArgs.length > 0) {
|
|
154
|
+
text = remainingArgs.join(' ');
|
|
155
|
+
processText(text);
|
|
156
|
+
} else {
|
|
157
|
+
showHelp();
|
|
158
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "devkits-text-counter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Count words, characters, lines, and reading time in text",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dk-count": "./index.js",
|
|
8
|
+
"text-count": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "node test.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"text",
|
|
15
|
+
"count",
|
|
16
|
+
"words",
|
|
17
|
+
"characters",
|
|
18
|
+
"lines",
|
|
19
|
+
"devkits",
|
|
20
|
+
"developer-tools",
|
|
21
|
+
"cli",
|
|
22
|
+
"command-line",
|
|
23
|
+
"nodejs",
|
|
24
|
+
"utility",
|
|
25
|
+
"productivity",
|
|
26
|
+
"dev-tools",
|
|
27
|
+
"free-tools"
|
|
28
|
+
],
|
|
29
|
+
"author": "DevKits Team <devkits-auto@protonmail.com>",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/devkits/tools"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://devkits-tools.surge.sh/tools/text-counter",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/devkits/tools/issues"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=14.0.0"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"index.js",
|
|
44
|
+
"README.md",
|
|
45
|
+
"test.js"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {}
|
|
48
|
+
}
|
package/test.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tests for @devkits/text-counter
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
const tests = [
|
|
10
|
+
{
|
|
11
|
+
name: 'Count words in text',
|
|
12
|
+
cmd: 'echo "Hello World Test" | node index.js -w',
|
|
13
|
+
check: (result) => parseInt(result.trim()) === 3
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Count characters in text',
|
|
17
|
+
cmd: 'echo "Hello" | node index.js -c',
|
|
18
|
+
check: (result) => parseInt(result.trim()) === 6 // includes newline from echo
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'Count lines in text',
|
|
22
|
+
cmd: 'echo -e "line1\\nline2\\nline3" | node index.js -l',
|
|
23
|
+
check: (result) => parseInt(result.trim()) === 3
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'JSON output has all fields',
|
|
27
|
+
cmd: 'echo "Hello World" | node index.js --json',
|
|
28
|
+
check: (result) => {
|
|
29
|
+
const data = JSON.parse(result);
|
|
30
|
+
return data.words !== undefined &&
|
|
31
|
+
data.characters !== undefined &&
|
|
32
|
+
data.lines !== undefined;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Reading time calculated',
|
|
37
|
+
cmd: 'node index.js "word ".repeat(200)',
|
|
38
|
+
check: (result) => result.includes('Reading time:')
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
let passed = 0;
|
|
43
|
+
let failed = 0;
|
|
44
|
+
|
|
45
|
+
console.log('Running @devkits/text-counter tests...\n');
|
|
46
|
+
|
|
47
|
+
for (const test of tests) {
|
|
48
|
+
try {
|
|
49
|
+
const result = execSync(test.cmd, { encoding: 'utf8' }).trim();
|
|
50
|
+
if (test.check(result)) {
|
|
51
|
+
console.log(`✅ ${test.name}`);
|
|
52
|
+
passed++;
|
|
53
|
+
} else {
|
|
54
|
+
console.log(`❌ ${test.name}`);
|
|
55
|
+
console.log(` Got: ${result}`);
|
|
56
|
+
failed++;
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.log(`❌ ${test.name} - Error: ${err.message}`);
|
|
60
|
+
failed++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`\n${passed}/${tests.length} tests passed`);
|
|
65
|
+
process.exit(failed > 0 ? 1 : 0);
|