@natlibfi/marc-record-validators-melinda 10.11.1 → 10.12.0-alpha.2

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 (43) hide show
  1. package/dist/prepublicationUtils.js +242 -0
  2. package/dist/prepublicationUtils.js.map +1 -0
  3. package/dist/punctuation2.js +106 -66
  4. package/dist/punctuation2.js.map +1 -1
  5. package/dist/removeInferiorDataFields.js +36 -14
  6. package/dist/removeInferiorDataFields.js.map +1 -1
  7. package/dist/sortSubfields.js +36 -9
  8. package/dist/sortSubfields.js.map +1 -1
  9. package/dist/subfieldValueNormalizations.js +23 -9
  10. package/dist/subfieldValueNormalizations.js.map +1 -1
  11. package/dist/utils.js +4 -0
  12. package/dist/utils.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/prepublicationUtils.js +263 -0
  15. package/src/punctuation2.js +39 -22
  16. package/src/removeInferiorDataFields.js +38 -14
  17. package/src/sortSubfields.js +38 -8
  18. package/src/subfieldValueNormalizations.js +29 -9
  19. package/src/utils.js +4 -0
  20. package/test-fixtures/normalize-subfield-value/01/expectedResult.json +2 -0
  21. package/test-fixtures/normalize-subfield-value/01/record.json +6 -2
  22. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +2 -2
  23. package/test-fixtures/remove-inferior-datafields/f02a/expectedResult.json +15 -0
  24. package/test-fixtures/remove-inferior-datafields/f02a/metadata.json +6 -0
  25. package/test-fixtures/remove-inferior-datafields/f02a/record.json +25 -0
  26. package/test-fixtures/remove-inferior-datafields/f02b/expectedResult.json +15 -0
  27. package/test-fixtures/remove-inferior-datafields/f02b/metadata.json +6 -0
  28. package/test-fixtures/remove-inferior-datafields/f02b/record.json +25 -0
  29. package/test-fixtures/remove-inferior-datafields/f05/expectedResult.json +2 -9
  30. package/test-fixtures/remove-inferior-datafields/f07a/expectedResult.json +46 -0
  31. package/test-fixtures/remove-inferior-datafields/f07a/metadata.json +6 -0
  32. package/test-fixtures/remove-inferior-datafields/f07a/record.json +45 -0
  33. package/test-fixtures/remove-inferior-datafields/f07b/expectedResult.json +30 -0
  34. package/test-fixtures/remove-inferior-datafields/f07b/metadata.json +6 -0
  35. package/test-fixtures/remove-inferior-datafields/f07b/record.json +45 -0
  36. package/test-fixtures/remove-inferior-datafields/f07c/expectedResult.json +28 -0
  37. package/test-fixtures/remove-inferior-datafields/f07c/metadata.json +6 -0
  38. package/test-fixtures/remove-inferior-datafields/f07c/record.json +32 -0
  39. package/test-fixtures/remove-inferior-datafields/f08/expectedResult.json +22 -0
  40. package/test-fixtures/remove-inferior-datafields/f08/metadata.json +6 -0
  41. package/test-fixtures/remove-inferior-datafields/f08/record.json +33 -0
  42. package/test-fixtures/sort-subfields/f01/expectedResult.json +5 -1
  43. package/test-fixtures/sort-subfields/f01/record.json +5 -0
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.baseHasEqualOrHigherEncodingLevel = baseHasEqualOrHigherEncodingLevel;
7
+ exports.deleteAllPrepublicationNotesFromField500InNonPubRecord = deleteAllPrepublicationNotesFromField500InNonPubRecord;
8
+ exports.encodingLevelIsBetterThanPrepublication = encodingLevelIsBetterThanPrepublication;
9
+ exports.fieldRefersToEnnakkotieto = fieldRefersToEnnakkotieto;
10
+ exports.fieldRefersToKoneellisestiTuotettuTietue = fieldRefersToKoneellisestiTuotettuTietue;
11
+ exports.fieldRefersToTarkistettuEnnakkotieto = fieldRefersToTarkistettuEnnakkotieto;
12
+ exports.firstFieldHasBetterPrepubEncodingLevel = firstFieldHasBetterPrepubEncodingLevel;
13
+ exports.getEncodingLevel = getEncodingLevel;
14
+ exports.getPrepublicationLevel = getPrepublicationLevel;
15
+ exports.getRelevant5XXFields = getRelevant5XXFields;
16
+ exports.isEnnakkotietoField = isEnnakkotietoField;
17
+ exports.isEnnakkotietoSubfield = isEnnakkotietoSubfield;
18
+ exports.isFikkaRecord = isFikkaRecord;
19
+ exports.isKingOfTheHill = isKingOfTheHill;
20
+ exports.prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto = prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto;
21
+ exports.removeWorsePrepubField500s = removeWorsePrepubField500s;
22
+ exports.removeWorsePrepubField594s = removeWorsePrepubField594s;
23
+ var _utils = require("./utils");
24
+ var _debug = _interopRequireDefault(require("debug"));
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+ const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda:prepublicationUtils');
27
+ //const debugData = debug.extend('data');
28
+ const debugDev = debug.extend('dev');
29
+ const KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best
30
+ const TARKISTETTU_ENNAKKOTIETO = 2;
31
+ const ENNAKKOTIETO = 3;
32
+ //const EI_TASOA = 4;
33
+
34
+ const encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145
35
+ const prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');
36
+ function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {
37
+ return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;
38
+ }
39
+ function encodingLevelIsBetterThanPrepublication(encodingLevel) {
40
+ const index = encodingLevelPreferenceArray.indexOf(encodingLevel);
41
+ return index > -1 && index < prepublicationLevelIndex;
42
+ }
43
+ function containsSubstringInSubfieldA(field, substring) {
44
+ return field.subfields.some(sf => sf.code === 'a' && sf.value.includes(substring));
45
+ }
46
+
47
+ // These three functions below all refer to field 500:
48
+ function fieldRefersToKoneellisestiTuotettuTietue(field) {
49
+ return containsSubstringInSubfieldA(field, 'Koneellisesti tuotettu tietue');
50
+ }
51
+ function fieldRefersToTarkistettuEnnakkotieto(field) {
52
+ return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO');
53
+ }
54
+ function fieldRefersToEnnakkotieto(field) {
55
+ // NB! This matches also 'TARKISTETTU ENNAKKOTIETO' case!
56
+ return containsSubstringInSubfieldA(field, 'ENNAKKOTIETO');
57
+ }
58
+ function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {
59
+ if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {
60
+ return false;
61
+ }
62
+ if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {
63
+ return true;
64
+ }
65
+ if (fieldRefersToTarkistettuEnnakkotieto(field2)) {
66
+ return false;
67
+ }
68
+ if (fieldRefersToTarkistettuEnnakkotieto(field1)) {
69
+ return true;
70
+ }
71
+ if (fieldRefersToEnnakkotieto(field2)) {
72
+ return false;
73
+ }
74
+ if (fieldRefersToEnnakkotieto(field1)) {
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+
80
+ /*
81
+ export function firstFieldHasEqualOrBetterPrepubEncodingLevel(field1, field2) {
82
+ // Could be optimized...
83
+ if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {
84
+ return true;
85
+ }
86
+ if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {
87
+ return false;
88
+ }
89
+ if (fieldRefersToTarkistettuEnnakkotieto(field1)) {
90
+ return true;
91
+ }
92
+ if (fieldRefersToTarkistettuEnnakkotieto(field2)) {
93
+ return false;
94
+ }
95
+ if (fieldRefersToEnnakkotieto(field1)) {
96
+ return true;
97
+ }
98
+ return !fieldRefersToEnnakkotieto(field2);
99
+ }
100
+ */
101
+
102
+ /*
103
+ function hasEnnakkotietoSubfield(field) {
104
+ return field.subfields.some(sf => ['g', '9'].includes(sf.code) && sf.value.includes('ENNAKKOTIETO'));
105
+ }
106
+ */
107
+
108
+ /*
109
+ export function isPrepublicationField6XX(field) {
110
+ if (!field.tag.match(/^6(?:[0-4][0-9]|5[0-5])$/u)) { // Not within 600 ... 655 range
111
+ return false;
112
+ }
113
+ return field.subfields.some(sf => hasEnnakkotietoSubfield(sf));
114
+ }
115
+ */
116
+
117
+ function getRelevant5XXFields(record, f500 = false, f594 = false) {
118
+ const cands = actualGetFields();
119
+ //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);
120
+ const filtered = cands.filter(field => hasRelevantPrepubData(field));
121
+ //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);
122
+ return filtered;
123
+
124
+ //return actualGetFields().filter(field => hasRelevantPrepubData(field));
125
+
126
+ function hasRelevantPrepubData(field) {
127
+ // Check prepub ($a):
128
+ if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToEnnakkotieto(field)) {
129
+ return false;
130
+ }
131
+ // Check relevance (594$5):
132
+ if (field.tag === '500') {
133
+ return field.subfields.every(sf => sf.code !== '5'); //true;
134
+ }
135
+
136
+ return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));
137
+ }
138
+ function actualGetFields() {
139
+ if (f500 && f594) {
140
+ return record.get(/^(?:500|594)$/u);
141
+ }
142
+ if (f500) {
143
+ return record.get(/^500$/u);
144
+ }
145
+ if (f594) {
146
+ return record.get(/^594$/u);
147
+ }
148
+ return [];
149
+ }
150
+ }
151
+
152
+ // Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...
153
+ // We should use that and not have a copy here...
154
+ function getPrepublicationLevel(record, f500 = false, f594 = false) {
155
+ // Smaller return value is better
156
+ const fields = getRelevant5XXFields(record, f500, f594);
157
+ if (!fields) {
158
+ return null;
159
+ }
160
+ if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {
161
+ return KONEELLISESTI_TUOTETTU_TIETUE;
162
+ }
163
+ if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {
164
+ return TARKISTETTU_ENNAKKOTIETO;
165
+ }
166
+ if (fields.some(f => fieldRefersToEnnakkotieto(f))) {
167
+ return ENNAKKOTIETO;
168
+ }
169
+ return null;
170
+ }
171
+ function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {
172
+ const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);
173
+ const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);
174
+ if (baseIndex === -1) {
175
+ // Base wins if both are bad:
176
+ return sourceIndex === -1;
177
+ }
178
+ return baseIndex <= sourceIndex;
179
+ }
180
+ function hasFikkaLOW(record) {
181
+ return record.fields.some(field => field.tag === 'LOW' && (0, _utils.fieldHasSubfield)(field, 'a', 'FIKKA'));
182
+ }
183
+ function hasNatLibFi042(record) {
184
+ return record.fields.some(field => field.tag === '042' && ((0, _utils.fieldHasSubfield)(field, 'a', 'finb') || (0, _utils.fieldHasSubfield)(field, 'a', 'finbd')));
185
+ }
186
+ function isFikkaRecord(record) {
187
+ // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?
188
+ return hasFikkaLOW(record) && hasNatLibFi042(record);
189
+ }
190
+ function getEncodingLevel(record) {
191
+ return record.leader.substring(17, 18);
192
+ }
193
+ function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {
194
+ const encodingLevel = getEncodingLevel(record);
195
+ // Skip prepublication (or theoretically even worse) records:
196
+ if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {
197
+ //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here
198
+ return;
199
+ }
200
+
201
+ // MET-306: keep "koneellisesti tuotettu tietue" if encodng level is '2':
202
+ const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);
203
+ if (f500.length === 0) {
204
+ return;
205
+ }
206
+ (0, _utils.nvdebug)(`Delete all ${f500.length} instance(s) of field 500`, debugDev);
207
+ f500.forEach(field => record.removeField(field));
208
+ }
209
+ function removeWorsePrepubField500s(record) {
210
+ // Remove lower-level entries:
211
+ const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true
212
+ (0, _utils.nvdebugFieldArray)(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);
213
+ const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));
214
+ (0, _utils.nvdebugFieldArray)(nonBest, ' Remove non-best 500: ', debugDev);
215
+ nonBest.forEach(field => record.removeField(field));
216
+ }
217
+ function removeWorsePrepubField594s(record) {
218
+ // Remove lower-level entries:
219
+ const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true
220
+ (0, _utils.nvdebugFieldArray)(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);
221
+ const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));
222
+ (0, _utils.nvdebugFieldArray)(nonBest, ' Remove non-best 594: ', debugDev);
223
+ nonBest.forEach(field => record.removeField(field));
224
+ }
225
+ function isEnnakkotietoSubfield(subfield) {
226
+ if (subfield.code !== '9' && subfield.code !== 'g') {
227
+ return false;
228
+ }
229
+ // Length <= 13 allows punctuation, but does not require it:
230
+ if (subfield.value.substr(0, 12) === 'ENNAKKOTIETO' && subfield.value.length <= 13) {
231
+ return true;
232
+ }
233
+ return false;
234
+ }
235
+ function isEnnakkotietoField(field) {
236
+ return field.subfields.some(sf => isEnnakkotietoSubfield(sf));
237
+ }
238
+ function isKingOfTheHill(field, opposingFields) {
239
+ // Field is no better than at least one of the opposing fields
240
+ return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));
241
+ }
242
+ //# sourceMappingURL=prepublicationUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepublicationUtils.js","names":["_utils","require","_debug","_interopRequireDefault","obj","__esModule","default","debug","createDebugLogger","debugDev","extend","KONEELLISESTI_TUOTETTU_TIETUE","TARKISTETTU_ENNAKKOTIETO","ENNAKKOTIETO","encodingLevelPreferenceArray","prepublicationLevelIndex","indexOf","prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto","prepublicationLevel","encodingLevelIsBetterThanPrepublication","encodingLevel","index","containsSubstringInSubfieldA","field","substring","subfields","some","sf","code","value","includes","fieldRefersToKoneellisestiTuotettuTietue","fieldRefersToTarkistettuEnnakkotieto","fieldRefersToEnnakkotieto","firstFieldHasBetterPrepubEncodingLevel","field1","field2","getRelevant5XXFields","record","f500","f594","cands","actualGetFields","filtered","filter","hasRelevantPrepubData","tag","every","get","getPrepublicationLevel","fields","f","baseHasEqualOrHigherEncodingLevel","baseEncodingLevel","sourceEncodingLevel","baseIndex","sourceIndex","hasFikkaLOW","fieldHasSubfield","hasNatLibFi042","isFikkaRecord","getEncodingLevel","leader","deleteAllPrepublicationNotesFromField500InNonPubRecord","length","nvdebug","forEach","removeField","removeWorsePrepubField500s","nvdebugFieldArray","nonBest","removeWorsePrepubField594s","fields594","isEnnakkotietoSubfield","subfield","substr","isEnnakkotietoField","isKingOfTheHill","opposingFields","opposingField"],"sources":["../src/prepublicationUtils.js"],"sourcesContent":["import {fieldHasSubfield, nvdebug, nvdebugFieldArray} from './utils';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:prepublicationUtils');\n//const debugData = debug.extend('data');\nconst debugDev = debug.extend('dev');\n\nconst KONEELLISESTI_TUOTETTU_TIETUE = 1; // Best\nconst TARKISTETTU_ENNAKKOTIETO = 2;\nconst ENNAKKOTIETO = 3;\n//const EI_TASOA = 4;\n\nconst encodingLevelPreferenceArray = [' ', '1', '3', '4', '5', '2', '7', 'u', 'z', '8']; // MET-145\nconst prepublicationLevelIndex = encodingLevelPreferenceArray.indexOf('8');\n\nexport function prepublicationLevelIsKoneellisestiTuotettuTietueOrTarkistettuEnnakkotieto(prepublicationLevel) {\n return prepublicationLevel === KONEELLISESTI_TUOTETTU_TIETUE || prepublicationLevel === TARKISTETTU_ENNAKKOTIETO;\n}\n\n\nexport function encodingLevelIsBetterThanPrepublication(encodingLevel) {\n const index = encodingLevelPreferenceArray.indexOf(encodingLevel);\n return index > -1 && index < prepublicationLevelIndex;\n}\n\n\nfunction containsSubstringInSubfieldA(field, substring) {\n return field.subfields.some(sf => sf.code === 'a' && sf.value.includes(substring));\n}\n\n\n// These three functions below all refer to field 500:\nexport function fieldRefersToKoneellisestiTuotettuTietue(field) {\n return containsSubstringInSubfieldA(field, 'Koneellisesti tuotettu tietue');\n}\n\n\nexport function fieldRefersToTarkistettuEnnakkotieto(field) {\n return containsSubstringInSubfieldA(field, 'TARKISTETTU ENNAKKOTIETO');\n}\n\n\nexport function fieldRefersToEnnakkotieto(field) {\n // NB! This matches also 'TARKISTETTU ENNAKKOTIETO' case!\n return containsSubstringInSubfieldA(field, 'ENNAKKOTIETO');\n}\n\n\nexport function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return false;\n}\n\n/*\nexport function firstFieldHasEqualOrBetterPrepubEncodingLevel(field1, field2) {\n // Could be optimized...\n if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {\n return true;\n }\n if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {\n return false;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field1)) {\n return true;\n }\n if (fieldRefersToTarkistettuEnnakkotieto(field2)) {\n return false;\n }\n if (fieldRefersToEnnakkotieto(field1)) {\n return true;\n }\n return !fieldRefersToEnnakkotieto(field2);\n}\n*/\n\n/*\nfunction hasEnnakkotietoSubfield(field) {\n return field.subfields.some(sf => ['g', '9'].includes(sf.code) && sf.value.includes('ENNAKKOTIETO'));\n}\n*/\n\n/*\nexport function isPrepublicationField6XX(field) {\n if (!field.tag.match(/^6(?:[0-4][0-9]|5[0-5])$/u)) { // Not within 600 ... 655 range\n return false;\n }\n return field.subfields.some(sf => hasEnnakkotietoSubfield(sf));\n}\n*/\n\n\nexport function getRelevant5XXFields(record, f500 = false, f594 = false) {\n const cands = actualGetFields();\n //nvdebugFieldArray(cands, 'gR5XXa: ', debugDev);\n const filtered = cands.filter(field => hasRelevantPrepubData(field));\n //nvdebugFieldArray(filtered, 'gR5XXb: ', debugDev);\n return filtered;\n\n //return actualGetFields().filter(field => hasRelevantPrepubData(field));\n\n function hasRelevantPrepubData(field) {\n // Check prepub ($a):\n if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToEnnakkotieto(field)) {\n return false;\n }\n // Check relevance (594$5):\n if (field.tag === '500') {\n return field.subfields.every(sf => sf.code !== '5'); //true;\n }\n return field.subfields.some(sf => sf.code === '5' && ['FENNI', 'FIKKA', 'VIOLA'].includes(sf.value));\n }\n\n function actualGetFields() {\n if (f500 && f594) {\n return record.get(/^(?:500|594)$/u);\n }\n if (f500) {\n return record.get(/^500$/u);\n }\n if (f594) {\n return record.get(/^594$/u);\n }\n return [];\n }\n\n}\n\n\n// Very similar to getPrepublicationLevel() in melinda-record-match-validator's getPrepublicationLevel()...\n// We should use that and not have a copy here...\nexport function getPrepublicationLevel(record, f500 = false, f594 = false) {\n // Smaller return value is better\n const fields = getRelevant5XXFields(record, f500, f594);\n\n if (!fields) {\n return null;\n }\n if (fields.some(f => fieldRefersToKoneellisestiTuotettuTietue(f))) {\n return KONEELLISESTI_TUOTETTU_TIETUE;\n }\n\n if (fields.some(f => fieldRefersToTarkistettuEnnakkotieto(f))) {\n return TARKISTETTU_ENNAKKOTIETO;\n }\n\n if (fields.some(f => fieldRefersToEnnakkotieto(f))) {\n return ENNAKKOTIETO;\n }\n\n return null;\n}\n\n\nexport function baseHasEqualOrHigherEncodingLevel(baseEncodingLevel, sourceEncodingLevel) {\n const baseIndex = encodingLevelPreferenceArray.indexOf(baseEncodingLevel);\n const sourceIndex = encodingLevelPreferenceArray.indexOf(sourceEncodingLevel);\n\n if (baseIndex === -1) {\n // Base wins if both are bad:\n return sourceIndex === -1;\n }\n return baseIndex <= sourceIndex;\n}\n\n\nfunction hasFikkaLOW(record) {\n return record.fields.some(field => field.tag === 'LOW' && fieldHasSubfield(field, 'a', 'FIKKA'));\n}\n\n\nfunction hasNatLibFi042(record) {\n return record.fields.some(field => field.tag === '042' && (fieldHasSubfield(field, 'a', 'finb') || fieldHasSubfield(field, 'a', 'finbd')));\n}\n\n\nexport function isFikkaRecord(record) {\n // NB! Does not include Humaniora. Pienpainatteet (not that they'd have duplicates)?\n return hasFikkaLOW(record) && hasNatLibFi042(record);\n}\n\n\nexport function getEncodingLevel(record) {\n return record.leader.substring(17, 18);\n}\n\n\nexport function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {\n const encodingLevel = getEncodingLevel(record);\n // Skip prepublication (or theoretically even worse) records:\n if (!encodingLevelIsBetterThanPrepublication(encodingLevel)) {\n //if (['2', '8'].includes(encodingLevel)) { // MET-306: added '2' here\n return;\n }\n\n // MET-306: keep \"koneellisesti tuotettu tietue\" if encodng level is '2':\n const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);\n if (f500.length === 0) {\n return;\n }\n\n\n nvdebug(`Delete all ${f500.length} instance(s) of field 500`, debugDev);\n f500.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField500s(record) {\n // Remove lower-level entries:\n const fields = getRelevant5XXFields(record, true, false); // 500=false, 594=true\n nvdebugFieldArray(fields, ' Candidates for non-best 500 b4 filtering: ', debugDev);\n const nonBest = fields.filter(field => fields.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 500: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function removeWorsePrepubField594s(record) {\n // Remove lower-level entries:\n const fields594 = getRelevant5XXFields(record, false, true); // 500=false, 594=true\n nvdebugFieldArray(fields594, ' Candidates for non-best 594 b4 filtering: ', debugDev);\n const nonBest = fields594.filter(field => fields594.some(field2 => firstFieldHasBetterPrepubEncodingLevel(field2, field)));\n nvdebugFieldArray(nonBest, ' Remove non-best 594: ', debugDev);\n nonBest.forEach(field => record.removeField(field));\n}\n\n\nexport function isEnnakkotietoSubfield(subfield) {\n if (subfield.code !== '9' && subfield.code !== 'g') {\n return false;\n }\n // Length <= 13 allows punctuation, but does not require it:\n if (subfield.value.substr(0, 12) === 'ENNAKKOTIETO' && subfield.value.length <= 13) {\n return true;\n }\n return false;\n}\n\nexport function isEnnakkotietoField(field) {\n return field.subfields.some(sf => isEnnakkotietoSubfield(sf));\n}\n\nexport function isKingOfTheHill(field, opposingFields) {\n // Field is no better than at least one of the opposing fields\n return opposingFields.every(opposingField => firstFieldHasBetterPrepubEncodingLevel(field, opposingField));\n}\n\n"],"mappings":"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"}
@@ -340,6 +340,47 @@ const cleanLegalSeriesTitle = [
340
340
  'followedBy': 'v',
341
341
  'remove': / *;$/u
342
342
  }];
343
+ const clean24X = [{
344
+ 'name': 'I:A',
345
+ 'code': 'i',
346
+ 'followedBy': 'i',
347
+ 'remove': / *:$/u
348
+ }, {
349
+ 'name': 'A:B',
350
+ 'code': 'a',
351
+ 'followedBy': 'b',
352
+ 'remove': / [:;=]$/u
353
+ }, {
354
+ 'name': 'AB:K',
355
+ 'code': 'ab',
356
+ 'followedBy': 'k',
357
+ 'remove': / :$/u
358
+ }, {
359
+ 'name': 'ABK:F',
360
+ 'code': 'abk',
361
+ 'followedBy': 'f',
362
+ 'remove': /,$/u
363
+ }, {
364
+ 'name': 'ABFNP:C',
365
+ 'code': 'abfnp',
366
+ 'followedBy': 'c',
367
+ 'remove': / \/$/u
368
+ }, {
369
+ 'name': 'ABN:N',
370
+ 'code': 'abn',
371
+ 'followedBy': 'n',
372
+ 'remove': /\.$/u
373
+ }, {
374
+ 'name': 'ABNP:#',
375
+ 'code': 'abnp',
376
+ 'followedBy': '#',
377
+ 'remove': /\.$/u
378
+ }, {
379
+ 'name': 'N:P',
380
+ 'code': 'n',
381
+ 'followedBy': 'p',
382
+ 'remove': /,$/u
383
+ }];
343
384
  const cleanValidPunctuationRules = {
344
385
  '100': legalX00punc,
345
386
  '110': legalX10punc,
@@ -349,42 +390,8 @@ const cleanValidPunctuationRules = {
349
390
  '710': legalX10punc,
350
391
  '800': legalX00punc,
351
392
  '810': legalX10punc,
352
- '245': [{
353
- 'name': 'A:B',
354
- 'code': 'a',
355
- 'followedBy': 'b',
356
- 'remove': / [:;=]$/u
357
- }, {
358
- 'name': 'AB:K',
359
- 'code': 'ab',
360
- 'followedBy': 'k',
361
- 'remove': / :$/u
362
- }, {
363
- 'name': 'ABK:F',
364
- 'code': 'abk',
365
- 'followedBy': 'f',
366
- 'remove': /,$/u
367
- }, {
368
- 'name': 'ABFNP:C',
369
- 'code': 'abfnp',
370
- 'followedBy': 'c',
371
- 'remove': / \/$/u
372
- }, {
373
- 'name': 'ABN:N',
374
- 'code': 'abn',
375
- 'followedBy': 'n',
376
- 'remove': /\.$/u
377
- }, {
378
- 'name': 'ABNP:#',
379
- 'code': 'abnp',
380
- 'followedBy': '#',
381
- 'remove': /\.$/u
382
- }, {
383
- 'name': 'N:P',
384
- 'code': 'n',
385
- 'followedBy': 'p',
386
- 'remove': /,$/u
387
- }],
393
+ '245': clean24X,
394
+ '246': clean24X,
388
395
  '260': [{
389
396
  'code': 'a',
390
397
  'followedBy': 'b',
@@ -453,12 +460,66 @@ const cleanValidPunctuationRules = {
453
460
  'ind2': ['4'],
454
461
  'remove': /\.$/u
455
462
  }],
456
- '830': cleanLegalSeriesTitle
463
+ '830': cleanLegalSeriesTitle,
464
+ '946': clean24X
457
465
  };
458
466
 
459
467
  // addColonToRelationshipInformation only applies to 700/710 but as others don't have $i, it's fine
460
468
  const addX00 = [addX00aComma, addX00aComma2, addX00aDot, addLanguageComma, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation];
461
469
  const addX10 = [addX10bDot, addX10eComma, addX10Dot, addLanguageComma, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation];
470
+ const add245 = [
471
+ // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
472
+ {
473
+ 'code': 'a',
474
+ 'followedBy': 'b',
475
+ 'add': ' :',
476
+ 'context': defaultNeedsPuncAfter
477
+ }, {
478
+ 'code': 'abk',
479
+ 'followedBy': 'f',
480
+ 'add': ',',
481
+ 'context': defaultNeedsPuncAfter
482
+ }, {
483
+ 'code': 'abfnp',
484
+ 'followedBy': 'c',
485
+ 'add': ' /',
486
+ 'context': defaultNeedsPuncAfter
487
+ }, {
488
+ 'code': 'abc',
489
+ 'followedBy': '#',
490
+ 'add': '.',
491
+ 'context': defaultNeedsPuncAfter
492
+ } // Stepping on punctuation/ toes
493
+ ];
494
+
495
+ const add246 = [{
496
+ 'code': 'i',
497
+ 'followedBy': 'a',
498
+ 'add': ':',
499
+ 'context': defaultNeedsPuncAfter
500
+ }, {
501
+ 'code': 'a',
502
+ 'followedBy': 'b',
503
+ 'add': ' :',
504
+ 'context': defaultNeedsPuncAfter
505
+ }, {
506
+ 'code': 'abk',
507
+ 'followedBy': 'f',
508
+ 'add': ',',
509
+ 'context': defaultNeedsPuncAfter
510
+ }, {
511
+ 'code': 'abfnp',
512
+ 'followedBy': 'c',
513
+ 'add': ' /',
514
+ 'context': defaultNeedsPuncAfter
515
+ }, {
516
+ 'code': 'abc',
517
+ 'followedBy': '#',
518
+ 'add': '.',
519
+ 'context': defaultNeedsPuncAfter
520
+ } // Stepping on punctuation/ toes
521
+ ];
522
+
462
523
  const addSeriesTitle = [
463
524
  // 490 and 830
464
525
  {
@@ -477,31 +538,8 @@ const addSeriesTitle = [
477
538
  const addPairedPunctuationRules = {
478
539
  '100': addX00,
479
540
  '110': addX10,
480
- '245': [
481
- // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
482
- {
483
- 'code': 'a',
484
- 'followedBy': 'b',
485
- 'add': ' :',
486
- 'context': defaultNeedsPuncAfter
487
- }, {
488
- 'code': 'abk',
489
- 'followedBy': 'f',
490
- 'add': ',',
491
- 'context': defaultNeedsPuncAfter
492
- }, {
493
- 'code': 'abfnp',
494
- 'followedBy': 'c',
495
- 'add': ' /',
496
- 'context': defaultNeedsPuncAfter
497
- }, {
498
- 'code': 'abc',
499
- 'followedBy': '#',
500
- 'add': '.',
501
- 'context': defaultNeedsPuncAfter
502
- } // Stepping on punctuation/ toes
503
- ],
504
-
541
+ '245': add245,
542
+ '246': add246,
505
543
  '260': [{
506
544
  'code': 'a',
507
545
  'followedBy': 'b',
@@ -582,7 +620,8 @@ const addPairedPunctuationRules = {
582
620
  '710': addX10,
583
621
  '800': addX00,
584
622
  '810': addX10,
585
- '830': addSeriesTitle
623
+ '830': addSeriesTitle,
624
+ '946': add246
586
625
  };
587
626
  function ruleAppliesToSubfieldCode(targetSubfieldCodes, currSubfieldCode) {
588
627
  const negation = targetSubfieldCodes.includes('!');
@@ -699,12 +738,13 @@ function subfieldFixPunctuation(field, subfield1, subfield2) {
699
738
  applyPunctuationRules(field, subfield1, subfield2, addPairedPunctuationRules, ADD);
700
739
  }
701
740
  function subfieldStripPunctuation(field, subfield1, subfield2) {
702
- (0, _utils.nvdebug)(`FSP1: '${subfield1.value}'`);
741
+ //nvdebug(`FSP1: '${subfield1.value}'`);
703
742
  applyPunctuationRules(field, subfield1, subfield2, cleanValidPunctuationRules, REMOVE);
704
- (0, _utils.nvdebug)(`FSP2: '${subfield1.value}'`);
743
+ //nvdebug(`FSP2: '${subfield1.value}'`);
705
744
  applyPunctuationRules(field, subfield1, subfield2, cleanCrappyPunctuationRules, REMOVE);
706
- (0, _utils.nvdebug)(`FSP3: '${subfield1.value}'`);
745
+ //nvdebug(`FSP3: '${subfield1.value}'`);
707
746
  }
747
+
708
748
  function fieldStripPunctuation(field) {
709
749
  if (!field.subfields) {
710
750
  return field;