Module: GovCodes::Dafecd::RiSdi::Title
- Defined in:
- lib/gov_codes/dafecd/ri_sdi/title.rb
Overview
Conservative title normalization for RI/SDI records.
These helpers mirror the AFSC SpecialtyParser's title handling exactly (sanitize -> title-case verbatim, flag probable pdf glue) but live in their own module so the RI/SDI extraction shares NONE of the AFSC ladder pipeline's mutable state — the already-shipped enlisted/officer artifacts cannot be perturbed by anything done here.
As in the AFSC pipeline, no de-gluing is attempted: a run-together title like "ENLISTEDAIDE" becomes "Enlistedaide" and is flagged via #glued? for the deferred, governed de-glue pass. Clean titles are authored out of band.
Constant Summary collapse
- DECORATIVE =
Patterns::DECORATIVE
- UNICODE_DASHES =
Patterns::UNICODE_DASHES
Class Method Summary collapse
-
.glued?(name) ⇒ Boolean
Heuristic proxy for pdf-reader glue: an unusually long single token (excluding preserved acronyms).
-
.real?(title) ⇒ Boolean
A real title starts with a capital letter, a digit, or an opening paren — never the lowercase word that begins a wrapped prose sentence (the "SDI 8P000, completion of ..." false positive).
-
.sanitize(line) ⇒ Object
Remove decorative symbol glyphs, normalize unicode dashes, and collapse whitespace runs so a title line reduces to its plain-text content.
-
.title_line?(stripped) ⇒ Boolean
A title line is short, starts with a capital / paren / digit, and is not a prose sentence.
-
.titleize(raw) ⇒ Object
Conservative title-case: capitalize each alphabetic word, preserving parenthesized acronyms and all-caps-with-digit tokens.
- .titleize_word(word) ⇒ Object
Class Method Details
.glued?(name) ⇒ Boolean
Heuristic proxy for pdf-reader glue: an unusually long single token (excluding preserved acronyms). Reported, not relied upon.
66 67 68 69 70 71 72 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 66 def glued?(name) return false if name.nil? name.split(/\s+/).any? do |token| = token.delete("()/-") .length >= 12 && .match?(/\A[A-Za-z]+\z/) end end |
.real?(title) ⇒ Boolean
A real title starts with a capital letter, a digit, or an opening paren — never the lowercase word that begins a wrapped prose sentence (the "SDI 8P000, completion of ..." false positive).
59 60 61 62 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 59 def real?(title) t = title.to_s.strip !t.empty? && t.match?(/\A[A-Z0-9(]/) end |
.sanitize(line) ⇒ Object
Remove decorative symbol glyphs, normalize unicode dashes, and collapse whitespace runs so a title line reduces to its plain-text content.
27 28 29 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 27 def sanitize(line) line.gsub(DECORATIVE, "").gsub(UNICODE_DASHES, "-").gsub(/\s+/, " ").strip end |
.title_line?(stripped) ⇒ Boolean
A title line is short, starts with a capital / paren / digit, and is not a prose sentence. Accepts ALL-CAPS and Title-Case forms.
33 34 35 36 37 38 39 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 33 def title_line?(stripped) return false if stripped.length > 90 return false unless stripped.match?(/\A[A-Z0-9(]/) return false if stripped.split(/\s+/).size > 12 return false if stripped.match?(/[a-z]\.\s+[A-Z]/) # mid-line sentence break = prose stripped.match?(/[A-Za-z]/) end |
.titleize(raw) ⇒ Object
Conservative title-case: capitalize each alphabetic word, preserving parenthesized acronyms and all-caps-with-digit tokens.
43 44 45 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 43 def titleize(raw) raw.split(/\s+/).map { |word| titleize_word(word) }.join(" ") end |
.titleize_word(word) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'lib/gov_codes/dafecd/ri_sdi/title.rb', line 47 def titleize_word(word) return word if word.match?(/\A\([A-Z0-9&\/.-]{2,}\)\z/) return word if word.match?(/\A[A-Z]*\d[A-Z0-9]*\z/) && word.match?(/[A-Z0-9]/) word.split(/([\/-])/).map { |seg| seg.match?(/[A-Za-z]/) ? seg.capitalize : seg }.join end |