From 6fd03e1913ae533046ab3411c084d8c432276ead Mon Sep 17 00:00:00 2001 From: upstream Date: Wed, 23 Sep 2026 12:38:21 +0200 Subject: [PATCH] Upstream spencermountain/compromise state of the touched files before 2b66fef810 --- .../contraction-two/compute/isPossessive.js | 154 +++++++++++++ .../postTagger/model/adjective/adj-verb.js | 74 +++++++ .../contractions/is-has-possessive.test.js | 204 ++++++++++++++++++ 3 files changed, 432 insertions(+) create mode 100644 src/2-two/contraction-two/compute/isPossessive.js create mode 100644 src/2-two/postTagger/model/adjective/adj-verb.js create mode 100644 tests/two/contractions/is-has-possessive.test.js diff --git a/src/2-two/contraction-two/compute/isPossessive.js b/src/2-two/contraction-two/compute/isPossessive.js new file mode 100644 index 0000000..f5d91d2 --- /dev/null +++ b/src/2-two/contraction-two/compute/isPossessive.js @@ -0,0 +1,154 @@ +const banList = { + that: true, + there: true, + let: true, + here: true, + everywhere: true, +} + +const beforePossessive = { + in: true, //in sunday's + by: true, //by sunday's + for: true, //for sunday's +} +const adjLike = new Set(['too', 'also', 'enough', 'about']) +const nounLike = new Set(['is', 'are', 'did', 'were', 'could', 'should', 'must', 'had', 'have']) + +const isPossessive = (terms, i) => { + const term = terms[i] + // these can't be possessive + if (banList.hasOwnProperty(term.machine || term.normal)) { + return false + } + // if we already know it + if (term.tags.has('Possessive')) { + return true + } + // who's + if (term.tags.has('QuestionWord')) { + return false + } + // some pronouns are never possessive + if (term.normal === `he's` || term.normal === `she's`) { + return false + } + //if end of sentence, it is possessive - "was spencer's" + const nextTerm = terms[i + 1] + if (!nextTerm) { + return true + } + // "it's a life" vs "run it's business" + if (term.normal === `it's`) { + if (nextTerm.tags.has('#Noun')) { + return true + } + return false + } + // the sun's setting vs the artist's painting + // gerund = is, noun = possessive + // (we are doing some dupe-work of the switch classifier here) + if (nextTerm.switch == 'Noun|Gerund') { + const next2 = terms[i + 2] + // the artist's painting. + if (!next2) { + if (term.tags.has('Actor') || term.tags.has('ProperNoun')) { + return true + } + return false + } + // the artist's painting is.. + if (next2.tags.has('Copula')) { + return true + } + // the cat's sleeping on .. + if (next2.normal === 'on' || next2.normal === 'in') { + return false + } + return false + } + //a gerund suggests 'is walking' + if (nextTerm.tags.has('Verb')) { + //fix 'jamie's bite' + if (nextTerm.tags.has('Infinitive')) { + return true + } + //'jamaica's growing' + if (nextTerm.tags.has('Gerund')) { + return false + } + //fix 'spencer's runs' + if (nextTerm.tags.has('PresentTense')) { + return true + } + return false + } + + // john's nuts + if (nextTerm.switch === 'Adj|Noun') { + const twoTerm = terms[i + 2] + if (!twoTerm) { + return false //adj + } + // john's nuts were.. + if (nounLike.has(twoTerm.normal)) { + return true + } + // john's nuts about.. + if (adjLike.has(twoTerm.normal)) { + return false //adj + } + } + //spencer's house + if (nextTerm.tags.has('Noun')) { + const nextStr = nextTerm.machine || nextTerm.normal + // 'spencer's here' + if (nextStr === 'here' || nextStr === 'there' || nextStr === 'everywhere') { + return false + } + // the chair's his + if (nextTerm.tags.has('Possessive')) { + return false + } + // the captain's John + if (nextTerm.tags.has('ProperNoun') && !term.tags.has('ProperNoun')) { + return false + } + return true + } + + // by sunday's final + if (terms[i - 1] && beforePossessive[terms[i - 1].normal] === true) { + return true + } + + // spencer's tired + if (nextTerm.tags.has('Adjective')) { + const twoTerm = terms[i + 2] + //the rocket's red + if (!twoTerm) { + return false + } + // rocket's red nozzle + if (twoTerm.tags.has('Noun') && !twoTerm.tags.has('Pronoun')) { + //project's behind schedule + const str = nextTerm.normal + if (str === 'above' || str === 'below' || str === 'behind') { + return false + } + return true + } + // rocket's red glare + if (twoTerm.switch === 'Noun|Verb') { + return true + } + //othwerwise, an adjective suggests 'is good' + return false + } + // baby's first steps + if (nextTerm.tags.has('Value')) { + return true + } + // otherwise not possessive + return false +} +export default isPossessive diff --git a/src/2-two/postTagger/model/adjective/adj-verb.js b/src/2-two/postTagger/model/adjective/adj-verb.js new file mode 100644 index 0000000..3848629 --- /dev/null +++ b/src/2-two/postTagger/model/adjective/adj-verb.js @@ -0,0 +1,74 @@ +export default [ + // amusing his aunt + // { match: '[#Adjective] #Possessive #Noun', group: 0, tag: 'Verb', reason: 'gerund-his-noun' }, + // loving you + // { match: '[#Adjective] (us|you)', group: 0, tag: 'Gerund', reason: 'loving-you' }, + // slowly stunning + { match: '(slowly|quickly) [#Adjective]', group: 0, tag: 'Verb', reason: 'slowly-adj' }, + // does mean + { match: 'does (#Adverb|not)? [#Adjective]', group: 0, tag: 'PresentTense', reason: 'does-mean' }, + // okay by me + { match: '[(fine|okay|cool|ok)] by me', group: 0, tag: 'Adjective', reason: 'okay-by-me' }, + // i mean + { match: 'i (#Adverb|do)? not? [mean]', group: 0, tag: 'PresentTense', reason: 'i-mean' }, + //will secure our + { match: 'will #Adjective', tag: 'Auxiliary Infinitive', reason: 'will-adj' }, + //he disguised the thing + { match: '#Pronoun [#Adjective] #Determiner #Adjective? #Noun', group: 0, tag: 'Verb', reason: 'he-adj-the' }, + //is eager to go + { match: '#Copula [%Adj|Present%] to #Verb', group: 0, tag: 'Verb', reason: 'adj-to' }, + //is done well + { match: '#Copula [#Adjective] (well|badly|quickly|slowly)', group: 0, tag: 'Verb', reason: 'done-well' }, + // rude and insulting + { match: '#Adjective and [#Gerund] !#Preposition?', group: 0, tag: 'Adjective', reason: 'rude-and-x' }, + // were over cooked + { match: '#Copula #Adverb? (over|under) [#PastTense]', group: 0, tag: 'Adjective', reason: 'over-cooked' }, + // was bland and overcooked + { match: '#Copula #Adjective+ (and|or) [#PastTense]$', group: 0, tag: 'Adjective', reason: 'bland-and-overcooked' }, + // got tired of + { match: 'got #Adverb? [#PastTense] of', group: 0, tag: 'Adjective', reason: 'got-tired-of' }, + //felt loved + { + match: + '(seem|seems|seemed|appear|appeared|appears|feel|feels|felt|sound|sounds|sounded) (#Adverb|#Adjective)? [#PastTense]', + group: 0, + tag: 'Adjective', + reason: 'felt-loved', + }, + // seem confused + { match: '(seem|feel|seemed|felt) [#PastTense #Particle?]', group: 0, tag: 'Adjective', reason: 'seem-confused' }, + // a bit confused + { match: 'a (bit|little|tad) [#PastTense #Particle?]', group: 0, tag: 'Adjective', reason: 'a-bit-confused' }, + // do not be embarrassed + { match: 'not be [%Adj|Past% #Particle?]', group: 0, tag: 'Adjective', reason: 'do-not-be-confused' }, + // is just right + { match: '#Copula just [%Adj|Past% #Particle?]', group: 0, tag: 'Adjective', reason: 'is-just-right' }, + // as pale as + { match: 'as [#Infinitive] as', group: 0, tag: 'Adjective', reason: 'as-pale-as' }, + //failed and oppressive + { match: '[%Adj|Past%] and #Adjective', group: 0, tag: 'Adjective', reason: 'faled-and-oppressive' }, + // or heightened emotion + { + match: 'or [#PastTense] #Noun', + group: 0, + tag: 'Adjective', + notIf: '(#Copula|#Pronoun)', + reason: 'or-heightened-emotion', + }, + // became involved + { match: '(become|became|becoming|becomes) [#Verb]', group: 0, tag: 'Adjective', reason: 'become-verb' }, + // their declared intentions + { match: '#Possessive [#PastTense] #Noun', group: 0, tag: 'Adjective', reason: 'declared-intentions' }, + // is he cool + { match: '#Copula #Pronoun [%Adj|Present%]', group: 0, tag: 'Adjective', reason: 'is-he-cool' }, + // is crowded with + { + match: '#Copula [%Adj|Past%] with', + group: 0, + tag: 'Adjective', + notIf: '(associated|worn|baked|aged|armed|bound|fried|loaded|mixed|packed|pumped|filled|sealed)', + reason: 'is-crowded-with', + }, + // is empty$ + { match: '#Copula #Adverb? [%Adj|Present%]$', group: 0, tag: 'Adjective', reason: 'was-empty$' }, +] diff --git a/tests/two/contractions/is-has-possessive.test.js b/tests/two/contractions/is-has-possessive.test.js new file mode 100644 index 0000000..e7e95b1 --- /dev/null +++ b/tests/two/contractions/is-has-possessive.test.js @@ -0,0 +1,204 @@ +import test from 'tape' +import nlp from '../_lib.js' +const here = '[two/is-has] ' + +test('is-has', function (t) { + const arr = [ + ["Artist's creative process is unique to each individual", '#Possessive'], + ["Athlete's dedication often leads to success", '#Possessive'], + ["Baby's first steps are always memorable", '#Possessive'], + ["He's a professional photographer", 'is'], + ["He's a talented musician", 'is'], + ["He's always been a good friend", 'has'], + ["He's always on time", 'is'], + ["He's an excellent cook", 'is'], + ["He's become a successful entrepreneur", 'has'], + ["He's feeling much better", 'is'], + ["He's got a new job", 'has'], + ["He's lived here for years", 'has'], + // ["He's never let us down before", 'has'], + ["He's never met her before", 'has'], + ["He's never seen such a beautiful sunset", 'has'], + ["He's studying for the exam", 'is'], + ["He's the captain of the team", 'is'], + ["He's the one in charge", 'is'], + ["He's the one who called", 'is'], + ["He's very talented", 'is'], + ["It's a beautiful morning", 'is'], + ["It's important to stay focused", 'is'], + ["It's not as easy as it looks", 'is'], + ["It's not what it seems", 'is'], + ["It's not what it used to be", 'is'], + ["It's raining outside", 'is'], + ["It's your turn to speak", 'is'], + ["Jamaica's growing rapidly", 'is'], + ["John's car is parked outside", '#Possessive'], + ["john's closed tasks", 'has'], + ["John's finished his homework", 'has'], + ["John's guitar is in the corner", '#Possessive'], + ["John's house is very warm", '#Possessive'], + ["John's nuts about Georgia", 'is'], + ["John's nuts were roasting", '#Possessive'], + ["John's nuts had been salted", '#Possessive'], + ["John's quickly running", 'is'], + ["Mary's visited Paris before", 'has'], + ["My sister's birthday is next week", '#Possessive'], + ["My sister's wedding is next month", '#Possessive'], + ["Professor's office hours are posted on the door", '#Possessive'], + ["Restaurant's signature dish is a customer favorite", '#Possessive'], + ["She's a talented artist", 'is'], + ["She's already finished her homework", 'has'], + ["She's always been a fast learner", 'has'], + ["She's always been a good listener", 'has'], + ["She's always been a hard worker", 'has'], + ["She's been a great friend", 'has'], + ["She's been to Europe several times", 'has'], + ["She's been working all day", 'has'], + ["She's excited about the trip", 'is'], + ["She's finished her degree", 'has'], + ["She's finished her work", 'has'], + ["She's got a lot of experience", 'has'], + ["She's got a lot of friends", 'has'], + ["She's got a new car", 'has'], + ["She's got a talent for singing", 'has'], + ["She's lost her keys again", 'has'], + ["She's never been to Asia", 'has'], + ["She's never seen such a beautiful sunset", 'has'], + ["She's never tasted sushi before", 'has'], + ["She's reached her goal", 'has'], + ["She's the one who called", 'is'], + ["She's the one who organized the event", 'is'], + ["Student's question sparked an interesting discussion", '#Possessive'], + ["The architect's plans were carefully drawn", '#Possessive'], + ["The architect's vision is reflected in the design", '#Possessive'], + ["The artist's gallery displayed stunning works", '#Possessive'], + ["The artist's painting is on display", '#Possessive'], + ["The artist's technique is unique", '#Possessive'], + ["The assignment's due tomorrow", 'is'], + ["The athlete's dedication is inspiring", '#Possessive'], + ["The author's storytelling is captivating", '#Possessive'], + ["The baby's crying in the crib", 'is'], + ["The baby's first steps are exciting", '#Possessive'], + ["The baby's learned to crawl", 'has'], + ["The baby's room needs redecorating", '#Possessive'], + ["The book's been on the bestseller list", 'has'], + ["The book's missing a few chapters", 'is'], + ["The book's missing a few pages", 'is'], + ["The building's foundation is strong", '#Possessive'], + ["The cake's already been eaten", 'has'], + ["The cake's been eaten", 'has'], + ["The captain's chair was empty", '#Possessive'], + ["The captain's leadership is crucial", '#Possessive'], + ["The captain's orders were clear", '#Possessive'], + ["The car's engine is making a strange noise", 'is'], + ["The car's engine needs maintenance", '#Possessive'], + ["The car's engine roared to life", '#Possessive'], + ["The car's out of gas", 'is'], + ["The car's parked in the garage", 'is'], + ["The car's sleek design caught everyone's attention", '#Possessive'], + ["The cat's asleep on the windowsill", 'is'], + ["The cat's eyes gleamed in the darkness", '#Possessive'], + ["The cat's eyes sparkled in the moonlight", '#Possessive'], + ["The cat's fur is soft", '#Possessive'], + ["The cat's hiding under the table", 'is'], + ["The cat's playful antics amused everyone", '#Possessive'], + ["The cat's sleeping on the roof", 'is'], + ["The CEO's decision impacted the entire company", '#Possessive'], + ["The chef's recipe is a closely guarded secret", '#Possessive'], + ["The child's imagination is vivid", '#Possessive'], + ["The child's innocence is heartwarming", '#Possessive'], + ["The child's laughter is infectious", '#Possessive'], + ["The city's population is growing", '#Possessive'], + ["The city's skyline is breathtaking", '#Possessive'], + ["The coffee's aroma filled the room", '#Possessive'], + ["The coffee's too hot to drink", 'is'], + ["The coffee's too hot", 'is'], + ["The company's CEO is giving a speech", '#Possessive'], + ["The company's expanding globally", 'is'], + ["The company's expanding rapidly", 'is'], + ["The company's headquarters are in the city", '#Possessive'], + ["The company's success is remarkable", '#Possessive'], + ["The computer's crashed again", 'has'], + ["The concert's sold out", 'is'], + ["The concert's starting soon", 'is'], + ["The detective's intuition was sharp", '#Possessive'], + ["The doctor's advice was helpful", '#Possessive'], + ["The doctor's diagnosis was accurate", '#Possessive'], + ["The dog's barking in the backyard", 'is'], + ["The dog's behavior is unpredictable", '#Possessive'], + ["The dog's chasing its tail", 'is'], + ["The dog's collar is missing", '#Possessive'], + ["The engineer's design was innovative", '#Possessive'], + ["The explorer's journey was filled with challenges", '#Possessive'], + ["The explorer's map guided the journey", '#Possessive'], + ["The farmer's crops were ready for harvest", '#Possessive'], + ["The food's ready to be served", 'is'], + ["The garden's beauty is captivating", '#Possessive'], + ["The garden's flowers are in full bloom", '#Possessive'], + ["The journalist's story was front-page news", '#Possessive'], + ["The lawyer's argument was persuasive", '#Possessive'], + ["The lawyer's argument won the case", '#Possessive'], + ["The librarian's knowledge of books was vast", '#Possessive'], + ["The manager's decision was unexpected", '#Possessive'], + ["The meeting's been rescheduled", 'has'], + ["The meeting's scheduled for 3 PM", 'is'], + ["The mountain's peak is covered in snow", '#Possessive'], + ["The movie's already started", 'has'], + ["The musician's talent is evident", '#Possessive'], + ["The novel's plot is intriguing", '#Possessive'], + ["The nurse's care was comforting", '#Possessive'], + ["The package's arrived on time", 'has'], + ["The package's arrived", 'has'], + ["The plane's just landed", 'has'], + ["The professor's lecture was enlightening", '#Possessive'], + ["The professor's lecture was informative", '#Possessive'], + ["The project's almost complete", 'is'], + ["The project's already started", 'has'], + ["The project's behind schedule", 'is'], + ["The project's completed on time", 'has'], + ["The project's completion is imminent", '#Possessive'], + ["The scientist's discovery is groundbreaking", '#Possessive'], + ["The scientist's experiment yielded interesting results", '#Possessive'], + ["The scientist's research is groundbreaking", '#Possessive'], + ["The software's being updated", 'is'], + ["The store's closed on Sundays", 'is'], + ["The student's backpack is in the hallway", '#Possessive'], + ["The student's question was thought-provoking", '#Possessive'], + ["The student's understanding is impressive", '#Possessive'], + ["The sun's setting", 'is'], + ["The sun's shining brightly", 'is'], + ["The teacher's guidance is invaluable", '#Possessive'], + ["The team's strategy is well-thought-out", '#Possessive'], + ["The team's unity is commendable", '#Possessive'], + ["The team's won every game this season", 'has'], + ["The team's won the championship", 'has'], + ["The train's already left the station", 'has'], + ["The weather's getting colder", 'is'], + ["They're convinced he's innocent", 'is'], + + ["the cell's natural", 'is'], + ["the cell's natural mechanisms", '#Possessive'], + ["the field's leading proponents", '#Possessive'], + ["the rocket's red glare", '#Possessive'], + ["the rocket's glare", '#Possessive'], + ["the rocket's red", 'is'], + ["Everybody's waiting up to hear ", 'is'], + ["this truck's close proximity", '#Possessive'], + ["causing a patient's secondary rhinitis", '#Possessive'], + ["Prince Ahmed's natural disposition", '#Possessive'], + ["that genre's stylistic achievements", '#Possessive'], + ["picking up on Jeramie's quick explanations", '#Possessive'], + [`This company's "Natural Soda"`, '#Possessive'], + [`Toronto's loudest singing group `, '#Possessive'], + [`Drake's rich album cover`, '#Possessive'], + [`a role in Los Angeles's cultural identity`, '#Possessive'], + [`this artist's painting of his "Anatomy Lesson" `, '#Possessive'], + [`the Art Institute of Chicago's Building `, '#Possessive'], + [`it features Cody's chanting. `, '#Possessive'], + ] + arr.forEach(a => { + const doc = nlp(a[0]) + t.equal(doc.has(a[1]), true, here + ' (' + a[1] + ') ' + a[0]) + }) + t.end() +})