@bernierllc/text-tools
v1.0.0
Published
Comprehensive text manipulation utilities for pluralization, case conversion, truncation, slugification, Unicode handling, and smart formatting
Downloads
10
Readme
@bernierllc/text-tools
Comprehensive text manipulation and formatting utilities for JavaScript/TypeScript applications. Provides production-ready, locale-aware text processing including pluralization, case conversion, truncation, slugification, Unicode handling, and smart formatting.
Installation
npm install @bernierllc/text-toolsFeatures
- ✅ Pluralization - English pluralization rules with custom overrides
- ✅ Case Conversion - camelCase, snake_case, kebab-case, PascalCase, Title Case
- ✅ Truncation - Smart word-boundary truncation with ellipsis
- ✅ Slugification - URL-safe slug generation with accent stripping
- ✅ String Comparison - Case-insensitive, accent-insensitive, fuzzy matching
- ✅ Unicode Handling - Emoji detection/removal, accent stripping, HTML escaping
- ✅ Smart Formatting - Word wrapping, padding, indentation, curly quotes
- ✅ Text Validation - Content detection, alphanumeric validation
- ✅ Similarity - Levenshtein distance, phonetic comparison
- ✅ Word Operations - Word counting, reading time estimation, excerpts
Usage
Pluralization
import { pluralize, formatCount, formatRange } from '@bernierllc/text-tools';
// Basic pluralization
pluralize('opportunity', 1); // 'opportunity'
pluralize('opportunity', 5); // 'opportunities'
pluralize('city', 2); // 'cities'
// Custom plural forms
pluralize('person', 2, 'people'); // 'people'
pluralize('child', 3, 'children'); // 'children'
// Format with count
formatCount(1, 'opportunity'); // '1 opportunity'
formatCount(5, 'opportunity'); // '5 opportunities'
// Format ranges
formatRange(2, 5, 'class'); // '2 of 5 classes'Case Conversion
import {
toTitleCase,
toSentenceCase,
toCamelCase,
toSnakeCase,
toKebabCase,
toPascalCase
} from '@bernierllc/text-tools';
toTitleCase('the quick brown fox'); // 'The Quick Brown Fox'
toSentenceCase('HELLO WORLD'); // 'Hello world'
toCamelCase('hello world'); // 'helloWorld'
toSnakeCase('Hello World'); // 'hello_world'
toKebabCase('Hello World'); // 'hello-world'
toPascalCase('hello world'); // 'HelloWorld'Truncation
import { truncate, truncateWords } from '@bernierllc/text-tools';
// Truncate at word boundaries
truncate('The quick brown fox', 10); // 'The quick...'
// Truncate in middle
truncate('The quick brown fox', 12, { position: 'middle' }); // 'The...fox'
// Custom ellipsis
truncate('Long text', 8, { ellipsis: '---' }); // 'Long---'
// Truncate by word count
truncateWords('one two three four', 2); // 'one two...'Slugification
import { slugify } from '@bernierllc/text-tools';
slugify('Hello World!'); // 'hello-world'
slugify('Café & Bar'); // 'cafe-bar'
slugify('Hello World', { separator: '_' }); // 'hello_world'
// Custom replacements
slugify('Hello & World', {
customReplacements: { '&': 'and' }
}); // 'hello-and-world'String Comparison
import { compareIgnoreCase, compareIgnoreAccents, fuzzyMatch } from '@bernierllc/text-tools';
compareIgnoreCase('hello', 'HELLO'); // 0 (equal)
compareIgnoreAccents('café', 'cafe'); // 0 (equal)
fuzzyMatch('hello world', 'hlo'); // trueUnicode & Emoji
import {
stripEmojis,
stripAccents,
containsEmoji,
countEmojis,
escapeHtml,
escapeRegex
} from '@bernierllc/text-tools';
stripEmojis('Hello 👋 World 🌍'); // 'Hello World '
stripAccents('Café résumé'); // 'Cafe resume'
containsEmoji('Hello 👋'); // true
countEmojis('Hello 👋 World 🌍'); // 2
escapeHtml('<div>Hello</div>'); // '<div>Hello</div>'
escapeRegex('hello.world'); // 'hello\\.world'Whitespace & Cleaning
import {
normalizeWhitespace,
stripHtml,
stripMarkdown,
collapse
} from '@bernierllc/text-tools';
normalizeWhitespace('hello \n\t world'); // 'hello world'
stripHtml('<p>Hello <strong>World</strong></p>'); // 'Hello World'
stripMarkdown('**bold** and _italic_'); // 'bold and italic'
collapse('hello world '); // 'helloworld'Word Operations
import {
wordCount,
characterCount,
estimateReadingTime,
excerpt
} from '@bernierllc/text-tools';
wordCount('Hello, world! How are you?'); // 5
characterCount('Hello world', { ignoreWhitespace: true }); // 10
estimateReadingTime(longText); // { minutes: 5, seconds: 30 }
estimateReadingTime(longText, { format: 'minutes' }); // 5
excerpt(longText, 100); // First 100 chars at word boundary + '...'
excerpt(htmlText, 100, { stripHtml: true }); // Strip HTML firstText Validation
import {
isEmpty,
hasContent,
isAlphanumeric
} from '@bernierllc/text-tools';
isEmpty(' '); // true
hasContent('hello'); // true
isAlphanumeric('abc123'); // trueFormatting
import { wrap, indent, dedent, pad } from '@bernierllc/text-tools';
wrap('long text here', 10); // Wraps at 10 chars per line
indent('line1\nline2', 2); // ' line1\n line2'
dedent(' line1\n line2'); // 'line1\nline2'
pad('hello', 10); // 'hello '
pad('hello', 10, { side: 'left' }); // ' hello'
pad('hi', 6, { side: 'both' }); // ' hi 'Search & Replace
import {
replaceAll,
removePrefix,
removeSuffix,
ensurePrefix,
ensureSuffix
} from '@bernierllc/text-tools';
replaceAll('hello world hello', 'hello', 'hi'); // 'hi world hi'
removePrefix('hello-world', 'hello-'); // 'world'
removeSuffix('hello.txt', '.txt'); // 'hello'
ensurePrefix('world', 'hello-'); // 'hello-world'
ensureSuffix('file', '.txt'); // 'file.txt'Smart Formatting
import {
smartQuotes,
oxfordComma,
humanizeList,
numberToWords,
wordsToNumber
} from '@bernierllc/text-tools';
smartQuotes('"Hello" and \'world\''); // '"Hello" and 'world''
oxfordComma(['a', 'b', 'c']); // 'a, b, and c'
humanizeList(['a', 'b', 'c']); // 'a, b, and c'
humanizeList(['a', 'b'], { conjunction: 'or' }); // 'a or b'
numberToWords(42); // 'forty-two'
wordsToNumber('forty-two'); // 42Similarity & Distance
import {
levenshteinDistance,
similarity,
soundsLike
} from '@bernierllc/text-tools';
levenshteinDistance('kitten', 'sitting'); // 3
similarity('hello', 'hello'); // 1.0
similarity('hello', 'hallo'); // 0.8
soundsLike('knight', 'night'); // trueAPI Reference
Pluralization
pluralize(word, count?, customPlural?)- Pluralize word based on countformatCount(count, singular, customPlural?)- Format count with proper pluralizationformatRange(current, total, singular, customPlural?)- Format range like "2 of 5 items"
Case Conversion
toTitleCase(text)- Convert to Title CasetoSentenceCase(text)- Convert to Sentence casetoCamelCase(text)- Convert to camelCasetoSnakeCase(text)- Convert to snake_casetoKebabCase(text)- Convert to kebab-casetoPascalCase(text)- Convert to PascalCase
Truncation
truncate(text, maxLength, options?)- Smart truncation with word boundariestruncateWords(text, maxWords)- Truncate by word count
Slugification
slugify(text, options?)- Create URL-safe slugs
String Comparison
compareIgnoreCase(a, b)- Case-insensitive comparisoncompareIgnoreAccents(a, b)- Accent-insensitive comparisonfuzzyMatch(text, pattern)- Fuzzy string matching
Unicode & Special Characters
stripEmojis(text)- Remove all emojisstripAccents(text)- Remove accent markscontainsEmoji(text)- Check for emoji presencecountEmojis(text)- Count emojisescapeHtml(text)- Escape HTML entitiesunescapeHtml(text)- Unescape HTML entitiesescapeRegex(text)- Escape regex special characters
Whitespace & Cleaning
normalizeWhitespace(text)- Normalize to single spacesstripHtml(html)- Remove HTML tagsstripMarkdown(markdown)- Remove markdown syntaxcollapse(text)- Remove all whitespace
Word Operations
wordCount(text)- Count wordscharacterCount(text, options?)- Count charactersestimateReadingTime(text, options?)- Estimate reading timeexcerpt(text, maxLength, options?)- Create excerpt
Text Validation
isEmpty(text)- Check if empty or whitespace onlyhasContent(text)- Check if has meaningful contentisAlphanumeric(text)- Validate alphanumeric only
Formatting
wrap(text, width, options?)- Wrap text at widthindent(text, spaces)- Indent all linesdedent(text)- Remove common indentationpad(text, length, options?)- Pad to length
Search & Replace
replaceAll(text, search, replace)- Replace all occurrencesremovePrefix(text, prefix)- Remove prefix if existsremoveSuffix(text, suffix)- Remove suffix if existsensurePrefix(text, prefix)- Add prefix if missingensureSuffix(text, suffix)- Add suffix if missing
Smart Formatting
smartQuotes(text)- Convert to curly quotesoxfordComma(items)- Format with Oxford commahumanizeList(items, options?)- Format list with conjunctionnumberToWords(num)- Convert number to words (0-999)wordsToNumber(text)- Parse words to number
Similarity & Distance
levenshteinDistance(a, b)- Calculate edit distancesimilarity(a, b, options?)- Calculate similarity score (0-1)soundsLike(a, b)- Phonetic comparison
Integration Status
- Logger: not-applicable - Pure utility functions with no side effects
- Docs-Suite: ready - Complete TypeDoc documentation
- NeverHub: not-applicable - Core utility package with pure functions
License
Copyright (c) 2025 Bernier LLC. All rights reserved.
This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
