cocina_display 1.10.0 → 1.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03c9a2548b9c996e4083311c34980125df77e41dc01ffa613e1539f9524b623a
4
- data.tar.gz: ec9d5c04f50fb1cba69384b40c8ab9b009e8f8e9046b8e4dd67b15dd22f60479
3
+ metadata.gz: 225982c5b9748bc337ec552e64becdb2ad78c1e6c2bb8ac8e9c77064140bf69b
4
+ data.tar.gz: 64e7a2349e5b7e3cd0deca4675423ab135cf270d228ff067b7872637a2b79f48
5
5
  SHA512:
6
- metadata.gz: f3f777efbd5262a640b9e9c93e63411d7c52c6aaf603b3203742a0af5108c8ece948918b6900db17dd42ec92e63c17f71a15b739fc2ced4c82d4b8f4e05d6af7
7
- data.tar.gz: 91633c63df3e10220d5a8c564f2900194546d14b96ca6b115ddcbb12fff8a2f182bda92023dfd32ff5f6486f1fda3c93a8b578e93ae3075c4d5812bbfd39ffea
6
+ metadata.gz: 6ebdbca3032b4b8f54dd63d7f62ee9fea98a8380de0981d5acaa335bec5093cb0f170c1237fee7388461ca2d6786da35b58f90dfdf9017ae5d3eb96f33c11cf3
7
+ data.tar.gz: 736d1e098f29f20a4a480c99d91642f664d62e4c25aa449505e5421047d7d84d2f9ba56741d8a8c33755832718d9c092fb77b867cd64b3b483a6d359d2022fcb
@@ -26,26 +26,20 @@ en:
26
26
  note: Note
27
27
  resource_type: Resource Type
28
28
  identifier:
29
- doi: DOI
30
- handle: Handle
31
29
  identifier: Identifier
30
+ local: Local identifier
31
+ other: Other identifier
32
+ doi: DOI
32
33
  isbn: ISBN
33
34
  ismn: ISMN
34
35
  isrc: ISRC
35
36
  issn: ISSN
36
37
  issn_l: ISSN
37
- issue_number: Issue number
38
- language: Language
39
38
  lccn: LCCN
40
- matrix_number: Matrix number
41
- music_plate: Music plate
42
- music_publisher: Music publisher
43
39
  oclc: OCLC
44
40
  orcid: ORCID
45
41
  sici: SICI
46
- stock_number: Stock number
47
42
  upc: UPC
48
- videorecording_identifier: Videorecording identifier
49
43
  language: Language
50
44
  license: License
51
45
  note:
@@ -44,8 +44,9 @@ module CocinaDisplay
44
44
  # All {Title} objects, grouped by their label for display.
45
45
  # @note All primary titles are included under "Title", not just the first.
46
46
  # @return [Array<DisplayData>]
47
- def title_display_data
48
- DisplayData.from_objects(all_titles)
47
+ # @param exclude_primary [Boolean] Exclude primary titles. Defaults to false.
48
+ def title_display_data(exclude_primary: false)
49
+ DisplayData.from_objects(exclude_primary ? secondary_titles : all_titles)
49
50
  end
50
51
 
51
52
  # The first title marked primary, or the first without a type.
@@ -1,4 +1,5 @@
1
1
  require "edtf"
2
+ require "iso8601"
2
3
 
3
4
  require "active_support"
4
5
  require "active_support/core_ext/object/blank"
@@ -486,11 +487,48 @@ module CocinaDisplay
486
487
 
487
488
  # Strict ISO8601-encoded date parser.
488
489
  class Iso8601Format < Date
490
+ def self.normalize_to_edtf(value)
491
+ # Remove time component if there is one
492
+ value = value.split("T").first if value.include?("T")
493
+
494
+ # Datetime without "T" was valid until 2019, but iso8601 gem rejects it.
495
+ # YYYYMMDD is valid but EDTF needs dashes to parse it.
496
+ if /^\d{14}$/.match?(value) || /^\d{8}$/.match?(value)
497
+ "#{value[0..3]}-#{value[4..5]}-#{value[6..7]}"
498
+ else
499
+ super
500
+ end
501
+ end
502
+
489
503
  def self.parse_date(value)
490
- ::Date.parse(normalize_to_edtf(value))
491
- rescue ::Date::Error
492
- notifier&.notify("Invalid date value \"#{value}\" for iso8601 encoding")
493
- nil
504
+ value = normalize_to_edtf(value)
505
+
506
+ # Bail out if ISO8601 gem doesn't validate it
507
+ begin
508
+ date = ISO8601::Date.new(value)
509
+ rescue ISO8601::Errors::UnknownPattern
510
+ notifier&.notify("Invalid date value \"#{value}\" for iso8601 encoding")
511
+ return nil
512
+ end
513
+
514
+ case value
515
+ # Calendar dates already match EDTF format
516
+ when /^\d{4}-\d{2}-\d{2}$/, /^\d{4}-\d{2}$/, /^\d{4}$/
517
+ super
518
+ # Weeks with no day become a 7-day range
519
+ when /^\d{4}-W\d{2}$/, /^\d{4}W\d{2}$/
520
+ week_end = date + 6
521
+ ::Date.edtf("#{date}/#{week_end}")
522
+ # Weeks with day become a single day
523
+ when /^\d{4}-W\d{2}-\d$/, /^\d{4}W\d{3}$/
524
+ ::Date.edtf(date.to_s)
525
+ # Ordinal dates become a single day
526
+ when /^\d{4}-\d{3}$/, /^\d{7}$/
527
+ ::Date.edtf(date.to_s)
528
+ else
529
+ notifier&.notify("Unhandled date value \"#{value}\" for iso8601 encoding")
530
+ nil
531
+ end
494
532
  end
495
533
  end
496
534
 
@@ -80,7 +80,7 @@ module CocinaDisplay
80
80
  # @return [String]
81
81
  def label
82
82
  cocina["displayLabel"].presence ||
83
- I18n.t(label_key, default: :identifier, scope: "cocina_display.field_label.identifier")
83
+ I18n.t(label_key, default: default_label, scope: "cocina_display.field_label.identifier")
84
84
  end
85
85
 
86
86
  # Check if the identifier is a DOI.
@@ -92,6 +92,12 @@ module CocinaDisplay
92
92
 
93
93
  private
94
94
 
95
+ # Default label for an identifier, based on its type.
96
+ # @return [String]
97
+ def default_label
98
+ type&.capitalize || :identifier
99
+ end
100
+
95
101
  # Key used for i18n lookup of the label, based on the type.
96
102
  # @return [String, nil]
97
103
  def label_key
@@ -8,24 +8,35 @@ module CocinaDisplay
8
8
  TOC_TYPES = ["table of contents"].freeze
9
9
  TOC_DISPLAY_LABEL_REGEX = /Table of contents/i
10
10
 
11
- attr_reader :cocina
11
+ attr_reader :cocina, :delimiter
12
12
 
13
13
  # Initialize a Note from Cocina structured data.
14
14
  # @param cocina [Hash]
15
- def initialize(cocina)
15
+ # @param delimiter [String] Delimiter to use when joining for display.
16
+ def initialize(cocina, delimiter: " -- ")
16
17
  @cocina = cocina
18
+ @delimiter = delimiter
17
19
  end
18
20
 
19
- # String representation of the note.
21
+ # The value to use for display.
20
22
  # @return [String, nil]
21
23
  def to_s
22
- Utils.compact_and_join(values, delimiter: " -- ").presence
24
+ flat_value
25
+ end
26
+
27
+ # Single concatenated string value for the note.
28
+ # @return [String, nil]
29
+ def flat_value
30
+ Utils.compact_and_join(values, delimiter: delimiter).presence
23
31
  end
24
32
 
25
33
  # The raw values from the Cocina data, flattened if nested.
26
- # @return [String]
34
+ # Strips excess whitespace and the delimiter if present.
35
+ # @return [Array<String>]
27
36
  def values
28
- Utils.flatten_nested_values(cocina).pluck("value").compact_blank
37
+ Utils.flatten_nested_values(cocina).pluck("value")
38
+ .map { |value| value.gsub(delimiter.strip, "").strip }
39
+ .compact_blank
29
40
  end
30
41
 
31
42
  # The raw values from the Cocina data as a hash with type as key.
@@ -2,5 +2,5 @@
2
2
 
3
3
  # :nodoc:
4
4
  module CocinaDisplay
5
- VERSION = "1.10.0" # :nodoc:
5
+ VERSION = "1.12.0" # :nodoc:
6
6
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina_display
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Budak
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-02-25 00:00:00.000000000 Z
10
+ date: 2026-03-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: janeway-jsonpath
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '3.2'
54
+ - !ruby/object:Gem::Dependency
55
+ name: iso8601
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.13.0
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.13.0
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: i18n
56
70
  requirement: !ruby/object:Gem::Requirement