Class: PennMARC::Title

Inherits:
Helper
  • Object
show all
Defined in:
lib/pennmarc/helpers/title.rb

Overview

This helper contains logic for parsing out Title and Title-related fields.

Constant Summary collapse

AUX_TITLE_TAGS =

these will be used when completing the *search_aux methods

{
  main: %w[130 210 240 245 246 247 440 490 730 740 830],
  related: %w[773 774 780 785],
  entity: %w[700 710 711]
}.freeze

Class Method Summary collapse

Methods included from Util

#datafield_and_linked_alternate, #join_and_squish, #join_subfields, #linked_alternate, #linked_alternate_not_6_or_8, #prefixed_subject_and_alternate, #remove_paren_value_from_subfield_i, #subfield_defined?, #subfield_in?, #subfield_not_in?, #subfield_undefined?, #subfield_value?, #subfield_value_in?, #subfield_value_not_in?, #subfield_values, #subfield_values_for, #substring_after, #substring_before, #translate_relator, #trim_trailing, #valid_subject_genre_source_code?

Class Method Details

.former(record) ⇒ Array<String>

TODO:

what are e and w subfields?

Note:

Ported from get_former_title_display. That method returns a hash for constructing a search link. We may need to do something like that eventually.

Former Title for display. These values come from 247.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    array of former titles



170
171
172
173
174
175
176
177
178
179
# File 'lib/pennmarc/helpers/title.rb', line 170

def former(record)
  record.fields
        .filter_map do |field|
    next unless field.tag == '247' || (field.tag == '880' && subfield_value?(field, '6', /^247/))

    former_title = join_subfields field, &subfield_not_in?(%w[6 8 e w]) # 6 and 8 are not meaningful for display
    former_title_append = join_subfields field, &subfield_in?(%w[e w])
    "#{former_title} #{former_title_append}".strip
  end
end

.journal_search(record) ⇒ Array<String>

TODO:

port this, it is way complicated but essential for relevance

Journal Title Search field.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    journal title information for search



40
# File 'lib/pennmarc/helpers/title.rb', line 40

def journal_search(record); end

.journal_search_aux(record) ⇒ Array<String>

TODO:

port this, it is way complicated but essential for relevance

Auxiliary Journal Title Search field.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    journal title information for search



46
# File 'lib/pennmarc/helpers/title.rb', line 46

def journal_search_aux(record); end

.other(record) ⇒ Array<String>

Other Title for display

Data comes from 246 (OCLC docs) and 740 (OCLC docs)

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    Array of other titles as strings



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/pennmarc/helpers/title.rb', line 145

def other(record)
  other_titles = record.fields('246').map do |field|
    join_subfields(field, &subfield_not_in?(%w[6 8]))
  end
  other_titles += record.fields('740')
                        .filter_map do |field|
    next unless field.indicator2.in? ['', ' ', '0', '1', '3']

    join_subfields(field, &subfield_not_in?(%w[5 6 8]))
  end
  other_titles + record.fields('880').filter_map do |field|
    next unless subfield_value_in? field, '6', %w[246 740]

    join_subfields(field, &subfield_not_in?(%w[5 6 8]))
  end
end

.search(record) ⇒ Array<String>

Note:

Ported from get_title_1_search_values.

Main Title Search field. Takes from 245 and linked 880.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    array of title values for search



18
19
20
21
22
23
24
25
26
27
# File 'lib/pennmarc/helpers/title.rb', line 18

def search(record)
  titles = record.fields('245').filter_map do |field|
    join_subfields(field, &subfield_not_in?(%w[c 6 8 h]))
  end
  titles + record.fields('880').filter_map do |field|
    next unless subfield_value?(field, '6', /245/)

    join_subfields(field, &subfield_not_in?(%w[c 6 8 h]))
  end
end

.search_aux(record) ⇒ Array<String>

TODO:

port this, it is way complicated but essential for relevance

Note:

Ported from get_title_2_search_values.

Auxiliary Title Search field. Takes from many fields that contain title-like information.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    array of title values for search



34
# File 'lib/pennmarc/helpers/title.rb', line 34

def search_aux(record); end

.show(record) ⇒ String

TODO:

still consider ǂh? medium, which OCLC doc says DO NOT USE…but that is OCLC…

TODO:

is punctuation handling still as desired? treatment here is described in spreadsheet from 2011

Single-valued Title, for use in headings. Takes the first 245 value. Special consideration for punctuation practices.

Parameters:

  • record (MARC::Record)

Returns:

  • (String)

    single title for display



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/pennmarc/helpers/title.rb', line 55

def show(record)
  field = record.fields('245').first
  title_or_form = field.find_all(&subfield_in?(%w[a k]))
                       .map { |sf| trim_trailing(:comma, trim_trailing(:slash, sf.value).rstrip) }
                       .first || ''
  other_info = field.find_all(&subfield_in?(%w[b n p]))
                    .map { |sf| trim_trailing(:slash, sf.value) }
                    .join(' ')
  hpunct = field.find_all { |sf| sf.code == 'h' }.map { |sf| sf.value.last }.first
  punctuation = if [title_or_form.last, hpunct].include?('=')
                  '='
                else
                  [title_or_form.last, hpunct].include?(':') ? ':' : nil
                end
  [trim_trailing(:colon, trim_trailing(:equal, title_or_form)).strip,
   punctuation,
   other_info].compact_blank.join(' ')
end

.sort(record) ⇒ String

TODO:

refactor to reduce complexity

Note:

Currently we index two “title sort” fields: title_nssort (ssort type - regex token filter applied) and title_sort_tl (text left justified). It is not yet clear why this distinction is useful. For now, use a properly normalized (leading articles and punctuation removed) single title value here.

Canonical title with non-filing characters relocated to the end.

Parameters:

  • record (MARC::Record)

Returns:

  • (String)

    title value for sorting



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/pennmarc/helpers/title.rb', line 82

def sort(record)
  title_field = record.fields('245').first
  # attempt to get number of non-filing characters present, default to 0
  offset = if /^[0-9]$/.match?(title_field.indicator2)
             title_field.indicator2.to_i
           else
             0
           end
  raw_title = join_subfields(title_field, &subfield_in?(['a'])) # get title from subfield a
  value = if offset.between?(1, 9)
            { prefix: raw_title[0..offset - 1]&.strip, filing: raw_title[offset..]&.strip }
          elsif raw_title.present?
            handle_bracket_prefix raw_title
          else
            # no subfield a, no indicator
            raw_form = join_subfields(title_field, &subfield_in?(['k']))
            handle_bracket_prefix raw_form
          end
  value[:filing] = [value[:filing],
                    join_subfields(title_field, &subfield_in?(%w[b n p]))].compact_blank.join(' ')
  [value[:filing], value[:prefix]].join(' ').strip
end

.standardized(record) ⇒ Array<String>

Note:

this is simplified from legacy practice as a linking hash is not returned. I believe this only supported title browse and we will not be supporting that at this time

Returns Array of standardized titles as strings.

Parameters:

  • record (MARC::Record)

Returns:

  • (Array<String>)

    Array of standardized titles as strings



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/pennmarc/helpers/title.rb', line 117

def standardized(record)
  standardized_titles = record.fields(%w[130 240]).map do |field|
    join_subfields(field, &subfield_not_in?(%w[0 6 8 e w]))
  end
  standardized_titles += record.fields('730').filter_map do |field|
    # skip unless one of the indicators is blank
    next unless field.indicator1 == '' || field.indicator2 == ''

    # skip if a subfield i is present
    next if subfield_defined?(field, 'i')

    join_subfields(field, &subfield_not_in?(%w[5 6 8 e w]))
  end
  standardized_titles + record.fields('880').filter_map do |field|
    next unless subfield_undefined?(field, 'i') ||
                subfield_value_in?(field, '6', %w[130 240 730])

    join_subfields field, &subfield_not_in?(%w[5 6 8 e w])
  end
end