@danielhaim/titlecaser 1.7.12 → 1.7.14
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 +196 -414
- package/dist/titlecaser.amd.js +2 -2
- package/dist/titlecaser.esm.js +2 -2
- package/dist/titlecaser.module.js +2 -2
- package/index.d.ts +1 -3
- package/package.json +1 -1
- package/src/TitleCaser.js +128 -60
- package/src/TitleCaserUtils.js +97 -128
package/README.md
CHANGED
|
@@ -4,430 +4,300 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@danielhaim/titlecaser)
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
A
|
|
7
|
+
A style-guide–aware title case engine for JavaScript that implements **AP**, **APA**, **Chicago**, **NYT**, **Wikipedia**, and **British** styles with contextual acronym disambiguation and 1,000+ curated domain terms.
|
|
8
8
|
|
|
9
9
|
<a target="_blank" href="https://danielhaim1.github.io/TitleCaser/"><img src="https://raw.githubusercontent.com/danielhaim1/TitleCaser/main/docs/assets/demo.png" width="100%" height="auto" alt="TitleCaser Demo"></a>
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
* [Demo](https://danielhaim1.github.io/TitleCaser/)
|
|
13
|
-
* [CodePen Demo 1](https://codepen.io/danielhaim/pen/oNQgjBv)
|
|
14
|
-
* [CodePen Demo 2](https://codepen.io/danielhaim/pen/oNPGzKw)
|
|
15
|
-
* [Table of Contents](#table-of-contents)
|
|
16
|
-
* [Introduction](#introduction)
|
|
17
|
-
* [Key Features:](#key-features)
|
|
18
|
-
* [Installation](#installation)
|
|
19
|
-
* [Usage](#usage)
|
|
20
|
-
* [Usage in the Browser](#usage-in-the-browser)
|
|
21
|
-
* [Options](#options)
|
|
22
|
-
* [Methods](#methods)
|
|
23
|
-
* [Examples](#examples)
|
|
24
|
-
+ [Basic Usage](#basic-usage)
|
|
25
|
-
+ [Customizing Word Replacements Method](#customizing-word-replacements-method)
|
|
26
|
-
+ [Customizing TitleCaser](#customizing-titlecaser)
|
|
27
|
-
+ [TitleCaser with Default Word Replacement](#titlecaser-with-default-word-replacement)
|
|
28
|
-
+ [TitleCaser with Possessive Noun and a Colon](#titlecaser-with-possessive-noun-and-a-colon)
|
|
29
|
-
* [Build Process](#build-process)
|
|
30
|
-
* [Test](#test)
|
|
31
|
-
* [Resources](#resources)
|
|
32
|
-
* [Report Bugs](#report-bugs)
|
|
33
|
-
* [Contributing](CONTRIBUTING.md)
|
|
34
|
-
* [Changelog](CHANGELOG.md)
|
|
35
|
-
|
|
36
|
-
## Overview
|
|
37
|
-
|
|
38
|
-
TitleCaser is a comprehensive solution for converting text to title case according to various style guides (AP, APA, Chicago, NYT, Wikipedia, British). It handles special cases like hyphens, apostrophes, Roman numerals, and acronyms, and provides extensive customization options.
|
|
39
|
-
|
|
40
|
-
## Language Conventions and Style Library
|
|
41
|
-
|
|
42
|
-
**The comprehensive Language Conventions and Style Library (LCSL)** is specifically designed to assist web content developers in adhering to the latest style guides and English language conventions. This all-inclusive library has various features, including support for numerous style guides such as **AP, APA, Chicago, NY Times, Wikipedia, and British styles** and customizable preferences to tailor to individual needs. **TitleCaser is a component of this library**, and LCSL is set to be open-sourced by the end of 2025.
|
|
43
|
-
|
|
44
|
-
### Streamlined Workflow
|
|
45
|
-
To streamline workflow, modules are available in both **browser and node environment versions** and include a command-line interface for building, testing, and minimizing the module. Additionally, it features a **filter ability** that allows users to ignore certain phrases containing short words, preventing the module from mistakenly flagging instances where short words are used as part of a larger term or phrase.
|
|
46
|
-
|
|
47
|
-
### Comprehensive Capitalization Handling
|
|
48
|
-
The module has been designed to handle various capitalization scenarios, including:
|
|
49
|
-
- **Hyphenated words**
|
|
50
|
-
- **Prefixes and suffixes**
|
|
51
|
-
- **Reserved words**
|
|
52
|
-
- **Roman numerals**
|
|
53
|
-
- **Proper nouns** that contain lowercase letters
|
|
54
|
-
- **Words that require capitalization** in specific contexts
|
|
55
|
-
|
|
56
|
-
This ensures that your content meets the appropriate style and formatting guidelines, regardless of the context. It also offers **word replacement capabilities**, as well as **ignored phrases** to create consistency in cases where certain terms may be capitalized differently depending on the context.
|
|
57
|
-
|
|
58
|
-
### Essential Tool for Content Developers
|
|
59
|
-
Whether you're developing web content for a major news organization or simply looking to improve your writing skills, this module is an **essential tool** that can help ensure your work is accurate, consistent, and conforms to the latest style guidelines.
|
|
60
|
-
|
|
61
|
-
### Key Features:
|
|
62
|
-
- **Support for popular style guides** and customizable preferences
|
|
63
|
-
- **Advanced capitalization handling** for suffixes, prefixes, hyphenated words, and reserved words
|
|
64
|
-
- **Support for proper capitalization** of Roman numerals and exclusion of specific words and phrases from title capitalization
|
|
65
|
-
- **Word replacement capabilities** for consistency in capitalization
|
|
66
|
-
- **Command-line interface** for building, testing, and minimizing the module
|
|
67
|
-
- **Pre-defined word lists** for articles, conjunctions, prepositions, and non-capitalized words in titles
|
|
68
|
-
- **Exclusion of common phrases** from title capitalization
|
|
69
|
-
|
|
70
|
-
## Features
|
|
71
|
-
|
|
72
|
-
- **Multiple Style Support**: AP, APA, Chicago, NYT, Wikipedia, and British title case styles
|
|
73
|
-
- **Special Case Handling**: Hyphens, apostrophes, Roman numerals, acronyms, and more
|
|
74
|
-
- **Word Replacement**: Replace specific words with their correct forms
|
|
75
|
-
- **Exact Phrase Replacement**: Replace exact phrases with their correct forms
|
|
76
|
-
- **Smart Quotes**: Optional conversion to smart quotes
|
|
77
|
-
- **Extensive Term Lists**: Includes extensive lists of correctly cased terms
|
|
78
|
-
- **Customizable Options**: Customize word lists, replacements, and other options
|
|
79
|
-
|
|
80
|
-
## Installation
|
|
11
|
+
---
|
|
81
12
|
|
|
82
|
-
|
|
83
|
-
npm install @danielhaim/titlecaser
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Usage
|
|
13
|
+
## Links
|
|
87
14
|
|
|
88
|
-
|
|
15
|
+
- [Demo](https://danielhaim1.github.io/TitleCaser/)
|
|
16
|
+
- [CodePen Demo 1](https://codepen.io/danielhaim/pen/oNQgjBv)
|
|
17
|
+
- [CodePen Demo 2](https://codepen.io/danielhaim/pen/oNPGzKw)
|
|
18
|
+
- [Contributing](CONTRIBUTING.md)
|
|
19
|
+
- [Changelog](CHANGELOG.md)
|
|
20
|
+
- [License](LICENSE)
|
|
89
21
|
|
|
90
|
-
|
|
91
|
-
import { TitleCaser } from '@danielhaim/titlecaser';
|
|
92
|
-
|
|
93
|
-
// Basic usage with Chicago style
|
|
94
|
-
const titleCaser = new TitleCaser({
|
|
95
|
-
style: 'chicago'
|
|
96
|
-
});
|
|
97
|
-
const result = titleCaser.toTitleCase('the book of life');
|
|
98
|
-
console.log(result); // "The Book of Life"
|
|
22
|
+
---
|
|
99
23
|
|
|
100
|
-
|
|
101
|
-
const customTitleCaser = new TitleCaser({
|
|
102
|
-
style: 'ap',
|
|
103
|
-
smartQuotes: true,
|
|
104
|
-
ignoredWords: ['a', 'an', 'the'],
|
|
105
|
-
acronyms: ['API', 'JSON', 'XML']
|
|
106
|
-
});
|
|
24
|
+
## Introduction
|
|
107
25
|
|
|
108
|
-
|
|
109
|
-
console.log(customResult); // "The API and JSON Data"
|
|
26
|
+
TitleCaser is a deterministic, style-guide–aware title casing engine built for production publishing systems. It implements major editorial standards with rule-driven capitalization logic, including contextual acronym disambiguation, compound handling, possessive normalization, punctuation-aware processing, and curated domain vocabulary enforcement across marketing, academia, business, finance, geography, legal, defense, and technology.
|
|
110
27
|
|
|
111
|
-
|
|
112
|
-
titleCaser.addReplaceTerm('js', 'JavaScript');
|
|
113
|
-
const jsResult = titleCaser.toTitleCase('js development');
|
|
114
|
-
console.log(jsResult); // "JavaScript Development"
|
|
28
|
+
Its multi-pass processing architecture ensures deterministic output while supporting custom overrides, exact phrase preservation, and controlled vocabulary enforcement. Designed for Node.js and browser environments, TitleCaser integrates cleanly into CMS pipelines, build systems, and automated editorial workflows where precision and repeatability are required.
|
|
115
29
|
|
|
116
|
-
|
|
117
|
-
titleCaser.addExactPhraseReplacements([
|
|
118
|
-
{ 'the correct phrase': 'The Correct Phrase' }
|
|
119
|
-
]);
|
|
120
|
-
const phraseResult = titleCaser.toTitleCase('this is the correct phrase');
|
|
121
|
-
console.log(phraseResult); // "This Is The Correct Phrase"
|
|
122
|
-
```
|
|
30
|
+
---
|
|
123
31
|
|
|
124
|
-
##
|
|
32
|
+
## Key Features
|
|
125
33
|
|
|
126
|
-
|
|
34
|
+
### Multi-Style Editorial Engine
|
|
35
|
+
Built-in rule systems for **AP**, **APA**, **Chicago**, **NYT**, **Wikipedia** (sentence case), and **British** styles. Each style applies its own logic for minor words, hyphenated compounds, possessives, colon capitalization, and acronym handling, producing consistent, repeatable output.
|
|
127
36
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```
|
|
37
|
+
### Contextual Acronym & Pronoun Disambiguation
|
|
38
|
+
Distinguishes regional acronyms from identical lowercase words using positional and surrounding-word heuristics.
|
|
131
39
|
|
|
132
|
-
|
|
40
|
+
For example:
|
|
133
41
|
|
|
134
42
|
```javascript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
};
|
|
138
|
-
const input = 'the future of devops: the next era';
|
|
139
|
-
const output = input.toTitleCase(options);
|
|
43
|
+
"It’s up to us in the US military to decide."
|
|
44
|
+
→ "It’s Up to Us in the US Military to Decide."
|
|
140
45
|
|
|
141
|
-
|
|
46
|
+
"us-uk-led coalition"
|
|
47
|
+
→ "US-UK-Led Coalition"
|
|
142
48
|
```
|
|
143
49
|
|
|
144
|
-
|
|
50
|
+
- Supports US, UK, EU, USA (dotted and undotted forms)
|
|
51
|
+
- Handles hyphenated compounds (US-Backed, US-UK-Led)
|
|
52
|
+
- Works in parenthetical and comma-separated contexts
|
|
53
|
+
- Detects end-of-sentence acronyms
|
|
54
|
+
- Avoids false positives inside longer words
|
|
55
|
+
|
|
56
|
+
### Structured Vocabulary Normalization
|
|
57
|
+
Includes **1,000+ curated normalization rules** across brands, technology, geography, business, marketing, defense, academia, finance, and legal domains.
|
|
58
|
+
|
|
59
|
+
- Mixed-case normalization (`GOOGle → Google`)
|
|
60
|
+
- Intentional lowercase brands (`iPhone`, `eBay`)
|
|
61
|
+
- Roman numerals (`Louis-IV`)
|
|
62
|
+
- Unicode names (`Škoda`)
|
|
63
|
+
- Possessive handling (`GOOGle's tensorflow → Google's TensorFlow`)
|
|
64
|
+
- Runtime custom term overrides
|
|
65
|
+
- Exact phrase replacements
|
|
66
|
+
|
|
67
|
+
### Advanced Hyphenation & Compound Handling
|
|
68
|
+
Intelligent processing of hyphenated compounds with style-specific rules:
|
|
69
|
+
|
|
70
|
+
- Multi-hyphen compounds (`US-UK-Led Coalition`)
|
|
71
|
+
- Style-specific compound rules (AP vs Chicago)
|
|
72
|
+
- En dash and em dash normalization
|
|
73
|
+
- Acronym-first compound logic
|
|
74
|
+
- Roman numerals inside compounds
|
|
75
|
+
- Brand casing preservation inside compounds
|
|
76
|
+
|
|
77
|
+
### Multi-Pass Deterministic Processing
|
|
78
|
+
Layered multi-pass processing for stable handling of complex inputs:
|
|
79
|
+
|
|
80
|
+
- Input normalization (spacing and `<br>` handling)
|
|
81
|
+
- Token-based whitespace-preserving transformation pipeline
|
|
82
|
+
- Style-aware casing pass
|
|
83
|
+
- Acronym resolution pass
|
|
84
|
+
- Short-word correction pass
|
|
85
|
+
- Final contextual correction pass
|
|
86
|
+
- Optional smart quote conversion
|
|
87
|
+
- Exact phrase override pass
|
|
88
|
+
|
|
89
|
+
### HTML-Safe & CMS-Ready
|
|
90
|
+
Designed for integration into publishing workflows, CMS pipelines, and automated editorial systems.
|
|
91
|
+
|
|
92
|
+
- Preserves `<br>` tags
|
|
93
|
+
- Normalizes spacing around colon + `<br>`
|
|
94
|
+
- Retains ampersands and symbols
|
|
95
|
+
- Handles excessive whitespace safely
|
|
96
|
+
- Optional whitespace preservation for editor-safe real-time usage
|
|
97
|
+
|
|
98
|
+
### Runtime & Build Support
|
|
99
|
+
The AMD/browser build extends `String.prototype.toTitleCase()` for direct string usage in client environments.
|
|
100
|
+
|
|
101
|
+
- Node.js (ES modules)
|
|
102
|
+
- Browser (prototype extension via AMD build)
|
|
103
|
+
- AMD distribution build
|
|
104
|
+
- CLI build and test scripts
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Quick Start
|
|
145
109
|
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
<h2>the iphone's impact on modern communication: a sociolinguistic analysis</h2>
|
|
149
|
-
<h2>back-end and front-end</h2>
|
|
110
|
+
```bash
|
|
111
|
+
npm install @danielhaim/titlecaser
|
|
150
112
|
```
|
|
151
113
|
|
|
152
114
|
```javascript
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const h2Elements = document.querySelectorAll("h2");
|
|
156
|
-
h2Elements.forEach((h2) => {
|
|
157
|
-
const innerHTML = h2.innerHTML;
|
|
158
|
-
const modifiedContent = innerHTML.toTitleCase(options);
|
|
159
|
-
h2.innerHTML = modifiedContent;
|
|
160
|
-
});
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error(
|
|
163
|
-
"An error occurred while applying title case transformation:",
|
|
164
|
-
error
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
applyTitleCaseToH2Elements();
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Options
|
|
173
|
-
|
|
174
|
-
The `{options}` parameter is an object that contains the settings for the conversion process.
|
|
115
|
+
import { TitleCaser } from '@danielhaim/titlecaser';
|
|
175
116
|
|
|
176
|
-
|
|
177
|
-
- `articlesList` refers to the words that should be treated as articles in title case.
|
|
178
|
-
- `shortConjunctionsList` pertains to the words that should be treated as short conjunctions in title case.
|
|
179
|
-
- `shortPrepositionsList` relates to the words that should be treated as short prepositions in title case.
|
|
180
|
-
- `neverCapitalizedList` contains the words that should never be capitalized in title case.
|
|
181
|
-
- `wordReplacementsList` is a map of terms that will be replaced during the title case conversion process.
|
|
182
|
-
- `smartQuotes` boolean value that determines whether quotes should be replaced with smart quotes.
|
|
117
|
+
const titleCaser = new TitleCaser({ style: 'ap' });
|
|
183
118
|
|
|
184
|
-
|
|
119
|
+
titleCaser.toTitleCase('the quick brown fox'); // → "The Quick Brown Fox"
|
|
120
|
+
titleCaser.toTitleCase('nodejs development on aws'); // → "Node.js Development on AWS"
|
|
121
|
+
titleCaser.toTitleCase('let us know about the us military'); // → "Let Us Know About the US Military"
|
|
122
|
+
```
|
|
185
123
|
|
|
186
|
-
|
|
187
|
-
- `removeReplaceTerm(term)`: Removes a replaced term from the `wordReplacementsList` array in the option object of the `TitleCaser` instance. Throws an error if the term is not found in the array, otherwise removes it from the array and updates the option object.
|
|
188
|
-
- `addReplaceTerm(term, replacement)`: Adds a single term-replacement pair to the `wordReplacementsList`. If the term already exists, it updates the replacement value.
|
|
189
|
-
- `addExactPhraseReplacements(newPhrases)` - This method allows adding an array of exact phrase replacements to the `TitleCaser` class. Each item in the array should be an object with a single key-value pair, where the key is the phrase to be replaced and the value is the desired replacement.
|
|
190
|
-
- `setStyle(style: string)`: Sets the style option in the object of the TitleCaser instance. The method takes a string argument style that specifies the style to use for the title casing. If the argument is not a string, the method throws a TypeError. Otherwise, it updates the style option in the object.
|
|
191
|
-
- `smartQuotes(smartQuotes: boolean)`: Specifies whether to replace straight quotes with smart quotes during title casing. Provide a boolean argument smartQuotes to enable or disable this feature.
|
|
124
|
+
---
|
|
192
125
|
|
|
193
|
-
##
|
|
126
|
+
## Core Usage
|
|
194
127
|
|
|
195
|
-
###
|
|
128
|
+
### Editorial-Grade Transformation (AP Example)
|
|
129
|
+
Handles brand normalization, acronyms, hyphenation, possessives, and colon rules:
|
|
196
130
|
|
|
197
131
|
```javascript
|
|
198
132
|
import { TitleCaser } from '@danielhaim/titlecaser';
|
|
199
133
|
|
|
200
|
-
const titleCaser = new TitleCaser();
|
|
201
|
-
const result = titleCaser.toTitleCase('hello world');
|
|
202
|
-
console.log(result); // "Hello World"
|
|
203
|
-
```
|
|
134
|
+
const titleCaser = new TitleCaser({ style: 'ap' });
|
|
204
135
|
|
|
205
|
-
|
|
136
|
+
titleCaser.toTitleCase(
|
|
137
|
+
"nodejs development on aws: an in-depth tutorial on server-side javascript deployment"
|
|
138
|
+
); // → "Node.js Development on AWS: An In-depth Tutorial on Server-side JavaScript Deployment"
|
|
139
|
+
```
|
|
206
140
|
|
|
207
|
-
|
|
141
|
+
### Custom Term Normalization
|
|
142
|
+
```javascript
|
|
143
|
+
titleCaser.addReplaceTerm('js', 'JavaScript');
|
|
144
|
+
titleCaser.toTitleCase('js development'); // → "JavaScript Development"
|
|
145
|
+
```
|
|
208
146
|
|
|
147
|
+
### Exact Phrase Replacement
|
|
209
148
|
```javascript
|
|
210
|
-
|
|
149
|
+
titleCaser.addExactPhraseReplacements([
|
|
150
|
+
{ 'the correct phrase': 'The Correct Phrase' }
|
|
151
|
+
]);
|
|
211
152
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
153
|
+
titleCaser.toTitleCase('this is the correct phrase'); // → "This Is The Correct Phrase"
|
|
154
|
+
```
|
|
215
155
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
titleCaser.setReplaceTerms({
|
|
222
|
-
'apa': 'APA'
|
|
156
|
+
### Smart Quotes
|
|
157
|
+
```javascript
|
|
158
|
+
const tc = new TitleCaser({
|
|
159
|
+
style: 'ap',
|
|
160
|
+
smartQuotes: true
|
|
223
161
|
});
|
|
224
162
|
|
|
225
|
-
|
|
226
|
-
const inputString = "hello world, replace me!";
|
|
227
|
-
const expectedOutput = "Hello World, Replace Me!";
|
|
228
|
-
|
|
229
|
-
// Call toTitleCase() to convert the input string to title case
|
|
230
|
-
const outputString = titleCaser.toTitleCase(inputString);
|
|
163
|
+
tc.toTitleCase('"never underestimate the power o\' persistence,"'); // → “Never Underestimate the Power O’ Persistence,”
|
|
231
164
|
```
|
|
232
165
|
|
|
233
|
-
###
|
|
234
|
-
|
|
235
|
-
The example below demonstrates how to use the TitleCaser class to convert a string to a title case with specific settings.
|
|
236
|
-
|
|
237
|
-
```javascript
|
|
238
|
-
import { TitleCaser } from '@danielhaim/titlecaser';
|
|
239
|
-
|
|
240
|
-
// Set the options object
|
|
241
|
-
const options = {
|
|
242
|
-
style: "nyt",
|
|
243
|
-
wordReplacementsList: {
|
|
244
|
-
"nodejs": "Node.js",
|
|
245
|
-
"javascript": "JavaScript",
|
|
246
|
-
"mongodb": "MongoDB"
|
|
247
|
-
}
|
|
248
|
-
};
|
|
166
|
+
### Whitespace Normalization
|
|
249
167
|
|
|
250
|
-
|
|
251
|
-
const titleCaser = new TitleCaser(options);
|
|
168
|
+
Whitespace normalization is enabled by default.
|
|
252
169
|
|
|
253
|
-
|
|
254
|
-
const input = "the basics of nodejs development with mongodb";
|
|
170
|
+
By default, TitleCaser collapses consecutive whitespace and trims leading and trailing spaces:
|
|
255
171
|
|
|
256
|
-
|
|
257
|
-
const
|
|
172
|
+
```javascript
|
|
173
|
+
const tc = new TitleCaser({ style: "ap" });
|
|
258
174
|
|
|
259
|
-
|
|
260
|
-
const actualOutput = titleCaser.toTitleCase(input);
|
|
175
|
+
tc.toTitleCase(" the quick brown fox "); // → "The Quick Brown Fox"
|
|
261
176
|
```
|
|
262
177
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
The example below demonstrates how to use the TitleCaser class to convert a string to a title case with AP style formatting, including hyphenated words and word/brand replacement.
|
|
178
|
+
For real-time editors or environments where spacing must be preserved, disable normalization:
|
|
266
179
|
|
|
267
180
|
```javascript
|
|
268
|
-
|
|
181
|
+
const tc = new TitleCaser({
|
|
182
|
+
style: "ap",
|
|
183
|
+
normalizeWhitespace: false
|
|
184
|
+
});
|
|
269
185
|
|
|
270
|
-
//
|
|
271
|
-
|
|
186
|
+
tc.toTitleCase(" the quick brown fox "); // → " The Quick Brown Fox "
|
|
187
|
+
```
|
|
272
188
|
|
|
273
|
-
|
|
274
|
-
|
|
189
|
+
When normalizeWhitespace is false:
|
|
190
|
+
- Internal spacing is preserved
|
|
191
|
+
- Leading/trailing whitespace is preserved
|
|
192
|
+
- Newlines and tabs are preserved
|
|
193
|
+
- Only letter casing is transformed
|
|
275
194
|
|
|
276
|
-
|
|
277
|
-
const expectedOutput = 'Node.js Development on AWS: An In-depth Tutorial on Server-side JavaScript Deployment';
|
|
195
|
+
This behavior allows safe integration into real-time editors without unexpected trimming or cursor instability when normalization is disabled (see [Issue #17](https://github.com/danielhaim1/TitleCaser/issues/17) for discussion).
|
|
278
196
|
|
|
279
|
-
|
|
280
|
-
|
|
197
|
+
### Browser Usage
|
|
198
|
+
```html
|
|
199
|
+
<script src="./path/to/TitleCaser.amd.js"></script>
|
|
281
200
|
```
|
|
282
201
|
|
|
283
|
-
### TitleCaser with Possessive Noun and a Colon
|
|
284
|
-
|
|
285
|
-
The example below demonstrates how to use the TitleCaser class to convert a string to title case with AP style formatting, including a possessive noun and a colon.
|
|
286
|
-
|
|
287
202
|
```javascript
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// Instantiate a new TitleCaser object with AP style formatting
|
|
291
|
-
const titleCaser = new TitleCaser({ style: "ap" });
|
|
203
|
+
const output = "the future of devops: the next era"
|
|
204
|
+
.toTitleCase({ style: 'apa' });
|
|
292
205
|
|
|
293
|
-
//
|
|
294
|
-
const input = "the iphone's impact on modern communication: a sociolinguistic analysis";
|
|
295
|
-
|
|
296
|
-
// Set the expected output
|
|
297
|
-
const expectedOutput = "The iPhone's Impact on Modern Communication: A Sociolinguistic Analysis";
|
|
298
|
-
|
|
299
|
-
// Call the toTitleCase method and store the result in actualOutput
|
|
300
|
-
const actualOutput = titleCaser.toTitleCase(input);
|
|
206
|
+
console.log(output); // → "The Future of DevOps: The Next Era"
|
|
301
207
|
```
|
|
302
208
|
|
|
303
|
-
###
|
|
304
|
-
|
|
305
|
-
The example below demonstrates how to use the TitleCaser with smart quotes.
|
|
209
|
+
### Real-World DOM Example
|
|
210
|
+
Automatically normalize editorial headings in a publishing workflow:
|
|
306
211
|
|
|
212
|
+
```html
|
|
213
|
+
<h2>nodejs development on aws: an in-depth tutorial on server-side javascript deployment</h2>
|
|
214
|
+
<h2>the iphone's impact on modern communication: a sociolinguistic analysis</h2>
|
|
215
|
+
<h2>back-end and front-end</h2>
|
|
216
|
+
```
|
|
307
217
|
```javascript
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
// Instantiate a new TitleCaser object with AP style formatting and smart quotes enabled
|
|
311
|
-
const titleCaser = new TitleCaser({
|
|
312
|
-
style: 'ap',
|
|
313
|
-
smartQuotes: true
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
// Set the input string to be tested
|
|
317
|
-
const input = '"Never underestimate the power O\' persistence,"';
|
|
218
|
+
function applyTitleCaseToH2Elements(options = { style: "apa" }) {
|
|
219
|
+
const h2Elements = document.querySelectorAll("h2");
|
|
318
220
|
|
|
319
|
-
|
|
320
|
-
|
|
221
|
+
h2Elements.forEach((h2) => {
|
|
222
|
+
h2.innerHTML = h2.innerHTML.toTitleCase(options);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
321
225
|
|
|
322
|
-
|
|
323
|
-
const actualOutput = titleCaser.toTitleCase(input);
|
|
226
|
+
applyTitleCaseToH2Elements();
|
|
324
227
|
```
|
|
325
228
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
TitleCaser is structured into three main components:
|
|
329
|
-
|
|
330
|
-
1. **TitleCaser.js** - The main class that provides the public API
|
|
331
|
-
2. **TitleCaserConsts.js** - Contains constants, configuration, and data structures
|
|
332
|
-
3. **TitleCaserUtils.js** - Contains utility functions for text processing
|
|
333
|
-
|
|
334
|
-
### Data Structure
|
|
335
|
-
|
|
336
|
-
The package uses several JSON files to store specialized terms:
|
|
337
|
-
|
|
338
|
-
- **brandList.json**: Brand names and trademarks
|
|
339
|
-
- **businessFinanceLegalTerms.json**: Business and legal terminology
|
|
340
|
-
- **eCommerceDigitalTerms.json**: E-commerce and digital terms
|
|
341
|
-
- **globalGeography.json**: Geographic terms
|
|
342
|
-
- **marketingMediaTerms.json**: Marketing and media terms
|
|
343
|
-
- **miscSpecializedTerms.json**: Miscellaneous specialized terms
|
|
344
|
-
- **techComputingConcepts.json**: Technology and computing terms
|
|
345
|
-
- **timeAcademicTerms.json**: Time and academic terms
|
|
229
|
+
---
|
|
346
230
|
|
|
347
231
|
## API Reference
|
|
348
|
-
|
|
349
232
|
### Constructor
|
|
350
|
-
|
|
351
233
|
```javascript
|
|
352
234
|
new TitleCaser(options)
|
|
353
235
|
```
|
|
354
236
|
|
|
355
|
-
|
|
237
|
+
### Options
|
|
356
238
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
239
|
+
| Option | Type | Default | Description |
|
|
240
|
+
|------------------------|------------|---------|-------------|
|
|
241
|
+
| `style` | string | `'ap'` | Editorial style: `'ap' \| 'apa' \| 'chicago' \| 'nyt' \| 'wikipedia' \| 'british'` |
|
|
242
|
+
| `smartQuotes` | boolean | `false` | Converts straight quotes (`' "`) to typographic curly quotes |
|
|
243
|
+
| `neverCapitalize` | string[] | `[]` | Additional words that should remain lowercase (merged with style defaults) |
|
|
244
|
+
| `wordReplacementsList` | object[] | internal defaults | Array of `{ 'term': 'replacement' }` objects used for term normalization |
|
|
245
|
+
| `debug` | boolean | `false` | Enables internal warning logs during processing |
|
|
246
|
+
| `normalizeWhitespace` | boolean | `true` | Collapses consecutive whitespace and trims leading/trailing whitespace. Set to `false` to preserve original spacing (editor-safe mode). |
|
|
361
247
|
|
|
362
248
|
### Methods
|
|
363
249
|
|
|
364
250
|
#### toTitleCase(text)
|
|
365
|
-
|
|
366
|
-
Converts text to title case according to the selected style.
|
|
367
|
-
|
|
368
251
|
```javascript
|
|
369
|
-
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
#### setReplaceTerms(replaceTerms)
|
|
373
|
-
|
|
374
|
-
Sets the word replacement list.
|
|
375
|
-
|
|
376
|
-
```javascript
|
|
377
|
-
titleCaser.setReplaceTerms([
|
|
378
|
-
{ 'js': 'JavaScript' },
|
|
379
|
-
{ 'api': 'API' }
|
|
380
|
-
]);
|
|
252
|
+
titleCaser.toTitleCase('hello world'); // → "Hello World"
|
|
381
253
|
```
|
|
382
254
|
|
|
383
255
|
#### addReplaceTerm(term, replacement)
|
|
384
|
-
|
|
385
|
-
Adds a single term replacement.
|
|
386
|
-
|
|
387
256
|
```javascript
|
|
388
257
|
titleCaser.addReplaceTerm('js', 'JavaScript');
|
|
389
258
|
```
|
|
390
259
|
|
|
391
260
|
#### removeReplaceTerm(term)
|
|
392
|
-
|
|
393
|
-
Removes a term from the replacement list.
|
|
394
|
-
|
|
395
261
|
```javascript
|
|
396
262
|
titleCaser.removeReplaceTerm('js');
|
|
397
263
|
```
|
|
398
264
|
|
|
399
|
-
####
|
|
400
|
-
|
|
401
|
-
|
|
265
|
+
#### setReplaceTerms(terms)
|
|
266
|
+
```javascript
|
|
267
|
+
titleCaser.setReplaceTerms([
|
|
268
|
+
{ 'js': 'JavaScript' },
|
|
269
|
+
{ 'aws': 'AWS' }
|
|
270
|
+
]);
|
|
271
|
+
```
|
|
402
272
|
|
|
273
|
+
#### addExactPhraseReplacements(phrases)
|
|
403
274
|
```javascript
|
|
404
275
|
titleCaser.addExactPhraseReplacements([
|
|
405
|
-
{ 'the correct phrase': 'The Correct Phrase' }
|
|
276
|
+
{ 'the correct phrase': 'The Correct Phrase' },
|
|
277
|
+
{ 'another phrase': 'Another Phrase' }
|
|
406
278
|
]);
|
|
407
279
|
```
|
|
408
280
|
|
|
409
281
|
#### setStyle(style)
|
|
410
|
-
|
|
411
|
-
Sets the title case style.
|
|
412
|
-
|
|
413
282
|
```javascript
|
|
414
283
|
titleCaser.setStyle('chicago');
|
|
415
284
|
```
|
|
416
285
|
|
|
417
|
-
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Test Coverage
|
|
418
289
|
|
|
419
290
|
```bash
|
|
420
|
-
npm run build-package
|
|
421
|
-
npm run build-docs
|
|
422
|
-
npm run copy-package-to-docs
|
|
423
291
|
npm run test
|
|
424
292
|
```
|
|
425
293
|
|
|
426
|
-
|
|
294
|
+
- Extensive unit test coverage
|
|
295
|
+
- Cross-style validation (AP, Chicago, APA, NYT, Wikipedia)
|
|
296
|
+
- Acronym disambiguation edge cases
|
|
297
|
+
- Hyphenation edge cases
|
|
298
|
+
- Brand normalization
|
|
427
299
|
|
|
428
|
-
|
|
429
|
-
npm run test
|
|
430
|
-
```
|
|
300
|
+
---
|
|
431
301
|
|
|
432
302
|
## Resources
|
|
433
303
|
|
|
@@ -435,123 +305,35 @@ Useful materials for improving your knowledge of writing and language style guid
|
|
|
435
305
|
|
|
436
306
|
- [AP Stylebook, 56th Edition](https://store.stylebooks.com/ap-stylebook-56th-edition-print.html)
|
|
437
307
|
- [Publication Manual of the American Psychological Association, Seventh Edition (2020)](https://apastyle.apa.org/products/publication-manual-7th-edition)
|
|
438
|
-
- [Chicago Manual of Style: Capitalization](https://
|
|
308
|
+
- [Chicago Manual of Style: Capitalization](https://www.chicagomanualofstyle.org/book/ed17/part2/ch08/psec022.html)
|
|
439
309
|
- [The Bluebook: A Uniform System of Citation. 21st ed. Cambridge: Harvard Law Review Association, 2020](https://open.mitchellhamline.edu/cgi/viewcontent.cgi?article=2782&context=wmlr)
|
|
440
310
|
- [The Chicago Manual of Style, 17th Edition](https://press.uchicago.edu/ucp/books/book/chicago/C/bo25956703.html)
|
|
441
311
|
- [The New York Times Manual of Style and Usage](https://www.worldcat.org/title/946964415)
|
|
442
|
-
- [Wikipedia: Letter case](https://
|
|
312
|
+
- [Wikipedia: Letter case](https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Capital_letters)
|
|
443
313
|
- [Wikipedia:Manual of Style/Titles of works](https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Titles_of_works#Capital_letters)
|
|
444
314
|
|
|
315
|
+
---
|
|
316
|
+
|
|
445
317
|
## Report Bugs
|
|
446
318
|
|
|
447
319
|
If you encounter any bugs or issues while using the library or the demo page, please report them by opening a new issue in the repository's issue tracker.
|
|
448
320
|
|
|
449
321
|
When reporting a bug, please provide as much detail as possible, including the steps to reproduce the issue and any error messages that you see. I appreciate any contribution to improving this library.
|
|
450
322
|
|
|
323
|
+
---
|
|
324
|
+
|
|
451
325
|
## Contributing
|
|
452
326
|
|
|
453
327
|
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
|
|
454
328
|
|
|
329
|
+
---
|
|
330
|
+
|
|
455
331
|
## License
|
|
456
332
|
|
|
457
333
|
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
458
334
|
|
|
335
|
+
---
|
|
336
|
+
|
|
459
337
|
## Changelog
|
|
460
338
|
|
|
461
339
|
See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
|
|
462
|
-
|
|
463
|
-
## Tests
|
|
464
|
-
|
|
465
|
-
```bash
|
|
466
|
-
TitleCaser – Combined Words Ending with Symbol
|
|
467
|
-
✓ should preserve punctuation in "Championing Self-Acceptance: Landmark Initiative" (4 ms)
|
|
468
|
-
TitleCaser – Disambiguation of Acronym vs. Pronoun (AP Style)
|
|
469
|
-
✓ should capitalize "US" when preceded by "the" (1 ms)
|
|
470
|
-
✓ should capitalize "US" in geopolitical context (with comma) (1 ms)
|
|
471
|
-
✓ should capitalize "US" and "UK" together
|
|
472
|
-
✓ should capitalize "US" after "from the" (1 ms)
|
|
473
|
-
✓ should capitalize "US" after "via" (1 ms)
|
|
474
|
-
✓ should capitalize "US" before "Military"
|
|
475
|
-
✓ should capitalize "US" in geopolitical context (repeated case) (1 ms)
|
|
476
|
-
✓ should capitalize pronoun "us" (case #1) (1 ms)
|
|
477
|
-
✓ should capitalize pronoun "us" (case #2)
|
|
478
|
-
✓ should capitalize pronoun "us" (case #3) (1 ms)
|
|
479
|
-
✓ should capitalize "UK" in geopolitical context (with comma)
|
|
480
|
-
✓ should handle multiple country codes in same sentence (1 ms)
|
|
481
|
-
✓ should capitalize pronoun "us" in a parenthetical phrase (1 ms)
|
|
482
|
-
✓ should capitalize "USA" in formal context
|
|
483
|
-
✓ should capitalize "US" before "government" (AP style) (1 ms)
|
|
484
|
-
✓ should capitalize "US" before "military" (AP style)
|
|
485
|
-
✓ should capitalize "US" in geopolitical context (policy mention)
|
|
486
|
-
✓ should capitalize "US" before "Military" (repeat case) (1 ms)
|
|
487
|
-
✓ should capitalize "US" at the end of a sentence
|
|
488
|
-
✓ should capitalize pronoun "us" in casual speech
|
|
489
|
-
✓ should capitalize pronoun "us" in emotional context (1 ms)
|
|
490
|
-
✓ should capitalize pronoun "us" in passive voice
|
|
491
|
-
✓ should capitalize pronoun "us" with a compound verb
|
|
492
|
-
✓ should capitalize pronoun "us" in an inverted clause (1 ms)
|
|
493
|
-
✓ should capitalize pronoun "us" (repeat case #1)
|
|
494
|
-
✓ should capitalize pronoun "us" (repeat case #2) (1 ms)
|
|
495
|
-
✓ should capitalize pronoun "us" before "US Military"
|
|
496
|
-
✓ should capitalize pronoun "us" before "military" (1 ms)
|
|
497
|
-
✓ should capitalize pronoun "us" in a comma-separated clause
|
|
498
|
-
✓ should capitalize "UK" at end of sentence (1 ms)
|
|
499
|
-
✓ should capitalize "UK" in geopolitical context (repeat with comma)
|
|
500
|
-
✓ should capitalize "UK" before government mention (1 ms)
|
|
501
|
-
✓ should capitalize "UK" before territory mention
|
|
502
|
-
✓ should handle multiple country codes and pronouns in one sentence (2 ms)
|
|
503
|
-
✓ should handle multiple codes and pronouns with mention of military
|
|
504
|
-
✓ should handle multiple codes and pronouns with mention of talks (1 ms)
|
|
505
|
-
✓ should handle multiple codes and pronouns with mention of a bill (1 ms)
|
|
506
|
-
✓ should capitalize "USA" in formal context (repeat case)
|
|
507
|
-
✓ should capitalize "USA" before a bill mention (1 ms)
|
|
508
|
-
✓ should handle AP-style acronym "U.S." in uppercase context
|
|
509
|
-
✓ should handle "On & Off" phrases #1 (1 ms)
|
|
510
|
-
✓ should handle "On & Off" phrases #2
|
|
511
|
-
TitleCaser – Hyphenated & Apostrophized Words
|
|
512
|
-
✓ should capitalize both parts of "t-mobile"
|
|
513
|
-
✓ should capitalize "coca-cola"
|
|
514
|
-
✓ should capitalize general hyphenated term "e-commerce" (1 ms)
|
|
515
|
-
✓ should capitalize apostrophe word "o'connor"
|
|
516
|
-
TitleCaser – Basic Title Casing Options (Default Style)
|
|
517
|
-
✓ should convert a basic lowercase phrase to title case
|
|
518
|
-
✓ should handle excessive spacing and lowercase articles
|
|
519
|
-
✓ should handle brand casing with AP-style logic (1 ms)
|
|
520
|
-
✓ should preserve correct casing in hyphenated names like "louis-iv"
|
|
521
|
-
✓ should properly capitalize prepositions beyond 3 letters (1 ms)
|
|
522
|
-
TitleCaser – Class Methods (setReplaceTerms, addExactPhraseReplacements, etc.)
|
|
523
|
-
✓ should apply Wikipedia style to an entire sentence (1 ms)
|
|
524
|
-
✓ should apply multiple term replacements via setReplaceTerms()
|
|
525
|
-
✓ should apply exact phrase replacements (1 ms)
|
|
526
|
-
✓ should remove a single replacement rule via removeReplaceTerm()
|
|
527
|
-
TitleCaser – Variation Stability Tests (AP, Chicago, APA, NYT, Wikipedia)
|
|
528
|
-
✓ should correctly handle brand names with "ap" style
|
|
529
|
-
✓ should handle brand name "NERDs Candy" with AP style
|
|
530
|
-
✓ should handle possessives and colons (AP style)
|
|
531
|
-
✓ should handle hyphenated "BACK-end" with AP style
|
|
532
|
-
✓ should handle acronym with colon (AP style) (1 ms)
|
|
533
|
-
✓ should handle colon + comparison phrase (Chicago)
|
|
534
|
-
✓ should capitalize hyphenated terms (Chicago) (1 ms)
|
|
535
|
-
✓ should apply custom replacements for brand names (Chicago) (1 ms)
|
|
536
|
-
✓ Smart quotes enabled
|
|
537
|
-
✓ should keep acronyms in uppercase (Chicago)
|
|
538
|
-
✓ should capitalize after colon (APA) (1 ms)
|
|
539
|
-
✓ should handle colon and apostrophes (APA)
|
|
540
|
-
✓ should handle short conjunctions and brand normalization (APA) (1 ms)
|
|
541
|
-
✓ should handle acronym + colon usage (NYT) (1 ms)
|
|
542
|
-
✓ should preserve sentence case for Wikipedia style (DevOps example) (1 ms)
|
|
543
|
-
✓ should handle Wikipedia style with colon usage (1 ms)
|
|
544
|
-
TitleCaser – Reserved Words & Special Handling
|
|
545
|
-
✓ should transform a single reserved word correctly
|
|
546
|
-
✓ should transform sentence with reserved word + colon
|
|
547
|
-
✓ should handle possessive form of reserved word
|
|
548
|
-
✓ should apply brand replacements (e.g., "mcdonalds" → "McDonald's") (1 ms)
|
|
549
|
-
✓ should handle HTML <br> with colon (spaced)
|
|
550
|
-
✓ should handle HTML <br> with full sentence split (1 ms)
|
|
551
|
-
✓ should handle <br> with no space after colon
|
|
552
|
-
✓ should handle ampersand "&" symbol (1 ms)
|
|
553
|
-
✓ should handle excessive whitespace
|
|
554
|
-
TitleCaser – addReplaceTerm Method
|
|
555
|
-
✓ should add a new replacement term
|
|
556
|
-
✓ should update an existing replacement term
|
|
557
|
-
```
|