Class: Pubid::Core::UpdateCodes

Inherits:
Object
  • Object
show all
Defined in:
lib/pubid/core/update_codes.rb

Overview

Centralized update_codes loader and applier.

Reads YAML files from data/flavor/update_codes.yaml and applies substitution patterns to normalize malformed identifiers BEFORE parsing.

Each flavor’s parse entry point calls UpdateCodes.apply(code, :flavor) before any parser-specific preprocessing.

Format in YAML files:

plain string match: "IEC 60285-/1:1989"  →  "IEC 60285-1:1989"
regex match:        "/^NBS CIRC sup$/"   →  "NBS CIRC 24e7sup"
regex with flags:   "/^nbs\\b/i"          →  "NBS"

Plain strings use full-line anchoring (^pattern$). Regex patterns are wrapped in /…/ slashes with optional trailing flags (i = IGNORECASE, m = MULTILINE, x = EXTENDED) and applied via gsub.

Constant Summary collapse

DATA_DIR =
Pathname.new(__dir__).join("../../../data").expand_path
REGEX_LITERAL =

Regex literal: /body/flags where flags is optional (i, m, x).

%r{\A/(.*)/([imx]*)\z}m

Class Method Summary collapse

Class Method Details

.apply(code, flavor) ⇒ String

Apply update_codes substitutions for the given flavor.

Examples:

UpdateCodes.apply("IEC 60285-/1:1989", :iec)
# => "IEC 60285-1:1989"

Parameters:

  • code (String)

    identifier string to normalize

  • flavor (Symbol, String)

    flavor name (e.g., :iso, :iec, :ieee, :nist)

Returns:

  • (String)

    normalized identifier string



41
42
43
44
45
46
47
48
49
# File 'lib/pubid/core/update_codes.rb', line 41

def apply(code, flavor)
  codes = for_flavor(flavor)
  return code if codes.nil? || codes.empty?

  codes.each do |from, to|
    code = code.gsub(compile_pattern(from), to.to_s)
  end
  code
end

.compile_options(flags) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/pubid/core/update_codes.rb', line 79

def compile_options(flags)
  options = 0
  options |= Regexp::IGNORECASE if flags.include?("i")
  options |= Regexp::MULTILINE if flags.include?("m")
  options |= Regexp::EXTENDED if flags.include?("x")
  options
end

.compile_pattern(from) ⇒ Object

Compile a YAML key into a Regexp. Plain strings are anchored to the full line; regex literals support optional trailing flags.



72
73
74
75
76
77
# File 'lib/pubid/core/update_codes.rb', line 72

def compile_pattern(from)
  match = from.to_s.match(REGEX_LITERAL)
  return /^#{Regexp.escape(from.to_s)}$/ unless match

  Regexp.new(match[1], compile_options(match[2]))
end

.flavorsArray<Symbol>

Available flavors that have update_codes files.

Returns:

  • (Array<Symbol>)

    flavors with data/flavor/update_codes.yaml



64
65
66
67
68
# File 'lib/pubid/core/update_codes.rb', line 64

def flavors
  @flavors ||= DATA_DIR.children.select(&:directory?).map do |dir|
    dir.basename.to_s.to_sym
  end.select { |f| (DATA_DIR / f.to_s / "update_codes.yaml").exist? }
end

.for_flavor(flavor) ⇒ Hash?

Get the loaded update_codes hash for a flavor (cached).

Parameters:

  • flavor (Symbol, String)

    flavor name

Returns:

  • (Hash, nil)

    the YAML hash, or nil if file doesn’t exist



55
56
57
58
59
# File 'lib/pubid/core/update_codes.rb', line 55

def for_flavor(flavor)
  @cache ||= {}
  flavor_key = flavor.to_s.to_sym
  @cache[flavor_key] ||= load_yaml(flavor_key)
end