Class: Libis::Tools::Metadata::VarField

Inherits:
Object
  • Object
show all
Defined in:
lib/libis/tools/metadata/var_field.rb

Overview

Helper class implementing a variable field for MARC

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag, ind1, ind2) ⇒ VarField

Create new variable field with given tag and indicators

Parameters:

  • tag (String)

    tag

  • ind1 (String)

    first indicator. nil will be translated into empty string.

  • ind2 (String)

    second indicator. nil will be translated into empty string.



23
24
25
26
27
28
# File 'lib/libis/tools/metadata/var_field.rb', line 23

def initialize(tag, ind1, ind2)
  @tag = tag
  @ind1 = ind1 || ''
  @ind2 = ind2 || ''
  @subfield_data = Hash.new { |h, k| h[k] = Array.new   }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (private)

implementation for methods for retrieving subfield values

The methods start with a single character: the operation ‘f’ for retrieving only the first occurence of the subfield ‘a’ for retrieving all the subfield values for each of the given subfields if omitted, ‘f’ is assumed

Then a ‘_’ acts as a subdivider between the operation and the subfield(s). It must always be present, even if the operation is omitted.

The last past is a sequence of subfield codes that should be used for selecting the values. The order in which the subfields are listed is respected in the resulting array of values.

Examples:

t = VarField.new('100', '', '',
                 { 'a' => %w'Name NickName',
                   'b' => %w'LastName MaidenName',
                   'c' => %w'eMail',
                   '1' => %w'Age',
                   '9' => %w'Score'})

# >> 100##$aName$aNickName$bLastName$bMaidenName$ceMail$1Age$9Score <<

t._1ab => ['Age', 'Name', 'LastName']
# equivalent to: t.f_1av or t.fields('1ab')

t.a_9ab => ['Score', 'Name', 'NickName', 'LastName', 'MaidenName']
# equivalent to: t.fields_array('9ab')

Note that it is not possible to use a fieldspec for the sequence of subfield codes. Spaces and ‘-’ are not allowed in method calls. If you want this, use the #subfield(s) and #subfield(s)_array methods.



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/libis/tools/metadata/var_field.rb', line 209

def method_missing(name, *args)
  operation, subfields = name.to_s.split('_')
  assert(subfields.size > 0, 'need to specify at least one subfield')
  operation = 'f' if operation.empty?
  # convert subfield list to fieldspec
  subfields = subfields.split('').join(' ')
  case operation
    when 'f'
      if subfields.size > 1
        operation = :subfields
      else
        operation = :subfield
      end
    when 'a'
      if subfields.size > 1
        operation = :subfields_array
      else
        operation = :subfield_array
      end
    else
      throw "Unknown method invocation: '#{name}' with: #{args}"
  end
  send(operation, subfields)
end

Instance Attribute Details

#ind1Object (readonly)

Returns the value of attribute ind1.



15
16
17
# File 'lib/libis/tools/metadata/var_field.rb', line 15

def ind1
  @ind1
end

#ind2Object (readonly)

Returns the value of attribute ind2.



16
17
18
# File 'lib/libis/tools/metadata/var_field.rb', line 16

def ind2
  @ind2
end

#subfield_dataObject (readonly)

Returns the value of attribute subfield_data.



17
18
19
# File 'lib/libis/tools/metadata/var_field.rb', line 17

def subfield_data
  @subfield_data
end

#tagObject (readonly)

Returns the value of attribute tag.



14
15
16
# File 'lib/libis/tools/metadata/var_field.rb', line 14

def tag
  @tag
end

Instance Method Details

#add_subfield(name, value) ⇒ Object

Add subfield to variable field

Parameters:

  • name (String)

    subfield indicator without ‘$’

  • value (String)

    content of the subfield



33
34
35
# File 'lib/libis/tools/metadata/var_field.rb', line 33

def add_subfield(name, value)
  @subfield_data[name] << value
end

#dumpString

dump the contents

Returns:

  • (String)

    debug output to inspect the contents of the VarField



40
41
42
43
44
# File 'lib/libis/tools/metadata/var_field.rb', line 40

def dump
  output = "#{@tag}:#{@ind1}:#{@ind2}:\n"
  @subfield_data.each { |s, t| output += "\t#{s}:#{t}\n" }
  output
end

#dump_lineString

dump the contents

Returns:

  • (String)

    debug output to inspect the contents of the VarField - Single line version



49
50
51
52
53
# File 'lib/libis/tools/metadata/var_field.rb', line 49

def dump_line
  output = "#{@tag}:#{@ind1}:#{@ind2}:"
  @subfield_data.each { |s, t| output += "$#{s}#{t}" }
  output
end

#keysArray

list the subfield codes

Returns:

  • (Array)

    a list of all subfield codes



58
59
60
# File 'lib/libis/tools/metadata/var_field.rb', line 58

def keys
  @subfield_data.keys
end

#match(criteria) ⇒ String

check if the current VarField matches the given subfield criteria.

The subfield criteria consists of groups of characters. At least one of these groups should match for the test to succeed Within the group sets of codes may be divided by a hyphen (-). The first set of codes must all be present; the second set of codes must all not be present. Either set may be empty.

Examples:

'ab'      matches '$a...$b...'            => ['ab']
                  '$a...$b...$c...'       => ['ab']
          but not '$a...'                 => nil      # ($b missing)
                  '$b...'                 => nil      # ($a missing)
'a b'     matches '$a...'                 => ['a']
                  '$b...'                 => ['b']
                  '$a...$b...'            => ['a', 'b']
                  '$a...$b...$c...'       => ['a', 'b']
          but not '$c...'                 => nil      # ($a or $b must be present)
'abc-d'   matches '$a..,$b...$c...'       => ['abc-d']
                  '$a..,$b...$c...$e...'  => ['abc-d']
          but not '$a...$b...$e...'       => nil      # ($c missing)
                  '$a...$b...$c...$d...'  => nil      # ($d should not be present)
'a-b b-a' matches '$a...'                 => ['a-b']
                  '$a...$c...'            => ['a-b']
                  '$b...'                 => ['b-a']
                  '$b...$c...'            => ['b-a']
          but not '$a...$b...'            => nil
'a-b c-d' matches '$a...'                 => ['a-b']
                  '$a...$c...'            => ['a-b', 'c-d']
                  '$a...$b...$c...'       => ['c-d']
                  '$b...$c...'            => ['c-d']
          but not '$a...$b...'            => nil
                  '$c...$d...'            => nil
                  '$b...$c...$d...'       => nil
                  '$a...$b...$c...$d...'  => nil

Parameters:

  • criteria (String)

    subfield criteria: sequence of alternative set of subfield codes that should-shouldn’t be present

Returns:

  • (String)

    The matching part(s) of the criteria or nil if no match



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/libis/tools/metadata/var_field.rb', line 140

def match(criteria)
  begin
    parser = Libis::Tools::Metadata::SubfieldCriteriaParser.new
    tree = parser.parse(criteria)
    return [] if tree.is_a? String
    tree = [tree] unless tree.is_a? Array
    result = tree.map do |selection|
      next unless parser.match_selection(selection, keys)
      parser.selection_to_s(selection)
    end.compact
    return nil if result.empty?
    result
  rescue Parslet::ParseFailed => failure
    failure.cause.set_label(criteria)
    raise failure
  end
end

#subfield(s) ⇒ String

get the first (or only) subfield value for the given code

Parameters:

  • s (Character)

    the subfield code

Returns:

  • (String)

    the first or only entry of a subfield or nil if not present



66
67
68
# File 'lib/libis/tools/metadata/var_field.rb', line 66

def subfield(s)
  subfield_array(s).first
end

#subfield_array(s) ⇒ Array

get a list of all subfield values for a given code

Parameters:

  • s (Character)

    the subfield code

Returns:

  • (Array)

    all the entries of a repeatable subfield



74
75
76
77
# File 'lib/libis/tools/metadata/var_field.rb', line 74

def subfield_array(s)
  assert(s.is_a?(String) && (s =~ /^[\da-z]$/) == 0, 'method expects a lower case alphanumerical char')
  @subfield_data.has_key?(s) ? @subfield_data[s].dup : []
end

#subfields(s) ⇒ Array

get a list of the first subfield values for all the codes in the given string

The subfield codes are cleaned (see criteria_to_array)

Parameters:

  • s (String)

    subfield code specification (see match)

Returns:

  • (Array)

    list of the first or only entries of all subfield codes in the input string



85
86
87
88
89
# File 'lib/libis/tools/metadata/var_field.rb', line 85

def subfields(s)
  assert(s.is_a?(String), 'method expects a string')
  return [] unless (match_array = match(s))
  criteria_to_array(match_array.join(' ')).collect { |i| send(:subfield, i) }.flatten.compact
end

#subfields_array(s) ⇒ Array

get a list of all the subfield values for all the codes in the given string

The subfield codes are cleaned (see criteria_to_array)

Parameters:

  • s (String)

    subfield code criteria (see match)

Returns:

  • (Array)

    list of the all the entries of all subfield codes in the input string



98
99
100
101
102
# File 'lib/libis/tools/metadata/var_field.rb', line 98

def subfields_array(s)
  assert(s.is_a?(String), 'method expects a string')
  return [] unless (match_array = match(s))
  criteria_to_array(match_array.join(' ')).collect { |i| send(:subfield_array, i) }.flatten.compact
end