Class: GovCodes::Dafecd::RecordSplitter

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

Overview

Splits the full directory text into one string per specialty record.

A specialty record begins at either:

* a "CEM Code <code>" line (enlisted only), or
* a bare standalone "AFSC <code>" line (officer single-code records), or
* the first ladder line ("AFSC <code>, <title>") of a ladder group that
is NOT immediately preceded (ignoring blank lines) by another ladder
line, CEM line, or bare-code line.

Running page headers ("DAFECD, " / "DAFOCD, ") are stripped before splitting. Behavior is publication-specific (injected Publication); the default is the enlisted directory.

Constant Summary collapse

CONTINUATION_WORD =

A lone title-case word on its own line (e.g. "Leader" left behind when Text.split_glued_afsc splits "LeaderAFSC 1A178"). Such wrapped continuations must not break a ladder group.

/\A[A-Z][a-z]+\z/

Instance Method Summary collapse

Constructor Details

#initialize(text, publication: Publication.dafecd) ⇒ RecordSplitter

Returns a new instance of RecordSplitter.



34
35
36
37
# File 'lib/gov_codes/dafecd/record_splitter.rb', line 34

def initialize(text, publication: Publication.dafecd)
  @publication = publication
  @text = Text.split_glued_afsc(text, publication.glued_afsc)
end

Instance Method Details

#recordsArray<String>

Returns one string per specialty record.

Returns:

  • (Array<String>)

    one string per specialty record



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gov_codes/dafecd/record_splitter.rb', line 40

def records
  lines = @text.lines.reject { |line| line =~ @publication.header }

  records = []
  current = nil
  prev_meaningful_was_anchor = false

  lines.each do |line|
    is_ladder = line =~ @publication.ladder
    is_cem = @publication.cem && line =~ @publication.cem
    is_bare = @publication.bare_code && line =~ @publication.bare_code
    stripped = line.strip
    # Blank lines and lone continuation words are neutral: they neither
    # start a record nor break a run of ladder/CEM/bare lines.
    neutral = stripped.empty? || stripped.match?(CONTINUATION_WORD)

    starts_record =
      is_cem ||
      is_bare ||
      (is_ladder && !prev_meaningful_was_anchor)

    if starts_record
      current = +""
      records << current
    end

    current << line if current

    unless neutral
      prev_meaningful_was_anchor = !!(is_ladder || is_cem || is_bare)
    end
  end

  records
end