diff --git a/src/2-two/contraction-two/api/contract.js b/src/2-two/contraction-two/api/contract.js new file mode 100644 index 0000000..c697bf7 --- /dev/null +++ b/src/2-two/contraction-two/api/contract.js @@ -0,0 +1,64 @@ +const postPunct = /[,)"';:\-–—.…]/ + +const setContraction = function (m, suffix) { + if (!m.found) { + return + } + const terms = m.termList() + //avoid any problematic punctuation + for (let i = 0; i < terms.length - 1; i++) { + const t = terms[i] + if (postPunct.test(t.post)) { + return + } + } + // set first word as full text + terms[0].implicit = terms[0].normal + terms[0].text += suffix + terms[0].normal += suffix + // clean-up the others + terms.slice(1).forEach(t => { + t.implicit = t.normal + t.text = '' + t.normal = '' + }) + for (let i = 0; i < terms.length - 1; i++) { + terms[i].post = terms[i].post.replace(/ /, '') + } +} + +/** turn 'i am' into i'm */ +const contract = function () { + const doc = this.not('@hasContraction') + // we are -> we're + let m = doc.match('(we|they|you) are') + setContraction(m, `'re`) + // they will -> they'll + m = doc.match('(he|she|they|it|we|you) will') + setContraction(m, `'ll`) + // she is -> she's + m = doc.match('(he|she|they|it|we) is') + setContraction(m, `'s`) + // spencer is -> spencer's + m = doc.match('#Person is') + setContraction(m, `'s`) + // spencer would -> spencer'd + m = doc.match('#Person would') + setContraction(m, `'d`) + // would not -> wouldn't + m = doc.match('(is|was|had|would|should|could|do|does|have|has|can) not') + setContraction(m, `n't`) + // i have -> i've + m = doc.match('(i|we|they) have') + setContraction(m, `'ve`) + // would have -> would've + m = doc.match('(would|should|could) have') + setContraction(m, `'ve`) + // i am -> i'm + m = doc.match('i am') + setContraction(m, `'m`) + // going to -> gonna + m = doc.match('going to') + return this +} +export default contract diff --git a/tests/two/contractions/contract.test.js b/tests/two/contractions/contract.test.js new file mode 100644 index 0000000..79f153b --- /dev/null +++ b/tests/two/contractions/contract.test.js @@ -0,0 +1,76 @@ +import test from 'tape' +import nlp from '../_lib.js' +const here = '[two/contract] ' + +test('contract basic', function (t) { + let r = nlp(`he is cool.`) + r.contract() + t.equal(r.out('text'), `he's cool.`, here + 'expanded-contract') + + r = nlp(`he's cool.`) + r.contract() + t.equal(r.out('text'), `he's cool.`, here + 'contracted-contract') + + r = nlp(`please do not eat the marshmellow`) + r.contract() + t.equal(r.out('text'), `please don't eat the marshmellow`, here + 'expanded-contract') + + r = nlp(`please don't eat the marshmellow`) + r.contract() + t.equal(r.out('text'), `please don't eat the marshmellow`, here + 'contracted-contract') + + r = nlp(`i have stood`) + r.contract() + t.equal(r.out('text'), `i've stood`, here + 'expanded-contract') + + r = nlp(`i've stood`) + r.contract() + t.equal(r.out('text'), `i've stood`, here + 'contracted-contract') + + r = nlp('i am good') + r.contract() + t.equal(r.out('text'), `i'm good`, here + 'contract-1') + r.contractions().expand() + t.equal(r.out('text'), `i am good`, here + 'expand-2') + r.contract() + t.equal(r.out('text'), `i'm good`, here + 'contract-2') + + r.contractions().contract().contract().contract() + t.equal(r.out('text'), `i'm good`, here + 'contract-n') + + t.end() +}) + +test('avoid contraction messes', function (t) { + let doc = nlp('Tony, is').contract() + t.equal(doc.has('is'), true, here + 'avoid-contraction 1') + + doc = nlp('(Tony) is').contract() + t.equal(doc.has('is'), true, here + 'avoid-contraction 2') + + doc = nlp(`'Tony' is`).contract() + t.equal(doc.has('is'), true, here + 'avoid-contraction 3') + + doc = nlp('Tony-is').contract() + t.equal(doc.has('is'), true, here + 'avoid-contraction 4') + const str = `Tony +is` + doc = nlp(str).contract() + t.equal(doc.has('is'), true, here + 'avoid-contraction 5') + + t.end() +}) + +test('multiple contraction in sentence', function (t) { + let doc = nlp(`he's foo she's`) + t.equal(doc.terms().length, 5, here + 'multi-contraction-count') + t.equal(doc.has('he is foo she is'), true, here + 'multi-contraction-order') + + doc = nlp(`he's she's`) + t.equal(doc.terms().length, 4, here + 'multi-contraction-count-2') + t.equal(doc.has('he is she is'), true, here + 'multi-contraction-order-2') + + doc = nlp(`he's dead, he's dead`) + t.equal(doc.match('he is dead').length, 2, here + 'multi-contraction-count') + t.end() +})