vicary 0.2.18 → 0.3.0

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.
@@ -1993,6 +1993,30 @@ module Vicary
1993
1993
  out
1994
1994
  end
1995
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
+
1996
2020
  # Every name-shaped span, before any notability decision.
1997
2021
  #
1998
2022
  # High recall and deliberately poor precision — precision is what the
@@ -2166,6 +2190,12 @@ module Vicary
2166
2190
  ).each do |candidate|
2167
2191
  next if claimed.any? { |s, e| candidate.start < e && candidate.end > s }
2168
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
+
2169
2199
  out << candidate
2170
2200
  end
2171
2201
  end
data/lib/vicary/redact.rb CHANGED
@@ -148,6 +148,13 @@ module Vicary
148
148
  relation_refusal = options.fetch(:relation_refusal, true)
149
149
  title_relation_refusal = options.fetch(:title_relation_refusal, true)
150
150
 
151
+ # Adlib renders over the numbered restore map, so it refuses without one
152
+ # rather than ship placeholders under a setting that promised prose.
153
+ rendering = render_mode(options[:render])
154
+ if rendering == RENDER_ADLIB && !number_placeholders
155
+ raise ArgumentError, "adlib rendering needs local mode with numbered placeholders"
156
+ end
157
+
151
158
  minter = PlaceholderMinter.new(number: number_placeholders)
152
159
  return [text, 0, minter.assigned] if text.nil? || text.empty?
153
160
 
@@ -171,6 +178,14 @@ module Vicary
171
178
  n += count
172
179
  end
173
180
 
181
+ if rendering == RENDER_ADLIB
182
+ # A fourth element, so `masked, n, map = ...` callers keep working; the
183
+ # map is the adlib inverse, `{stand-in: original}`, as in the reference.
184
+ adlib = render_adlib(masked, minter.assigned, text,
185
+ seed: resolve_adlib_seed(options[:adlib_seed]), identity: identity)
186
+ return [adlib.text, n, adlib.restore_map, adlib]
187
+ end
188
+
174
189
  [masked, n, minter.assigned]
175
190
  end
176
191
 
@@ -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.18"
9
+ VERSION = "0.3.0"
10
10
  end
data/lib/vicary.rb CHANGED
@@ -45,3 +45,4 @@ require_relative "vicary/latency_baseline"
45
45
  require_relative "vicary/redact"
46
46
  require_relative "vicary/spans"
47
47
  require_relative "vicary/placeholders"
48
+ require_relative "vicary/adlib"
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.18
4
+ version: 0.3.0
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-22 00:00:00.000000000 Z
11
+ date: 2026-11-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Finds the names a student writes about — classmates, teachers, relatives — and
@@ -25,9 +25,16 @@ files:
25
25
  - README.md
26
26
  - assets/MANIFEST.json
27
27
  - assets/notability.txt.gz
28
+ - assets/pools/given.txt
29
+ - assets/pools/org.txt
30
+ - assets/pools/place.txt
31
+ - assets/pools/school.txt
32
+ - assets/pools/street.txt
33
+ - assets/pools/surname.txt
28
34
  - assets/stop_words_never_capitalised.txt
29
35
  - assets/stop_words_sometimes_capitalised.txt
30
36
  - lib/vicary.rb
37
+ - lib/vicary/adlib.rb
31
38
  - lib/vicary/asset.rb
32
39
  - lib/vicary/candidates.rb
33
40
  - lib/vicary/census.rb