@natlibfi/marc-record-validators-melinda 10.13.0 → 10.13.1-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.
- package/.github/workflows/melinda-node-tests.yml +3 -3
- package/dist/field-505-separators.js +77 -0
- package/dist/field-505-separators.js.map +1 -0
- package/dist/field-505-separators.spec.js +51 -0
- package/dist/field-505-separators.spec.js.map +1 -0
- package/dist/fixRelatorTerms.js +278 -0
- package/dist/fixRelatorTerms.js.map +1 -0
- package/dist/fixRelatorTerms.spec.js +51 -0
- package/dist/fixRelatorTerms.spec.js.map +1 -0
- package/dist/index.js +101 -3
- package/dist/index.js.map +1 -1
- package/dist/normalize-qualifying-information.js +97 -0
- package/dist/normalize-qualifying-information.js.map +1 -0
- package/dist/normalize-qualifying-information.spec.js +51 -0
- package/dist/normalize-qualifying-information.spec.js.map +1 -0
- package/dist/normalizeSubfieldValueForComparison.js +12 -3
- package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
- package/dist/prepublicationUtils.js +8 -26
- package/dist/prepublicationUtils.js.map +1 -1
- package/dist/punctuation2.js +7 -2
- package/dist/punctuation2.js.map +1 -1
- package/dist/removeInferiorDataFields.js +69 -10
- package/dist/removeInferiorDataFields.js.map +1 -1
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -1
- package/package.json +11 -11
- package/src/field-505-separators.js +75 -0
- package/src/field-505-separators.spec.js +52 -0
- package/src/fixRelatorTerms.js +233 -0
- package/src/fixRelatorTerms.spec.js +52 -0
- package/src/index.js +33 -4
- package/src/normalize-qualifying-information.js +92 -0
- package/src/normalize-qualifying-information.spec.js +52 -0
- package/src/normalizeSubfieldValueForComparison.js +14 -3
- package/src/prepublicationUtils.js +8 -25
- package/src/punctuation2.js +3 -2
- package/src/removeInferiorDataFields.js +70 -10
- package/src/utils.js +12 -0
- package/test-fixtures/field-505-separators/01/expectedResult.json +7 -0
- package/test-fixtures/field-505-separators/01/metadata.json +7 -0
- package/test-fixtures/field-505-separators/01/record.json +25 -0
- package/test-fixtures/field-505-separators/02/expectedResult.json +27 -0
- package/test-fixtures/field-505-separators/02/metadata.json +7 -0
- package/test-fixtures/field-505-separators/02/record.json +25 -0
- package/test-fixtures/fix-relator-terms/f01/expectedResult.json +14 -0
- package/test-fixtures/fix-relator-terms/f01/metadata.json +6 -0
- package/test-fixtures/fix-relator-terms/f01/record.json +13 -0
- package/test-fixtures/fix-relator-terms/f01b/expectedResult.json +12 -0
- package/test-fixtures/fix-relator-terms/f01b/metadata.json +6 -0
- package/test-fixtures/fix-relator-terms/f01b/record.json +11 -0
- package/test-fixtures/fix-relator-terms/f02/expectedResult.json +12 -0
- package/test-fixtures/fix-relator-terms/f02/metadata.json +6 -0
- package/test-fixtures/fix-relator-terms/f02/record.json +11 -0
- package/test-fixtures/normalize-qualifying-information/01/expectedResult.json +8 -0
- package/test-fixtures/normalize-qualifying-information/01/metadata.json +7 -0
- package/test-fixtures/normalize-qualifying-information/01/record.json +25 -0
- package/test-fixtures/normalize-qualifying-information/02/expectedResult.json +27 -0
- package/test-fixtures/normalize-qualifying-information/02/metadata.json +7 -0
- package/test-fixtures/normalize-qualifying-information/02/record.json +25 -0
- package/test-fixtures/punctuation2/97/expectedResult.json +6 -1
- package/test-fixtures/punctuation2/97/record.json +5 -0
- package/test-fixtures/remove-inferior-datafields/f09/expectedResult.json +20 -0
- package/test-fixtures/remove-inferior-datafields/f09/metadata.json +6 -0
- package/test-fixtures/remove-inferior-datafields/f09/record.json +30 -0
- package/test-fixtures/remove-inferior-datafields/f10/expectedResult.json +17 -0
- package/test-fixtures/remove-inferior-datafields/f10/metadata.json +6 -0
- package/test-fixtures/remove-inferior-datafields/f10/record.json +27 -0
- package/test-fixtures/remove-inferior-datafields/f11/expectedResult.json +14 -0
- package/test-fixtures/remove-inferior-datafields/f11/metadata.json +6 -0
- package/test-fixtures/remove-inferior-datafields/f11/record.json +18 -0
- package/test-fixtures/strip-punctuation/98/expectedResult.json +5 -0
- package/test-fixtures/strip-punctuation/98/record.json +5 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {MarcRecord} from '@natlibfi/marc-record';
|
|
3
|
+
import validatorFactory from './normalize-qualifying-information';
|
|
4
|
+
import {READERS} from '@natlibfi/fixura';
|
|
5
|
+
import generateTests from '@natlibfi/fixugen';
|
|
6
|
+
import createDebugLogger from 'debug';
|
|
7
|
+
|
|
8
|
+
generateTests({
|
|
9
|
+
callback,
|
|
10
|
+
path: [__dirname, '..', 'test-fixtures', 'normalize-qualifying-information'],
|
|
11
|
+
useMetadataFile: true,
|
|
12
|
+
recurse: false,
|
|
13
|
+
fixura: {
|
|
14
|
+
reader: READERS.JSON
|
|
15
|
+
},
|
|
16
|
+
mocha: {
|
|
17
|
+
before: () => testValidatorFactory()
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/normalize-qualifying-information:test');
|
|
21
|
+
|
|
22
|
+
async function testValidatorFactory() {
|
|
23
|
+
const validator = await validatorFactory();
|
|
24
|
+
|
|
25
|
+
expect(validator)
|
|
26
|
+
.to.be.an('object')
|
|
27
|
+
.that.has.any.keys('description', 'validate');
|
|
28
|
+
|
|
29
|
+
expect(validator.description).to.be.a('string');
|
|
30
|
+
expect(validator.validate).to.be.a('function');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function callback({getFixture, enabled = true, fix = false}) {
|
|
34
|
+
if (enabled === false) {
|
|
35
|
+
debug('TEST SKIPPED!');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const validator = await validatorFactory();
|
|
40
|
+
const record = new MarcRecord(getFixture('record.json'));
|
|
41
|
+
const expectedResult = getFixture('expectedResult.json');
|
|
42
|
+
// console.log(expectedResult); // eslint-disable-line
|
|
43
|
+
|
|
44
|
+
if (!fix) {
|
|
45
|
+
const result = await validator.validate(record);
|
|
46
|
+
expect(result).to.eql(expectedResult);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
await validator.fix(record);
|
|
51
|
+
expect(record).to.eql(expectedResult);
|
|
52
|
+
}
|
|
@@ -8,6 +8,7 @@ const debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:no
|
|
|
8
8
|
const debugDev = debug.extend('dev');
|
|
9
9
|
|
|
10
10
|
export function subfieldContainsPartData(tag, subfieldCode) {
|
|
11
|
+
// NB! Used by reducers' mergeSubield.js
|
|
11
12
|
if (subfieldCode === 'v' && ['490', '800', '810', '811', '830'].includes(tag)) {
|
|
12
13
|
return true;
|
|
13
14
|
}
|
|
@@ -18,8 +19,9 @@ export function subfieldContainsPartData(tag, subfieldCode) {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
function splitPartData(originalValue) {
|
|
22
|
+
// Remove brackets from number-only:
|
|
21
23
|
const value = originalValue.replace(/^\[([0-9]+)\][-.,:; ]*$/ui, '$1'); // eslint-disable-line prefer-named-capture-group
|
|
22
|
-
const splitPoint = value.lastIndexOf(' ');
|
|
24
|
+
const splitPoint = value.lastIndexOf(' '); // MRA-627: "5, 2017" should be split here. Think of this later on...
|
|
23
25
|
if (splitPoint === -1) {
|
|
24
26
|
return [undefined, value];
|
|
25
27
|
}
|
|
@@ -33,13 +35,19 @@ function normalizePartType(originalValue) {
|
|
|
33
35
|
return undefined;
|
|
34
36
|
}
|
|
35
37
|
const value = originalValue.toLowerCase();
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
// Return Finnish singular nominative. Choise of language is arbitrary. This is best-ish for debug purposes...
|
|
40
|
+
if (['n:o', 'no', 'nr', 'nro', 'number', 'numero', 'nummer'].includes(value)) {
|
|
41
|
+
return 'numero';
|
|
42
|
+
}
|
|
43
|
+
if (['band', 'bd', 'häfte', 'nide', 'osa', 'part', 'teil', 'vol', 'vol.', 'volume'].includes(value)) {
|
|
38
44
|
return 'osa';
|
|
39
45
|
}
|
|
46
|
+
|
|
40
47
|
if (['p.', 'page', 'pages', 'pp.', 's.', 'sidor', 'sivu', 'sivut'].includes(value)) {
|
|
41
48
|
return 'sivu';
|
|
42
49
|
}
|
|
50
|
+
|
|
43
51
|
return value;
|
|
44
52
|
}
|
|
45
53
|
|
|
@@ -67,12 +75,15 @@ function splitAndNormalizePartData(value) {
|
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
export function partsAgree(value1, value2, tag, subfieldCode) {
|
|
78
|
+
// Note, that parts can not be normalized away, as "2" can agree with "Part 2" and "Raita 2" and "Volume 2"...
|
|
79
|
+
// NB! Used by reducers' mergeSubield.js
|
|
70
80
|
if (!subfieldContainsPartData(tag, subfieldCode)) {
|
|
71
81
|
return false;
|
|
72
82
|
}
|
|
73
83
|
const [partType1, partNumber1] = splitAndNormalizePartData(value1);
|
|
74
84
|
const [partType2, partNumber2] = splitAndNormalizePartData(value2);
|
|
75
85
|
if (partNumber1 !== partNumber2) {
|
|
86
|
+
// MRA-627: This should/could accept 5/1997
|
|
76
87
|
return false;
|
|
77
88
|
}
|
|
78
89
|
if (partType1 === undefined || partType2 === undefined || partType1 === partType2) {
|
|
@@ -41,8 +41,12 @@ export function fieldRefersToTarkistettuEnnakkotieto(field) {
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
export function fieldRefersToEnnakkotieto(field) {
|
|
44
|
-
// NB! This matches
|
|
45
|
-
|
|
44
|
+
// NB! This no longer matches 'TARKISTETTU ENNAKKOTIETO' case! Bug or Feature?
|
|
45
|
+
if (containsSubstringInSubfieldA(field, 'ENNAKKOTIETO') && !fieldRefersToTarkistettuEnnakkotieto(field)) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// MRA-420: "EI VIELÄ ILMESTYNYT" is a Helmet note, that is semantically similar to ENNAKKOTIETO:
|
|
49
|
+
return containsSubstringInSubfieldA(field, 'EI VIELÄ ILMESTYNYT');
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
|
|
@@ -68,27 +72,6 @@ export function firstFieldHasBetterPrepubEncodingLevel(field1, field2) {
|
|
|
68
72
|
return false;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
/*
|
|
72
|
-
export function firstFieldHasEqualOrBetterPrepubEncodingLevel(field1, field2) {
|
|
73
|
-
// Could be optimized...
|
|
74
|
-
if (fieldRefersToKoneellisestiTuotettuTietue(field1)) {
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
if (fieldRefersToKoneellisestiTuotettuTietue(field2)) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
if (fieldRefersToTarkistettuEnnakkotieto(field1)) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
if (fieldRefersToTarkistettuEnnakkotieto(field2)) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
if (fieldRefersToEnnakkotieto(field1)) {
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
return !fieldRefersToEnnakkotieto(field2);
|
|
90
|
-
}
|
|
91
|
-
*/
|
|
92
75
|
|
|
93
76
|
/*
|
|
94
77
|
function hasEnnakkotietoSubfield(field) {
|
|
@@ -117,7 +100,7 @@ export function getRelevant5XXFields(record, f500 = false, f594 = false) {
|
|
|
117
100
|
|
|
118
101
|
function hasRelevantPrepubData(field) {
|
|
119
102
|
// Check prepub ($a):
|
|
120
|
-
if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToEnnakkotieto(field)) {
|
|
103
|
+
if (!fieldRefersToKoneellisestiTuotettuTietue(field) && !fieldRefersToTarkistettuEnnakkotieto(field) && !fieldRefersToEnnakkotieto(field)) {
|
|
121
104
|
return false;
|
|
122
105
|
}
|
|
123
106
|
// Check relevance (594$5):
|
|
@@ -209,7 +192,7 @@ export function deleteAllPrepublicationNotesFromField500InNonPubRecord(record) {
|
|
|
209
192
|
return;
|
|
210
193
|
}
|
|
211
194
|
|
|
212
|
-
// MET-306: keep "koneellisesti tuotettu tietue" if
|
|
195
|
+
// MET-306: keep "koneellisesti tuotettu tietue" if encoding level is '2':
|
|
213
196
|
const f500 = getRelevant5XXFields(record, true, false).filter(field => encodingLevel === '2' ? !fieldRefersToKoneellisestiTuotettuTietue(field) : true);
|
|
214
197
|
if (f500.length === 0) {
|
|
215
198
|
return;
|
package/src/punctuation2.js
CHANGED
|
@@ -117,7 +117,7 @@ const addX10bDot = {'name': 'Add X10 pre-$b dot', 'add': '.', 'code': 'ab', 'fol
|
|
|
117
117
|
const addX10eComma = {'add': ',', 'code': 'abe', 'followedBy': 'e', 'context': defaultNeedsPuncAfter};
|
|
118
118
|
const addX10Dot = {'name': 'Add X10 final dot', 'add': '.', 'code': 'abe', 'followedBy': '#', 'context': defaultNeedsPuncAfter};
|
|
119
119
|
const addLanguageComma = {'name': 'Add comma before 810$l', 'add': ',', 'code': 'tv', 'followedBy': 'l', 'context': defaultNeedsPuncAfter2};
|
|
120
|
-
const addColonToRelationshipInformation = {'name': 'Add \':\' to 7X0 $i relationship info', 'add': ':', 'code': 'i', 'context':
|
|
120
|
+
const addColonToRelationshipInformation = {'name': 'Add \':\' to 7X0 $i relationship info', 'add': ':', 'code': 'i', 'context': defaultNeedsPuncAfter2};
|
|
121
121
|
|
|
122
122
|
// 490:
|
|
123
123
|
const addSemicolonBeforeVolumeDesignation = {'name': 'Add " ;" before $v', 'add': ' ;', 'code': 'atxyz', 'followedBy': 'v', 'context': /[^;]$/u};
|
|
@@ -181,11 +181,12 @@ const cleanCrappyPunctuationRules = {
|
|
|
181
181
|
const cleanLegalX00Comma = {'code': 'abcde', 'followedBy': 'cdegj', 'context': /.,$/u, 'remove': /,$/u};
|
|
182
182
|
// Accept upper case letters in X00$b, since they are probably Roman numerals.
|
|
183
183
|
const cleanLegalX00bDot = {'code': 'b', 'followedBy': 't#', context: /^[IVXLCDM]+\.$/u, 'remove': /\.$/u};
|
|
184
|
+
const cleanLegalX00iColon = {'code': 'i', 'followedBy': 'a', 'remove': / *:$/u}; // NB! context is not needed
|
|
184
185
|
const cleanLegalX00Dot = {'code': 'abcdetvl', 'followedBy': 'tu#', 'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u, 'remove': /\.$/u};
|
|
185
186
|
const cleanLanguageComma = {'name': 'language comma', 'code': 'tv', 'followedBy': 'l', 'context': /.,$/u, 'remove': /,$/u};
|
|
186
187
|
|
|
187
188
|
|
|
188
|
-
const legalX00punc = [cleanLegalX00Comma, cleanLegalX00bDot, cleanLegalX00Dot, cleanLanguageComma];
|
|
189
|
+
const legalX00punc = [cleanLegalX00Comma, cleanLegalX00iColon, cleanLegalX00bDot, cleanLegalX00Dot, cleanLanguageComma];
|
|
189
190
|
|
|
190
191
|
const cleanLegalX10Comma = {'name': 'X10comma', 'code': 'abe', 'followedBy': 'e', 'context': /.,$/u, 'remove': /,$/u};
|
|
191
192
|
const cleanLegalX10Dot = {'name': 'X10dot', 'code': 'ab', 'followedBy': 'b#', 'context': /.\.$/u, 'remove': /\.$/u};
|
|
@@ -176,6 +176,57 @@ export function removeInferiorChains(record, fix = true) {
|
|
|
176
176
|
return deletedStringsArray;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
function deriveIndividualDeletables490(fieldAsString) {
|
|
180
|
+
if (!fieldAsString.match(/^490/u)) {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* eslint-disable */
|
|
185
|
+
let deletable490s = [];
|
|
186
|
+
|
|
187
|
+
// $6-less version (keep this first)
|
|
188
|
+
let tmp = fieldAsString.replace(/ ‡6 [^‡]+ ‡/u, ' ‡');
|
|
189
|
+
if ( tmp !== fieldAsString) {
|
|
190
|
+
fieldAsString = tmp; // NB! Carry on with $6-less version!
|
|
191
|
+
deletable490s.push(tmp);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Without final $v or $x:
|
|
195
|
+
tmp = fieldAsString.replace(/ *[;,] ‡[vx] [^‡]+$/u, '');
|
|
196
|
+
if ( tmp !== fieldAsString) {
|
|
197
|
+
deletable490s.push(tmp);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Add intermedia $x-less version
|
|
201
|
+
tmp = fieldAsString.replace(/, ‡x [^‡]+(, ‡x| ; ‡v)/u, '$1');
|
|
202
|
+
// Add final $v/$x-less version
|
|
203
|
+
if ( tmp !== fieldAsString) {
|
|
204
|
+
deletable490s.push(tmp);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Add $xv-less version
|
|
208
|
+
tmp = fieldAsString.replace(/, ‡x [^‡]+ ‡v [^‡]+$/u, '');
|
|
209
|
+
if ( tmp !== fieldAsString) {
|
|
210
|
+
deletable490s.push(tmp);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// MRA-433-ish (non-chain): 490 ind1=1 vs ind1=0: remove latter
|
|
214
|
+
if (fieldAsString.match(/^490 1/) ) {
|
|
215
|
+
// TODO: $x-less and $v-less versions...
|
|
216
|
+
tmp = `490 0${fieldAsString.substring(5)}`;
|
|
217
|
+
deletable490s.push(tmp);
|
|
218
|
+
const arr = deriveIndividualDeletables490(tmp);
|
|
219
|
+
arr.forEach(val => deletable490s.push(val));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
nvdebug(`${deletable490s.length} derivation(s) for ${fieldAsString}`);
|
|
223
|
+
if (deletable490s.length > 0) {
|
|
224
|
+
nvdebug(deletable490s.join('\n'));
|
|
225
|
+
}
|
|
226
|
+
/* eslint-enable */
|
|
227
|
+
return deletable490s;
|
|
228
|
+
}
|
|
229
|
+
|
|
179
230
|
function deriveIndividualDeletables(record) {
|
|
180
231
|
/* eslint-disable */
|
|
181
232
|
let deletableStringsArray = [];
|
|
@@ -187,7 +238,6 @@ function deriveIndividualDeletables(record) {
|
|
|
187
238
|
function fieldDeriveIndividualDeletables(field) {
|
|
188
239
|
const fieldAsString = fieldToString(field);
|
|
189
240
|
|
|
190
|
-
nvdebug(`Derivations for ${fieldAsString}`);
|
|
191
241
|
// Proof-of-concept rule:
|
|
192
242
|
let tmp = fieldAsString;
|
|
193
243
|
if (field.tag.match(/^[1678]00$/u)) {
|
|
@@ -197,22 +247,38 @@ function deriveIndividualDeletables(record) {
|
|
|
197
247
|
}
|
|
198
248
|
}
|
|
199
249
|
|
|
250
|
+
if (field.tag === '505') { // MRA-413-ish
|
|
251
|
+
if (fieldAsString.match(/^.0.*-- ‡t/u)) {
|
|
252
|
+
tmp = fieldAsString;
|
|
253
|
+
tmp = tmp.replace(/ -- ‡t /gu, ' -- ');
|
|
254
|
+
tmp = tmp.replace(/ ‡[rg] /gu, ' ');
|
|
255
|
+
tmp = tmp.replace(/ ‡t /u, ' ‡a '); // first $t, not
|
|
256
|
+
tmp = tmp.replace(/^505 (.)0/u, '505 $1#');
|
|
257
|
+
if (tmp !== fieldAsString) {
|
|
258
|
+
deletableStringsArray.push(tmp);
|
|
259
|
+
}
|
|
260
|
+
//nvdebug(`505 ORIGINAL: '${fieldAsString}'`)
|
|
261
|
+
//nvdebug(`505 DERIVATE: '${tmp}'`)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
200
265
|
// MET-381: remove occurence number TAG-00, if TAG-NN existists
|
|
201
266
|
if (field.tag === '880') {
|
|
202
267
|
tmp = fieldAsString;
|
|
203
268
|
if (tmp.match(/ ‡6 [0-9][0-9][0-9]-(?:[1-9][0-9]|0[1-9])/)) {
|
|
204
269
|
tmp = tmp.replace(/( ‡6 [0-9][0-9][0-9])-[0-9]+/, '$1-00');
|
|
205
|
-
nvdebug(`MET-381: ADD TO DELETABLES: ${tmp}`);
|
|
270
|
+
nvdebug(`MET-381: ADD TO DELETABLES: '${tmp}'`);
|
|
206
271
|
deletableStringsArray.push(tmp);
|
|
207
272
|
if (tmp.match(/ ‡6 [0-9][0-9][0-9]-00\/[^ ]+ /)) {
|
|
208
273
|
tmp = tmp.replace(/( ‡6 [0-9][0-9][0-9]-00)[^ ]+/, '$1');
|
|
209
|
-
nvdebug(`MET-381: ADD TO DELETABLES: ${tmp}`);
|
|
274
|
+
nvdebug(`MET-381: ADD TO DELETABLES: '${tmp}'`);
|
|
210
275
|
deletableStringsArray.push(tmp);
|
|
211
276
|
}
|
|
212
277
|
}
|
|
213
278
|
}
|
|
214
279
|
|
|
215
|
-
|
|
280
|
+
const d490 = deriveIndividualDeletables490(fieldAsString);
|
|
281
|
+
d490.forEach(str => deletableStringsArray.push(str));
|
|
216
282
|
|
|
217
283
|
// Remove keepless versions:
|
|
218
284
|
tmp = fieldAsString;
|
|
@@ -221,13 +287,7 @@ function deriveIndividualDeletables(record) {
|
|
|
221
287
|
deletableStringsArray.push(tmp);
|
|
222
288
|
}
|
|
223
289
|
|
|
224
|
-
// MRA-433-ish (non-chain): 490 ind1=1 vs ind1=0: remove latter
|
|
225
|
-
if (fieldAsString.match(/^490 1/) ) {
|
|
226
|
-
tmp = fieldAsString.replace(/^490 1/u, '490 0');
|
|
227
|
-
deletableStringsArray.push(tmp);
|
|
228
|
-
}
|
|
229
290
|
}
|
|
230
|
-
|
|
231
291
|
/* eslint-enable */
|
|
232
292
|
return deletableStringsArray; // we should do uniq!
|
|
233
293
|
|
package/src/utils.js
CHANGED
|
@@ -61,3 +61,15 @@ export function isControlSubfieldCode(subfieldCode) {
|
|
|
61
61
|
}
|
|
62
62
|
return false;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
export function getCatalogingLanguage(record) {
|
|
66
|
+
const [field040] = record.get(/^040$/u);
|
|
67
|
+
if (!field040) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const [b] = field040.subfields.filter(sf => sf.code === 'b');
|
|
71
|
+
if (!b) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return b.value;
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fields": [
|
|
3
|
+
{
|
|
4
|
+
"tag": "005",
|
|
5
|
+
"value": "20220202020202.0"
|
|
6
|
+
},
|
|
7
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
8
|
+
{ "code": "a", "value": "Foo ; Bar ; Lorum ; Ipsum" }
|
|
9
|
+
]},
|
|
10
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
11
|
+
{ "code": "a", "value": "No -- action --required" }
|
|
12
|
+
]},
|
|
13
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
14
|
+
{ "code": "t", "value": "Foo ;" },
|
|
15
|
+
{ "code": "t", "value": "Bar ;" },
|
|
16
|
+
{ "code": "t", "value": "Lorum ;" },
|
|
17
|
+
{ "code": "t", "value": "Ipsum" }
|
|
18
|
+
]},
|
|
19
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
20
|
+
{ "code": "t", "value": "Replace --" },
|
|
21
|
+
{ "code": "t", "value": "only" },
|
|
22
|
+
{ "code": "t", "value": "semicolon" }
|
|
23
|
+
]}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"fields": [
|
|
4
|
+
{
|
|
5
|
+
"tag": "005",
|
|
6
|
+
"value": "20220202020202.0"
|
|
7
|
+
},
|
|
8
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
9
|
+
{ "code": "a", "value": "Foo -- Bar -- Lorum -- Ipsum" }
|
|
10
|
+
]},
|
|
11
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
12
|
+
{ "code": "a", "value": "No -- action --required" }
|
|
13
|
+
]},
|
|
14
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
15
|
+
{ "code": "t", "value": "Foo --" },
|
|
16
|
+
{ "code": "t", "value": "Bar --" },
|
|
17
|
+
{ "code": "t", "value": "Lorum --" },
|
|
18
|
+
{ "code": "t", "value": "Ipsum" }
|
|
19
|
+
]},
|
|
20
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
21
|
+
{ "code": "t", "value": "Replace --" },
|
|
22
|
+
{ "code": "t", "value": "only" },
|
|
23
|
+
{ "code": "t", "value": "semicolon" }
|
|
24
|
+
]}
|
|
25
|
+
],
|
|
26
|
+
"leader": ""
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fields": [
|
|
3
|
+
{
|
|
4
|
+
"tag": "005",
|
|
5
|
+
"value": "20220202020202.0"
|
|
6
|
+
},
|
|
7
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
8
|
+
{ "code": "a", "value": "Foo ; Bar ; Lorum ; Ipsum" }
|
|
9
|
+
]},
|
|
10
|
+
{ "tag": "505", "ind1": "8", "ind2": " ", "subfields": [
|
|
11
|
+
{ "code": "a", "value": "No -- action --required" }
|
|
12
|
+
]},
|
|
13
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
14
|
+
{ "code": "t", "value": "Foo ;" },
|
|
15
|
+
{ "code": "t", "value": "Bar ;" },
|
|
16
|
+
{ "code": "t", "value": "Lorum ;" },
|
|
17
|
+
{ "code": "t", "value": "Ipsum" }
|
|
18
|
+
]},
|
|
19
|
+
{ "tag": "505", "ind1": "8", "ind2": "0", "subfields": [
|
|
20
|
+
{ "code": "t", "value": "Replace --" },
|
|
21
|
+
{ "code": "t", "value": "only" },
|
|
22
|
+
{ "code": "t", "value": "semicolon" }
|
|
23
|
+
]}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "01331cam a22003494i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "040", "ind1": " ", "ind2": " ", "subfields": [ { "code": "b", "value": "fin" } ] },
|
|
6
|
+
{ "tag": "700", "ind1": " ", "ind2": " ",
|
|
7
|
+
"subfields": [
|
|
8
|
+
{ "code": "a", "value": "Nimi," },
|
|
9
|
+
{ "code": "e", "value": "säveltäjä,"},
|
|
10
|
+
{ "code": "e", "value": "esittäjä,"},
|
|
11
|
+
{ "code": "e", "value": "sanoittaja." }
|
|
12
|
+
] }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"leader": "01331cam a22003494i 4500",
|
|
3
|
+
"fields": [
|
|
4
|
+
{ "tag": "040", "ind1": " ", "ind2": " ", "subfields": [ { "code": "b", "value": "fin" } ] },
|
|
5
|
+
{ "tag": "700", "ind1": " ", "ind2": " ",
|
|
6
|
+
"subfields": [
|
|
7
|
+
{ "code": "a", "value": "Nimi," },
|
|
8
|
+
{ "code": "e", "value": "säv.,"},
|
|
9
|
+
{ "code": "e", "value": "esitt.,"},
|
|
10
|
+
{ "code": "e", "value": "san." }
|
|
11
|
+
] }
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "01331cam a22003494i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "700", "ind1": " ", "ind2": " ",
|
|
6
|
+
"subfields": [
|
|
7
|
+
{ "code": "a", "value": "Nimi," },
|
|
8
|
+
{ "code": "e", "value": "esittäjä,"},
|
|
9
|
+
{ "code": "e", "value": "sanoittaja." }
|
|
10
|
+
] }
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "01331cam a22003494i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "040", "ind1": " ", "ind2": " ", "subfields": [ { "code": "b", "value": "fin" } ] },
|
|
6
|
+
{ "tag": "700", "ind1": " ", "ind2": " ",
|
|
7
|
+
"subfields": [
|
|
8
|
+
{ "code": "a", "value": "Nimi," },
|
|
9
|
+
{ "code": "e", "value": "kirjoittaja."}
|
|
10
|
+
] }
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"leader": "01331cam a22003494i 4500",
|
|
3
|
+
"fields": [
|
|
4
|
+
{ "tag": "040", "ind1": " ", "ind2": " ", "subfields": [ { "code": "b", "value": "fin" } ] },
|
|
5
|
+
{ "tag": "700", "ind1": " ", "ind2": " ",
|
|
6
|
+
"subfields": [
|
|
7
|
+
{ "code": "a", "value": "Nimi," },
|
|
8
|
+
{ "code": "e", "value": "författare."}
|
|
9
|
+
] }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"message": [
|
|
3
|
+
"'TODO: 020 ## ‡a fv67890 ‡q häftad' => '020 ## ‡a fv67890 ‡q mjuka pärmar'",
|
|
4
|
+
"'TODO: 020 ## ‡a 1234567890 ‡q SID.' => '020 ## ‡a 1234567890 ‡q kovakantinen'",
|
|
5
|
+
"'TODO: 024 8# ‡a MEL123 ‡q Nidottu' => '024 8# ‡a MEL123 ‡q pehmeäkantinen'"
|
|
6
|
+
],
|
|
7
|
+
"valid": false
|
|
8
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fields": [
|
|
3
|
+
{
|
|
4
|
+
"tag": "005",
|
|
5
|
+
"value": "20220202020202.0"
|
|
6
|
+
},
|
|
7
|
+
{ "tag": "020", "ind1": " ", "ind2": " ", "subfields": [
|
|
8
|
+
{ "code": "a", "value": "fv67890" },
|
|
9
|
+
{ "code": "q", "value": "häftad" }
|
|
10
|
+
]},
|
|
11
|
+
{ "tag": "020", "ind1": " ", "ind2": " ", "subfields": [
|
|
12
|
+
{ "code": "a", "value": "1234567890" },
|
|
13
|
+
{ "code": "q", "value": "SID." }
|
|
14
|
+
]},
|
|
15
|
+
{ "tag": "024", "ind1": "8", "ind2": " ", "subfields": [
|
|
16
|
+
{ "code": "a", "value": "MEL123" },
|
|
17
|
+
{ "code": "q", "value": "Nidottu" }
|
|
18
|
+
]},
|
|
19
|
+
{ "tag": "028", "ind1": "0", "ind2": " ", "subfields": [
|
|
20
|
+
{ "code": "a", "value": "TätäEnVieläOsaa" },
|
|
21
|
+
{ "code": "q", "value": "(sid.)" }
|
|
22
|
+
]}
|
|
23
|
+
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"fields": [
|
|
4
|
+
{
|
|
5
|
+
"tag": "005",
|
|
6
|
+
"value": "20220202020202.0"
|
|
7
|
+
},
|
|
8
|
+
{ "tag": "020", "ind1": " ", "ind2": " ", "subfields": [
|
|
9
|
+
{ "code": "a", "value": "fv67890" },
|
|
10
|
+
{ "code": "q", "value": "mjuka pärmar" }
|
|
11
|
+
]},
|
|
12
|
+
{ "tag": "020", "ind1": " ", "ind2": " ", "subfields": [
|
|
13
|
+
{ "code": "a", "value": "1234567890" },
|
|
14
|
+
{ "code": "q", "value": "kovakantinen" }
|
|
15
|
+
]},
|
|
16
|
+
{ "tag": "024", "ind1": "8", "ind2": " ", "subfields": [
|
|
17
|
+
{ "code": "a", "value": "MEL123" },
|
|
18
|
+
{ "code": "q", "value": "pehmeäkantinen" }
|
|
19
|
+
]},
|
|
20
|
+
{ "tag": "028", "ind1": "0", "ind2": " ", "subfields": [
|
|
21
|
+
{ "code": "a", "value": "TätäEnVieläOsaa" },
|
|
22
|
+
{ "code": "q", "value": "(sid.)" }
|
|
23
|
+
]}
|
|
24
|
+
|
|
25
|
+
],
|
|
26
|
+
"leader": ""
|
|
27
|
+
}
|