Converts camelCase, PascalCase and delimited strings to captions, for labelling a form field, table column or menu item from the name behind it
Delimiters are dot, underscore, and dash: [ . _ - ]
foo.bar / foo_bar / fooBar / foo-bar
Foo Bar
_hello_world_
Hello World
thisIsATest
This Is A Test
npm install --save to-caption
import toCaption from 'to-caption'
toCaption('helloWorld') // 'Hello World'
const toCaption = require('to-caption')
toCaption('helloWorld') // 'Hello World'
TypeScript declarations are included for both.
A webpacked UMD build is included at dist/toCaption.js. The function is exported as window.toCaption(...)
<html>
<head>
<script src="https://unpkg.com/to-caption/dist/toCaption.js"></script>
<script>
console.log(toCaption('helloWorld'))
</script>
</head>
</html>
fooÉtat becomes Foo Étatnull, undefined and anything else that is not a string give an empty stringThis table should give you an idea of the process.
| ID | Label | Comment |
|---|---|---|
| this.is.a.test | This Is A Test | |
| foo | Foo | |
| Foo | Foo | |
| foobar | Foobar | |
| fooBar | Foo Bar | |
| FooBar | Foo Bar | |
| foo_bar | Foo Bar | |
| foo.bar | Foo Bar | |
| foo-bar | Foo Bar | |
| foo/bar | Foo/bar | Slash is not a delimiter |
| foo/bar | Foo Bar | delimiters = '/' |
| _foo | Foo | |
| foo_ | Foo | |
| _foo_ | Foo | |
| _foo_bar_ | Foo Bar | |
| __foo | Foo | |
| foo__ | Foo | |
| --foo--bar-- | Foo Bar | |
| address2 | Address2 | Digits stay attached |
| address2 | Address 2 | numbers = 'split' |
| parseHTTPResponse | Parse H T T P Response | Every capital starts a word |
| parseHTTPResponse | Parse HTTP Response | acronyms = 'keep' |
| FOOBAR | F O O B A R | See the onAllUppercase option to avoid this behavior |
| FOOBAR | FOOBAR | onAllUppercase = 'keep' |
| FOOBAR | Foobar | onAllUppercase = 'titlecase' |
| FOO_BAR | Foo Bar | onAllUppercase = 'titlecase' |
| FOO_BAR | FOO BAR | acronyms = 'keep' |
The second argument is optional, and may be undefined or null. Options combine freely
toCaption('parseHTTP2Response', { acronyms: 'keep', numbers: 'split' }) // 'Parse HTTP 2 Response'
| Option | Values | Default |
|---|---|---|
onAllUppercase |
'keep', 'titlecase' |
every capital becomes its own word |
acronyms |
'keep' |
every capital becomes its own word |
numbers |
'split' |
digits stay attached to the letters beside them |
delimiters |
any string | '._-' |
Any value not listed, including undefined and null, gives the default
toCaption('HELLO', { onAllUppercase: 'keep' }) // 'HELLO'
Sets the behavior when the string is all uppercase: it has at least one letter, and no lowercase letters. A string with no letters at all, such as 123_456, is not all uppercase and is captioned as usual
The string is returned exactly as given, delimiters included (_HELLO_WORLD_ stays _HELLO_WORLD_). To keep the capitals and still replace the delimiters, use acronyms: 'keep' instead
Each delimited word becomes titlecase (HELLO_WORLD becomes Hello World)
The string has spaces between each letter, as if each letter was a word (H E L L O)
toCaption('parseHTTPResponse', { acronyms: 'keep' }) // 'Parse HTTP Response'
A run of capitals stays together. The last capital of a run starts the next word when a lowercase letter follows it, so XMLHttpRequest becomes XML Http Request and thisIsATest is still This Is A Test. An all uppercase string keeps its words whole (HELLO_WORLD becomes HELLO WORLD), unless onAllUppercase says otherwise
Every capital starts a word (Parse H T T P Response)
toCaption('version10Beta3', { numbers: 'split' }) // 'Version 10 Beta 3'
A space goes between digits and letters, and the word after a number is capitalized (item2name becomes Item 2 Name). A run of digits stays together
Digits stay attached to the letters beside them (Version10 Beta3)
toCaption('foo bar/baz', { delimiters: ' /' }) // 'Foo Bar Baz'
A string of the characters that separate words. It replaces the default '._-' and does not add to it, so include those three if you still want them. An empty string means nothing is a delimiter
require. Tested on Node 20, 24 and 25npm run build # webpack the UMD build into dist/
npm run copyright # set the copyright year range in LICENSE and every source header
npm run lint # eslint, including the no-semicolon and single-quote rules
npm test # mocha, against both the ES module and the CommonJS build
npm run check:types # verify the published types resolve for every consumer
npm run check:homepage # confirm the homepage in package.json answers
npm publish runs all of these first, through prepublishOnly
The copyright holder and start year are set once, in config.copyright in package.json. The end year is always the current year, and npm run lint fails on any header that is out of date
The files in test2/ are manual checks: node test2/node_import.js, node test2/node_require.cjs, and test2/test.html in a browser
MIT. Check the LICENSE file for all the details.