vicary 0.2.17 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 381ed16c17b2aa427a72b173af92825ad08db621b13e562fdc7977d41d760a26
4
- data.tar.gz: 9e7a68508af7f405888c9a0e5ebc9b7993b3f0e7de6149c91156cf7c23b9fe29
3
+ metadata.gz: a5bf0874dcc6fb688fb61bc76441886d82f709b45017a97e41a71a5de67a8be3
4
+ data.tar.gz: 21b6dcb645bd2a449ba89b8971d25e3c0cf650a6cc6e2515e0daff3c5e22e8a7
5
5
  SHA512:
6
- metadata.gz: 87ffdbf4edb505a3c1d5faca88c817a5a1ad44b093fbfc329f99958c05a528b078c3fdcc1d97c9e6ffca2d255be617cb3912d6d6e2a9735f02861600aa0f0ce6
7
- data.tar.gz: ec871699f441d07106e5f32981eb9a34f35ce2935f75a7f78163fc0ae277dc1afbe8fdd042e3dbf9676b8a4493dc9fb8078c36a0e3ba9cb65804cad79b17c93b
6
+ metadata.gz: a3f1e0e9ed8bafb67ceb4812dce7c56cac60e3f58fb2fbc2ad0ecd5fce15741ebd9f9404c3ccf5a23912f27f849642bf867d805ad627981fcfcff56ce03162d9
7
+ data.tar.gz: f86e63597d16e1aa83ba33fa41bfe9a8fdff3ef59ecaa12e2d7fcaec2d38e00b837a0578fbafe25a53b90acb5017cc128f3929d02cfc6ade4cd25f3ea0e05d88
data/assets/MANIFEST.json CHANGED
@@ -22,11 +22,11 @@
22
22
  }
23
23
  },
24
24
  "stop_words_never_capitalised.txt": {
25
- "bytes": 8017,
26
- "entries": 499,
25
+ "bytes": 8108,
26
+ "entries": 511,
27
27
  "format": 1,
28
28
  "min_package_version": "0.2.10",
29
- "sha256": "23798cb88672c126d71a9d0988b9adf0aa044bdc291847012d76deae71fe1d33"
29
+ "sha256": "809e92aa74f001533be8bd33bfe119f5edab4bef2fbde687140f16c998c1039f"
30
30
  },
31
31
  "stop_words_sometimes_capitalised.txt": {
32
32
  "bytes": 6351,
@@ -37,5 +37,5 @@
37
37
  }
38
38
  },
39
39
  "manifest_version": 1,
40
- "written_by": "vicary 0.2.13"
40
+ "written_by": "vicary 0.2.17"
41
41
  }
@@ -1,5 +1,5 @@
1
1
  #!lexicon 1
2
- #!list stop_words_never_capitalised 499
2
+ #!list stop_words_never_capitalised 511
3
3
  # Ordinary words that must never become name candidates, and that English never
4
4
  # capitalises in the middle of a sentence.
5
5
  #
@@ -58,6 +58,7 @@
58
58
  a an the this that these those there here it its it's
59
59
  i me my mine myself we us our ours ourselves you your yours
60
60
  he him his she her hers they them their theirs who whom whose which what
61
+ how why where wherever whatever whoever
61
62
  and or but so because although though however therefore thus hence yet
62
63
  if then else when while until since before after during once whenever
63
64
  for from to into onto out off over under above below between among across
@@ -109,18 +110,19 @@
109
110
  cants coulds didnts dids doeses doings donts durings eithers elses etcs
110
111
  everies everybodies everyones everythings everywheres feels fews finallies
111
112
  finds froms gaves gets gives gos gots growings hads hases havings helpeds
112
- hences hims hises howevers ids ifs ills ins insteads intos ises isnts justs
113
- keeps kepts knews knows learneds learnings learns leaves lefts lets lookeds
114
- lookings looks makes maybes mights mosts movings muches musts myselfs
115
- neededs neithers nobodies nos nothings nots nowheres nows offs oftens okays
116
- onces onlies ons ontos ourselveses outs perhapses playings pluses puts
117
- quites rarelies rathers reads reallies remembereds remembers runnings saids
118
- saws says sets severals shalls shes shoulds sinces sittings somebodies
119
- someones somethings sometimeses somewheres standings starteds stoppeds
120
- suches talkings taughts teaches tells thans thems thens therefores thes
121
- theses thinkings thinks thises thoses thoughs thoughts throughs thuses
113
+ hences hims hises howevers hows ids ifs ills ins insteads intos ises isnts
114
+ justs keeps kepts knews knows learneds learnings learns leaves lefts lets
115
+ lookeds lookings looks makes maybes mights mosts movings muches musts
116
+ myselfs neededs neithers nobodies nos nothings nots nowheres nows offs
117
+ oftens okays onces onlies ons ontos ourselveses outs perhapses playings
118
+ pluses puts quites rarelies rathers reads reallies remembereds remembers
119
+ runnings saids saws says sets severals shalls shes shoulds sinces sittings
120
+ somebodies someones somethings sometimeses somewheres standings starteds
121
+ stoppeds suches talkings taughts teaches tells thans thems thens therefores
122
+ thes theses thinkings thinks thises thoses thoughs thoughts throughs thuses
122
123
  todays togethers tolds tomorrows toos trieds tries tryings unders unlesses
123
124
  untils ups uses usings usuallies veries versuses walkings wanteds wants
124
- wases wents weres whenevers whens whethers whiches whoms whos whoses withins
125
- withouts wonts workeds woulds writes wrotes yeahs yeses yesterdays yets yous
125
+ wases wents weres whatevers whenevers whens wheres wherevers whethers
126
+ whiches whies whoevers whoms whos whoses withins withouts wonts workeds
127
+ woulds writes wrotes yeahs yeses yesterdays yets yous
126
128
  # <<< end generated inflections
@@ -257,6 +257,16 @@ module Vicary
257
257
  # Matches the abbreviation a break candidate sits directly behind.
258
258
  TRAILING_WORD = /([A-Za-z]+)\.\s*\z/
259
259
 
260
+ # Words that name the letter after them as a letter: "a capital C", "a big M".
261
+ # Feedback on spelling and capitals says this all the time, and the letter
262
+ # then stood alone mid-sentence with nothing to tell it from an initial.
263
+ # Measured on 696 generated replies: 4 of the 39 placeholders a host's guard
264
+ # had to remove.
265
+ LETTER_NAMING_WORDS = Set.new(%w[capital big small lowercase uppercase letter]).freeze
266
+
267
+ # The word directly before a span, read back over whitespace and an opening quote.
268
+ PRECEDING_WORD = /([A-Za-z]+)[\s'"‘“]*\z/
269
+
260
270
  # {SENTENCE_BREAK} with the `\A` arm removed, so it cannot match empty.
261
271
  #
262
272
  # A dialect difference, and it moved a number. `SENTENCE_BREAK` matches the
@@ -925,6 +935,18 @@ module Vicary
925
935
  # Reading the document's own orthography
926
936
  # ---------------------------------------------------------------------
927
937
 
938
+ # A lone capital that is a label or a letter, never an initial: glued to a
939
+ # digit (`E9`, a quote label the word pattern used to cut at the digit) or
940
+ # named as a letter by the word before it ({LETTER_NAMING_WORDS}). Only a
941
+ # single character is ever released; `Jake2009` stays a candidate.
942
+ def letter_not_a_name?(text, start, finish)
943
+ return false unless finish - start == 1
944
+ return true if finish < text.length && text[finish].match?(/[0-9]/)
945
+
946
+ preceding = PRECEDING_WORD.match(text[0...start])
947
+ !preceding.nil? && LETTER_NAMING_WORDS.include?(preceding[1].downcase)
948
+ end
949
+
928
950
  # Offsets at which a sentence begins.
929
951
  #
930
952
  # A break directly behind a title abbreviation is not one — see
@@ -1971,6 +1993,30 @@ module Vicary
1971
1993
  out
1972
1994
  end
1973
1995
 
1996
+ # A title abbreviation and the word it introduces, the title in any case.
1997
+ # With a period every title in the set counts; without one only `mr` and
1998
+ # `mrs`, because a bare `ms` or `dr` is as often "ms paint" or "dr" for drive.
1999
+ TITLED_WORD_RE = /\b(?:(?:mrs|mr|ms|dr|prof)\.[ \t]+|(?:mrs|mr)[ \t]+)([A-Za-z][A-Za-z'’]*(?:-[A-Za-z][A-Za-z'’]*)*)/i
2000
+
2001
+ # A surname written in lowercase behind a title: "mr. kowalski". The
2002
+ # lowercase route seeds on the given-name tier, so a surname alone never
2003
+ # reaches it, and the capitalised route needs the capital the writer left
2004
+ # off. A title is the one place the word after it is a name whatever its
2005
+ # case, so the span is the title and that one word. A stop word or a single
2006
+ # letter after the title is skipped.
2007
+ def find_titled_lowercase_candidates(text, protected_span, settlement = nil)
2008
+ out = []
2009
+ each_match(text, TITLED_WORD_RE) do |m|
2010
+ word = m[1]
2011
+ start = m.begin(0)
2012
+ stop = start + m[0].length
2013
+ next if word.length < 2 || stop?(word.downcase) || protected_span.call(start, stop)
2014
+
2015
+ out << Candidate.new(m[0], start, stop, classify(words(m[0]), settlement))
2016
+ end
2017
+ out
2018
+ end
2019
+
1974
2020
  # Every name-shaped span, before any notability decision.
1975
2021
  #
1976
2022
  # High recall and deliberately poor precision — precision is what the
@@ -2078,6 +2124,7 @@ module Vicary
2078
2124
 
2079
2125
  start = m.begin(0) + offset
2080
2126
  next if is_protected.call(start, start + joined.length)
2127
+ next if letter_not_a_name?(text, start, start + joined.length)
2081
2128
 
2082
2129
  # Cheapest of the three capital-discounting rules and the only one
2083
2130
  # that reads neither position nor list, so it goes first.
@@ -2143,6 +2190,12 @@ module Vicary
2143
2190
  ).each do |candidate|
2144
2191
  next if claimed.any? { |s, e| candidate.start < e && candidate.end > s }
2145
2192
 
2193
+ out << candidate
2194
+ end
2195
+ claimed = out.map { |candidate| [candidate.start, candidate.end] }
2196
+ find_titled_lowercase_candidates(text, is_protected, settlement).each do |candidate|
2197
+ next if claimed.any? { |s, e| candidate.start < e && candidate.end > s }
2198
+
2146
2199
  out << candidate
2147
2200
  end
2148
2201
  end
@@ -6,5 +6,5 @@ module Vicary
6
6
  # Shared across all three front doors on purpose: one detector, one number. A
7
7
  # gem 0.3.0 that corresponds to nothing on PyPI cannot be reasoned about, and
8
8
  # the parity claim is between *versions*, not between package names.
9
- VERSION = "0.2.17"
9
+ VERSION = "0.2.19"
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vicary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.17
4
+ version: 0.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Thomas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-21 00:00:00.000000000 Z
11
+ date: 2026-10-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Finds the names a student writes about — classmates, teachers, relatives — and