@natlibfi/marc-record-validators-melinda 10.16.0 → 10.16.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.
Files changed (131) hide show
  1. package/dist/access-rights.js.map +1 -1
  2. package/dist/access-rights.spec.js.map +1 -1
  3. package/dist/double-commas.js.map +1 -1
  4. package/dist/double-commas.spec.js.map +1 -1
  5. package/dist/duplicates-ind1.js.map +1 -1
  6. package/dist/duplicates-ind1.spec.js.map +1 -1
  7. package/dist/empty-fields.js.map +1 -1
  8. package/dist/empty-fields.spec.js.map +1 -1
  9. package/dist/ending-punctuation-conf.js.map +1 -1
  10. package/dist/ending-punctuation.js.map +1 -1
  11. package/dist/ending-punctuation.spec.js.map +1 -1
  12. package/dist/ending-whitespace.js.map +1 -1
  13. package/dist/ending-whitespace.spec.js.map +1 -1
  14. package/dist/field-008-18-34-character-groups.js.map +1 -1
  15. package/dist/field-008-18-34-character-groups.spec.js.map +1 -1
  16. package/dist/field-505-separators.js.map +1 -1
  17. package/dist/field-505-separators.spec.js.map +1 -1
  18. package/dist/field-521-fix.js.map +1 -1
  19. package/dist/field-521-fix.spec.js.map +1 -1
  20. package/dist/field-exclusion.js.map +1 -1
  21. package/dist/field-exclusion.spec.js.map +1 -1
  22. package/dist/field-structure.js.map +1 -1
  23. package/dist/field-structure.spec.js.map +1 -1
  24. package/dist/fields-present.js.map +1 -1
  25. package/dist/fields-present.spec.js.map +1 -1
  26. package/dist/fix-country-codes.js.map +1 -1
  27. package/dist/fix-country-codes.spec.js.map +1 -1
  28. package/dist/fixRelatorTerms.js.map +1 -1
  29. package/dist/fixRelatorTerms.spec.js.map +1 -1
  30. package/dist/fixed-fields.js.map +1 -1
  31. package/dist/fixed-fields.spec.js.map +1 -1
  32. package/dist/identical-fields.js.map +1 -1
  33. package/dist/identical-fields.spec.js.map +1 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/indicator-fixes.js.map +1 -1
  36. package/dist/indicator-fixes.spec.js.map +1 -1
  37. package/dist/isbn-issn.js.map +1 -1
  38. package/dist/isbn-issn.spec.js.map +1 -1
  39. package/dist/item-language.js.map +1 -1
  40. package/dist/item-language.spec.js.map +1 -1
  41. package/dist/mergeField500Lisapainokset.js.map +1 -1
  42. package/dist/mergeField500Lisapainokset.spec.js.map +1 -1
  43. package/dist/mergeRelatorTermFields.js.map +1 -1
  44. package/dist/mergeRelatorTermFields.spec.js.map +1 -1
  45. package/dist/multiple-subfield-0.js.map +1 -1
  46. package/dist/multiple-subfield-0.spec.js.map +1 -1
  47. package/dist/non-breaking-space.js.map +1 -1
  48. package/dist/non-breaking-space.spec.js.map +1 -1
  49. package/dist/normalize-dashes.js.map +1 -1
  50. package/dist/normalize-dashes.spec.js.map +1 -1
  51. package/dist/normalize-identifiers.js.map +1 -1
  52. package/dist/normalize-identifiers.spec.js.map +1 -1
  53. package/dist/normalize-qualifying-information.js.map +1 -1
  54. package/dist/normalize-qualifying-information.spec.js.map +1 -1
  55. package/dist/normalize-utf8-diacritics.js.map +1 -1
  56. package/dist/normalize-utf8-diacritics.spec.js.map +1 -1
  57. package/dist/normalizeFieldForComparison.js.map +1 -1
  58. package/dist/normalizeSubfieldValueForComparison.js.map +1 -1
  59. package/dist/prepublicationUtils.js.map +1 -1
  60. package/dist/punctuation/index.js.map +1 -1
  61. package/dist/punctuation/rules/aut.js.map +1 -1
  62. package/dist/punctuation/rules/bib.js.map +1 -1
  63. package/dist/punctuation/rules/index.js.map +1 -1
  64. package/dist/punctuation.spec.js.map +1 -1
  65. package/dist/punctuation2.js +131 -89
  66. package/dist/punctuation2.js.map +1 -1
  67. package/dist/punctuation2.spec.js.map +1 -1
  68. package/dist/reindexSubfield6OccurenceNumbers.js.map +1 -1
  69. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +1 -1
  70. package/dist/removeDuplicateDataFields.js.map +1 -1
  71. package/dist/removeDuplicateDataFields.spec.js.map +1 -1
  72. package/dist/removeInferiorDataFields.js.map +1 -1
  73. package/dist/removeInferiorDataFields.spec.js.map +1 -1
  74. package/dist/resolvable-ext-references-melinda.js.map +1 -1
  75. package/dist/resolvable-ext-references-melinda.spec.js.map +1 -1
  76. package/dist/resolveOrphanedSubfield6s.js.map +1 -1
  77. package/dist/resolveOrphanedSubfield6s.spec.js.map +1 -1
  78. package/dist/sanitize-vocabulary-source-codes.js.map +1 -1
  79. package/dist/sanitize-vocabulary-source-codes.spec.js.map +1 -1
  80. package/dist/sort-tags.js.map +1 -1
  81. package/dist/sort-tags.spec.js.map +1 -1
  82. package/dist/sortFields.js.map +1 -1
  83. package/dist/sortFields.spec.js.map +1 -1
  84. package/dist/sortRelatorTerms.js.map +1 -1
  85. package/dist/sortRelatorTerms.spec.js.map +1 -1
  86. package/dist/sortSubfields.js.map +1 -1
  87. package/dist/sortSubfields.spec.js.map +1 -1
  88. package/dist/stripPunctuation.js.map +1 -1
  89. package/dist/stripPunctuation.spec.js.map +1 -1
  90. package/dist/subfield-exclusion.js.map +1 -1
  91. package/dist/subfield-exclusion.spec.js.map +1 -1
  92. package/dist/subfield6Utils.js.map +1 -1
  93. package/dist/subfield8Utils.js.map +1 -1
  94. package/dist/subfieldValueNormalizations.js +28 -8
  95. package/dist/subfieldValueNormalizations.js.map +1 -1
  96. package/dist/subfieldValueNormalizations.spec.js.map +1 -1
  97. package/dist/sync-007-and-300.js.map +1 -1
  98. package/dist/sync-007-and-300.spec.js.map +1 -1
  99. package/dist/typeOfDate-008.js.map +1 -1
  100. package/dist/typeOfDate-008.spec.js.map +1 -1
  101. package/dist/unicode-decomposition.js.map +1 -1
  102. package/dist/unicode-decomposition.spec.js.map +1 -1
  103. package/dist/update-field-540.js.map +1 -1
  104. package/dist/update-field-540.spec.js.map +1 -1
  105. package/dist/urn.js.map +1 -1
  106. package/dist/urn.spec.js.map +1 -1
  107. package/dist/utils.js.map +1 -1
  108. package/package.json +6 -6
  109. package/src/punctuation2.js +103 -56
  110. package/src/subfieldValueNormalizations.js +32 -9
  111. package/test-fixtures/normalize-subfield-value/03/expectedResult.json +26 -0
  112. package/test-fixtures/normalize-subfield-value/03/metadata.json +6 -0
  113. package/test-fixtures/normalize-subfield-value/03/record.json +25 -0
  114. package/test-fixtures/normalize-subfield-value/100_and_880/expectedResult.json +22 -0
  115. package/test-fixtures/normalize-subfield-value/100_and_880/metadata.json +5 -0
  116. package/test-fixtures/normalize-subfield-value/100_and_880/record.json +20 -0
  117. package/test-fixtures/punctuation2/100_and_880/expectedResult.json +22 -0
  118. package/test-fixtures/punctuation2/100_and_880/metadata.json +6 -0
  119. package/test-fixtures/punctuation2/100_and_880/record.json +20 -0
  120. package/test-fixtures/punctuation2/240/expectedResult.json +12 -0
  121. package/test-fixtures/punctuation2/240/metadata.json +6 -0
  122. package/test-fixtures/punctuation2/240/record.json +10 -0
  123. package/test-fixtures/punctuation2/800/expectedResult.json +15 -0
  124. package/test-fixtures/punctuation2/800/metadata.json +6 -0
  125. package/test-fixtures/punctuation2/800/record.json +14 -0
  126. package/test-fixtures/strip-punctuation/100_and_880/expectedResult.json +37 -0
  127. package/test-fixtures/strip-punctuation/100_and_880/metadata.json +5 -0
  128. package/test-fixtures/strip-punctuation/100_and_880/record.json +35 -0
  129. package/test-fixtures/strip-punctuation/240/expectedResult.json +16 -0
  130. package/test-fixtures/strip-punctuation/240/metadata.json +6 -0
  131. package/test-fixtures/strip-punctuation/240/record.json +14 -0
@@ -9,6 +9,7 @@ exports.fieldGetFixedString = fieldGetFixedString;
9
9
  exports.fieldNeedsModification = fieldNeedsModification;
10
10
  exports.fieldStripPunctuation = fieldStripPunctuation;
11
11
  var _endingPunctuation = require("./ending-punctuation");
12
+ var _subfield6Utils = require("./subfield6Utils");
12
13
  var _utils = require("./utils");
13
14
  var _clone = _interopRequireDefault(require("clone"));
14
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -28,14 +29,15 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
28
29
 
29
30
  //const debug = createDebugLogger('debug/punctuation2');
30
31
 
32
+ const descriptionString = 'Remove invalid and add valid punctuation to data fields';
31
33
  function _default() {
32
34
  return {
33
- description: 'Add punctuation to data fields',
35
+ description: descriptionString,
34
36
  validate,
35
37
  fix
36
38
  };
37
39
  function fix(record) {
38
- (0, _utils.nvdebug)('Add punctuation to data fields: fixer');
40
+ (0, _utils.nvdebug)(`${descriptionString}: fixer`);
39
41
  const res = {
40
42
  message: [],
41
43
  fix: [],
@@ -45,7 +47,7 @@ function _default() {
45
47
  return res;
46
48
  }
47
49
  function validate(record) {
48
- (0, _utils.nvdebug)('Add punctuation to data fields: validate');
50
+ (0, _utils.nvdebug)(`${descriptionString}: validate`);
49
51
  const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, true));
50
52
  const values = fieldsNeedingModification.map(f => (0, _utils.fieldToString)(f));
51
53
  const newValues = fieldsNeedingModification.map(f => fieldGetFixedString(f, true));
@@ -88,9 +90,9 @@ function fieldNeedsModification(field, add = true) {
88
90
  /////////////////////////////////////////////////////////////////////////////////////
89
91
 
90
92
  //const stripCrap = / *[-;:,+]+$/u;
91
- const commaNeedsPuncAfter = /(?:[a-z0-9A-Z]|å|ä|ö|Å|Ä|Ö|\))$/u;
92
93
  const defaultNeedsPuncAfter = /(?:[a-z0-9A-Z]|å|ä|ö|Å|Ä|Ö)$/u;
93
94
  const defaultNeedsPuncAfter2 = /(?:[\]a-zA-Z0-9)]|ä|å|ö|Å|Ä|Ö)$/u;
95
+ const doesNotEndInPunc = /[^!?.:;,]$/u; // non-punc for pre-240/700/XXX $, note that '.' comes if preceded by ')'
94
96
  const blocksPuncRHS = /^(?:\()/u;
95
97
  const allowsPuncRHS = /^(?:[A-Za-z0-9]|å|ä|ö|Å|Ä|Ö)/u;
96
98
  const dotIsProbablyPunc = /(?:[a-z0-9)]|å|ä|ö|(?:[A-Za-z0-9]|Å|Ä|Ö)(?:[A-Z]|Å|Ä|Ö))\.$/u;
@@ -103,8 +105,8 @@ const removeColons = {
103
105
  'remove': / *[;:]$/u
104
106
  };
105
107
  const removeX00Comma = {
106
- 'code': 'abcqde',
107
- 'followedBy': 'abcqde#',
108
+ 'code': 'abcdenqt',
109
+ 'followedBy': 'abcdenqtv#',
108
110
  'context': /.,$/u,
109
111
  'remove': /,$/u
110
112
  };
@@ -138,6 +140,14 @@ const cleanX00eDot = {
138
140
  'context': /(?:[ai]ja|jä)[.,]$/u,
139
141
  'remove': /\.$/u
140
142
  };
143
+ const removeCommaBeforeLanguageSubfieldL = {
144
+ 'followedBy': 'l',
145
+ 'remove': /,$/u
146
+ };
147
+ const removeCommaBeforeTitleSubfieldT = {
148
+ 'followedBy': 't',
149
+ 'remove': /,$/u
150
+ };
141
151
  const X00RemoveDotAfterBracket = {
142
152
  'code': 'cq',
143
153
  'context': /\)\.$/u,
@@ -152,9 +162,17 @@ const cleanPuncBeforeLanguage = {
152
162
  };
153
163
  const addX00aComma = {
154
164
  'add': ',',
155
- 'code': 'abcqdej',
165
+ 'code': 'abcqej',
166
+ 'followedBy': 'cdeg',
167
+ 'context': doesNotEndInPunc,
168
+ 'contextRHS': allowsPuncRHS
169
+ };
170
+ const addX00dComma = {
171
+ 'name': 'X00$d ending in "-" does not get comma',
172
+ 'add': ',',
173
+ 'code': 'd',
156
174
  'followedBy': 'cdeg',
157
- 'context': commaNeedsPuncAfter,
175
+ 'context': /[^-,.!]$/u,
158
176
  'contextRHS': allowsPuncRHS
159
177
  };
160
178
  const addX00aComma2 = {
@@ -164,10 +182,10 @@ const addX00aComma2 = {
164
182
  'context': /(?:[A-Z]|Å|Ä|Ö)\.$/u,
165
183
  'contextRHS': allowsPuncRHS
166
184
  };
167
- const addX00aDot = {
185
+ const addX00Dot = {
168
186
  'add': '.',
169
- 'code': 'abcdet',
170
- 'followedBy': '#tu',
187
+ 'code': 'abcdetv',
188
+ 'followedBy': '#fklptu',
171
189
  'context': defaultNeedsPuncAfter
172
190
  };
173
191
 
@@ -192,19 +210,19 @@ const addX10Dot = {
192
210
  'followedBy': 'tu#',
193
211
  'context': defaultNeedsPuncAfter
194
212
  };
195
- const addLanguageComma = {
196
- 'name': 'Add comma before 810$l',
197
- 'add': ',',
198
- 'code': 'tv',
199
- 'followedBy': 'l',
200
- 'context': defaultNeedsPuncAfter2
201
- };
202
213
  const addColonToRelationshipInformation = {
203
214
  'name': 'Add \':\' to 7X0 $i relationship info',
204
215
  'add': ':',
205
216
  'code': 'i',
206
217
  'context': defaultNeedsPuncAfter2
207
218
  };
219
+ const addDotBeforeLanguageSubfieldL = {
220
+ 'name': 'Add dot before $l',
221
+ 'add': '.',
222
+ 'code': 'abepst',
223
+ 'followedBy': 'l',
224
+ 'context': doesNotEndInPunc
225
+ };
208
226
 
209
227
  // 490:
210
228
  const addSemicolonBeforeVolumeDesignation = {
@@ -222,8 +240,11 @@ const REMOVE_AND_ADD = 3;
222
240
  // Crappy punctuation consists of various crap that is somewhat common.
223
241
  // We strip crap for merge decisions. We are not trying to actively remove crap here.
224
242
 
225
- const removeX00Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, cleanX00dCommaOrDot, cleanRHS, X00RemoveDotAfterBracket, removeColons, cleanPuncBeforeLanguage];
226
- const removeX10Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, removeColons, cleanPuncBeforeLanguage];
243
+ const removeCrapFromAllEntryFields = [removeCommaBeforeLanguageSubfieldL, removeCommaBeforeTitleSubfieldT];
244
+ const removeX00Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, cleanX00dCommaOrDot, cleanRHS, X00RemoveDotAfterBracket, removeColons, cleanPuncBeforeLanguage, ...removeCrapFromAllEntryFields];
245
+ const removeX10Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, removeColons, cleanPuncBeforeLanguage, ...removeCrapFromAllEntryFields];
246
+ const removeX11Whatever = removeCrapFromAllEntryFields;
247
+ const removeX30Whatever = removeCrapFromAllEntryFields;
227
248
  const remove490And830Whatever = [{
228
249
  'code': 'axyzv',
229
250
  'followedBy': 'axyzv',
@@ -273,11 +294,14 @@ const crappy24X = [{
273
294
  'followedBy': 'pc',
274
295
  'remove': /\.$/u,
275
296
  'context': dotIsProbablyPunc
276
- } // MELINDA-8817
277
- ];
297
+ },
298
+ // MELINDA-8817
299
+ removeCommaBeforeLanguageSubfieldL];
278
300
  const cleanCrappyPunctuationRules = {
279
301
  '100': removeX00Whatever,
280
302
  '110': removeX10Whatever,
303
+ '111': removeX11Whatever,
304
+ '130': removeX30Whatever,
281
305
  '240': crappy24X,
282
306
  '245': crappy24X,
283
307
  '246': crappy24X,
@@ -308,8 +332,12 @@ const cleanCrappyPunctuationRules = {
308
332
  '490': remove490And830Whatever,
309
333
  '600': removeX00Whatever,
310
334
  '610': removeX10Whatever,
335
+ '611': removeX11Whatever,
336
+ '630': removeX30Whatever,
311
337
  '700': removeX00Whatever,
312
338
  '710': removeX10Whatever,
339
+ '711': removeX11Whatever,
340
+ '730': removeX30Whatever,
313
341
  '773': linkingEntryWhatever,
314
342
  '774': linkingEntryWhatever,
315
343
  '776': linkingEntryWhatever,
@@ -342,14 +370,14 @@ const cleanLegalX00Dot = {
342
370
  'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u,
343
371
  'remove': /\.$/u
344
372
  };
345
- const cleanLanguageComma = {
346
- 'name': 'language comma',
347
- 'code': 'tv',
373
+ const cleanDotBeforeLanguageSubfieldL = {
374
+ 'name': 'pre-language-$l dot',
348
375
  'followedBy': 'l',
349
- 'context': /.,$/u,
350
- 'remove': /,$/u
376
+ 'context': /.\.$/u,
377
+ 'remove': /\.$/u
351
378
  };
352
- const legalX00punc = [cleanLegalX00Comma, cleanLegalX00iColon, cleanLegalX00bDot, cleanLegalX00Dot, cleanLanguageComma];
379
+ const legalEntryField = [cleanDotBeforeLanguageSubfieldL];
380
+ const legalX00punc = [cleanLegalX00Comma, cleanLegalX00iColon, cleanLegalX00bDot, cleanLegalX00Dot, ...legalEntryField];
353
381
  const cleanLegalX10Comma = {
354
382
  'name': 'X10comma',
355
383
  'code': 'abe',
@@ -364,7 +392,7 @@ const cleanLegalX10Dot = {
364
392
  'context': /.\.$/u,
365
393
  'remove': /\.$/u
366
394
  };
367
- const legalX10punc = [cleanLegalX10Comma, cleanLegalX10Dot, cleanX00eDot, cleanLanguageComma];
395
+ const legalX10punc = [cleanLegalX10Comma, cleanLegalX10Dot, cleanX00eDot, ...legalEntryField];
368
396
  const cleanLegalSeriesTitle = [
369
397
  // 490 and 830
370
398
  {
@@ -421,16 +449,14 @@ const clean24X = [{
421
449
  'code': 'n',
422
450
  'followedBy': 'p',
423
451
  'remove': /,$/u
424
- }];
452
+ }, cleanDotBeforeLanguageSubfieldL];
425
453
  const cleanValidPunctuationRules = {
426
454
  '100': legalX00punc,
427
455
  '110': legalX10punc,
428
- '600': legalX00punc,
429
- '610': legalX10punc,
430
- '700': legalX00punc,
431
- '710': legalX10punc,
432
- '800': legalX00punc,
433
- '810': legalX10punc,
456
+ '111': legalEntryField,
457
+ '130': legalEntryField,
458
+ '240': clean24X,
459
+ '243': clean24X,
434
460
  '245': clean24X,
435
461
  '246': clean24X,
436
462
  '260': [{
@@ -493,6 +519,10 @@ const cleanValidPunctuationRules = {
493
519
  'followedBy': 'c',
494
520
  'remove': /:$/u
495
521
  }],
522
+ '600': legalX00punc,
523
+ '610': legalX10punc,
524
+ '611': legalEntryField,
525
+ '630': legalEntryField,
496
526
  // Experimental, MET366-ish (end punc in internationally valid, but we don't use it here in Finland):
497
527
  '648': [{
498
528
  'code': 'a',
@@ -500,68 +530,63 @@ const cleanValidPunctuationRules = {
500
530
  'ind2': ['4'],
501
531
  'remove': /\.$/u
502
532
  }],
503
- '830': cleanLegalSeriesTitle,
533
+ '700': legalX00punc,
534
+ '710': legalX10punc,
535
+ '711': legalEntryField,
536
+ '730': legalEntryField,
537
+ '800': legalX00punc,
538
+ '810': legalX10punc,
539
+ '811': legalEntryField,
540
+ '830': [...legalEntryField, ...cleanLegalSeriesTitle],
504
541
  '946': clean24X
505
542
  };
506
543
 
507
- // addColonToRelationshipInformation only applies to 700/710 but as others don't have $i, it's fine
508
- const addX00 = [addX00aComma, addX00aComma2, addX00aDot, addLanguageComma, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation];
509
- const addX10 = [addX10bDot, addX10eComma, addX10Dot, addLanguageComma, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation];
510
- const add245 = [
511
- // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
512
- {
544
+ // Overgeneralizes a bit: eg. addColonToRelationshipInformation only applies to 700/710 but as others don't have $i, it's fine.
545
+ const addToAllEntryFields = [addDotBeforeLanguageSubfieldL, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation];
546
+ const addX00 = [addX00aComma, addX00aComma2, addX00Dot, addX00dComma, ...addToAllEntryFields];
547
+ const addX10 = [addX10bDot, addX10eComma, addX10Dot, ...addToAllEntryFields];
548
+ const addX11 = [...addToAllEntryFields];
549
+ const addX30 = [...addToAllEntryFields];
550
+ const add24X = [{
551
+ 'code': 'i',
552
+ 'followedBy': 'a',
553
+ 'add': ':',
554
+ 'context': defaultNeedsPuncAfter
555
+ }, {
513
556
  'code': 'a',
514
557
  'followedBy': 'b',
515
558
  'add': ' :',
516
559
  'context': defaultNeedsPuncAfter
517
- }, {
518
- 'code': 'ab',
519
- 'followedBy': 'n',
520
- 'add': '.',
521
- 'context': defaultNeedsPuncAfter
522
560
  }, {
523
561
  'code': 'abk',
524
562
  'followedBy': 'f',
525
563
  'add': ',',
526
564
  'context': defaultNeedsPuncAfter
527
- }, {
528
- 'code': 'n',
529
- 'followedBy': 'p',
530
- 'add': ',',
531
- 'context': defaultNeedsPuncAfter
532
565
  }, {
533
566
  'code': 'abfnp',
534
567
  'followedBy': 'c',
535
568
  'add': ' /',
536
569
  'context': defaultNeedsPuncAfter
537
- }, {
538
- 'code': 'abc',
539
- 'followedBy': '#',
570
+ }, addDotBeforeLanguageSubfieldL];
571
+ const add245 = [...add24X,
572
+ // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
573
+ {
574
+ 'code': 'ab',
575
+ 'followedBy': 'n',
540
576
  'add': '.',
541
577
  'context': defaultNeedsPuncAfter
542
- } // Stepping on "punctuation validaror's" toes
543
- ];
544
- const add246 = [{
545
- 'code': 'i',
546
- 'followedBy': 'a',
547
- 'add': ':',
548
- 'context': defaultNeedsPuncAfter
549
- }, {
550
- 'code': 'a',
551
- 'followedBy': 'b',
552
- 'add': ' :',
553
- 'context': defaultNeedsPuncAfter
554
578
  }, {
555
- 'code': 'abk',
556
- 'followedBy': 'f',
579
+ 'code': 'n',
580
+ 'followedBy': 'p',
557
581
  'add': ',',
558
582
  'context': defaultNeedsPuncAfter
559
583
  }, {
560
- 'code': 'abfnp',
561
- 'followedBy': 'c',
562
- 'add': ' /',
584
+ 'code': 'abc',
585
+ 'followedBy': '#',
586
+ 'add': '.',
563
587
  'context': defaultNeedsPuncAfter
564
- }];
588
+ } // Stepping on "punctuation validator's" toes
589
+ ];
565
590
  const addSeriesTitle = [
566
591
  // 490 and 830
567
592
  {
@@ -579,9 +604,12 @@ const addSeriesTitle = [
579
604
  const addPairedPunctuationRules = {
580
605
  '100': addX00,
581
606
  '110': addX10,
582
- '240': add246,
607
+ '111': addX11,
608
+ '130': addX30,
609
+ '240': add24X,
610
+ '243': add24X,
583
611
  '245': add245,
584
- '246': add246,
612
+ '246': add24X,
585
613
  '260': [{
586
614
  'code': 'a',
587
615
  'followedBy': 'b',
@@ -658,11 +686,16 @@ const addPairedPunctuationRules = {
658
686
  }],
659
687
  '600': addX00,
660
688
  '610': addX10,
689
+ '611': addX11,
690
+ '630': addX30,
661
691
  '700': addX00,
662
692
  '710': addX10,
693
+ '711': addX11,
694
+ '730': addX30,
663
695
  '800': addX00,
664
696
  '810': addX10,
665
- '830': addSeriesTitle,
697
+ '811': addX11,
698
+ '830': [...addX30, ...addSeriesTitle],
666
699
  '946': [{
667
700
  'code': 'i',
668
701
  'followedBy': 'a',
@@ -690,6 +723,10 @@ function debugRule(rule) {
690
723
  */
691
724
 
692
725
  function ruleAppliesToSubfieldCode(targetSubfieldCodes, currSubfieldCode) {
726
+ if (!targetSubfieldCodes) {
727
+ // We are not interested in what subfield precedes 240$l, ',' is removed anyway
728
+ return true;
729
+ }
693
730
  const negation = targetSubfieldCodes.includes('!');
694
731
  if (negation) {
695
732
  return !targetSubfieldCodes.includes(currSubfieldCode);
@@ -769,36 +806,41 @@ function checkRule(rule, field, subfield1, subfield2) {
769
806
  return true;
770
807
  }
771
808
  function applyPunctuationRules(field, subfield1, subfield2, ruleArray = null, operation = NONE) {
772
- if (!(`${field.tag}` in ruleArray) || ruleArray === null || operation === NONE) {
773
- /*
774
- if (!['020', '650'].includes(tag) || !isControlSubfieldCode(subfield1.code)) { // eslint-disable-line functional/no-conditional-statements
775
- nvdebug(`No punctuation rules found for ${tag} (looking for: ‡${subfield1.code})`, debug);
776
- }
777
- */
809
+ if (operation === NONE || ruleArray === null) {
810
+ // !fieldIsApplicable(field, ruleArray)) {
811
+ return;
812
+ }
813
+ const tag2 = field.tag === '880' ? (0, _subfield6Utils.fieldGetUnambiguousTag)(field) : field.tag;
814
+ if (!tag2) {
815
+ return;
816
+ }
817
+ if (!(`${tag2}` in ruleArray)) {
778
818
  return;
779
819
  }
780
- (0, _utils.nvdebug)(`PUNCTUATE ${field.tag} '${(0, _utils.subfieldToString)(subfield1)}' XXX '${subfield2 ? (0, _utils.subfieldToString)(subfield2) : '#'} }`);
781
820
 
782
- //nvdebug(`OP=${operation} ${tag}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`, debug);
783
- const candRules = ruleArray[field.tag];
821
+ //nvdebug(`PUNCTUATE ${field.tag}/${tag2} '${subfieldToString(subfield1)}' XXX '${subfield2 ? subfieldToString(subfield2) : '#'} }`);
822
+
823
+ //nvdebug(`OP=${operation} ${tag2}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`);
824
+ const candRules = ruleArray[tag2];
784
825
  candRules.forEach(rule => {
785
826
  //debugRule(rule);
786
-
827
+ //nvdebug(' WP1');
787
828
  if (!checkRule(rule, field, subfield1, subfield2)) {
788
829
  return;
789
830
  }
831
+ //nvdebug(' WP2');
790
832
 
791
833
  //const originalValue = subfield1.value;
792
834
  if (rule.remove && [REMOVE, REMOVE_AND_ADD].includes(operation) && subfield1.value.match(rule.remove)) {
793
835
  // eslint-disable-line functional/no-conditional-statements
794
836
  //nvdebug(` PUNC REMOVAL TO BE PERFORMED FOR $${subfield1.code} '${subfield1.value}'`, debug);
795
837
  subfield1.value = subfield1.value.replace(rule.remove, ''); // eslint-disable-line functional/immutable-data
796
- //nvdebug(` PUNC REMOVAL PERFORMED FOR '${subfield1.value}'`, debug);
838
+ //nvdebug(` PUNC REMOVAL PERFORMED FOR '${subfield1.value}'`);
797
839
  }
798
840
  if (rule.add && [ADD, REMOVE_AND_ADD].includes(operation)) {
799
841
  // eslint-disable-line functional/no-conditional-statements
800
842
  subfield1.value += rule.add; // eslint-disable-line functional/immutable-data
801
- //nvdebug(` ADDED '${rule.add}' TO FORM '${subfield1.value}'`, debug);
843
+ //nvdebug(` ADDED '${rule.add}' TO FORM '${subfield1.value}'`);
802
844
  }
803
845
 
804
846
  /*