mods_display 0.9.1 → 1.0.0.alpha2

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -1
  3. data/.rubocop_todo.yml +433 -35
  4. data/README.md +0 -95
  5. data/app/components/mods_display/field_component.html.erb +13 -0
  6. data/app/components/mods_display/field_component.rb +27 -0
  7. data/app/components/mods_display/list_field_component.html.erb +11 -0
  8. data/app/components/mods_display/list_field_component.rb +10 -0
  9. data/app/components/mods_display/record_component.html.erb +5 -0
  10. data/app/components/mods_display/record_component.rb +39 -0
  11. data/app/helpers/mods_display/record_helper.rb +106 -0
  12. data/app/models/mods_display/record.rb +26 -0
  13. data/config/locales/en.yml +1 -1
  14. data/config.ru +9 -0
  15. data/lib/mods_display/engine.rb +13 -0
  16. data/lib/mods_display/fields/access_condition.rb +4 -0
  17. data/lib/mods_display/fields/contents.rb +14 -15
  18. data/lib/mods_display/fields/field.rb +13 -149
  19. data/lib/mods_display/fields/genre.rb +4 -0
  20. data/lib/mods_display/fields/imprint.rb +52 -3
  21. data/lib/mods_display/fields/location.rb +1 -1
  22. data/lib/mods_display/fields/name.rb +11 -20
  23. data/lib/mods_display/fields/nested_related_item.rb +7 -18
  24. data/lib/mods_display/fields/note.rb +4 -0
  25. data/lib/mods_display/fields/related_item.rb +4 -0
  26. data/lib/mods_display/fields/resource_type.rb +1 -1
  27. data/lib/mods_display/fields/sub_title.rb +3 -3
  28. data/lib/mods_display/fields/subject.rb +13 -39
  29. data/lib/mods_display/fields/title.rb +43 -32
  30. data/lib/mods_display/fields/values.rb +4 -4
  31. data/lib/mods_display/html.rb +55 -106
  32. data/lib/mods_display/version.rb +1 -1
  33. data/lib/mods_display.rb +2 -17
  34. data/mods_display.gemspec +15 -9
  35. metadata +45 -105
  36. data/.github/workflows/ruby.yml +0 -24
  37. data/.gitignore +0 -21
  38. data/lib/mods_display/configuration/access_condition.rb +0 -21
  39. data/lib/mods_display/configuration/base.rb +0 -34
  40. data/lib/mods_display/configuration/genre.rb +0 -9
  41. data/lib/mods_display/configuration/imprint.rb +0 -13
  42. data/lib/mods_display/configuration/name.rb +0 -9
  43. data/lib/mods_display/configuration/note.rb +0 -9
  44. data/lib/mods_display/configuration/related_item.rb +0 -9
  45. data/lib/mods_display/configuration/subject.rb +0 -13
  46. data/lib/mods_display/configuration/title.rb +0 -9
  47. data/lib/mods_display/configuration.rb +0 -93
  48. data/lib/mods_display/controller_extension.rb +0 -32
  49. data/lib/mods_display/helpers/record_helper.rb +0 -131
  50. data/lib/mods_display/model_extension.rb +0 -22
  51. data/lib/mods_display/railtie.rb +0 -10
  52. data/spec/configuration/access_condition_spec.rb +0 -10
  53. data/spec/configuration/base_spec.rb +0 -39
  54. data/spec/fake_app.rb +0 -18
  55. data/spec/fields/abstract_spec.rb +0 -39
  56. data/spec/fields/access_condition_spec.rb +0 -107
  57. data/spec/fields/audience_spec.rb +0 -24
  58. data/spec/fields/cartographics_spec.rb +0 -38
  59. data/spec/fields/collection_spec.rb +0 -77
  60. data/spec/fields/contact_spec.rb +0 -23
  61. data/spec/fields/contents_spec.rb +0 -39
  62. data/spec/fields/description_spec.rb +0 -55
  63. data/spec/fields/extent_spec.rb +0 -31
  64. data/spec/fields/form_spec.rb +0 -49
  65. data/spec/fields/genre_spec.rb +0 -34
  66. data/spec/fields/geo_spec.rb +0 -40
  67. data/spec/fields/identifier_spec.rb +0 -61
  68. data/spec/fields/imprint_spec.rb +0 -289
  69. data/spec/fields/language_spec.rb +0 -51
  70. data/spec/fields/location_spec.rb +0 -81
  71. data/spec/fields/name_spec.rb +0 -166
  72. data/spec/fields/nested_related_item_spec.rb +0 -89
  73. data/spec/fields/note_spec.rb +0 -72
  74. data/spec/fields/related_item_spec.rb +0 -72
  75. data/spec/fields/resource_type_spec.rb +0 -34
  76. data/spec/fields/sub_title_spec.rb +0 -20
  77. data/spec/fields/subject_spec.rb +0 -113
  78. data/spec/fields/title_spec.rb +0 -74
  79. data/spec/fixtures/access_condition_fixtures.rb +0 -58
  80. data/spec/fixtures/cartographics_fixtures.rb +0 -52
  81. data/spec/fixtures/imprint_fixtures.rb +0 -349
  82. data/spec/fixtures/name_fixtures.rb +0 -398
  83. data/spec/fixtures/nested_realted_items_fixtures.rb +0 -64
  84. data/spec/fixtures/related_item_fixtures.rb +0 -107
  85. data/spec/fixtures/subjects_fixtures.rb +0 -115
  86. data/spec/fixtures/title_fixtures.rb +0 -101
  87. data/spec/helpers/record_helper_spec.rb +0 -241
  88. data/spec/integration/configuration_spec.rb +0 -57
  89. data/spec/integration/html_spec.rb +0 -87
  90. data/spec/integration/installation_spec.rb +0 -26
  91. data/spec/spec_helper.rb +0 -46
  92. data/spec/test_fr.yml +0 -3
@@ -0,0 +1,27 @@
1
+ module ModsDisplay
2
+ class FieldComponent < ViewComponent::Base
3
+ with_collection_parameter :field
4
+
5
+ def initialize(field:, delimiter: nil, label_html_attributes: {}, value_html_attributes: {}, value_transformer: nil)
6
+ super
7
+
8
+ @field = field
9
+ @delimiter = delimiter
10
+ @value_transformer = value_transformer
11
+ @label_html_attributes = label_html_attributes
12
+ @value_html_attributes = value_html_attributes
13
+ end
14
+
15
+ def render?
16
+ @field.values.any?(&:present?)
17
+ end
18
+
19
+ def format_value(value)
20
+ if @value_transformer
21
+ @value_transformer.call(value)
22
+ else
23
+ helpers.link_urls_and_email(value)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ <% if @field.label %>
2
+ <%= tag.dt @field.label.sub(/:$/, ''), **@label_html_attributes %>
3
+ <% end %>
4
+
5
+ <%= tag.dd format_value(value), **@value_html_attributes %>
6
+ <% tag.ul **@list_html_attributes %>
7
+ <% @field.values.select(&:present?).each do |value| %>
8
+ <%= tag.li format_value(value), **@list_item_html_attributes %>
9
+ <% end %>
10
+ <% end %>
11
+ <% end %>
@@ -0,0 +1,10 @@
1
+ module ModsDisplay
2
+ class ListFieldComponent < ModsDisplay::FieldComponent
3
+ def initialize(list_html_attributes: {}, list_item_html_attributes: {}, **args)
4
+ super(**args)
5
+
6
+ @list_html_attributes = list_html_attributes
7
+ @list_item_html_attributes = list_item_html_attributes
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ <%= tag.dl **@html_attributes do %>
2
+ <% @fields.each do |field| %>
3
+ <%= render @record.mods_field(field) %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,39 @@
1
+ module ModsDisplay
2
+ class RecordComponent < ViewComponent::Base
3
+ DEFAULT_FIELDS = [
4
+ :subTitle,
5
+ :name,
6
+ :language,
7
+ :imprint,
8
+ :resourceType,
9
+ :genre,
10
+ :form,
11
+ :extent,
12
+ :geo,
13
+ :description,
14
+ :cartographics,
15
+ :abstract,
16
+ :contents,
17
+ :audience,
18
+ :note,
19
+ :contact,
20
+ :collection,
21
+ :nestedRelatedItem,
22
+ :relatedItem,
23
+ :subject,
24
+ :identifier,
25
+ :location
26
+ # :accessCondition
27
+ ].freeze
28
+
29
+ with_collection_parameter :record
30
+
31
+ def initialize(record:, fields: DEFAULT_FIELDS, html_attributes: {})
32
+ super
33
+
34
+ @record = record
35
+ @fields = fields
36
+ @html_attributes = html_attributes
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModsDisplay
4
+ module RecordHelper
5
+ def mods_display_label(label)
6
+ content_tag(:dt, label.delete(':')) + "\n".html_safe
7
+ end
8
+
9
+ # @private
10
+ def mods_display_content(values, delimiter = nil)
11
+ mods_record_field ModsDisplay::Values.new(values: Array(values)), delimiter
12
+ end
13
+
14
+ def mods_record_field(field, delimiter = nil, component: ModsDisplay::FieldComponent, &block)
15
+ render component.new(field: field, delimiter: delimiter, value_transformer: block)
16
+ end
17
+
18
+ def mods_name_field(field, &block)
19
+ mods_record_field(field) do |name|
20
+ block_given? ? capture { yield(name.name) } : name.name
21
+ end
22
+ end
23
+
24
+ def mods_display_name(values, &block)
25
+ mods_name_field(ModsDisplay::Values.new(values: Array(values)), &block)
26
+ end
27
+
28
+ # We need this to remove the ending ":" from the role labels only in data from
29
+ # mods_display
30
+ # @private (but currently used in searchworks)
31
+ def sanitize_mods_name_label(label)
32
+ label.sub(/:$/, '')
33
+ end
34
+
35
+ def mods_subject_field(field, &block)
36
+ mods_record_field(field) do |subject_line|
37
+ safe_join(link_mods_subjects(subject_line, &block), ' > ')
38
+ end
39
+ end
40
+
41
+ def mods_genre_field(field, &block)
42
+ mods_record_field(field) do |genre_line|
43
+ link_to_mods_subject(genre_line, &block)
44
+ end
45
+ end
46
+
47
+ # @private
48
+ def link_mods_genres(genre, &block)
49
+ link_buffer = []
50
+ link_to_mods_subject(genre, link_buffer, &block)
51
+ end
52
+
53
+ # @private
54
+ def link_mods_subjects(subjects, &block)
55
+ link_buffer = []
56
+ linked_subjects = []
57
+ subjects.each do |subject|
58
+ if subject.present?
59
+ linked_subjects << link_to_mods_subject(subject, link_buffer, &block)
60
+ end
61
+ end
62
+ linked_subjects
63
+ end
64
+
65
+ # @private
66
+ def link_to_mods_subject(subject, buffer = [], &block)
67
+ subject_text = subject.respond_to?(:name) ? subject.name : subject
68
+ link = block_given? ? capture { yield(subject_text, buffer) } : subject_text
69
+ buffer << subject_text.strip
70
+ link << " (#{subject.roles.join(', ')})" if subject.respond_to?(:roles) && subject.roles.present?
71
+ link
72
+ end
73
+
74
+ # rubocop:disable Layout/LineLength
75
+ # @private, but used in PURL currently
76
+ def link_urls_and_email(val, tags: %w[a dl dd dt i b em strong])
77
+ val = val.gsub(%r{<[^/> ]+}) do |possible_tag|
78
+ # Allow potentially valid HTML tags through to the sanitizer step, and HTML escape the rest
79
+ if tags.include? possible_tag[1..]
80
+ possible_tag
81
+ else
82
+ "&lt;#{possible_tag[1..]}"
83
+ end
84
+ end
85
+
86
+ # http://daringfireball.net/2010/07/improved_regex_for_matching_urls
87
+ url = %r{(?i)\b(?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\([^\s()<>]+|\([^\s()<>]+\)*\))+(?:\([^\s()<>]+|\([^\s()<>]+\)*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])}i
88
+ # http://www.regular-expressions.info/email.html
89
+ email = %r{[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b}i
90
+ matches = [val.scan(url), val.scan(email)].flatten.uniq
91
+ unless val =~ /<a/ # we'll assume that linking has alraedy occured and we don't want to double link
92
+ matches.each do |match|
93
+ if match =~ email
94
+ val.gsub!(match, "<a href='mailto:#{match}'>#{match}</a>")
95
+ else
96
+ val.gsub!(match, "<a href='#{match}'>#{match}</a>")
97
+ end
98
+ end
99
+ end
100
+
101
+ sanitize val, tags: tags, attributes: %w[href]
102
+ end
103
+ # rubocop:enable Layout/LineLength
104
+
105
+ end
106
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stanford-mods'
4
+
5
+ ##
6
+ # A convenience object for parsing and rendering MODS
7
+ module ModsDisplay
8
+ class Record
9
+ attr_reader :xml
10
+
11
+ def initialize(xml)
12
+ @xml = xml
13
+ end
14
+
15
+ def mods_record
16
+ return if xml.nil?
17
+ @mods_record ||= Stanford::Mods::Record.new.tap { |mods| mods.from_str(xml, false) }
18
+ end
19
+
20
+ def mods_display_html
21
+ return unless mods_record
22
+
23
+ ModsDisplay::HTML.new(mods_record)
24
+ end
25
+ end
26
+ end
@@ -42,7 +42,7 @@ en:
42
42
  license: "License:"
43
43
  location: "Location:"
44
44
  map_data: "Map data:"
45
- matrix_number: "Matric number:"
45
+ matrix_number: "Matrix number:"
46
46
  music_plate: "Music plate:"
47
47
  music_publisher: "Music publisher:"
48
48
  note: "Note:"
data/config.ru ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+
6
+ Bundler.require :default, :development
7
+
8
+ Combustion.initialize! :all
9
+ run Combustion::Application
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'view_component'
4
+
5
+ module ModsDisplay
6
+ class Engine < ::Rails::Engine
7
+ initializer 'mods_display.helpers' do
8
+ config.after_initialize do
9
+ ActionView::Base.include ModsDisplay::RecordHelper
10
+ end
11
+ end
12
+ end
13
+ end
@@ -60,6 +60,10 @@ module ModsDisplay
60
60
 
61
61
  private
62
62
 
63
+ def delimiter
64
+ '<br />'
65
+ end
66
+
63
67
  def process_access_statement(element)
64
68
  case normalize_type(element)
65
69
  when 'copyright'
@@ -1,21 +1,20 @@
1
1
  module ModsDisplay
2
2
  class Contents < Field
3
- def to_html
4
- return nil if fields.empty? || @config.ignore?
5
- output = ''
6
- fields.each do |field|
7
- next unless field.values.any? { |f| f && !f.empty? }
8
- output << "<dt#{label_class} #{sanitized_field_title(field.label)}>#{field.label}</dt>"
9
- output << "<dd#{value_class}>"
10
- output << '<ul><li>'
11
- # compress all values into a "--"-delimited string then split them up
12
- output << field.values.join('--').split('--').map(&:strip).map do |val|
13
- @config.link ? link_to_value(val.to_s) : link_urls_and_email(val.to_s)
14
- end.join('</li><li>')
15
- output << '</li></ul>'
16
- output << '</dd>'
3
+ def to_html(view_context = ApplicationController.renderer)
4
+ f = fields.map do |field|
5
+ ModsDisplay::Values.new(label: field.label, values: [field.values.join("\n\n")])
17
6
  end
18
- output
7
+
8
+ helpers = view_context.respond_to?(:simple_format) ? view_context : ApplicationController.new.view_context
9
+
10
+ value_transformer = lambda do |value|
11
+ text = ERB::Util.h(value.gsub('&#10;', "\n"))
12
+ helpers.simple_format(text, {}, sanitize: false)
13
+ end
14
+
15
+ component = ModsDisplay::FieldComponent.with_collection(f, value_transformer: value_transformer)
16
+
17
+ view_context.render component
19
18
  end
20
19
 
21
20
  private
@@ -1,10 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module ModsDisplay
3
3
  class Field
4
- def initialize(values, config, klass)
4
+ def initialize(values)
5
5
  @values = values
6
- @config = config
7
- @klass = klass
8
6
  end
9
7
 
10
8
  def fields
@@ -22,83 +20,18 @@ module ModsDisplay
22
20
  displayLabel(@values.first)
23
21
  end
24
22
 
25
- def to_html
26
- return nil if fields.empty? || @config.ignore?
27
- output = ''
28
- fields.each do |field|
29
- next unless field.values.any? { |f| f && !f.empty? }
30
- output << "<dt#{label_class} #{sanitized_field_title(field.label)}>#{field.label}</dt>"
31
- output << "<dd#{value_class}>"
32
- output << field.values.map do |val|
33
- @config.link ? link_to_value(val.to_s) : link_urls_and_email(val.to_s)
34
- end.join(@config.delimiter)
35
- output << '</dd>'
36
- end
37
- output
23
+ def to_html(view_context = ApplicationController.renderer)
24
+ view_context.render ModsDisplay::FieldComponent.with_collection(fields, delimiter: delimiter)
38
25
  end
39
26
 
40
- private
41
-
42
- def compact_and_join_with_delimiter(values, delimiter)
43
- compact_values = values.compact.reject { |v| v.strip.empty? }
44
- return compact_values.join(delimiter) if compact_values.length == 1 ||
45
- !ends_in_terminating_punctuation?(delimiter)
46
- compact_values.each_with_index.map do |value, i|
47
- if (compact_values.length - 1) == i || # last item?
48
- ends_in_terminating_punctuation?(value)
49
- value << ' '
50
- else
51
- value << delimiter
52
- end
53
- end.join.strip
27
+ def render_in(view_context)
28
+ to_html(view_context)
54
29
  end
55
30
 
56
- def process_bc_ad_dates(date_fields)
57
- date_fields.map do |date_field|
58
- case
59
- when date_is_bc_edtf?(date_field)
60
- year = date_field.text.strip.gsub(/^-0*/, '').to_i + 1
61
- date_field.content = "#{year} B.C."
62
- when date_is_ad?(date_field)
63
- date_field.content = "#{date_field.text.strip.gsub(/^0*/, '')} A.D."
64
- end
65
- date_field
66
- end
67
- end
68
-
69
- def date_is_bc_edtf?(date_field)
70
- date_field.text.strip.start_with?('-') && date_is_edtf?(date_field)
71
- end
72
-
73
- def date_is_ad?(date_field)
74
- date_field.text.strip.gsub(/^0*/, '').length < 4
75
- end
76
-
77
- def date_is_edtf?(date_field)
78
- field_is_encoded?(date_field, 'edtf')
79
- end
80
-
81
- def field_is_encoded?(field, encoding)
82
- field.attributes['encoding'] &&
83
- field.attributes['encoding'].respond_to?(:value) &&
84
- field.attributes['encoding'].value.downcase == encoding
85
- end
86
-
87
- def ends_in_terminating_punctuation?(value)
88
- value.strip.end_with?('.', ',', ':', ';')
89
- end
90
-
91
- def label_class
92
- " class='#{@config.label_class}'" unless @config.label_class == ''
93
- end
94
-
95
- def value_class
96
- " class='#{@config.value_class}'" unless @config.value_class == ''
97
- end
31
+ private
98
32
 
99
- def link_to_value(link_text, link_href = nil)
100
- href_or_text = link_href || link_text
101
- "<a href='#{@klass.send(@config.link[0], replace_tokens(@config.link[1], href_or_text))}'>#{link_text}</a>"
33
+ def delimiter
34
+ nil
102
35
  end
103
36
 
104
37
  def displayForm(element)
@@ -113,83 +46,14 @@ module ModsDisplay
113
46
  "#{element.attributes['displayLabel'].value}:"
114
47
  end
115
48
 
116
- def sanitized_field_title(label)
117
- "title='#{label.gsub(/:$/, '').strip}'"
118
- end
119
-
120
- def replace_tokens(object, value)
121
- object = object.dup
122
- if object.is_a?(Hash)
123
- object.each do |k, v|
124
- object[k] = replace_token(v, value)
125
- end
126
- elsif object.is_a?(String)
127
- object = replace_token(object, value)
128
- end
129
- object
130
- end
131
-
132
- def replace_token(string, value)
133
- string = string.dup
134
- tokens.each do |token|
135
- string.gsub!(token, value)
136
- end
137
- string
138
- end
139
-
140
- def tokens
141
- ['%value%']
142
- end
49
+ def collapse_fields(display_fields)
50
+ return display_fields if display_fields.length == 1
143
51
 
144
- # rubocop:disable Metrics/LineLength
145
- # Disabling line length due to necessarily long regular expressions
146
- def link_urls_and_email(val)
147
- val = val.dup
148
- # http://daringfireball.net/2010/07/improved_regex_for_matching_urls
149
- url = %r{(?i)\b(?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\([^\s()<>]+|\([^\s()<>]+\)*\))+(?:\([^\s()<>]+|\([^\s()<>]+\)*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])}i
150
- # http://www.regular-expressions.info/email.html
151
- email = /[A-Z0-9_\.%\+\-\']+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,4}|museum|travel)/i
152
- matches = [val.scan(url), val.scan(email)].flatten
153
- unless val =~ /<a/ # we'll assume that linking has alraedy occured and we don't want to double link
154
- matches.each do |match|
155
- if match =~ email
156
- val = val.gsub(match, "<a href='mailto:#{match}'>#{match}</a>")
157
- else
158
- val = val.gsub(match, "<a href='#{match}'>#{match}</a>")
159
- end
160
- end
161
- end
162
- val
163
- end
164
- # rubocop:enable Metrics/LineLength
52
+ display_fields.slice_when { |before, after| before.label != after.label }.map do |group|
53
+ next group.first if group.length == 1
165
54
 
166
- def collapse_fields(display_fields)
167
- return_values = []
168
- current_label = nil
169
- prev_label = nil
170
- buffer = []
171
- display_fields.each_with_index do |field, index|
172
- current_label = field.label
173
- current_values = field.values
174
- if display_fields.length == 1
175
- return_values << ModsDisplay::Values.new(label: current_label, values: current_values)
176
- elsif index == (display_fields.length - 1)
177
- # need to deal w/ when we have a last element but we have separate labels in the buffer.
178
- if current_label != prev_label
179
- return_values << ModsDisplay::Values.new(label: prev_label, values: buffer.flatten)
180
- return_values << ModsDisplay::Values.new(label: current_label, values: current_values)
181
- else
182
- buffer.concat(current_values)
183
- return_values << ModsDisplay::Values.new(label: current_label, values: buffer.flatten)
184
- end
185
- elsif prev_label && (current_label != prev_label)
186
- return_values << ModsDisplay::Values.new(label: prev_label, values: buffer.flatten)
187
- buffer = []
188
- end
189
- buffer.concat(current_values)
190
- prev_label = current_label
55
+ ModsDisplay::Values.new(label: group.first.label, values: group.map(&:values).flatten)
191
56
  end
192
- return_values
193
57
  end
194
58
  end
195
59
  end
@@ -9,6 +9,10 @@ module ModsDisplay
9
9
 
10
10
  private
11
11
 
12
+ def delimiter
13
+ '<br />'
14
+ end
15
+
12
16
  def displayLabel(element)
13
17
  super(element) || I18n.t('mods_display.genre')
14
18
  end
@@ -168,9 +168,9 @@ module ModsDisplay
168
168
  date_field = date_field.clone
169
169
  date_field.content = begin
170
170
  if date_field.text.strip =~ /^\d{4}-\d{2}-\d{2}$/
171
- Date.parse(date_field.text).strftime(@config.full_date_format)
171
+ Date.parse(date_field.text).strftime('%B %d, %Y')
172
172
  elsif date_field.text.strip =~ /^\d{4}-\d{2}$/
173
- Date.parse("#{date_field.text}-01").strftime(@config.short_date_format)
173
+ Date.parse("#{date_field.text}-01").strftime('%B %Y')
174
174
  else
175
175
  date_field.content
176
176
  end
@@ -183,7 +183,7 @@ module ModsDisplay
183
183
  def process_iso8601_date(date_field)
184
184
  date_field = date_field.clone
185
185
  date_field.content = begin
186
- Date.iso8601(date_field.text).strftime(@config.full_date_format)
186
+ Date.iso8601(date_field.text).strftime('%B %d, %Y')
187
187
  rescue
188
188
  date_field.content
189
189
  end
@@ -256,6 +256,55 @@ module ModsDisplay
256
256
 
257
257
  private
258
258
 
259
+ def compact_and_join_with_delimiter(values, delimiter)
260
+ compact_values = values.compact.reject { |v| v.strip.empty? }
261
+ return compact_values.join(delimiter) if compact_values.length == 1 ||
262
+ !ends_in_terminating_punctuation?(delimiter)
263
+ compact_values.each_with_index.map do |value, i|
264
+ if (compact_values.length - 1) == i || # last item?
265
+ ends_in_terminating_punctuation?(value)
266
+ value << ' '
267
+ else
268
+ value << delimiter
269
+ end
270
+ end.join.strip
271
+ end
272
+
273
+ def process_bc_ad_dates(date_fields)
274
+ date_fields.map do |date_field|
275
+ case
276
+ when date_is_bc_edtf?(date_field)
277
+ year = date_field.text.strip.gsub(/^-0*/, '').to_i + 1
278
+ date_field.content = "#{year} B.C."
279
+ when date_is_ad?(date_field)
280
+ date_field.content = "#{date_field.text.strip.gsub(/^0*/, '')} A.D."
281
+ end
282
+ date_field
283
+ end
284
+ end
285
+
286
+ def date_is_bc_edtf?(date_field)
287
+ date_field.text.strip.start_with?('-') && date_is_edtf?(date_field)
288
+ end
289
+
290
+ def date_is_ad?(date_field)
291
+ date_field.text.strip.gsub(/^0*/, '').length < 4
292
+ end
293
+
294
+ def date_is_edtf?(date_field)
295
+ field_is_encoded?(date_field, 'edtf')
296
+ end
297
+
298
+ def field_is_encoded?(field, encoding)
299
+ field.attributes['encoding'] &&
300
+ field.attributes['encoding'].respond_to?(:value) &&
301
+ field.attributes['encoding'].value.downcase == encoding
302
+ end
303
+
304
+ def ends_in_terminating_punctuation?(value)
305
+ value.strip.end_with?('.', ',', ':', ';')
306
+ end
307
+
259
308
  def edition_element(value)
260
309
  value.edition.reject do |e|
261
310
  e.text.strip.empty?
@@ -24,7 +24,7 @@ module ModsDisplay
24
24
  private
25
25
 
26
26
  def location_field_keys
27
- [:physicalLocation, :url, :shelfLocation, :holdingSimple, :holdingExternal]
27
+ [:physicalLocation, :url, :shelfLocator, :holdingSimple, :holdingExternal]
28
28
  end
29
29
 
30
30
  def location_label(element)
@@ -16,26 +16,18 @@ module ModsDisplay
16
16
  collapse_roles(collapse_fields(return_fields))
17
17
  end
18
18
 
19
- def to_html
20
- return nil if fields.empty? || @config.ignore?
21
- output = ''
22
- fields.each do |field|
23
- output << "<dt#{label_class} #{sanitized_field_title(field.label)}>#{field.label}</dt>"
24
- output << "<dd#{value_class}>"
25
- output << field.values.map do |val|
26
- if @config.link
27
- link_to_value(val.name)
28
- else
29
- val.to_s
30
- end
31
- end.join(@config.delimiter)
32
- output << '</dd>'
33
- end
34
- output
19
+ def to_html(view_context = ApplicationController.renderer)
20
+ component = ModsDisplay::FieldComponent.with_collection(fields, value_transformer: ->(value) { value.to_s })
21
+
22
+ view_context.render component
35
23
  end
36
24
 
37
25
  private
38
26
 
27
+ def delimiter
28
+ '<br />'
29
+ end
30
+
39
31
  def collapse_roles(fields)
40
32
  return [] if fields.blank?
41
33
 
@@ -150,12 +142,11 @@ module ModsDisplay
150
142
  def rebuild_fields_with_new_labels(label_keys, results)
151
143
  # Build the new fields data, stripping out the roles within the Person classes
152
144
  label_keys.uniq.map do |k|
153
- mdv = ModsDisplay::Values.new({})
154
- mdv.label = k
155
- mdv.values = results[k].map do |person|
145
+ values = results[k].map do |person|
156
146
  ModsDisplay::Name::Person.new(name: person.name)
157
147
  end
158
- mdv
148
+
149
+ ModsDisplay::Values.new(label: k, values: values)
159
150
  end
160
151
  end
161
152