@natlibfi/marc-record-validators-melinda 10.8.0 → 10.8.1-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/mergeRelatorTermFields.js +140 -0
- package/dist/mergeRelatorTermFields.js.map +1 -0
- package/dist/mergeRelatorTermFields.spec.js +51 -0
- package/dist/mergeRelatorTermFields.spec.js.map +1 -0
- package/dist/punctuation2.js +53 -22
- package/dist/punctuation2.js.map +1 -1
- package/dist/removeInferiorDataFields.js +14 -0
- package/dist/removeInferiorDataFields.js.map +1 -1
- package/dist/sortRelatorTerms.js +3 -1
- package/dist/sortRelatorTerms.js.map +1 -1
- package/dist/sortSubfields.js +5 -4
- package/dist/sortSubfields.js.map +1 -1
- package/dist/update-field-540.js +7 -1
- package/dist/update-field-540.js.map +1 -1
- package/package.json +4 -4
- package/src/mergeRelatorTermFields.js +143 -0
- package/src/mergeRelatorTermFields.spec.js +52 -0
- package/src/punctuation2.js +54 -23
- package/src/removeInferiorDataFields.js +14 -0
- package/src/sortRelatorTerms.js +4 -1
- package/src/sortSubfields.js +5 -4
- package/src/update-field-540.js +2 -1
- package/test-fixtures/mergeRelatorTermFields/fixer/01/expectedResult.json +14 -0
- package/test-fixtures/mergeRelatorTermFields/fixer/01/metadata.json +6 -0
- package/test-fixtures/mergeRelatorTermFields/fixer/01/record.json +16 -0
- package/test-fixtures/mergeRelatorTermFields/fixer/02/expectedResult.json +17 -0
- package/test-fixtures/mergeRelatorTermFields/fixer/02/metadata.json +6 -0
- package/test-fixtures/mergeRelatorTermFields/fixer/02/record.json +23 -0
- package/test-fixtures/mergeRelatorTermFields/validator/01/expectedResult.json +6 -0
- package/test-fixtures/mergeRelatorTermFields/validator/01/metadata.json +6 -0
- package/test-fixtures/mergeRelatorTermFields/validator/01/record.json +16 -0
- package/test-fixtures/mergeRelatorTermFields/validator/02/expectedResult.json +4 -0
- package/test-fixtures/mergeRelatorTermFields/validator/02/metadata.json +6 -0
- package/test-fixtures/mergeRelatorTermFields/validator/02/record.json +16 -0
- package/test-fixtures/punctuation2/98/expectedResult.json +6 -0
- package/test-fixtures/punctuation2/98/metadata.json +1 -1
- package/test-fixtures/punctuation2/98/record.json +6 -0
- package/test-fixtures/remove-inferior-datafields/f05/expectedResult.json +18 -1
- package/test-fixtures/remove-inferior-datafields/f05/metadata.json +1 -2
- package/test-fixtures/remove-inferior-datafields/f05/record.json +16 -0
- package/test-fixtures/remove-inferior-datafields/f06/expectedResult.json +16 -0
- package/test-fixtures/remove-inferior-datafields/f06/metadata.json +6 -0
- package/test-fixtures/remove-inferior-datafields/f06/record.json +20 -0
- package/test-fixtures/sort-subfields/f01/expectedResult.json +8 -0
- package/test-fixtures/sort-subfields/f01/metadata.json +1 -1
- package/test-fixtures/sort-subfields/f01/record.json +6 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = _default;
|
|
7
|
+
var _clone = _interopRequireDefault(require("clone"));
|
|
8
|
+
var _punctuation = require("./punctuation2");
|
|
9
|
+
var _utils = require("./utils");
|
|
10
|
+
var _sortSubfields = require("./sortSubfields");
|
|
11
|
+
var _sortRelatorTerms = require("./sortRelatorTerms");
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
// Merge author/agent fields
|
|
14
|
+
//
|
|
15
|
+
// Rationale: Same author can appear in one 1XX and multiple 7XX fields having only different $e subfields.
|
|
16
|
+
// These fields can be merged (and $e-subfields can then be sorted)...
|
|
17
|
+
//
|
|
18
|
+
// Author(s): Nicholas Volk
|
|
19
|
+
|
|
20
|
+
//import createDebugLogger from 'debug';
|
|
21
|
+
/*
|
|
22
|
+
//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:mergeRelatorTermFields');
|
|
23
|
+
//const debugData = debug.extend('data');
|
|
24
|
+
*/
|
|
25
|
+
function _default() {
|
|
26
|
+
return {
|
|
27
|
+
description: 'Merge author fields that only differ in $e relator terms',
|
|
28
|
+
validate,
|
|
29
|
+
fix
|
|
30
|
+
};
|
|
31
|
+
function fix(record) {
|
|
32
|
+
const msg = mergeRelatorTermFields(record, true);
|
|
33
|
+
const res = {
|
|
34
|
+
message: msg,
|
|
35
|
+
fix: msg,
|
|
36
|
+
valid: true
|
|
37
|
+
};
|
|
38
|
+
return res;
|
|
39
|
+
}
|
|
40
|
+
function validate(record) {
|
|
41
|
+
const msg = mergeRelatorTermFields(record, false);
|
|
42
|
+
const res = {
|
|
43
|
+
message: msg
|
|
44
|
+
};
|
|
45
|
+
res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data
|
|
46
|
+
return res;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createNormalizedClone(field) {
|
|
50
|
+
const clonedField = (0, _clone.default)(field);
|
|
51
|
+
// Normalize
|
|
52
|
+
(0, _punctuation.fieldStripPunctuation)(clonedField);
|
|
53
|
+
return clonedField;
|
|
54
|
+
}
|
|
55
|
+
function createNormalizedCloneWithoutRelatorTerms(field) {
|
|
56
|
+
const clonedField = createNormalizedClone(field);
|
|
57
|
+
// Remove relator terms $e subfi:
|
|
58
|
+
clonedField.subfields = clonedField.subfields.filter(sf => sf.code !== 'e'); // eslint-disable-line functional/immutable-data
|
|
59
|
+
return clonedField;
|
|
60
|
+
}
|
|
61
|
+
function fieldToRelatorTermSubfieldCode(field) {
|
|
62
|
+
if (['100', '110', '700', '710', '720', '751', '752'].includes(field.tag)) {
|
|
63
|
+
return 'e';
|
|
64
|
+
}
|
|
65
|
+
if (field.tag === '111' || field.tag === '711') {
|
|
66
|
+
return 'j';
|
|
67
|
+
}
|
|
68
|
+
return '?'; // No need to complain. Nothing is found.
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getRelatorTermStrings(relatorTermSubfieldCode, field) {
|
|
72
|
+
return field.subfields.filter(sf => sf.code === relatorTermSubfieldCode).map(sf => sf.value);
|
|
73
|
+
}
|
|
74
|
+
function extractAddableRelatorTerms(fromField, toField) {
|
|
75
|
+
const relatorTermSubfieldCode = fieldToRelatorTermSubfieldCode(fromField);
|
|
76
|
+
const normalizedFromFieldRelatorTerms = getRelatorTermStrings(relatorTermSubfieldCode, fromField);
|
|
77
|
+
if (normalizedFromFieldRelatorTerms.length === 0) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
// Remove values that already exist:
|
|
81
|
+
const normalizedToFieldRelatorTerms = getRelatorTermStrings(relatorTermSubfieldCode, toField);
|
|
82
|
+
return normalizedFromFieldRelatorTerms.filter(str => !normalizedToFieldRelatorTerms.includes(str));
|
|
83
|
+
}
|
|
84
|
+
function copyRelatorSubfields(fromField, toField) {
|
|
85
|
+
const relatorTermSubfieldCode = fieldToRelatorTermSubfieldCode(fromField);
|
|
86
|
+
const newRelatorTerms = extractAddableRelatorTerms(fromField, toField);
|
|
87
|
+
newRelatorTerms.forEach(term => toField.subfields.push({
|
|
88
|
+
code: relatorTermSubfieldCode,
|
|
89
|
+
value: term
|
|
90
|
+
})); // eslint-disable-line functional/immutable-data
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function mergeRelatorTermFields(record, fix = false) {
|
|
94
|
+
/* eslint-disable */
|
|
95
|
+
// NV: 111/711, 751 and 752 where so rare that I did not add them here
|
|
96
|
+
let fields = record.get('(?:[17][01]0|720)');
|
|
97
|
+
let result = [];
|
|
98
|
+
const comparisonFieldsAsString = fields.map(f => (0, _utils.fieldToString)(createNormalizedCloneWithoutRelatorTerms(f)));
|
|
99
|
+
(0, _utils.nvdebug)(`mergeRelatorTermFields(): ${fields.length} cand field(s) found`);
|
|
100
|
+
for (let i = 0; i < fields.length - 1; i++) {
|
|
101
|
+
let currField = fields[i];
|
|
102
|
+
if (currField.deleted) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
(0, _utils.nvdebug)(`RT: Trying to pair ${comparisonFieldsAsString[i]}/${i}`);
|
|
106
|
+
for (let j = i + 1; j < fields.length; j++) {
|
|
107
|
+
(0, _utils.nvdebug)(` Compare with ${comparisonFieldsAsString[j]}/${j}`);
|
|
108
|
+
let mergableField = fields[j];
|
|
109
|
+
// Skip 1/7 from 1XX/7XX for similarity check:
|
|
110
|
+
if (comparisonFieldsAsString[i].substring(1) !== comparisonFieldsAsString[j].substring(1)) {
|
|
111
|
+
(0, _utils.nvdebug)(" NOT PAIR");
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (mergableField.deleted) {
|
|
115
|
+
(0, _utils.nvdebug)(" DELETED");
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const str = `MERGE RELATOR TERM FIELD: ${(0, _utils.fieldToString)(mergableField)}`;
|
|
119
|
+
(0, _utils.nvdebug)(str);
|
|
120
|
+
if (!result.includes(str)) {
|
|
121
|
+
result.push(str);
|
|
122
|
+
}
|
|
123
|
+
if (fix) {
|
|
124
|
+
mergableField.deleted = 1;
|
|
125
|
+
copyRelatorSubfields(mergableField, currField);
|
|
126
|
+
(0, _punctuation.fieldFixPunctuation)(currField);
|
|
127
|
+
(0, _sortSubfields.sortAdjacentSubfields)(currField); // Put the added $e subfield to proper places.
|
|
128
|
+
(0, _sortRelatorTerms.sortAdjacentESubfields)(currField); // Sort $e subfields with each other
|
|
129
|
+
(0, _punctuation.fieldFixPunctuation)(currField);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!fix) {
|
|
134
|
+
fields.forEach(f => delete f.deleted);
|
|
135
|
+
}
|
|
136
|
+
record.fields = record.fields.filter(f => !f.deleted);
|
|
137
|
+
/* eslint-enable */
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=mergeRelatorTermFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeRelatorTermFields.js","names":["_clone","_interopRequireDefault","require","_punctuation","_utils","_sortSubfields","_sortRelatorTerms","obj","__esModule","default","_default","description","validate","fix","record","msg","mergeRelatorTermFields","res","message","valid","length","createNormalizedClone","field","clonedField","clone","fieldStripPunctuation","createNormalizedCloneWithoutRelatorTerms","subfields","filter","sf","code","fieldToRelatorTermSubfieldCode","includes","tag","getRelatorTermStrings","relatorTermSubfieldCode","map","value","extractAddableRelatorTerms","fromField","toField","normalizedFromFieldRelatorTerms","normalizedToFieldRelatorTerms","str","copyRelatorSubfields","newRelatorTerms","forEach","term","push","fields","get","result","comparisonFieldsAsString","f","fieldToString","nvdebug","i","currField","deleted","j","mergableField","substring","fieldFixPunctuation","sortAdjacentSubfields","sortAdjacentESubfields"],"sources":["../src/mergeRelatorTermFields.js"],"sourcesContent":["// Merge author/agent fields\n//\n// Rationale: Same author can appear in one 1XX and multiple 7XX fields having only different $e subfields.\n// These fields can be merged (and $e-subfields can then be sorted)...\n//\n// Author(s): Nicholas Volk\n\n\nimport clone from 'clone';\nimport {fieldFixPunctuation, fieldStripPunctuation} from './punctuation2';\nimport {fieldToString, nvdebug} from './utils';\nimport {sortAdjacentSubfields} from './sortSubfields';\nimport {sortAdjacentESubfields} from './sortRelatorTerms';\n//import createDebugLogger from 'debug';\n/*\n//const debug = createDebugLogger('@natlibfi/marc-record-validators-melinda:mergeRelatorTermFields');\n//const debugData = debug.extend('data');\n*/\n\nexport default function () {\n\n return {\n description: 'Merge author fields that only differ in $e relator terms',\n validate, fix\n };\n\n function fix(record) {\n const msg = mergeRelatorTermFields(record, true);\n const res = {message: msg, fix: msg, valid: true};\n return res;\n }\n\n function validate(record) {\n const msg = mergeRelatorTermFields(record, false);\n const res = {message: msg};\n\n res.valid = !(res.message.length >= 1); // eslint-disable-line functional/immutable-data\n return res;\n }\n}\n\nfunction createNormalizedClone(field) {\n const clonedField = clone(field);\n // Normalize\n fieldStripPunctuation(clonedField);\n return clonedField;\n}\n\nfunction createNormalizedCloneWithoutRelatorTerms(field) {\n const clonedField = createNormalizedClone(field);\n // Remove relator terms $e subfi:\n clonedField.subfields = clonedField.subfields.filter(sf => sf.code !== 'e'); // eslint-disable-line functional/immutable-data\n return clonedField;\n}\n\nfunction fieldToRelatorTermSubfieldCode(field) {\n if (['100', '110', '700', '710', '720', '751', '752'].includes(field.tag)) {\n return 'e';\n }\n if (field.tag === '111' || field.tag === '711') {\n return 'j';\n }\n return '?'; // No need to complain. Nothing is found.\n}\n\nfunction getRelatorTermStrings(relatorTermSubfieldCode, field) {\n return field.subfields.filter(sf => sf.code === relatorTermSubfieldCode).map(sf => sf.value);\n\n}\n\nfunction extractAddableRelatorTerms(fromField, toField) {\n const relatorTermSubfieldCode = fieldToRelatorTermSubfieldCode(fromField);\n const normalizedFromFieldRelatorTerms = getRelatorTermStrings(relatorTermSubfieldCode, fromField);\n if (normalizedFromFieldRelatorTerms.length === 0) {\n return [];\n }\n // Remove values that already exist:\n const normalizedToFieldRelatorTerms = getRelatorTermStrings(relatorTermSubfieldCode, toField);\n return normalizedFromFieldRelatorTerms.filter(str => !normalizedToFieldRelatorTerms.includes(str));\n}\n\n\nfunction copyRelatorSubfields(fromField, toField) {\n const relatorTermSubfieldCode = fieldToRelatorTermSubfieldCode(fromField);\n const newRelatorTerms = extractAddableRelatorTerms(fromField, toField);\n\n newRelatorTerms.forEach(term => toField.subfields.push({code: relatorTermSubfieldCode, value: term})); // eslint-disable-line functional/immutable-data\n\n}\n\nfunction mergeRelatorTermFields(record, fix = false) {\n /* eslint-disable */\n // NV: 111/711, 751 and 752 where so rare that I did not add them here\n let fields = record.get('(?:[17][01]0|720)'); \n let result = [];\n const comparisonFieldsAsString = fields.map(f => fieldToString(createNormalizedCloneWithoutRelatorTerms(f)));\n\n nvdebug(`mergeRelatorTermFields(): ${fields.length} cand field(s) found`);\n for(let i=0; i < fields.length-1; i++) {\n let currField = fields[i];\n if (currField.deleted) {\n continue;\n }\n nvdebug(`RT: Trying to pair ${comparisonFieldsAsString[i]}/${i}`);\n for (let j=i+1; j < fields.length; j++) {\n nvdebug(` Compare with ${comparisonFieldsAsString[j]}/${j}`);\n let mergableField = fields[j];\n // Skip 1/7 from 1XX/7XX for similarity check:\n if ( comparisonFieldsAsString[i].substring(1) !== comparisonFieldsAsString[j].substring(1)) {\n nvdebug(\" NOT PAIR\");\n continue;\n }\n if (mergableField.deleted) {\n nvdebug(\" DELETED\");\n continue;\n }\n const str = `MERGE RELATOR TERM FIELD: ${fieldToString(mergableField)}`;\n nvdebug(str);\n\n if(!result.includes(str)) {\n result.push(str)\n }\n\n if (fix) {\n mergableField.deleted = 1;\n copyRelatorSubfields(mergableField, currField);\n fieldFixPunctuation(currField);\n sortAdjacentSubfields(currField); // Put the added $e subfield to proper places.\n sortAdjacentESubfields(currField); // Sort $e subfields with each other\n fieldFixPunctuation(currField);\n\n }\n }\n }\n\n if(!fix) {\n fields.forEach(f => delete f.deleted);\n }\n\n record.fields = record.fields.filter(f => !f.deleted);\n /* eslint-enable */\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _chai = require("chai");
|
|
4
|
+
var _marcRecord = require("@natlibfi/marc-record");
|
|
5
|
+
var _mergeRelatorTermFields = _interopRequireDefault(require("./mergeRelatorTermFields"));
|
|
6
|
+
var _fixura = require("@natlibfi/fixura");
|
|
7
|
+
var _fixugen = _interopRequireDefault(require("@natlibfi/fixugen"));
|
|
8
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
(0, _fixugen.default)({
|
|
11
|
+
callback,
|
|
12
|
+
path: [__dirname, '..', 'test-fixtures', 'mergeRelatorTermFields'],
|
|
13
|
+
useMetadataFile: true,
|
|
14
|
+
recurse: true,
|
|
15
|
+
fixura: {
|
|
16
|
+
reader: _fixura.READERS.JSON
|
|
17
|
+
},
|
|
18
|
+
mocha: {
|
|
19
|
+
before: () => testValidatorFactory()
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const debug = (0, _debug.default)('@natlibfi/marc-record-validators-melinda/mergeRelatorTermFields:test');
|
|
23
|
+
async function testValidatorFactory() {
|
|
24
|
+
const validator = await (0, _mergeRelatorTermFields.default)();
|
|
25
|
+
(0, _chai.expect)(validator).to.be.an('object').that.has.any.keys('description', 'validate');
|
|
26
|
+
(0, _chai.expect)(validator.description).to.be.a('string');
|
|
27
|
+
(0, _chai.expect)(validator.validate).to.be.a('function');
|
|
28
|
+
}
|
|
29
|
+
async function callback({
|
|
30
|
+
getFixture,
|
|
31
|
+
enabled = true,
|
|
32
|
+
fix = false
|
|
33
|
+
}) {
|
|
34
|
+
if (enabled === false) {
|
|
35
|
+
debug('TEST SKIPPED!');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const validator = await (0, _mergeRelatorTermFields.default)();
|
|
39
|
+
const record = new _marcRecord.MarcRecord(getFixture('record.json'));
|
|
40
|
+
const expectedResult = getFixture('expectedResult.json');
|
|
41
|
+
// console.log(expectedResult); // eslint-disable-line
|
|
42
|
+
|
|
43
|
+
if (!fix) {
|
|
44
|
+
const result = await validator.validate(record);
|
|
45
|
+
(0, _chai.expect)(result).to.eql(expectedResult);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
await validator.fix(record);
|
|
49
|
+
(0, _chai.expect)(record).to.eql(expectedResult);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=mergeRelatorTermFields.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeRelatorTermFields.spec.js","names":["_chai","require","_marcRecord","_mergeRelatorTermFields","_interopRequireDefault","_fixura","_fixugen","_debug","obj","__esModule","default","generateTests","callback","path","__dirname","useMetadataFile","recurse","fixura","reader","READERS","JSON","mocha","before","testValidatorFactory","debug","createDebugLogger","validator","validatorFactory","expect","to","be","an","that","has","any","keys","description","a","validate","getFixture","enabled","fix","record","MarcRecord","expectedResult","result","eql"],"sources":["../src/mergeRelatorTermFields.spec.js"],"sourcesContent":["import {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport validatorFactory from './mergeRelatorTermFields';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\nimport createDebugLogger from 'debug';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'mergeRelatorTermFields'],\n useMetadataFile: true,\n recurse: true,\n fixura: {\n reader: READERS.JSON\n },\n mocha: {\n before: () => testValidatorFactory()\n }\n});\nconst debug = createDebugLogger('@natlibfi/marc-record-validators-melinda/mergeRelatorTermFields:test');\n\nasync function testValidatorFactory() {\n const validator = await validatorFactory();\n\n expect(validator)\n .to.be.an('object')\n .that.has.any.keys('description', 'validate');\n\n expect(validator.description).to.be.a('string');\n expect(validator.validate).to.be.a('function');\n}\n\nasync function callback({getFixture, enabled = true, fix = false}) {\n if (enabled === false) {\n debug('TEST SKIPPED!');\n return;\n }\n\n const validator = await validatorFactory();\n const record = new MarcRecord(getFixture('record.json'));\n const expectedResult = getFixture('expectedResult.json');\n // console.log(expectedResult); // eslint-disable-line\n\n if (!fix) {\n const result = await validator.validate(record);\n expect(result).to.eql(expectedResult);\n return;\n }\n\n await validator.fix(record);\n expect(record).to.eql(expectedResult);\n}\n"],"mappings":";;AAAA,IAAAA,KAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,uBAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,QAAA,GAAAF,sBAAA,CAAAH,OAAA;AACA,IAAAM,MAAA,GAAAH,sBAAA,CAAAH,OAAA;AAAsC,SAAAG,uBAAAI,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAEtC,IAAAG,gBAAa,EAAC;EACZC,QAAQ;EACRC,IAAI,EAAE,CAACC,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,wBAAwB,CAAC;EAClEC,eAAe,EAAE,IAAI;EACrBC,OAAO,EAAE,IAAI;EACbC,MAAM,EAAE;IACNC,MAAM,EAAEC,eAAO,CAACC;EAClB,CAAC;EACDC,KAAK,EAAE;IACLC,MAAM,EAAEA,CAAA,KAAMC,oBAAoB,CAAC;EACrC;AACF,CAAC,CAAC;AACF,MAAMC,KAAK,GAAG,IAAAC,cAAiB,EAAC,sEAAsE,CAAC;AAEvG,eAAeF,oBAAoBA,CAAA,EAAG;EACpC,MAAMG,SAAS,GAAG,MAAM,IAAAC,+BAAgB,EAAC,CAAC;EAE1C,IAAAC,YAAM,EAACF,SAAS,CAAC,CACdG,EAAE,CAACC,EAAE,CAACC,EAAE,CAAC,QAAQ,CAAC,CAClBC,IAAI,CAACC,GAAG,CAACC,GAAG,CAACC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC;EAE/C,IAAAP,YAAM,EAACF,SAAS,CAACU,WAAW,CAAC,CAACP,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,QAAQ,CAAC;EAC/C,IAAAT,YAAM,EAACF,SAAS,CAACY,QAAQ,CAAC,CAACT,EAAE,CAACC,EAAE,CAACO,CAAC,CAAC,UAAU,CAAC;AAChD;AAEA,eAAezB,QAAQA,CAAC;EAAC2B,UAAU;EAAEC,OAAO,GAAG,IAAI;EAAEC,GAAG,GAAG;AAAK,CAAC,EAAE;EACjE,IAAID,OAAO,KAAK,KAAK,EAAE;IACrBhB,KAAK,CAAC,eAAe,CAAC;IACtB;EACF;EAEA,MAAME,SAAS,GAAG,MAAM,IAAAC,+BAAgB,EAAC,CAAC;EAC1C,MAAMe,MAAM,GAAG,IAAIC,sBAAU,CAACJ,UAAU,CAAC,aAAa,CAAC,CAAC;EACxD,MAAMK,cAAc,GAAGL,UAAU,CAAC,qBAAqB,CAAC;EACxD;;EAEA,IAAI,CAACE,GAAG,EAAE;IACR,MAAMI,MAAM,GAAG,MAAMnB,SAAS,CAACY,QAAQ,CAACI,MAAM,CAAC;IAC/C,IAAAd,YAAM,EAACiB,MAAM,CAAC,CAAChB,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;IACrC;EACF;EAEA,MAAMlB,SAAS,CAACe,GAAG,CAACC,MAAM,CAAC;EAC3B,IAAAd,YAAM,EAACc,MAAM,CAAC,CAACb,EAAE,CAACiB,GAAG,CAACF,cAAc,CAAC;AACvC"}
|
package/dist/punctuation2.js
CHANGED
|
@@ -17,6 +17,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
17
17
|
*
|
|
18
18
|
* NOTE #1: https://www.kiwi.fi/display/kumea/Loppupisteohje is implemented via another validator/fixer.(ending-punctuation)
|
|
19
19
|
* NOTE #2: Validator/fixer punctuation does similar stuff, but focuses on X00 fields.
|
|
20
|
+
* NOTE #3: As of 2023-06-05 control subfields ($0...$9) are obsolete. Don't use them in rules.
|
|
21
|
+
* (They are jumped over when looking for next (non-controlfield subfield)
|
|
20
22
|
*/
|
|
21
23
|
|
|
22
24
|
// import createDebugLogger from 'debug';
|
|
@@ -52,12 +54,18 @@ function _default() {
|
|
|
52
54
|
return res;
|
|
53
55
|
}
|
|
54
56
|
}
|
|
57
|
+
function isControlSubfield(subfield) {
|
|
58
|
+
return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(subfield.code);
|
|
59
|
+
}
|
|
60
|
+
function getNextRelevantSubfield(field, currSubfieldIndex) {
|
|
61
|
+
return field.subfields.find((subfield, index) => index > currSubfieldIndex && !isControlSubfield(subfield));
|
|
62
|
+
}
|
|
55
63
|
function fieldGetFixedString(field) {
|
|
56
64
|
const cloneField = (0, _clone.default)(field);
|
|
57
65
|
cloneField.subfields.forEach((sf, i) => {
|
|
58
66
|
// NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
|
|
59
67
|
// (In plain English: We should skip $0 - $9 at least, maybe $w as well...)
|
|
60
|
-
subfieldFixPunctuation(cloneField
|
|
68
|
+
subfieldFixPunctuation(cloneField, sf, getNextRelevantSubfield(cloneField, i));
|
|
61
69
|
});
|
|
62
70
|
return (0, _utils.fieldToString)(cloneField);
|
|
63
71
|
}
|
|
@@ -92,7 +100,7 @@ const removeColons = {
|
|
|
92
100
|
};
|
|
93
101
|
const removeX00Comma = {
|
|
94
102
|
'code': 'abcqde',
|
|
95
|
-
'followedBy': 'abcqde#
|
|
103
|
+
'followedBy': 'abcqde#',
|
|
96
104
|
'context': /.,$/u,
|
|
97
105
|
'remove': /,$/u
|
|
98
106
|
};
|
|
@@ -105,7 +113,7 @@ const cleanRHS = {
|
|
|
105
113
|
};
|
|
106
114
|
const cleanX00dCommaOrDot = {
|
|
107
115
|
'code': 'd',
|
|
108
|
-
'followedBy': 'et#
|
|
116
|
+
'followedBy': 'et#',
|
|
109
117
|
'context': /[0-9]-[,.]$/u,
|
|
110
118
|
'remove': /[,.]$/u
|
|
111
119
|
};
|
|
@@ -122,7 +130,7 @@ const cleanCorruption = {
|
|
|
122
130
|
// These $e dot removals are tricky: before removing the comma, we should know that it ain't an abbreviation such as "esitt."...
|
|
123
131
|
const cleanX00eDot = {
|
|
124
132
|
'code': 'e',
|
|
125
|
-
'followedBy': 'egj#
|
|
133
|
+
'followedBy': 'egj#',
|
|
126
134
|
'context': /(?:[ai]ja|jä)[.,]$/u,
|
|
127
135
|
'remove': /\.$/u
|
|
128
136
|
};
|
|
@@ -155,7 +163,7 @@ const addX00aComma2 = {
|
|
|
155
163
|
const addX00aDot = {
|
|
156
164
|
'add': '.',
|
|
157
165
|
'code': 'abcde',
|
|
158
|
-
'followedBy': '#
|
|
166
|
+
'followedBy': '#tu',
|
|
159
167
|
'context': defaultNeedsPuncAfter
|
|
160
168
|
};
|
|
161
169
|
const addX10bDot = {
|
|
@@ -175,7 +183,7 @@ const addX10Dot = {
|
|
|
175
183
|
'name': 'Add X10 final dot',
|
|
176
184
|
'add': '.',
|
|
177
185
|
'code': 'abe',
|
|
178
|
-
'followedBy': '#
|
|
186
|
+
'followedBy': '#',
|
|
179
187
|
'context': defaultNeedsPuncAfter
|
|
180
188
|
};
|
|
181
189
|
const addLanguageComma = {
|
|
@@ -272,13 +280,13 @@ const cleanLegalX00Comma = {
|
|
|
272
280
|
// Accept upper case letters in X00$b, since they are probably Roman numerals.
|
|
273
281
|
const cleanLegalX00bDot = {
|
|
274
282
|
'code': 'b',
|
|
275
|
-
'followedBy': 't#
|
|
283
|
+
'followedBy': 't#',
|
|
276
284
|
context: /^[IVXLCDM]+\.$/u,
|
|
277
285
|
'remove': /\.$/u
|
|
278
286
|
};
|
|
279
287
|
const cleanLegalX00Dot = {
|
|
280
288
|
'code': 'abcdetvl',
|
|
281
|
-
'followedBy': 'tu#
|
|
289
|
+
'followedBy': 'tu#',
|
|
282
290
|
'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u,
|
|
283
291
|
'remove': /\.$/u
|
|
284
292
|
};
|
|
@@ -300,7 +308,7 @@ const cleanLegalX10Comma = {
|
|
|
300
308
|
const cleanLegalX10Dot = {
|
|
301
309
|
'name': 'X10dot',
|
|
302
310
|
'code': 'ab',
|
|
303
|
-
'followedBy': 'b#
|
|
311
|
+
'followedBy': 'b#',
|
|
304
312
|
'context': /.\.$/u,
|
|
305
313
|
'remove': /\.$/u
|
|
306
314
|
};
|
|
@@ -418,6 +426,13 @@ const cleanValidPunctuationRules = {
|
|
|
418
426
|
'code': 'p',
|
|
419
427
|
'followedBy': 'c',
|
|
420
428
|
'remove': /:$/u
|
|
429
|
+
}],
|
|
430
|
+
// Experimental, MET366-ish (end punc in internationally valid, but we don't use it here in Finland):
|
|
431
|
+
'648': [{
|
|
432
|
+
'code': 'a',
|
|
433
|
+
'content': /^[0-9]+\.$/u,
|
|
434
|
+
'ind2': ['4'],
|
|
435
|
+
'remove': /\.$/u
|
|
421
436
|
}]
|
|
422
437
|
};
|
|
423
438
|
|
|
@@ -550,6 +565,18 @@ function ruleAppliesToSubfieldCode(targetSubfieldCodes, currSubfieldCode) {
|
|
|
550
565
|
}
|
|
551
566
|
return targetSubfieldCodes.includes(currSubfieldCode);
|
|
552
567
|
}
|
|
568
|
+
function ruleAppliesToField(rule, field) {
|
|
569
|
+
if ('ind1' in rule && field.ind1.includes(rule.ind1)) {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
if ('ind2' in rule && field.ind2.includes(rule.ind2)) {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// If we want to check, say, $2, it should be implemented here!
|
|
577
|
+
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
553
580
|
function ruleAppliesToCurrentSubfield(rule, subfield) {
|
|
554
581
|
if (!ruleAppliesToSubfieldCode(rule.code, subfield.code)) {
|
|
555
582
|
return false;
|
|
@@ -566,7 +593,7 @@ function ruleAppliesToNextSubfield(rule, nextSubfield) {
|
|
|
566
593
|
return true;
|
|
567
594
|
}
|
|
568
595
|
// The '#' existence check applies only to the RHS field. LHS always exists.
|
|
569
|
-
if (nextSubfield
|
|
596
|
+
if (!nextSubfield) {
|
|
570
597
|
const negation = rule.followedBy.includes('!');
|
|
571
598
|
if (negation) {
|
|
572
599
|
return !rule.followedBy.includes('#');
|
|
@@ -582,16 +609,20 @@ function ruleAppliesToNextSubfield(rule, nextSubfield) {
|
|
|
582
609
|
}
|
|
583
610
|
return true;
|
|
584
611
|
}
|
|
585
|
-
function checkRule(rule, subfield1, subfield2) {
|
|
612
|
+
function checkRule(rule, field, subfield1, subfield2) {
|
|
613
|
+
if (!ruleAppliesToField(rule, field)) {
|
|
614
|
+
(0, _utils.nvdebug)(`FAIL ON WHOLE FIELD: '${(0, _utils.fieldToString)(field)}`);
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
586
617
|
//const name = rule.name || 'UNNAMED';
|
|
587
618
|
if (!ruleAppliesToCurrentSubfield(rule, subfield1)) {
|
|
588
|
-
//nvdebug(`${name}: FAIL ON LHS
|
|
619
|
+
//nvdebug(`${name}: FAIL ON LHS SUBFIELD: '$${subfield1.code} ${subfield1.value}', SF=${rule.code}`, debug);
|
|
589
620
|
return false;
|
|
590
621
|
}
|
|
591
622
|
|
|
592
623
|
// NB! This is not a perfect solution. We might have $e$0$e where $e$0 punctuation should actually be based on $e$e rules
|
|
593
624
|
if (!ruleAppliesToNextSubfield(rule, subfield2)) {
|
|
594
|
-
//const msg = subfield2 ? `${name}: FAIL ON RHS
|
|
625
|
+
//const msg = subfield2 ? `${name}: FAIL ON RHS SUBFIELD '${subfield2.code}' not in [${rule.followedBy}]` : `${name}: FAIL ON RHS FIELD`;
|
|
595
626
|
//nvdebug(msg, debug);
|
|
596
627
|
return false;
|
|
597
628
|
}
|
|
@@ -599,14 +630,14 @@ function checkRule(rule, subfield1, subfield2) {
|
|
|
599
630
|
//nvdebug(`${name}: ACCEPT ${rule.code}/${subfield1.code}, SF2=${rule.followedBy}/${subfield2 ? subfield2.code : '#'}`, debug);
|
|
600
631
|
return true;
|
|
601
632
|
}
|
|
602
|
-
function applyPunctuationRules(
|
|
633
|
+
function applyPunctuationRules(field, subfield1, subfield2, ruleArray = null, operation = NONE) {
|
|
603
634
|
/*
|
|
604
635
|
if (ruleArray === null || operation === NONE) {
|
|
605
636
|
debug(`applyPunctuation(): No rules to apply!`);
|
|
606
637
|
return;
|
|
607
638
|
}
|
|
608
639
|
*/
|
|
609
|
-
if (!(`${tag}` in ruleArray) || ruleArray === null || operation === NONE) {
|
|
640
|
+
if (!(`${field.tag}` in ruleArray) || ruleArray === null || operation === NONE) {
|
|
610
641
|
/*
|
|
611
642
|
if (!['020', '650'].includes(tag) || !isControlSubfieldCode(subfield1.code)) { // eslint-disable-line functional/no-conditional-statements
|
|
612
643
|
nvdebug(`No punctuation rules found for ${tag} (looking for: ‡${subfield1.code})`, debug);
|
|
@@ -616,7 +647,7 @@ function applyPunctuationRules(tag, subfield1, subfield2, ruleArray = null, oper
|
|
|
616
647
|
}
|
|
617
648
|
|
|
618
649
|
//nvdebug(`OP=${operation} ${tag}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`, debug);
|
|
619
|
-
const activeRules = ruleArray[tag].filter(rule => checkRule(rule, subfield1, subfield2));
|
|
650
|
+
const activeRules = ruleArray[field.tag].filter(rule => checkRule(rule, field, subfield1, subfield2));
|
|
620
651
|
activeRules.forEach(rule => {
|
|
621
652
|
const originalValue = subfield1.value;
|
|
622
653
|
if (rule.remove && [REMOVE, REMOVE_AND_ADD].includes(operation) && subfield1.value.match(rule.remove)) {
|
|
@@ -637,9 +668,9 @@ function applyPunctuationRules(tag, subfield1, subfield2, ruleArray = null, oper
|
|
|
637
668
|
}
|
|
638
669
|
});
|
|
639
670
|
}
|
|
640
|
-
function subfieldFixPunctuation(
|
|
641
|
-
applyPunctuationRules(
|
|
642
|
-
applyPunctuationRules(
|
|
671
|
+
function subfieldFixPunctuation(field, subfield1, subfield2) {
|
|
672
|
+
applyPunctuationRules(field, subfield1, subfield2, cleanCrappyPunctuationRules, REMOVE);
|
|
673
|
+
applyPunctuationRules(field, subfield1, subfield2, addPairedPunctuationRules, ADD);
|
|
643
674
|
}
|
|
644
675
|
function fieldStripPunctuation(field) {
|
|
645
676
|
if (!field.subfields) {
|
|
@@ -647,9 +678,9 @@ function fieldStripPunctuation(field) {
|
|
|
647
678
|
}
|
|
648
679
|
field.subfields.forEach((sf, i) => {
|
|
649
680
|
(0, _utils.nvdebug)(`FSP1: '${sf.value}'`);
|
|
650
|
-
applyPunctuationRules(field
|
|
681
|
+
applyPunctuationRules(field, sf, i + 1 < field.subfields.length ? field.subfields[i + 1] : null, cleanValidPunctuationRules, REMOVE);
|
|
651
682
|
(0, _utils.nvdebug)(`FSP2: '${sf.value}'`);
|
|
652
|
-
applyPunctuationRules(field
|
|
683
|
+
applyPunctuationRules(field, sf, i + 1 < field.subfields.length ? field.subfields[i + 1] : null, cleanCrappyPunctuationRules, REMOVE);
|
|
653
684
|
(0, _utils.nvdebug)(`FSP3: '${sf.value}'`);
|
|
654
685
|
});
|
|
655
686
|
return field;
|
|
@@ -662,7 +693,7 @@ function fieldFixPunctuation(field) {
|
|
|
662
693
|
field.subfields.forEach((sf, i) => {
|
|
663
694
|
// NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
|
|
664
695
|
// (In plain English: We should skip $0 - $9 at least, maybe $w as well...)
|
|
665
|
-
subfieldFixPunctuation(field
|
|
696
|
+
subfieldFixPunctuation(field, sf, getNextRelevantSubfield(field, i));
|
|
666
697
|
});
|
|
667
698
|
|
|
668
699
|
// Use shared code for final punctuation (sadly this does not fix intermediate punc):
|