@natlibfi/marc-record-validators-melinda 11.6.7 → 12.0.0-alpha.12

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 (563) hide show
  1. package/.github/workflows/{melinda-node-tests.yml → melinda-node-tests-and-publish.yml} +37 -12
  2. package/dist/access-rights.js +63 -91
  3. package/dist/access-rights.js.map +7 -1
  4. package/dist/access-rights.test.js +137 -0
  5. package/dist/access-rights.test.js.map +7 -0
  6. package/dist/addMissingField041.js +21 -53
  7. package/dist/addMissingField041.js.map +7 -1
  8. package/dist/addMissingField041.test.js +39 -0
  9. package/dist/addMissingField041.test.js.map +7 -0
  10. package/dist/addMissingField336.js +99 -191
  11. package/dist/addMissingField336.js.map +7 -1
  12. package/dist/addMissingField336.test.js +39 -0
  13. package/dist/addMissingField336.test.js.map +7 -0
  14. package/dist/addMissingField337.js +63 -132
  15. package/dist/addMissingField337.js.map +7 -1
  16. package/dist/addMissingField337.test.js +39 -0
  17. package/dist/addMissingField337.test.js.map +7 -0
  18. package/dist/addMissingField338.js +147 -253
  19. package/dist/addMissingField338.js.map +7 -1
  20. package/dist/addMissingField338.test.js +39 -0
  21. package/dist/addMissingField338.test.js.map +7 -0
  22. package/dist/cyrillux-usemarcon-replacement.js +119 -272
  23. package/dist/cyrillux-usemarcon-replacement.js.map +7 -1
  24. package/dist/cyrillux-usemarcon-replacement.test.js +43 -0
  25. package/dist/cyrillux-usemarcon-replacement.test.js.map +7 -0
  26. package/dist/cyrillux.js +119 -223
  27. package/dist/cyrillux.js.map +7 -1
  28. package/dist/cyrillux.test.js +39 -0
  29. package/dist/cyrillux.test.js.map +7 -0
  30. package/dist/disambiguateSeriesStatements.js +40 -81
  31. package/dist/disambiguateSeriesStatements.js.map +7 -1
  32. package/dist/disambiguateSeriesStatements.test.js +44 -0
  33. package/dist/disambiguateSeriesStatements.test.js.map +7 -0
  34. package/dist/double-commas.js +7 -14
  35. package/dist/double-commas.js.map +7 -1
  36. package/dist/double-commas.test.js +48 -0
  37. package/dist/double-commas.test.js.map +7 -0
  38. package/dist/duplicates-ind1.js +10 -31
  39. package/dist/duplicates-ind1.js.map +7 -1
  40. package/dist/duplicates-ind1.test.js +40 -0
  41. package/dist/duplicates-ind1.test.js.map +7 -0
  42. package/dist/empty-fields.js +10 -22
  43. package/dist/empty-fields.js.map +7 -1
  44. package/dist/empty-fields.test.js +129 -0
  45. package/dist/empty-fields.test.js.map +7 -0
  46. package/dist/ending-punctuation-conf.js +873 -769
  47. package/dist/ending-punctuation-conf.js.map +7 -1
  48. package/dist/ending-punctuation.js +156 -169
  49. package/dist/ending-punctuation.js.map +7 -1
  50. package/dist/ending-punctuation.test.js +2385 -0
  51. package/dist/ending-punctuation.test.js.map +7 -0
  52. package/dist/ending-whitespace.js +10 -35
  53. package/dist/ending-whitespace.js.map +7 -1
  54. package/dist/ending-whitespace.test.js +38 -0
  55. package/dist/ending-whitespace.test.js.map +7 -0
  56. package/dist/field-008-18-34-character-groups.js +40 -125
  57. package/dist/field-008-18-34-character-groups.js.map +7 -1
  58. package/dist/field-008-18-34-character-groups.test.js +45 -0
  59. package/dist/field-008-18-34-character-groups.test.js.map +7 -0
  60. package/dist/field-505-separators.js +19 -39
  61. package/dist/field-505-separators.js.map +7 -1
  62. package/dist/field-505-separators.test.js +45 -0
  63. package/dist/field-505-separators.test.js.map +7 -0
  64. package/dist/field-521-fix.js +19 -47
  65. package/dist/field-521-fix.js.map +7 -1
  66. package/dist/field-521-fix.test.js +44 -0
  67. package/dist/field-521-fix.test.js.map +7 -0
  68. package/dist/field-exclusion.js +37 -91
  69. package/dist/field-exclusion.js.map +7 -1
  70. package/dist/field-exclusion.test.js +821 -0
  71. package/dist/field-exclusion.test.js.map +7 -0
  72. package/dist/field-structure.js +52 -104
  73. package/dist/field-structure.js.map +7 -1
  74. package/dist/field-structure.test.js +587 -0
  75. package/dist/field-structure.test.js.map +7 -0
  76. package/dist/field33XUtils.js +119 -503
  77. package/dist/field33XUtils.js.map +7 -1
  78. package/dist/fields-present.js +11 -23
  79. package/dist/fields-present.js.map +7 -1
  80. package/dist/fields-present.test.js +95 -0
  81. package/dist/fields-present.test.js.map +7 -0
  82. package/dist/fix-33X.js +393 -431
  83. package/dist/fix-33X.js.map +7 -1
  84. package/dist/fix-33X.test.js +39 -0
  85. package/dist/fix-33X.test.js.map +7 -0
  86. package/dist/fix-country-codes.js +20 -50
  87. package/dist/fix-country-codes.js.map +7 -1
  88. package/dist/fix-country-codes.test.js +44 -0
  89. package/dist/fix-country-codes.test.js.map +7 -0
  90. package/dist/fix-language-codes.js +23 -53
  91. package/dist/fix-language-codes.js.map +7 -1
  92. package/dist/fix-language-codes.test.js +38 -0
  93. package/dist/fix-language-codes.test.js.map +7 -0
  94. package/dist/fixRelatorTerms.js +82 -209
  95. package/dist/fixRelatorTerms.js.map +7 -1
  96. package/dist/fixRelatorTerms.test.js +44 -0
  97. package/dist/fixRelatorTerms.test.js.map +7 -0
  98. package/dist/fixed-fields.js +21 -30
  99. package/dist/fixed-fields.js.map +7 -1
  100. package/dist/fixed-fields.test.js +87 -0
  101. package/dist/fixed-fields.test.js.map +7 -0
  102. package/dist/identical-fields.js +8 -24
  103. package/dist/identical-fields.js.map +7 -1
  104. package/dist/identical-fields.test.js +119 -0
  105. package/dist/identical-fields.test.js.map +7 -0
  106. package/dist/index.js +182 -413
  107. package/dist/index.js.map +7 -1
  108. package/dist/indicator-fixes.js +66 -94
  109. package/dist/indicator-fixes.js.map +7 -1
  110. package/dist/indicator-fixes.test.js +42 -0
  111. package/dist/indicator-fixes.test.js.map +7 -0
  112. package/dist/isbn-issn.js +71 -128
  113. package/dist/isbn-issn.js.map +7 -1
  114. package/dist/isbn-issn.test.js +398 -0
  115. package/dist/isbn-issn.test.js.map +7 -0
  116. package/dist/item-language.js +32 -65
  117. package/dist/item-language.js.map +7 -1
  118. package/dist/item-language.test.js +322 -0
  119. package/dist/item-language.test.js.map +7 -0
  120. package/dist/melindaCustomMergeFields.js +5182 -11233
  121. package/dist/melindaCustomMergeFields.js.map +7 -1
  122. package/dist/merge-fields/controlSubfields.js +75 -142
  123. package/dist/merge-fields/controlSubfields.js.map +7 -1
  124. package/dist/merge-fields/counterpartField.js +187 -379
  125. package/dist/merge-fields/counterpartField.js.map +7 -1
  126. package/dist/merge-fields/dataProvenance.js +29 -0
  127. package/dist/merge-fields/dataProvenance.js.map +7 -0
  128. package/dist/merge-fields/index.js +25 -50
  129. package/dist/merge-fields/index.js.map +7 -1
  130. package/dist/merge-fields/mergableIndicator.js +18 -51
  131. package/dist/merge-fields/mergableIndicator.js.map +7 -1
  132. package/dist/merge-fields/mergableTag.js +78 -30
  133. package/dist/merge-fields/mergableTag.js.map +7 -1
  134. package/dist/merge-fields/mergeConfig.js +66 -171
  135. package/dist/merge-fields/mergeConfig.js.map +7 -1
  136. package/dist/merge-fields/mergeConstraints.js +323 -1214
  137. package/dist/merge-fields/mergeConstraints.js.map +7 -1
  138. package/dist/merge-fields/mergeField.js +47 -111
  139. package/dist/merge-fields/mergeField.js.map +7 -1
  140. package/dist/merge-fields/mergeIndicator.js +64 -118
  141. package/dist/merge-fields/mergeIndicator.js.map +7 -1
  142. package/dist/merge-fields/mergeOrAddPostprocess.js +14 -38
  143. package/dist/merge-fields/mergeOrAddPostprocess.js.map +7 -1
  144. package/dist/merge-fields/mergeOrAddSubfield.js +62 -104
  145. package/dist/merge-fields/mergeOrAddSubfield.js.map +7 -1
  146. package/dist/merge-fields/mergeSubfield.js +47 -95
  147. package/dist/merge-fields/mergeSubfield.js.map +7 -1
  148. package/dist/merge-fields/removeDuplicateSubfields.js +18 -31
  149. package/dist/merge-fields/removeDuplicateSubfields.js.map +7 -1
  150. package/dist/merge-fields/worldKnowledge.js +15 -40
  151. package/dist/merge-fields/worldKnowledge.js.map +7 -1
  152. package/dist/merge-fields.test.js +46 -0
  153. package/dist/merge-fields.test.js.map +7 -0
  154. package/dist/mergeField500Lisapainokset.js +27 -56
  155. package/dist/mergeField500Lisapainokset.js.map +7 -1
  156. package/dist/mergeField500Lisapainokset.test.js +44 -0
  157. package/dist/mergeField500Lisapainokset.test.js.map +7 -0
  158. package/dist/mergeRelatorTermFields.js +33 -69
  159. package/dist/mergeRelatorTermFields.js.map +7 -1
  160. package/dist/mergeRelatorTermFields.test.js +44 -0
  161. package/dist/mergeRelatorTermFields.test.js.map +7 -0
  162. package/dist/modernize-502.js +23 -55
  163. package/dist/modernize-502.js.map +7 -1
  164. package/dist/modernize-502.test.js +38 -0
  165. package/dist/modernize-502.test.js.map +7 -0
  166. package/dist/multiple-subfield-0.js +23 -48
  167. package/dist/multiple-subfield-0.js.map +7 -1
  168. package/dist/multiple-subfield-0.test.js +44 -0
  169. package/dist/multiple-subfield-0.test.js.map +7 -0
  170. package/dist/non-breaking-space.js +11 -32
  171. package/dist/non-breaking-space.js.map +7 -1
  172. package/dist/non-breaking-space.test.js +38 -0
  173. package/dist/non-breaking-space.test.js.map +7 -0
  174. package/dist/normalize-dashes.js +18 -37
  175. package/dist/normalize-dashes.js.map +7 -1
  176. package/dist/normalize-dashes.test.js +44 -0
  177. package/dist/normalize-dashes.test.js.map +7 -0
  178. package/dist/normalize-identifiers.js +54 -140
  179. package/dist/normalize-identifiers.js.map +7 -1
  180. package/dist/normalize-identifiers.test.js +44 -0
  181. package/dist/normalize-identifiers.test.js.map +7 -0
  182. package/dist/normalize-qualifying-information.js +23 -48
  183. package/dist/normalize-qualifying-information.js.map +7 -1
  184. package/dist/normalize-qualifying-information.test.js +44 -0
  185. package/dist/normalize-qualifying-information.test.js.map +7 -0
  186. package/dist/normalize-utf8-diacritics.js +19 -105
  187. package/dist/normalize-utf8-diacritics.js.map +7 -1
  188. package/dist/normalize-utf8-diacritics.test.js +44 -0
  189. package/dist/normalize-utf8-diacritics.test.js.map +7 -0
  190. package/dist/normalizeFieldForComparison.js +91 -158
  191. package/dist/normalizeFieldForComparison.js.map +7 -1
  192. package/dist/normalizeSubfieldValueForComparison.js +37 -77
  193. package/dist/normalizeSubfieldValueForComparison.js.map +7 -1
  194. package/dist/prepublicationUtils.js +58 -111
  195. package/dist/prepublicationUtils.js.map +7 -1
  196. package/dist/punctuation/index.js +56 -72
  197. package/dist/punctuation/index.js.map +7 -1
  198. package/dist/punctuation/rules/aut.js +372 -331
  199. package/dist/punctuation/rules/aut.js.map +7 -1
  200. package/dist/punctuation/rules/bib.js +420 -373
  201. package/dist/punctuation/rules/bib.js.map +7 -1
  202. package/dist/punctuation/rules/index.js +7 -21
  203. package/dist/punctuation/rules/index.js.map +7 -1
  204. package/dist/punctuation.test.js +44 -0
  205. package/dist/punctuation.test.js.map +7 -0
  206. package/dist/punctuation2.js +259 -802
  207. package/dist/punctuation2.js.map +7 -1
  208. package/dist/punctuation2.test.js +44 -0
  209. package/dist/punctuation2.test.js.map +7 -0
  210. package/dist/reindexSubfield6OccurenceNumbers.js +61 -96
  211. package/dist/reindexSubfield6OccurenceNumbers.js.map +7 -1
  212. package/dist/reindexSubfield6OccurenceNumbers.test.js +44 -0
  213. package/dist/reindexSubfield6OccurenceNumbers.test.js.map +7 -0
  214. package/dist/removeDuplicateDataFields.js +102 -202
  215. package/dist/removeDuplicateDataFields.js.map +7 -1
  216. package/dist/removeDuplicateDataFields.test.js +44 -0
  217. package/dist/removeDuplicateDataFields.test.js.map +7 -0
  218. package/dist/removeInferiorDataFields.js +104 -227
  219. package/dist/removeInferiorDataFields.js.map +7 -1
  220. package/dist/removeInferiorDataFields.test.js +44 -0
  221. package/dist/removeInferiorDataFields.test.js.map +7 -0
  222. package/dist/resolvable-ext-references-melinda.js +25 -60
  223. package/dist/resolvable-ext-references-melinda.js.map +7 -1
  224. package/dist/resolvable-ext-references-melinda.test.js +160 -0
  225. package/dist/resolvable-ext-references-melinda.test.js.map +7 -0
  226. package/dist/resolveOrphanedSubfield6s.js +32 -63
  227. package/dist/resolveOrphanedSubfield6s.js.map +7 -1
  228. package/dist/resolveOrphanedSubfield6s.test.js +44 -0
  229. package/dist/resolveOrphanedSubfield6s.test.js.map +7 -0
  230. package/dist/sanitize-vocabulary-source-codes.js +27 -55
  231. package/dist/sanitize-vocabulary-source-codes.js.map +7 -1
  232. package/dist/sanitize-vocabulary-source-codes.test.js +45 -0
  233. package/dist/sanitize-vocabulary-source-codes.test.js.map +7 -0
  234. package/dist/sort-tags.js +13 -25
  235. package/dist/sort-tags.js.map +7 -1
  236. package/dist/sort-tags.test.js +261 -0
  237. package/dist/sort-tags.test.js.map +7 -0
  238. package/dist/sortFields.js +152 -222
  239. package/dist/sortFields.js.map +7 -1
  240. package/dist/sortFields.test.js +44 -0
  241. package/dist/sortFields.test.js.map +7 -0
  242. package/dist/sortRelatorTerms.js +30 -68
  243. package/dist/sortRelatorTerms.js.map +7 -1
  244. package/dist/sortRelatorTerms.test.js +44 -0
  245. package/dist/sortRelatorTerms.test.js.map +7 -0
  246. package/dist/sortSubfields.js +102 -255
  247. package/dist/sortSubfields.js.map +7 -1
  248. package/dist/sortSubfields.test.js +44 -0
  249. package/dist/sortSubfields.test.js.map +7 -0
  250. package/dist/stripPunctuation.js +13 -36
  251. package/dist/stripPunctuation.js.map +7 -1
  252. package/dist/stripPunctuation.test.js +44 -0
  253. package/dist/stripPunctuation.test.js.map +7 -0
  254. package/dist/subfield-exclusion.js +28 -75
  255. package/dist/subfield-exclusion.js.map +7 -1
  256. package/dist/subfield-exclusion.test.js +471 -0
  257. package/dist/subfield-exclusion.test.js.map +7 -0
  258. package/dist/subfield6Utils.js +107 -269
  259. package/dist/subfield6Utils.js.map +7 -1
  260. package/dist/subfield8Utils.js +26 -50
  261. package/dist/subfield8Utils.js.map +7 -1
  262. package/dist/subfieldValueNormalizations.js +40 -74
  263. package/dist/subfieldValueNormalizations.js.map +7 -1
  264. package/dist/subfieldValueNormalizations.test.js +45 -0
  265. package/dist/subfieldValueNormalizations.test.js.map +7 -0
  266. package/dist/sync-007-and-300.js +22 -53
  267. package/dist/sync-007-and-300.js.map +7 -1
  268. package/dist/sync-007-and-300.test.js +44 -0
  269. package/dist/sync-007-and-300.test.js.map +7 -0
  270. package/dist/translate-terms.js +67 -155
  271. package/dist/translate-terms.js.map +7 -1
  272. package/dist/translate-terms.test.js +54 -0
  273. package/dist/translate-terms.test.js.map +7 -0
  274. package/dist/typeOfDate-008.js +10 -25
  275. package/dist/typeOfDate-008.js.map +7 -1
  276. package/dist/typeOfDate-008.test.js +40 -0
  277. package/dist/typeOfDate-008.test.js.map +7 -0
  278. package/dist/unicode-decomposition.js +94 -107
  279. package/dist/unicode-decomposition.js.map +7 -1
  280. package/dist/unicode-decomposition.test.js +94 -0
  281. package/dist/unicode-decomposition.test.js.map +7 -0
  282. package/dist/update-field-540.js +30 -75
  283. package/dist/update-field-540.js.map +7 -1
  284. package/dist/update-field-540.test.js +44 -0
  285. package/dist/update-field-540.test.js.map +7 -0
  286. package/dist/urn.js +55 -128
  287. package/dist/urn.js.map +7 -1
  288. package/dist/urn.test.js +44 -0
  289. package/dist/urn.test.js.map +7 -0
  290. package/dist/utils.js +78 -126
  291. package/dist/utils.js.map +7 -1
  292. package/eslint.config.mjs +1 -2
  293. package/package.json +28 -101
  294. package/src/access-rights.js +1 -1
  295. package/src/{access-rights.spec.js → access-rights.test.js} +9 -10
  296. package/src/addMissingField041.js +1 -1
  297. package/src/{addMissingField336.spec.js → addMissingField041.test.js} +13 -14
  298. package/src/addMissingField336.js +3 -3
  299. package/src/{addMissingField041.spec.js → addMissingField336.test.js} +13 -14
  300. package/src/addMissingField337.js +2 -2
  301. package/src/{addMissingField337.spec.js → addMissingField337.test.js} +13 -14
  302. package/src/addMissingField338.js +2 -2
  303. package/src/{addMissingField338.spec.js → addMissingField338.test.js} +13 -14
  304. package/src/cyrillux-usemarcon-replacement.js +18 -18
  305. package/src/{cyrillux-usemarcon-replacement.spec.js → cyrillux-usemarcon-replacement.test.js} +17 -14
  306. package/src/cyrillux.js +19 -12
  307. package/src/{cyrillux.spec.js → cyrillux.test.js} +13 -14
  308. package/src/disambiguateSeriesStatements.js +2 -2
  309. package/src/{disambiguateSeriesStatements.spec.js → disambiguateSeriesStatements.test.js} +12 -13
  310. package/src/double-commas.js +1 -1
  311. package/src/{double-commas.spec.js → double-commas.test.js} +9 -11
  312. package/src/duplicates-ind1.js +1 -1
  313. package/src/{duplicates-ind1.spec.js → duplicates-ind1.test.js} +12 -13
  314. package/src/{empty-fields.spec.js → empty-fields.test.js} +11 -13
  315. package/src/ending-punctuation-conf.js +6 -5
  316. package/src/ending-punctuation.js +115 -24
  317. package/src/{ending-punctuation.spec.js → ending-punctuation.test.js} +357 -275
  318. package/src/{ending-whitespace.spec.js → ending-whitespace.test.js} +12 -13
  319. package/src/field-008-18-34-character-groups.js +2 -2
  320. package/src/{field-008-18-34-character-groups.spec.js → field-008-18-34-character-groups.test.js} +13 -13
  321. package/src/field-505-separators.js +3 -3
  322. package/src/{field-505-separators.spec.js → field-505-separators.test.js} +16 -14
  323. package/src/field-521-fix.js +2 -2
  324. package/src/{field-521-fix.spec.js → field-521-fix.test.js} +12 -13
  325. package/src/field-exclusion.js +1 -1
  326. package/src/{field-exclusion.spec.js → field-exclusion.test.js} +60 -57
  327. package/src/{field-structure.spec.js → field-structure.test.js} +29 -29
  328. package/src/{fields-present.spec.js → fields-present.test.js} +12 -15
  329. package/src/fix-33X.js +4 -4
  330. package/src/{fix-33X.spec.js → fix-33X.test.js} +13 -14
  331. package/src/fix-country-codes.js +1 -1
  332. package/src/{fix-country-codes.spec.js → fix-country-codes.test.js} +12 -13
  333. package/src/fix-language-codes.js +5 -5
  334. package/src/{fix-language-codes.spec.js → fix-language-codes.test.js} +12 -13
  335. package/src/fixRelatorTerms.js +5 -5
  336. package/src/{fixRelatorTerms.spec.js → fixRelatorTerms.test.js} +13 -13
  337. package/src/{fixed-fields.spec.js → fixed-fields.test.js} +11 -14
  338. package/src/identical-fields.js +1 -1
  339. package/src/{identical-fields.spec.js → identical-fields.test.js} +9 -11
  340. package/src/index.js +132 -59
  341. package/src/indicator-fixes.js +17 -4
  342. package/src/{indicator-fixes.spec.js → indicator-fixes.test.js} +9 -12
  343. package/src/isbn-issn.js +12 -7
  344. package/src/{isbn-issn.spec.js → isbn-issn.test.js} +20 -22
  345. package/src/{item-language.spec.js → item-language.test.js} +21 -22
  346. package/src/melindaCustomMergeFields.js +1 -1
  347. package/src/merge-fields/controlSubfields.js +1 -1
  348. package/src/merge-fields/counterpartField.js +14 -9
  349. package/src/merge-fields/dataProvenance.js +41 -0
  350. package/src/merge-fields/index.js +12 -3
  351. package/src/merge-fields/mergableIndicator.js +1 -1
  352. package/src/merge-fields/mergeField.js +8 -8
  353. package/src/merge-fields/mergeIndicator.js +1 -1
  354. package/src/merge-fields/mergeOrAddPostprocess.js +4 -4
  355. package/src/merge-fields/mergeOrAddSubfield.js +2 -2
  356. package/src/merge-fields/mergeSubfield.js +4 -4
  357. package/src/merge-fields/removeDuplicateSubfields.js +2 -2
  358. package/src/{merge-fields.spec.js → merge-fields.test.js} +18 -15
  359. package/src/mergeField500Lisapainokset.js +1 -1
  360. package/src/{mergeField500Lisapainokset.spec.js → mergeField500Lisapainokset.test.js} +12 -13
  361. package/src/mergeRelatorTermFields.js +5 -7
  362. package/src/{mergeRelatorTermFields.spec.js → mergeRelatorTermFields.test.js} +12 -13
  363. package/src/modernize-502.js +1 -1
  364. package/src/{modernize-502.spec.js → modernize-502.test.js} +12 -13
  365. package/src/multiple-subfield-0.js +3 -3
  366. package/src/{multiple-subfield-0.spec.js → multiple-subfield-0.test.js} +13 -13
  367. package/src/{non-breaking-space.spec.js → non-breaking-space.test.js} +12 -13
  368. package/src/normalize-dashes.js +2 -2
  369. package/src/{normalize-dashes.spec.js → normalize-dashes.test.js} +12 -13
  370. package/src/normalize-identifiers.js +1 -1
  371. package/src/{normalize-identifiers.spec.js → normalize-identifiers.test.js} +12 -13
  372. package/src/normalize-qualifying-information.js +2 -2
  373. package/src/{normalize-qualifying-information.spec.js → normalize-qualifying-information.test.js} +12 -13
  374. package/src/normalize-utf8-diacritics.js +2 -2
  375. package/src/{normalize-utf8-diacritics.spec.js → normalize-utf8-diacritics.test.js} +13 -13
  376. package/src/normalizeFieldForComparison.js +32 -6
  377. package/src/normalizeSubfieldValueForComparison.js +1 -1
  378. package/src/prepublicationUtils.js +4 -4
  379. package/src/punctuation/index.js +1 -1
  380. package/src/punctuation/rules/index.js +2 -2
  381. package/src/{punctuation.spec.js → punctuation.test.js} +12 -13
  382. package/src/punctuation2.js +17 -8
  383. package/src/{punctuation2.spec.js → punctuation2.test.js} +12 -13
  384. package/src/reindexSubfield6OccurenceNumbers.js +5 -7
  385. package/src/{reindexSubfield6OccurenceNumbers.spec.js → reindexSubfield6OccurenceNumbers.test.js} +12 -13
  386. package/src/removeDuplicateDataFields.js +11 -19
  387. package/src/{removeDuplicateDataFields.spec.js → removeDuplicateDataFields.test.js} +12 -13
  388. package/src/removeInferiorDataFields.js +15 -12
  389. package/src/{removeInferiorDataFields.spec.js → removeInferiorDataFields.test.js} +13 -13
  390. package/src/resolvable-ext-references-melinda.js +1 -1
  391. package/src/{resolvable-ext-references-melinda.spec.js → resolvable-ext-references-melinda.test.js} +42 -27
  392. package/src/resolveOrphanedSubfield6s.js +6 -6
  393. package/src/{resolveOrphanedSubfield6s.spec.js → resolveOrphanedSubfield6s.test.js} +13 -13
  394. package/src/sanitize-vocabulary-source-codes.js +4 -4
  395. package/src/{sanitize-vocabulary-source-codes.spec.js → sanitize-vocabulary-source-codes.test.js} +16 -14
  396. package/src/{sort-tags.spec.js → sort-tags.test.js} +9 -11
  397. package/src/sortFields.js +4 -4
  398. package/src/{sortFields.spec.js → sortFields.test.js} +12 -13
  399. package/src/sortRelatorTerms.js +3 -3
  400. package/src/{sortRelatorTerms.spec.js → sortRelatorTerms.test.js} +13 -13
  401. package/src/sortSubfields.js +8 -6
  402. package/src/{sortSubfields.spec.js → sortSubfields.test.js} +13 -13
  403. package/src/stripPunctuation.js +3 -3
  404. package/src/{stripPunctuation.spec.js → stripPunctuation.test.js} +13 -13
  405. package/src/subfield-exclusion.js +1 -1
  406. package/src/{subfield-exclusion.spec.js → subfield-exclusion.test.js} +45 -36
  407. package/src/subfield6Utils.js +6 -10
  408. package/src/subfield8Utils.js +4 -4
  409. package/src/subfieldValueNormalizations.js +3 -3
  410. package/src/{subfieldValueNormalizations.spec.js → subfieldValueNormalizations.test.js} +18 -14
  411. package/src/sync-007-and-300.js +2 -2
  412. package/src/{sync-007-and-300.spec.js → sync-007-and-300.test.js} +13 -13
  413. package/src/translate-terms.js +3 -3
  414. package/src/translate-terms.test.js +75 -0
  415. package/src/{typeOfDate-008.spec.js → typeOfDate-008.test.js} +12 -13
  416. package/src/{unicode-decomposition.spec.js → unicode-decomposition.test.js} +10 -16
  417. package/src/update-field-540.js +2 -2
  418. package/src/{update-field-540.spec.js → update-field-540.test.js} +13 -10
  419. package/src/urn.js +2 -2
  420. package/src/{urn.spec.js → urn.test.js} +12 -13
  421. package/src/utils.js +21 -5
  422. package/test-fixtures/field-505-separators/03/expectedResult.json +3 -1
  423. package/test-fixtures/field-505-separators/03/record.json +3 -0
  424. package/test-fixtures/indicator-fixes/10/expectedResult.json +11 -0
  425. package/test-fixtures/indicator-fixes/10/metadata.json +4 -0
  426. package/test-fixtures/indicator-fixes/10/record.json +11 -0
  427. package/test-fixtures/merge-fields/f05/expectedResult.json +24 -0
  428. package/test-fixtures/merge-fields/f05/metadata.json +6 -0
  429. package/test-fixtures/merge-fields/f05/record.json +30 -0
  430. package/test-fixtures/normalize-subfield-value/01/metadata.json +4 -1
  431. package/test-fixtures/normalize-subfield-value/01/record.json +3 -0
  432. package/test-fixtures/normalize-subfield-value/02/expectedResult.json +3 -1
  433. package/test-fixtures/normalize-subfield-value/02/metadata.json +2 -1
  434. package/test-fixtures/normalize-subfield-value/02/record.json +3 -0
  435. package/test-fixtures/remove-inferior-datafields/f16/expectedResult.json +12 -0
  436. package/test-fixtures/remove-inferior-datafields/f16/metadata.json +5 -0
  437. package/test-fixtures/remove-inferior-datafields/f16/record.json +14 -0
  438. package/test-fixtures/sanitize-vocabulary-source-codes/f03/expectedResult.json +3 -1
  439. package/test-fixtures/sanitize-vocabulary-source-codes/f04/expectedResult.json +3 -1
  440. package/test-fixtures/sanitize-vocabulary-source-codes/v04/metadata.json +1 -4
  441. package/test-fixtures/sanitize-vocabulary-source-codes/v04/record.json +1 -1
  442. package/test-fixtures/translate-terms-data.js +42 -0
  443. package/dist/access-rights.spec.js +0 -195
  444. package/dist/access-rights.spec.js.map +0 -1
  445. package/dist/addMissingField041.spec.js +0 -45
  446. package/dist/addMissingField041.spec.js.map +0 -1
  447. package/dist/addMissingField336.spec.js +0 -45
  448. package/dist/addMissingField336.spec.js.map +0 -1
  449. package/dist/addMissingField337.spec.js +0 -43
  450. package/dist/addMissingField337.spec.js.map +0 -1
  451. package/dist/addMissingField338.spec.js +0 -45
  452. package/dist/addMissingField338.spec.js.map +0 -1
  453. package/dist/cyrillux-usemarcon-replacement.spec.js +0 -45
  454. package/dist/cyrillux-usemarcon-replacement.spec.js.map +0 -1
  455. package/dist/cyrillux.spec.js +0 -46
  456. package/dist/cyrillux.spec.js.map +0 -1
  457. package/dist/disambiguateSeriesStatements.spec.js +0 -51
  458. package/dist/disambiguateSeriesStatements.spec.js.map +0 -1
  459. package/dist/double-commas.spec.js +0 -73
  460. package/dist/double-commas.spec.js.map +0 -1
  461. package/dist/duplicates-ind1.spec.js +0 -45
  462. package/dist/duplicates-ind1.spec.js.map +0 -1
  463. package/dist/empty-fields.spec.js +0 -118
  464. package/dist/empty-fields.spec.js.map +0 -1
  465. package/dist/ending-punctuation.spec.js +0 -2654
  466. package/dist/ending-punctuation.spec.js.map +0 -1
  467. package/dist/ending-whitespace.spec.js +0 -42
  468. package/dist/ending-whitespace.spec.js.map +0 -1
  469. package/dist/field-008-18-34-character-groups.spec.js +0 -51
  470. package/dist/field-008-18-34-character-groups.spec.js.map +0 -1
  471. package/dist/field-505-separators.spec.js +0 -51
  472. package/dist/field-505-separators.spec.js.map +0 -1
  473. package/dist/field-521-fix.spec.js +0 -51
  474. package/dist/field-521-fix.spec.js.map +0 -1
  475. package/dist/field-exclusion.spec.js +0 -1054
  476. package/dist/field-exclusion.spec.js.map +0 -1
  477. package/dist/field-structure.spec.js +0 -535
  478. package/dist/field-structure.spec.js.map +0 -1
  479. package/dist/fields-present.spec.js +0 -121
  480. package/dist/fields-present.spec.js.map +0 -1
  481. package/dist/fix-33X.spec.js +0 -45
  482. package/dist/fix-33X.spec.js.map +0 -1
  483. package/dist/fix-country-codes.spec.js +0 -51
  484. package/dist/fix-country-codes.spec.js.map +0 -1
  485. package/dist/fix-language-codes.spec.js +0 -44
  486. package/dist/fix-language-codes.spec.js.map +0 -1
  487. package/dist/fixRelatorTerms.spec.js +0 -51
  488. package/dist/fixRelatorTerms.spec.js.map +0 -1
  489. package/dist/fixed-fields.spec.js +0 -140
  490. package/dist/fixed-fields.spec.js.map +0 -1
  491. package/dist/identical-fields.spec.js +0 -99
  492. package/dist/identical-fields.spec.js.map +0 -1
  493. package/dist/indicator-fixes.spec.js +0 -51
  494. package/dist/indicator-fixes.spec.js.map +0 -1
  495. package/dist/isbn-issn.spec.js +0 -595
  496. package/dist/isbn-issn.spec.js.map +0 -1
  497. package/dist/item-language.spec.js +0 -306
  498. package/dist/item-language.spec.js.map +0 -1
  499. package/dist/melindaCustomMergeFields.json +0 -5120
  500. package/dist/merge-fields.spec.js +0 -51
  501. package/dist/merge-fields.spec.js.map +0 -1
  502. package/dist/mergeField500Lisapainokset.spec.js +0 -51
  503. package/dist/mergeField500Lisapainokset.spec.js.map +0 -1
  504. package/dist/mergeRelatorTermFields.spec.js +0 -51
  505. package/dist/mergeRelatorTermFields.spec.js.map +0 -1
  506. package/dist/modernize-502.spec.js +0 -49
  507. package/dist/modernize-502.spec.js.map +0 -1
  508. package/dist/multiple-subfield-0.spec.js +0 -51
  509. package/dist/multiple-subfield-0.spec.js.map +0 -1
  510. package/dist/non-breaking-space.spec.js +0 -42
  511. package/dist/non-breaking-space.spec.js.map +0 -1
  512. package/dist/normalize-dashes.spec.js +0 -51
  513. package/dist/normalize-dashes.spec.js.map +0 -1
  514. package/dist/normalize-identifiers.spec.js +0 -51
  515. package/dist/normalize-identifiers.spec.js.map +0 -1
  516. package/dist/normalize-qualifying-information.spec.js +0 -51
  517. package/dist/normalize-qualifying-information.spec.js.map +0 -1
  518. package/dist/normalize-utf8-diacritics.spec.js +0 -51
  519. package/dist/normalize-utf8-diacritics.spec.js.map +0 -1
  520. package/dist/punctuation.spec.js +0 -51
  521. package/dist/punctuation.spec.js.map +0 -1
  522. package/dist/punctuation2.spec.js +0 -51
  523. package/dist/punctuation2.spec.js.map +0 -1
  524. package/dist/reindexSubfield6OccurenceNumbers.spec.js +0 -51
  525. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +0 -1
  526. package/dist/removeDuplicateDataFields.spec.js +0 -51
  527. package/dist/removeDuplicateDataFields.spec.js.map +0 -1
  528. package/dist/removeInferiorDataFields.spec.js +0 -51
  529. package/dist/removeInferiorDataFields.spec.js.map +0 -1
  530. package/dist/resolvable-ext-references-melinda.spec.js +0 -166
  531. package/dist/resolvable-ext-references-melinda.spec.js.map +0 -1
  532. package/dist/resolveOrphanedSubfield6s.spec.js +0 -51
  533. package/dist/resolveOrphanedSubfield6s.spec.js.map +0 -1
  534. package/dist/sanitize-vocabulary-source-codes.spec.js +0 -51
  535. package/dist/sanitize-vocabulary-source-codes.spec.js.map +0 -1
  536. package/dist/sort-tags.spec.js +0 -207
  537. package/dist/sort-tags.spec.js.map +0 -1
  538. package/dist/sortFields.spec.js +0 -51
  539. package/dist/sortFields.spec.js.map +0 -1
  540. package/dist/sortRelatorTerms.spec.js +0 -51
  541. package/dist/sortRelatorTerms.spec.js.map +0 -1
  542. package/dist/sortSubfields.spec.js +0 -52
  543. package/dist/sortSubfields.spec.js.map +0 -1
  544. package/dist/stripPunctuation.spec.js +0 -51
  545. package/dist/stripPunctuation.spec.js.map +0 -1
  546. package/dist/subfield-exclusion.spec.js +0 -523
  547. package/dist/subfield-exclusion.spec.js.map +0 -1
  548. package/dist/subfieldValueNormalizations.spec.js +0 -51
  549. package/dist/subfieldValueNormalizations.spec.js.map +0 -1
  550. package/dist/sync-007-and-300.spec.js +0 -51
  551. package/dist/sync-007-and-300.spec.js.map +0 -1
  552. package/dist/translate-terms.spec.js +0 -51
  553. package/dist/translate-terms.spec.js.map +0 -1
  554. package/dist/typeOfDate-008.spec.js +0 -47
  555. package/dist/typeOfDate-008.spec.js.map +0 -1
  556. package/dist/unicode-decomposition.spec.js +0 -91
  557. package/dist/unicode-decomposition.spec.js.map +0 -1
  558. package/dist/update-field-540.spec.js +0 -51
  559. package/dist/update-field-540.spec.js.map +0 -1
  560. package/dist/urn.spec.js +0 -52
  561. package/dist/urn.spec.js.map +0 -1
  562. package/src/melindaCustomMergeFields.json +0 -5120
  563. package/src/translate-terms.spec.js +0 -52
@@ -1,926 +1,396 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
- exports.fieldFixPunctuation = fieldFixPunctuation;
8
- exports.fieldGetFixedString = fieldGetFixedString;
9
- exports.fieldNeedsModification = fieldNeedsModification;
10
- exports.fieldStripPunctuation = fieldStripPunctuation;
11
- var _endingPunctuation = require("./ending-punctuation");
12
- var _subfield6Utils = require("./subfield6Utils");
13
- var _utils = require("./utils");
14
- var _clone = _interopRequireDefault(require("clone"));
15
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
- /*
17
- * punctuation.js -- try and fix a marc field punctuation
18
- *
19
- * Author(s): Nicholas Volk <nicholas.volk@helsinki.fi>
20
- *
21
- * NOTE #1: https://www.kiwi.fi/display/kumea/Loppupisteohje is implemented via another validator/fixer (ending-punctuation).
22
- * This file has some support but it's now yet thorough. (And mmight never be.)
23
- * NOTE #2: Validator/fixer punctuation does similar stuff, but focuses on X00 fields.
24
- * NOTE #3: As of 2023-06-05 control subfields ($0...$9) are obsolete. Don't use them in rules.
25
- * (They are jumped over when looking for next (non-controlfield subfield)
26
- */
27
-
28
- //import createDebugLogger from 'debug';
29
-
30
- //const debug = createDebugLogger('debug/punctuation2');
31
-
32
- const descriptionString = 'Remove invalid and add valid punctuation to data fields';
33
- function _default() {
1
+ import { validateSingleField } from "./ending-punctuation.js";
2
+ import { tagToDataProvenanceSubfieldCode } from "./merge-fields/dataProvenance.js";
3
+ import { fieldGetUnambiguousTag } from "./subfield6Utils.js";
4
+ import { fieldToString, isControlSubfieldCode, nvdebug } from "./utils.js";
5
+ import clone from "clone";
6
+ const descriptionString = "Remove invalid and add valid punctuation to data fields";
7
+ export default function() {
34
8
  return {
35
9
  description: descriptionString,
36
10
  validate,
37
11
  fix
38
12
  };
39
13
  function fix(record) {
40
- (0, _utils.nvdebug)(`${descriptionString}: fixer`);
41
- const res = {
42
- message: [],
43
- fix: [],
44
- valid: true
45
- };
46
- record.fields.forEach(f => fieldFixPunctuation(f)); // eslint-disable-line array-callback-return
14
+ nvdebug(`${descriptionString}: fixer`);
15
+ const res = { message: [], fix: [], valid: true };
16
+ record.fields.forEach((f) => fieldFixPunctuation(f));
47
17
  return res;
48
18
  }
49
19
  function validate(record) {
50
- (0, _utils.nvdebug)(`${descriptionString}: validate`);
51
- const fieldsNeedingModification = record.fields.filter(f => fieldNeedsModification(f, true));
52
- const values = fieldsNeedingModification.map(f => (0, _utils.fieldToString)(f));
53
- const newValues = fieldsNeedingModification.map(f => fieldGetFixedString(f, true));
20
+ nvdebug(`${descriptionString}: validate`);
21
+ const fieldsNeedingModification = record.fields.filter((f) => fieldNeedsModification(f, true));
22
+ const values = fieldsNeedingModification.map((f) => fieldToString(f));
23
+ const newValues = fieldsNeedingModification.map((f) => fieldGetFixedString(f, true));
54
24
  const messages = values.map((val, i) => `'${val}' => '${newValues[i]}'`);
55
- const res = {
56
- message: messages
57
- };
25
+ const res = { message: messages };
58
26
  res.valid = res.message.length < 1;
59
27
  return res;
60
28
  }
61
29
  }
62
- function isControlSubfield(subfield) {
63
- return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(subfield.code);
30
+ function isIrrelevantSubfield(subfield, tag) {
31
+ const dataProvenanceSubfieldCode = tagToDataProvenanceSubfieldCode(tag);
32
+ if (subfield.code === dataProvenanceSubfieldCode) {
33
+ return true;
34
+ }
35
+ return isControlSubfieldCode(subfield.code);
64
36
  }
65
37
  function getNextRelevantSubfield(field, currSubfieldIndex) {
66
- return field.subfields.find((subfield, index) => index > currSubfieldIndex && !isControlSubfield(subfield));
38
+ return field.subfields.find((subfield, index) => index > currSubfieldIndex && !isIrrelevantSubfield(subfield, field.tag));
67
39
  }
68
- function fieldGetFixedString(field, add = true) {
69
- const cloneField = (0, _clone.default)(field);
40
+ export function fieldGetFixedString(field, add = true) {
41
+ const cloneField = clone(field);
70
42
  const operation = add ? subfieldFixPunctuation : subfieldStripPunctuation;
71
43
  cloneField.subfields.forEach((sf, i) => {
72
- // NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
73
- // (In plain English: We should skip $0 - $9 at least, maybe $w as well...)
74
44
  operation(cloneField, sf, getNextRelevantSubfield(cloneField, i));
75
45
  });
76
- return (0, _utils.fieldToString)(cloneField);
46
+ return fieldToString(cloneField);
77
47
  }
78
- function fieldNeedsModification(field, add = true) {
48
+ export function fieldNeedsModification(field, add = true) {
79
49
  if (!field.subfields) {
80
50
  return false;
81
51
  }
82
- const originalFieldAsString = (0, _utils.fieldToString)(field);
52
+ const originalFieldAsString = fieldToString(field);
83
53
  const modifiedFieldAsString = fieldGetFixedString(field, add);
84
54
  return modifiedFieldAsString !== originalFieldAsString;
85
55
  }
86
-
87
- /////////////////////////////////////////////////////////////////////////////////////
88
- // <= Above code is written for the validator logic <= //
89
- // => Everything below was originally transferred from reducers' punctuation.js => //
90
- /////////////////////////////////////////////////////////////////////////////////////
91
-
92
- //const stripCrap = / *[-;:,+]+$/u;
93
56
  const needsPuncAfterAlphanumeric = /(?:[a-z0-9A-Z]|å|ä|ö|Å|Ä|Ö)$/u;
94
57
  const defaultNeedsPuncAfter2 = /(?:[\]a-zA-Z0-9)]|ä|å|ö|Å|Ä|Ö)$/u;
95
- const doesNotEndInPunc = /[^!?.:;,]$/u; // non-punc for pre-240/700/XXX $, note that '.' comes if preceded by ')'
58
+ const doesNotEndInPunc = /[^!?.:;,]$/u;
96
59
  const blocksPuncRHS = /^(?:\()/u;
97
60
  const allowsPuncRHS = /^(?:[A-Za-z0-9]|å|ä|ö|Å|Ä|Ö)/u;
98
- const aToZ = 'abcdefghijklmnopqrstuvwxyz';
61
+ const aToZ = "abcdefghijklmnopqrstuvwxyz";
99
62
  const dotIsProbablyPunc = /(?:[a-z0-9)]|å|ä|ö|(?:[A-Za-z0-9]|Å|Ä|Ö)(?:[A-Z]|Å|Ä|Ö))\.$/u;
100
63
  const puncIsProbablyPunc = /(?:[a-z0-9)]|å|ä|ö) ?[.,:;]$/u;
101
- // NB! 65X: Finnish terms don't use punctuation, but international ones do. Neither one is currently (2021-11-08) coded here.
102
-
103
- // Will unfortunately trigger "Sukunimi, Th." type:
104
- const removeColons = {
105
- 'code': 'abcdefghijklmnopqrstuvwxyz',
106
- 'remove': / *[;:]$/u
107
- };
108
- const removeX00Comma = {
109
- 'code': 'abcdejnqt',
110
- 'followedBy': 'abcdenqtv#',
111
- 'context': /.,$/u,
112
- 'remove': /,$/u
113
- };
114
- const cleanRHS = {
115
- 'code': 'abcd',
116
- 'followedBy': 'bcde',
117
- 'context': /(?:(?:[a-z0-9]|å|ä|ö)\.|,)$/u,
118
- 'contextRHS': blocksPuncRHS,
119
- 'remove': /[.,]$/u
120
- };
121
- const cleanX00dCommaOrDot = {
122
- 'code': 'd',
123
- 'followedBy': 'et#',
124
- 'context': /[0-9]-[,.]$/u,
125
- 'remove': /[,.]$/u
126
- };
127
- const cleanX00aDot = {
128
- 'code': 'abcde',
129
- 'followedBy': 'cdegj',
130
- 'context': dotIsProbablyPunc,
131
- 'remove': /\.$/u
132
- };
133
- const cleanCorruption = {
134
- 'code': 'abcdefghijklmnopqrstuvwxyz',
135
- 'remove': / \.$/u
136
- };
137
- // These $e dot removals are tricky: before removing the comma, we should know that it ain't an abbreviation such as "esitt."...
138
- const cleanX00eDot = {
139
- 'code': 'e',
140
- 'followedBy': 'egj#',
141
- 'context': /(?:[ai]ja|jä)[.,]$/u,
142
- 'remove': /\.$/u
143
- };
144
- const cleanX11jDot = {
145
- 'code': 'e',
146
- 'followedBy': 'egj#',
147
- 'context': /(?:[ai]ja|jä)[.,]$/u,
148
- 'remove': /\.$/u
149
- };
150
- const removeCommaBeforeLanguageSubfieldL = {
151
- 'followedBy': 'l',
152
- 'remove': /,$/u
153
- };
154
- const removeCommaBeforeTitleSubfieldT = {
155
- 'followedBy': 't',
156
- 'remove': /,$/u
157
- };
158
- const X00RemoveDotAfterBracket = {
159
- 'code': 'cq',
160
- 'context': /\)\.$/u,
161
- 'remove': /\.$/u
162
- };
163
- // 390, 800, 810, 830...
164
- const cleanPuncBeforeLanguage = {
165
- 'code': 'atvxyz',
166
- 'followedBy': 'l',
167
- 'context': puncIsProbablyPunc,
168
- 'remove': / *[.,:;]$/u
169
- };
170
- const addX00aComma = {
171
- 'add': ',',
172
- 'code': 'abcqej',
173
- 'followedBy': 'cdeg',
174
- 'context': doesNotEndInPunc,
175
- 'contextRHS': allowsPuncRHS
176
- };
177
- const addX00dComma = {
178
- 'name': 'X00$d ending in "-" does not get comma',
179
- 'add': ',',
180
- 'code': 'd',
181
- 'followedBy': 'cdeg',
182
- 'context': /[^-,.!]$/u,
183
- 'contextRHS': allowsPuncRHS
184
- };
185
- const addX00aComma2 = {
186
- 'add': ',',
187
- 'code': 'abcdej',
188
- 'followedBy': 'cdeg',
189
- 'context': /(?:[A-Z]|Å|Ä|Ö)\.$/u,
190
- 'contextRHS': allowsPuncRHS
191
- };
192
- const addX00Dot = {
193
- 'add': '.',
194
- 'code': 'abcdetv',
195
- 'followedBy': 'fklptu',
196
- 'context': needsPuncAfterAlphanumeric
197
- };
198
- const addEntryFieldFinalDot = {
199
- 'name': 'X00 final dot',
200
- 'add': '.',
201
- 'code': 'abcdefghijklmnopqrstuvwxyz',
202
- 'followedBy': '#',
203
- 'context': /[^.)!?-]$/u
204
- };
205
- const addX10iColon = {
206
- name: 'Punctuate relationship information',
207
- add: ':',
208
- code: 'i',
209
- context: defaultNeedsPuncAfter2
210
- };
211
- const addX10bDot = {
212
- 'name': 'Add X10 pre-$b dot',
213
- 'add': '.',
214
- 'code': 'ab',
215
- 'followedBy': 'b',
216
- 'context': defaultNeedsPuncAfter2
217
- };
218
- const addX10eComma = {
219
- 'add': ',',
220
- 'code': 'abe',
221
- 'followedBy': 'e',
222
- 'context': defaultNeedsPuncAfter2
223
- };
224
- const addX10Dot = {
225
- 'name': 'Add X10 final dot',
226
- 'add': '.',
227
- 'code': 'abet',
228
- 'followedBy': 'tu#',
229
- 'context': needsPuncAfterAlphanumeric
230
- };
231
- const addColonToRelationshipInformation = {
232
- 'name': 'Add \':\' to 7X0 $i relationship info',
233
- 'add': ':',
234
- 'code': 'i',
235
- 'context': defaultNeedsPuncAfter2
236
- };
237
- const addX11Spacecolon = {
238
- name: '611 space colon(y :-)',
239
- add: ' :',
240
- code: 'nd',
241
- followedBy: 'dc',
242
- 'context': defaultNeedsPuncAfter2
243
- };
244
- const addDotBeforeLanguageSubfieldL = {
245
- 'name': 'Add dot before $l',
246
- 'add': '.',
247
- 'code': 'abepst',
248
- 'followedBy': 'l',
249
- 'context': doesNotEndInPunc
250
- };
251
-
252
- // 490:
253
- const addSemicolonBeforeVolumeDesignation = {
254
- 'name': 'Add " ;" before $v',
255
- 'add': ' ;',
256
- 'code': 'atxyz',
257
- 'followedBy': 'v',
258
- 'context': /[^;]$/u
259
- };
64
+ const removeColons = { "code": "abcdefghijklmnopqrstuvwxyz", "remove": / *[;:]$/u };
65
+ const removeX00Comma = { "code": "abcdejnqt", "followedBy": "abcdenqtv#", "context": /.,$/u, "remove": /,$/u };
66
+ const cleanRHS = { "code": "abcd", "followedBy": "bcde", "context": /(?:(?:[a-z0-9]|å|ä|ö)\.|,)$/u, "contextRHS": blocksPuncRHS, "remove": /[.,]$/u };
67
+ const cleanX00dCommaOrDot = { "code": "d", "followedBy": "et#", "context": /[0-9]-[,.]$/u, "remove": /[,.]$/u };
68
+ const cleanX00aDot = { "code": "abcde", "followedBy": "cdegj", "context": dotIsProbablyPunc, "remove": /\.$/u };
69
+ const cleanCorruption = { "code": "abcdefghijklmnopqrstuvwxyz", "remove": / \.$/u };
70
+ const cleanX00eDot = { "code": "e", "followedBy": "egj#", "context": /(?:[ai]ja|jä)[.,]$/u, "remove": /\.$/u };
71
+ const cleanX11jDot = { "code": "e", "followedBy": "egj#", "context": /(?:[ai]ja|jä)[.,]$/u, "remove": /\.$/u };
72
+ const removeCommaBeforeLanguageSubfieldL = { "followedBy": "l", "remove": /,$/u };
73
+ const removeCommaBeforeTitleSubfieldT = { "followedBy": "t", "remove": /,$/u };
74
+ const X00RemoveDotAfterBracket = { "code": "cq", "context": /\)\.$/u, "remove": /\.$/u };
75
+ const cleanPuncBeforeLanguage = { "code": "atvxyz", "followedBy": "l", "context": puncIsProbablyPunc, "remove": / *[.,:;]$/u };
76
+ const addX00aComma = { "add": ",", "code": "abcqej", "followedBy": "cdeg", "context": doesNotEndInPunc, "contextRHS": allowsPuncRHS };
77
+ const addX00dComma = { "name": 'X00$d ending in "-" does not get comma', "add": ",", "code": "d", "followedBy": "cdeg", "context": /[^-,.!]$/u, "contextRHS": allowsPuncRHS };
78
+ const addX00aComma2 = { "add": ",", "code": "abcdej", "followedBy": "cdeg", "context": /(?:[A-Z]|Å|Ä|Ö)\.$/u, "contextRHS": allowsPuncRHS };
79
+ const addX00Dot = { "add": ".", "code": "abcdetv", "followedBy": "fklptu", "context": needsPuncAfterAlphanumeric };
80
+ const addEntryFieldFinalDot = { "name": "X00 final dot", "add": ".", "code": "abcdefghijklmnopqrstuvwxyz", "followedBy": "#", "context": /[^.)!?-]$/u };
81
+ const addX10iColon = { name: "Punctuate relationship information", add: ":", code: "i", context: defaultNeedsPuncAfter2 };
82
+ const addX10bDot = { "name": "Add X10 pre-$b dot", "add": ".", "code": "ab", "followedBy": "b", "context": defaultNeedsPuncAfter2 };
83
+ const addX10eComma = { "add": ",", "code": "abe", "followedBy": "e", "context": defaultNeedsPuncAfter2 };
84
+ const addX10Dot = { "name": "Add X10 final dot", "add": ".", "code": "abet", "followedBy": "tu#", "context": needsPuncAfterAlphanumeric };
85
+ const addColonToRelationshipInformation = { "name": "Add ':' to 7X0 $i relationship info", "add": ":", "code": "i", "context": defaultNeedsPuncAfter2 };
86
+ const addX11Spacecolon = { name: "611 space colon(y :-)", add: " :", code: "nd", followedBy: "dc", "context": defaultNeedsPuncAfter2 };
87
+ const addDotBeforeLanguageSubfieldL = { "name": "Add dot before $l", "add": ".", "code": "abepst", "followedBy": "l", "context": doesNotEndInPunc };
88
+ const addSemicolonBeforeVolumeDesignation = { "name": 'Add " ;" before $v', "add": " ;", "code": "atxyz", "followedBy": "v", "context": /[^;]$/u };
260
89
  const NONE = 0;
261
90
  const ADD = 2;
262
91
  const REMOVE = 1;
263
92
  const REMOVE_AND_ADD = 3;
264
-
265
- // Crappy punctuation consists of various crap that is somewhat common.
266
- // We strip crap for merge decisions. We are not trying to actively remove crap here.
267
-
268
93
  const removeCrapFromAllEntryFields = [removeCommaBeforeLanguageSubfieldL, removeCommaBeforeTitleSubfieldT];
269
94
  const removeX00Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, cleanX00dCommaOrDot, cleanRHS, X00RemoveDotAfterBracket, removeColons, cleanPuncBeforeLanguage, ...removeCrapFromAllEntryFields];
270
95
  const removeX10Whatever = [removeX00Comma, cleanX00aDot, cleanX00eDot, cleanCorruption, removeColons, cleanPuncBeforeLanguage, ...removeCrapFromAllEntryFields];
271
96
  const removeX11Whatever = [removeX00Comma, cleanX11jDot, ...removeCrapFromAllEntryFields];
272
97
  const removeX30Whatever = removeCrapFromAllEntryFields;
273
- const remove490And830Whatever = [{
274
- 'code': 'axyzv',
275
- 'followedBy': 'axyzv',
276
- 'remove': /(?: *;| *=|,)$/u
277
- }];
278
- const linkingEntryRemoveWhatever = [{
279
- 'code': 'i',
280
- 'followedBy': 'at',
281
- 'remove': / ?:$/u
282
- },
283
- // ':'
284
- {
285
- 'code': 'at',
286
- 'remove': /\.$/u
287
- }, {
288
- 'code': 'abdghiklmnopqrstuwxyz',
289
- 'followedBy': 'abdghiklmnopqrstuwxyz',
290
- 'remove': /\. -$/u
291
- }];
292
-
293
- // '!' means negation, thus '!b' means any other subfield but 'b'.
294
- // 'followedBy': '#' means that current subfield is the last subfield.
295
- // NB! Note that control subfields are ignored in punctuation rules.
296
- // NB #2! Control field ignorance causes issues with field 257: https://wiki.helsinki.fi/display/rdasovellusohje/Loppupisteohje
297
- // Might need to work on that at some point. NOT a top priority though.
298
- // NB #3! Final punctuation creation is/should be handled by endind-punctuation.js validator!
299
-
300
- const crappy24X = [{
301
- 'code': 'abnp',
302
- 'followedBy': '!c',
303
- 'remove': / \/$/u
304
- }, {
305
- 'code': 'abn',
306
- 'followedBy': 'c',
307
- 'remove': /\.$/u,
308
- 'context': dotIsProbablyPunc
309
- }, {
310
- 'code': 'abn',
311
- 'followedBy': 'c',
312
- 'remove': /\.$/u,
313
- 'context': dotIsProbablyPunc
314
- }, {
315
- 'code': 'abc',
316
- 'followedBy': '#',
317
- 'remove': /\.$/u,
318
- 'context': dotIsProbablyPunc
319
- }, {
320
- 'code': 'abfghinp',
321
- 'followedBy': '#',
322
- 'remove': /\.$/u,
323
- 'context': dotIsProbablyPunc
324
- }, {
325
- 'code': 'n',
326
- 'followedBy': 'p',
327
- 'remove': /\.$/u,
328
- 'context': dotIsProbablyPunc
329
- },
330
- // MELINDA-8817
331
- {
332
- 'code': 'p',
333
- 'followedBy': 'pc',
334
- 'remove': /\.$/u,
335
- 'context': dotIsProbablyPunc
336
- },
337
- // MELINDA-8817
338
- removeCommaBeforeLanguageSubfieldL];
98
+ const remove490And830Whatever = [{ "code": "axyzv", "followedBy": "axyzv", "remove": /(?: *;| *=|,)$/u }];
99
+ const linkingEntryRemoveWhatever = [
100
+ { "code": "i", "followedBy": "at", "remove": / ?:$/u },
101
+ // ':'
102
+ { "code": "at", "remove": /\.$/u },
103
+ // Only ". -" separator is still used in music. We can strip it, but can only create the non-music punctuation!
104
+ { "code": "abdghiklmnopqrstuwxyz", "followedBy": "abdghiklmnopqrstuwxyz#", "remove": /\. -$/u }
105
+ ];
106
+ const crappy24X = [
107
+ { "code": "abnp", "followedBy": "!c", "remove": / \/$/u },
108
+ { "code": "abn", "followedBy": "c", "remove": /\.$/u, "context": dotIsProbablyPunc },
109
+ { "code": "abn", "followedBy": "c", "remove": /\.$/u, "context": dotIsProbablyPunc },
110
+ { "code": "abc", "followedBy": "#", "remove": /\.$/u, "context": dotIsProbablyPunc },
111
+ { "code": "abfghinp", "followedBy": "#", "remove": /\.$/u, "context": dotIsProbablyPunc },
112
+ { "code": "n", "followedBy": "p", "remove": /\.$/u, "context": dotIsProbablyPunc },
113
+ // MELINDA-8817
114
+ { "code": "p", "followedBy": "pc", "remove": /\.$/u, "context": dotIsProbablyPunc },
115
+ // MELINDA-8817
116
+ removeCommaBeforeLanguageSubfieldL
117
+ ];
339
118
  const cleanCrappyPunctuationRules = {
340
- '100': removeX00Whatever,
341
- '110': removeX10Whatever,
342
- '111': removeX11Whatever,
343
- '130': removeX30Whatever,
344
- '240': crappy24X,
345
- '245': crappy24X,
346
- '246': crappy24X,
347
- '300': [{
348
- 'code': 'a',
349
- 'followedBy': '!b',
350
- 'remove': / *:$/u
351
- }, {
352
- 'code': 'a',
353
- 'followedBy': 'b',
354
- 'remove': /:$/u,
355
- 'context': /[^ ]:$/u
356
- }, {
357
- 'code': 'ab',
358
- 'followedBy': '!c',
359
- 'remove': / *;$/u
360
- }, {
361
- 'code': 'ab',
362
- 'followedBy': 'c',
363
- 'remove': /;$/u,
364
- 'context': /[^ ];$/u
365
- }, {
366
- 'code': 'abc',
367
- 'followedBy': '!e',
368
- 'remove': / *\+$/u
369
- } // Removes both valid (with one space) and invalid (spaceless et al) puncs
119
+ "100": removeX00Whatever,
120
+ "110": removeX10Whatever,
121
+ "111": removeX11Whatever,
122
+ "130": removeX30Whatever,
123
+ "240": crappy24X,
124
+ "245": crappy24X,
125
+ "246": crappy24X,
126
+ "300": [
127
+ { "code": "a", "followedBy": "!b", "remove": / *:$/u },
128
+ { "code": "a", "followedBy": "b", "remove": /:$/u, "context": /[^ ]:$/u },
129
+ { "code": "ab", "followedBy": "!c", "remove": / *;$/u },
130
+ { "code": "ab", "followedBy": "c", "remove": /;$/u, "context": /[^ ];$/u },
131
+ { "code": "abc", "followedBy": "!e", "remove": / *\+$/u }
132
+ // Removes both valid (with one space) and invalid (spaceless et al) puncs
370
133
  ],
371
- '490': remove490And830Whatever,
372
- '600': removeX00Whatever,
373
- '610': removeX10Whatever,
374
- '611': removeX11Whatever,
375
- '630': removeX30Whatever,
376
- '700': removeX00Whatever,
377
- '710': removeX10Whatever,
378
- '711': removeX11Whatever,
379
- '730': removeX30Whatever,
380
- '773': linkingEntryRemoveWhatever,
381
- '774': linkingEntryRemoveWhatever,
382
- '776': linkingEntryRemoveWhatever,
383
- '787': linkingEntryRemoveWhatever,
384
- '800': removeX00Whatever,
385
- '810': removeX10Whatever,
386
- '830': remove490And830Whatever,
387
- '946': crappy24X
388
- };
389
- const cleanLegalX00Comma = {
390
- 'code': 'abcde',
391
- 'followedBy': 'cdegj',
392
- 'context': /.,$/u,
393
- 'remove': /,$/u
394
- };
395
- // Accept upper case letters in X00$b, since they are probably Roman numerals.
396
- const cleanLegalX00bDot = {
397
- 'code': 'b',
398
- 'followedBy': 't#',
399
- context: /^[IVXLCDM]+\.$/u,
400
- 'remove': /\.$/u
401
- };
402
- const cleanLegalX00iColon = {
403
- 'code': 'i',
404
- 'followedBy': 'a',
405
- 'remove': / *:$/u
406
- }; // NB! context is not needed
407
- const cleanLegalX00Dot = {
408
- 'code': 'abcdetvl',
409
- 'followedBy': 'tu#',
410
- 'context': /(?:[a-z0-9)]|å|ä|ö)\.$/u,
411
- 'remove': /\.$/u
412
- };
413
- const cleanDotBeforeLanguageSubfieldL = {
414
- 'name': 'pre-language-$l dot',
415
- 'followedBy': 'l',
416
- 'context': /.\.$/u,
417
- 'remove': /\.$/u
418
- };
134
+ "490": remove490And830Whatever,
135
+ "600": removeX00Whatever,
136
+ "610": removeX10Whatever,
137
+ "611": removeX11Whatever,
138
+ "630": removeX30Whatever,
139
+ "700": removeX00Whatever,
140
+ "710": removeX10Whatever,
141
+ "711": removeX11Whatever,
142
+ "730": removeX30Whatever,
143
+ "773": linkingEntryRemoveWhatever,
144
+ "774": linkingEntryRemoveWhatever,
145
+ "776": linkingEntryRemoveWhatever,
146
+ "787": linkingEntryRemoveWhatever,
147
+ "800": removeX00Whatever,
148
+ "810": removeX10Whatever,
149
+ "830": remove490And830Whatever,
150
+ "946": crappy24X
151
+ };
152
+ const cleanLegalX00Comma = { "code": "abcde", "followedBy": "cdegj", "context": /.,$/u, "remove": /,$/u };
153
+ const cleanLegalX00bDot = { "code": "b", "followedBy": "t#", context: /^[IVXLCDM]+\.$/u, "remove": /\.$/u };
154
+ const cleanLegalX00iColon = { "code": "i", "followedBy": "a", "remove": / *:$/u };
155
+ const cleanLegalX00Dot = { "code": "abcdetvl", "followedBy": "tu#", "context": /(?:[a-z0-9)]|å|ä|ö)\.$/u, "remove": /\.$/u };
156
+ const cleanDotBeforeLanguageSubfieldL = { "name": "pre-language-$l dot", "followedBy": "l", "context": /.\.$/u, "remove": /\.$/u };
419
157
  const legalEntryField = [cleanDotBeforeLanguageSubfieldL];
420
- const legalX11SpaceColon = {
421
- name: 'legal X11 spacecolony',
422
- code: 'nd',
423
- followedBy: 'dc',
424
- context: / :$/u,
425
- remove: / :$/u
426
- };
158
+ const legalX11SpaceColon = { name: "legal X11 spacecolony", code: "nd", followedBy: "dc", context: / :$/u, remove: / :$/u };
427
159
  const legalX00punc = [cleanLegalX00Comma, cleanLegalX00iColon, cleanLegalX00bDot, cleanLegalX00Dot, ...legalEntryField];
428
- const cleanLegalX10Comma = {
429
- 'name': 'X10comma',
430
- 'code': 'abe',
431
- 'followedBy': 'e',
432
- 'context': /.,$/u,
433
- 'remove': /,$/u
434
- };
435
- const cleanLegalX10Dot = {
436
- 'name': 'X10dot',
437
- 'code': 'abt',
438
- 'followedBy': 'bst#',
439
- 'context': /.\.$/u,
440
- 'remove': /\.$/u
441
- };
160
+ const cleanLegalX10Comma = { "name": "X10comma", "code": "abe", "followedBy": "e", "context": /.,$/u, "remove": /,$/u };
161
+ const cleanLegalX10Dot = { "name": "X10dot", "code": "abt", "followedBy": "bst#", "context": /.\.$/u, "remove": /\.$/u };
442
162
  const legalX10punc = [cleanLegalX10Comma, cleanLegalX10Dot, cleanX00eDot, ...legalEntryField];
443
163
  const cleanLegalSeriesTitle = [
444
- // 490 and 830
445
- {
446
- 'code': 'a',
447
- 'followedBy': 'a',
448
- 'remove': / =$/u
449
- }, {
450
- 'code': 'axyz',
451
- 'followedBy': 'xyz',
452
- 'remove': /,$/u,
453
- 'context': /.,$/u
454
- }, {
455
- 'code': 'axyz',
456
- 'followedBy': 'v',
457
- 'remove': / *;$/u
458
- }];
459
- const clean24X = [{
460
- 'name': 'I:A',
461
- 'code': 'i',
462
- 'followedBy': 'a',
463
- 'remove': / *:$/u
464
- }, {
465
- 'name': 'A:B',
466
- 'code': 'a',
467
- 'followedBy': 'b',
468
- 'remove': / [:;=]$/u
469
- }, {
470
- 'name': 'AB:K',
471
- 'code': 'ab',
472
- 'followedBy': 'k',
473
- 'remove': / :$/u
474
- }, {
475
- 'name': 'ABK:F',
476
- 'code': 'abk',
477
- 'followedBy': 'f',
478
- 'remove': /,$/u
479
- }, {
480
- 'name': 'ABFNP:C',
481
- 'code': 'abfnp',
482
- 'followedBy': 'c',
483
- 'remove': / \/$/u
484
- }, {
485
- 'name': 'ABN:N',
486
- 'code': 'abn',
487
- 'followedBy': 'n',
488
- 'remove': /\.$/u
489
- }, {
490
- 'name': 'ABNP:#',
491
- 'code': 'abnp',
492
- 'followedBy': '#',
493
- 'remove': /\.$/u
494
- }, {
495
- 'name': 'N:P',
496
- 'code': 'n',
497
- 'followedBy': 'p',
498
- 'remove': /,$/u
499
- }, cleanDotBeforeLanguageSubfieldL];
164
+ // 490 and 830
165
+ { "code": "a", "followedBy": "a", "remove": / =$/u },
166
+ { "code": "axyz", "followedBy": "xyz", "remove": /,$/u, "context": /.,$/u },
167
+ { "code": "axyz", "followedBy": "v", "remove": / *;$/u }
168
+ ];
169
+ const clean24X = [
170
+ { "name": "I:A", "code": "i", "followedBy": "a", "remove": / *:$/u },
171
+ { "name": "A:B", "code": "a", "followedBy": "b", "remove": / [:;=]$/u },
172
+ { "name": "AB:K", "code": "ab", "followedBy": "k", "remove": / :$/u },
173
+ { "name": "ABK:F", "code": "abk", "followedBy": "f", "remove": /,$/u },
174
+ { "name": "ABFNP:C", "code": "abfnp", "followedBy": "c", "remove": / \/$/u },
175
+ { "name": "ABN:N", "code": "abn", "followedBy": "n", "remove": /\.$/u },
176
+ { "name": "ABNP:#", "code": "abnp", "followedBy": "#", "remove": /\.$/u },
177
+ { "name": "N:P", "code": "n", "followedBy": "p", "remove": /,$/u },
178
+ cleanDotBeforeLanguageSubfieldL
179
+ ];
500
180
  const legalX11Punc = [...legalEntryField, legalX11SpaceColon];
501
181
  const cleanValidPunctuationRules = {
502
- '100': legalX00punc,
503
- '110': legalX10punc,
504
- '111': legalX11Punc,
505
- '130': legalEntryField,
506
- '240': clean24X,
507
- '243': clean24X,
508
- '245': clean24X,
509
- '246': clean24X,
510
- '260': [{
511
- 'code': 'abc',
512
- 'followedBy': 'a',
513
- 'remove': / ;$/u
514
- }, {
515
- 'code': 'a',
516
- 'followedBy': 'b',
517
- 'remove': / :$/u
518
- }, {
519
- 'code': 'b',
520
- 'followedBy': 'c',
521
- 'remove': /,$/u
522
- }, {
523
- 'code': 'c',
524
- 'followedBy': '#',
525
- 'remove': /\.$/u
526
- }, {
527
- 'code': 'd',
528
- 'followedBy': 'e',
529
- 'remove': / :$/u
530
- }, {
531
- 'code': 'e',
532
- 'followedBy': 'f',
533
- 'remove': /,$/u
534
- }, {
535
- 'code': 'f',
536
- 'followedBy': '#',
537
- 'remove': /\.$/u
538
- } // Probably ')' but should it be removed?
182
+ "100": legalX00punc,
183
+ "110": legalX10punc,
184
+ "111": legalX11Punc,
185
+ "130": legalEntryField,
186
+ "240": clean24X,
187
+ "243": clean24X,
188
+ "245": clean24X,
189
+ "246": clean24X,
190
+ "260": [
191
+ { "code": "abc", "followedBy": "a", "remove": / ;$/u },
192
+ { "code": "a", "followedBy": "b", "remove": / :$/u },
193
+ { "code": "b", "followedBy": "c", "remove": /,$/u },
194
+ { "code": "c", "followedBy": "#", "remove": /\.$/u },
195
+ { "code": "d", "followedBy": "e", "remove": / :$/u },
196
+ { "code": "e", "followedBy": "f", "remove": /,$/u },
197
+ { "code": "f", "followedBy": "#", "remove": /\.$/u }
198
+ // Probably ')' but should it be removed?
539
199
  ],
540
- '264': [{
541
- 'code': 'a',
542
- 'followedBy': 'b',
543
- 'remove': / :$/u
544
- }, {
545
- 'code': 'b',
546
- 'followedBy': 'c',
547
- 'remove': /,$/u
548
- }, {
549
- 'code': 'c',
550
- 'followedBy': '#',
551
- 'remove': /\.$/u
552
- }],
553
- '300': [
554
- // NB! Remove crap as well, thus the '*' in / *:$/
555
- {
556
- 'code': 'a',
557
- 'followedBy': 'b',
558
- 'remove': / :$/u
559
- }, {
560
- 'code': 'ab',
561
- 'followedBy': 'c',
562
- 'remove': / ;$/u
563
- }, {
564
- 'code': 'abc',
565
- 'followedBy': 'e',
566
- 'remove': / \+$/u
567
- }],
568
- '490': cleanLegalSeriesTitle,
569
- '534': [{
570
- 'code': 'p',
571
- 'followedBy': 'c',
572
- 'remove': /:$/u
573
- }],
574
- '600': legalX00punc,
575
- '610': legalX10punc,
576
- '611': legalX11Punc,
577
- '630': legalEntryField,
200
+ "264": [
201
+ { "code": "a", "followedBy": "b", "remove": / :$/u },
202
+ { "code": "b", "followedBy": "c", "remove": /,$/u },
203
+ { "code": "c", "followedBy": "#", "remove": /\.$/u }
204
+ ],
205
+ "300": [
206
+ // NB! Remove crap as well, thus the '*' in / *:$/
207
+ { "code": "a", "followedBy": "b", "remove": / :$/u },
208
+ { "code": "ab", "followedBy": "c", "remove": / ;$/u },
209
+ { "code": "abc", "followedBy": "e", "remove": / \+$/u }
210
+ ],
211
+ "490": cleanLegalSeriesTitle,
212
+ "534": [{ "code": "p", "followedBy": "c", "remove": /:$/u }],
213
+ "600": legalX00punc,
214
+ "610": legalX10punc,
215
+ "611": legalX11Punc,
216
+ "630": legalEntryField,
578
217
  // Experimental, MET366-ish (end punc in internationally valid, but we don't use it here in Finland):
579
- '648': [{
580
- 'code': 'a',
581
- 'content': /^[0-9]+\.$/u,
582
- 'ind2': ['4'],
583
- 'remove': /\.$/u
584
- }],
585
- '700': legalX00punc,
586
- '710': legalX10punc,
587
- '711': legalX11Punc,
588
- '730': legalEntryField,
589
- '800': legalX00punc,
590
- '810': legalX10punc,
591
- '811': legalX11Punc,
592
- '830': [...legalEntryField, ...cleanLegalSeriesTitle],
593
- '946': clean24X
218
+ "648": [{ "code": "a", "content": /^[0-9]+\.$/u, "ind2": ["4"], "remove": /\.$/u }],
219
+ "700": legalX00punc,
220
+ "710": legalX10punc,
221
+ "711": legalX11Punc,
222
+ "730": legalEntryField,
223
+ "800": legalX00punc,
224
+ "810": legalX10punc,
225
+ "811": legalX11Punc,
226
+ "830": [...legalEntryField, ...cleanLegalSeriesTitle],
227
+ "946": clean24X
594
228
  };
595
-
596
- // Overgeneralizes a bit: eg. addColonToRelationshipInformation only applies to 700/710 but as others don't have $i, it's fine.
597
229
  const addToAllEntryFields = [addDotBeforeLanguageSubfieldL, addSemicolonBeforeVolumeDesignation, addColonToRelationshipInformation, addEntryFieldFinalDot];
598
230
  const addX00 = [addX00aComma, addX00aComma2, addX00Dot, addX00dComma, ...addToAllEntryFields];
599
231
  const addX10 = [addX10iColon, addX10bDot, addX10eComma, addX10Dot, ...addToAllEntryFields];
600
232
  const addX11 = [...addToAllEntryFields, addX11Spacecolon];
601
233
  const addX30 = [...addToAllEntryFields];
602
- const add24X = [{
603
- 'code': 'i',
604
- 'followedBy': 'a',
605
- 'add': ':',
606
- 'context': needsPuncAfterAlphanumeric
607
- }, {
608
- 'code': 'a',
609
- 'followedBy': 'b',
610
- 'add': ' :',
611
- 'context': '[^:]$'
612
- }, {
613
- 'code': 'abk',
614
- 'followedBy': 'f',
615
- 'add': ',',
616
- 'context': needsPuncAfterAlphanumeric
617
- }, {
618
- 'code': 'abfnp',
619
- 'followedBy': 'c',
620
- 'add': ' /',
621
- 'context': '[^/]$'
622
- }, addDotBeforeLanguageSubfieldL];
623
- const add245 = [...add24X,
624
- // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
625
- {
626
- 'code': 'ab',
627
- 'followedBy': 'n',
628
- 'add': '.',
629
- 'context': needsPuncAfterAlphanumeric
630
- }, {
631
- 'code': 'n',
632
- 'followedBy': 'p',
633
- 'add': ',',
634
- 'context': defaultNeedsPuncAfter2
635
- }, {
636
- 'code': 'abnpc',
637
- 'followedBy': '#',
638
- 'add': '.',
639
- 'context': needsPuncAfterAlphanumeric
640
- } // Stepping on "punctuation validator's" toes
234
+ const add24X = [
235
+ { "code": "i", "followedBy": "a", "add": ":", "context": needsPuncAfterAlphanumeric },
236
+ { "code": "a", "followedBy": "b", "add": " :", "context": "[^:]$" },
237
+ { "code": "abk", "followedBy": "f", "add": ",", "context": needsPuncAfterAlphanumeric },
238
+ { "code": "abfnp", "followedBy": "c", "add": " /", "context": "[^/]$" },
239
+ addDotBeforeLanguageSubfieldL
240
+ ];
241
+ const add245 = [
242
+ ...add24X,
243
+ // Blah! Also "$a = $b" and "$a ; $b" can be valid... But ' :' is better than nothing, I guess...
244
+ { "code": "ab", "followedBy": "n", "add": ".", "context": needsPuncAfterAlphanumeric },
245
+ { "code": "n", "followedBy": "p", "add": ",", "context": defaultNeedsPuncAfter2 },
246
+ { "code": "abnpc", "followedBy": "#", "add": ".", "context": needsPuncAfterAlphanumeric }
247
+ // Stepping on "punctuation validator's" toes
641
248
  ];
642
249
  const addSeriesTitle = [
643
- // 490 and 830
644
- {
645
- 'code': 'a',
646
- 'followedBy': 'a',
647
- 'add': ' =',
648
- 'context': defaultNeedsPuncAfter2
649
- }, {
650
- 'code': 'axyz',
651
- 'followedBy': 'xy',
652
- 'add': ',',
653
- 'context': defaultNeedsPuncAfter2
654
- }, addSemicolonBeforeVolumeDesignation // eg. 490$axyz-$v
250
+ // 490 and 830
251
+ { "code": "a", "followedBy": "a", "add": " =", "context": defaultNeedsPuncAfter2 },
252
+ { "code": "axyz", "followedBy": "xy", "add": ",", "context": defaultNeedsPuncAfter2 },
253
+ addSemicolonBeforeVolumeDesignation
254
+ // eg. 490$axyz-$v
655
255
  ];
656
256
  const addLinkingEntry = [
657
- // NB! Music 773 uses different punctuation rules, that are not implement here (can they even be?)
658
- {
659
- 'code': 'i',
660
- 'followedBy': aToZ,
661
- 'add': ':',
662
- 'context': defaultNeedsPuncAfter2
663
- }, {
664
- 'code': 'a',
665
- 'followedBy': 't',
666
- 'add': '.',
667
- 'context': defaultNeedsPuncAfter2
668
- }, {
669
- 'code': 't',
670
- 'followedBy': 'dghoz',
671
- 'add': '.',
672
- 'context': defaultNeedsPuncAfter2
673
- }];
257
+ // NB! Music 773 uses different punctuation rules, that are not implement here (can they even be?)
258
+ { "code": "i", "followedBy": aToZ, "add": ":", "context": defaultNeedsPuncAfter2 },
259
+ { "code": "a", "followedBy": "t", "add": ".", "context": defaultNeedsPuncAfter2 },
260
+ { "code": "t", "followedBy": "dghoz", "add": ".", "context": defaultNeedsPuncAfter2 }
261
+ ];
674
262
  const addPairedPunctuationRules = {
675
- '100': addX00,
676
- '110': addX10,
677
- '111': addX11,
678
- '130': addX30,
679
- '240': add24X,
680
- '243': add24X,
681
- '245': add245,
682
- '246': add24X,
683
- '260': [{
684
- 'code': 'a',
685
- 'followedBy': 'b',
686
- 'add': ' :',
687
- 'context': defaultNeedsPuncAfter2
688
- }, {
689
- 'code': 'ab',
690
- 'followedBy': 'c',
691
- 'add': ',',
692
- 'context': defaultNeedsPuncAfter2
693
- }, {
694
- 'code': 'abc',
695
- 'followedBy': 'a',
696
- 'add': ' ;',
697
- 'context': defaultNeedsPuncAfter2
698
- }, {
699
- 'code': 'e',
700
- 'followedBy': 'f',
701
- 'add': ' :',
702
- 'context': defaultNeedsPuncAfter2
703
- }, {
704
- 'code': 'f',
705
- 'followedBy': 'g',
706
- 'add': ',',
707
- 'context': defaultNeedsPuncAfter2
708
- }],
709
- '264': [{
710
- 'code': 'a',
711
- 'followedBy': 'b',
712
- 'add': ' :',
713
- 'context': defaultNeedsPuncAfter2
714
- }, {
715
- 'code': 'b',
716
- 'followedBy': 'c',
717
- 'add': ',',
718
- 'context': defaultNeedsPuncAfter2
719
- },
720
- // NB! The $c rule messes dotless exception "264 #4 $c p1983" up
721
- // We'll need to add a hacky postprocessor for this? Add 'hasInd1': '0123' etc?
722
- {
723
- 'code': 'c',
724
- 'followedBy': '#',
725
- 'add': '.',
726
- 'context': needsPuncAfterAlphanumeric,
727
- 'ind2': ['0', '1', '2', '3']
728
- }],
729
- '300': [{
730
- 'code': 'a',
731
- 'followedBy': 'b',
732
- 'add': ' :',
733
- 'context': defaultNeedsPuncAfter2
734
- }, {
735
- 'code': 'ab',
736
- 'followedBy': 'c',
737
- 'add': ' ;',
738
- 'context': defaultNeedsPuncAfter2
739
- }, {
740
- 'code': 'abc',
741
- 'followedBy': 'e',
742
- 'add': ' +',
743
- 'context': defaultNeedsPuncAfter2
744
- }],
745
- '490': addSeriesTitle,
746
- '506': [{
747
- 'code': 'a',
748
- 'followedBy': '#',
749
- 'add': '.',
750
- 'context': defaultNeedsPuncAfter2
751
- }],
752
- '534': [{
753
- 'code': 'p',
754
- 'followedBy': 'c',
755
- 'add': ':',
756
- 'context': defaultNeedsPuncAfter2
757
- }],
758
- '600': addX00,
759
- '610': addX10,
760
- '611': addX11,
761
- '630': addX30,
762
- '700': addX00,
763
- '710': addX10,
764
- '711': addX11,
765
- '730': addX30,
766
- '773': addLinkingEntry,
767
- '787': addLinkingEntry,
768
- '800': addX00,
769
- '810': addX10,
770
- '811': addX11,
771
- '830': [...addX30, ...addSeriesTitle],
772
- '946': [{
773
- 'code': 'i',
774
- 'followedBy': 'a',
775
- 'add': ':',
776
- 'context': defaultNeedsPuncAfter2
777
- }]
263
+ "100": addX00,
264
+ "110": addX10,
265
+ "111": addX11,
266
+ "130": addX30,
267
+ "240": add24X,
268
+ "243": add24X,
269
+ "245": add245,
270
+ "246": add24X,
271
+ "260": [
272
+ { "code": "a", "followedBy": "b", "add": " :", "context": defaultNeedsPuncAfter2 },
273
+ { "code": "ab", "followedBy": "c", "add": ",", "context": defaultNeedsPuncAfter2 },
274
+ { "code": "abc", "followedBy": "a", "add": " ;", "context": defaultNeedsPuncAfter2 },
275
+ { "code": "e", "followedBy": "f", "add": " :", "context": defaultNeedsPuncAfter2 },
276
+ { "code": "f", "followedBy": "g", "add": ",", "context": defaultNeedsPuncAfter2 }
277
+ ],
278
+ "264": [
279
+ { "code": "a", "followedBy": "b", "add": " :", "context": defaultNeedsPuncAfter2 },
280
+ { "code": "b", "followedBy": "c", "add": ",", "context": defaultNeedsPuncAfter2 },
281
+ // NB! The $c rule messes dotless exception "264 #4 $c p1983" up
282
+ // We'll need to add a hacky postprocessor for this? Add 'hasInd1': '0123' etc?
283
+ { "code": "c", "followedBy": "#", "add": ".", "context": needsPuncAfterAlphanumeric, "ind2": ["0", "1", "2", "3"] }
284
+ ],
285
+ "300": [
286
+ { "code": "a", "followedBy": "b", "add": " :", "context": defaultNeedsPuncAfter2 },
287
+ { "code": "ab", "followedBy": "c", "add": " ;", "context": defaultNeedsPuncAfter2 },
288
+ { "code": "abc", "followedBy": "e", "add": " +", "context": defaultNeedsPuncAfter2 }
289
+ ],
290
+ "490": addSeriesTitle,
291
+ "506": [{ "code": "a", "followedBy": "#", "add": ".", "context": defaultNeedsPuncAfter2 }],
292
+ "534": [{ "code": "p", "followedBy": "c", "add": ":", "context": defaultNeedsPuncAfter2 }],
293
+ "600": addX00,
294
+ "610": addX10,
295
+ "611": addX11,
296
+ "630": addX30,
297
+ "700": addX00,
298
+ "710": addX10,
299
+ "711": addX11,
300
+ "730": addX30,
301
+ "773": addLinkingEntry,
302
+ "787": addLinkingEntry,
303
+ "800": addX00,
304
+ "810": addX10,
305
+ "811": addX11,
306
+ "830": [...addX30, ...addSeriesTitle],
307
+ "946": [{ "code": "i", "followedBy": "a", "add": ":", "context": defaultNeedsPuncAfter2 }]
778
308
  };
779
-
780
- /*
781
- function debugRule(rule) {
782
- //nvdebug('');
783
- nvdebug(`NAME ${rule.name ? rule.name : '<unnamed>'}`);
784
- nvdebug(`SUBFIELD CODE '${rule.code}' FOLLOWED BY SUBFIELD CODE '${rule.followedBy}'`);
785
- if ('add' in rule) {
786
- nvdebug(`ADD '${rule.add}'`);
787
- }
788
- if ('remove' in rule) {
789
- nvdebug(`REMOVE '${rule.remove}'`);
790
- }
791
- if ('context' in rule) {
792
- nvdebug(`CONTEXT '${rule.context.toString()}'`);
793
- }
794
- //nvdebug('');
795
- }
796
- */
797
-
798
309
  function ruleAppliesToSubfieldCode(targetSubfieldCodes, currSubfieldCode) {
799
310
  if (!targetSubfieldCodes) {
800
- // We are not interested in what subfield precedes 240$l, ',' is removed anyway
801
311
  return true;
802
312
  }
803
- const negation = targetSubfieldCodes.includes('!');
313
+ const negation = targetSubfieldCodes.includes("!");
804
314
  if (negation) {
805
315
  return !targetSubfieldCodes.includes(currSubfieldCode);
806
316
  }
807
317
  return targetSubfieldCodes.includes(currSubfieldCode);
808
318
  }
809
319
  function ruleAppliesToField(rule, field) {
810
- if ('ind1' in rule && !rule.ind1.includes(field.ind1)) {
320
+ if ("ind1" in rule && !rule.ind1.includes(field.ind1)) {
811
321
  return false;
812
322
  }
813
- if ('ind2' in rule && !rule.ind2.includes(field.ind2)) {
323
+ if ("ind2" in rule && !rule.ind2.includes(field.ind2)) {
814
324
  return false;
815
325
  }
816
-
817
- // If we want to check, say, $2, it should be implemented here!
818
-
819
326
  return true;
820
327
  }
821
328
  function ruleAppliesToCurrentSubfield(rule, subfield) {
822
- //nvdebug(` Apply rule on LHS?`);
823
329
  if (!ruleAppliesToSubfieldCode(rule.code, subfield.code)) {
824
- //nvdebug(` Reject rule!`);
825
330
  return false;
826
331
  }
827
- if ('context' in rule) {
828
- //nvdebug(` Check '${subfield.value}' versus '${rule.context.toString()}'`);
332
+ if ("context" in rule) {
829
333
  if (!subfield.value.match(rule.context)) {
830
- // njsscan-ignore: regex_injection_dos
831
- //nvdebug(` Reject rule!`);
832
334
  return false;
833
335
  }
834
336
  }
835
- //nvdebug(` Apply rule!`);
836
337
  return true;
837
338
  }
838
339
  function ruleAppliesToNextSubfield(rule, nextSubfield) {
839
- if (!('followedBy' in rule)) {
840
- // Return true, if we are not interested in the next subfield
340
+ if (!("followedBy" in rule)) {
841
341
  return true;
842
342
  }
843
- // The '#' existence check applies only to the RHS field. LHS always exists.
844
343
  if (!nextSubfield) {
845
- const negation = rule.followedBy.includes('!');
344
+ const negation = rule.followedBy.includes("!");
846
345
  if (negation) {
847
- return !rule.followedBy.includes('#');
346
+ return !rule.followedBy.includes("#");
848
347
  }
849
- return rule.followedBy.includes('#');
348
+ return rule.followedBy.includes("#");
850
349
  }
851
350
  if (!ruleAppliesToSubfieldCode(rule.followedBy, nextSubfield.code)) {
852
351
  return false;
853
352
  }
854
- if ('contextRHS' in rule && !nextSubfield.value.match(rule.contextRHS)) {
855
- // njsscan-ignore: regex_injection_dos
353
+ if ("contextRHS" in rule && !nextSubfield.value.match(rule.contextRHS)) {
856
354
  return false;
857
355
  }
858
356
  return true;
859
357
  }
860
358
  function checkRule(rule, field, subfield1, subfield2) {
861
359
  if (!ruleAppliesToField(rule, field)) {
862
- //nvdebug(`FAIL ON WHOLE FIELD: '${fieldToString(field)}`);
863
360
  return false;
864
361
  }
865
- //const name = rule.name || 'UNNAMED';
866
362
  if (!ruleAppliesToCurrentSubfield(rule, subfield1)) {
867
- //nvdebug(`${name}: FAIL ON LHS SUBFIELD: '$${subfield1.code} ${subfield1.value}', SF=${rule.code}`, debug);
868
363
  return false;
869
364
  }
870
-
871
- // 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
872
365
  if (!ruleAppliesToNextSubfield(rule, subfield2)) {
873
- //const msg = subfield2 ? `${name}: FAIL ON RHS SUBFIELD '${subfield2.code}' not in [${rule.followedBy}]` : `${name}: FAIL ON RHS FIELD`;
874
- //nvdebug(msg, debug);
875
366
  return false;
876
367
  }
877
-
878
- //nvdebug(`${rule.name ? rule.name : '<unnamed>'}: ACCEPT ${rule.code} (${subfield1.code}), SF2=${rule.followedBy} (${subfield2 ? subfield2.code : '#'})`, debug);
879
368
  return true;
880
369
  }
881
370
  function applyPunctuationRules(field, subfield1, subfield2, ruleArray = null, operation = NONE) {
882
371
  if (operation === NONE || ruleArray === null) {
883
- // !fieldIsApplicable(field, ruleArray)) {
884
372
  return;
885
373
  }
886
- const tag2 = field.tag === '880' ? (0, _subfield6Utils.fieldGetUnambiguousTag)(field) : field.tag;
374
+ const tag2 = field.tag === "880" ? fieldGetUnambiguousTag(field) : field.tag;
887
375
  if (!tag2) {
888
376
  return;
889
377
  }
890
378
  if (!(`${tag2}` in ruleArray)) {
891
379
  return;
892
380
  }
893
-
894
- //nvdebug(`PUNCTUATE ${field.tag}/${tag2} '${subfieldToString(subfield1)}' XXX '${subfield2 ? subfieldToString(subfield2) : '#'} }`);
895
-
896
- //nvdebug(`OP=${operation} ${tag2}: '${subfield1.code}: ${subfield1.value}' ??? '${subfield2 ? subfield2.code : '#'}'`);
897
381
  const candRules = ruleArray[tag2];
898
- candRules.every(rule => {
899
- // uses "every", not "forEach", so that only one rule is applies to the given subfields
900
- //debugRule(rule);
382
+ candRules.every((rule) => {
901
383
  if (!checkRule(rule, field, subfield1, subfield2)) {
902
384
  return true;
903
385
  }
904
-
905
- //const originalValue = subfield1.value;
906
386
  if (rule.remove && [REMOVE, REMOVE_AND_ADD].includes(operation) && subfield1.value.match(rule.remove)) {
907
- //nvdebug(` PUNC REMOVAL TO BE PERFORMED FOR $${subfield1.code} '${subfield1.value}'`, debug);
908
- subfield1.value = subfield1.value.replace(rule.remove, '');
909
- //nvdebug(` PUNC REMOVAL PERFORMED FOR '${subfield1.value}'`);
387
+ subfield1.value = subfield1.value.replace(rule.remove, "");
910
388
  return false;
911
389
  }
912
390
  if (rule.add && [ADD, REMOVE_AND_ADD].includes(operation)) {
913
391
  subfield1.value += rule.add;
914
- //nvdebug(` ADDED '${rule.add}' TO FORM '${subfield1.value}' USING RULE ${rule.name}`);
915
392
  return false;
916
393
  }
917
-
918
- /*
919
- if (subfield1.value !== originalValue) {
920
- nvdebug(` PROCESS PUNC: '‡${subfield1.code} ${originalValue}' => '‡${subfield1.code} ${subfield1.value}'`, debug);
921
- }
922
- */
923
-
924
394
  return true;
925
395
  });
926
396
  }
@@ -929,41 +399,28 @@ function subfieldFixPunctuation(field, subfield1, subfield2) {
929
399
  applyPunctuationRules(field, subfield1, subfield2, addPairedPunctuationRules, ADD);
930
400
  }
931
401
  function subfieldStripPunctuation(field, subfield1, subfield2) {
932
- //nvdebug(`FSP1: '${subfield1.value}'`);
933
402
  applyPunctuationRules(field, subfield1, subfield2, cleanValidPunctuationRules, REMOVE);
934
- //nvdebug(`FSP2: '${subfield1.value}'`);
935
403
  applyPunctuationRules(field, subfield1, subfield2, cleanCrappyPunctuationRules, REMOVE);
936
- //nvdebug(`FSP3: '${subfield1.value}'`);
937
404
  }
938
- function fieldStripPunctuation(field) {
405
+ export function fieldStripPunctuation(field) {
939
406
  if (!field.subfields) {
940
407
  return field;
941
408
  }
942
409
  field.subfields.forEach((sf, i) => {
943
- // NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
944
- // (In plain English: We should skip $0 - $9 at least, maybe $w as well...)
945
410
  subfieldStripPunctuation(field, sf, getNextRelevantSubfield(field, i));
946
411
  });
947
412
  return field;
948
413
  }
949
- function fieldFixPunctuation(field) {
414
+ export function fieldFixPunctuation(field) {
950
415
  if (!field.subfields) {
951
416
  return field;
952
417
  }
953
- //nvdebug(`################### fieldFixPunctuation() TEST ${fieldToString(field)}`);
954
-
955
418
  field.subfields.forEach((sf, i) => {
956
- // NB! instead of next subfield, we should actually get next *non-control-subfield*!!!
957
- // (In plain English: We should skip $0 - $9 at least, maybe $w as well...)
958
- // We'll need some magic for field 257 here, do we? (Also Finnish lexicons vs global lexicons in 65X fields)
959
419
  subfieldFixPunctuation(field, sf, getNextRelevantSubfield(field, i));
960
420
  });
961
-
962
- // Use shared code for final punctuation (sadly this does not fix intermediate punc):
963
421
  if (field.useExternalEndPunctuation) {
964
- // addFinalPunctuation(field); // local version. use shared code instead.
965
- (0, _endingPunctuation.validateSingleField)(field, false, true); // NB! Don't use field.tag as second argument! It's a string, not an int. 3rd arg must be true (=fix)
422
+ validateSingleField(field, false, true);
966
423
  }
967
424
  return field;
968
425
  }
969
- //# sourceMappingURL=punctuation2.js.map
426
+ //# sourceMappingURL=punctuation2.js.map