mods_display 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/README.md +10 -18
  4. data/app/components/mods_display/row_field_component.html.erb +11 -0
  5. data/app/components/mods_display/row_field_component.rb +43 -0
  6. data/app/helpers/mods_display/record_helper.rb +20 -0
  7. data/config/locales/en.yml +3 -0
  8. data/lib/mods_display/fields/access_condition.rb +5 -5
  9. data/lib/mods_display/fields/cartographics.rb +7 -9
  10. data/lib/mods_display/fields/collection.rb +14 -14
  11. data/lib/mods_display/fields/contact.rb +7 -7
  12. data/lib/mods_display/fields/contents.rb +5 -1
  13. data/lib/mods_display/fields/copyright_date.rb +9 -0
  14. data/lib/mods_display/fields/date_captured.rb +9 -0
  15. data/lib/mods_display/fields/date_created.rb +9 -0
  16. data/lib/mods_display/fields/date_issued.rb +9 -0
  17. data/lib/mods_display/fields/date_modified.rb +9 -0
  18. data/lib/mods_display/fields/date_other.rb +26 -0
  19. data/lib/mods_display/fields/date_valid.rb +9 -0
  20. data/lib/mods_display/fields/description.rb +6 -3
  21. data/lib/mods_display/fields/edition.rb +22 -0
  22. data/lib/mods_display/fields/extent.rb +4 -4
  23. data/lib/mods_display/fields/field.rb +54 -8
  24. data/lib/mods_display/fields/form.rb +4 -4
  25. data/lib/mods_display/fields/frequency.rb +19 -0
  26. data/lib/mods_display/fields/genre.rb +5 -2
  27. data/lib/mods_display/fields/geo.rb +2 -2
  28. data/lib/mods_display/fields/identifier.rb +5 -2
  29. data/lib/mods_display/fields/imprint.rb +13 -36
  30. data/lib/mods_display/fields/issuance.rb +19 -0
  31. data/lib/mods_display/fields/language.rb +4 -4
  32. data/lib/mods_display/fields/location.rb +5 -5
  33. data/lib/mods_display/fields/name.rb +8 -7
  34. data/lib/mods_display/fields/nested_related_item.rb +45 -37
  35. data/lib/mods_display/fields/note.rb +10 -7
  36. data/lib/mods_display/fields/place.rb +35 -0
  37. data/lib/mods_display/fields/publisher.rb +21 -0
  38. data/lib/mods_display/fields/reference_title.rb +30 -0
  39. data/lib/mods_display/fields/related_item.rb +59 -40
  40. data/lib/mods_display/fields/resource_type.rb +7 -4
  41. data/lib/mods_display/fields/subject.rb +3 -3
  42. data/lib/mods_display/fields/title.rb +46 -30
  43. data/lib/mods_display/fields/values.rb +1 -0
  44. data/lib/mods_display/html.rb +25 -10
  45. data/lib/mods_display/version.rb +1 -1
  46. data/lib/mods_display.rb +13 -0
  47. data/mods_display.gemspec +1 -1
  48. metadata +21 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd385f9d4aea6c14524378831877c327c6fdfd2664356e148b457af9c26a5623
4
- data.tar.gz: b66857f71c766dc6edb03b8783d1d63486e94c63c8e9a71a0474f6b5a11d44cc
3
+ metadata.gz: 4152dce7ec61d92e04a5cddf9c5c152c414eeb725c05b975be1ec66eeadc2fa7
4
+ data.tar.gz: '087502061c3666fe0b4eec7c00a2a93e9532610cb4b35d7de6555a3dd7d2a8c8'
5
5
  SHA512:
6
- metadata.gz: 6b4760e8eee0c1eef22badaf5087b4095c4c88766c3b128bbaa1e841e2b1aa34294ced0be7199875b6aa57cdf1b3385dd5c11d624f4ce818afcc7fa4f1da25ab
7
- data.tar.gz: 93c93c4249b55816c9716b1c632d0b4c5b5a2874365e33139fbbf6cd9421f01d3aa9800d347c72ae7837bcf98ef763650e8151a3cab547cecb287a72ff7a9ace
6
+ metadata.gz: 1843e6a4f59a79c0f54f757e9c99820af6235681eea8a2c494bb40a6291db2f0408b6af26a6b8541bd91348cd1572c87329e510c12713df2afe9e72aea1a6baa
7
+ data.tar.gz: b4f433ae7fe636d51b92222cf64e8cbabdadcdc3aca05333165d9f0699957a59f94a4d254efad3e43e908f2b8991d12d7e70a652cdd10b15e639a7317b98d889
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # ModsDisplay
2
2
 
3
- A gem for displaying MODS Metadata in a configurable way.
3
+ A gem for displaying MODS Metadata in a configurable way.
4
+
5
+ This gem is used to centralize the display logic of MODS metadata by creating html fragments such as
6
+
7
+ ```
8
+ <dt>Publisher</dt>
9
+ <dd>Diagon Alley Publications</dd>
10
+ ```
11
+
12
+ which can be styled in consuming apps such as SearchWorks or Exhibits.
4
13
 
5
14
  ## Demo
6
15
 
@@ -20,23 +29,6 @@ Or install it yourself as:
20
29
 
21
30
  $ gem install mods_display
22
31
 
23
- ## Release/Upgrade Notes
24
-
25
- #### v0.5.0
26
- There are three major changes in this version.
27
-
28
- 1. RelatedItem nodes with a type of `constituent` or `host` are now treated separately and will render the full MODS display of any nested metadata. If accessing the `ModsDisplay::Values` directly through their accessors (e.g. custom grouping), this new metadata is available under `.nested_related_items`.
29
- * _**Note:** You may want to style and add some javascript toggling behavior (see exhibits for an example)._
30
- 2. Name nodes are now grouped/labeled by their role. If you were iterating over the names and splitting them out by their labels, that will need to change.
31
- 3. Table of contents/Summaries are now split on `--` and rendered as an unordered list.
32
- * _**Note:** You may want to style this list._
33
-
34
- #### v0.3.0
35
-
36
- Labels now have internationalization support. We have added colons to the english labels due to certain languages' punctuation rules requiring different spacing between the label and colon.
37
-
38
- Given that fact, you will want to update any pre 0.3.0 code that searches for elements by label in a way that would fail with the presence of a colon.
39
-
40
32
  ## Contributing
41
33
 
42
34
  1. Fork it
@@ -0,0 +1,11 @@
1
+ <% values.each do |value| %>
2
+ <tr>
3
+ <% if label %>
4
+ <%= tag.th label, **label_html_attributes %>
5
+ <% end %>
6
+
7
+ <%= tag.td **value_html_attributes do %>
8
+ <%= value %>
9
+ <% end %>
10
+ </tr>
11
+ <% end %>
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class RowFieldComponent < ViewComponent::Base
5
+ with_collection_parameter :field
6
+
7
+ def initialize(field:, delimiter: nil, label_html_attributes: {}, value_html_attributes: {}, value_transformer: nil)
8
+ super
9
+
10
+ @field = field
11
+ @delimiter = delimiter
12
+ @value_transformer = value_transformer
13
+ @label_html_attributes = label_html_attributes
14
+ @value_html_attributes = value_html_attributes
15
+ end
16
+
17
+ attr_reader :field, :delimiter, :label_html_attributes, :value_html_attributes
18
+
19
+ def render?
20
+ field.values.any?(&:present?)
21
+ end
22
+
23
+ def format_value(value)
24
+ if @value_transformer
25
+ @value_transformer.call(value)
26
+ else
27
+ helpers.format_mods_html(value, field: field)
28
+ end
29
+ end
30
+
31
+ def values
32
+ if delimiter
33
+ [safe_join(field.values.select(&:present?).map { |value| format_value(value) }, delimiter)]
34
+ else
35
+ field.values.select(&:present?).map { |value| format_value(value) }
36
+ end
37
+ end
38
+
39
+ def label
40
+ field.label&.sub(/:$/, '')
41
+ end
42
+ end
43
+ end
@@ -17,6 +17,14 @@ module ModsDisplay
17
17
  render component.new(field: field, delimiter: delimiter, value_transformer: block)
18
18
  end
19
19
 
20
+ def mods_record_definition_field(field, delimiter: nil, label_html_attributes: {}, &block)
21
+ render ModsDisplay::FieldComponent.new(field: field, delimiter: delimiter, label_html_attributes: label_html_attributes, value_transformer: block)
22
+ end
23
+
24
+ def mods_record_row_field(field, delimiter: ', ', &block)
25
+ render ModsDisplay::RowFieldComponent.new(field: field, delimiter: delimiter, value_transformer: block)
26
+ end
27
+
20
28
  # this returns a role's label and the display names for ModsDisplay:Name:Person
21
29
  def mods_name_field(field)
22
30
  mods_record_field(field) do |name|
@@ -41,12 +49,24 @@ module ModsDisplay
41
49
  end
42
50
  end
43
51
 
52
+ def mods_subject_row_field(field, delimiter: nil, &block)
53
+ mods_record_row_field(field, delimiter: delimiter) do |subject_line|
54
+ safe_join(link_mods_subjects(subject_line, &block), ' > ')
55
+ end
56
+ end
57
+
44
58
  def mods_genre_field(field, &block)
45
59
  mods_record_field(field) do |genre_line|
46
60
  link_to_mods_subject(genre_line, &block)
47
61
  end
48
62
  end
49
63
 
64
+ def mods_genre_row_field(field, delimiter: nil, &block)
65
+ mods_record_row_field(field, delimiter: delimiter) do |genre_line|
66
+ link_to_mods_subject(genre_line, &block)
67
+ end
68
+ end
69
+
50
70
  # @private
51
71
  def link_mods_genres(genre, &block)
52
72
  link_buffer = []
@@ -17,11 +17,14 @@ en:
17
17
  creation_production_credits: "Creation/Production credits:"
18
18
  date_captured: "Date captured:"
19
19
  date_created: "Date created:"
20
+ date_issued: "Publication date:"
20
21
  date_modified: "Date modified:"
22
+ date_other: "Other date:"
21
23
  date_sequential_designation: "Date/Sequential designation:"
22
24
  date_valid: "Date valid:"
23
25
  digital_origin: "Digital origin:"
24
26
  doi: "DOI:"
27
+ edition: "Edition:"
25
28
  extent: "Extent:"
26
29
  form: "Form:"
27
30
  frequency: "Frequency:"
@@ -51,10 +51,10 @@ module ModsDisplay
51
51
  }.freeze
52
52
 
53
53
  def fields
54
- return_fields = @values.map do |value|
54
+ return_fields = @stanford_mods_elements.map do |stanford_mods_element|
55
55
  ModsDisplay::Values.new(
56
- label: displayLabel(value) || access_label(value),
57
- values: [process_access_statement(value)],
56
+ label: displayLabel(stanford_mods_element) || access_label(stanford_mods_element),
57
+ values: [process_access_statement(stanford_mods_element)],
58
58
  field: self
59
59
  )
60
60
  end
@@ -85,7 +85,7 @@ module ModsDisplay
85
85
  def license_statement(element)
86
86
  element_text = element_text(element)
87
87
  legacy_matches = element_text.match(/^(?<code>.*) (?<type>.*):(?<description>.*)$/)
88
- return legacy_license_statement(element, legacy_matches) if legacy_matches
88
+ return legacy_license_statement(legacy_matches) if legacy_matches
89
89
 
90
90
  matches = element_text.match(/^This work is licensed under a (.+?)\.$/)
91
91
  return linked_licensed_statement(element, matches) if matches && element['xlink:href'].present?
@@ -97,7 +97,7 @@ module ModsDisplay
97
97
  "This work is licensed under a <a href='#{element['xlink:href']}'>#{matches[1]}</a>."
98
98
  end
99
99
 
100
- def legacy_license_statement(_element, matches)
100
+ def legacy_license_statement(matches)
101
101
  code = matches[:code].downcase
102
102
  type = matches[:type].downcase
103
103
  description = license_description(code, type) || matches[:description]
@@ -3,22 +3,20 @@
3
3
  module ModsDisplay
4
4
  class Cartographics < Field
5
5
  def fields
6
- return nil if @values.nil?
6
+ return nil if @stanford_mods_elements.nil?
7
7
 
8
8
  return_fields = []
9
- @values.each do |value|
10
- next unless value.respond_to?(:cartographics)
9
+ @stanford_mods_elements.each do |subject_element|
10
+ next unless subject_element.respond_to?(:cartographics)
11
11
 
12
- value.cartographics.each do |field|
12
+ subject_element.cartographics.each do |field|
13
13
  scale = field.scale.empty? ? 'Scale not given' : element_text(field.scale)
14
14
  projection = field.projection.empty? ? nil : element_text(field.projection)
15
15
  coordinates = field.coordinates.empty? ? nil : element_text(field.coordinates)
16
- post_scale = if [projection,
17
- coordinates].compact.length.positive?
18
- [projection, coordinates].compact.join(' ')
19
- end
16
+ post_scale = [projection, coordinates].compact.join(' ') if [projection, coordinates].compact.length.positive?
17
+
20
18
  return_fields << ModsDisplay::Values.new(
21
- label: (displayLabel(field) || label || I18n.t('mods_display.map_data')),
19
+ label: displayLabel(field) || label || I18n.t('mods_display.map_data'),
22
20
  values: [[scale, post_scale].compact.join(' ; ')]
23
21
  )
24
22
  end
@@ -5,18 +5,18 @@ module ModsDisplay
5
5
  # Collection class to parse collection data out of Mods relatedItem fields
6
6
  ###
7
7
  class Collection < Field
8
- def collection_label(value)
9
- displayLabel(value) || I18n.t('mods_display.collection')
8
+ def collection_label(related_item_element)
9
+ displayLabel(related_item_element) || I18n.t('mods_display.collection')
10
10
  end
11
11
 
12
12
  def fields
13
13
  return_fields = []
14
- @values.each do |value|
15
- next unless related_item_is_a_collection?(value)
14
+ @stanford_mods_elements.each do |related_item_element|
15
+ next unless related_item_is_a_collection?(related_item_element)
16
16
 
17
17
  return_fields << ModsDisplay::Values.new(
18
- label: collection_label(value),
19
- values: [element_text(value.titleInfo)]
18
+ label: collection_label(related_item_element),
19
+ values: [element_text(related_item_element.titleInfo)]
20
20
  )
21
21
  end
22
22
  collapse_fields(return_fields)
@@ -24,17 +24,17 @@ module ModsDisplay
24
24
 
25
25
  private
26
26
 
27
- def related_item_is_a_collection?(value)
28
- value.respond_to?(:titleInfo) && resource_type_is_collection?(value)
27
+ def related_item_is_a_collection?(related_item_element)
28
+ related_item_element.respond_to?(:titleInfo) && resource_type_is_collection?(related_item_element)
29
29
  end
30
30
 
31
- def resource_type_is_collection?(value)
32
- return false unless value.respond_to?(:typeOfResource)
33
- return false unless value.typeOfResource.attributes.length.positive?
31
+ def resource_type_is_collection?(related_item_element)
32
+ return false unless related_item_element.respond_to?(:typeOfResource)
33
+ return false unless related_item_element.typeOfResource.attributes.length.positive?
34
34
 
35
- value.typeOfResource.attributes.length.positive? &&
36
- value.typeOfResource.attributes.first.key?('collection') &&
37
- value.typeOfResource.attributes.first['collection'].value == 'yes'
35
+ related_item_element.typeOfResource.attributes.length.positive? &&
36
+ related_item_element.typeOfResource.attributes.first.key?('collection') &&
37
+ related_item_element.typeOfResource.attributes.first['collection'].value == 'yes'
38
38
  end
39
39
  end
40
40
  end
@@ -3,10 +3,10 @@
3
3
  module ModsDisplay
4
4
  class Contact < Field
5
5
  def fields
6
- return_fields = contact_fields.map do |value|
6
+ return_fields = contact_elements.map do |contact_element|
7
7
  ModsDisplay::Values.new(
8
- label: displayLabel(value) || I18n.t('mods_display.contact'),
9
- values: [element_text(value)]
8
+ label: displayLabel(contact_element) || I18n.t('mods_display.contact'),
9
+ values: [element_text(contact_element)]
10
10
  )
11
11
  end
12
12
  collapse_fields(return_fields)
@@ -14,10 +14,10 @@ module ModsDisplay
14
14
 
15
15
  private
16
16
 
17
- def contact_fields
18
- @values.select do |value|
19
- value.attributes['type'].respond_to?(:value) &&
20
- value.attributes['type'].value.downcase == 'contact'
17
+ def contact_elements
18
+ @stanford_mods_elements.select do |note_element|
19
+ note_element.attributes['type'].respond_to?(:value) &&
20
+ note_element.attributes['type'].value.downcase == 'contact'
21
21
  end
22
22
  end
23
23
  end
@@ -4,7 +4,11 @@ module ModsDisplay
4
4
  class Contents < Field
5
5
  def to_html(view_context = ApplicationController.renderer)
6
6
  f = fields.map do |field|
7
- ModsDisplay::Values.new(label: field.label, values: [field.values.join("\n\n")], field: self)
7
+ ModsDisplay::Values.new(
8
+ label: field.label,
9
+ values: [field.values.join("\n\n")],
10
+ field: self
11
+ )
8
12
  end
9
13
 
10
14
  helpers = view_context.respond_to?(:simple_format) ? view_context : ApplicationController.new.view_context
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class CopyrightDate < Field
5
+ def fields
6
+ date_fields(:copyrightDate)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateCaptured < Field
5
+ def fields
6
+ date_fields(:dateCaptured)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateCreated < Field
5
+ def fields
6
+ date_fields(:dateCreated)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateIssued < Field
5
+ def fields
6
+ date_fields(:dateIssued)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateModified < Field
5
+ def fields
6
+ date_fields(:dateModified)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateOther < Field
5
+ def fields
6
+ date_fields(:dateOther)
7
+ end
8
+
9
+ private
10
+
11
+ # this is called from the Field.select_best_date method
12
+ # @param date [Stanford::Mods::Imprint::Date]
13
+ def qualified_value_with_type(date)
14
+ type = type_attribute_value(date)
15
+ type ? "#{date.qualified_value} (#{type})" : date.qualified_value
16
+ end
17
+
18
+ def type_attribute_value(date)
19
+ if date.is_a?(Stanford::Mods::Imprint::DateRange)
20
+ date.start.value.type || date.stop.value.type
21
+ else
22
+ date.value.type
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class DateValid < Field
5
+ def fields
6
+ date_fields(:dateValid)
7
+ end
8
+ end
9
+ end
@@ -3,8 +3,11 @@
3
3
  module ModsDisplay
4
4
  class Description < Field
5
5
  def fields
6
- return_fields = description_fields.map do |value|
7
- ModsDisplay::Values.new(label: description_label(value), values: [element_text(value)])
6
+ return_fields = description_fields.map do |element|
7
+ ModsDisplay::Values.new(
8
+ label: description_label(element),
9
+ values: [element_text(element)]
10
+ )
8
11
  end
9
12
  collapse_fields(return_fields)
10
13
  end
@@ -16,7 +19,7 @@ module ModsDisplay
16
19
  private
17
20
 
18
21
  def description_fields
19
- @values.children.select do |child|
22
+ @stanford_mods_elements.children.select do |child|
20
23
  labels.keys.include?(child.name.to_sym)
21
24
  end
22
25
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class Edition < Field
5
+ def fields
6
+ return_fields = @stanford_mods_elements.map do |origin_info_element|
7
+ edition_value = Stanford::Mods::Imprint.new(origin_info_element).edition_vals_str
8
+ next unless edition_value.present?
9
+
10
+ # remove trailing spaces (thanks MARC, for catalog card formatting!)
11
+ edition_value.gsub!(%r{ */$}, '')
12
+
13
+ ModsDisplay::Values.new(
14
+ label: I18n.t('mods_display.edition'),
15
+ values: [edition_value],
16
+ field: self
17
+ )
18
+ end.compact
19
+ collapse_fields(return_fields)
20
+ end
21
+ end
22
+ end
@@ -3,20 +3,20 @@
3
3
  module ModsDisplay
4
4
  class Extent < Field
5
5
  def fields
6
- return [] unless extent_fields.present?
6
+ return [] unless extent_elements.present?
7
7
 
8
8
  [
9
9
  ModsDisplay::Values.new(
10
10
  label: I18n.t('mods_display.extent'),
11
- values: extent_fields.map { |x| element_text(x) }
11
+ values: extent_elements.map { |x| element_text(x) }
12
12
  )
13
13
  ]
14
14
  end
15
15
 
16
16
  private
17
17
 
18
- def extent_fields
19
- @values.map(&:extent).flatten
18
+ def extent_elements
19
+ @stanford_mods_elements.map(&:extent).flatten
20
20
  end
21
21
  end
22
22
  end
@@ -1,16 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ModsDisplay
4
+ # superclass for processing stanford-mods elements into ModsDisplay::Values retrieved by the fields method
5
+ # by consuming applications.
4
6
  class Field
5
- def initialize(values)
6
- @values = values
7
+ # @stanford_mods_elements is an array of Nokogiri::XML::Element-ish objects from stanford-mods
8
+ # per ModsDisplay::HTML::MODS_DISPLAY_FIELD_MAPPING
9
+ def initialize(stanford_mods_elements)
10
+ @stanford_mods_elements = stanford_mods_elements
7
11
  end
8
12
 
9
13
  def fields
10
- return_fields = @values.map do |value|
14
+ return_fields = @stanford_mods_elements.map do |stanford_mods_element|
11
15
  ModsDisplay::Values.new(
12
- label: displayLabel(value) || label,
13
- values: [element_text(value)],
16
+ label: displayLabel(stanford_mods_element) || label,
17
+ values: [element_text(stanford_mods_element)],
14
18
  field: self
15
19
  )
16
20
  end
@@ -18,9 +22,9 @@ module ModsDisplay
18
22
  end
19
23
 
20
24
  def label
21
- return nil if @values.nil?
25
+ return nil if @stanford_mods_elements.nil?
22
26
 
23
- displayLabel(@values.first)
27
+ displayLabel(@stanford_mods_elements.first)
24
28
  end
25
29
 
26
30
  def to_html(view_context = ApplicationController.renderer)
@@ -50,12 +54,54 @@ module ModsDisplay
50
54
  display_fields.slice_when { |before, after| before.label != after.label }.map do |group|
51
55
  next group.first if group.length == 1
52
56
 
53
- ModsDisplay::Values.new(label: group.first.label, values: group.map(&:values).flatten(1))
57
+ ModsDisplay::Values.new(
58
+ label: group.first.label,
59
+ values: group.map(&:values).flatten(1)
60
+ )
54
61
  end
55
62
  end
56
63
 
57
64
  def element_text(element)
58
65
  element.xpath('.//text()').to_html.strip
59
66
  end
67
+
68
+ # used for originInfo date fields, e.g. DateCreated, DateIssued ...
69
+ def date_fields(date_symbol)
70
+ return_fields = @stanford_mods_elements.map do |origin_info_element|
71
+ date_values = Stanford::Mods::Imprint.new(origin_info_element).dates([date_symbol])
72
+ next unless date_values.present?
73
+
74
+ ModsDisplay::Values.new(
75
+ label: I18n.t("mods_display.#{date_symbol.to_s.underscore}"),
76
+ values: select_best_date(date_values),
77
+ field: self
78
+ )
79
+ end.compact
80
+ collapse_fields(return_fields)
81
+ end
82
+
83
+ # used for originInfo dates, e.g. for Imprint, DateCreated, DateIssued, etc.
84
+ def select_best_date(dates)
85
+ # ensure dates are unique with respect to their base values
86
+ dates = dates.group_by(&:base_value).map do |_value, group|
87
+ group.first if group.one?
88
+
89
+ # if one of the duplicates wasn't encoded, use that one (see:
90
+ # https://consul.stanford.edu/display/chimera/MODS+display+rules#MODSdisplayrules-3b.%3CoriginInfo%3E),
91
+ # otherwise just randomly pick the last in the group
92
+ group.reject(&:encoding).first || group.last
93
+ end
94
+
95
+ # if any single dates are already part of a range, discard them
96
+ range_base_values = dates.select { |date| date.is_a?(Stanford::Mods::Imprint::DateRange) }
97
+ .map(&:base_values).flatten
98
+ dates = dates.reject { |date| range_base_values.include?(date.base_value) }
99
+
100
+ # for DateOther field (but not for Imprint field), include the type attribute value in parens
101
+ return dates.map { |date| qualified_value_with_type(date) } if instance_of?(ModsDisplay::DateOther)
102
+
103
+ # output formatted dates with qualifiers, CE/BCE, etc.
104
+ dates.map(&:qualified_value)
105
+ end
60
106
  end
61
107
  end
@@ -3,20 +3,20 @@
3
3
  module ModsDisplay
4
4
  class Form < Field
5
5
  def fields
6
- return [] unless form_fields.present?
6
+ return [] unless form_elements.present?
7
7
 
8
8
  [
9
9
  ModsDisplay::Values.new(
10
10
  label: I18n.t('mods_display.form'),
11
- values: form_fields.map { |x| element_text(x) }.uniq { |x| x.downcase.gsub(/\s/, '').gsub(/[[:punct:]]/, '') }
11
+ values: form_elements.map { |x| element_text(x) }.uniq { |x| x.downcase.gsub(/\s/, '').gsub(/[[:punct:]]/, '') }
12
12
  )
13
13
  ]
14
14
  end
15
15
 
16
16
  private
17
17
 
18
- def form_fields
19
- @values.map(&:form).flatten
18
+ def form_elements
19
+ @stanford_mods_elements.map(&:form).flatten
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ class Frequency < Field
5
+ def fields
6
+ return_fields = @stanford_mods_elements.map do |origin_info_element|
7
+ frequency_value = origin_info_element.frequency&.text&.strip
8
+ next unless frequency_value.present?
9
+
10
+ ModsDisplay::Values.new(
11
+ label: I18n.t('mods_display.frequency'),
12
+ values: [frequency_value],
13
+ field: self
14
+ )
15
+ end.compact
16
+ collapse_fields(return_fields)
17
+ end
18
+ end
19
+ end
@@ -3,8 +3,11 @@
3
3
  module ModsDisplay
4
4
  class Genre < Field
5
5
  def fields
6
- return_fields = @values.map do |value|
7
- ModsDisplay::Values.new(label: displayLabel(value) || label, values: [element_text(value).capitalize].flatten)
6
+ return_fields = @stanford_mods_elements.map do |genre_element|
7
+ ModsDisplay::Values.new(
8
+ label: displayLabel(genre_element) || label,
9
+ values: [element_text(genre_element).capitalize].flatten
10
+ )
8
11
  end
9
12
  collapse_fields(return_fields)
10
13
  end
@@ -25,8 +25,8 @@ module ModsDisplay
25
25
  end
26
26
 
27
27
  def geo_extensions
28
- @geo_values ||= @values.select do |value|
29
- displayLabel(value) =~ /^geo:?$/
28
+ @geo_values ||= @stanford_mods_elements.select do |extension_element|
29
+ displayLabel(extension_element) =~ /^geo:?$/
30
30
  end
31
31
  end
32
32
  end