@natlibfi/marc-record-validators-melinda 11.2.2-alpha.2 → 11.3.0-alpha.1
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/dist/cyrillux-usemarcon-replacement.js +5 -2
- package/dist/cyrillux-usemarcon-replacement.js.map +1 -1
- package/dist/cyrillux.js +197 -0
- package/dist/cyrillux.js.map +1 -0
- package/dist/cyrillux.spec.js +46 -0
- package/dist/cyrillux.spec.js.map +1 -0
- package/dist/fix-33X.js +23 -2
- package/dist/fix-33X.js.map +1 -1
- package/dist/fixRelatorTerms.js +5 -1
- package/dist/fixRelatorTerms.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/subfield6Utils.js +4 -1
- package/dist/subfield6Utils.js.map +1 -1
- package/dist/utils.js +15 -0
- package/dist/utils.js.map +1 -1
- package/package.json +9 -6
- package/src/cyrillux-usemarcon-replacement.js +6 -4
- package/src/cyrillux.js +173 -0
- package/src/cyrillux.spec.js +46 -0
- package/src/fix-33X.js +18 -2
- package/src/fixRelatorTerms.js +5 -2
- package/src/index.js +2 -0
- package/src/subfield6Utils.js +4 -3
- package/src/utils.js +13 -0
- package/test-fixtures/cyrillux/f01/expectedResult.json +23 -0
- package/test-fixtures/cyrillux/f01/metadata.json +5 -0
- package/test-fixtures/cyrillux/f01/record.json +8 -0
- package/test-fixtures/cyrillux/f02/expectedResult.json +30 -0
- package/test-fixtures/cyrillux/f02/metadata.json +10 -0
- package/test-fixtures/cyrillux/f02/record.json +14 -0
- package/test-fixtures/cyrillux/f03/expectedResult.json +13 -0
- package/test-fixtures/cyrillux/f03/metadata.json +10 -0
- package/test-fixtures/cyrillux/f03/record.json +11 -0
- package/test-fixtures/cyrillux/f04/expectedResult.json +13 -0
- package/test-fixtures/cyrillux/f04/metadata.json +10 -0
- package/test-fixtures/cyrillux/f04/record.json +11 -0
- package/test-fixtures/cyrillux/f05/expectedResult.json +20 -0
- package/test-fixtures/cyrillux/f05/metadata.json +5 -0
- package/test-fixtures/cyrillux/f05/record.json +18 -0
- package/test-fixtures/cyrillux/v01/expectedResult.json +7 -0
- package/test-fixtures/cyrillux/v01/metadata.json +5 -0
- package/test-fixtures/cyrillux/v01/record.json +8 -0
- package/test-fixtures/cyrillux/v02/expectedResult.json +5 -0
- package/test-fixtures/cyrillux/v02/metadata.json +5 -0
- package/test-fixtures/cyrillux/v02/record.json +8 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f15/expectedResult.json +38 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f15/metadata.json +5 -0
- package/test-fixtures/cyrillux-usemarcon-replacement/f15/record.json +35 -0
- package/test-fixtures/fix-relator-terms/f03/expectedResult.json +15 -0
- package/test-fixtures/fix-relator-terms/f03/metadata.json +5 -0
- package/test-fixtures/fix-relator-terms/f03/record.json +14 -0
- package/test-fixtures/sort-fields/12/input.json +60 -0
- package/test-fixtures/sort-fields/12/metadata.json +5 -0
- package/test-fixtures/sort-fields/12/result.json +61 -0
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["isElectronicMaterial","record","f337s","get","length","some","f","fieldHasSubfield","nvdebug","message","func","undefined","field","subfieldCode","subfieldValue","subfields","sf","code","value","subfieldToString","normalizeIndicatorValue","val","recordToString","ldr","leader","fields","map","fieldToString","join","
|
|
1
|
+
{"version":3,"file":"utils.js","names":["isElectronicMaterial","record","f337s","get","length","some","f","fieldHasSubfield","nvdebug","message","func","undefined","field","subfieldCode","subfieldValue","subfields","sf","code","value","subfieldToString","normalizeIndicatorValue","val","recordToString","ldr","leader","fields","map","fieldToString","join","removeSubfield","tag","filter","recordRemoveValuelessSubfields","ind1","ind2","formatSubfields","fieldsToString","nvdebugFieldArray","prefix","forEach","isControlSubfieldCode","includes","getCatalogingLanguage","defaultCatalogingLanguage","field040","b","uniqArray","arr","i","indexOf"],"sources":["../src/utils.js"],"sourcesContent":["export function isElectronicMaterial(record) {\n const f337s = record.get('337');\n\n return f337s.length > 0 && f337s.some(f => fieldHasSubfield(f, 'b', 'c') && fieldHasSubfield(f, '2', 'rdamedia'));\n}\n\nexport function nvdebug(message, func = undefined) {\n if (func) { // eslint-disable-line functional/no-conditional-statements\n func(message);\n }\n //console.info(message); // eslint-disable-line no-console\n}\n\nexport function fieldHasSubfield(field, subfieldCode, subfieldValue = null) {\n if (!field.subfields) {\n return false;\n }\n if (subfieldValue === null) {\n return field.subfields.some(sf => sf.code === subfieldCode);\n }\n return field.subfields.some(sf => sf.code === subfieldCode && subfieldValue === sf.value);\n}\n\nexport function subfieldToString(sf) {\n if (!sf.value) {\n return `‡${sf.code}`;\n }\n return `‡${sf.code} ${sf.value}`;\n}\n\nfunction normalizeIndicatorValue(val) {\n if (val === ' ') {\n return '#';\n }\n return val;\n}\n\nexport function recordToString(record) {\n const ldr = `LDR ${record.leader}`;\n const fields = record.fields.map(f => fieldToString(f));\n return `${ldr}\\n${fields.join('\\n')}`;\n}\n\nexport function removeSubfield(record, tag, subfieldCode) {\n record.fields = record.fields.map(field => { // eslint-disable-line functional/immutable-data\n if (field.tag !== tag || !field.subfields) { // Don't procss irrelevant fields\n return field;\n }\n field.subfields = field.subfields.filter(sf => sf.code !== subfieldCode); // eslint-disable-line functional/immutable-data\n if (field.subfields.length === 0) {\n return false;\n }\n return field;\n }).filter(field => field);\n}\n\nexport function recordRemoveValuelessSubfields(record) {\n record.fields = record.fields.map(field => { // eslint-disable-line functional/immutable-data\n if (!field.subfields) { // Keep control fields\n return field;\n }\n // Remove empty subfields from datafields:\n field.subfields = field.subfields.filter(sf => sf.value); // eslint-disable-line functional/immutable-data\n\n if (field.subfields && field.subfields.length === 0) {\n return false; // Return false instead of a field if field has no subfields left. These will soon be filtered out.\n }\n\n return field; //if field has subfields return it\n }).filter(field => field); // Filter those falses out\n}\n\nexport function fieldToString(f) {\n if ('subfields' in f) {\n return `${f.tag} ${normalizeIndicatorValue(f.ind1)}${normalizeIndicatorValue(f.ind2)}${formatSubfields(f)}`;\n }\n return `${f.tag} ${f.value}`;\n\n function formatSubfields(field) {\n return field.subfields.map(sf => ` ${subfieldToString(sf)}`).join('');\n }\n}\n\nexport function fieldsToString(fields) {\n return fields.map(f => fieldToString(f)).join('\\t__SEPARATOR__\\t');\n}\n\nexport function nvdebugFieldArray(fields, prefix = ' ', func = undefined) {\n fields.forEach(field => nvdebug(`${prefix}${fieldToString(field)}`, func));\n}\n\nexport function isControlSubfieldCode(subfieldCode) {\n if (['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'w'].includes(subfieldCode)) {\n return true;\n }\n return false;\n}\n\nexport function getCatalogingLanguage(record, defaultCatalogingLanguage = undefined) {\n const [field040] = record.get(/^040$/u);\n if (!field040) {\n return defaultCatalogingLanguage;\n }\n const [b] = field040.subfields.filter(sf => sf.code === 'b');\n if (!b) {\n return defaultCatalogingLanguage;\n }\n return b.value;\n}\n\n\nexport function uniqArray(arr) {\n return arr.filter((val, i) => arr.indexOf(val) === i);\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"url": "git@github.com:natlibfi/marc-record-validators-melinda.git"
|
|
15
15
|
},
|
|
16
16
|
"license": "MIT",
|
|
17
|
-
"version": "11.
|
|
17
|
+
"version": "11.3.0-alpha.1",
|
|
18
18
|
"main": "./dist/index.js",
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public"
|
|
@@ -37,25 +37,28 @@
|
|
|
37
37
|
"cover:report": "nyc report"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@babel/register": "^7.
|
|
40
|
+
"@babel/register": "^7.24.6",
|
|
41
41
|
"@natlibfi/issn-verify": "^1.0.4",
|
|
42
42
|
"@natlibfi/marc-record": "^8.1.3",
|
|
43
43
|
"@natlibfi/marc-record-validate": "^8.0.8",
|
|
44
44
|
"cld3-asm": "^3.1.1",
|
|
45
45
|
"clone": "^2.1.2",
|
|
46
46
|
"debug": "^4.3.4",
|
|
47
|
+
"iso9_1995": "^0.0.2",
|
|
47
48
|
"isbn3": "^1.1.48",
|
|
48
49
|
"langs": "^2.0.0",
|
|
49
50
|
"node-fetch": "^2.7.0",
|
|
50
|
-
"
|
|
51
|
+
"sfs4900": "^0.0.1",
|
|
52
|
+
"xml2js": "^0.6.2",
|
|
53
|
+
"xregexp": "^5.1.1"
|
|
51
54
|
},
|
|
52
55
|
"peerDependencies": {
|
|
53
56
|
"@natlibfi/marc-record-validate": "^8.0.7"
|
|
54
57
|
},
|
|
55
58
|
"devDependencies": {
|
|
56
|
-
"@babel/cli": "^7.24.
|
|
57
|
-
"@babel/core": "^7.24.
|
|
58
|
-
"@babel/preset-env": "^7.24.
|
|
59
|
+
"@babel/cli": "^7.24.7",
|
|
60
|
+
"@babel/core": "^7.24.7",
|
|
61
|
+
"@babel/preset-env": "^7.24.7",
|
|
59
62
|
"@natlibfi/eslint-config-melinda-backend": "^3.0.5",
|
|
60
63
|
"@natlibfi/fixugen": "^2.0.5",
|
|
61
64
|
"@natlibfi/fixura": "^3.0.5",
|
|
@@ -21,7 +21,7 @@ import {default as fixQualifyingInformation} from './normalize-qualifying-inform
|
|
|
21
21
|
import {sortAdjacentSubfields} from './sortSubfields';
|
|
22
22
|
|
|
23
23
|
// import createDebugLogger from 'debug';
|
|
24
|
-
import {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString} from './utils';
|
|
24
|
+
import {fieldHasSubfield, nvdebug, recordRemoveValuelessSubfields, recordToString, removeSubfield} from './utils';
|
|
25
25
|
|
|
26
26
|
// const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/punctuation2');
|
|
27
27
|
|
|
@@ -48,12 +48,15 @@ export default function () {
|
|
|
48
48
|
if (isAlephRecord(record)) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
+
|
|
51
52
|
// Update LDR/17 to '4'
|
|
52
53
|
record.leader = `${record.leader.substring(0, 17)}4${record.leader.substring(18, 24)}`; // eslint-disable-line functional/immutable-data
|
|
53
54
|
|
|
54
55
|
// Remove unwanted fields:
|
|
55
56
|
record.fields = record.fields.filter(f => !dropTags.includes(f.tag)); // eslint-disable-line functional/immutable-data
|
|
56
57
|
|
|
58
|
+
removeSubfield(record, '020', 'c');
|
|
59
|
+
|
|
57
60
|
// Remove 084 fields that don't have $2 ykl (based on USEMARCON-RDA/bw_rda_kyril.rul code by LL 2019)
|
|
58
61
|
record.fields = record.fields.filter(f => f.tag !== '084' || f.subfields.some(sf => sf.code === '2' && sf.value === 'ykl')); // eslint-disable-line functional/immutable-data
|
|
59
62
|
|
|
@@ -122,14 +125,13 @@ export default function () {
|
|
|
122
125
|
|
|
123
126
|
add041().fix(record);
|
|
124
127
|
|
|
125
|
-
fixRelatorTerms().fix(record);
|
|
126
|
-
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
function realFixAll2(record) {
|
|
130
131
|
fixQualifyingInformation().fix(record); // 015, 020, 024 and 028
|
|
131
132
|
|
|
132
133
|
// Cyrillux specific code might change 040$b and thus affect these rules:
|
|
134
|
+
fixRelatorTerms().fix(record);
|
|
133
135
|
fix33X().fix(record); // 33X$a => 33X$a$b$2
|
|
134
136
|
add336().fix(record);
|
|
135
137
|
add337().fix(record);
|
|
@@ -170,7 +172,7 @@ export default function () {
|
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
function fixField040(record) {
|
|
173
|
-
const f040 = record.
|
|
175
|
+
const f040 = record.get('040');
|
|
174
176
|
|
|
175
177
|
const subfieldsBE = [
|
|
176
178
|
{code: 'b', value: 'mul'},
|
package/src/cyrillux.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
//import createDebugLogger from 'debug';
|
|
2
|
+
import clone from 'clone';
|
|
3
|
+
import {fieldToString, fieldsToString, isControlSubfieldCode} from './utils';
|
|
4
|
+
import * as iso9 from 'iso9_1995';
|
|
5
|
+
import {intToOccurrenceNumberString, recordGetMaxSubfield6OccurrenceNumberAsInteger} from './subfield6Utils';
|
|
6
|
+
|
|
7
|
+
import XRegExp from 'xregexp';
|
|
8
|
+
import * as sfs4900 from 'sfs4900';
|
|
9
|
+
import {default as sortFields} from './sortFields';
|
|
10
|
+
import {default as reindexSubfield6OccurenceNumbers} from './reindexSubfield6OccurenceNumbers';
|
|
11
|
+
|
|
12
|
+
export default function (config = {}) {
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
description: 'Cyrillux functionality: convert original field to latinitsa (ISO-9) and add 880s for original cyrillic and latinitsa (SFS-4900)',
|
|
16
|
+
validate, fix
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function preprocessConfig() {
|
|
20
|
+
config.doISO9Transliteration = typeof config.doISO9Transliteration === 'undefined' ? true : config.doISO9Transliteration; // eslint-disable-line functional/immutable-data
|
|
21
|
+
config.doSFS4900Transliteration = typeof config.doSFS4900Transliteration === 'undefined' ? true : config.doSFS4900Transliteration; // eslint-disable-line functional/immutable-data
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function fix(record) {
|
|
25
|
+
// Fix always succeeds
|
|
26
|
+
const res = {message: [], fix: [], valid: true};
|
|
27
|
+
|
|
28
|
+
preprocessConfig(config);
|
|
29
|
+
|
|
30
|
+
const nBefore = record.fields.length;
|
|
31
|
+
|
|
32
|
+
record.fields = processFields(record.fields); // eslint-disable-line functional/immutable-data
|
|
33
|
+
|
|
34
|
+
if (nBefore < record.fields.length) { // eslint-disable-line functional/no-conditional-statements
|
|
35
|
+
reindexSubfield6OccurenceNumbers().fix(record);
|
|
36
|
+
sortFields().fix(record);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function processFields(input, output = []) {
|
|
40
|
+
const [currField, ...remainingInput] = input;
|
|
41
|
+
if (!currField) {
|
|
42
|
+
return output;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const fakeRecord = {fields: output};
|
|
46
|
+
const createdMax = recordGetMaxSubfield6OccurrenceNumberAsInteger(fakeRecord);
|
|
47
|
+
const result = processField(currField, record, createdMax);
|
|
48
|
+
|
|
49
|
+
return processFields(remainingInput, [...output, ...result]);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return res;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function validate(record) {
|
|
56
|
+
const res = {message: [], valid: true};
|
|
57
|
+
|
|
58
|
+
preprocessConfig(config);
|
|
59
|
+
|
|
60
|
+
record.fields?.forEach(field => {
|
|
61
|
+
validateField(field, res, record);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data
|
|
65
|
+
return res;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function validateField(field, res, record) {
|
|
69
|
+
const orig = fieldToString(field);
|
|
70
|
+
|
|
71
|
+
const normalizedFields = processField(clone(field), record);
|
|
72
|
+
const mod = fieldsToString(normalizedFields).replace(/\t__SEPARATOR__\t/ug, ', ').replace(/ (‡6 [0-9][0-9][0-9])-[0-9][0-9]+/gu, ' $1-NN'); // eslint-disable-line prefer-named-capture-group
|
|
73
|
+
if (orig !== mod) { // Fail as the input is "broken"/"crap"/sumthing
|
|
74
|
+
res.message.push(`CHANGE: ${orig} => ${mod}`); // eslint-disable-line functional/immutable-data
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isCyrillicCharacter(char) {
|
|
81
|
+
return XRegExp('[\\p{Cyrillic}]').test(char); // eslint-disable-line new-cap
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function containsCyrillicCharacters(str) { // from melinda-ui-cyrillux
|
|
85
|
+
if (!str) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return str.split('').some(isCyrillicCharacter);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function fieldContainsCyrillicCharacters(field) { // based on melinda-ui-cyrillux
|
|
92
|
+
return field.subfields && field.subfields.some(sf => subfieldShouldTransliterateToIso9(sf));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function subfieldShouldTransliterateToIso9(subfield) {
|
|
96
|
+
if (isControlSubfieldCode(subfield.code)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return containsCyrillicCharacters(subfield.value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function fieldShouldTransliterateToIso9(field) {
|
|
103
|
+
// Skip certain tags ('880' is the actual skip-me beef here, but we have seen other no-nos as well)
|
|
104
|
+
if (['336', '337', '338', '880'].includes(field.tag)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
// Skip control fields and fields that already have a translitteration
|
|
108
|
+
if (!field.subfields || field.subfields.some(sf => sf.code === '6')) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return fieldContainsCyrillicCharacters(field);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function mapSubfieldToIso9(subfield) {
|
|
115
|
+
const value = subfieldShouldTransliterateToIso9(subfield) ? iso9.convertToLatin(subfield.value) : subfield.value;
|
|
116
|
+
return {code: subfield.code, value};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function mapSubfieldToSfs4900(subfield) {
|
|
120
|
+
const value = subfieldShouldTransliterateToIso9(subfield) ? sfs4900.convertToLatin(subfield.value).result : subfield.value;
|
|
121
|
+
return {code: subfield.code, value};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
function mapFieldToIso9(field, occurrenceNumber) {
|
|
126
|
+
const subfield6 = {code: '6', value: `880-${occurrenceNumber}`};
|
|
127
|
+
const subfield9 = {code: '9', value: 'ISO9 <TRANS>'};
|
|
128
|
+
|
|
129
|
+
const subfields = field.subfields.map(sf => mapSubfieldToIso9(sf));
|
|
130
|
+
|
|
131
|
+
if (!config.doISO9Transliteration && !config.doSFS4900Transliteration) {
|
|
132
|
+
// Just converts the field to ISO-9 latinitsa, does not create any field-880s, so don't bother with $6 or $9 either
|
|
133
|
+
return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {tag: field.tag, ind1: field.ind1, ind2: field.ind2, subfields: [subfield6, ...subfields, subfield9]};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function mapFieldToCyrillicField880(field, occurrenceNumber) {
|
|
140
|
+
const subfields = [
|
|
141
|
+
{code: '6', value: `${field.tag}-${occurrenceNumber}`},
|
|
142
|
+
...field.subfields.map(sf => clone(sf)),
|
|
143
|
+
{code: '9', value: 'CYRILLIC <TRANS>'}
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
return {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function mapFieldToSfs4900Field880(field, occurrenceNumber) {
|
|
150
|
+
|
|
151
|
+
const subfields = [
|
|
152
|
+
{code: '6', value: `${field.tag}-${occurrenceNumber}`},
|
|
153
|
+
...field.subfields.map(sf => mapSubfieldToSfs4900(sf)),
|
|
154
|
+
{code: '9', value: 'SFS4900 <TRANS>'}
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
return {tag: '880', ind1: field.ind1, ind2: field.ind2, subfields};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function processField(originalField, record, maxCreatedOccurrenceNumber = 0) {
|
|
161
|
+
if (!fieldShouldTransliterateToIso9(originalField)) {
|
|
162
|
+
return [originalField];
|
|
163
|
+
}
|
|
164
|
+
const newOccurrenceNumberAsInt = maxCreatedOccurrenceNumber ? maxCreatedOccurrenceNumber + 1 : recordGetMaxSubfield6OccurrenceNumberAsInteger(record) + 1;
|
|
165
|
+
const newOccurrenceNumberAsString = intToOccurrenceNumberString(newOccurrenceNumberAsInt);
|
|
166
|
+
|
|
167
|
+
const newMainField = mapFieldToIso9(originalField, newOccurrenceNumberAsString); // ISO-9
|
|
168
|
+
const newCyrillicField = config.doISO9Transliteration ? mapFieldToCyrillicField880(originalField, newOccurrenceNumberAsString) : undefined; // CYRILLIC
|
|
169
|
+
const newSFS4900Field = config.doSFS4900Transliteration ? mapFieldToSfs4900Field880(originalField, newOccurrenceNumberAsString) : undefined; /// SFS-4900
|
|
170
|
+
|
|
171
|
+
return [newMainField, newCyrillicField, newSFS4900Field].filter(f => f);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {MarcRecord} from '@natlibfi/marc-record';
|
|
3
|
+
import validatorFactory from './cyrillux';
|
|
4
|
+
import {READERS} from '@natlibfi/fixura';
|
|
5
|
+
import generateTests from '@natlibfi/fixugen';
|
|
6
|
+
|
|
7
|
+
generateTests({
|
|
8
|
+
callback,
|
|
9
|
+
path: [__dirname, '..', 'test-fixtures', 'cyrillux'],
|
|
10
|
+
useMetadataFile: true,
|
|
11
|
+
recurse: false,
|
|
12
|
+
fixura: {
|
|
13
|
+
reader: READERS.JSON
|
|
14
|
+
},
|
|
15
|
+
mocha: {
|
|
16
|
+
before: () => testValidatorFactory()
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
async function testValidatorFactory() {
|
|
21
|
+
const validator = await validatorFactory();
|
|
22
|
+
|
|
23
|
+
expect(validator)
|
|
24
|
+
.to.be.an('object')
|
|
25
|
+
.that.has.any.keys('description', 'validate');
|
|
26
|
+
|
|
27
|
+
expect(validator.description).to.be.a('string');
|
|
28
|
+
expect(validator.validate).to.be.a('function');
|
|
29
|
+
expect(validator.fix).to.be.a('function');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function callback({getFixture, fix = false, config = {}}) {
|
|
33
|
+
const validator = await validatorFactory(config);
|
|
34
|
+
const record = new MarcRecord(getFixture('record.json'));
|
|
35
|
+
const expectedResult = getFixture('expectedResult.json');
|
|
36
|
+
// console.log(expectedResult); // eslint-disable-line
|
|
37
|
+
|
|
38
|
+
if (!fix) {
|
|
39
|
+
const result = await validator.validate(record);
|
|
40
|
+
expect(result).to.eql(expectedResult);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await validator.fix(record);
|
|
45
|
+
expect(record).to.eql(expectedResult);
|
|
46
|
+
}
|
package/src/fix-33X.js
CHANGED
|
@@ -148,7 +148,16 @@ const map336 = {
|
|
|
148
148
|
'unbewegtes Bild': 'sti',
|
|
149
149
|
'unspecified': 'zzz',
|
|
150
150
|
'Ääni': 'snd',
|
|
151
|
-
'ääni': 'snd'
|
|
151
|
+
'ääni': 'snd',
|
|
152
|
+
'Электронная программа': 'cop', // computer program
|
|
153
|
+
'Изображение (картографическое)': 'cri',
|
|
154
|
+
'Музыка (знаковая)': 'ntm', // notated music
|
|
155
|
+
'Музыка (исполнительская)': 'prm', // performed music
|
|
156
|
+
'Устная речь': 'spw',
|
|
157
|
+
'Изображение (неподвижное)': 'sti',
|
|
158
|
+
'Изображение (движущееся)': 'tdi', // 2D moving image
|
|
159
|
+
'Текст': 'txt',
|
|
160
|
+
'Текст (визуальный)': 'txt'
|
|
152
161
|
};
|
|
153
162
|
|
|
154
163
|
const map337 = {
|
|
@@ -195,7 +204,14 @@ const map337 = {
|
|
|
195
204
|
'unspecified': 'z',
|
|
196
205
|
'useita mediatyyppejä': 'z',
|
|
197
206
|
'video': 'v',
|
|
198
|
-
'övrig': 'x'
|
|
207
|
+
'övrig': 'x',
|
|
208
|
+
// Cyrillic (sorted by result):
|
|
209
|
+
'электронн': 'c',
|
|
210
|
+
'электронный': 'c',
|
|
211
|
+
'непосредственн': 'n',
|
|
212
|
+
'непосредственный': 'n',
|
|
213
|
+
'аудио': 's', // audio
|
|
214
|
+
'видео': 'v'
|
|
199
215
|
};
|
|
200
216
|
|
|
201
217
|
const map338 = {
|
package/src/fixRelatorTerms.js
CHANGED
|
@@ -110,7 +110,10 @@ const finnishAbbreviations = {
|
|
|
110
110
|
'säv.': 'säveltäjä',
|
|
111
111
|
'toim.': 'toimittaja',
|
|
112
112
|
// Quick and dirty implementation of https://github.com/NatLibFi/USEMARCON-BOOKWHERE-RDA/blob/master/bw_rda_kyril.rul#L651
|
|
113
|
-
|
|
113
|
+
// As per M.I./Slavica
|
|
114
|
+
'худож.': 'kuvittaja',
|
|
115
|
+
'пер.': 'kääntäjä',
|
|
116
|
+
'сост.': 'toimittaja', // might also be 'kokoaja'
|
|
114
117
|
'ред.': 'toimittaja'
|
|
115
118
|
};
|
|
116
119
|
|
|
@@ -130,7 +133,7 @@ function subfieldHandleRelatorTermAbbreviation(subfield, language) {
|
|
|
130
133
|
const lcValue = value.toLowerCase(); // Check Å, Ä, Ö...
|
|
131
134
|
|
|
132
135
|
// NB: Policy: if no language or multi-language: apply all rules! (Not much overlap I hope...)
|
|
133
|
-
if (language === 'fin' || language === 'mul') {
|
|
136
|
+
if (!language || language === 'fin' || language === 'mul') {
|
|
134
137
|
nvdebug(`Relator try Finnish for '${lcValue}}'...`, debugDev);
|
|
135
138
|
if (lcValue in finnishAbbreviations) {
|
|
136
139
|
const hit = `${finnishAbbreviations[lcValue]}${punc}`;
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import AddMissingField041 from './addMissingField041';
|
|
|
3
3
|
import AddMissingField336 from './addMissingField336';
|
|
4
4
|
import AddMissingField337 from './addMissingField337';
|
|
5
5
|
import AddMissingField338 from './addMissingField338';
|
|
6
|
+
import Cyrillux from './cyrillux';
|
|
6
7
|
import CyrilluxUsemarconReplacement from './cyrillux-usemarcon-replacement';
|
|
7
8
|
import DoubleCommas from './double-commas';
|
|
8
9
|
import DuplicatesInd1 from './duplicates-ind1';
|
|
@@ -59,6 +60,7 @@ export {
|
|
|
59
60
|
AddMissingField336,
|
|
60
61
|
AddMissingField337,
|
|
61
62
|
AddMissingField338,
|
|
63
|
+
Cyrillux,
|
|
62
64
|
CyrilluxUsemarconReplacement,
|
|
63
65
|
DoubleCommas,
|
|
64
66
|
DuplicatesInd1,
|
package/src/subfield6Utils.js
CHANGED
|
@@ -127,7 +127,6 @@ export function fieldGetMaxSubfield6OccurrenceNumberAsInteger(field) {
|
|
|
127
127
|
return Math.max(...vals);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
131
130
|
export function fieldHasWantedTagAndOccurrenceNumber(field, tagAndOccurrenceNumber) {
|
|
132
131
|
return field.subfields && field.subfields.some(sf => subfield6HasWantedTagAndOccurrenceNumber(sf, tagAndOccurrenceNumber));
|
|
133
132
|
}
|
|
@@ -459,14 +458,16 @@ export function recordGetSubfield6ChainHeads(record) {
|
|
|
459
458
|
}
|
|
460
459
|
|
|
461
460
|
export function recordGetMaxSubfield6OccurrenceNumberAsInteger(record) {
|
|
461
|
+
if (record.fields.length === 0) {
|
|
462
|
+
return 0;
|
|
463
|
+
}
|
|
462
464
|
// Should we cache the value here?
|
|
463
465
|
const vals = record.fields.map((field) => fieldGetMaxSubfield6OccurrenceNumberAsInteger(field));
|
|
464
466
|
return Math.max(...vals);
|
|
465
467
|
}
|
|
466
468
|
|
|
467
|
-
|
|
468
469
|
export function get6s(field, candidateFields) { // NB! Convert field to fields!!!
|
|
469
|
-
// Get all fields with given
|
|
470
|
+
// Get all fields with given occurrence number
|
|
470
471
|
const sixes = field.subfields.filter(sf => isValidSubfield6(sf));
|
|
471
472
|
|
|
472
473
|
if (sixes.length === 0) {
|
package/src/utils.js
CHANGED
|
@@ -41,6 +41,19 @@ export function recordToString(record) {
|
|
|
41
41
|
return `${ldr}\n${fields.join('\n')}`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export function removeSubfield(record, tag, subfieldCode) {
|
|
45
|
+
record.fields = record.fields.map(field => { // eslint-disable-line functional/immutable-data
|
|
46
|
+
if (field.tag !== tag || !field.subfields) { // Don't procss irrelevant fields
|
|
47
|
+
return field;
|
|
48
|
+
}
|
|
49
|
+
field.subfields = field.subfields.filter(sf => sf.code !== subfieldCode); // eslint-disable-line functional/immutable-data
|
|
50
|
+
if (field.subfields.length === 0) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return field;
|
|
54
|
+
}).filter(field => field);
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
export function recordRemoveValuelessSubfields(record) {
|
|
45
58
|
record.fields = record.fields.map(field => { // eslint-disable-line functional/immutable-data
|
|
46
59
|
if (!field.subfields) { // Keep control fields
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "12345cam 22123454i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
6
|
+
{ "code": "6", "value": "880-01"},
|
|
7
|
+
{ "code": "a", "value": "Modin, Ûrij Ivanovič." },
|
|
8
|
+
{ "code": "9", "value": "ISO9 <TRANS>"}
|
|
9
|
+
]},
|
|
10
|
+
{ "tag": "880", "ind1": "1", "ind2": " ", "subfields": [
|
|
11
|
+
{"code": "6", "value": "100-01"},
|
|
12
|
+
{"code": "a", "value": "Модин, Юрий Иванович."},
|
|
13
|
+
{"code": "9", "value": "CYRILLIC <TRANS>"}
|
|
14
|
+
]},
|
|
15
|
+
{ "tag": "880", "ind1": "1", "ind2": " ", "subfields": [
|
|
16
|
+
{"code": "6", "value": "100-01"},
|
|
17
|
+
{"code": "a", "value": "Modin, Juri Ivanovitš."},
|
|
18
|
+
{"code": "9", "value": "SFS4900 <TRANS>"}
|
|
19
|
+
]}
|
|
20
|
+
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "12345cam 22123454i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
6
|
+
{ "code": "6", "value": "880-01"},
|
|
7
|
+
{ "code": "a", "value": "Modin, Ûrij Ivanovič." },
|
|
8
|
+
{ "code": "9", "value": "ISO9 <TRANS>"}
|
|
9
|
+
]},
|
|
10
|
+
{ "tag": "245", "ind1": "1", "ind2": " ", "subfields": [
|
|
11
|
+
{ "code": "6", "value": "880-02"},
|
|
12
|
+
{ "code": "a", "value": "Sudʹby razvedčikov." },
|
|
13
|
+
{ "code": "9", "value": "ISO9 <TRANS>"}
|
|
14
|
+
]},
|
|
15
|
+
{ "tag": "650", "ind1": "4", "ind2": " ", "subfields": [
|
|
16
|
+
{ "code": "a", "value": "whatever." }
|
|
17
|
+
]},
|
|
18
|
+
{ "tag": "880", "ind1": "1", "ind2": " ", "subfields": [
|
|
19
|
+
{"code": "6", "value": "100-01"},
|
|
20
|
+
{"code": "a", "value": "Модин, Юрий Иванович."},
|
|
21
|
+
{"code": "9", "value": "CYRILLIC <TRANS>"}
|
|
22
|
+
]},
|
|
23
|
+
{ "tag": "880", "ind1": "1", "ind2": " ", "subfields": [
|
|
24
|
+
{"code": "6", "value": "245-02"},
|
|
25
|
+
{"code": "a", "value": "Судьбы разведчиков."},
|
|
26
|
+
{"code": "9", "value": "CYRILLIC <TRANS>"}
|
|
27
|
+
]}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Fix: fields 100 and 245 require translitteration",
|
|
3
|
+
"comment": "Tests incrementation of occurrence numbers and usage of config",
|
|
4
|
+
"only": false,
|
|
5
|
+
"fix": true,
|
|
6
|
+
"config": {
|
|
7
|
+
"doISO9Transliteration": true,
|
|
8
|
+
"doSFS4900Transliteration": false
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"leader": "12345cam 22123454i 4500",
|
|
3
|
+
"fields": [
|
|
4
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
5
|
+
{ "code": "a", "value": "Модин, Юрий Иванович." }
|
|
6
|
+
]},
|
|
7
|
+
{"tag": "245", "ind1": "1", "ind2": " ", "subfields": [
|
|
8
|
+
{ "code": "a", "value": "Судьбы разведчиков."}
|
|
9
|
+
]},
|
|
10
|
+
{ "tag": "650", "ind1": "4", "ind2": " ", "subfields": [
|
|
11
|
+
{ "code": "a", "value": "whatever." }
|
|
12
|
+
]}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "12345cam 22123454i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
6
|
+
{ "code": "a", "value": "Modin, Ûrij Ivanovič." }
|
|
7
|
+
]},
|
|
8
|
+
{ "tag": "245", "ind1": "1", "ind2": " ", "subfields": [
|
|
9
|
+
{ "code": "a", "value": "Sudʹby razvedčikov." }
|
|
10
|
+
]}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"leader": "12345cam 22123454i 4500",
|
|
3
|
+
"fields": [
|
|
4
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
5
|
+
{ "code": "a", "value": "Модин, Юрий Иванович." }
|
|
6
|
+
]},
|
|
7
|
+
{"tag": "245", "ind1": "1", "ind2": " ", "subfields": [
|
|
8
|
+
{ "code": "a", "value": "Судьбы разведчиков."}
|
|
9
|
+
]}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_validationOptions": {},
|
|
3
|
+
"leader": "12345cam 22123454i 4500",
|
|
4
|
+
"fields": [
|
|
5
|
+
{ "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
|
|
6
|
+
{ "code": "a", "value": "Modin, Ûrij Ivanovič." }
|
|
7
|
+
]},
|
|
8
|
+
{ "tag": "245", "ind1": "1", "ind2": " ", "subfields": [
|
|
9
|
+
{ "code": "a", "value": "Sudʹby razvedčikov." }
|
|
10
|
+
]}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
|