diff --git a/src/3-three/nouns/api/toSingular.js b/src/3-three/nouns/api/toSingular.js index 8dcd9d2..f1a0e1c 100644 --- a/src/3-three/nouns/api/toSingular.js +++ b/src/3-three/nouns/api/toSingular.js @@ -1,5 +1,16 @@ const keep = { tags: true } +// give 'dane' the case of the word it replaced: 'Danes' -> 'Dane', 'DANES' -> 'DANE' +const matchCase = function (original, str) { + if (original.length > 1 && original === original.toUpperCase() && original !== original.toLowerCase()) { + return str.toUpperCase() + } + if (/^\p{Lu}/u.test(original)) { + return str.charAt(0).toUpperCase() + str.slice(1) + } + return str +} + const nounToSingular = function (m, parsed) { // already singular? if (parsed.isPlural === false) { @@ -10,7 +21,15 @@ const nounToSingular = function (m, parsed) { // inflect the root noun const str = parsed.root.text('normal') const single = toSingular(str, model) - m.replace(parsed.root, single, keep).tag('Singular', 'toPlural') + const before = (parsed.root.docs[0] || []).map(term => term.text) + const after = m.replace(parsed.root, single, keep).tag('Singular', 'toPlural') + // the conversion works on the normalized text, so put the original case back + const terms = after.docs[0] || [] + if (terms.length === before.length) { + terms.forEach((term, i) => { + term.text = matchCase(before[i], term.text) + }) + } // should we change the determiner/article? // m.debug() return m diff --git a/tests/three/nouns/toSingular.test.js b/tests/three/nouns/toSingular.test.js index c61259b..0760e51 100644 --- a/tests/three/nouns/toSingular.test.js +++ b/tests/three/nouns/toSingular.test.js @@ -256,4 +256,18 @@ test('toSingular - longer:', function (t) { t.equal(doc.text(), a[1], here + '[longer] ' + a[0]) }) t.end() -}) \ No newline at end of file +}) +test('toSingular - keeps case:', function (t) { + const arr = [ + [`Those are Great Danes`, `Those are Great Dane`], + [`The Children played`, `The Child played`], + [`I saw Mice`, `I saw Mouse`], + [`I saw MICE`, `I saw MOUSE`], + ] + arr.forEach(function (a) { + const doc = nlp(a[0]) + doc.nouns().toSingular() + t.equal(doc.text(), a[1], here + '[case] ' + a[0]) + }) + t.end() +})