diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..5a5888d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +coverage/ +double-metaphone.js +double-metaphone.min.js diff --git a/cli.js b/cli.js index dbeeb56..3a19038 100755 --- a/cli.js +++ b/cli.js @@ -1,61 +1,60 @@ #!/usr/bin/env node -'use strict'; +'use strict' -var pack = require('./package.json'); -var doubleMetaphone = require('.'); +var pack = require('./package.json') +var doubleMetaphone = require('.') -var argv = process.argv.slice(2); +var argv = process.argv.slice(2) -if ( - argv.indexOf('--help') !== -1 || - argv.indexOf('-h') !== -1 -) { - console.log(help()); -} else if ( - argv.indexOf('--version') !== -1 || - argv.indexOf('-v') !== -1 -) { - console.log(pack.version); +if (argv.indexOf('--help') !== -1 || argv.indexOf('-h') !== -1) { + console.log(help()) +} else if (argv.indexOf('--version') !== -1 || argv.indexOf('-v') !== -1) { + console.log(pack.version) } else if (argv.length === 0) { - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - process.stdin.on('data', function (data) { - console.log(phonetics(data)); - }); + process.stdin.resume() + process.stdin.setEncoding('utf8') + process.stdin.on('data', function(data) { + console.log(phonetics(data)) + }) } else { - console.log(phonetics(argv.join(' '))); + console.log(phonetics(argv.join(' '))) } function phonetics(values) { - return values.split(/\s+/g).map(function (val) { - return doubleMetaphone(val).join('\t'); - }).join(' '); + return values + .split(/\s+/g) + .map(function(val) { + return doubleMetaphone(val).join('\t') + }) + .join(' ') } function help() { - return [ - '', - 'Usage: ' + pack.name + ' [options] ', - '', - pack.description, - '', - 'Options:', - '', - ' -h, --help output usage information', - ' -v, --version output version number', - '', - 'Usage:', - '', - '# output phonetics', - '$ ' + pack.name + ' michael', - '# ' + phonetics('michael'), - '', - '# output phonetics from stdin', - '$ echo \'Xavier\' | ' + pack.name, - '# ' + phonetics('Xavier'), - '', - '# with stemmer', - '$ echo \'acceptingness\' | stemmer | ' + pack.name, - '# ' + phonetics('accepting') - ].join('\n ') + '\n'; + return ( + [ + '', + 'Usage: ' + pack.name + ' [options] ', + '', + pack.description, + '', + 'Options:', + '', + ' -h, --help output usage information', + ' -v, --version output version number', + '', + 'Usage:', + '', + '# output phonetics', + '$ ' + pack.name + ' michael', + '# ' + phonetics('michael'), + '', + '# output phonetics from stdin', + "$ echo 'Xavier' | " + pack.name, + '# ' + phonetics('Xavier'), + '', + '# with stemmer', + "$ echo 'acceptingness' | stemmer | " + pack.name, + '# ' + phonetics('accepting') + ].join('\n ') + '\n' + ) } diff --git a/index.js b/index.js index fa00795..7d944a4 100644 --- a/index.js +++ b/index.js @@ -1,103 +1,89 @@ -'use strict'; +'use strict' -/* Expose. */ -module.exports = doubleMetaphone; +module.exports = doubleMetaphone -/* Match vowels (including `Y`). */ -var VOWELS = /[AEIOUY]/; +// Match vowels (including `Y`). +var vowels = /[AEIOUY]/ -/* Match few Slavo-Germanic values. */ -var SLAVO_GERMANIC = /W|K|CZ|WITZ/; +// Match few Slavo-Germanic values. +var slavoGermanic = /W|K|CZ|WITZ/ -/* Match few Germanic values. */ -var GERMANIC = /^(VAN |VON |SCH)/; +// Match few Germanic values. +var germanic = /^(VAN |VON |SCH)/ -/* Match initial values of which the first character - * should be skipped. */ -var INITIAL_EXCEPTIONS = /^(GN|KN|PN|WR|PS)/; +// Match initial values of which the first character should be skipped. +var initialExceptions = /^(GN|KN|PN|WR|PS)/ -/* Match initial Greek-like values of which the `CH` - * sounds like `K`. */ -var GREEK_INITIAL_CH = /^CH(IA|EM|OR([^E])|YM|ARAC|ARIS)/; +// Match initial Greek-like values of which the `CH` sounds like `K`. +var initialGreekCh = /^CH(IA|EM|OR([^E])|YM|ARAC|ARIS)/ -/* Match Greek-like values of which the `CH` sounds - * like `K`. */ -var GREEK_CH = /ORCHES|ARCHIT|ORCHID/; +// Match Greek-like values of which the `CH` sounds like `K`. +var greekCh = /ORCHES|ARCHIT|ORCHID/ -/* Match values which when following `CH`, transform `CH` - * to sound like `K`. */ -var CH_FOR_KH = /[ BFHLMNRVW]/; +// Match values which when following `CH`, transform `CH` to sound like `K`. +var chForKh = /[ BFHLMNRVW]/ -/* Match values which when preceding a vowel and `UGH`, - * sound like `F`. */ -var G_FOR_F = /[CGLRT]/; +// Match values which when preceding a vowel and `UGH`, sound like `F`. +var gForF = /[CGLRT]/ -/* Match initial values which sound like either `K` or `J`. */ -var INITIAL_G_FOR_KJ = /Y[\s\S]|E[BILPRSY]|I[BELN]/; +// Match initial values which sound like either `K` or `J`. +var initialGForKj = /Y[\s\S]|E[BILPRSY]|I[BELN]/ -/* Match initial values which sound like either `K` or `J`. */ -var INITIAL_ANGER_EXCEPTION = /^[DMR]ANGER/; +// Match initial values which sound like either `K` or `J`. +var initialAngerException = /^[DMR]ANGER/ -/* Match values which when following `GY`, do not sound - * like `K` or `J`. */ -var G_FOR_KJ = /[EGIR]/; +// Match values which when following `GY`, do not sound like `K` or `J`. +var gForKj = /[EGIR]/ -/* Match values which when following `J`, do not sound `J`. */ -var J_FOR_J_EXCEPTION = /[LTKSNMBZ]/; +// Match values which when following `J`, do not sound `J`. +var jForJException = /[LTKSNMBZ]/ -/* Match values which might sound like `L`. */ -var ALLE = /AS|OS/; +// Match values which might sound like `L`. +var alle = /AS|OS/ -/* Match Germanic values preceding `SH` which sound - * like `S`. */ -var H_FOR_S = /EIM|OEK|OLM|OLZ/; +// Match Germanic values preceding `SH` which sound like `S`. +var hForS = /EIM|OEK|OLM|OLZ/ -/* Match Dutch values following `SCH` which sound like - * either `X` and `SK`, or `SK`. */ -var DUTCH_SCH = /E[DMNR]|UY|OO/; +// Match Dutch values following `SCH` which sound like either `X` and `SK`, +// or `SK`. +var dutchSch = /E[DMNR]|UY|OO/ -/** - * Get the phonetics according to the Double Metaphone - * algorithm from a value. - * - * @param {string} value - value to detect phonetics for. - * @return {Array.} - Two phonetics. - */ +// Get the phonetics according to the Double Metaphone algorithm from a value. function doubleMetaphone(value) { - var primary = ''; - var secondary = ''; - var index = 0; - var length = value.length; - var last = length - 1; - var isSlavoGermanic; - var isGermanic; - var subvalue; - var next; - var prev; - var nextnext; - var characters; - - value = String(value).toUpperCase() + ' '; - isSlavoGermanic = SLAVO_GERMANIC.test(value); - isGermanic = GERMANIC.test(value); - characters = value.split(''); - - /* Skip this at beginning of word. */ - if (INITIAL_EXCEPTIONS.test(value)) { - index++; + var primary = '' + var secondary = '' + var index = 0 + var length = value.length + var last = length - 1 + var isSlavoGermanic + var isGermanic + var subvalue + var next + var prev + var nextnext + var characters + + value = String(value).toUpperCase() + ' ' + isSlavoGermanic = slavoGermanic.test(value) + isGermanic = germanic.test(value) + characters = value.split('') + + // Skip this at beginning of word. + if (initialExceptions.test(value)) { + index++ } - /* Initial X is pronounced Z, which maps to S. Such as `Xavier` */ + // Initial X is pronounced Z, which maps to S. Such as `Xavier`. if (characters[0] === 'X') { - primary += 'S'; - secondary += 'S'; - index++; + primary += 'S' + secondary += 'S' + index++ } while (index < length) { - prev = characters[index - 1]; - next = characters[index + 1]; - nextnext = characters[index + 2]; + prev = characters[index - 1] + next = characters[index + 1] + nextnext = characters[index + 2] switch (characters[index]) { case 'A': @@ -110,1020 +96,920 @@ function doubleMetaphone(value) { case 'Ê': case 'É': if (index === 0) { - /* All initial vowels now map to `A`. */ - primary += 'A'; - secondary += 'A'; + // All initial vowels now map to `A`. + primary += 'A' + secondary += 'A' } - index++; + index++ - break; + break case 'B': - primary += 'P'; - secondary += 'P'; + primary += 'P' + secondary += 'P' if (next === 'B') { - index++; + index++ } - index++; + index++ - break; + break case 'Ç': - primary += 'S'; - secondary += 'S'; - index++; + primary += 'S' + secondary += 'S' + index++ - break; + break case 'C': - /* Various Germanic: */ + // Various Germanic: if ( prev === 'A' && next === 'H' && nextnext !== 'I' && - !VOWELS.test(characters[index - 2]) && - ( - nextnext !== 'E' || - ( - subvalue = value.slice(index - 2, index + 4) && - (subvalue === 'BACHER' || subvalue === 'MACHER') - ) - ) + !vowels.test(characters[index - 2]) && + (nextnext !== 'E' || + (subvalue = + value.slice(index - 2, index + 4) && + (subvalue === 'BACHER' || subvalue === 'MACHER'))) ) { - primary += 'K'; - secondary += 'K'; - index += 2; + primary += 'K' + secondary += 'K' + index += 2 - break; + break } - /* Special case for `Caesar`. */ + // Special case for `Caesar`. if (index === 0 && value.slice(index + 1, index + 6) === 'AESAR') { - primary += 'S'; - secondary += 'S'; - index += 2; + primary += 'S' + secondary += 'S' + index += 2 - break; + break } - /* Italian `Chianti`. */ + // Italian `Chianti`. if (value.slice(index + 1, index + 4) === 'HIA') { - primary += 'K'; - secondary += 'K'; - index += 2; + primary += 'K' + secondary += 'K' + index += 2 - break; + break } if (next === 'H') { - /* Find `Michael`. */ - if ( - index > 0 && - nextnext === 'A' && - characters[index + 3] === 'E' - ) { - primary += 'K'; - secondary += 'X'; - index += 2; + // Find `Michael`. + if (index > 0 && nextnext === 'A' && characters[index + 3] === 'E') { + primary += 'K' + secondary += 'X' + index += 2 - break; + break } - /* Greek roots such as `chemistry`, `chorus`. */ - if (index === 0 && GREEK_INITIAL_CH.test(value)) { - primary += 'K'; - secondary += 'K'; - index += 2; + // Greek roots such as `chemistry`, `chorus`. + if (index === 0 && initialGreekCh.test(value)) { + primary += 'K' + secondary += 'K' + index += 2 - break; + break } - /* Germanic, Greek, or otherwise `CH` for `KH` sound. */ + // Germanic, Greek, or otherwise `CH` for `KH` sound. if ( isGermanic || - /* Such as 'architect' but not 'arch', orchestra', - * 'orchid'. */ - GREEK_CH.test(value.slice(index - 2, index + 4)) || + // Such as 'architect' but not 'arch', orchestra', 'orchid'. + greekCh.test(value.slice(index - 2, index + 4)) || (nextnext === 'T' || nextnext === 'S') || - ( - ( - index === 0 || - prev === 'A' || - prev === 'E' || - prev === 'O' || - prev === 'U' - ) && - /* Such as `wachtler`, `weschsler`, but not - * `tichner`. */ - CH_FOR_KH.test(nextnext) - ) + ((index === 0 || + prev === 'A' || + prev === 'E' || + prev === 'O' || + prev === 'U') && + // Such as `wachtler`, `weschsler`, but not `tichner`. + chForKh.test(nextnext)) ) { - primary += 'K'; - secondary += 'K'; + primary += 'K' + secondary += 'K' } else if (index === 0) { - primary += 'X'; - secondary += 'X'; - /* Such as 'McHugh'. */ + primary += 'X' + secondary += 'X' + // Such as 'McHugh'. } else if (value.slice(0, 2) === 'MC') { - /* Bug? Why matching absolute? what about McHiccup? */ - primary += 'K'; - secondary += 'K'; + // Bug? Why matching absolute? what about McHiccup? + primary += 'K' + secondary += 'K' } else { - primary += 'X'; - secondary += 'K'; + primary += 'X' + secondary += 'K' } - index += 2; + index += 2 - break; + break } - /* Such as `Czerny`. */ - if ( - next === 'Z' && - value.slice(index - 2, index) !== 'WI' - ) { - primary += 'S'; - secondary += 'X'; - index += 2; + // Such as `Czerny`. + if (next === 'Z' && value.slice(index - 2, index) !== 'WI') { + primary += 'S' + secondary += 'X' + index += 2 - break; + break } - /* Such as `Focaccia`. */ + // Such as `Focaccia`. if (value.slice(index + 1, index + 4) === 'CIA') { - primary += 'X'; - secondary += 'X'; - index += 3; + primary += 'X' + secondary += 'X' + index += 3 - break; + break } - /* Double `C`, but not `McClellan`. */ - if ( - next === 'C' && - !(index === 1 && characters[0] === 'M') - ) { - /* Such as `Bellocchio`, but not `Bacchus`. */ + // Double `C`, but not `McClellan`. + if (next === 'C' && !(index === 1 && characters[0] === 'M')) { + // Such as `Bellocchio`, but not `Bacchus`. if ( - ( - nextnext === 'I' || - nextnext === 'E' || - nextnext === 'H' - ) && + (nextnext === 'I' || nextnext === 'E' || nextnext === 'H') && value.slice(index + 2, index + 4) !== 'HU' ) { - subvalue = value.slice(index - 1, index + 4); + subvalue = value.slice(index - 1, index + 4) - /* Such as `Accident`, `Accede`, `Succeed`. */ + // Such as `Accident`, `Accede`, `Succeed`. if ( (index === 1 && prev === 'A') || subvalue === 'UCCEE' || subvalue === 'UCCES' ) { - primary += 'KS'; - secondary += 'KS'; - /* Such as `Bacci`, `Bertucci`, other Italian. */ + primary += 'KS' + secondary += 'KS' + // Such as `Bacci`, `Bertucci`, other Italian. } else { - primary += 'X'; - secondary += 'X'; + primary += 'X' + secondary += 'X' } - index += 3; + index += 3 - break; + break } else { - /* Pierce's rule. */ - primary += 'K'; - secondary += 'K'; - index += 2; + // Pierce's rule. + primary += 'K' + secondary += 'K' + index += 2 - break; + break } } if (next === 'G' || next === 'K' || next === 'Q') { - primary += 'K'; - secondary += 'K'; - index += 2; + primary += 'K' + secondary += 'K' + index += 2 - break; + break } - /* Italian. */ + // Italian. if ( next === 'I' && - /* Bug: The original algorithm also calls for A (as - * in CIA), which is already taken care of above. */ + // Bug: The original algorithm also calls for A (as in CIA), which is + // already taken care of above. (nextnext === 'E' || nextnext === 'O') ) { - primary += 'S'; - secondary += 'X'; - index += 2; + primary += 'S' + secondary += 'X' + index += 2 - break; + break } if (next === 'I' || next === 'E' || next === 'Y') { - primary += 'S'; - secondary += 'S'; - index += 2; + primary += 'S' + secondary += 'S' + index += 2 - break; + break } - primary += 'K'; - secondary += 'K'; + primary += 'K' + secondary += 'K' - /* Skip two extra characters ahead in `Mac Caffrey`, - * `Mac Gregor`. */ + // Skip two extra characters ahead in `Mac Caffrey`, `Mac Gregor`. if ( next === ' ' && (nextnext === 'C' || nextnext === 'G' || nextnext === 'Q') ) { - index += 3; - break; + index += 3 + break } - /* Bug: Already covered above. - * - * if ( - * next === 'K' || - * next === 'Q' || - * (next === 'C' && nextnext !== 'E' && nextnext !== 'I') - * ) { - * index++; - * } - */ - index++; - - break; + // Bug: Already covered above. + // if ( + // next === 'K' || + // next === 'Q' || + // (next === 'C' && nextnext !== 'E' && nextnext !== 'I') + // ) { + // index++; + // } + + index++ + + break case 'D': if (next === 'G') { - /* Such as `edge`. */ + // Such as `edge`. if (nextnext === 'E' || nextnext === 'I' || nextnext === 'Y') { - primary += 'J'; - secondary += 'J'; - index += 3; - /* Such as `Edgar`. */ + primary += 'J' + secondary += 'J' + index += 3 + // Such as `Edgar`. } else { - primary += 'TK'; - secondary += 'TK'; - index += 2; + primary += 'TK' + secondary += 'TK' + index += 2 } - break; + break } if (next === 'T' || next === 'D') { - primary += 'T'; - secondary += 'T'; - index += 2; + primary += 'T' + secondary += 'T' + index += 2 - break; + break } - primary += 'T'; - secondary += 'T'; - index++; + primary += 'T' + secondary += 'T' + index++ - break; + break case 'F': if (next === 'F') { - index++; + index++ } - index++; - primary += 'F'; - secondary += 'F'; + index++ + primary += 'F' + secondary += 'F' - break; + break case 'G': if (next === 'H') { - if (index > 0 && !VOWELS.test(prev)) { - primary += 'K'; - secondary += 'K'; - index += 2; + if (index > 0 && !vowels.test(prev)) { + primary += 'K' + secondary += 'K' + index += 2 - break; + break } - /* Such as `Ghislane`, `Ghiradelli`. */ + // Such as `Ghislane`, `Ghiradelli`. if (index === 0) { if (nextnext === 'I') { - primary += 'J'; - secondary += 'J'; + primary += 'J' + secondary += 'J' } else { - primary += 'K'; - secondary += 'K'; + primary += 'K' + secondary += 'K' } - index += 2; + index += 2 - break; + break } - /* Parker's rule (with some further refinements). */ + // Parker's rule (with some further refinements). if ( - ( - /* Such as `Hugh`. The comma is not a bug. */ - subvalue = characters[index - 2], - subvalue === 'B' || - subvalue === 'H' || - subvalue === 'D' - ) || - ( - /* Such as `bough`. The comma is not a bug. */ - subvalue = characters[index - 3], - subvalue === 'B' || - subvalue === 'H' || - subvalue === 'D' - ) || - ( - /* Such as `Broughton`. The comma is not a bug. */ - subvalue = characters[index - 4], - subvalue === 'B' || - subvalue === 'H' - ) + // Such as `Hugh`. The comma is not a bug. + ((subvalue = characters[index - 2]), + subvalue === 'B' || subvalue === 'H' || subvalue === 'D') || + // Such as `bough`. The comma is not a bug. + ((subvalue = characters[index - 3]), + subvalue === 'B' || subvalue === 'H' || subvalue === 'D') || + // Such as `Broughton`. The comma is not a bug. + ((subvalue = characters[index - 4]), + subvalue === 'B' || subvalue === 'H') ) { - index += 2; + index += 2 - break; + break } - /* Such as `laugh`, `McLaughlin`, `cough`, `gough`, - * `rough`, `tough`. */ - if ( - index > 2 && - prev === 'U' && - G_FOR_F.test(characters[index - 3]) - ) { - primary += 'F'; - secondary += 'F'; + // Such as `laugh`, `McLaughlin`, `cough`, `gough`, `rough`, `tough`. + if (index > 2 && prev === 'U' && gForF.test(characters[index - 3])) { + primary += 'F' + secondary += 'F' } else if (index > 0 && prev !== 'I') { - primary += 'K'; - secondary += 'K'; + primary += 'K' + secondary += 'K' } - index += 2; + index += 2 - break; + break } if (next === 'N') { - if ( - index === 1 && - VOWELS.test(characters[0]) && - !isSlavoGermanic - ) { - primary += 'KN'; - secondary += 'N'; - /* Not like `Cagney`. */ + if (index === 1 && vowels.test(characters[0]) && !isSlavoGermanic) { + primary += 'KN' + secondary += 'N' + // Not like `Cagney`. } else if ( value.slice(index + 2, index + 4) !== 'EY' && value.slice(index + 1) !== 'Y' && !isSlavoGermanic ) { - primary += 'N'; - secondary += 'KN'; + primary += 'N' + secondary += 'KN' } else { - primary += 'KN'; - secondary += 'KN'; + primary += 'KN' + secondary += 'KN' } - index += 2; + index += 2 - break; + break } - /* Such as `Tagliaro`. */ - if ( - value.slice(index + 1, index + 3) === 'LI' && - !isSlavoGermanic - ) { - primary += 'KL'; - secondary += 'L'; - index += 2; + // Such as `Tagliaro`. + if (value.slice(index + 1, index + 3) === 'LI' && !isSlavoGermanic) { + primary += 'KL' + secondary += 'L' + index += 2 - break; + break } - /* -ges-, -gep-, -gel- at beginning. */ - if ( - index === 0 && - INITIAL_G_FOR_KJ.test(value.slice(1, 3)) - ) { - primary += 'K'; - secondary += 'J'; - index += 2; + // -ges-, -gep-, -gel- at beginning. + if (index === 0 && initialGForKj.test(value.slice(1, 3))) { + primary += 'K' + secondary += 'J' + index += 2 - break; + break } - /* -ger-, -gy-. */ + // -ger-, -gy-. if ( - ( - value.slice(index + 1, index + 3) === 'ER' && - prev !== 'I' && prev !== 'E' && - !INITIAL_ANGER_EXCEPTION.test(value.slice(0, 6)) - ) || - (next === 'Y' && !G_FOR_KJ.test(prev)) + (value.slice(index + 1, index + 3) === 'ER' && + prev !== 'I' && + prev !== 'E' && + !initialAngerException.test(value.slice(0, 6))) || + (next === 'Y' && !gForKj.test(prev)) ) { - primary += 'K'; - secondary += 'J'; - index += 2; + primary += 'K' + secondary += 'J' + index += 2 - break; + break } - /* Italian such as `biaggi`. */ + // Italian such as `biaggi`. if ( next === 'E' || next === 'I' || next === 'Y' || - ( - (prev === 'A' || prev === 'O') && - next === 'G' && - nextnext === 'I' - ) + ((prev === 'A' || prev === 'O') && next === 'G' && nextnext === 'I') ) { - /* Obvious Germanic. */ - if ( - value.slice(index + 1, index + 3) === 'ET' || - isGermanic - ) { - primary += 'K'; - secondary += 'K'; + // Obvious Germanic. + if (value.slice(index + 1, index + 3) === 'ET' || isGermanic) { + primary += 'K' + secondary += 'K' } else { - primary += 'J'; + primary += 'J' - /* Always soft if French ending. */ + // Always soft if French ending. if (value.slice(index + 1, index + 5) === 'IER ') { - secondary += 'J'; + secondary += 'J' } else { - secondary += 'K'; + secondary += 'K' } } - index += 2; + index += 2 - break; + break } if (next === 'G') { - index++; + index++ } - index++; + index++ - primary += 'K'; - secondary += 'K'; + primary += 'K' + secondary += 'K' - break; + break case 'H': - /* Only keep if first & before vowel or btw. 2 vowels. */ - if (VOWELS.test(next) && (index === 0 || VOWELS.test(prev))) { - primary += 'H'; - secondary += 'H'; + // Only keep if first & before vowel or btw. 2 vowels. + if (vowels.test(next) && (index === 0 || vowels.test(prev))) { + primary += 'H' + secondary += 'H' - index++; + index++ } - index++; + index++ - break; + break case 'J': - /* Obvious Spanish, `jose`, `San Jacinto`. */ + // Obvious Spanish, `jose`, `San Jacinto`. if ( value.slice(index, index + 4) === 'JOSE' || value.slice(0, 4) === 'SAN ' ) { if ( value.slice(0, 4) === 'SAN ' || - ( - index === 0 && - characters[index + 4] === ' ' - ) + (index === 0 && characters[index + 4] === ' ') ) { - primary += 'H'; - secondary += 'H'; + primary += 'H' + secondary += 'H' } else { - primary += 'J'; - secondary += 'H'; + primary += 'J' + secondary += 'H' } - index++; + index++ - break; + break } if ( index === 0 - /* Bug: unreachable (see previous statement). - * && value.slice(index, index + 4) !== 'JOSE'. */ + // Bug: unreachable (see previous statement). + // && value.slice(index, index + 4) !== 'JOSE'. ) { - primary += 'J'; + primary += 'J' - /* Such as `Yankelovich` or `Jankelowicz`. */ - secondary += 'A'; - /* Spanish pron. of such as `bajador`. */ + // Such as `Yankelovich` or `Jankelowicz`. + secondary += 'A' + // Spanish pron. of such as `bajador`. } else if ( !isSlavoGermanic && (next === 'A' || next === 'O') && - VOWELS.test(prev) + vowels.test(prev) ) { - primary += 'J'; - secondary += 'H'; + primary += 'J' + secondary += 'H' } else if (index === last) { - primary += 'J'; + primary += 'J' } else if ( - prev !== 'S' && prev !== 'K' && prev !== 'L' && - !J_FOR_J_EXCEPTION.test(next) + prev !== 'S' && + prev !== 'K' && + prev !== 'L' && + !jForJException.test(next) ) { - primary += 'J'; - secondary += 'J'; - /* It could happen. */ + primary += 'J' + secondary += 'J' + // It could happen. } else if (next === 'J') { - index++; + index++ } - index++; + index++ - break; + break case 'K': if (next === 'K') { - index++; + index++ } - primary += 'K'; - secondary += 'K'; - index++; + primary += 'K' + secondary += 'K' + index++ - break; + break case 'L': if (next === 'L') { - /* Spanish such as `cabrillo`, `gallegos`. */ + // Spanish such as `cabrillo`, `gallegos`. if ( - ( - index === length - 3 && - ( - (prev === 'A' && nextnext === 'E') || - (prev === 'I' && (nextnext === 'O' || nextnext === 'A')) - ) - ) || - ( - prev === 'A' && + (index === length - 3 && + ((prev === 'A' && nextnext === 'E') || + (prev === 'I' && (nextnext === 'O' || nextnext === 'A')))) || + (prev === 'A' && nextnext === 'E' && - ( - (characters[last] === 'A' || characters[last] === 'O') || - ALLE.test(value.slice(last - 1, length)) - ) - ) + (characters[last] === 'A' || + characters[last] === 'O' || + alle.test(value.slice(last - 1, length)))) ) { - primary += 'L'; - index += 2; + primary += 'L' + index += 2 - break; + break } - index++; + index++ } - primary += 'L'; - secondary += 'L'; - index++; + primary += 'L' + secondary += 'L' + index++ - break; + break case 'M': if ( next === 'M' || - /* Such as `dumb`, `thumb`. */ - ( - prev === 'U' && + // Such as `dumb`, `thumb`. + (prev === 'U' && next === 'B' && - (index + 1 === last || value.slice(index + 2, index + 4) === 'ER') - ) + (index + 1 === last || value.slice(index + 2, index + 4) === 'ER')) ) { - index++; + index++ } - index++; - primary += 'M'; - secondary += 'M'; + index++ + primary += 'M' + secondary += 'M' - break; + break case 'N': if (next === 'N') { - index++; + index++ } - index++; - primary += 'N'; - secondary += 'N'; + index++ + primary += 'N' + secondary += 'N' - break; + break case 'Ñ': - index++; - primary += 'N'; - secondary += 'N'; + index++ + primary += 'N' + secondary += 'N' - break; + break case 'P': if (next === 'H') { - primary += 'F'; - secondary += 'F'; - index += 2; + primary += 'F' + secondary += 'F' + index += 2 - break; + break } - /* Also account for `campbell` and `raspberry`. */ - subvalue = next; + // Also account for `campbell` and `raspberry`. + subvalue = next if (subvalue === 'P' || subvalue === 'B') { - index++; + index++ } - index++; + index++ - primary += 'P'; - secondary += 'P'; + primary += 'P' + secondary += 'P' - break; + break case 'Q': if (next === 'Q') { - index++; + index++ } - index++; - primary += 'K'; - secondary += 'K'; + index++ + primary += 'K' + secondary += 'K' - break; + break case 'R': - /* French such as `Rogier`, but exclude `Hochmeier`. */ + // French such as `Rogier`, but exclude `Hochmeier`. if ( index === last && !isSlavoGermanic && prev === 'E' && characters[index - 2] === 'I' && characters[index - 4] !== 'M' && - ( - characters[index - 3] !== 'E' && - characters[index - 3] !== 'A' - ) + (characters[index - 3] !== 'E' && characters[index - 3] !== 'A') ) { - secondary += 'R'; + secondary += 'R' } else { - primary += 'R'; - secondary += 'R'; + primary += 'R' + secondary += 'R' } if (next === 'R') { - index++; + index++ } - index++; + index++ - break; + break case 'S': - /* Special cases `island`, `isle`, `carlisle`, `carlysle`. */ + // Special cases `island`, `isle`, `carlisle`, `carlysle`. if (next === 'L' && (prev === 'I' || prev === 'Y')) { - index++; + index++ - break; + break } - /* Special case `sugar-`. */ + // Special case `sugar-`. if (index === 0 && value.slice(1, 5) === 'UGAR') { - primary += 'X'; - secondary += 'S'; - index++; + primary += 'X' + secondary += 'S' + index++ - break; + break } if (next === 'H') { - /* Germanic. */ - if (H_FOR_S.test(value.slice(index + 1, index + 5))) { - primary += 'S'; - secondary += 'S'; + // Germanic. + if (hForS.test(value.slice(index + 1, index + 5))) { + primary += 'S' + secondary += 'S' } else { - primary += 'X'; - secondary += 'X'; + primary += 'X' + secondary += 'X' } - index += 2; - break; + index += 2 + break } if ( next === 'I' && (nextnext === 'O' || nextnext === 'A') - /* Bug: Already covered by previous branch - * || value.slice(index, index + 4) === 'SIAN' */ + // Bug: Already covered by previous branch + // || value.slice(index, index + 4) === 'SIAN' ) { if (isSlavoGermanic) { - primary += 'S'; - secondary += 'S'; + primary += 'S' + secondary += 'S' } else { - primary += 'S'; - secondary += 'X'; + primary += 'S' + secondary += 'X' } - index += 3; + index += 3 - break; + break } - /* German & Anglicization's, such as `Smith` match `Schmidt`, - * `snider` match `Schneider`. Also, -sz- in slavic language - * although in hungarian it is pronounced `s`. */ + // German & Anglicization's, such as `Smith` match `Schmidt`, `snider` + // match `Schneider`. Also, -sz- in slavic language although in + // hungarian it is pronounced `s`. if ( next === 'Z' || - ( - index === 0 && - (next === 'L' || next === 'M' || next === 'N' || next === 'W') - ) + (index === 0 && + (next === 'L' || next === 'M' || next === 'N' || next === 'W')) ) { - primary += 'S'; - secondary += 'X'; + primary += 'S' + secondary += 'X' if (next === 'Z') { - index++; + index++ } - index++; + index++ - break; + break } if (next === 'C') { - /* Schlesinger's rule. */ + // Schlesinger's rule. if (nextnext === 'H') { - subvalue = value.slice(index + 3, index + 5); + subvalue = value.slice(index + 3, index + 5) - /* Dutch origin, such as `school`, `schooner`. */ - if (DUTCH_SCH.test(subvalue)) { - /* Such as `schermerhorn`, `schenker`. */ + // Dutch origin, such as `school`, `schooner`. + if (dutchSch.test(subvalue)) { + // Such as `schermerhorn`, `schenker`. if (subvalue === 'ER' || subvalue === 'EN') { - primary += 'X'; - secondary += 'SK'; + primary += 'X' + secondary += 'SK' } else { - primary += 'SK'; - secondary += 'SK'; + primary += 'SK' + secondary += 'SK' } - index += 3; + index += 3 - break; + break } if ( index === 0 && - !VOWELS.test(characters[3]) && + !vowels.test(characters[3]) && characters[3] !== 'W' ) { - primary += 'X'; - secondary += 'S'; + primary += 'X' + secondary += 'S' } else { - primary += 'X'; - secondary += 'X'; + primary += 'X' + secondary += 'X' } - index += 3; + index += 3 - break; + break } - if ( - nextnext === 'I' || - nextnext === 'E' || - nextnext === 'Y' - ) { - primary += 'S'; - secondary += 'S'; - index += 3; - break; + if (nextnext === 'I' || nextnext === 'E' || nextnext === 'Y') { + primary += 'S' + secondary += 'S' + index += 3 + break } - primary += 'SK'; - secondary += 'SK'; - index += 3; + primary += 'SK' + secondary += 'SK' + index += 3 - break; + break } - subvalue = value.slice(index - 2, index); + subvalue = value.slice(index - 2, index) - /* French such as `resnais`, `artois`. */ - if ( - index === last && - (subvalue === 'AI' || subvalue === 'OI') - ) { - secondary += 'S'; + // French such as `resnais`, `artois`. + if (index === last && (subvalue === 'AI' || subvalue === 'OI')) { + secondary += 'S' } else { - primary += 'S'; - secondary += 'S'; + primary += 'S' + secondary += 'S' } if ( next === 'S' - /* Bug: already taken care of by `German & - * Anglicization's` above: - * || next === 'Z' */ + // Bug: already taken care of by `German & Anglicization's` above: + // || next === 'Z' ) { - index++; + index++ } - index++; + index++ - break; + break case 'T': - if ( - next === 'I' && - nextnext === 'O' && - characters[index + 3] === 'N' - ) { - primary += 'X'; - secondary += 'X'; - index += 3; + if (next === 'I' && nextnext === 'O' && characters[index + 3] === 'N') { + primary += 'X' + secondary += 'X' + index += 3 - break; + break } - subvalue = value.slice(index + 1, index + 3); + subvalue = value.slice(index + 1, index + 3) if ( (next === 'I' && nextnext === 'A') || (next === 'C' && nextnext === 'H') ) { - primary += 'X'; - secondary += 'X'; - index += 3; + primary += 'X' + secondary += 'X' + index += 3 - break; + break } if (next === 'H' || (next === 'T' && nextnext === 'H')) { - /* Special case `Thomas`, `Thames` or Germanic. */ + // Special case `Thomas`, `Thames` or Germanic. if ( isGermanic || - ( - (nextnext === 'O' || nextnext === 'A') && - characters[index + 3] === 'M' - ) + ((nextnext === 'O' || nextnext === 'A') && + characters[index + 3] === 'M') ) { - primary += 'T'; - secondary += 'T'; + primary += 'T' + secondary += 'T' } else { - primary += '0'; - secondary += 'T'; + primary += '0' + secondary += 'T' } - index += 2; + index += 2 - break; + break } if (next === 'T' || next === 'D') { - index++; + index++ } - index++; - primary += 'T'; - secondary += 'T'; + index++ + primary += 'T' + secondary += 'T' - break; + break case 'V': if (next === 'V') { - index++; + index++ } - primary += 'F'; - secondary += 'F'; - index++; + primary += 'F' + secondary += 'F' + index++ - break; + break case 'W': - /* Can also be in middle of word (as already taken care of - * for initial). */ + // Can also be in middle of word (as already taken care of for initial). if (next === 'R') { - primary += 'R'; - secondary += 'R'; - index += 2; + primary += 'R' + secondary += 'R' + index += 2 - break; + break } if (index === 0) { - /* `Wasserman` should match `Vasserman`. */ - if (VOWELS.test(next)) { - primary += 'A'; - secondary += 'F'; + // `Wasserman` should match `Vasserman`. + if (vowels.test(next)) { + primary += 'A' + secondary += 'F' } else if (next === 'H') { - /* Need `Uomo` to match `Womo`. */ - primary += 'A'; - secondary += 'A'; + // Need `Uomo` to match `Womo`. + primary += 'A' + secondary += 'A' } } - /* `Arnow` should match `Arnoff`. */ + // `Arnow` should match `Arnoff`. if ( - ( - (prev === 'E' || prev === 'O') && + ((prev === 'E' || prev === 'O') && next === 'S' && nextnext === 'K' && - ( - characters[index + 3] === 'I' || - characters[index + 3] === 'Y' - ) - ) || - /* Maybe a bug? Shouldn't this be general Germanic? */ + (characters[index + 3] === 'I' || characters[index + 3] === 'Y')) || + // Maybe a bug? Shouldn't this be general Germanic? value.slice(0, 3) === 'SCH' || - (index === last && VOWELS.test(prev)) + (index === last && vowels.test(prev)) ) { - secondary += 'F'; - index++; + secondary += 'F' + index++ - break; + break } - /* Polish such as `Filipowicz`. */ + // Polish such as `Filipowicz`. if ( next === 'I' && (nextnext === 'C' || nextnext === 'T') && characters[index + 3] === 'Z' ) { - primary += 'TS'; - secondary += 'FX'; - index += 4; + primary += 'TS' + secondary += 'FX' + index += 4 - break; + break } - index++; + index++ - break; + break case 'X': - /* French such as `breaux`. */ + // French such as `breaux`. if ( !( index === last && - ( - /* Bug: IAU and EAU also match by AU - * (/IAU|EAU/.test(value.slice(index - 3, index))) || */ - ( - prev === 'U' && - (characters[index - 2] === 'A' || characters[index - 2] === 'O') - ) - ) + // Bug: IAU and EAU also match by AU + // (/IAU|EAU/.test(value.slice(index - 3, index))) || + (prev === 'U' && + (characters[index - 2] === 'A' || characters[index - 2] === 'O')) ) ) { - primary += 'KS'; - secondary += 'KS'; + primary += 'KS' + secondary += 'KS' } if (next === 'C' || next === 'X') { - index++; + index++ } - index++; + index++ - break; + break case 'Z': - /* Chinese pinyin such as `Zhao`. */ + // Chinese pinyin such as `Zhao`. if (next === 'H') { - primary += 'J'; - secondary += 'J'; - index += 2; + primary += 'J' + secondary += 'J' + index += 2 - break; + break } else if ( - ( - next === 'Z' && - (nextnext === 'A' || nextnext === 'I' || nextnext === 'O') - ) || + (next === 'Z' && + (nextnext === 'A' || nextnext === 'I' || nextnext === 'O')) || (isSlavoGermanic && index > 0 && prev !== 'T') ) { - primary += 'S'; - secondary += 'TS'; + primary += 'S' + secondary += 'TS' } else { - primary += 'S'; - secondary += 'S'; + primary += 'S' + secondary += 'S' } if (next === 'Z') { - index++; + index++ } - index++; + index++ - break; + break default: - index++; + index++ } } - return [primary, secondary]; + return [primary, secondary] } diff --git a/package.json b/package.json index 40652ff..6e6516b 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "browserify": "^16.0.0", "execa": "^1.0.0", "nyc": "^13.0.0", + "prettier": "^1.14.2", "remark-cli": "^5.0.0", "remark-preset-wooorm": "^4.0.0", "tape": "^4.4.0", @@ -36,14 +37,13 @@ "xo": "^0.22.0" }, "scripts": { - "build-md": "remark . -qfo", + "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", "build-bundle": "browserify . -s doubleMetaphone -o double-metaphone.js", "build-mangle": "browserify . -s doubleMetaphone -p tinyify -o double-metaphone.min.js", - "build": "npm run build-md && npm run build-bundle && npm run build-mangle", - "lint": "xo", + "build": "npm run build-bundle && npm run build-mangle", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test/index.js", - "test": "npm run build && npm run lint && npm run test-coverage" + "test": "npm run format && npm run build && npm run test-coverage" }, "nyc": { "check-coverage": true, @@ -51,8 +51,16 @@ "functions": 100, "branches": 100 }, + "prettier": { + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "bracketSpacing": false, + "semi": false, + "trailingComma": "none" + }, "xo": { - "space": true, + "prettier": true, "esnext": false, "rules": { "complexity": "off" diff --git a/readme.md b/readme.md index b53bbf7..7c4f0ec 100644 --- a/readme.md +++ b/readme.md @@ -13,25 +13,25 @@ npm install double-metaphone Use: ```js -var doubleMetaphone = require('double-metaphone'); - -doubleMetaphone('michael'); //=> ['MKL', 'MXL'] -doubleMetaphone('crevalle'); //=> ['KRFL', 'KRF'] -doubleMetaphone('Filipowitz'); //=> ['FLPTS', 'FLPFX'] -doubleMetaphone('Xavier'); //=> ['SF', 'SFR'] -doubleMetaphone('delicious'); //=> ['TLSS', 'TLXS'] -doubleMetaphone('acceptingness'); //=> ['AKSPTNNS', 'AKSPTNKNS'] -doubleMetaphone('allegrettos'); //=> ['ALKRTS', 'AKRTS'] +var doubleMetaphone = require('double-metaphone') + +doubleMetaphone('michael') // => ['MKL', 'MXL'] +doubleMetaphone('crevalle') // => ['KRFL', 'KRF'] +doubleMetaphone('Filipowitz') // => ['FLPTS', 'FLPFX'] +doubleMetaphone('Xavier') // => ['SF', 'SFR'] +doubleMetaphone('delicious') // => ['TLSS', 'TLXS'] +doubleMetaphone('acceptingness') // => ['AKSPTNNS', 'AKSPTNKNS'] +doubleMetaphone('allegrettos') // => ['ALKRTS', 'AKRTS'] ``` With [stemmer][]: ```js -var doubleMetaphone = require('double-metaphone'); -var stemmer = require('stemmer'); +var doubleMetaphone = require('double-metaphone') +var stemmer = require('stemmer') -doubleMetaphone(stemmer('acceptingness')); //=> [ 'AKSPTNK', 'AKSPTNK' ] -doubleMetaphone(stemmer('allegrettos')); //=> [ 'ALKRT', 'AKRT' ] +doubleMetaphone(stemmer('acceptingness')) // => [ 'AKSPTNK', 'AKSPTNK' ] +doubleMetaphone(stemmer('allegrettos')) // => [ 'ALKRT', 'AKRT' ] ``` ## CLI diff --git a/test/api.js b/test/api.js index 70e7027..c0be9cd 100644 --- a/test/api.js +++ b/test/api.js @@ -1,594 +1,766 @@ -'use strict'; - -var assert = require('assert'); -var test = require('tape'); -var m = require('..'); - -test('api', function (t) { - t.equal(typeof m, 'function', 'should be a `function`'); - - t.test('compatibility w/ natural', function (st) { - st.deepEqual(m('ptah'), ['PT', 'PT']); - st.deepEqual(m('ceasar'), ['SSR', 'SSR']); - st.deepEqual(m('ach'), ['AK', 'AK']); - st.deepEqual(m('chemical'), ['KMKL', 'KMKL']); - st.deepEqual(m('choral'), ['KRL', 'KRL']); - - st.end(); - }); - - t.deepEqual(m('alexander'), m('aleksander'), 'GH-2'); - - t.deepEqual(m('HICCUPS'), m('HiCcUpS'), 'should ignore casing (1)'); - t.deepEqual(m('HiCcUpS'), m('hiccups'), 'should ignore casing (2)'); - - t.equal(m('gnarl')[0].charAt(0), 'N', 'should drop the initial G when followed by N'); - t.equal(m('knack')[0].charAt(0), 'N', 'should drop the initial K when followed by N'); - t.equal(m('pneumatic')[0].charAt(0), 'N', 'should drop the initial P when followed by N'); - t.equal(m('wrack')[0].charAt(0), 'R', 'should drop the initial W when followed by R'); - t.equal(m('psycho')[0].charAt(0), 'S', 'should drop the initial P when followed by S'); - t.equal(m('Xavier')[0].charAt(0), 'S', 'should transform the initial X to S'); - - t.doesNotThrow( - function () { - 'aeiouy'.split('').forEach(function (vowel) { - assert.strictEqual(m(vowel)[0], 'A'); - }); - }, - 'should transform all initial vowels to A' - ); - - t.doesNotThrow( - function () { - 'aeiouy'.split('').forEach(function (vowel) { - assert.strictEqual(m('b' + vowel)[0].length, 1); - }); - }, - 'should drop all non-initial vowels' - ); - - t.equal(m('b')[0].charAt(0), 'P', 'should transform B to P (1)'); - t.equal(m('bb')[0].charAt(0), 'P', 'should transform B to P (2)'); - - t.equal(m('Ç')[0].charAt(0), 'S', 'should transform Ç to S'); +'use strict' + +var assert = require('assert') +var test = require('tape') +var m = require('..') + +test('api', function(t) { + t.equal(typeof m, 'function', 'should be a `function`') + + t.test('compatibility w/ natural', function(st) { + st.deepEqual(m('ptah'), ['PT', 'PT']) + st.deepEqual(m('ceasar'), ['SSR', 'SSR']) + st.deepEqual(m('ach'), ['AK', 'AK']) + st.deepEqual(m('chemical'), ['KMKL', 'KMKL']) + st.deepEqual(m('choral'), ['KRL', 'KRL']) + + st.end() + }) + + t.deepEqual(m('alexander'), m('aleksander'), 'GH-2') + + t.deepEqual(m('HICCUPS'), m('HiCcUpS'), 'should ignore casing (1)') + t.deepEqual(m('HiCcUpS'), m('hiccups'), 'should ignore casing (2)') + + t.equal( + m('gnarl')[0].charAt(0), + 'N', + 'should drop the initial G when followed by N' + ) + t.equal( + m('knack')[0].charAt(0), + 'N', + 'should drop the initial K when followed by N' + ) + t.equal( + m('pneumatic')[0].charAt(0), + 'N', + 'should drop the initial P when followed by N' + ) + t.equal( + m('wrack')[0].charAt(0), + 'R', + 'should drop the initial W when followed by R' + ) + t.equal( + m('psycho')[0].charAt(0), + 'S', + 'should drop the initial P when followed by S' + ) + t.equal(m('Xavier')[0].charAt(0), 'S', 'should transform the initial X to S') + + t.doesNotThrow(function() { + 'aeiouy'.split('').forEach(function(vowel) { + assert.strictEqual(m(vowel)[0], 'A') + }) + }, 'should transform all initial vowels to A') + + t.doesNotThrow(function() { + 'aeiouy'.split('').forEach(function(vowel) { + assert.strictEqual(m('b' + vowel)[0].length, 1) + }) + }, 'should drop all non-initial vowels') + + t.equal(m('b')[0].charAt(0), 'P', 'should transform B to P (1)') + t.equal(m('bb')[0].charAt(0), 'P', 'should transform B to P (2)') + + t.equal(m('Ç')[0].charAt(0), 'S', 'should transform Ç to S') t.test( - 'should transform C to K, when preceded by A (not preceded by a ' + - 'vowel), followed by H (in turn not followed by I and E, unless ' + - 'the E is in a sequence of BACHER or MACHER)', - function (st) { - st.equal(m('ACH')[0].charAt(1), 'K'); - st.notEqual(m('AACH')[0].charAt(2), 'K'); - st.notEqual(m('ACHI')[0].charAt(1), 'K'); - st.equal(m('ACHB')[0].charAt(1), 'K'); - st.equal(m('MACHER')[1].charAt(1), 'K'); - st.equal(m('BACHER')[1].charAt(1), 'K'); - st.end(); + 'should transform C to K, when preceded by A (not preceded by a vowel), followed by H (in turn not followed by I and E, unless the E is in a sequence of BACHER or MACHER)', + function(st) { + st.equal(m('ACH')[0].charAt(1), 'K') + st.notEqual(m('AACH')[0].charAt(2), 'K') + st.notEqual(m('ACHI')[0].charAt(1), 'K') + st.equal(m('ACHB')[0].charAt(1), 'K') + st.equal(m('MACHER')[1].charAt(1), 'K') + st.equal(m('BACHER')[1].charAt(1), 'K') + st.end() } - ); - - t.equal(m('CAESAR')[0].charAt(0), 'S', 'should transform the C to S, when in an initial CAESAR'); - t.equal(m('chianti')[0].charAt(0), 'K', 'should transform the C to K, when in CHIA'); - t.equal(m('michael')[0].charAt(1), 'K', 'should transform the C to K and X, when in CHAE (1)'); - t.equal(m('michael')[1].charAt(1), 'X', 'should transform the C to K and X, when in CHAE (2)'); - t.equal(m('chiastic')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHIA'); - t.equal(m('chemical')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHEM'); - t.equal(m('choral')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHOR'); - t.equal(m('chyme')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHYM'); - t.equal(m('character')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHARAC'); - t.equal(m('charisma')[0].charAt(0), 'K', 'should transform the C to K, when in an initial CHARIS'); - t.equal(m('von ch')[0].charAt(2), 'K', 'should transform the C to K, when followed by H, and the given value starts with `von `'); + ) + + t.equal( + m('CAESAR')[0].charAt(0), + 'S', + 'should transform the C to S, when in an initial CAESAR' + ) + t.equal( + m('chianti')[0].charAt(0), + 'K', + 'should transform the C to K, when in CHIA' + ) + t.equal( + m('michael')[0].charAt(1), + 'K', + 'should transform the C to K and X, when in CHAE (1)' + ) + t.equal( + m('michael')[1].charAt(1), + 'X', + 'should transform the C to K and X, when in CHAE (2)' + ) + t.equal( + m('chiastic')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHIA' + ) + t.equal( + m('chemical')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHEM' + ) + t.equal( + m('choral')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHOR' + ) + t.equal( + m('chyme')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHYM' + ) + t.equal( + m('character')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHARAC' + ) + t.equal( + m('charisma')[0].charAt(0), + 'K', + 'should transform the C to K, when in an initial CHARIS' + ) + t.equal( + m('von ch')[0].charAt(2), + 'K', + 'should transform the C to K, when followed by H, and the given value starts with `von `' + ) /* This might be a bug, not sure. Now other C's will transform to * K in a string sarting with `sch`. */ - t.equal(m('schooner')[0].charAt(1), 'K', 'should transform the C to K, when followed by H, and the given value starts with SCH'); + t.equal( + m('schooner')[0].charAt(1), + 'K', + 'should transform the C to K, when followed by H, and the given value starts with SCH' + ) - t.equal(m('orchestra')[0].charAt(2), 'K', 'should transform the C to K, when in ORCHES'); - t.equal(m('architect')[0].charAt(2), 'K', 'should transform the C to K, when in ARCHIT'); - t.notEqual(m('arch')[0].charAt(2), 'K', 'should NOT transform the C to K, when in ARCH'); - t.equal(m('orchid')[0].charAt(2), 'K', 'should transform the C to K, when in ORCHID'); - t.equal(m('chthonic')[0].charAt(0), 'K', 'should transform the C to K, when followed by HT'); - t.equal(m('fuchsia')[0].charAt(1), 'K', 'should transform the C to K, when followed by HS'); + t.equal( + m('orchestra')[0].charAt(2), + 'K', + 'should transform the C to K, when in ORCHES' + ) + t.equal( + m('architect')[0].charAt(2), + 'K', + 'should transform the C to K, when in ARCHIT' + ) + t.notEqual( + m('arch')[0].charAt(2), + 'K', + 'should NOT transform the C to K, when in ARCH' + ) + t.equal( + m('orchid')[0].charAt(2), + 'K', + 'should transform the C to K, when in ORCHID' + ) + t.equal( + m('chthonic')[0].charAt(0), + 'K', + 'should transform the C to K, when followed by HT' + ) + t.equal( + m('fuchsia')[0].charAt(1), + 'K', + 'should transform the C to K, when followed by HS' + ) - t.equal(m('chloride')[0].charAt(0), 'K', 'should transform the C to K, when an initial, and followed by H and either ` `, B, F, H, L, M, N, R, V, or W (1)'); - t.equal(m('chroma')[0].charAt(0), 'K', 'should transform the C to K, when an initial, and followed by H and either ` `, B, F, H, L, M, N, R, V, or W (2)'); - t.equal(m('tichner')[1].charAt(1), 'K', 'should transform the C to K, when preceded by A, E, O, or U, followed by H and either " ", B, F, H, L, M, N, R, V, or W'); + t.equal( + m('chloride')[0].charAt(0), + 'K', + 'should transform the C to K, when an initial, and followed by H and either ` `, B, F, H, L, M, N, R, V, or W (1)' + ) + t.equal( + m('chroma')[0].charAt(0), + 'K', + 'should transform the C to K, when an initial, and followed by H and either ` `, B, F, H, L, M, N, R, V, or W (2)' + ) + t.equal( + m('tichner')[1].charAt(1), + 'K', + 'should transform the C to K, when preceded by A, E, O, or U, followed by H and either " ", B, F, H, L, M, N, R, V, or W' + ) t.equal( m('tichner')[1].charAt(1), 'K', - 'should transform the C to K, when preceded by A, E, O, or U, ' + - 'followed by H and either " ", B, F, H, L, M, N, R, V, or W' - ); + 'should transform the C to K, when preceded by A, E, O, or U, followed by H and either " ", B, F, H, L, M, N, R, V, or W' + ) - t.equal(m('McHugh')[0].charAt(1), 'K', 'should transform the C in MCH to K'); - t.equal(m('chore')[0].charAt(0), 'X', 'should transform the C to X, when in an initial CH'); + t.equal(m('McHugh')[0].charAt(1), 'K', 'should transform the C in MCH to K') + t.equal( + m('chore')[0].charAt(0), + 'X', + 'should transform the C to X, when in an initial CH' + ) - t.test('should transform the C to X and K, when followed by H', function (st) { - var phonetics = m('achievement'); + t.test('should transform the C to X and K, when followed by H', function(st) { + var phonetics = m('achievement') - st.equal(phonetics[0].charAt(1), 'X'); - st.equal(phonetics[1].charAt(1), 'K'); + st.equal(phonetics[0].charAt(1), 'X') + st.equal(phonetics[1].charAt(1), 'K') - st.end(); - }); + st.end() + }) - t.test('should transform the C to S and X, when followed by Z and not preceded by WI', function (st) { - var phonetics = m('czerny'); + t.test( + 'should transform the C to S and X, when followed by Z and not preceded by WI', + function(st) { + var phonetics = m('czerny') - st.equal(phonetics[0].charAt(0), 'S'); - st.equal(phonetics[1].charAt(0), 'X'); + st.equal(phonetics[0].charAt(0), 'S') + st.equal(phonetics[1].charAt(0), 'X') - st.end(); - }); + st.end() + } + ) - t.equal(m('focaccia')[0].charAt(2), 'X', 'should transform the C to X, when followed by CIA'); + t.equal( + m('focaccia')[0].charAt(2), + 'X', + 'should transform the C to X, when followed by CIA' + ) - t.test('should transform the C to KS, when in an initial ACC, followed by either E, I, or H (but not HU)', function (st) { - var phonetics = m('accident'); + t.test( + 'should transform the C to KS, when in an initial ACC, followed by either E, I, or H (but not HU)', + function(st) { + var phonetics = m('accident') - st.equal(phonetics[0].charAt(1), 'K'); - st.equal(phonetics[0].charAt(2), 'S'); + st.equal(phonetics[0].charAt(1), 'K') + st.equal(phonetics[0].charAt(2), 'S') - phonetics = m('accede'); + phonetics = m('accede') - st.equal(phonetics[0].charAt(1), 'K'); - st.equal(phonetics[0].charAt(2), 'S'); + st.equal(phonetics[0].charAt(1), 'K') + st.equal(phonetics[0].charAt(2), 'S') - st.end(); - }); + st.end() + } + ) - t.test('should transform the C to KS, when in UCCEE or UCCES', function (st) { - var phonetics = m('succeed'); + t.test('should transform the C to KS, when in UCCEE or UCCES', function(st) { + var phonetics = m('succeed') - st.equal(phonetics[0].charAt(1), 'K'); - st.equal(phonetics[0].charAt(2), 'S'); + st.equal(phonetics[0].charAt(1), 'K') + st.equal(phonetics[0].charAt(2), 'S') - st.end(); - }); + st.end() + }) - t.test('should transform the C to X, when followed by C (but not in an initial MCC), either E, I, or H (but not HU)', function (st) { - st.equal(m('bacci')[0].charAt(1), 'X'); - st.equal(m('bertucci')[0].charAt(3), 'X'); + t.test( + 'should transform the C to X, when followed by C (but not in an initial MCC), either E, I, or H (but not HU)', + function(st) { + st.equal(m('bacci')[0].charAt(1), 'X') + st.equal(m('bertucci')[0].charAt(3), 'X') - st.end(); - }); + st.end() + } + ) - t.equal(m('hiccups')[0].charAt(1), 'K', 'should transform the C to K, when followed by C (but not in an initial MCC)'); - t.equal(m('knack')[0].charAt(1), 'K', 'should transform the C to K, when followed by either G, K, or Q'); + t.equal( + m('hiccups')[0].charAt(1), + 'K', + 'should transform the C to K, when followed by C (but not in an initial MCC)' + ) + t.equal( + m('knack')[0].charAt(1), + 'K', + 'should transform the C to K, when followed by either G, K, or Q' + ) - t.test('should transform the C to S and X, when followed by I and either E, or O', function (st) { - var phonetics = m('ancient'); + t.test( + 'should transform the C to S and X, when followed by I and either E, or O', + function(st) { + var phonetics = m('ancient') - st.equal(phonetics[0].charAt(2), 'S'); - st.equal(phonetics[1].charAt(2), 'X'); + st.equal(phonetics[0].charAt(2), 'S') + st.equal(phonetics[1].charAt(2), 'X') - phonetics = m('delicious'); + phonetics = m('delicious') - st.equal(phonetics[0].charAt(2), 'S'); - st.equal(phonetics[1].charAt(2), 'X'); + st.equal(phonetics[0].charAt(2), 'S') + st.equal(phonetics[1].charAt(2), 'X') - st.end(); - }); + st.end() + } + ) t.test( 'should transform the C to S, when followed by either I, E, or Y', - function (st) { - st.equal(m('acicula')[0].charAt(1), 'S'); - st.equal(m('abduce')[0].charAt(3), 'S'); - st.equal(m('acyl')[0].charAt(1), 'S'); + function(st) { + st.equal(m('acicula')[0].charAt(1), 'S') + st.equal(m('abduce')[0].charAt(3), 'S') + st.equal(m('acyl')[0].charAt(1), 'S') - st.end(); + st.end() } - ); - - t.equal(m('Mac Caffrey')[0].charAt(1), 'K', 'should transform "C C" to K'); - t.equal(m('Mac Gregor')[0].charAt(1), 'K', 'should transform "C G" to K'); - t.equal(m('Mac Quillan')[0].charAt(1), 'K', 'should transform "C G" to K'); - t.equal(m('aback')[0].charAt(2), 'K', 'should transform CK to K'); - t.equal(m('acquit')[0].charAt(1), 'K', 'should transform CQ to K'); - t.equal(m('acclimate')[0].charAt(1), 'K', 'should transform CC to K, when not followed by E or I'); - t.equal(m('edge')[0].charAt(1), 'J', 'should transform DGE to J'); - t.equal(m('pidgin')[0].charAt(1), 'J', 'should transform DGI to J'); - t.equal(m('edgy')[0].charAt(1), 'J', 'should transform DGY to J'); - t.equal(m('Edgar')[0].slice(1, 3), 'TK', 'should transform DG to TK'); - t.equal(m('width')[0].charAt(1), 'T', 'should transform DT to T'); - t.equal(m('add')[0].charAt(1), 'T', 'should transform DD to T'); - t.equal(m('Abduce')[0].charAt(2), 'T', 'should transform D to T'); - t.equal(m('affect')[0].charAt(1), 'F', 'should transform FF to F'); - t.equal(m('abaft')[0].charAt(2), 'F', 'should transform F to F'); - t.equal(m('aargh')[0].charAt(2), 'K', 'should transform GH to K when preceded by a consonant'); - t.equal(m('ghislane')[0].charAt(0), 'J', 'should transform initial GHI to J'); - t.equal(m('ghoul')[0].charAt(0), 'K', 'should transform initial GH to K'); - t.equal(m('hugh')[0], 'H', 'should drop GH in B.GH, H.GH, or D.GH'); - t.equal(m('bough')[0], 'P', 'should drop GH in B..GH, H..GH, or D..GH'); - t.equal(m('broughton')[0], 'PRTN', 'should drop GH in B...GH or H...GH'); - t.equal(m('laugh')[0], 'LF', 'should transform GH to F in C.UGH, G.UGH, L.UGH, R.UGH, T.UGH'); - t.equal(m('curagh')[0], 'KRK', 'should transform GH to K, when preceded by anything other than I'); - t.equal(m('weight')[0], 'AT', 'should drop GH'); + ) + + t.equal(m('Mac Caffrey')[0].charAt(1), 'K', 'should transform "C C" to K') + t.equal(m('Mac Gregor')[0].charAt(1), 'K', 'should transform "C G" to K') + t.equal(m('Mac Quillan')[0].charAt(1), 'K', 'should transform "C G" to K') + t.equal(m('aback')[0].charAt(2), 'K', 'should transform CK to K') + t.equal(m('acquit')[0].charAt(1), 'K', 'should transform CQ to K') + t.equal( + m('acclimate')[0].charAt(1), + 'K', + 'should transform CC to K, when not followed by E or I' + ) + t.equal(m('edge')[0].charAt(1), 'J', 'should transform DGE to J') + t.equal(m('pidgin')[0].charAt(1), 'J', 'should transform DGI to J') + t.equal(m('edgy')[0].charAt(1), 'J', 'should transform DGY to J') + t.equal(m('Edgar')[0].slice(1, 3), 'TK', 'should transform DG to TK') + t.equal(m('width')[0].charAt(1), 'T', 'should transform DT to T') + t.equal(m('add')[0].charAt(1), 'T', 'should transform DD to T') + t.equal(m('Abduce')[0].charAt(2), 'T', 'should transform D to T') + t.equal(m('affect')[0].charAt(1), 'F', 'should transform FF to F') + t.equal(m('abaft')[0].charAt(2), 'F', 'should transform F to F') + t.equal( + m('aargh')[0].charAt(2), + 'K', + 'should transform GH to K when preceded by a consonant' + ) + t.equal(m('ghislane')[0].charAt(0), 'J', 'should transform initial GHI to J') + t.equal(m('ghoul')[0].charAt(0), 'K', 'should transform initial GH to K') + t.equal(m('hugh')[0], 'H', 'should drop GH in B.GH, H.GH, or D.GH') + t.equal(m('bough')[0], 'P', 'should drop GH in B..GH, H..GH, or D..GH') + t.equal(m('broughton')[0], 'PRTN', 'should drop GH in B...GH or H...GH') + t.equal( + m('laugh')[0], + 'LF', + 'should transform GH to F in C.UGH, G.UGH, L.UGH, R.UGH, T.UGH' + ) + t.equal( + m('curagh')[0], + 'KRK', + 'should transform GH to K, when preceded by anything other than I' + ) + t.equal(m('weight')[0], 'AT', 'should drop GH') t.test( - 'should transform GN to KN and N, when preceded by a vowel and ^, ' + - 'and not Slavo-Germanic', - function (st) { - var phonetics = m('agnize'); + 'should transform GN to KN and N, when preceded by a vowel and ^, and not Slavo-Germanic', + function(st) { + var phonetics = m('agnize') - st.equal(phonetics[0].slice(0, 3), 'AKN'); - st.equal(phonetics[1].slice(0, 2), 'AN'); + st.equal(phonetics[0].slice(0, 3), 'AKN') + st.equal(phonetics[1].slice(0, 2), 'AN') - st.end(); + st.end() } - ); + ) t.deepEqual( m('tagliaro'), ['TKLR', 'TLR'], 'should transform GLI to KL and L' - ); + ) t.test( - 'should transform GN to N and KN, when not followed by EY and Y, ' + - 'and not Slavo-Germanic', - function (st) { - var phonetics = m('acceptingness'); + 'should transform GN to N and KN, when not followed by EY and Y, and not Slavo-Germanic', + function(st) { + var phonetics = m('acceptingness') - st.equal(phonetics[0].slice(-3), 'NNS'); - st.equal(phonetics[1].slice(-4), 'NKNS'); + st.equal(phonetics[0].slice(-3), 'NNS') + st.equal(phonetics[1].slice(-4), 'NKNS') - st.end(); + st.end() } - ); + ) - t.equal(m('cagney')[0], 'KKN', 'should transform GN to KN'); + t.equal(m('cagney')[0], 'KKN', 'should transform GN to KN') t.test( - 'should transform an initial GY., GES, GEP, GEB, GEL, GEY, GIB, ' + - 'GIL, GIN, GIE, GEI, and GER to K and J', - function (st) { - var phonetics = m('Gerben'); + 'should transform an initial GY., GES, GEP, GEB, GEL, GEY, GIB, GIL, GIN, GIE, GEI, and GER to K and J', + function(st) { + var phonetics = m('Gerben') - st.equal(phonetics[0].charAt(0), 'K'); - st.equal(phonetics[1].charAt(0), 'J'); + st.equal(phonetics[0].charAt(0), 'K') + st.equal(phonetics[1].charAt(0), 'J') - st.end(); + st.end() } - ); + ) t.test( - 'should transform GER to K and J, when not in DANGER, RANGER, and ' + - 'MANGER, and not preceded by E and I', - function (st) { - var phonetics = m('auger'); + 'should transform GER to K and J, when not in DANGER, RANGER, and MANGER, and not preceded by E and I', + function(st) { + var phonetics = m('auger') - st.equal(phonetics[0].charAt(1), 'K'); - st.equal(phonetics[1].charAt(1), 'J'); + st.equal(phonetics[0].charAt(1), 'K') + st.equal(phonetics[1].charAt(1), 'J') - st.end(); + st.end() } - ); + ) t.test( - 'should transform GY to K and J, when not preceded by E, I, R, ' + - 'and O', - function (st) { - var phonetics = m('bulgy'); + 'should transform GY to K and J, when not preceded by E, I, R, and O', + function(st) { + var phonetics = m('bulgy') - st.equal(phonetics[0].charAt(2), 'K'); - st.equal(phonetics[1].charAt(2), 'J'); + st.equal(phonetics[0].charAt(2), 'K') + st.equal(phonetics[1].charAt(2), 'J') - st.end(); + st.end() } - ); + ) - t.equal(m('altogether')[0].charAt(3), 'K', 'should transform the G in GET to K'); - t.equal(m('Van Agema')[0].charAt(2), 'K', 'should transform G to K, when Germanic and followed by E, I, or Y'); - t.equal(m('Von Goggin')[0].charAt(3), 'K', 'should transform G to K, when Germanic, preceded by A or O, and followed by GI'); - t.equal(m('tangier')[0].charAt(2), 'J', 'should transform G to J, when followed by "IER "'); + t.equal( + m('altogether')[0].charAt(3), + 'K', + 'should transform the G in GET to K' + ) + t.equal( + m('Van Agema')[0].charAt(2), + 'K', + 'should transform G to K, when Germanic and followed by E, I, or Y' + ) + t.equal( + m('Von Goggin')[0].charAt(3), + 'K', + 'should transform G to K, when Germanic, preceded by A or O, and followed by GI' + ) + t.equal( + m('tangier')[0].charAt(2), + 'J', + 'should transform G to J, when followed by "IER "' + ) t.test( - 'should transform G to J and K, when followed by E, I, or Y, or ' + - 'preceded by A or O and followed by GI', - function (st) { - var phonetics = m('biaggi'); + 'should transform G to J and K, when followed by E, I, or Y, or preceded by A or O and followed by GI', + function(st) { + var phonetics = m('biaggi') - st.equal(phonetics[0].charAt(1), 'J'); - st.equal(phonetics[1].charAt(1), 'K'); + st.equal(phonetics[0].charAt(1), 'J') + st.equal(phonetics[1].charAt(1), 'K') - st.end(); + st.end() } - ); + ) - t.equal(m('GG')[0], 'K', 'should transform GG to K'); - t.equal(m('G')[0], 'K', 'should transform G to K'); - t.equal(m('ha')[0], 'H', 'should keep H when initial and followed by a vowel'); - t.equal(m('aha')[0], 'AH', 'should keep H when both followed and preceded by a vowel'); - t.equal(m('h')[0], '', 'should drop H'); - t.equal(m('San Jacinto')[0].charAt(2), 'H', 'should transform J to H when obviously spanish (an initial "SAN ")'); - t.equal(m('Jose')[0].charAt(0), 'H', 'should transform J to H in an initial "J... "'); + t.equal(m('GG')[0], 'K', 'should transform GG to K') + t.equal(m('G')[0], 'K', 'should transform G to K') + t.equal(m('ha')[0], 'H', 'should keep H when initial and followed by a vowel') + t.equal( + m('aha')[0], + 'AH', + 'should keep H when both followed and preceded by a vowel' + ) + t.equal(m('h')[0], '', 'should drop H') + t.equal( + m('San Jacinto')[0].charAt(2), + 'H', + 'should transform J to H when obviously spanish (an initial "SAN ")' + ) + t.equal( + m('Jose')[0].charAt(0), + 'H', + 'should transform J to H in an initial "J... "' + ) - t.test( - 'should transform the J to J and H, when in JOSE', - function (st) { - var phonetics = m('Joseph'); + t.test('should transform the J to J and H, when in JOSE', function(st) { + var phonetics = m('Joseph') - st.equal(phonetics[0].charAt(0), 'J'); - st.equal(phonetics[1].charAt(0), 'H'); + st.equal(phonetics[0].charAt(0), 'J') + st.equal(phonetics[1].charAt(0), 'H') - st.end(); - } - ); + st.end() + }) - t.test( - 'should transform the J to J and H, when in JOSE', - function (st) { - var phonetics = m('Jankelowicz'); + t.test('should transform the J to J and H, when in JOSE', function(st) { + var phonetics = m('Jankelowicz') - st.equal(phonetics[0].charAt(0), 'J'); - st.equal(phonetics[1].charAt(0), 'A'); + st.equal(phonetics[0].charAt(0), 'J') + st.equal(phonetics[1].charAt(0), 'A') - st.end(); - } - ); + st.end() + }) t.test( - 'should transform J to J and H, when preceded by a vowel, followed ' + - 'by A or O, and not Slavo-Germanic', - function (st) { - var phonetics = m('bajador'); + 'should transform J to J and H, when preceded by a vowel, followed by A or O, and not Slavo-Germanic', + function(st) { + var phonetics = m('bajador') - st.equal(phonetics[0].charAt(1), 'J'); - st.equal(phonetics[1].charAt(1), 'H'); + st.equal(phonetics[0].charAt(1), 'J') + st.equal(phonetics[1].charAt(1), 'H') - st.end(); + st.end() } - ); + ) - t.test( - 'should both keep and drop a final J', - function (st) { - var phonetics = m('svaraj'); + t.test('should both keep and drop a final J', function(st) { + var phonetics = m('svaraj') - st.equal(phonetics[0], 'SFRJ'); - st.equal(phonetics[1], 'SFR'); + st.equal(phonetics[0], 'SFRJ') + st.equal(phonetics[1], 'SFR') - st.end(); - } - ); + st.end() + }) - t.equal(m('abject')[0].charAt(2), 'J', 'should keep J when not preceded by S, K, and L, and not followed by L, T, K, S, N, M, B, and Z'); - t.equal(m('sjji')[0].charAt(0), 'S', 'should drop JJ'); - t.equal(m('disject')[0], 'TSKT', 'should drop J'); - t.equal(m('trekker')[0], 'TRKR', 'should transform KK to K'); - t.equal(m('like')[0], 'LK', 'should keep K'); + t.equal( + m('abject')[0].charAt(2), + 'J', + 'should keep J when not preceded by S, K, and L, and not followed by L, T, K, S, N, M, B, and Z' + ) + t.equal(m('sjji')[0].charAt(0), 'S', 'should drop JJ') + t.equal(m('disject')[0], 'TSKT', 'should drop J') + t.equal(m('trekker')[0], 'TRKR', 'should transform KK to K') + t.equal(m('like')[0], 'LK', 'should keep K') t.test( - 'should both transform LL to L, and drop it, when in a final ' + - 'ILLO, ILLA and ALLE', - function (st) { - st.deepEqual(m('cabrillo'), ['KPRL', 'KPR']); - st.deepEqual(m('villa'), ['FL', 'F']); - st.deepEqual(m('crevalle'), ['KRFL', 'KRF']); - - st.end(); + 'should both transform LL to L, and drop it, when in a final ILLO, ILLA and ALLE', + function(st) { + st.deepEqual(m('cabrillo'), ['KPRL', 'KPR']) + st.deepEqual(m('villa'), ['FL', 'F']) + st.deepEqual(m('crevalle'), ['KRFL', 'KRF']) + + st.end() } - ); + ) t.test( - 'should both transform the LL to L, and drop it, in ALLE, ' + - 'when the given value ends in A, O, AS, or OS', - function (st) { - st.deepEqual(m('allegretto'), ['ALKRT', 'AKRT']); - st.deepEqual(m('allegros'), ['ALKRS', 'AKRS']); - st.end(); + 'should both transform the LL to L, and drop it, in ALLE, when the given value ends in A, O, AS, or OS', + function(st) { + st.deepEqual(m('allegretto'), ['ALKRT', 'AKRT']) + st.deepEqual(m('allegros'), ['ALKRS', 'AKRS']) + st.end() } - ); - - t.equal(m('ll')[0], 'L', 'should transform LL to L'); - t.equal(m('l')[0], 'L', 'should keep L'); - t.equal(m('thumb')[0], '0M', 'should transform a final UMB to M'); - t.equal(m('dumber')[0], 'TMR', 'should transform UMB to M when followed by ER'); - t.equal(m('mm')[0], 'M', 'should transform MM to M'); - t.equal(m('m')[0], 'M', 'should keep M'); - t.equal(m('nn')[0], 'N', 'should transform NN to N'); - t.equal(m('n')[0], 'N', 'should keep N'); - t.equal(m('Ñ')[0], 'N', 'should transform Ñ to N'); - t.equal(m('ph')[0], 'F', 'should transform PH to F'); - t.equal(m('pb')[0], 'P', 'should transform PB to P'); - t.equal(m('pp')[0], 'P', 'should transform PP to P'); - t.equal(m('p')[0], 'P', 'should keep P'); - t.equal(m('qq')[0], 'K', 'should transform QQ to K'); - t.equal(m('q')[0], 'K', 'should transform Q to K'); + ) + + t.equal(m('ll')[0], 'L', 'should transform LL to L') + t.equal(m('l')[0], 'L', 'should keep L') + t.equal(m('thumb')[0], '0M', 'should transform a final UMB to M') + t.equal( + m('dumber')[0], + 'TMR', + 'should transform UMB to M when followed by ER' + ) + t.equal(m('mm')[0], 'M', 'should transform MM to M') + t.equal(m('m')[0], 'M', 'should keep M') + t.equal(m('nn')[0], 'N', 'should transform NN to N') + t.equal(m('n')[0], 'N', 'should keep N') + t.equal(m('Ñ')[0], 'N', 'should transform Ñ to N') + t.equal(m('ph')[0], 'F', 'should transform PH to F') + t.equal(m('pb')[0], 'P', 'should transform PB to P') + t.equal(m('pp')[0], 'P', 'should transform PP to P') + t.equal(m('p')[0], 'P', 'should keep P') + t.equal(m('qq')[0], 'K', 'should transform QQ to K') + t.equal(m('q')[0], 'K', 'should transform Q to K') t.deepEqual( m('Xavier'), ['SF', 'SFR'], - 'should both drop and keep a final R when preceded by IE, in ' + - 'turn not preceded by ME and MA' - ); + 'should both drop and keep a final R when preceded by IE, in turn not preceded by ME and MA' + ) - t.equal(m('rr')[0], 'R', 'should transform RR to R'); - t.equal(m('r')[0], 'R', 'should keep R'); - t.equal(m('island')[0], 'ALNT', 'should drop S when preceded by I or Y and followed by L'); - t.equal(m('island')[0], 'ALNT', 'should drop S when preceded by I or Y and followed by L'); + t.equal(m('rr')[0], 'R', 'should transform RR to R') + t.equal(m('r')[0], 'R', 'should keep R') + t.equal( + m('island')[0], + 'ALNT', + 'should drop S when preceded by I or Y and followed by L' + ) + t.equal( + m('island')[0], + 'ALNT', + 'should drop S when preceded by I or Y and followed by L' + ) - t.test( - 'should transform the S to X and S in an initial SUGAR', - function (st) { - var phonetics = m('sugar'); + t.test('should transform the S to X and S in an initial SUGAR', function(st) { + var phonetics = m('sugar') - st.equal(phonetics[0].charAt(0), 'X'); - st.equal(phonetics[1].charAt(0), 'S'); + st.equal(phonetics[0].charAt(0), 'X') + st.equal(phonetics[1].charAt(0), 'S') - st.end(); - } - ); + st.end() + }) - t.equal(m('Sholz')[0].charAt(0), 'S', 'should transform the SH to S in SHEIM, SHOEK, SHOLM, SHOLZ'); - t.equal(m('sh')[0].charAt(0), 'X', 'should transform the SH to X'); + t.equal( + m('Sholz')[0].charAt(0), + 'S', + 'should transform the SH to S in SHEIM, SHOEK, SHOLM, SHOLZ' + ) + t.equal(m('sh')[0].charAt(0), 'X', 'should transform the SH to X') t.deepEqual( m('sio'), ['S', 'X'], 'should transform SIO and SIA to S and X, when not Slavo-Germanic' - ); + ) t.deepEqual( m('sioricz'), ['SRS', 'SRX'], 'should transform SIO and SIA to S, when Slavo-Germanic' - ); + ) - t.deepEqual( - m('sz'), - ['S', 'X'], - 'should transform SZ to X and S' - ); + t.deepEqual(m('sz'), ['S', 'X'], 'should transform SZ to X and S') t.deepEqual( m('sl'), ['SL', 'XL'], 'should transform S to X and S when followed by L, M, N, or W' - ); + ) t.deepEqual( m('schenker'), ['XNKR', 'SKNKR'], 'should transform SCH to X and SK when followed by ER or EN' - ); + ) t.deepEqual( m('schooner'), ['SKNR', 'SKNR'], 'should transform SCH to SK when followed by OO, UY, ED, or EM' - ); + ) t.deepEqual( m('schlepp'), ['XLP', 'SLP'], - 'should transform SCH to X and S, when initial, and not followed ' + - 'by a non-vowel and W' - ); + 'should transform SCH to X and S, when initial, and not followed by a non-vowel and W' + ) - t.equal(m('borscht')[0], 'PRXT', 'should transform SCH to X'); - t.equal(m('sci')[0], 'S', 'should transform SCI, SCE, and SCY to S'); - t.equal(m('scu')[0], 'SK', 'should transform SC. to SK'); + t.equal(m('borscht')[0], 'PRXT', 'should transform SCH to X') + t.equal(m('sci')[0], 'S', 'should transform SCI, SCE, and SCY to S') + t.equal(m('scu')[0], 'SK', 'should transform SC. to SK') t.deepEqual( m('ois'), ['A', 'AS'], 'should drop and keep S, when final and preceded by AI or OI' - ); - - t.equal(m('ss')[0], 'S', 'should transform SS to S'); - t.equal(m('s')[0], 'S', 'should keep S'); - t.equal(m('tion')[0], 'XN', 'should transform TIO to X, when followed by N'); - t.equal(m('tia')[0], 'X', 'should transform TIA and TCH to X'); - t.equal(m('tch')[0], 'X', 'should transform TIA and TCH to X'); - t.equal(m('thom')[0], 'TM', 'should transform TH to T, when followed by OM or AM (1)'); - t.equal(m('tham')[0], 'TM', 'should transform TH to T, when followed by OM or AM (2)'); - t.equal(m('Von Goethals')[0].charAt(3), 'T', 'should transform TH to T, when Germanic'); - t.equal(m('Von Matthes')[0].charAt(3), 'T', 'should transform TT to T, when Germanic and followed by H'); + ) - t.deepEqual( - m('th'), - ['0', 'T'], - 'should transform TH to 0 and T' - ); - - t.equal(m('tt')[0], 'T', 'should transform TT to T'); - t.equal(m('td')[0], 'T', 'should transform TD to T'); - t.equal(m('t')[0], 'T', 'should keep T'); - t.equal(m('vv')[0], 'F', 'should transform VV to F'); - t.equal(m('v')[0], 'F', 'should transform V to F'); - t.equal(m('awr')[0], 'AR', 'should transform WR to R'); + t.equal(m('ss')[0], 'S', 'should transform SS to S') + t.equal(m('s')[0], 'S', 'should keep S') + t.equal(m('tion')[0], 'XN', 'should transform TIO to X, when followed by N') + t.equal(m('tia')[0], 'X', 'should transform TIA and TCH to X') + t.equal(m('tch')[0], 'X', 'should transform TIA and TCH to X') + t.equal( + m('thom')[0], + 'TM', + 'should transform TH to T, when followed by OM or AM (1)' + ) + t.equal( + m('tham')[0], + 'TM', + 'should transform TH to T, when followed by OM or AM (2)' + ) + t.equal( + m('Von Goethals')[0].charAt(3), + 'T', + 'should transform TH to T, when Germanic' + ) + t.equal( + m('Von Matthes')[0].charAt(3), + 'T', + 'should transform TT to T, when Germanic and followed by H' + ) + + t.deepEqual(m('th'), ['0', 'T'], 'should transform TH to 0 and T') + + t.equal(m('tt')[0], 'T', 'should transform TT to T') + t.equal(m('td')[0], 'T', 'should transform TD to T') + t.equal(m('t')[0], 'T', 'should keep T') + t.equal(m('vv')[0], 'F', 'should transform VV to F') + t.equal(m('v')[0], 'F', 'should transform V to F') + t.equal(m('awr')[0], 'AR', 'should transform WR to R') t.deepEqual( m('wa'), ['A', 'F'], 'should transform W to A and F, when initial and followed by a vowel' - ); + ) - t.equal(m('wh')[0], 'A', 'should transform W to A, when initial and followed by H'); + t.equal( + m('wh')[0], + 'A', + 'should transform W to A, when initial and followed by H' + ) t.test( - 'should both drop and transform W to F, when in EWSKI, EWSKY, ' + - 'OWSKI, or OWSKY', - function (st) { - st.deepEqual(m('Tsjaikowski'), ['TSKSK', 'TSKFSK']); - st.deepEqual(m('Tsjaikowsky'), ['TSKSK', 'TSKFSK']); + 'should both drop and transform W to F, when in EWSKI, EWSKY, OWSKI, or OWSKY', + function(st) { + st.deepEqual(m('Tsjaikowski'), ['TSKSK', 'TSKFSK']) + st.deepEqual(m('Tsjaikowsky'), ['TSKSK', 'TSKFSK']) - st.end(); + st.end() } - ); + ) t.deepEqual( m('schwa'), ['X', 'XF'], - 'should both drop and transform W to F, when the value starts ' + - 'with SCH' - ); + 'should both drop and transform W to F, when the value starts with SCH' + ) t.deepEqual( m('Arnow'), ['ARN', 'ARNF'], - 'should both drop and transform W to F, when final and preceded by ' + - 'a vowel' - ); + 'should both drop and transform W to F, when final and preceded by a vowel' + ) t.test( 'should transform W to TS and FX, when followed by ICZ or ITZ', - function (st) { - st.deepEqual(m('Filipowicz'), ['FLPTS', 'FLPFX']); - st.deepEqual(m('Filipowitz'), ['FLPTS', 'FLPFX']); + function(st) { + st.deepEqual(m('Filipowicz'), ['FLPTS', 'FLPFX']) + st.deepEqual(m('Filipowitz'), ['FLPTS', 'FLPFX']) - st.end(); + st.end() } - ); + ) - t.equal(m('w')[0], '', 'should drop W'); - t.equal(m('matrix')[0], 'MTRKS', 'should transform X to KS, when final'); + t.equal(m('w')[0], '', 'should drop W') + t.equal(m('matrix')[0], 'MTRKS', 'should transform X to KS, when final') t.test( 'should transform X to KS, when *NOT* preceded by IAU, EAU, AU, or OU', - function (st) { - st.equal(m('iauxa')[0], 'AKS'); - st.equal(m('eauxa')[0], 'AKS'); - st.equal(m('auxa')[0], 'AKS'); - st.equal(m('ouxa')[0], 'AKS'); + function(st) { + st.equal(m('iauxa')[0], 'AKS') + st.equal(m('eauxa')[0], 'AKS') + st.equal(m('auxa')[0], 'AKS') + st.equal(m('ouxa')[0], 'AKS') - st.end(); + st.end() } - ); + ) - t.equal(m('AUX')[0], 'A', 'should drop `UX` in `AUX`'); - t.equal(m('OUX')[0], 'A', 'should drop `UX` in `OUX`'); - t.equal(m('breaux')[0], 'PR', 'should drop `aux` in `breaux`'); + t.equal(m('AUX')[0], 'A', 'should drop `UX` in `AUX`') + t.equal(m('OUX')[0], 'A', 'should drop `UX` in `OUX`') + t.equal(m('breaux')[0], 'PR', 'should drop `aux` in `breaux`') - t.equal(m('AXC')[0], 'AKS', 'should *not* drop XC'); - t.equal(m('axx')[0], 'AKS', 'should *not* drop XX'); - t.equal(m('axe')[0], 'AKS', 'should *not* drop X'); - t.equal(m('zhao')[0], 'J', 'should transform ZH to J'); + t.equal(m('AXC')[0], 'AKS', 'should *not* drop XC') + t.equal(m('axx')[0], 'AKS', 'should *not* drop XX') + t.equal(m('axe')[0], 'AKS', 'should *not* drop X') + t.equal(m('zhao')[0], 'J', 'should transform ZH to J') t.test( 'should transform Z to S and TS, when followed by ZA, ZI, or ZO', - function (st) { - st.deepEqual(m('zza'), ['S', 'TS']); - st.deepEqual(m('zzi'), ['S', 'TS']); - st.deepEqual(m('zzo'), ['S', 'TS']); + function(st) { + st.deepEqual(m('zza'), ['S', 'TS']) + st.deepEqual(m('zzi'), ['S', 'TS']) + st.deepEqual(m('zzo'), ['S', 'TS']) - st.end(); + st.end() } - ); + ) t.deepEqual( m('Mazurkiewicz'), ['MSRKTS', 'MTSRKFX'], - 'should transform Z to S and TS, when not initial, not ' + - 'Slavo-Germanic, and not preceded by T' - ); + 'should transform Z to S and TS, when not initial, not Slavo-Germanic, and not preceded by T' + ) - t.equal(m('zz')[0], 'S', 'should transform ZZ to S'); - t.equal(m('z')[0], 'S', 'should transform Z to S'); + t.equal(m('zz')[0], 'S', 'should transform ZZ to S') + t.equal(m('z')[0], 'S', 'should transform Z to S') - t.end(); -}); + t.end() +}) diff --git a/test/cli.js b/test/cli.js index c983bfe..a782cc0 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,42 +1,44 @@ -'use strict'; - -var PassThrough = require('stream').PassThrough; -var test = require('tape'); -var execa = require('execa'); -var version = require('../package').version; - -test('cli', function (t) { - var input = new PassThrough(); - - t.plan(7); - - execa.stdout('./cli.js', ['michael']).then(function (result) { - t.equal(result, 'MKL MXL', 'argument'); - }); - - execa.stdout('./cli.js', ['detestable', 'vileness']).then(function (result) { - t.equal(result, 'TTSTPL\tTTSTPL FLNS\tFLNS', 'arguments'); - }); - - execa.stdout('./cli.js', {input: input}).then(function (result) { - t.equal(result, 'TTSTPL\tTTSTPL FLNS\tFLNS', 'stdin'); - }); - - input.write('detestable'); - - setImmediate(function () { - input.end(' vileness'); - }); - - ['-h', '--help'].forEach(function (flag) { - execa.stdout('./cli.js', [flag]).then(function (result) { - t.ok(/\s+Usage: double-metaphone/.test(result), flag); - }); - }); - - ['-v', '--version'].forEach(function (flag) { - execa.stdout('./cli.js', [flag]).then(function (result) { - t.equal(result, version, flag); - }); - }); -}); +'use strict' + +var PassThrough = require('stream').PassThrough +var test = require('tape') +var execa = require('execa') +var version = require('../package').version + +test('cli', function(t) { + var input = new PassThrough() + var helps = ['-h', '--help'] + var versions = ['-v', '--version'] + + t.plan(7) + + execa.stdout('./cli.js', ['michael']).then(function(result) { + t.equal(result, 'MKL MXL', 'argument') + }) + + execa.stdout('./cli.js', ['detestable', 'vileness']).then(function(result) { + t.equal(result, 'TTSTPL\tTTSTPL FLNS\tFLNS', 'arguments') + }) + + execa.stdout('./cli.js', {input: input}).then(function(result) { + t.equal(result, 'TTSTPL\tTTSTPL FLNS\tFLNS', 'stdin') + }) + + input.write('detestable') + + setImmediate(function() { + input.end(' vileness') + }) + + helps.forEach(function(flag) { + execa.stdout('./cli.js', [flag]).then(function(result) { + t.ok(/\s+Usage: double-metaphone/.test(result), flag) + }) + }) + + versions.forEach(function(flag) { + execa.stdout('./cli.js', [flag]).then(function(result) { + t.equal(result, version, flag) + }) + }) +}) diff --git a/test/index.js b/test/index.js index ca1bec9..b3361a1 100644 --- a/test/index.js +++ b/test/index.js @@ -1,5 +1,5 @@ -'use strict'; +'use strict' /* eslint-disable import/no-unassigned-import */ -require('./api'); -require('./cli'); +require('./api') +require('./cli')