diff --git a/src/2-two/contraction-two/compute/index.js b/src/2-two/contraction-two/compute/index.js new file mode 100644 index 0000000..e1f6a49 --- /dev/null +++ b/src/2-two/contraction-two/compute/index.js @@ -0,0 +1,87 @@ +import splice from './_splice.js' +import apostropheS from './apostrophe-s.js' +import apostropheD from './apostrophe-d.js' +import apostropheT from './apostrophe-t.js' +import isPossessive from './isPossessive.js' + +const byApostrophe = /'/ + +// poor-mans reindexing of this sentence only +const reIndex = function (terms) { + terms.forEach((t, i) => { + if (t.index) { + t.index[1] = i + } + }) +} + +// run tagger on our new implicit terms +const reTag = function (terms, view, start, len) { + const tmp = view.update() + tmp.document = [terms] + // offer to re-tag neighbours, too + let end = start + len + if (start > 0) { + start -= 1 + } + if (terms[end]) { + end += 1 + } + tmp.ptrs = [[0, start, end]] + tmp.compute(['freeze', 'lexicon', 'preTagger', 'unfreeze']) + // don't for a reindex of the whole document + reIndex(terms) +} + +const byEnd = { + // how'd + d: (terms, i) => apostropheD(terms, i), + // we ain't + t: (terms, i) => apostropheT(terms, i), + // bob's + s: (terms, i, world) => { + // [bob's house] vs [bob's cool] + if (isPossessive(terms, i)) { + return world.methods.one.setTag([terms[i]], 'Possessive', world, null, '2-contraction') + } + return apostropheS(terms, i) + }, +} + +const toDocs = function (words, view) { + const doc = view.fromText(words.join(' ')) + doc.compute('id') + return doc.docs[0] +} + +//really easy ones +const contractionTwo = view => { + const { world, document } = view + // each sentence + document.forEach((terms, n) => { + // loop through terms backwards + for (let i = terms.length - 1; i >= 0; i -= 1) { + // is it already a contraction + if (terms[i].implicit) { + continue + } + let after = null + if (byApostrophe.test(terms[i].normal) === true) { + after = terms[i].normal.split(byApostrophe)[1] + } + let words = null + // any known-ones, like 'dunno'? + if (Object.hasOwn(byEnd, after)) { + words = byEnd[after](terms, i, world) + } + // actually insert the new terms + if (words) { + words = toDocs(words, view) + splice(document, [n, i], words) + reTag(document[n], view, i, words.length) + continue + } + } + }) +} +export default { contractionTwo } diff --git a/tests/two/contractions/expand.test.js b/tests/two/contractions/expand.test.js new file mode 100644 index 0000000..2f75d58 --- /dev/null +++ b/tests/two/contractions/expand.test.js @@ -0,0 +1,88 @@ +import test from 'tape' +import nlp from '../_lib.js' +const here = '[two/expand] ' + +test('basic is contractions', function (t) { + let r = nlp(`he is cool.`) + r.contractions().expand() + t.equal(r.out('text'), `he is cool.`, here + 'expanded-expand') + + r = nlp(`he's cool.`) + r.contractions().expand() + t.equal(r.out('text'), `he is cool.`, here + 'contracted-expand') + + r = nlp(`he ain't going`) + r.contractions().expand() + t.equal(r.out('text'), `he is not going`, here + 'aint') + + r = nlp(`that's really great.`) + r.contractions().expand() + t.equal(r.out('text'), `that is really great.`, here + 'contracted-expand') + + r = nlp(`she'll, eat icecream`) + r.contractions().expand() + t.equal(r.out('text'), `she will, eat icecream`, here + 'with-punctuation') + + r = nlp("we're not gonna take it, no we're not gonna take it") + r.contractions().expand() + t.equal(r.out('text'), `we are not going to take it, no we are not going to take it`, here + 'expand gonna twice') + + r = nlp("we're we're gonna gonna") + r.contractions().expand() + t.equal(r.out('text'), `we are we are going to going to`, here + 'expand consecutive') + t.end() +}) + +test('do-not contractions', function (t) { + let r = nlp(`please do not eat the marshmellow`) + r.contractions().expand() + t.equal(r.out('text'), `please do not eat the marshmellow`, here + 'expanded-expand') + + r = nlp(`please don't eat the marshmellow`) + r.contractions().expand() + t.equal(r.out('text'), `please do not eat the marshmellow`, here + 'contracted-expand') + + t.end() +}) + +test('have contractions', function (t) { + let r = nlp(`i have stood`) + r.contractions().expand() + t.equal(r.out('text'), `i have stood`, here + 'expanded-expand') + + r = nlp(`i've stood`) + r.contractions().expand() + t.equal(r.out('text'), `i have stood`, here + 'contracted-expand') + + t.end() +}) + +test('repeated contract-expand', function (t) { + const r = nlp(`i'm good`) + r.contractions().expand() + + r.contractions().expand().expand().expand() + t.equal(r.out('text'), `i am good`, here + 'expand-n') + t.end() +}) + +test('contracted', function (t) { + const r = nlp(`I'll go to Toronto. I will see.`) + const m = r.contractions() + const str = m.out('text') + t.equal(str, `I'll`, here + 'contracted') + + t.equal(m.length, 1, here + 'no-expanded') + t.end() +}) + +test('would-or-did', function (t) { + let r = nlp(`i'd contemplate`) + let str = r.contractions().expand().all().out('text') + t.equal(str, `i would contemplate`, here + 'i-would') + + r = nlp(`i'd contemplated`) + str = r.contractions().expand().all().out('text') + t.equal(str, `i had contemplated`, here + 'i-had') + t.end() +})