/vendor/plugins/blacklight/vendor/gems/marc-0.2.2/lib/marc/datafield.rb

https://github.com/bess/northwest-digital-archives · Ruby · 169 lines · 121 code · 11 blank · 37 comment · 4 complexity · b9b2ccce7baf7085d424f2370089d6ac MD5 · raw file

  1. require 'marc/subfield'
  2. require 'marc/record'
  3. module MARC
  4. # MARC records contain data fields, each of which has a tag,
  5. # indicators and subfields. Tags for data fields must be in
  6. # the range 010-999.
  7. # Accessor attributes: tag, indicator1, indicator2
  8. #
  9. # DataField mixes in Enumerable to enable access to it's constituent
  10. # Subfield objects. For instance, if you have a DataField representing
  11. # a 856 tag, and want to find all 'z' subfields:
  12. #
  13. # subfield_z = field.find_all {|subfield| subfield.code == 'z'}
  14. #
  15. # Also, the accessor 'subfields' is an array of MARC::Subfield objects
  16. # which can be accessed or modified by the client directly if
  17. # neccesary.
  18. class DataField
  19. include Enumerable
  20. # The tag for the field
  21. attr_accessor :tag
  22. # The first indicator
  23. attr_accessor :indicator1
  24. # The second indicator
  25. attr_accessor :indicator2
  26. # A list of MARC::Subfield objects
  27. attr_accessor :subfields
  28. # Create a new field with tag, indicators and subfields.
  29. # Subfields are passed in as comma separated list of
  30. # MARC::Subfield objects,
  31. #
  32. # field = MARC::DataField.new('245','0','0',
  33. # MARC::Subfield.new('a', 'Consilience :'),
  34. # MARC::Subfield.new('b', 'the unity of knowledge ',
  35. # MARC::Subfield.new('c', 'by Edward O. Wilson.'))
  36. #
  37. # or using a shorthand:
  38. #
  39. # field = MARC::DataField.new('245','0','0',
  40. # ['a', 'Consilience :'],['b','the unity of knowledge ',
  41. # ['c', 'by Edward O. Wilson.'] )
  42. def initialize(tag, i1=' ', i2=' ', *subfields)
  43. # if the tag is less than 3 characters long and
  44. # the string is all numeric then we pad with zeros
  45. if tag.length < 3 and /^[0-9]*$/ =~ tag
  46. @tag = "%03d" % tag
  47. else
  48. @tag = tag
  49. end
  50. # can't allow nil to be passed in or else it'll
  51. # screw us up later when we try to encode
  52. @indicator1 = i1 == nil ? ' ' : i1
  53. @indicator2 = i2 == nil ? ' ' : i2
  54. @subfields = []
  55. # must use MARC::ControlField for tags < 010
  56. if @tag.to_i < 10 and not @tag =~ /[A-z]/
  57. raise MARC::Exception.new(),
  58. "MARC::DataField objects can't have tags < 010"
  59. end
  60. # allows MARC::Subfield objects to be passed directly
  61. # or a shorthand of ['a','Foo'], ['b','Bar']
  62. subfields.each do |subfield|
  63. case subfield
  64. when MARC::Subfield
  65. @subfields.push(subfield)
  66. when Array
  67. if subfield.length > 2
  68. raise MARC::Exception.new(),
  69. "arrays must only have 2 elements"
  70. end
  71. @subfields.push(
  72. MARC::Subfield.new(subfield[0],subfield[1]))
  73. else
  74. raise MARC::Exception.new(),
  75. "invalid subfield type #{subfield.class}"
  76. end
  77. end
  78. end
  79. # Returns a string representation of the field such as:
  80. # 245 00 $aConsilience :$bthe unity of knowledge $cby Edward O. Wilson.
  81. def to_s
  82. str = "#{tag} "
  83. str += "#{indicator1}#{indicator2} "
  84. @subfields.each { |subfield| str += subfield.to_s }
  85. return str
  86. end
  87. # Add a subfield (MARC::Subfield) to the field
  88. # field.append(MARC::Subfield.new('a','Dave Thomas'))
  89. def append(subfield)
  90. @subfields.push(subfield)
  91. end
  92. # You can iterate through the subfields in a Field:
  93. # field.each {|s| print s}
  94. def each
  95. for subfield in subfields
  96. yield subfield
  97. end
  98. end
  99. # You can lookup subfields with this shorthand. Note it
  100. # will return a string and not a MARC::Subfield object.
  101. # subfield = field['a']
  102. def [](code)
  103. subfield = self.find {|s| s.code == code}
  104. return subfield.value if subfield
  105. return
  106. end
  107. # Two fields are equal if their tag, indicators and
  108. # subfields are all equal.
  109. def ==(other)
  110. if @tag != other.tag
  111. return false
  112. elsif @indicator1 != other.indicator1
  113. return false
  114. elsif @indicator2 != other.indicator2
  115. return false
  116. elsif @subfields != other.subfields
  117. return false
  118. end
  119. return true
  120. end
  121. # To support regex matching with fields
  122. #
  123. # if field =~ /Huckleberry/ ...
  124. def =~(regex)
  125. return self.to_s =~ regex
  126. end
  127. # to get the field as a string, without the tag and indicators
  128. # useful in situations where you want a legible version of the field
  129. #
  130. # print record['245'].value
  131. def value
  132. return(@subfields.map {|s| s.value} .join '')
  133. end
  134. end
  135. end