Class: GovCodes::Dafecd::TitleDegluer

Inherits:
Object
  • Object
show all
Defined in:
lib/gov_codes/dafecd/title_degluer.rb

Overview

Applies verified de-glued specialty titles.

pdf-reader drops spaces inside DAFECD titles ("MOBILITY FORCEAVIATOR"). The deterministic extractor title-cases those verbatim ("Mobility Forceaviator") and cannot safely re-insert the missing spaces. The clean titles are produced out of band and shipped in title_overrides.yml.

The de-gluing invariant — enforced at build time by IndexBuilder — is that an override may only change SPACING and CASE relative to the raw source title; no letter, digit, or punctuation may change. Any drift (e.g. a future release renamed the specialty) fails the build loudly rather than silently applying a stale title.

Constant Summary collapse

DEFAULT_PATH =
File.expand_path("title_overrides.yml", __dir__)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(overrides = {}) ⇒ TitleDegluer

Returns a new instance of TitleDegluer.

Parameters:

  • overrides (Hash{Symbol=>String}) (defaults to: {})

    specialty => clean title



53
54
55
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 53

def initialize(overrides = {})
  @overrides = overrides
end

Class Method Details

.emptyObject

An empty de-gluer applies no overrides (keeps the auto-titlecased names).



37
38
39
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 37

def self.empty
  new({})
end

.for(publication) ⇒ TitleDegluer

Returns loaded from +publication+'s overrides file, or an empty de-gluer when that file does not yet exist (officer titles are supplied out of band in a later phase).

Returns:

  • (TitleDegluer)

    loaded from +publication+'s overrides file, or an empty de-gluer when that file does not yet exist (officer titles are supplied out of band in a later phase).



31
32
33
34
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 31

def self.for(publication)
  path = publication.title_overrides_path
  File.exist?(path) ? load(path) : empty
end

.load(path = DEFAULT_PATH) ⇒ TitleDegluer

Returns loaded from the shipped overrides file.

Returns:



23
24
25
26
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 23

def self.load(path = DEFAULT_PATH)
  overrides = YAML.safe_load_file(path, permitted_classes: [Symbol]) || {}
  new(overrides)
end

.matches_source?(override, raw_title) ⇒ Boolean

Does override differ from raw_title only in spacing/case?

Returns:

  • (Boolean)


47
48
49
50
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 47

def self.matches_source?(override, raw_title)
  return false if raw_title.nil?
  norm(override) == norm(raw_title)
end

.norm(str) ⇒ Object

Whitespace-and-case-insensitive normalization used for the invariant.



42
43
44
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 42

def self.norm(str)
  str.to_s.gsub(/\s+/, "").downcase
end

Instance Method Details

#any?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 62

def any?
  !@overrides.empty?
end

#override_for(specialty) ⇒ String?

Returns the clean title for specialty, or nil.

Returns:

  • (String, nil)

    the clean title for specialty, or nil



58
59
60
# File 'lib/gov_codes/dafecd/title_degluer.rb', line 58

def override_for(specialty)
  @overrides[specialty]
end