@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-alpha.12
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.
- package/.github/workflows/{melinda-node-tests.yml → melinda-node-tests-and-publish.yml} +37 -12
- package/dist/access-rights.js +63 -91
- package/dist/access-rights.js.map +7 -1
- package/dist/access-rights.test.js +137 -0
- package/dist/access-rights.test.js.map +7 -0
- package/dist/addMissingField041.js +21 -53
- package/dist/addMissingField041.js.map +7 -1
- package/dist/addMissingField041.test.js +39 -0
- package/dist/addMissingField041.test.js.map +7 -0
- package/dist/addMissingField336.js +99 -191
- package/dist/addMissingField336.js.map +7 -1
- package/dist/addMissingField336.test.js +39 -0
- package/dist/addMissingField336.test.js.map +7 -0
- package/dist/addMissingField337.js +63 -132
- package/dist/addMissingField337.js.map +7 -1
- package/dist/addMissingField337.test.js +39 -0
- package/dist/addMissingField337.test.js.map +7 -0
- package/dist/addMissingField338.js +147 -253
- package/dist/addMissingField338.js.map +7 -1
- package/dist/addMissingField338.test.js +39 -0
- package/dist/addMissingField338.test.js.map +7 -0
- package/dist/cyrillux-usemarcon-replacement.js +119 -272
- package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
- package/dist/cyrillux-usemarcon-replacement.test.js +43 -0
- package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
- package/dist/cyrillux.js +119 -223
- package/dist/cyrillux.js.map +7 -1
- package/dist/cyrillux.test.js +39 -0
- package/dist/cyrillux.test.js.map +7 -0
- package/dist/disambiguateSeriesStatements.js +40 -81
- package/dist/disambiguateSeriesStatements.js.map +7 -1
- package/dist/disambiguateSeriesStatements.test.js +44 -0
- package/dist/disambiguateSeriesStatements.test.js.map +7 -0
- package/dist/double-commas.js +7 -14
- package/dist/double-commas.js.map +7 -1
- package/dist/double-commas.test.js +48 -0
- package/dist/double-commas.test.js.map +7 -0
- package/dist/duplicates-ind1.js +10 -31
- package/dist/duplicates-ind1.js.map +7 -1
- package/dist/duplicates-ind1.test.js +40 -0
- package/dist/duplicates-ind1.test.js.map +7 -0
- package/dist/empty-fields.js +10 -22
- package/dist/empty-fields.js.map +7 -1
- package/dist/empty-fields.test.js +129 -0
- package/dist/empty-fields.test.js.map +7 -0
- package/dist/ending-punctuation-conf.js +873 -769
- package/dist/ending-punctuation-conf.js.map +7 -1
- package/dist/ending-punctuation.js +156 -169
- package/dist/ending-punctuation.js.map +7 -1
- package/dist/ending-punctuation.test.js +2385 -0
- package/dist/ending-punctuation.test.js.map +7 -0
- package/dist/ending-whitespace.js +10 -35
- package/dist/ending-whitespace.js.map +7 -1
- package/dist/ending-whitespace.test.js +38 -0
- package/dist/ending-whitespace.test.js.map +7 -0
- package/dist/field-008-18-34-character-groups.js +40 -125
- package/dist/field-008-18-34-character-groups.js.map +7 -1
- package/dist/field-008-18-34-character-groups.test.js +45 -0
- package/dist/field-008-18-34-character-groups.test.js.map +7 -0
- package/dist/field-505-separators.js +19 -39
- package/dist/field-505-separators.js.map +7 -1
- package/dist/field-505-separators.test.js +45 -0
- package/dist/field-505-separators.test.js.map +7 -0
- package/dist/field-521-fix.js +19 -47
- package/dist/field-521-fix.js.map +7 -1
- package/dist/field-521-fix.test.js +44 -0
- package/dist/field-521-fix.test.js.map +7 -0
- package/dist/field-exclusion.js +37 -91
- package/dist/field-exclusion.js.map +7 -1
- package/dist/field-exclusion.test.js +821 -0
- package/dist/field-exclusion.test.js.map +7 -0
- package/dist/field-structure.js +52 -104
- package/dist/field-structure.js.map +7 -1
- package/dist/field-structure.test.js +587 -0
- package/dist/field-structure.test.js.map +7 -0
- package/dist/field33XUtils.js +119 -503
- package/dist/field33XUtils.js.map +7 -1
- package/dist/fields-present.js +11 -23
- package/dist/fields-present.js.map +7 -1
- package/dist/fields-present.test.js +95 -0
- package/dist/fields-present.test.js.map +7 -0
- package/dist/fix-33X.js +393 -431
- package/dist/fix-33X.js.map +7 -1
- package/dist/fix-33X.test.js +39 -0
- package/dist/fix-33X.test.js.map +7 -0
- package/dist/fix-country-codes.js +20 -50
- package/dist/fix-country-codes.js.map +7 -1
- package/dist/fix-country-codes.test.js +44 -0
- package/dist/fix-country-codes.test.js.map +7 -0
- package/dist/fix-language-codes.js +23 -53
- package/dist/fix-language-codes.js.map +7 -1
- package/dist/fix-language-codes.test.js +38 -0
- package/dist/fix-language-codes.test.js.map +7 -0
- package/dist/fixRelatorTerms.js +82 -209
- package/dist/fixRelatorTerms.js.map +7 -1
- package/dist/fixRelatorTerms.test.js +44 -0
- package/dist/fixRelatorTerms.test.js.map +7 -0
- package/dist/fixed-fields.js +21 -30
- package/dist/fixed-fields.js.map +7 -1
- package/dist/fixed-fields.test.js +87 -0
- package/dist/fixed-fields.test.js.map +7 -0
- package/dist/identical-fields.js +8 -24
- package/dist/identical-fields.js.map +7 -1
- package/dist/identical-fields.test.js +119 -0
- package/dist/identical-fields.test.js.map +7 -0
- package/dist/index.js +182 -413
- package/dist/index.js.map +7 -1
- package/dist/indicator-fixes.js +66 -94
- package/dist/indicator-fixes.js.map +7 -1
- package/dist/indicator-fixes.test.js +42 -0
- package/dist/indicator-fixes.test.js.map +7 -0
- package/dist/isbn-issn.js +71 -128
- package/dist/isbn-issn.js.map +7 -1
- package/dist/isbn-issn.test.js +398 -0
- package/dist/isbn-issn.test.js.map +7 -0
- package/dist/item-language.js +32 -65
- package/dist/item-language.js.map +7 -1
- package/dist/item-language.test.js +322 -0
- package/dist/item-language.test.js.map +7 -0
- package/dist/melindaCustomMergeFields.js +5182 -11233
- package/dist/melindaCustomMergeFields.js.map +7 -1
- package/dist/merge-fields/controlSubfields.js +75 -142
- package/dist/merge-fields/controlSubfields.js.map +7 -1
- package/dist/merge-fields/counterpartField.js +187 -379
- package/dist/merge-fields/counterpartField.js.map +7 -1
- package/dist/merge-fields/dataProvenance.js +29 -0
- package/dist/merge-fields/dataProvenance.js.map +7 -0
- package/dist/merge-fields/index.js +25 -50
- package/dist/merge-fields/index.js.map +7 -1
- package/dist/merge-fields/mergableIndicator.js +18 -51
- package/dist/merge-fields/mergableIndicator.js.map +7 -1
- package/dist/merge-fields/mergableTag.js +78 -30
- package/dist/merge-fields/mergableTag.js.map +7 -1
- package/dist/merge-fields/mergeConfig.js +66 -171
- package/dist/merge-fields/mergeConfig.js.map +7 -1
- package/dist/merge-fields/mergeConstraints.js +323 -1214
- package/dist/merge-fields/mergeConstraints.js.map +7 -1
- package/dist/merge-fields/mergeField.js +47 -111
- package/dist/merge-fields/mergeField.js.map +7 -1
- package/dist/merge-fields/mergeIndicator.js +64 -118
- package/dist/merge-fields/mergeIndicator.js.map +7 -1
- package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
- package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
- package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
- package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
- package/dist/merge-fields/mergeSubfield.js +47 -95
- package/dist/merge-fields/mergeSubfield.js.map +7 -1
- package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
- package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
- package/dist/merge-fields/worldKnowledge.js +15 -40
- package/dist/merge-fields/worldKnowledge.js.map +7 -1
- package/dist/merge-fields.test.js +46 -0
- package/dist/merge-fields.test.js.map +7 -0
- package/dist/mergeField500Lisapainokset.js +27 -56
- package/dist/mergeField500Lisapainokset.js.map +7 -1
- package/dist/mergeField500Lisapainokset.test.js +44 -0
- package/dist/mergeField500Lisapainokset.test.js.map +7 -0
- package/dist/mergeRelatorTermFields.js +33 -69
- package/dist/mergeRelatorTermFields.js.map +7 -1
- package/dist/mergeRelatorTermFields.test.js +44 -0
- package/dist/mergeRelatorTermFields.test.js.map +7 -0
- package/dist/modernize-502.js +23 -55
- package/dist/modernize-502.js.map +7 -1
- package/dist/modernize-502.test.js +38 -0
- package/dist/modernize-502.test.js.map +7 -0
- package/dist/multiple-subfield-0.js +23 -48
- package/dist/multiple-subfield-0.js.map +7 -1
- package/dist/multiple-subfield-0.test.js +44 -0
- package/dist/multiple-subfield-0.test.js.map +7 -0
- package/dist/non-breaking-space.js +11 -32
- package/dist/non-breaking-space.js.map +7 -1
- package/dist/non-breaking-space.test.js +38 -0
- package/dist/non-breaking-space.test.js.map +7 -0
- package/dist/normalize-dashes.js +18 -37
- package/dist/normalize-dashes.js.map +7 -1
- package/dist/normalize-dashes.test.js +44 -0
- package/dist/normalize-dashes.test.js.map +7 -0
- package/dist/normalize-identifiers.js +54 -140
- package/dist/normalize-identifiers.js.map +7 -1
- package/dist/normalize-identifiers.test.js +44 -0
- package/dist/normalize-identifiers.test.js.map +7 -0
- package/dist/normalize-qualifying-information.js +23 -48
- package/dist/normalize-qualifying-information.js.map +7 -1
- package/dist/normalize-qualifying-information.test.js +44 -0
- package/dist/normalize-qualifying-information.test.js.map +7 -0
- package/dist/normalize-utf8-diacritics.js +19 -105
- package/dist/normalize-utf8-diacritics.js.map +7 -1
- package/dist/normalize-utf8-diacritics.test.js +44 -0
- package/dist/normalize-utf8-diacritics.test.js.map +7 -0
- package/dist/normalizeFieldForComparison.js +91 -158
- package/dist/normalizeFieldForComparison.js.map +7 -1
- package/dist/normalizeSubfieldValueForComparison.js +37 -77
- package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
- package/dist/prepublicationUtils.js +58 -111
- package/dist/prepublicationUtils.js.map +7 -1
- package/dist/punctuation/index.js +56 -72
- package/dist/punctuation/index.js.map +7 -1
- package/dist/punctuation/rules/aut.js +372 -331
- package/dist/punctuation/rules/aut.js.map +7 -1
- package/dist/punctuation/rules/bib.js +420 -373
- package/dist/punctuation/rules/bib.js.map +7 -1
- package/dist/punctuation/rules/index.js +7 -21
- package/dist/punctuation/rules/index.js.map +7 -1
- package/dist/punctuation.test.js +44 -0
- package/dist/punctuation.test.js.map +7 -0
- package/dist/punctuation2.js +259 -802
- package/dist/punctuation2.js.map +7 -1
- package/dist/punctuation2.test.js +44 -0
- package/dist/punctuation2.test.js.map +7 -0
- package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
- package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
- package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
- package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
- package/dist/removeDuplicateDataFields.js +102 -202
- package/dist/removeDuplicateDataFields.js.map +7 -1
- package/dist/removeDuplicateDataFields.test.js +44 -0
- package/dist/removeDuplicateDataFields.test.js.map +7 -0
- package/dist/removeInferiorDataFields.js +104 -227
- package/dist/removeInferiorDataFields.js.map +7 -1
- package/dist/removeInferiorDataFields.test.js +44 -0
- package/dist/removeInferiorDataFields.test.js.map +7 -0
- package/dist/resolvable-ext-references-melinda.js +25 -60
- package/dist/resolvable-ext-references-melinda.js.map +7 -1
- package/dist/resolvable-ext-references-melinda.test.js +160 -0
- package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
- package/dist/resolveOrphanedSubfield6s.js +32 -63
- package/dist/resolveOrphanedSubfield6s.js.map +7 -1
- package/dist/resolveOrphanedSubfield6s.test.js +44 -0
- package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
- package/dist/sanitize-vocabulary-source-codes.js +27 -55
- package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
- package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
- package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
- package/dist/sort-tags.js +13 -25
- package/dist/sort-tags.js.map +7 -1
- package/dist/sort-tags.test.js +261 -0
- package/dist/sort-tags.test.js.map +7 -0
- package/dist/sortFields.js +152 -222
- package/dist/sortFields.js.map +7 -1
- package/dist/sortFields.test.js +44 -0
- package/dist/sortFields.test.js.map +7 -0
- package/dist/sortRelatorTerms.js +30 -68
- package/dist/sortRelatorTerms.js.map +7 -1
- package/dist/sortRelatorTerms.test.js +44 -0
- package/dist/sortRelatorTerms.test.js.map +7 -0
- package/dist/sortSubfields.js +102 -255
- package/dist/sortSubfields.js.map +7 -1
- package/dist/sortSubfields.test.js +44 -0
- package/dist/sortSubfields.test.js.map +7 -0
- package/dist/stripPunctuation.js +13 -36
- package/dist/stripPunctuation.js.map +7 -1
- package/dist/stripPunctuation.test.js +44 -0
- package/dist/stripPunctuation.test.js.map +7 -0
- package/dist/subfield-exclusion.js +28 -75
- package/dist/subfield-exclusion.js.map +7 -1
- package/dist/subfield-exclusion.test.js +471 -0
- package/dist/subfield-exclusion.test.js.map +7 -0
- package/dist/subfield6Utils.js +107 -269
- package/dist/subfield6Utils.js.map +7 -1
- package/dist/subfield8Utils.js +26 -50
- package/dist/subfield8Utils.js.map +7 -1
- package/dist/subfieldValueNormalizations.js +40 -74
- package/dist/subfieldValueNormalizations.js.map +7 -1
- package/dist/subfieldValueNormalizations.test.js +45 -0
- package/dist/subfieldValueNormalizations.test.js.map +7 -0
- package/dist/sync-007-and-300.js +22 -53
- package/dist/sync-007-and-300.js.map +7 -1
- package/dist/sync-007-and-300.test.js +44 -0
- package/dist/sync-007-and-300.test.js.map +7 -0
- package/dist/translate-terms.js +67 -155
- package/dist/translate-terms.js.map +7 -1
- package/dist/translate-terms.test.js +54 -0
- package/dist/translate-terms.test.js.map +7 -0
- package/dist/typeOfDate-008.js +10 -25
- package/dist/typeOfDate-008.js.map +7 -1
- package/dist/typeOfDate-008.test.js +40 -0
- package/dist/typeOfDate-008.test.js.map +7 -0
- package/dist/unicode-decomposition.js +94 -107
- package/dist/unicode-decomposition.js.map +7 -1
- package/dist/unicode-decomposition.test.js +94 -0
- package/dist/unicode-decomposition.test.js.map +7 -0
- package/dist/update-field-540.js +30 -75
- package/dist/update-field-540.js.map +7 -1
- package/dist/update-field-540.test.js +44 -0
- package/dist/update-field-540.test.js.map +7 -0
- package/dist/urn.js +55 -128
- package/dist/urn.js.map +7 -1
- package/dist/urn.test.js +44 -0
- package/dist/urn.test.js.map +7 -0
- package/dist/utils.js +78 -126
- package/dist/utils.js.map +7 -1
- package/eslint.config.mjs +1 -2
- package/package.json +28 -101
- package/src/access-rights.js +1 -1
- package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
- package/src/addMissingField041.js +1 -1
- package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
- package/src/addMissingField336.js +3 -3
- package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
- package/src/addMissingField337.js +2 -2
- package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
- package/src/addMissingField338.js +2 -2
- package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
- package/src/cyrillux-usemarcon-replacement.js +18 -18
- package/src/{cyrillux-usemarcon-replacement.spec.js → cyrillux-usemarcon-replacement.test.js} +17 -14
- package/src/cyrillux.js +19 -12
- package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
- package/src/disambiguateSeriesStatements.js +2 -2
- package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
- package/src/double-commas.js +1 -1
- package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
- package/src/duplicates-ind1.js +1 -1
- package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
- package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
- package/src/ending-punctuation-conf.js +6 -5
- package/src/ending-punctuation.js +115 -24
- package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +357 -275
- package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
- package/src/field-008-18-34-character-groups.js +2 -2
- package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
- package/src/field-505-separators.js +3 -3
- package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
- package/src/field-521-fix.js +2 -2
- package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
- package/src/field-exclusion.js +1 -1
- package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
- package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
- package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
- package/src/fix-33X.js +4 -4
- package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
- package/src/fix-country-codes.js +1 -1
- package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
- package/src/fix-language-codes.js +5 -5
- package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
- package/src/fixRelatorTerms.js +5 -5
- package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
- package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
- package/src/identical-fields.js +1 -1
- package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
- package/src/index.js +132 -59
- package/src/indicator-fixes.js +17 -4
- package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
- package/src/isbn-issn.js +12 -7
- package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
- package/src/{item-language.spec.js → item-language.test.js} +21 -22
- package/src/melindaCustomMergeFields.js +1 -1
- package/src/merge-fields/controlSubfields.js +1 -1
- package/src/merge-fields/counterpartField.js +14 -9
- package/src/merge-fields/dataProvenance.js +41 -0
- package/src/merge-fields/index.js +12 -3
- package/src/merge-fields/mergableIndicator.js +1 -1
- package/src/merge-fields/mergeField.js +8 -8
- package/src/merge-fields/mergeIndicator.js +1 -1
- package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
- package/src/merge-fields/mergeOrAddSubfield.js +2 -2
- package/src/merge-fields/mergeSubfield.js +4 -4
- package/src/merge-fields/removeDuplicateSubfields.js +2 -2
- package/src/{merge-fields.spec.js → merge-fields.test.js} +18 -15
- package/src/mergeField500Lisapainokset.js +1 -1
- package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
- package/src/mergeRelatorTermFields.js +5 -7
- package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
- package/src/modernize-502.js +1 -1
- package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
- package/src/multiple-subfield-0.js +3 -3
- package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
- package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
- package/src/normalize-dashes.js +2 -2
- package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
- package/src/normalize-identifiers.js +1 -1
- package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
- package/src/normalize-qualifying-information.js +2 -2
- package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
- package/src/normalize-utf8-diacritics.js +2 -2
- package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
- package/src/normalizeFieldForComparison.js +32 -6
- package/src/normalizeSubfieldValueForComparison.js +1 -1
- package/src/prepublicationUtils.js +4 -4
- package/src/punctuation/index.js +1 -1
- package/src/punctuation/rules/index.js +2 -2
- package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
- package/src/punctuation2.js +17 -8
- package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
- package/src/reindexSubfield6OccurenceNumbers.js +5 -7
- package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
- package/src/removeDuplicateDataFields.js +11 -19
- package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
- package/src/removeInferiorDataFields.js +15 -12
- package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
- package/src/resolvable-ext-references-melinda.js +1 -1
- package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
- package/src/resolveOrphanedSubfield6s.js +6 -6
- package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
- package/src/sanitize-vocabulary-source-codes.js +4 -4
- package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
- package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
- package/src/sortFields.js +4 -4
- package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
- package/src/sortRelatorTerms.js +3 -3
- package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
- package/src/sortSubfields.js +8 -6
- package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
- package/src/stripPunctuation.js +3 -3
- package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
- package/src/subfield-exclusion.js +1 -1
- package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
- package/src/subfield6Utils.js +6 -10
- package/src/subfield8Utils.js +4 -4
- package/src/subfieldValueNormalizations.js +3 -3
- package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
- package/src/sync-007-and-300.js +2 -2
- package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
- package/src/translate-terms.js +3 -3
- package/src/translate-terms.test.js +75 -0
- package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
- package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
- package/src/update-field-540.js +2 -2
- package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
- package/src/urn.js +2 -2
- package/src/{urn.spec.js → urn.test.js} +12 -13
- package/src/utils.js +21 -5
- package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
- package/test-fixtures/field-505-separators/03/record.json +3 -0
- package/test-fixtures/indicator-fixes/10/expectedResult.json +11 -0
- package/test-fixtures/indicator-fixes/10/metadata.json +4 -0
- package/test-fixtures/indicator-fixes/10/record.json +11 -0
- package/test-fixtures/merge-fields/f05/expectedResult.json +24 -0
- package/test-fixtures/merge-fields/f05/metadata.json +6 -0
- package/test-fixtures/merge-fields/f05/record.json +30 -0
- package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
- package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
- package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
- package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
- package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
- package/test-fixtures/remove-inferior-datafields/f16/expectedResult.json +12 -0
- package/test-fixtures/remove-inferior-datafields/f16/metadata.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f16/record.json +14 -0
- package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
- package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
- package/test-fixtures/translate-terms-data.js +42 -0
- package/dist/access-rights.spec.js +0 -195
- package/dist/access-rights.spec.js.map +0 -1
- package/dist/addMissingField041.spec.js +0 -45
- package/dist/addMissingField041.spec.js.map +0 -1
- package/dist/addMissingField336.spec.js +0 -45
- package/dist/addMissingField336.spec.js.map +0 -1
- package/dist/addMissingField337.spec.js +0 -43
- package/dist/addMissingField337.spec.js.map +0 -1
- package/dist/addMissingField338.spec.js +0 -45
- package/dist/addMissingField338.spec.js.map +0 -1
- package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
- package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
- package/dist/cyrillux.spec.js +0 -46
- package/dist/cyrillux.spec.js.map +0 -1
- package/dist/disambiguateSeriesStatements.spec.js +0 -51
- package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
- package/dist/double-commas.spec.js +0 -73
- package/dist/double-commas.spec.js.map +0 -1
- package/dist/duplicates-ind1.spec.js +0 -45
- package/dist/duplicates-ind1.spec.js.map +0 -1
- package/dist/empty-fields.spec.js +0 -118
- package/dist/empty-fields.spec.js.map +0 -1
- package/dist/ending-punctuation.spec.js +0 -2654
- package/dist/ending-punctuation.spec.js.map +0 -1
- package/dist/ending-whitespace.spec.js +0 -42
- package/dist/ending-whitespace.spec.js.map +0 -1
- package/dist/field-008-18-34-character-groups.spec.js +0 -51
- package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
- package/dist/field-505-separators.spec.js +0 -51
- package/dist/field-505-separators.spec.js.map +0 -1
- package/dist/field-521-fix.spec.js +0 -51
- package/dist/field-521-fix.spec.js.map +0 -1
- package/dist/field-exclusion.spec.js +0 -1054
- package/dist/field-exclusion.spec.js.map +0 -1
- package/dist/field-structure.spec.js +0 -535
- package/dist/field-structure.spec.js.map +0 -1
- package/dist/fields-present.spec.js +0 -121
- package/dist/fields-present.spec.js.map +0 -1
- package/dist/fix-33X.spec.js +0 -45
- package/dist/fix-33X.spec.js.map +0 -1
- package/dist/fix-country-codes.spec.js +0 -51
- package/dist/fix-country-codes.spec.js.map +0 -1
- package/dist/fix-language-codes.spec.js +0 -44
- package/dist/fix-language-codes.spec.js.map +0 -1
- package/dist/fixRelatorTerms.spec.js +0 -51
- package/dist/fixRelatorTerms.spec.js.map +0 -1
- package/dist/fixed-fields.spec.js +0 -140
- package/dist/fixed-fields.spec.js.map +0 -1
- package/dist/identical-fields.spec.js +0 -99
- package/dist/identical-fields.spec.js.map +0 -1
- package/dist/indicator-fixes.spec.js +0 -51
- package/dist/indicator-fixes.spec.js.map +0 -1
- package/dist/isbn-issn.spec.js +0 -595
- package/dist/isbn-issn.spec.js.map +0 -1
- package/dist/item-language.spec.js +0 -306
- package/dist/item-language.spec.js.map +0 -1
- package/dist/melindaCustomMergeFields.json +0 -5120
- package/dist/merge-fields.spec.js +0 -51
- package/dist/merge-fields.spec.js.map +0 -1
- package/dist/mergeField500Lisapainokset.spec.js +0 -51
- package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
- package/dist/mergeRelatorTermFields.spec.js +0 -51
- package/dist/mergeRelatorTermFields.spec.js.map +0 -1
- package/dist/modernize-502.spec.js +0 -49
- package/dist/modernize-502.spec.js.map +0 -1
- package/dist/multiple-subfield-0.spec.js +0 -51
- package/dist/multiple-subfield-0.spec.js.map +0 -1
- package/dist/non-breaking-space.spec.js +0 -42
- package/dist/non-breaking-space.spec.js.map +0 -1
- package/dist/normalize-dashes.spec.js +0 -51
- package/dist/normalize-dashes.spec.js.map +0 -1
- package/dist/normalize-identifiers.spec.js +0 -51
- package/dist/normalize-identifiers.spec.js.map +0 -1
- package/dist/normalize-qualifying-information.spec.js +0 -51
- package/dist/normalize-qualifying-information.spec.js.map +0 -1
- package/dist/normalize-utf8-diacritics.spec.js +0 -51
- package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
- package/dist/punctuation.spec.js +0 -51
- package/dist/punctuation.spec.js.map +0 -1
- package/dist/punctuation2.spec.js +0 -51
- package/dist/punctuation2.spec.js.map +0 -1
- package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
- package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
- package/dist/removeDuplicateDataFields.spec.js +0 -51
- package/dist/removeDuplicateDataFields.spec.js.map +0 -1
- package/dist/removeInferiorDataFields.spec.js +0 -51
- package/dist/removeInferiorDataFields.spec.js.map +0 -1
- package/dist/resolvable-ext-references-melinda.spec.js +0 -166
- package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
- package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
- package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
- package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
- package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
- package/dist/sort-tags.spec.js +0 -207
- package/dist/sort-tags.spec.js.map +0 -1
- package/dist/sortFields.spec.js +0 -51
- package/dist/sortFields.spec.js.map +0 -1
- package/dist/sortRelatorTerms.spec.js +0 -51
- package/dist/sortRelatorTerms.spec.js.map +0 -1
- package/dist/sortSubfields.spec.js +0 -52
- package/dist/sortSubfields.spec.js.map +0 -1
- package/dist/stripPunctuation.spec.js +0 -51
- package/dist/stripPunctuation.spec.js.map +0 -1
- package/dist/subfield-exclusion.spec.js +0 -523
- package/dist/subfield-exclusion.spec.js.map +0 -1
- package/dist/subfieldValueNormalizations.spec.js +0 -51
- package/dist/subfieldValueNormalizations.spec.js.map +0 -1
- package/dist/sync-007-and-300.spec.js +0 -51
- package/dist/sync-007-and-300.spec.js.map +0 -1
- package/dist/translate-terms.spec.js +0 -51
- package/dist/translate-terms.spec.js.map +0 -1
- package/dist/typeOfDate-008.spec.js +0 -47
- package/dist/typeOfDate-008.spec.js.map +0 -1
- package/dist/unicode-decomposition.spec.js +0 -91
- package/dist/unicode-decomposition.spec.js.map +0 -1
- package/dist/update-field-540.spec.js +0 -51
- package/dist/update-field-540.spec.js.map +0 -1
- package/dist/urn.spec.js +0 -52
- package/dist/urn.spec.js.map +0 -1
- package/src/melindaCustomMergeFields.json +0 -5120
- package/src/translate-terms.spec.js +0 -52
|
@@ -1,103 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var _normalizeIdentifiers = require("./normalize-identifiers");
|
|
15
|
-
var _debug = _interopRequireDefault(require("debug"));
|
|
16
|
-
var _normalizeSubfieldValueForComparison = require("./normalizeSubfieldValueForComparison");
|
|
17
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
-
/*
|
|
19
|
-
Note that this file contains very powerful normalizations and spells that are:
|
|
20
|
-
- meant for comparing similarity/mergability of two fields (clone, normalize, compare),
|
|
21
|
-
- and NOT for modifying the actual field!
|
|
22
|
-
|
|
23
|
-
This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.
|
|
24
|
-
Thus it is here. However, most of the testing is done via merge-reducers...
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');
|
|
28
|
-
//const debugData = debug.extend('data');
|
|
29
|
-
const debugDev = debug.extend('dev');
|
|
30
|
-
function isEnnakkotietoSubfieldG(subfield) {
|
|
31
|
-
if (subfield.code !== 'g') {
|
|
1
|
+
import clone from "clone";
|
|
2
|
+
import { fieldStripPunctuation } from "./punctuation2.js";
|
|
3
|
+
import { fieldToString, isControlSubfieldCode } from "./utils.js";
|
|
4
|
+
import { fieldNormalizeControlNumbers } from "./normalize-identifiers.js";
|
|
5
|
+
import createDebugLogger from "debug";
|
|
6
|
+
import { normalizePartData, subfieldContainsPartData } from "./normalizeSubfieldValueForComparison.js";
|
|
7
|
+
const debug = createDebugLogger("@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison");
|
|
8
|
+
const debugDev = debug.extend("dev");
|
|
9
|
+
export function isEnnakkotietoSubfieldG(subfield) {
|
|
10
|
+
if (valuelessSubfield(subfield)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (subfield.code !== "g") {
|
|
32
14
|
return false;
|
|
33
15
|
}
|
|
34
16
|
return subfield.value.match(/^ENNAKKOTIETO\.?$/gui);
|
|
35
17
|
}
|
|
36
18
|
function debugFieldComparison(oldField, newField) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// We may drop certain subfields:
|
|
40
|
-
if (oldField.subfields.length === newField.subfields.length) {
|
|
41
|
-
oldField.subfields.forEach((subfield, index) => {
|
|
42
|
-
const newValue = newField.subfields[index].value;
|
|
43
|
-
if (subfield.value !== newValue) {
|
|
44
|
-
nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
*/
|
|
49
|
-
const oldString = (0, _utils.fieldToString)(oldField);
|
|
50
|
-
const newString = (0, _utils.fieldToString)(newField);
|
|
19
|
+
const oldString = fieldToString(oldField);
|
|
20
|
+
const newString = fieldToString(newField);
|
|
51
21
|
if (oldString === newString) {
|
|
52
22
|
return;
|
|
53
23
|
}
|
|
54
|
-
//nvdebug(`NORMALIZE FIELD:\n '${fieldToString(oldField)}' =>\n '${fieldToString(newField)}'`, debugDev);
|
|
55
24
|
}
|
|
56
|
-
function containsHumanName(tag =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (subfieldCode === undefined || subfieldCode === 'a') {
|
|
25
|
+
function containsHumanName(tag = "???", subfieldCode = void 0) {
|
|
26
|
+
if (["100", "600", "700", "800"].includes(tag)) {
|
|
27
|
+
if (subfieldCode === void 0 || subfieldCode === "a") {
|
|
60
28
|
return true;
|
|
61
29
|
}
|
|
62
30
|
}
|
|
63
|
-
// Others?
|
|
64
31
|
return false;
|
|
65
32
|
}
|
|
66
|
-
function containsCorporateName(tag =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (subfieldCode === undefined || subfieldCode === 'a') {
|
|
33
|
+
function containsCorporateName(tag = "???", subfieldCode = void 0) {
|
|
34
|
+
if (["110", "610", "710", "810"].includes(tag)) {
|
|
35
|
+
if (subfieldCode === void 0 || subfieldCode === "a") {
|
|
70
36
|
return true;
|
|
71
37
|
}
|
|
72
38
|
}
|
|
73
|
-
// Others?
|
|
74
39
|
return false;
|
|
75
40
|
}
|
|
76
41
|
function skipAllSubfieldNormalizations(value, subfieldCode, tag) {
|
|
77
|
-
if (isEnnakkotietoSubfieldG({
|
|
78
|
-
'code': subfieldCode,
|
|
79
|
-
value
|
|
80
|
-
})) {
|
|
42
|
+
if (isEnnakkotietoSubfieldG({ "code": subfieldCode, value })) {
|
|
81
43
|
return true;
|
|
82
44
|
}
|
|
83
|
-
if (tag ===
|
|
84
|
-
// A
|
|
45
|
+
if (tag === "035" && ["a", "z"].includes(subfieldCode)) {
|
|
85
46
|
return true;
|
|
86
47
|
}
|
|
87
|
-
if (
|
|
48
|
+
if (isControlSubfieldCode(subfieldCode)) {
|
|
88
49
|
return true;
|
|
89
50
|
}
|
|
90
51
|
return false;
|
|
91
52
|
}
|
|
92
53
|
function skipSubfieldLowercase(value, subfieldCode, tag) {
|
|
93
|
-
|
|
94
|
-
if ((0, _normalizeSubfieldValueForComparison.subfieldContainsPartData)(tag, subfieldCode)) {
|
|
54
|
+
if (subfieldContainsPartData(tag, subfieldCode)) {
|
|
95
55
|
return true;
|
|
96
56
|
}
|
|
97
57
|
return skipAllSubfieldNormalizations(value, subfieldCode, tag);
|
|
98
58
|
}
|
|
99
59
|
function skipAllFieldNormalizations(tag) {
|
|
100
|
-
if ([
|
|
60
|
+
if (["LOW", "SID"].includes(tag)) {
|
|
101
61
|
return true;
|
|
102
62
|
}
|
|
103
63
|
return false;
|
|
@@ -106,66 +66,62 @@ function subfieldValueLowercase(value, subfieldCode, tag) {
|
|
|
106
66
|
if (skipSubfieldLowercase(value, subfieldCode, tag)) {
|
|
107
67
|
return value;
|
|
108
68
|
}
|
|
109
|
-
|
|
110
|
-
//return value.toLowerCase();
|
|
111
69
|
const newValue = value.toLowerCase();
|
|
112
70
|
if (newValue !== value) {
|
|
113
|
-
//nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);
|
|
114
|
-
//nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);
|
|
115
71
|
return newValue;
|
|
116
72
|
}
|
|
117
73
|
return value;
|
|
118
74
|
}
|
|
119
75
|
function subfieldLowercase(sf, tag) {
|
|
76
|
+
if (valuelessSubfield(sf)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
120
79
|
sf.value = subfieldValueLowercase(sf.value, sf.code, tag);
|
|
121
80
|
}
|
|
122
81
|
function fieldLowercase(field) {
|
|
123
82
|
if (skipFieldLowercase(field)) {
|
|
124
83
|
return;
|
|
125
84
|
}
|
|
126
|
-
field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (skipAllFieldNormalizations(field.tag)) {
|
|
85
|
+
field.subfields.forEach((sf) => subfieldLowercase(sf, field.tag));
|
|
86
|
+
function skipFieldLowercase(field2) {
|
|
87
|
+
if (skipAllFieldNormalizations(field2.tag)) {
|
|
130
88
|
return true;
|
|
131
89
|
}
|
|
132
|
-
|
|
133
|
-
if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {
|
|
90
|
+
if (!containsHumanName(field2.tag) && !containsCorporateName(field2.tag) && !["240", "245", "630"].includes(field2.tag)) {
|
|
134
91
|
return true;
|
|
135
92
|
}
|
|
136
93
|
return false;
|
|
137
94
|
}
|
|
138
95
|
}
|
|
139
96
|
function hack490SubfieldA(field) {
|
|
140
|
-
if (field.tag !==
|
|
97
|
+
if (field.tag !== "490") {
|
|
141
98
|
return;
|
|
142
99
|
}
|
|
143
|
-
field.subfields.forEach(sf => removeSarja(sf));
|
|
144
|
-
|
|
145
|
-
// NB! This won't work, if the punctuation has not been stripped beforehand!
|
|
100
|
+
field.subfields.forEach((sf) => removeSarja(sf));
|
|
146
101
|
function removeSarja(subfield) {
|
|
147
|
-
if (subfield
|
|
102
|
+
if (valuelessSubfield(subfield)) {
|
|
148
103
|
return;
|
|
149
104
|
}
|
|
150
|
-
|
|
105
|
+
if (subfield.code !== "a") {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, "");
|
|
151
109
|
if (tmp.length > 0) {
|
|
152
110
|
subfield.value = tmp;
|
|
153
111
|
return;
|
|
154
112
|
}
|
|
155
113
|
}
|
|
156
114
|
}
|
|
157
|
-
function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {
|
|
158
|
-
|
|
159
|
-
if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {
|
|
115
|
+
export function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {
|
|
116
|
+
if (subfieldCode === "z" && ["765", "767", "770", "772", "773", "774", "776", "777", "780", "785", "786", "787"].includes(tag)) {
|
|
160
117
|
return true;
|
|
161
118
|
}
|
|
162
|
-
if (tag ===
|
|
119
|
+
if (tag === "020" && subfieldCode === "a") {
|
|
163
120
|
return true;
|
|
164
121
|
}
|
|
165
122
|
return false;
|
|
166
123
|
}
|
|
167
124
|
function looksLikeIsbn(value) {
|
|
168
|
-
// Does not check validity!
|
|
169
125
|
if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {
|
|
170
126
|
return true;
|
|
171
127
|
}
|
|
@@ -175,111 +131,86 @@ function normalizeISBN(field) {
|
|
|
175
131
|
if (!field.subfields) {
|
|
176
132
|
return;
|
|
177
133
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));
|
|
181
|
-
relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf)); // eslint-disable-line array-callback-return
|
|
182
|
-
|
|
134
|
+
const relevantSubfields = field.subfields.filter((sf) => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));
|
|
135
|
+
relevantSubfields.forEach((sf) => normalizeIsbnSubfield(sf));
|
|
183
136
|
function normalizeIsbnSubfield(sf) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
137
|
+
if (valuelessSubfield(sf)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
sf.value = sf.value.replace(/-/ug, "");
|
|
141
|
+
sf.value = sf.value.replace(/x/u, "X");
|
|
187
142
|
}
|
|
188
143
|
}
|
|
189
144
|
function fieldSpecificHacks(field) {
|
|
190
|
-
normalizeISBN(field);
|
|
145
|
+
normalizeISBN(field);
|
|
191
146
|
hack490SubfieldA(field);
|
|
192
147
|
}
|
|
193
|
-
function fieldTrimSubfieldValues(field) {
|
|
194
|
-
field.subfields?.forEach(sf => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
148
|
+
export function fieldTrimSubfieldValues(field) {
|
|
149
|
+
field.subfields?.forEach((sf) => {
|
|
150
|
+
if (valuelessSubfield(sf)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
sf.value = sf.value.replace(/^[ \t\n]+/u, "");
|
|
154
|
+
sf.value = sf.value.replace(/[ \t\n]+$/u, "");
|
|
155
|
+
sf.value = sf.value.replace(/[ \t\n]+/gu, " ");
|
|
198
156
|
});
|
|
199
157
|
}
|
|
200
158
|
function fieldRemoveDecomposedDiacritics(field) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
159
|
+
field.subfields.forEach((sf) => {
|
|
160
|
+
if (valuelessSubfield(sf)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
204
163
|
sf.value = removeDecomposedDiacritics(sf.value);
|
|
205
164
|
});
|
|
206
165
|
}
|
|
207
|
-
function removeDecomposedDiacritics(value =
|
|
208
|
-
|
|
209
|
-
// NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)
|
|
210
|
-
// NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.
|
|
211
|
-
return String(value).replace(/\p{Diacritic}/gu, '');
|
|
166
|
+
function removeDecomposedDiacritics(value = "") {
|
|
167
|
+
return String(value).replace(/\p{Diacritic}/gu, "");
|
|
212
168
|
}
|
|
213
169
|
function normalizeSubfieldValue(value, subfieldCode, tag) {
|
|
214
|
-
// NB! For comparison of values only
|
|
215
|
-
/* eslint-disable */
|
|
216
170
|
value = subfieldValueLowercase(value, subfieldCode, tag);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (['130', '730'].includes(tag) && subfieldCode === 'a') {
|
|
223
|
-
value = value.replace(' : ', ', '); // "Halloween ends (elokuva, 2022)" vs "Halloween ends (elokuva : 2023)"
|
|
171
|
+
value = normalizePartData(value, subfieldCode, tag);
|
|
172
|
+
value = value.replace(/^\[([^[\]]+)\]/gu, "$1");
|
|
173
|
+
if (["130", "730"].includes(tag) && subfieldCode === "a") {
|
|
174
|
+
value = value.replace(" : ", ", ");
|
|
224
175
|
}
|
|
225
|
-
/* eslint-enable */
|
|
226
|
-
|
|
227
|
-
// Not going to do these in the foreseeable future, but keeping them here for discussion:
|
|
228
|
-
// Possible normalizations include but are not limited to:
|
|
229
|
-
// ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?
|
|
230
|
-
// Ø => Ö?
|
|
231
|
-
// ß => ss
|
|
232
|
-
// þ => th (NB! Both upper and lower case)
|
|
233
|
-
// ...
|
|
234
|
-
// Probably nots:
|
|
235
|
-
// ü => y (probably not, though this correlates with Finnish letter-to-sound rules)
|
|
236
|
-
// w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)
|
|
237
|
-
// I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)
|
|
238
176
|
return value;
|
|
239
177
|
}
|
|
240
|
-
function cloneAndRemovePunctuation(field) {
|
|
241
|
-
const clonedField = (
|
|
178
|
+
export function cloneAndRemovePunctuation(field) {
|
|
179
|
+
const clonedField = clone(field);
|
|
242
180
|
if (fieldSkipNormalization(field)) {
|
|
243
181
|
return clonedField;
|
|
244
182
|
}
|
|
245
|
-
|
|
183
|
+
fieldStripPunctuation(clonedField);
|
|
246
184
|
fieldTrimSubfieldValues(clonedField);
|
|
247
|
-
debugDev(
|
|
185
|
+
debugDev("PUNC");
|
|
248
186
|
debugFieldComparison(field, clonedField);
|
|
249
187
|
return clonedField;
|
|
250
188
|
}
|
|
251
189
|
function removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {
|
|
252
|
-
if (tag ===
|
|
190
|
+
if (tag === "080") {
|
|
253
191
|
return value;
|
|
254
192
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// MRA-273: Handle X00$a name initials.
|
|
259
|
-
// NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.
|
|
260
|
-
// NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.
|
|
261
|
-
if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) {
|
|
262
|
-
// 400 is used in auth records. It's not a bib field at all.
|
|
263
|
-
value = value.replace(/([A-Z]|Å|Ä|Ö)\. +/ugi, '$1.');
|
|
193
|
+
value = value.replace(/['‘’"„“”«»]/gu, "");
|
|
194
|
+
if (subfieldCode === "a" && ["100", "400", "600", "700", "800"].includes(tag)) {
|
|
195
|
+
value = value.replace(/([A-Z]|Å|Ä|Ö)\. +/ugi, "$1.");
|
|
264
196
|
}
|
|
265
197
|
return value;
|
|
266
198
|
}
|
|
267
199
|
function normalizeField(field) {
|
|
268
|
-
|
|
269
|
-
(0, _punctuation.fieldStripPunctuation)(field);
|
|
200
|
+
fieldStripPunctuation(field);
|
|
270
201
|
fieldLowercase(field);
|
|
271
|
-
|
|
202
|
+
fieldNormalizeControlNumbers(field);
|
|
272
203
|
return field;
|
|
273
204
|
}
|
|
274
|
-
function cloneAndNormalizeFieldForComparison(field) {
|
|
275
|
-
|
|
276
|
-
// Some of the normalizations might be considered a bit overkill for other purposes.
|
|
277
|
-
const clonedField = (0, _clone.default)(field);
|
|
205
|
+
export function cloneAndNormalizeFieldForComparison(field) {
|
|
206
|
+
const clonedField = clone(field);
|
|
278
207
|
if (fieldSkipNormalization(field)) {
|
|
279
208
|
return clonedField;
|
|
280
209
|
}
|
|
281
|
-
clonedField.subfields.forEach(sf => {
|
|
282
|
-
|
|
210
|
+
clonedField.subfields.forEach((sf) => {
|
|
211
|
+
if (valuelessSubfield(sf)) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
283
214
|
sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag);
|
|
284
215
|
sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);
|
|
285
216
|
});
|
|
@@ -287,14 +218,16 @@ function cloneAndNormalizeFieldForComparison(field) {
|
|
|
287
218
|
fieldRemoveDecomposedDiacritics(clonedField);
|
|
288
219
|
fieldSpecificHacks(clonedField);
|
|
289
220
|
fieldTrimSubfieldValues(clonedField);
|
|
290
|
-
debugFieldComparison(field, clonedField);
|
|
291
|
-
|
|
221
|
+
debugFieldComparison(field, clonedField);
|
|
292
222
|
return clonedField;
|
|
293
223
|
}
|
|
294
224
|
function fieldSkipNormalization(field) {
|
|
295
|
-
if (!field.subfields || [
|
|
225
|
+
if (!field.subfields || ["018", "066", "080", "083"].includes(field.tag)) {
|
|
296
226
|
return true;
|
|
297
227
|
}
|
|
298
228
|
return false;
|
|
299
229
|
}
|
|
300
|
-
|
|
230
|
+
function valuelessSubfield(sf) {
|
|
231
|
+
return sf.value === void 0;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=normalizeFieldForComparison.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeFieldForComparison.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_normalizeIdentifiers","_debug","_normalizeSubfieldValueForComparison","e","__esModule","default","debug","createDebugLogger","debugDev","extend","isEnnakkotietoSubfieldG","subfield","code","value","match","debugFieldComparison","oldField","newField","oldString","fieldToString","newString","containsHumanName","tag","subfieldCode","undefined","includes","containsCorporateName","skipAllSubfieldNormalizations","isControlSubfieldCode","skipSubfieldLowercase","subfieldContainsPartData","skipAllFieldNormalizations","subfieldValueLowercase","newValue","toLowerCase","subfieldLowercase","sf","fieldLowercase","field","skipFieldLowercase","subfields","forEach","hack490SubfieldA","removeSarja","tmp","replace","length","tagAndSubfieldCodeReferToIsbn","looksLikeIsbn","normalizeISBN","relevantSubfields","filter","normalizeIsbnSubfield","fieldSpecificHacks","fieldTrimSubfieldValues","fieldRemoveDecomposedDiacritics","removeDecomposedDiacritics","String","normalizeSubfieldValue","normalizePartData","cloneAndRemovePunctuation","clonedField","clone","fieldSkipNormalization","fieldStripPunctuation","removeCharsThatDontCarryMeaning","normalizeField","fieldNormalizeControlNumbers","cloneAndNormalizeFieldForComparison"],"sources":["../src/normalizeFieldForComparison.js"],"sourcesContent":["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function isEnnakkotietoSubfieldG(subfield) {\n if (subfield.code !== 'g') {\n return false;\n }\n return subfield.value.match(/^ENNAKKOTIETO\\.?$/gui);\n}\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) {\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) {\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n if (isEnnakkotietoSubfieldG({'code': subfieldCode, value})) {\n return true;\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag);\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag)); // eslint-disable-line array-callback-return\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf)); // eslint-disable-line array-callback-return\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|ä|ö)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp;\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf)); // eslint-disable-line array-callback-return\n\n function normalizeIsbnSubfield(sf) {\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, '');\n sf.value = sf.value.replace(/x/u, 'X');\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' ');\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'être/motivation: \"Sirén\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n sf.value = removeDecomposedDiacritics(sf.value);\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters 'å', 'ä', 'ö', 'Å', Ä', and 'Ö' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // ø => ö? Might be language dependent: 041 $a fin => ö, 041 $a eng => o?\n // Ø => Ö?\n // ß => ss\n // þ => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // ü => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['‘’\"„“”«»]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|Å|Ä|Ö)\\. +/ugi, '$1.');\n }\n\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value);\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag);\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);\n });\n\n normalizeField(clonedField);\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/normalizeFieldForComparison.js"],
|
|
4
|
+
"sourcesContent": ["/*\n Note that this file contains very powerful normalizations and spells that are:\n - meant for comparing similarity/mergability of two fields (clone, normalize, compare),\n - and NOT for modifying the actual field!\n\n This is mainly used by melinda-marc-record-merge-reducers. However, also removeInferiorDataFields fixer also used this.\n Thus it is here. However, most of the testing is done via merge-reducers...\n*/\nimport clone from 'clone';\nimport {fieldStripPunctuation} from './punctuation2.js';\nimport {fieldToString, isControlSubfieldCode} from './utils.js';\n\nimport {fieldNormalizeControlNumbers/*, normalizeControlSubfieldValue*/} from './normalize-identifiers.js';\nimport createDebugLogger from 'debug';\nimport {normalizePartData, subfieldContainsPartData} from './normalizeSubfieldValueForComparison.js';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:normalizeFieldForComparison');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nexport function isEnnakkotietoSubfieldG(subfield) {\n if (valuelessSubfield(subfield)) {\n return false;\n }\n if (subfield.code !== 'g') {\n return false;\n }\n return subfield.value.match(/^ENNAKKOTIETO\\.?$/gui);\n}\n\nfunction debugFieldComparison(oldField, newField) { // NB: Debug-only function!\n /*\n // We may drop certain subfields:\n if (oldField.subfields.length === newField.subfields.length) {\n oldField.subfields.forEach((subfield, index) => {\n const newValue = newField.subfields[index].value;\n if (subfield.value !== newValue) {\n nvdebug(`NORMALIZE SUBFIELD: '${subfield.value}' => '${newValue}'`, debugDev);\n }\n });\n }\n */\n const oldString = fieldToString(oldField);\n const newString = fieldToString(newField);\n if (oldString === newString) {\n return;\n }\n //nvdebug(`NORMALIZE FIELD:\\n '${fieldToString(oldField)}' =>\\n '${fieldToString(newField)}'`, debugDev);\n}\n\nfunction containsHumanName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['100', '600', '700', '800'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction containsCorporateName(tag = '???', subfieldCode = undefined) {\n // NB! This set is for bibs! Auth has 400... What else...\n if (['110', '610', '710', '810'].includes(tag)) {\n if (subfieldCode === undefined || subfieldCode === 'a') {\n return true;\n }\n }\n // Others?\n return false;\n}\n\nfunction skipAllSubfieldNormalizations(value, subfieldCode, tag) {\n\n if (isEnnakkotietoSubfieldG({'code': subfieldCode, value})) {\n return true;\n }\n\n if (tag === '035' && ['a', 'z'].includes(subfieldCode)) { // A\n return true;\n }\n\n if (isControlSubfieldCode(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nfunction skipSubfieldLowercase(value, subfieldCode, tag) {\n // These may contain Roman Numerals...\n if (subfieldContainsPartData(tag, subfieldCode)) {\n return true;\n }\n\n return skipAllSubfieldNormalizations(value, subfieldCode, tag);\n}\n\nfunction skipAllFieldNormalizations(tag) {\n if (['LOW', 'SID'].includes(tag)) {\n return true;\n }\n return false;\n}\n\n\nfunction subfieldValueLowercase(value, subfieldCode, tag) {\n if (skipSubfieldLowercase(value, subfieldCode, tag)) {\n return value;\n }\n\n //return value.toLowerCase();\n const newValue = value.toLowerCase();\n if (newValue !== value) {\n //nvdebug(`SVL ${tag} $${subfieldCode} '${value}' =>`, debugDev);\n //nvdebug(`SVL ${tag} $${subfieldCode} '${newValue}'`, debugDev);\n return newValue;\n }\n return value;\n}\n\nfunction subfieldLowercase(sf, tag) {\n if (valuelessSubfield(sf)) {\n return;\n }\n sf.value = subfieldValueLowercase(sf.value, sf.code, tag);\n}\n\nfunction fieldLowercase(field) {\n if (skipFieldLowercase(field)) {\n return;\n }\n\n field.subfields.forEach(sf => subfieldLowercase(sf, field.tag));\n\n function skipFieldLowercase(field) {\n if (skipAllFieldNormalizations(field.tag)) {\n return true;\n }\n // Skip non-interesting fields\n if (!containsHumanName(field.tag) && !containsCorporateName(field.tag) && !['240', '245', '630'].includes(field.tag)) {\n return true;\n }\n\n return false;\n }\n}\n\n\nfunction hack490SubfieldA(field) {\n if (field.tag !== '490') {\n return;\n }\n field.subfields.forEach(sf => removeSarja(sf));\n\n // NB! This won't work, if the punctuation has not been stripped beforehand!\n function removeSarja(subfield) {\n if (valuelessSubfield(subfield)) {\n return;\n }\n\n if (subfield.code !== 'a') {\n return;\n }\n const tmp = subfield.value.replace(/ ?-(?:[a-z]|\u00E4|\u00F6)*sarja$/u, '');\n if (tmp.length > 0) {\n subfield.value = tmp;\n return;\n }\n }\n}\n\nexport function tagAndSubfieldCodeReferToIsbn(tag, subfieldCode) {\n // NB! We don't do this to 020$z!\n if (subfieldCode === 'z' && ['765', '767', '770', '772', '773', '774', '776', '777', '780', '785', '786', '787'].includes(tag)) {\n return true;\n }\n if (tag === '020' && subfieldCode === 'a') {\n return true;\n }\n return false;\n}\n\nfunction looksLikeIsbn(value) {\n // Does not check validity!\n if (value.match(/^(?:[0-9]-?){9}(?:[0-9]-?[0-9]-?[0-9]-?)?[0-9Xx]$/u)) {\n return true;\n }\n return false;\n}\n\nfunction normalizeISBN(field) {\n if (!field.subfields) {\n return;\n }\n\n //nvdebug(`ISBN-field? ${fieldToString(field)}`);\n const relevantSubfields = field.subfields.filter(sf => tagAndSubfieldCodeReferToIsbn(field.tag, sf.code) && looksLikeIsbn(sf.value));\n relevantSubfields.forEach(sf => normalizeIsbnSubfield(sf));\n\n function normalizeIsbnSubfield(sf) {\n if (valuelessSubfield(sf)) {\n return;\n }\n //nvdebug(` ISBN-subfield? ${subfieldToString(sf)}`);\n sf.value = sf.value.replace(/-/ug, '');\n sf.value = sf.value.replace(/x/u, 'X');\n }\n\n}\n\nfunction fieldSpecificHacks(field) {\n normalizeISBN(field); // 020$a, not $z!\n hack490SubfieldA(field);\n}\n\nexport function fieldTrimSubfieldValues(field) {\n field.subfields?.forEach((sf) => {\n if (valuelessSubfield(sf)) {\n return;\n }\n sf.value = sf.value.replace(/^[ \\t\\n]+/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+$/u, '');\n sf.value = sf.value.replace(/[ \\t\\n]+/gu, ' ');\n });\n}\n\nfunction fieldRemoveDecomposedDiacritics(field) {\n // Raison d'\u00EAtre/motivation: \"Sir\u00E9n\" and diacriticless \"Siren\" might refer to a same surname, so this normalization\n // allows us to compare authors and avoid duplicate fields.\n field.subfields.forEach((sf) => {\n if (valuelessSubfield(sf)) {\n return;\n }\n sf.value = removeDecomposedDiacritics(sf.value);\n });\n}\n\nfunction removeDecomposedDiacritics(value = '') {\n // NB #1: Does nothing to precomposed letters. Do String.normalize('NFD') first, if you want to handle them.\n // NB #2: Finnish letters '\u00E5', '\u00E4', '\u00F6', '\u00C5', \u00C4', and '\u00D6' should be handled (=precomposed) before calling this. (= keep them as is)\n // NB #3: Calling our very own fixComposition() before this function handles both #1 and #2.\n return String(value).replace(/\\p{Diacritic}/gu, '');\n}\n\nfunction normalizeSubfieldValue(value, subfieldCode, tag) {\n // NB! For comparison of values only\n /* eslint-disable */\n value = subfieldValueLowercase(value, subfieldCode, tag);\n\n // Normalize: s. = sivut = pp.\n value = normalizePartData(value, subfieldCode, tag);\n value = value.replace(/^\\[([^[\\]]+)\\]/gu, '$1'); // eslint-disable-line functional/immutable-data\n\n if (['130', '730'].includes(tag) && subfieldCode === 'a') {\n value = value.replace(' : ', ', '); // \"Halloween ends (elokuva, 2022)\" vs \"Halloween ends (elokuva : 2023)\"\n }\n /* eslint-enable */\n\n // Not going to do these in the foreseeable future, but keeping them here for discussion:\n // Possible normalizations include but are not limited to:\n // \u00F8 => \u00F6? Might be language dependent: 041 $a fin => \u00F6, 041 $a eng => o?\n // \u00D8 => \u00D6?\n // \u00DF => ss\n // \u00FE => th (NB! Both upper and lower case)\n // ...\n // Probably nots:\n // \u00FC => y (probably not, though this correlates with Finnish letter-to-sound rules)\n // w => v (OK for Finnish sorting in certain cases, but we are not here, are we?)\n // I guess we should use decomposed values in code here. (Not sure what composition my examples above use.)\n return value;\n}\n\nexport function cloneAndRemovePunctuation(field) {\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n fieldStripPunctuation(clonedField);\n fieldTrimSubfieldValues(clonedField);\n debugDev('PUNC');\n debugFieldComparison(field, clonedField);\n\n return clonedField;\n}\n\nfunction removeCharsThatDontCarryMeaning(value, tag, subfieldCode) {\n if (tag === '080') {\n return value;\n }\n\n // 3\" refers to inches, but as this is for comparison only we don't mind...\n value = value.replace(/['\u2018\u2019\"\u201E\u201C\u201D\u00AB\u00BB]/gu, ''); // MET-570 et al. Subset of https://hexdocs.pm/ex_unicode/Unicode.Category.QuoteMarks.html\n // MRA-273: Handle X00$a name initials.\n // NB #1: that we remove spaces for comparison (as it simpler), though actually space should be used. Doesn't matter as this is comparison only.\n // NB #2: we might/should eventually write a validator/fixer that adds those spaces. After that point, this expection should become obsolete.\n if (subfieldCode === 'a' && ['100', '400', '600', '700', '800'].includes(tag)) { // 400 is used in auth records. It's not a bib field at all.\n value = value.replace(/([A-Z]|\u00C5|\u00C4|\u00D6)\\. +/ugi, '$1.');\n }\n\n return value;\n}\n\nfunction normalizeField(field) {\n //sf.value = removeDecomposedDiacritics(sf.value);\n fieldStripPunctuation(field);\n fieldLowercase(field);\n fieldNormalizeControlNumbers(field); // FIN11 vs FI-MELINDA etc.\n return field;\n}\n\nexport function cloneAndNormalizeFieldForComparison(field) {\n // NB! This new field is for comparison purposes only.\n // Some of the normalizations might be considered a bit overkill for other purposes.\n const clonedField = clone(field);\n if (fieldSkipNormalization(field)) {\n return clonedField;\n }\n clonedField.subfields.forEach((sf) => { // Do this for all fields or some fields?\n if (valuelessSubfield(sf)) {\n return;\n }\n sf.value = normalizeSubfieldValue(sf.value, sf.code, field.tag);\n sf.value = removeCharsThatDontCarryMeaning(sf.value, field.tag, sf.code);\n });\n\n normalizeField(clonedField);\n fieldRemoveDecomposedDiacritics(clonedField);\n fieldSpecificHacks(clonedField);\n fieldTrimSubfieldValues(clonedField);\n\n\n debugFieldComparison(field, clonedField); // For debugging purposes only\n\n return clonedField;\n}\n\nfunction fieldSkipNormalization(field) {\n if (!field.subfields || ['018', '066', '080', '083'].includes(field.tag)) {\n return true;\n }\n return false;\n}\n\nfunction valuelessSubfield(sf) {\n return sf.value === undefined;\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["field"]
|
|
7
|
+
}
|