@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.
Files changed (55) hide show
  1. package/dist/cyrillux-usemarcon-replacement.js +5 -2
  2. package/dist/cyrillux-usemarcon-replacement.js.map +1 -1
  3. package/dist/cyrillux.js +197 -0
  4. package/dist/cyrillux.js.map +1 -0
  5. package/dist/cyrillux.spec.js +46 -0
  6. package/dist/cyrillux.spec.js.map +1 -0
  7. package/dist/fix-33X.js +23 -2
  8. package/dist/fix-33X.js.map +1 -1
  9. package/dist/fixRelatorTerms.js +5 -1
  10. package/dist/fixRelatorTerms.js.map +1 -1
  11. package/dist/index.js +7 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/subfield6Utils.js +4 -1
  14. package/dist/subfield6Utils.js.map +1 -1
  15. package/dist/utils.js +15 -0
  16. package/dist/utils.js.map +1 -1
  17. package/package.json +9 -6
  18. package/src/cyrillux-usemarcon-replacement.js +6 -4
  19. package/src/cyrillux.js +173 -0
  20. package/src/cyrillux.spec.js +46 -0
  21. package/src/fix-33X.js +18 -2
  22. package/src/fixRelatorTerms.js +5 -2
  23. package/src/index.js +2 -0
  24. package/src/subfield6Utils.js +4 -3
  25. package/src/utils.js +13 -0
  26. package/test-fixtures/cyrillux/f01/expectedResult.json +23 -0
  27. package/test-fixtures/cyrillux/f01/metadata.json +5 -0
  28. package/test-fixtures/cyrillux/f01/record.json +8 -0
  29. package/test-fixtures/cyrillux/f02/expectedResult.json +30 -0
  30. package/test-fixtures/cyrillux/f02/metadata.json +10 -0
  31. package/test-fixtures/cyrillux/f02/record.json +14 -0
  32. package/test-fixtures/cyrillux/f03/expectedResult.json +13 -0
  33. package/test-fixtures/cyrillux/f03/metadata.json +10 -0
  34. package/test-fixtures/cyrillux/f03/record.json +11 -0
  35. package/test-fixtures/cyrillux/f04/expectedResult.json +13 -0
  36. package/test-fixtures/cyrillux/f04/metadata.json +10 -0
  37. package/test-fixtures/cyrillux/f04/record.json +11 -0
  38. package/test-fixtures/cyrillux/f05/expectedResult.json +20 -0
  39. package/test-fixtures/cyrillux/f05/metadata.json +5 -0
  40. package/test-fixtures/cyrillux/f05/record.json +18 -0
  41. package/test-fixtures/cyrillux/v01/expectedResult.json +7 -0
  42. package/test-fixtures/cyrillux/v01/metadata.json +5 -0
  43. package/test-fixtures/cyrillux/v01/record.json +8 -0
  44. package/test-fixtures/cyrillux/v02/expectedResult.json +5 -0
  45. package/test-fixtures/cyrillux/v02/metadata.json +5 -0
  46. package/test-fixtures/cyrillux/v02/record.json +8 -0
  47. package/test-fixtures/cyrillux-usemarcon-replacement/f15/expectedResult.json +38 -0
  48. package/test-fixtures/cyrillux-usemarcon-replacement/f15/metadata.json +5 -0
  49. package/test-fixtures/cyrillux-usemarcon-replacement/f15/record.json +35 -0
  50. package/test-fixtures/fix-relator-terms/f03/expectedResult.json +15 -0
  51. package/test-fixtures/fix-relator-terms/f03/metadata.json +5 -0
  52. package/test-fixtures/fix-relator-terms/f03/record.json +14 -0
  53. package/test-fixtures/sort-fields/12/input.json +60 -0
  54. package/test-fixtures/sort-fields/12/metadata.json +5 -0
  55. 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","recordRemoveValuelessSubfields","filter","tag","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 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":[]}
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.2.2-alpha.2",
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.23.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
- "xml2js": "^0.6.2"
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.5",
57
- "@babel/core": "^7.24.5",
58
- "@babel/preset-env": "^7.24.5",
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.fields.filter(f => f.tag === '040');
175
+ const f040 = record.get('040');
174
176
 
175
177
  const subfieldsBE = [
176
178
  {code: 'b', value: 'mul'},
@@ -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 = {
@@ -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
- 'сост.': 'toimittaja',
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,
@@ -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 occurence number
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,5 @@
1
+ {
2
+ "description": "Fix: field 100 required translitteration",
3
+ "only": false,
4
+ "fix": true
5
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "leader": "12345cam 22123454i 4500",
3
+ "fields": [
4
+ { "tag": "100", "ind1": "1", "ind2": " ", "subfields": [
5
+ { "code": "a", "value": "Модин, Юрий Иванович." }
6
+ ]}
7
+ ]
8
+ }
@@ -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,10 @@
1
+ {
2
+ "description": "Fix: just convert field 100 to ISO-9 latinitsa",
3
+ "comment": "Tests usage of config and omitting of $6 and $9",
4
+ "only": false,
5
+ "fix": true,
6
+ "config": {
7
+ "doISO9Transliteration": false,
8
+ "doSFS4900Transliteration": false
9
+ }
10
+ }
@@ -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
+
@@ -0,0 +1,10 @@
1
+ {
2
+ "description": "Fix: just convert field 100 to ISO-9 latinitsa",
3
+ "comment": "Tests usage of config and omitting of $6 and $9",
4
+ "only": false,
5
+ "fix": true,
6
+ "config": {
7
+ "doISO9Transliteration": false,
8
+ "doSFS4900Transliteration": false
9
+ }
10
+ }