mods_display 1.0.0.alpha3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +42 -0
  3. data/.rubocop_todo.yml +72 -401
  4. data/Gemfile +4 -1
  5. data/Rakefile +8 -6
  6. data/app/components/mods_display/field_component.rb +2 -0
  7. data/app/components/mods_display/list_field_component.rb +2 -0
  8. data/app/components/mods_display/record_component.rb +2 -0
  9. data/app/helpers/mods_display/record_helper.rb +4 -7
  10. data/app/models/mods_display/record.rb +2 -1
  11. data/config.ru +2 -2
  12. data/lib/mods_display/country_codes.rb +2 -1
  13. data/lib/mods_display/fields/abstract.rb +2 -0
  14. data/lib/mods_display/fields/access_condition.rb +12 -12
  15. data/lib/mods_display/fields/audience.rb +2 -0
  16. data/lib/mods_display/fields/cartographics.rb +8 -1
  17. data/lib/mods_display/fields/collection.rb +6 -2
  18. data/lib/mods_display/fields/contact.rb +2 -0
  19. data/lib/mods_display/fields/contents.rb +2 -0
  20. data/lib/mods_display/fields/description.rb +3 -2
  21. data/lib/mods_display/fields/extent.rb +3 -0
  22. data/lib/mods_display/fields/field.rb +6 -9
  23. data/lib/mods_display/fields/form.rb +3 -0
  24. data/lib/mods_display/fields/genre.rb +2 -0
  25. data/lib/mods_display/fields/geo.rb +5 -2
  26. data/lib/mods_display/fields/identifier.rb +20 -17
  27. data/lib/mods_display/fields/imprint.rb +168 -217
  28. data/lib/mods_display/fields/language.rb +5 -1
  29. data/lib/mods_display/fields/location.rb +4 -1
  30. data/lib/mods_display/fields/name.rb +35 -19
  31. data/lib/mods_display/fields/nested_related_item.rb +18 -2
  32. data/lib/mods_display/fields/note.rb +9 -7
  33. data/lib/mods_display/fields/related_item.rb +12 -9
  34. data/lib/mods_display/fields/resource_type.rb +2 -0
  35. data/lib/mods_display/fields/sub_title.rb +2 -0
  36. data/lib/mods_display/fields/subject.rb +17 -50
  37. data/lib/mods_display/fields/title.rb +37 -26
  38. data/lib/mods_display/fields/values.rb +2 -0
  39. data/lib/mods_display/html.rb +4 -3
  40. data/lib/mods_display/related_item_concerns.rb +4 -2
  41. data/lib/mods_display/relator_codes.rb +2 -0
  42. data/lib/mods_display/version.rb +3 -1
  43. data/lib/mods_display.rb +5 -3
  44. data/mods_display.gemspec +1 -1
  45. metadata +14 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class RecordComponent < ViewComponent::Base
3
5
  DEFAULT_FIELDS = [
@@ -15,7 +15,7 @@ module ModsDisplay
15
15
  render component.new(field: field, delimiter: delimiter, value_transformer: block)
16
16
  end
17
17
 
18
- def mods_name_field(field, &block)
18
+ def mods_name_field(field)
19
19
  mods_record_field(field) do |name|
20
20
  block_given? ? capture { yield(name.name) } : name.name
21
21
  end
@@ -55,15 +55,13 @@ module ModsDisplay
55
55
  link_buffer = []
56
56
  linked_subjects = []
57
57
  subjects.each do |subject|
58
- if subject.present?
59
- linked_subjects << link_to_mods_subject(subject, link_buffer, &block)
60
- end
58
+ linked_subjects << link_to_mods_subject(subject, link_buffer, &block) if subject.present?
61
59
  end
62
60
  linked_subjects
63
61
  end
64
62
 
65
63
  # @private
66
- def link_to_mods_subject(subject, buffer = [], &block)
64
+ def link_to_mods_subject(subject, buffer = [])
67
65
  subject_text = subject.respond_to?(:name) ? subject.name : subject
68
66
  link = block_given? ? capture { yield(subject_text, buffer) } : subject_text
69
67
  buffer << subject_text.strip
@@ -73,7 +71,7 @@ module ModsDisplay
73
71
 
74
72
  # rubocop:disable Layout/LineLength
75
73
  # @private, but used in PURL currently
76
- def link_urls_and_email(val, tags: %w[a dl dd dt i b em strong])
74
+ def link_urls_and_email(val, tags: %w[a dl dd dt i b em strong br])
77
75
  val = val.gsub(%r{<[^/> ]+}) do |possible_tag|
78
76
  # Allow potentially valid HTML tags through to the sanitizer step, and HTML escape the rest
79
77
  if tags.include? possible_tag[1..]
@@ -101,6 +99,5 @@ module ModsDisplay
101
99
  sanitize val, tags: tags, attributes: %w[href]
102
100
  end
103
101
  # rubocop:enable Layout/LineLength
104
-
105
102
  end
106
103
  end
@@ -14,7 +14,8 @@ module ModsDisplay
14
14
 
15
15
  def mods_record
16
16
  return if xml.nil?
17
- @mods_record ||= Stanford::Mods::Record.new.tap { |mods| mods.from_str(xml, false) }
17
+
18
+ @mods_record ||= Stanford::Mods::Record.new.tap { |mods| mods.from_str(xml) }
18
19
  end
19
20
 
20
21
  def mods_display_html
data/config.ru CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rubygems"
4
- require "bundler"
3
+ require 'rubygems'
4
+ require 'bundler'
5
5
 
6
6
  Bundler.require :default, :development
7
7
 
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module ModsDisplay
3
4
  module CountryCodes
4
5
  def country_codes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Abstract < Field
3
5
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class AccessCondition < Field
3
5
  LICENSES = {
@@ -82,19 +84,16 @@ module ModsDisplay
82
84
  def license_statement(element)
83
85
  matches = element.text.match(/^(?<code>.*) (?<type>.*):(?<description>.*)$/)
84
86
 
85
- return "<div>#{element.text}</div>" unless matches
87
+ return element.text unless matches
86
88
 
87
89
  code = matches[:code].downcase
88
90
  type = matches[:type].downcase
89
91
  description = license_description(code, type) || matches[:description]
90
92
  url = license_url(code, type)
91
- output = "<div class='#{code}-#{type}'>"
92
- output << if url
93
- "<a href='#{url}'>#{description}</a>"
94
- else
95
- description
96
- end
97
- output << '</div>'
93
+
94
+ return "<a href='#{url}'>#{description}</a>" if url
95
+
96
+ description
98
97
  end
99
98
 
100
99
  def license_url(code, type)
@@ -114,21 +113,22 @@ module ModsDisplay
114
113
  def access_label(element)
115
114
  type = normalize_type(element)
116
115
  return access_labels[type] if access_labels.key?(type)
116
+
117
117
  I18n.t('mods_display.access_condition')
118
118
  end
119
119
 
120
120
  def normalize_type(element)
121
121
  type = element.attributes['type']
122
122
  return type.value.strip.gsub(/\s*/, '').downcase if type.respond_to?(:value)
123
+
123
124
  ''
124
125
  end
125
126
 
126
127
  def access_labels
127
- { 'useandreproduction' => I18n.t('mods_display.use_and_reproduction'),
128
+ { 'useandreproduction' => I18n.t('mods_display.use_and_reproduction'),
128
129
  'restrictiononaccess' => I18n.t('mods_display.restriction_on_access'),
129
- 'copyright' => I18n.t('mods_display.copyright'),
130
- 'license' => I18n.t('mods_display.license')
131
- }
130
+ 'copyright' => I18n.t('mods_display.copyright'),
131
+ 'license' => I18n.t('mods_display.license') }
132
132
  end
133
133
  end
134
134
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Audience < Field
3
5
  private
@@ -1,15 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Cartographics < Field
3
5
  def fields
4
6
  return nil if @values.nil?
7
+
5
8
  return_fields = []
6
9
  @values.each do |value|
7
10
  next unless value.respond_to?(:cartographics)
11
+
8
12
  value.cartographics.each do |field|
9
13
  scale = field.scale.empty? ? 'Scale not given' : field.scale.text
10
14
  projection = field.projection.empty? ? nil : field.projection.text
11
15
  coordinates = field.coordinates.empty? ? nil : field.coordinates.text
12
- post_scale = [projection, coordinates].compact.length > 0 ? [projection, coordinates].compact.join(' ') : nil
16
+ post_scale = if [projection,
17
+ coordinates].compact.length.positive?
18
+ [projection, coordinates].compact.join(' ')
19
+ end
13
20
  return_fields << ModsDisplay::Values.new(
14
21
  label: (displayLabel(field) || label || I18n.t('mods_display.map_data')),
15
22
  values: [[scale, post_scale].compact.join(' ; ')]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  ###
3
5
  # Collection class to parse collection data out of Mods relatedItem fields
@@ -11,6 +13,7 @@ module ModsDisplay
11
13
  return_fields = []
12
14
  @values.each do |value|
13
15
  next unless related_item_is_a_collection?(value)
16
+
14
17
  return_fields << ModsDisplay::Values.new(
15
18
  label: collection_label(value),
16
19
  values: [value.titleInfo.text.strip]
@@ -27,8 +30,9 @@ module ModsDisplay
27
30
 
28
31
  def resource_type_is_collection?(value)
29
32
  return unless value.respond_to?(:typeOfResource)
30
- return unless value.typeOfResource.attributes.length > 0
31
- value.typeOfResource.attributes.length > 0 &&
33
+ return unless value.typeOfResource.attributes.length.positive?
34
+
35
+ value.typeOfResource.attributes.length.positive? &&
32
36
  value.typeOfResource.attributes.first.key?('collection') &&
33
37
  value.typeOfResource.attributes.first['collection'].value == 'yes'
34
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Contact < Field
3
5
  def fields
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Contents < Field
3
5
  def to_html(view_context = ApplicationController.renderer)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Description < Field
3
5
  def fields
@@ -21,8 +23,7 @@ module ModsDisplay
21
23
 
22
24
  def labels
23
25
  { digitalOrigin: I18n.t('mods_display.digital_origin'),
24
- note: I18n.t('mods_display.note')
25
- }
26
+ note: I18n.t('mods_display.note') }
26
27
  end
27
28
  end
28
29
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Extent < Field
3
5
  def fields
4
6
  return [] unless extent_fields.present?
7
+
5
8
  [
6
9
  ModsDisplay::Values.new(
7
10
  label: I18n.t('mods_display.extent'),
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module ModsDisplay
3
4
  class Field
4
5
  def initialize(values)
@@ -9,7 +10,7 @@ module ModsDisplay
9
10
  return_fields = @values.map do |value|
10
11
  ModsDisplay::Values.new(
11
12
  label: displayLabel(value) || label,
12
- values: [displayForm(@values) || value.text].flatten
13
+ values: [value.text]
13
14
  )
14
15
  end
15
16
  collapse_fields(return_fields)
@@ -17,6 +18,7 @@ module ModsDisplay
17
18
 
18
19
  def label
19
20
  return nil if @values.nil?
21
+
20
22
  displayLabel(@values.first)
21
23
  end
22
24
 
@@ -34,15 +36,10 @@ module ModsDisplay
34
36
  nil
35
37
  end
36
38
 
37
- def displayForm(element)
38
- return element unless element # basically return nil
39
- display = element.children.find { |c| c.name == 'displayForm' }
40
- return display.text if display
41
- end
42
-
43
39
  def displayLabel(element)
44
40
  return unless element.respond_to?(:attributes) &&
45
41
  element.attributes['displayLabel'].respond_to?(:value)
42
+
46
43
  "#{element.attributes['displayLabel'].value}:"
47
44
  end
48
45
 
@@ -52,7 +49,7 @@ module ModsDisplay
52
49
  display_fields.slice_when { |before, after| before.label != after.label }.map do |group|
53
50
  next group.first if group.length == 1
54
51
 
55
- ModsDisplay::Values.new(label: group.first.label, values: group.map(&:values).flatten)
52
+ ModsDisplay::Values.new(label: group.first.label, values: group.map(&:values).flatten(1))
56
53
  end
57
54
  end
58
55
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Form < Field
3
5
  def fields
4
6
  return [] unless form_fields.present?
7
+
5
8
  [
6
9
  ModsDisplay::Values.new(
7
10
  label: I18n.t('mods_display.form'),
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Genre < Field
3
5
  def fields
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Geo < Field
3
5
  def fields
4
6
  return [] unless geo_extensions.present?
7
+
5
8
  extensions = geo_extensions.map(&method(:process_geo_extension))
6
9
  [
7
10
  ModsDisplay::Values.new(
@@ -16,8 +19,8 @@ module ModsDisplay
16
19
  def process_geo_extension(extension)
17
20
  rdf = Nokogiri::XML(extension.children.to_s)
18
21
  [
19
- rdf.xpath('//format').text[/format=(.*)$/, 1],
20
- rdf.xpath('//type').text[/#(.*)$/, 1]
22
+ rdf.xpath('//dc:format', dc: 'http://purl.org/dc/elements/1.1/').text[/format=(.*)$/, 1],
23
+ rdf.xpath('//dc:type', dc: 'http://purl.org/dc/elements/1.1/').text[/#(.*)$/, 1]
21
24
  ].compact.join('; ')
22
25
  end
23
26
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModsDisplay
2
4
  class Identifier < Field
3
5
  def fields
@@ -13,28 +15,29 @@ module ModsDisplay
13
15
  if element.attributes['type'].respond_to?(:value)
14
16
  return identifier_labels[element.attributes['type'].value] || "#{element.attributes['type'].value}:"
15
17
  end
18
+
16
19
  I18n.t('mods_display.identifier')
17
20
  end
18
21
 
19
22
  def identifier_labels
20
- { 'local' => I18n.t('mods_display.identifier'),
21
- 'isbn' => I18n.t('mods_display.isbn'),
22
- 'issn' => I18n.t('mods_display.issn'),
23
- 'issn-l' => I18n.t('mods_display.issn'),
24
- 'doi' => I18n.t('mods_display.doi'),
25
- 'hdl' => I18n.t('mods_display.handle'),
26
- 'isrc' => I18n.t('mods_display.isrc'),
27
- 'ismn' => I18n.t('mods_display.ismn'),
28
- 'issue number' => I18n.t('mods_display.issue_number'),
29
- 'lccn' => I18n.t('mods_display.lccn'),
30
- 'oclc' => I18n.t('mods_display.oclc'),
31
- 'matrix number' => I18n.t('mods_display.matrix_number'),
32
- 'music publisher' => I18n.t('mods_display.music_publisher'),
33
- 'music plate' => I18n.t('mods_display.music_plate'),
34
- 'sici' => I18n.t('mods_display.sici'),
35
- 'upc' => I18n.t('mods_display.upc'),
23
+ { 'local' => I18n.t('mods_display.identifier'),
24
+ 'isbn' => I18n.t('mods_display.isbn'),
25
+ 'issn' => I18n.t('mods_display.issn'),
26
+ 'issn-l' => I18n.t('mods_display.issn'),
27
+ 'doi' => I18n.t('mods_display.doi'),
28
+ 'hdl' => I18n.t('mods_display.handle'),
29
+ 'isrc' => I18n.t('mods_display.isrc'),
30
+ 'ismn' => I18n.t('mods_display.ismn'),
31
+ 'issue number' => I18n.t('mods_display.issue_number'),
32
+ 'lccn' => I18n.t('mods_display.lccn'),
33
+ 'oclc' => I18n.t('mods_display.oclc'),
34
+ 'matrix number' => I18n.t('mods_display.matrix_number'),
35
+ 'music publisher' => I18n.t('mods_display.music_publisher'),
36
+ 'music plate' => I18n.t('mods_display.music_plate'),
37
+ 'sici' => I18n.t('mods_display.sici'),
38
+ 'upc' => I18n.t('mods_display.upc'),
36
39
  'videorecording identifier' => I18n.t('mods_display.videorecording_identifier'),
37
- 'stock number' => I18n.t('mods_display.stock_number') }
40
+ 'stock number' => I18n.t('mods_display.stock_number') }
38
41
  end
39
42
  end
40
43
  end