@natlibfi/marc-record-validators-melinda 3.2.0 → 3.3.14-alpha.3

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 (593) hide show
  1. package/.github/CODEOWNERS +2 -0
  2. package/.github/dependabot.yml +40 -0
  3. package/.github/workflows/melinda-node-tests.yml +61 -0
  4. package/LICENSE.txt +21 -661
  5. package/README.md +4 -5
  6. package/dist/access-rights.js +94 -0
  7. package/dist/access-rights.js.map +1 -0
  8. package/dist/access-rights.spec.js +150 -0
  9. package/dist/access-rights.spec.js.map +1 -0
  10. package/dist/double-commas.js +17 -27
  11. package/dist/double-commas.js.map +1 -1
  12. package/dist/double-commas.spec.js +72 -27
  13. package/dist/double-commas.spec.js.map +1 -1
  14. package/dist/duplicates-ind1.js +47 -27
  15. package/dist/duplicates-ind1.js.map +1 -1
  16. package/dist/duplicates-ind1.spec.js +44 -27
  17. package/dist/duplicates-ind1.spec.js.map +1 -1
  18. package/dist/empty-fields.js +79 -29
  19. package/dist/empty-fields.js.map +1 -1
  20. package/dist/empty-fields.spec.js +113 -27
  21. package/dist/empty-fields.spec.js.map +1 -1
  22. package/dist/ending-punctuation-conf.js +772 -129
  23. package/dist/ending-punctuation-conf.js.map +1 -1
  24. package/dist/ending-punctuation.js +291 -72
  25. package/dist/ending-punctuation.js.map +1 -1
  26. package/dist/ending-punctuation.spec.js +2638 -118
  27. package/dist/ending-punctuation.spec.js.map +1 -1
  28. package/dist/ending-whitespace.js +58 -0
  29. package/dist/ending-whitespace.js.map +1 -0
  30. package/dist/ending-whitespace.spec.js +42 -0
  31. package/dist/ending-whitespace.spec.js.map +1 -0
  32. package/dist/field-521-fix.js +96 -0
  33. package/dist/field-521-fix.js.map +1 -0
  34. package/dist/field-521-fix.spec.js +51 -0
  35. package/dist/field-521-fix.spec.js.map +1 -0
  36. package/dist/field-exclusion.js +214 -63
  37. package/dist/field-exclusion.js.map +1 -1
  38. package/dist/field-exclusion.spec.js +1057 -31
  39. package/dist/field-exclusion.spec.js.map +1 -1
  40. package/dist/field-structure.js +249 -78
  41. package/dist/field-structure.js.map +1 -1
  42. package/dist/field-structure.spec.js +534 -31
  43. package/dist/field-structure.spec.js.map +1 -1
  44. package/dist/fields-present.js +31 -27
  45. package/dist/fields-present.js.map +1 -1
  46. package/dist/fields-present.spec.js +120 -27
  47. package/dist/fields-present.spec.js.map +1 -1
  48. package/dist/fixed-fields.js +72 -27
  49. package/dist/fixed-fields.js.map +1 -1
  50. package/dist/fixed-fields.spec.js +139 -27
  51. package/dist/fixed-fields.spec.js.map +1 -1
  52. package/dist/identical-fields.js +42 -28
  53. package/dist/identical-fields.js.map +1 -1
  54. package/dist/identical-fields.spec.js +98 -27
  55. package/dist/identical-fields.spec.js.map +1 -1
  56. package/dist/index.js +202 -27
  57. package/dist/index.js.map +1 -1
  58. package/dist/indicator-fixes.js +191 -0
  59. package/dist/indicator-fixes.js.map +1 -0
  60. package/dist/indicator-fixes.spec.js +51 -0
  61. package/dist/indicator-fixes.spec.js.map +1 -0
  62. package/dist/isbn-issn.js +266 -27
  63. package/dist/isbn-issn.js.map +1 -1
  64. package/dist/isbn-issn.spec.js +594 -27
  65. package/dist/isbn-issn.spec.js.map +1 -1
  66. package/dist/item-language.js +171 -27
  67. package/dist/item-language.js.map +1 -1
  68. package/dist/item-language.spec.js +305 -27
  69. package/dist/item-language.spec.js.map +1 -1
  70. package/dist/mergeField500Lisapainokset.js +155 -0
  71. package/dist/mergeField500Lisapainokset.js.map +1 -0
  72. package/dist/mergeField500Lisapainokset.spec.js +51 -0
  73. package/dist/mergeField500Lisapainokset.spec.js.map +1 -0
  74. package/dist/mergeRelatorTermFields.js +140 -0
  75. package/dist/mergeRelatorTermFields.js.map +1 -0
  76. package/dist/mergeRelatorTermFields.spec.js +51 -0
  77. package/dist/mergeRelatorTermFields.spec.js.map +1 -0
  78. package/dist/multiple-subfield-0.js +120 -0
  79. package/dist/multiple-subfield-0.js.map +1 -0
  80. package/dist/multiple-subfield-0.spec.js +51 -0
  81. package/dist/multiple-subfield-0.spec.js.map +1 -0
  82. package/dist/non-breaking-space.js +61 -0
  83. package/dist/non-breaking-space.js.map +1 -0
  84. package/dist/non-breaking-space.spec.js +42 -0
  85. package/dist/non-breaking-space.spec.js.map +1 -0
  86. package/dist/normalize-identifiers.js +210 -0
  87. package/dist/normalize-identifiers.js.map +1 -0
  88. package/dist/normalize-identifiers.spec.js +51 -0
  89. package/dist/normalize-identifiers.spec.js.map +1 -0
  90. package/dist/normalize-utf8-diacritics.js +140 -0
  91. package/dist/normalize-utf8-diacritics.js.map +1 -0
  92. package/dist/normalize-utf8-diacritics.spec.js +51 -0
  93. package/dist/normalize-utf8-diacritics.spec.js.map +1 -0
  94. package/dist/punctuation/index.js +281 -0
  95. package/dist/punctuation/index.js.map +1 -0
  96. package/dist/punctuation/rules/aut.js +332 -0
  97. package/dist/punctuation/rules/aut.js.map +1 -0
  98. package/dist/punctuation/rules/bib.js +374 -0
  99. package/dist/punctuation/rules/bib.js.map +1 -0
  100. package/dist/punctuation/rules/index.js +21 -0
  101. package/dist/punctuation/rules/index.js.map +1 -0
  102. package/dist/punctuation.spec.js +51 -0
  103. package/dist/punctuation.spec.js.map +1 -0
  104. package/dist/punctuation2.js +726 -0
  105. package/dist/punctuation2.js.map +1 -0
  106. package/dist/punctuation2.spec.js +51 -0
  107. package/dist/punctuation2.spec.js.map +1 -0
  108. package/dist/reindexSubfield6OccurenceNumbers.js +199 -0
  109. package/dist/reindexSubfield6OccurenceNumbers.js.map +1 -0
  110. package/dist/reindexSubfield6OccurenceNumbers.spec.js +51 -0
  111. package/dist/reindexSubfield6OccurenceNumbers.spec.js.map +1 -0
  112. package/dist/removeDuplicateDataFields.js +405 -0
  113. package/dist/removeDuplicateDataFields.js.map +1 -0
  114. package/dist/removeDuplicateDataFields.spec.js +51 -0
  115. package/dist/removeDuplicateDataFields.spec.js.map +1 -0
  116. package/dist/removeInferiorDataFields.js +245 -0
  117. package/dist/removeInferiorDataFields.js.map +1 -0
  118. package/dist/removeInferiorDataFields.spec.js +51 -0
  119. package/dist/removeInferiorDataFields.spec.js.map +1 -0
  120. package/dist/resolvable-ext-references-melinda.js +112 -31
  121. package/dist/resolvable-ext-references-melinda.js.map +1 -1
  122. package/dist/resolvable-ext-references-melinda.spec.js +166 -27
  123. package/dist/resolvable-ext-references-melinda.spec.js.map +1 -1
  124. package/dist/resolveOrphanedSubfield6s.js +116 -0
  125. package/dist/resolveOrphanedSubfield6s.js.map +1 -0
  126. package/dist/resolveOrphanedSubfield6s.spec.js +51 -0
  127. package/dist/resolveOrphanedSubfield6s.spec.js.map +1 -0
  128. package/dist/sanitize-vocabulary-source-codes.js +93 -0
  129. package/dist/sanitize-vocabulary-source-codes.js.map +1 -0
  130. package/dist/sanitize-vocabulary-source-codes.spec.js +51 -0
  131. package/dist/sanitize-vocabulary-source-codes.spec.js.map +1 -0
  132. package/dist/sort-tags.js +53 -27
  133. package/dist/sort-tags.js.map +1 -1
  134. package/dist/sort-tags.spec.js +206 -27
  135. package/dist/sort-tags.spec.js.map +1 -1
  136. package/dist/sortRelatorTerms.js +135 -0
  137. package/dist/sortRelatorTerms.js.map +1 -0
  138. package/dist/sortRelatorTerms.spec.js +51 -0
  139. package/dist/sortRelatorTerms.spec.js.map +1 -0
  140. package/dist/sortSubfields.js +279 -0
  141. package/dist/sortSubfields.js.map +1 -0
  142. package/dist/sortSubfields.spec.js +51 -0
  143. package/dist/sortSubfields.spec.js.map +1 -0
  144. package/dist/stripPunctuation.js +49 -0
  145. package/dist/stripPunctuation.js.map +1 -0
  146. package/dist/stripPunctuation.spec.js +51 -0
  147. package/dist/stripPunctuation.spec.js.map +1 -0
  148. package/dist/subfield-exclusion.js +174 -57
  149. package/dist/subfield-exclusion.js.map +1 -1
  150. package/dist/subfield-exclusion.spec.js +521 -31
  151. package/dist/subfield-exclusion.spec.js.map +1 -1
  152. package/dist/subfield6Utils.js +457 -0
  153. package/dist/subfield6Utils.js.map +1 -0
  154. package/dist/subfield8Utils.js +99 -0
  155. package/dist/subfield8Utils.js.map +1 -0
  156. package/dist/typeOfDate-008.js +48 -0
  157. package/dist/typeOfDate-008.js.map +1 -0
  158. package/dist/typeOfDate-008.spec.js +47 -0
  159. package/dist/typeOfDate-008.spec.js.map +1 -0
  160. package/dist/unicode-decomposition.js +139 -30
  161. package/dist/unicode-decomposition.js.map +1 -1
  162. package/dist/unicode-decomposition.spec.js +90 -27
  163. package/dist/unicode-decomposition.spec.js.map +1 -1
  164. package/dist/update-field-540.js +119 -0
  165. package/dist/update-field-540.js.map +1 -0
  166. package/dist/update-field-540.spec.js +51 -0
  167. package/dist/update-field-540.spec.js.map +1 -0
  168. package/dist/urn.js +185 -0
  169. package/dist/urn.js.map +1 -0
  170. package/dist/urn.spec.js +238 -0
  171. package/dist/urn.spec.js.map +1 -0
  172. package/dist/utils.js +58 -0
  173. package/dist/utils.js.map +1 -0
  174. package/package.json +114 -124
  175. package/src/access-rights.js +84 -0
  176. package/src/access-rights.spec.js +126 -0
  177. package/src/double-commas.js +12 -49
  178. package/src/double-commas.spec.js +50 -82
  179. package/src/duplicates-ind1.js +34 -74
  180. package/src/duplicates-ind1.spec.js +39 -117
  181. package/src/empty-fields.js +62 -74
  182. package/src/empty-fields.spec.js +134 -207
  183. package/src/ending-punctuation-conf.js +679 -644
  184. package/src/ending-punctuation.js +260 -250
  185. package/src/ending-punctuation.spec.js +2545 -2322
  186. package/src/ending-whitespace.js +40 -0
  187. package/src/ending-whitespace.spec.js +44 -0
  188. package/src/field-521-fix.js +92 -0
  189. package/src/field-521-fix.spec.js +52 -0
  190. package/src/field-exclusion.js +197 -215
  191. package/src/field-exclusion.spec.js +883 -481
  192. package/src/field-structure.js +213 -271
  193. package/src/field-structure.spec.js +597 -474
  194. package/src/fields-present.js +19 -49
  195. package/src/fields-present.spec.js +90 -91
  196. package/src/fixed-fields.js +61 -94
  197. package/src/fixed-fields.spec.js +81 -125
  198. package/src/identical-fields.js +29 -48
  199. package/src/identical-fields.spec.js +114 -146
  200. package/src/index.js +41 -46
  201. package/src/indicator-fixes.js +211 -0
  202. package/src/indicator-fixes.spec.js +52 -0
  203. package/src/isbn-issn.js +254 -106
  204. package/src/isbn-issn.spec.js +399 -172
  205. package/src/item-language.js +158 -195
  206. package/src/item-language.spec.js +314 -306
  207. package/src/mergeField500Lisapainokset.js +153 -0
  208. package/src/mergeField500Lisapainokset.spec.js +52 -0
  209. package/src/mergeRelatorTermFields.js +143 -0
  210. package/src/mergeRelatorTermFields.spec.js +52 -0
  211. package/src/multiple-subfield-0.js +129 -0
  212. package/src/multiple-subfield-0.spec.js +52 -0
  213. package/src/non-breaking-space.js +49 -0
  214. package/src/non-breaking-space.spec.js +44 -0
  215. package/src/normalize-identifiers.js +197 -0
  216. package/src/normalize-identifiers.spec.js +52 -0
  217. package/src/normalize-utf8-diacritics.js +141 -0
  218. package/src/normalize-utf8-diacritics.spec.js +52 -0
  219. package/src/punctuation/index.js +292 -0
  220. package/src/punctuation/rules/aut.js +372 -0
  221. package/src/punctuation/rules/bib.js +420 -0
  222. package/src/punctuation/rules/index.js +7 -0
  223. package/src/punctuation.spec.js +52 -0
  224. package/src/punctuation2.js +441 -0
  225. package/src/punctuation2.spec.js +52 -0
  226. package/src/reindexSubfield6OccurenceNumbers.js +210 -0
  227. package/src/reindexSubfield6OccurenceNumbers.spec.js +52 -0
  228. package/src/removeDuplicateDataFields.js +447 -0
  229. package/src/removeDuplicateDataFields.spec.js +52 -0
  230. package/src/removeInferiorDataFields.js +259 -0
  231. package/src/removeInferiorDataFields.spec.js +52 -0
  232. package/src/resolvable-ext-references-melinda.js +89 -122
  233. package/src/resolvable-ext-references-melinda.spec.js +168 -198
  234. package/src/resolveOrphanedSubfield6s.js +115 -0
  235. package/src/resolveOrphanedSubfield6s.spec.js +52 -0
  236. package/src/sanitize-vocabulary-source-codes.js +99 -0
  237. package/src/sanitize-vocabulary-source-codes.spec.js +52 -0
  238. package/src/sort-tags.js +34 -60
  239. package/src/sort-tags.spec.js +256 -290
  240. package/src/sortRelatorTerms.js +142 -0
  241. package/src/sortRelatorTerms.spec.js +52 -0
  242. package/src/sortSubfields.js +176 -0
  243. package/src/sortSubfields.spec.js +52 -0
  244. package/src/stripPunctuation.js +42 -0
  245. package/src/stripPunctuation.spec.js +52 -0
  246. package/src/subfield-exclusion.js +157 -180
  247. package/src/subfield-exclusion.spec.js +507 -453
  248. package/src/subfield6Utils.js +485 -0
  249. package/src/subfield8Utils.js +102 -0
  250. package/src/typeOfDate-008.js +40 -0
  251. package/src/typeOfDate-008.spec.js +47 -0
  252. package/src/unicode-decomposition.js +130 -145
  253. package/src/unicode-decomposition.spec.js +89 -115
  254. package/src/update-field-540.js +99 -0
  255. package/src/update-field-540.spec.js +52 -0
  256. package/src/urn.js +164 -0
  257. package/src/urn.spec.js +231 -0
  258. package/src/utils.js +52 -0
  259. package/test-fixtures/duplicates-ind1/01/expectedResult.json +4 -0
  260. package/test-fixtures/duplicates-ind1/01/metadata.json +4 -0
  261. package/test-fixtures/duplicates-ind1/01/record.json +16 -0
  262. package/test-fixtures/duplicates-ind1/02/expectedResult.json +6 -0
  263. package/test-fixtures/duplicates-ind1/02/metadata.json +4 -0
  264. package/test-fixtures/duplicates-ind1/02/record.json +16 -0
  265. package/test-fixtures/duplicates-ind1/03/expectedResult.json +13 -0
  266. package/test-fixtures/duplicates-ind1/03/metadata.json +6 -0
  267. package/test-fixtures/duplicates-ind1/03/record.json +16 -0
  268. package/test-fixtures/ending-whitespace/01/expectedResult.json +4 -0
  269. package/test-fixtures/ending-whitespace/01/metadata.json +6 -0
  270. package/test-fixtures/ending-whitespace/01/record.json +15 -0
  271. package/test-fixtures/ending-whitespace/02/expectedResult.json +4 -0
  272. package/test-fixtures/ending-whitespace/02/metadata.json +6 -0
  273. package/test-fixtures/ending-whitespace/02/record.json +15 -0
  274. package/test-fixtures/ending-whitespace/03/expectedResult.json +17 -0
  275. package/test-fixtures/ending-whitespace/03/metadata.json +6 -0
  276. package/test-fixtures/ending-whitespace/03/record.json +15 -0
  277. package/test-fixtures/ending-whitespace/04/expectedResult.json +10 -0
  278. package/test-fixtures/ending-whitespace/04/metadata.json +6 -0
  279. package/test-fixtures/ending-whitespace/04/record.json +8 -0
  280. package/test-fixtures/fix521/01/expectedResult.json +6 -0
  281. package/test-fixtures/fix521/01/metadata.json +5 -0
  282. package/test-fixtures/fix521/01/record.json +13 -0
  283. package/test-fixtures/fix521/02/expectedResult.json +15 -0
  284. package/test-fixtures/fix521/02/metadata.json +5 -0
  285. package/test-fixtures/fix521/02/record.json +13 -0
  286. package/test-fixtures/fix521/03/expectedResult.json +5 -0
  287. package/test-fixtures/fix521/03/metadata.json +5 -0
  288. package/test-fixtures/fix521/03/record.json +13 -0
  289. package/test-fixtures/indicator-fixes/01/expectedResult.json +9 -0
  290. package/test-fixtures/indicator-fixes/01/metadata.json +5 -0
  291. package/test-fixtures/indicator-fixes/01/record.json +64 -0
  292. package/test-fixtures/indicator-fixes/02/expectedResult.json +66 -0
  293. package/test-fixtures/indicator-fixes/02/metadata.json +5 -0
  294. package/test-fixtures/indicator-fixes/02/record.json +64 -0
  295. package/test-fixtures/indicator-fixes/03/expectedResult.json +55 -0
  296. package/test-fixtures/indicator-fixes/03/metadata.json +5 -0
  297. package/test-fixtures/indicator-fixes/03/record.json +54 -0
  298. package/test-fixtures/indicator-fixes/04/expectedResult.json +66 -0
  299. package/test-fixtures/indicator-fixes/04/metadata.json +5 -0
  300. package/test-fixtures/indicator-fixes/04/record.json +65 -0
  301. package/test-fixtures/indicator-fixes/05/expectedResult.json +66 -0
  302. package/test-fixtures/indicator-fixes/05/metadata.json +5 -0
  303. package/test-fixtures/indicator-fixes/05/record.json +65 -0
  304. package/test-fixtures/indicator-fixes/06/expectedResult.json +75 -0
  305. package/test-fixtures/indicator-fixes/06/metadata.json +5 -0
  306. package/test-fixtures/indicator-fixes/06/record.json +74 -0
  307. package/test-fixtures/lisapainokset/fixer/01/expectedResult.json +37 -0
  308. package/test-fixtures/lisapainokset/fixer/01/metadata.json +6 -0
  309. package/test-fixtures/lisapainokset/fixer/01/record.json +61 -0
  310. package/test-fixtures/lisapainokset/fixer/02/expectedResult.json +44 -0
  311. package/test-fixtures/lisapainokset/fixer/02/metadata.json +6 -0
  312. package/test-fixtures/lisapainokset/fixer/02/record.json +45 -0
  313. package/test-fixtures/lisapainokset/fixer/03/expectedResult.json +21 -0
  314. package/test-fixtures/lisapainokset/fixer/03/metadata.json +6 -0
  315. package/test-fixtures/lisapainokset/fixer/03/record.json +45 -0
  316. package/test-fixtures/lisapainokset/validator/01/expectedResult.json +7 -0
  317. package/test-fixtures/lisapainokset/validator/01/metadata.json +6 -0
  318. package/test-fixtures/lisapainokset/validator/01/record.json +45 -0
  319. package/test-fixtures/lisapainokset/validator/02/expectedResult.json +6 -0
  320. package/test-fixtures/lisapainokset/validator/02/metadata.json +6 -0
  321. package/test-fixtures/lisapainokset/validator/02/record.json +61 -0
  322. package/test-fixtures/lisapainokset/validator/03/expectedResult.json +4 -0
  323. package/test-fixtures/lisapainokset/validator/03/metadata.json +6 -0
  324. package/test-fixtures/lisapainokset/validator/03/record.json +37 -0
  325. package/test-fixtures/mergeRelatorTermFields/fixer/01/expectedResult.json +14 -0
  326. package/test-fixtures/mergeRelatorTermFields/fixer/01/metadata.json +6 -0
  327. package/test-fixtures/mergeRelatorTermFields/fixer/01/record.json +16 -0
  328. package/test-fixtures/mergeRelatorTermFields/fixer/02/expectedResult.json +17 -0
  329. package/test-fixtures/mergeRelatorTermFields/fixer/02/metadata.json +6 -0
  330. package/test-fixtures/mergeRelatorTermFields/fixer/02/record.json +23 -0
  331. package/test-fixtures/mergeRelatorTermFields/validator/01/expectedResult.json +6 -0
  332. package/test-fixtures/mergeRelatorTermFields/validator/01/metadata.json +6 -0
  333. package/test-fixtures/mergeRelatorTermFields/validator/01/record.json +16 -0
  334. package/test-fixtures/mergeRelatorTermFields/validator/02/expectedResult.json +4 -0
  335. package/test-fixtures/mergeRelatorTermFields/validator/02/metadata.json +6 -0
  336. package/test-fixtures/mergeRelatorTermFields/validator/02/record.json +16 -0
  337. package/test-fixtures/non-breaking-space/01/expectedResult.json +4 -0
  338. package/test-fixtures/non-breaking-space/01/metadata.json +6 -0
  339. package/test-fixtures/non-breaking-space/01/record.json +15 -0
  340. package/test-fixtures/non-breaking-space/02/expectedResult.json +4 -0
  341. package/test-fixtures/non-breaking-space/02/metadata.json +6 -0
  342. package/test-fixtures/non-breaking-space/02/record.json +15 -0
  343. package/test-fixtures/non-breaking-space/03/expectedResult.json +17 -0
  344. package/test-fixtures/non-breaking-space/03/metadata.json +6 -0
  345. package/test-fixtures/non-breaking-space/03/record.json +15 -0
  346. package/test-fixtures/non-breaking-space/04/expectedResult.json +21 -0
  347. package/test-fixtures/non-breaking-space/04/metadata.json +6 -0
  348. package/test-fixtures/non-breaking-space/04/record.json +19 -0
  349. package/test-fixtures/normalize-identifiers/01/expectedResult.json +8 -0
  350. package/test-fixtures/normalize-identifiers/01/metadata.json +5 -0
  351. package/test-fixtures/normalize-identifiers/01/record.json +81 -0
  352. package/test-fixtures/normalize-identifiers/02/expectedResult.json +92 -0
  353. package/test-fixtures/normalize-identifiers/02/metadata.json +5 -0
  354. package/test-fixtures/normalize-identifiers/02/record.json +92 -0
  355. package/test-fixtures/normalize-identifiers/03/expectedResult.json +63 -0
  356. package/test-fixtures/normalize-identifiers/03/metadata.json +5 -0
  357. package/test-fixtures/normalize-identifiers/03/record.json +61 -0
  358. package/test-fixtures/normalize-identifiers/04/expectedResult.json +79 -0
  359. package/test-fixtures/normalize-identifiers/04/metadata.json +5 -0
  360. package/test-fixtures/normalize-identifiers/04/record.json +77 -0
  361. package/test-fixtures/normalize-utf8-diacritics/01/expectedResult.json +7 -0
  362. package/test-fixtures/normalize-utf8-diacritics/01/metadata.json +5 -0
  363. package/test-fixtures/normalize-utf8-diacritics/01/record.json +39 -0
  364. package/test-fixtures/normalize-utf8-diacritics/02/expectedResult.json +41 -0
  365. package/test-fixtures/normalize-utf8-diacritics/02/metadata.json +5 -0
  366. package/test-fixtures/normalize-utf8-diacritics/02/record.json +39 -0
  367. package/test-fixtures/normalize-utf8-diacritics/03/expectedResult.json +5 -0
  368. package/test-fixtures/normalize-utf8-diacritics/03/metadata.json +5 -0
  369. package/test-fixtures/normalize-utf8-diacritics/03/record.json +37 -0
  370. package/test-fixtures/normalize-utf8-diacritics/04/expectedResult.json +41 -0
  371. package/test-fixtures/normalize-utf8-diacritics/04/metadata.json +5 -0
  372. package/test-fixtures/normalize-utf8-diacritics/04/record.json +39 -0
  373. package/test-fixtures/normalize-utf8-diacritics/05/expectedResult.json +41 -0
  374. package/test-fixtures/normalize-utf8-diacritics/05/metadata.json +5 -0
  375. package/test-fixtures/normalize-utf8-diacritics/05/record.json +41 -0
  376. package/test-fixtures/punctuation/01/expectedResult.json +3 -0
  377. package/test-fixtures/punctuation/01/metadata.json +4 -0
  378. package/test-fixtures/punctuation/01/record.json +18 -0
  379. package/test-fixtures/punctuation/02/expectedResult.json +3 -0
  380. package/test-fixtures/punctuation/02/metadata.json +4 -0
  381. package/test-fixtures/punctuation/02/record.json +18 -0
  382. package/test-fixtures/punctuation/03/expectedResult.json +21 -0
  383. package/test-fixtures/punctuation/03/metadata.json +5 -0
  384. package/test-fixtures/punctuation/03/record.json +19 -0
  385. package/test-fixtures/punctuation/04/expectedResult.json +21 -0
  386. package/test-fixtures/punctuation/04/metadata.json +5 -0
  387. package/test-fixtures/punctuation/04/record.json +19 -0
  388. package/test-fixtures/punctuation/05/expectedResult.json +44 -0
  389. package/test-fixtures/punctuation/05/metadata.json +5 -0
  390. package/test-fixtures/punctuation/05/record.json +42 -0
  391. package/test-fixtures/punctuation2/01/expectedResult.json +12 -0
  392. package/test-fixtures/punctuation2/01/metadata.json +6 -0
  393. package/test-fixtures/punctuation2/01/record.json +37 -0
  394. package/test-fixtures/punctuation2/02/expectedResult.json +4 -0
  395. package/test-fixtures/punctuation2/02/metadata.json +6 -0
  396. package/test-fixtures/punctuation2/02/record.json +14 -0
  397. package/test-fixtures/punctuation2/04/expectedResult.json +7 -0
  398. package/test-fixtures/punctuation2/04/metadata.json +6 -0
  399. package/test-fixtures/punctuation2/04/record.json +22 -0
  400. package/test-fixtures/punctuation2/05/expectedResult.json +6 -0
  401. package/test-fixtures/punctuation2/05/metadata.json +6 -0
  402. package/test-fixtures/punctuation2/05/record.json +12 -0
  403. package/test-fixtures/punctuation2/98/expectedResult.json +45 -0
  404. package/test-fixtures/punctuation2/98/metadata.json +6 -0
  405. package/test-fixtures/punctuation2/98/record.json +43 -0
  406. package/test-fixtures/punctuation2/99/expectedResult.json +15 -0
  407. package/test-fixtures/punctuation2/99/metadata.json +6 -0
  408. package/test-fixtures/punctuation2/99/record.json +14 -0
  409. package/test-fixtures/reindex-sf6-occurence-numbers/f01/expectedResult.json +35 -0
  410. package/test-fixtures/reindex-sf6-occurence-numbers/f01/metadata.json +6 -0
  411. package/test-fixtures/reindex-sf6-occurence-numbers/f01/record.json +34 -0
  412. package/test-fixtures/reindex-sf6-occurence-numbers/f02/expectedResult.json +53 -0
  413. package/test-fixtures/reindex-sf6-occurence-numbers/f02/metadata.json +6 -0
  414. package/test-fixtures/reindex-sf6-occurence-numbers/f02/record.json +51 -0
  415. package/test-fixtures/reindex-sf6-occurence-numbers/f03/expectedResult.json +46 -0
  416. package/test-fixtures/reindex-sf6-occurence-numbers/f03/metadata.json +7 -0
  417. package/test-fixtures/reindex-sf6-occurence-numbers/f03/record.json +44 -0
  418. package/test-fixtures/reindex-sf6-occurence-numbers/v01/expectedResult.json +6 -0
  419. package/test-fixtures/reindex-sf6-occurence-numbers/v01/metadata.json +5 -0
  420. package/test-fixtures/reindex-sf6-occurence-numbers/v01/record.json +31 -0
  421. package/test-fixtures/reindex-sf6-occurence-numbers/v02/expectedResult.json +6 -0
  422. package/test-fixtures/reindex-sf6-occurence-numbers/v02/metadata.json +6 -0
  423. package/test-fixtures/reindex-sf6-occurence-numbers/v02/record.json +38 -0
  424. package/test-fixtures/reindex-sf6-occurence-numbers/v03/expectedResult.json +6 -0
  425. package/test-fixtures/reindex-sf6-occurence-numbers/v03/metadata.json +6 -0
  426. package/test-fixtures/reindex-sf6-occurence-numbers/v03/record.json +30 -0
  427. package/test-fixtures/remove-duplicate-datafields/f01/expectedResult.json +35 -0
  428. package/test-fixtures/remove-duplicate-datafields/f01/metadata.json +6 -0
  429. package/test-fixtures/remove-duplicate-datafields/f01/record.json +34 -0
  430. package/test-fixtures/remove-duplicate-datafields/f03/expectedResult.json +20 -0
  431. package/test-fixtures/remove-duplicate-datafields/f03/metadata.json +6 -0
  432. package/test-fixtures/remove-duplicate-datafields/f03/record.json +33 -0
  433. package/test-fixtures/remove-duplicate-datafields/f03b/expectedResult.json +20 -0
  434. package/test-fixtures/remove-duplicate-datafields/f03b/metadata.json +6 -0
  435. package/test-fixtures/remove-duplicate-datafields/f03b/record.json +35 -0
  436. package/test-fixtures/remove-duplicate-datafields/f03c/expectedResult.json +25 -0
  437. package/test-fixtures/remove-duplicate-datafields/f03c/metadata.json +6 -0
  438. package/test-fixtures/remove-duplicate-datafields/f03c/record.json +43 -0
  439. package/test-fixtures/remove-duplicate-datafields/f04/expectedResult.json +31 -0
  440. package/test-fixtures/remove-duplicate-datafields/f04/metadata.json +6 -0
  441. package/test-fixtures/remove-duplicate-datafields/f04/record.json +41 -0
  442. package/test-fixtures/remove-duplicate-datafields/f05/expectedResult.json +23 -0
  443. package/test-fixtures/remove-duplicate-datafields/f05/metadata.json +6 -0
  444. package/test-fixtures/remove-duplicate-datafields/f05/record.json +29 -0
  445. package/test-fixtures/remove-duplicate-datafields/f06/expectedResult.json +24 -0
  446. package/test-fixtures/remove-duplicate-datafields/f06/metadata.json +6 -0
  447. package/test-fixtures/remove-duplicate-datafields/f06/record.json +41 -0
  448. package/test-fixtures/remove-duplicate-datafields/f07/expectedResult.json +15 -0
  449. package/test-fixtures/remove-duplicate-datafields/f07/metadata.json +6 -0
  450. package/test-fixtures/remove-duplicate-datafields/f07/record.json +21 -0
  451. package/test-fixtures/remove-duplicate-datafields/f08/expectedResult.json +21 -0
  452. package/test-fixtures/remove-duplicate-datafields/f08/metadata.json +6 -0
  453. package/test-fixtures/remove-duplicate-datafields/f08/record.json +33 -0
  454. package/test-fixtures/remove-duplicate-datafields/f09/expectedResult.json +6 -0
  455. package/test-fixtures/remove-duplicate-datafields/f09/metadata.json +6 -0
  456. package/test-fixtures/remove-duplicate-datafields/f09/record.json +9 -0
  457. package/test-fixtures/remove-duplicate-datafields/f10/expectedResult.json +15 -0
  458. package/test-fixtures/remove-duplicate-datafields/f10/metadata.json +6 -0
  459. package/test-fixtures/remove-duplicate-datafields/f10/record.json +24 -0
  460. package/test-fixtures/remove-duplicate-datafields/f11/expectedResult.json +30 -0
  461. package/test-fixtures/remove-duplicate-datafields/f11/metadata.json +6 -0
  462. package/test-fixtures/remove-duplicate-datafields/f11/record.json +53 -0
  463. package/test-fixtures/remove-duplicate-datafields/v01/expectedResult.json +6 -0
  464. package/test-fixtures/remove-duplicate-datafields/v01/metadata.json +6 -0
  465. package/test-fixtures/remove-duplicate-datafields/v01/record.json +31 -0
  466. package/test-fixtures/remove-duplicate-datafields/v02/expectedResult.json +10 -0
  467. package/test-fixtures/remove-duplicate-datafields/v02/metadata.json +6 -0
  468. package/test-fixtures/remove-duplicate-datafields/v02/record.json +45 -0
  469. package/test-fixtures/remove-duplicate-datafields/v03/expectedResult.json +6 -0
  470. package/test-fixtures/remove-duplicate-datafields/v03/metadata.json +7 -0
  471. package/test-fixtures/remove-duplicate-datafields/v03/record.json +37 -0
  472. package/test-fixtures/remove-duplicate-datafields/v04/expectedResult.json +8 -0
  473. package/test-fixtures/remove-duplicate-datafields/v04/metadata.json +6 -0
  474. package/test-fixtures/remove-duplicate-datafields/v04/record.json +41 -0
  475. package/test-fixtures/remove-inferior-datafields/f01/expectedResult.json +21 -0
  476. package/test-fixtures/remove-inferior-datafields/f01/metadata.json +6 -0
  477. package/test-fixtures/remove-inferior-datafields/f01/record.json +31 -0
  478. package/test-fixtures/remove-inferior-datafields/f03/expectedResult.json +16 -0
  479. package/test-fixtures/remove-inferior-datafields/f03/metadata.json +6 -0
  480. package/test-fixtures/remove-inferior-datafields/f03/record.json +27 -0
  481. package/test-fixtures/remove-inferior-datafields/f04/expectedResult.json +31 -0
  482. package/test-fixtures/remove-inferior-datafields/f04/metadata.json +6 -0
  483. package/test-fixtures/remove-inferior-datafields/f04/record.json +38 -0
  484. package/test-fixtures/remove-inferior-datafields/f05/expectedResult.json +34 -0
  485. package/test-fixtures/remove-inferior-datafields/f05/metadata.json +6 -0
  486. package/test-fixtures/remove-inferior-datafields/f05/record.json +41 -0
  487. package/test-fixtures/remove-inferior-datafields/f06/expectedResult.json +16 -0
  488. package/test-fixtures/remove-inferior-datafields/f06/metadata.json +6 -0
  489. package/test-fixtures/remove-inferior-datafields/f06/record.json +20 -0
  490. package/test-fixtures/remove-inferior-datafields/v01/expectedResult.json +6 -0
  491. package/test-fixtures/remove-inferior-datafields/v01/metadata.json +6 -0
  492. package/test-fixtures/remove-inferior-datafields/v01/record.json +31 -0
  493. package/test-fixtures/remove-inferior-datafields/v02/expectedResult.json +6 -0
  494. package/test-fixtures/remove-inferior-datafields/v02/metadata.json +6 -0
  495. package/test-fixtures/remove-inferior-datafields/v02/record.json +21 -0
  496. package/test-fixtures/remove-orphanded-sf6s/f01/expectedResult.json +35 -0
  497. package/test-fixtures/remove-orphanded-sf6s/f01/metadata.json +6 -0
  498. package/test-fixtures/remove-orphanded-sf6s/f01/record.json +34 -0
  499. package/test-fixtures/remove-orphanded-sf6s/f02/expectedResult.json +40 -0
  500. package/test-fixtures/remove-orphanded-sf6s/f02/metadata.json +6 -0
  501. package/test-fixtures/remove-orphanded-sf6s/f02/record.json +43 -0
  502. package/test-fixtures/remove-orphanded-sf6s/v01/expectedResult.json +6 -0
  503. package/test-fixtures/remove-orphanded-sf6s/v01/metadata.json +6 -0
  504. package/test-fixtures/remove-orphanded-sf6s/v01/record.json +31 -0
  505. package/test-fixtures/remove-orphanded-sf6s/v02/expectedResult.json +6 -0
  506. package/test-fixtures/remove-orphanded-sf6s/v02/metadata.json +6 -0
  507. package/test-fixtures/remove-orphanded-sf6s/v02/record.json +31 -0
  508. package/test-fixtures/resolvable-ext-references-melinda.js +0 -27
  509. package/test-fixtures/sanitize-vocabulary-source-codes/f01/expectedResult.json +32 -0
  510. package/test-fixtures/sanitize-vocabulary-source-codes/f01/metadata.json +6 -0
  511. package/test-fixtures/sanitize-vocabulary-source-codes/f01/record.json +32 -0
  512. package/test-fixtures/sanitize-vocabulary-source-codes/f02/expectedResult.json +24 -0
  513. package/test-fixtures/sanitize-vocabulary-source-codes/f02/metadata.json +6 -0
  514. package/test-fixtures/sanitize-vocabulary-source-codes/f02/record.json +24 -0
  515. package/test-fixtures/sanitize-vocabulary-source-codes/v01/expectedResult.json +12 -0
  516. package/test-fixtures/sanitize-vocabulary-source-codes/v01/metadata.json +6 -0
  517. package/test-fixtures/sanitize-vocabulary-source-codes/v01/record.json +24 -0
  518. package/test-fixtures/sort-relator-terms/f01/expectedResult.json +23 -0
  519. package/test-fixtures/sort-relator-terms/f01/metadata.json +6 -0
  520. package/test-fixtures/sort-relator-terms/f01/record.json +22 -0
  521. package/test-fixtures/sort-relator-terms/f02/expectedResult.json +26 -0
  522. package/test-fixtures/sort-relator-terms/f02/metadata.json +6 -0
  523. package/test-fixtures/sort-relator-terms/f02/record.json +22 -0
  524. package/test-fixtures/sort-relator-terms/v01/expectedResult.json +5 -0
  525. package/test-fixtures/sort-relator-terms/v01/metadata.json +6 -0
  526. package/test-fixtures/sort-relator-terms/v01/record.json +22 -0
  527. package/test-fixtures/sort-relator-terms/v02/expectedResult.json +6 -0
  528. package/test-fixtures/sort-relator-terms/v02/metadata.json +6 -0
  529. package/test-fixtures/sort-relator-terms/v02/record.json +14 -0
  530. package/test-fixtures/sort-subfields/f01/expectedResult.json +24 -0
  531. package/test-fixtures/sort-subfields/f01/metadata.json +6 -0
  532. package/test-fixtures/sort-subfields/f01/record.json +20 -0
  533. package/test-fixtures/sort-subfields/v01/expectedResult.json +5 -0
  534. package/test-fixtures/sort-subfields/v01/metadata.json +6 -0
  535. package/test-fixtures/sort-subfields/v01/record.json +24 -0
  536. package/test-fixtures/sort-subfields/v02/expectedResult.json +6 -0
  537. package/test-fixtures/sort-subfields/v02/metadata.json +6 -0
  538. package/test-fixtures/sort-subfields/v02/record.json +8 -0
  539. package/test-fixtures/strip-punctuation/01/expectedResult.json +12 -0
  540. package/test-fixtures/strip-punctuation/01/metadata.json +6 -0
  541. package/test-fixtures/strip-punctuation/01/record.json +37 -0
  542. package/test-fixtures/strip-punctuation/02/expectedResult.json +4 -0
  543. package/test-fixtures/strip-punctuation/02/metadata.json +6 -0
  544. package/test-fixtures/strip-punctuation/02/record.json +14 -0
  545. package/test-fixtures/strip-punctuation/04/expectedResult.json +6 -0
  546. package/test-fixtures/strip-punctuation/04/metadata.json +6 -0
  547. package/test-fixtures/strip-punctuation/04/record.json +22 -0
  548. package/test-fixtures/strip-punctuation/05/expectedResult.json +6 -0
  549. package/test-fixtures/strip-punctuation/05/metadata.json +6 -0
  550. package/test-fixtures/strip-punctuation/05/record.json +12 -0
  551. package/test-fixtures/strip-punctuation/98/expectedResult.json +44 -0
  552. package/test-fixtures/strip-punctuation/98/metadata.json +6 -0
  553. package/test-fixtures/strip-punctuation/98/record.json +45 -0
  554. package/test-fixtures/strip-punctuation/99/expectedResult.json +16 -0
  555. package/test-fixtures/strip-punctuation/99/metadata.json +6 -0
  556. package/test-fixtures/strip-punctuation/99/record.json +16 -0
  557. package/test-fixtures/subfield0/f01/expectedResult.json +25 -0
  558. package/test-fixtures/subfield0/f01/metadata.json +6 -0
  559. package/test-fixtures/subfield0/f01/record.json +23 -0
  560. package/test-fixtures/subfield0/f02/expectedResult.json +35 -0
  561. package/test-fixtures/subfield0/f02/metadata.json +6 -0
  562. package/test-fixtures/subfield0/f02/record.json +41 -0
  563. package/test-fixtures/subfield0/f03/expectedResult.json +21 -0
  564. package/test-fixtures/subfield0/f03/metadata.json +7 -0
  565. package/test-fixtures/subfield0/f03/record.json +24 -0
  566. package/test-fixtures/subfield0/v01/expectedResult.json +4 -0
  567. package/test-fixtures/subfield0/v01/metadata.json +6 -0
  568. package/test-fixtures/subfield0/v01/record.json +23 -0
  569. package/test-fixtures/subfield0/v02/expectedResult.json +9 -0
  570. package/test-fixtures/subfield0/v02/metadata.json +6 -0
  571. package/test-fixtures/subfield0/v02/record.json +38 -0
  572. package/test-fixtures/typeOfDate-008/01/expectedResult.json +3 -0
  573. package/test-fixtures/typeOfDate-008/01/metadata.json +4 -0
  574. package/test-fixtures/typeOfDate-008/01/record.json +14 -0
  575. package/test-fixtures/typeOfDate-008/02/expectedResult.json +4 -0
  576. package/test-fixtures/typeOfDate-008/02/metadata.json +4 -0
  577. package/test-fixtures/typeOfDate-008/02/record.json +14 -0
  578. package/test-fixtures/typeOfDate-008/03/expectedResult.json +14 -0
  579. package/test-fixtures/typeOfDate-008/03/metadata.json +5 -0
  580. package/test-fixtures/typeOfDate-008/03/record.json +14 -0
  581. package/test-fixtures/typeOfDate-008/04/expectedResult.json +14 -0
  582. package/test-fixtures/typeOfDate-008/04/metadata.json +5 -0
  583. package/test-fixtures/typeOfDate-008/04/record.json +14 -0
  584. package/test-fixtures/typeOfDate-008/05/expectedResult.json +14 -0
  585. package/test-fixtures/typeOfDate-008/05/metadata.json +5 -0
  586. package/test-fixtures/typeOfDate-008/05/record.json +14 -0
  587. package/test-fixtures/update-field-540/f01/expectedResult.json +23 -0
  588. package/test-fixtures/update-field-540/f01/metadata.json +6 -0
  589. package/test-fixtures/update-field-540/f01/record.json +23 -0
  590. package/test-fixtures/update-field-540/v01/expectedResult.json +7 -0
  591. package/test-fixtures/update-field-540/v01/metadata.json +6 -0
  592. package/test-fixtures/update-field-540/v01/record.json +23 -0
  593. package/.travis.yml +0 -10
@@ -0,0 +1,292 @@
1
+ import {MarcRecord} from '@natlibfi/marc-record';
2
+ import createDebug from 'debug';
3
+ import {autRules, bibRules} from './rules';
4
+
5
+ const debug = createDebug('@natlibfi/marc-record-validator-melinda/punctuation');
6
+
7
+ function cloneDeep(field) {
8
+ const r = new MarcRecord();
9
+ r.appendField(field);
10
+ return r.get(field.tag)?.[0];
11
+ }
12
+
13
+ export default function () {
14
+ function readPunctuationRulesFromJSON(recordType) {
15
+ const json = getRules(recordType);
16
+ const rules = json.filter(row => row.selector !== '').map(row => {
17
+ const {selector, namePortion, description, portion, preceedingPunctuation, exceptions} = row;
18
+ return {
19
+ selector: new RegExp(selector.replace(/X/ug, '.'), 'u'),
20
+ namePortion: namePortion.replace(/\$/ug, '').trim(),
21
+ description, portion, preceedingPunctuation, exceptions
22
+ };
23
+ });
24
+
25
+ return rules;
26
+ }
27
+
28
+ function getRules(recordType) {
29
+ if (recordType === 'z') {
30
+ return autRules;
31
+ }
32
+
33
+ return bibRules;
34
+ }
35
+
36
+ function fieldToString(field) {
37
+ if (field && field.subfields) {
38
+ const ind1 = field.ind1 || ' ';
39
+ const ind2 = field.ind2 || ' ';
40
+ const subfields = field.subfields.map(subfield => `‡${subfield.code}${subfield.value}`).join('');
41
+ return `${field.tag} ${ind1}${ind2} ${subfields}`;
42
+ }
43
+
44
+ return `${field.tag} ${field.value}`;
45
+ }
46
+
47
+ function validateField(recordType = 'a') {
48
+ return function (element) {
49
+ const testField = cloneDeep(element);
50
+ debug(`Original field: ${JSON.stringify(element)}`);
51
+ const punctuated = punctuateField(testField, recordType);
52
+ debug(`Punctuation result: ${JSON.stringify(punctuated)}`);
53
+ if (!punctuated) {
54
+ debug('No punctuation result -> true');
55
+ return true;
56
+ }
57
+
58
+ if (MarcRecord.isEqual(punctuated, element)) {
59
+ debug(`Original field (element): ${JSON.stringify(element)}`);
60
+ debug('Punctuation result equals original field');
61
+ return true;
62
+ }
63
+
64
+ return false;
65
+ };
66
+ }
67
+
68
+ function punctuateField(field, recordType) {
69
+ const rules = readPunctuationRulesFromJSON(recordType);
70
+ debug(`Handling field ${field.tag}`);
71
+ debug(`Field contents: ${fieldToString(field)}`);
72
+ const rulesForField = getRulesForField(field.tag, rules);
73
+ if (rulesForField.length === 0) {
74
+ debug(`No matching rules for field ${field.tag}`);
75
+ return;
76
+ }
77
+
78
+ let currentPortion; // eslint-disable-line functional/no-let
79
+ let preceedingField; // eslint-disable-line functional/no-let
80
+ let inNamePortion = true; // eslint-disable-line functional/no-let
81
+
82
+ debug(`Field subfields: ${field.subfields.map(sub => sub.code)}`);
83
+ debug(`Field portions: ${field.subfields.map(sub => getPortion(sub, rulesForField))}`);
84
+
85
+ field.subfields.forEach(subfield => {
86
+ debug(`Handling subfield ${subfield.code}`);
87
+ let portion = getPortion(subfield, rulesForField); // eslint-disable-line functional/no-let
88
+
89
+ if (portion === false) {
90
+ return;
91
+ }
92
+
93
+ if (portion === 'CF' || portion === 'NC') {
94
+ return;
95
+ }
96
+
97
+ if (inNamePortion && portion.includes('T', 'S')) { // eslint-disable-line functional/no-conditional-statements
98
+ debug(`Portion changed to ${portion}. Not in name portion anymore`);
99
+ inNamePortion = false;
100
+ }
101
+
102
+ if (inNamePortion && portion === 'NT') { // eslint-disable-line functional/no-conditional-statements
103
+ portion = 'N';
104
+ }
105
+
106
+ if (!inNamePortion && portion === 'NT') { // eslint-disable-line functional/no-conditional-statements
107
+ portion = 'T';
108
+ }
109
+
110
+ debug(`Current portion is ${portion}.`);
111
+
112
+ if (currentPortion) {
113
+ if (currentPortion === portion) { // eslint-disable-line functional/no-conditional-statements
114
+ debug(`Current stayed as ${portion}. Adding punctuation for subfield.`);
115
+ addSubfieldPunctuation(preceedingField, subfield, rulesForField);
116
+ } else {
117
+ debug(`Current portion changed to ${portion}.`);
118
+ if (portion !== 'S') { // eslint-disable-line functional/no-conditional-statements
119
+ debug('Adding punctuation for portion.');
120
+ addNamePortionPunctuation(preceedingField);
121
+ }
122
+ }
123
+ }
124
+
125
+ currentPortion = portion;
126
+ preceedingField = subfield;
127
+ });
128
+
129
+ if (recordType !== 'z') { // eslint-disable-line functional/no-conditional-statements
130
+ addNamePortionPunctuation(preceedingField);
131
+ }
132
+
133
+ debug(`After punctuation: ${fieldToString(field)}`);
134
+
135
+ return field;
136
+ }
137
+
138
+ function getRulesForField(tag, rules) {
139
+ return rules.filter(rule => rule.selector.test(tag));
140
+ }
141
+
142
+ function getPortion(subfield, rules) {
143
+ debug(`Looking for namePortion for ${subfield.code}`);
144
+ const [portion] = rules.filter(rule => rule.namePortion === subfield.code).map(rule => rule.portion);
145
+
146
+ if (portion === undefined) {
147
+ return false;
148
+ }
149
+
150
+ return portion.toUpperCase();
151
+ }
152
+
153
+ function addNamePortionPunctuation(preceedingSubfield) {
154
+ const subfieldContainsPunctuation = (/[?")\].\-!,]$/u).test(preceedingSubfield.value);
155
+ if (!subfieldContainsPunctuation) { // eslint-disable-line functional/no-conditional-statements
156
+ const nextValue = `${preceedingSubfield.value}.`;
157
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
158
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
159
+ }
160
+ }
161
+
162
+ function addSubfieldPunctuation(preceedingSubfield, currentSubfield, rules) {
163
+ const punctType = getPrecedingPunctuation(currentSubfield, rules);
164
+ const exceptionsFunctions = getExceptions(currentSubfield, rules);
165
+
166
+ const isExceptionCase = exceptionsFunctions.some(fn => fn(preceedingSubfield));
167
+
168
+ if (isExceptionCase) {
169
+ return;
170
+ }
171
+
172
+ const endsInPunctuation = (/[?")\]\-!,]$/u).test(preceedingSubfield.value);
173
+ debug(`addSubfieldPunctuation -- punctType: ${punctType} endsInPunctuation: ${endsInPunctuation}`);
174
+
175
+ if (!endsInPunctuation) {
176
+ if (punctType === 'PERIOD' && !(/\.$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
177
+ const nextValue = `${preceedingSubfield.value}.`;
178
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
179
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
180
+ }
181
+ }
182
+
183
+ if (punctType === 'COMMA') {
184
+ if (!(/,$/u).test(preceedingSubfield.value)) {
185
+ if (!(/^[[(]/u).test(currentSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
186
+ const nextValue = `${preceedingSubfield.value},`;
187
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
188
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
189
+ }
190
+ }
191
+ }
192
+
193
+ if (punctType === 'COND_COMMA') {
194
+ if (!(/[-,]$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
195
+ const nextValue = `${preceedingSubfield.value},`;
196
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
197
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
198
+ }
199
+ }
200
+
201
+ if (punctType === 'SPACECOLON') {
202
+ if (!(/:$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
203
+ const nextValue = `${preceedingSubfield.value} :`;
204
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
205
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
206
+ }
207
+ if ((/[^ ]:$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
208
+ const nextValue = `${preceedingSubfield.value.slice(0, -1)} :`;
209
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
210
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
211
+ }
212
+
213
+ }
214
+
215
+ debug('addSubfieldPunctuation -- end');
216
+ }
217
+
218
+ function getPrecedingPunctuation(subfield, rules) {
219
+ const [punct] = rules.filter(rule => rule.namePortion === subfield.code).map(rule => rule.preceedingPunctuation);
220
+
221
+ if (punct === undefined) {
222
+ throw new Error(`Unknown subfield code ${subfield.code}`);
223
+ }
224
+
225
+ return punct.toUpperCase();
226
+ }
227
+
228
+ function getExceptions(subfield, rules) {
229
+ const [exception] = rules.filter(rule => rule.namePortion === subfield.code).map(rule => parseExceptions(rule.exceptions));
230
+
231
+ if (exception === undefined) {
232
+ throw new Error(`Unknown subfield code ${subfield.code}`);
233
+ }
234
+
235
+ return exception;
236
+ }
237
+
238
+ function parseExceptions(expectionsString) {
239
+ const exceptionRules = expectionsString.split('\n');
240
+ const exceptionFuncs = [];
241
+
242
+ exceptionRules.forEach(exceptionRule => {
243
+ const match = (/- (.*) if preceded by (.*)/u).exec(exceptionRule); // eslint-disable-line prefer-named-capture-group
244
+ if (match) { // eslint-disable-line functional/no-conditional-statements
245
+ const [, type, preceededCode] = match;
246
+ const normalizedType = type.trim().toUpperCase().trim();
247
+ const normalizedCode = preceededCode.replace(/\$/ug, '').trim();
248
+ exceptionFuncs.push(ifPrecededByException(normalizedCode, normalizedType)); // eslint-disable-line functional/immutable-data
249
+ }
250
+ });
251
+
252
+ return exceptionFuncs;
253
+ }
254
+
255
+ function ifPrecededByException(code, type) {
256
+ return preceedingSubfield => {
257
+ if (code === preceedingSubfield.code) {
258
+ debug(`Adding ${type} to ${preceedingSubfield.code}`);
259
+ if (type === 'SEMICOLON' && !(/;$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
260
+ const nextValue = `${preceedingSubfield.value} ;`;
261
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
262
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
263
+ }
264
+
265
+ if (type === 'COLON' && !(/:$/u).test(preceedingSubfield.value)) { // eslint-disable-line functional/no-conditional-statements
266
+ const nextValue = `${preceedingSubfield.value} :`;
267
+ debug(`Updated subfield ${preceedingSubfield.code} from '${preceedingSubfield.value}' to '${nextValue}'`);
268
+ preceedingSubfield.value = nextValue; // eslint-disable-line functional/immutable-data
269
+ }
270
+
271
+ return true;
272
+ }
273
+
274
+ return false;
275
+ };
276
+ }
277
+
278
+ function validate(record) {
279
+ return {valid: record.fields.every(validateField(record.leader[6]))};
280
+ }
281
+
282
+ function fix(record) {
283
+ record.fields.map(field => punctuateField(field, record.leader[6]));
284
+ return true;
285
+ }
286
+
287
+ return {
288
+ description: 'Fixes punctuation of fields',
289
+ validate,
290
+ fix
291
+ };
292
+ }
@@ -0,0 +1,372 @@
1
+ const autRules =
2
+ [
3
+ {
4
+ selector: '[1457]00',
5
+ namePortion: '$a',
6
+ description: 'Personal name (NR)',
7
+ portion: 'N',
8
+ preceedingPunctuation: 'none',
9
+ exceptions: ''
10
+ },
11
+ {
12
+ selector: '[1457]10',
13
+ namePortion: '$a',
14
+ description: 'Corporate name or jurisdiction name as entry element (NR)',
15
+ portion: 'N',
16
+ preceedingPunctuation: 'none',
17
+ exceptions: ''
18
+ },
19
+ {
20
+ selector: '[1457]11',
21
+ namePortion: '$a',
22
+ description: 'Meeting name or jurisdiction name as entry element (NR)',
23
+ portion: 'N',
24
+ preceedingPunctuation: 'none',
25
+ exceptions: ''
26
+ },
27
+ {
28
+ selector: '[1457]00',
29
+ namePortion: '$b',
30
+ description: 'Numeration (NR)',
31
+ portion: 'N',
32
+ preceedingPunctuation: 'none',
33
+ exceptions: ''
34
+ },
35
+ {
36
+ selector: '[1457]10',
37
+ namePortion: '$b',
38
+ description: 'Subordinate unit (R)',
39
+ portion: 'N',
40
+ preceedingPunctuation: 'period',
41
+ exceptions: ''
42
+ },
43
+ {
44
+ selector: '[1457]00',
45
+ namePortion: '$c',
46
+ description: 'Titles and words associated with a name (R)',
47
+ portion: 'N',
48
+ preceedingPunctuation: 'comma',
49
+ exceptions: ''
50
+ },
51
+ {
52
+ selector: '[1457](10|11)',
53
+ namePortion: '$c',
54
+ description: 'Location of meeting (R)',
55
+ portion: 'N',
56
+ preceedingPunctuation: 'comma',
57
+ exceptions: '- colon if preceded by $d\n- semicolon if preceded by $c'
58
+ },
59
+ {
60
+ selector: '[1457]00',
61
+ namePortion: '$d',
62
+ description: 'Dates associated with a name (NR)',
63
+ portion: 'N',
64
+ preceedingPunctuation: 'comma',
65
+ exceptions: '- colon if preceded by $n'
66
+ },
67
+ {
68
+ selector: '[1457]11',
69
+ namePortion: '$d',
70
+ description: 'Date of meeting (NR)',
71
+ portion: 'N',
72
+ preceedingPunctuation: '',
73
+ exceptions: ''
74
+ },
75
+ {
76
+ selector: '[1457](00|10)',
77
+ namePortion: '$e',
78
+ description: 'Relator term (R)',
79
+ portion: 'N',
80
+ preceedingPunctuation: 'cond_comma',
81
+ exceptions: ''
82
+ },
83
+ {
84
+ selector: '[1457]11',
85
+ namePortion: '$e',
86
+ description: 'Subordinate unit (R)',
87
+ portion: 'N',
88
+ preceedingPunctuation: 'period',
89
+ exceptions: ''
90
+ },
91
+ {
92
+ selector: '[1457]11',
93
+ namePortion: '$j',
94
+ description: 'Relator term (R)',
95
+ portion: 'N',
96
+ preceedingPunctuation: 'comma',
97
+ exceptions: ''
98
+ },
99
+ {
100
+ selector: '[1457]00',
101
+ namePortion: '$j',
102
+ description: 'Attribution qualifier (R)',
103
+ portion: 'N',
104
+ preceedingPunctuation: 'comma',
105
+ exceptions: ''
106
+ },
107
+ {
108
+ selector: '[1457]00',
109
+ namePortion: '$q',
110
+ description: 'Fuller form of name (NR)',
111
+ portion: 'N',
112
+ preceedingPunctuation: 'comma',
113
+ exceptions: ''
114
+ },
115
+ {
116
+ selector: '[1457]11',
117
+ namePortion: '$q',
118
+ description: 'Name of meeting following jurisdiction name entry element (NR)',
119
+ portion: 'N',
120
+ preceedingPunctuation: '',
121
+ exceptions: ''
122
+ },
123
+ {
124
+ selector: '[1457](00|11)',
125
+ namePortion: '$u',
126
+ description: 'Affiliation (NR)',
127
+ portion: 'N',
128
+ preceedingPunctuation: 'period',
129
+ exceptions: '?'
130
+ },
131
+ {
132
+ selector: '[1457]10',
133
+ namePortion: '$u',
134
+ description: 'Affiliation (NR) or Address',
135
+ portion: 'N',
136
+ preceedingPunctuation: 'period',
137
+ exceptions: '- period, if address'
138
+ },
139
+ {
140
+ selector: '[1457](00|10|11)',
141
+ namePortion: '$4',
142
+ description: 'Relator code (R)',
143
+ portion: 'NC',
144
+ preceedingPunctuation: 'none',
145
+ exceptions: ''
146
+ },
147
+ {
148
+ selector: '[1457](00|10|11)',
149
+ namePortion: '$f',
150
+ description: 'Date of a work (NR)',
151
+ portion: 'T',
152
+ preceedingPunctuation: 'period',
153
+ exceptions: ''
154
+ },
155
+ {
156
+ selector: '[1457](00|10|11)',
157
+ namePortion: '$h',
158
+ description: 'Medium (NR)',
159
+ portion: 'T',
160
+ preceedingPunctuation: 'period',
161
+ exceptions: ''
162
+ },
163
+ {
164
+ selector: '[457](00|10|11)',
165
+ namePortion: '$i',
166
+ description: 'Relationship information (R)',
167
+ portion: 'cf',
168
+ preceedingPunctuation: 'none',
169
+ exceptions: ''
170
+ },
171
+ {
172
+ selector: '[1457](00|10|11)',
173
+ namePortion: '$k',
174
+ description: 'Form subheading (R)',
175
+ portion: 'T',
176
+ preceedingPunctuation: 'period',
177
+ exceptions: ''
178
+ },
179
+ {
180
+ selector: '[1457](00|10|11)',
181
+ namePortion: '$l',
182
+ description: 'Language of a work (NR)',
183
+ portion: 'T',
184
+ preceedingPunctuation: 'comma / period',
185
+ exceptions: '- Finnish MARC21 comma,\n- MARC21 period'
186
+ },
187
+ {
188
+ selector: '[1457](00|10|11)',
189
+ namePortion: '$m',
190
+ description: 'Medium of performance for music',
191
+ portion: 'T',
192
+ preceedingPunctuation: 'comma',
193
+ exceptions: ''
194
+ },
195
+ {
196
+ selector: '[1457](00|10|11)',
197
+ namePortion: '$n',
198
+ description: 'Number of part/section of a work (R)',
199
+ portion: 'T',
200
+ preceedingPunctuation: 'comma, period',
201
+ exceptions: ' - depends on data?\n- period, if preceded by $k, $m, $t\n- comma, if preceded by $b, $m'
202
+ },
203
+ {
204
+ selector: '[1457](00|10)',
205
+ namePortion: '$o',
206
+ description: 'Arranged statement for music (NR)',
207
+ portion: 'T',
208
+ preceedingPunctuation: 'semicolon',
209
+ exceptions: ''
210
+ },
211
+ {
212
+ selector: '[1457](00|10|11)',
213
+ namePortion: '$p',
214
+ description: 'Name of part/section of a work (R)',
215
+ portion: 'T',
216
+ preceedingPunctuation: 'comma, period, none',
217
+ exceptions: '- depends on data?\n- period if preceded by $t, $n, $p\n- comma, if preceded by $n\n- none, if preceded by $k'
218
+ },
219
+ {
220
+ selector: '[1457](00|10)',
221
+ namePortion: '$r',
222
+ description: 'Key for music (NR)',
223
+ portion: 'T',
224
+ preceedingPunctuation: 'comma',
225
+ exceptions: ''
226
+ },
227
+ {
228
+ selector: '[1457](00|10|11)',
229
+ namePortion: '$s',
230
+ description: 'Version (NR)',
231
+ portion: 'T',
232
+ preceedingPunctuation: 'period',
233
+ exceptions: ''
234
+ },
235
+ {
236
+ selector: '[1457](00|10|11)',
237
+ namePortion: '$t',
238
+ description: 'Title of a work (NR)',
239
+ portion: 'T',
240
+ preceedingPunctuation: 'none',
241
+ exceptions: '- usually first in section -> period'
242
+ },
243
+ {
244
+ selector: '[1457](10|11)',
245
+ namePortion: '$d',
246
+ description: 'Date of meeting or treaty signing (R)',
247
+ portion: 'NT',
248
+ preceedingPunctuation: '',
249
+ exceptions: ''
250
+ },
251
+ {
252
+ selector: '[1457](00|10|11)',
253
+ namePortion: '$g',
254
+ description: 'Miscellaneous information (NR)',
255
+ portion: 'NT',
256
+ preceedingPunctuation: 'comma',
257
+ exceptions: '- colon, if preceded by $d'
258
+ },
259
+ {
260
+ selector: '[1457]10',
261
+ namePortion: '$g',
262
+ description: 'Miscellaneous information (NR), other party to treaties.',
263
+ portion: 'NT',
264
+ preceedingPunctuation: 'comma',
265
+ exceptions: '- colon, if preceded by $d\n- period, if preceded by $t'
266
+ },
267
+ {
268
+ selector: '[1457](10|11)',
269
+ namePortion: '$n',
270
+ description: 'Number of part/section/meeting (R)',
271
+ portion: 'NT',
272
+ preceedingPunctuation: '',
273
+ exceptions: ''
274
+ },
275
+ {
276
+ selector: '[1457](00|10|11)',
277
+ namePortion: '$v',
278
+ description: 'Form subdivision (R) [600]',
279
+ portion: 'S',
280
+ preceedingPunctuation: 'none',
281
+ exceptions: ''
282
+ },
283
+ {
284
+ selector: '[1457](00|10|11)',
285
+ namePortion: '$x',
286
+ description: 'General subdivision (R) [600]',
287
+ portion: 'S',
288
+ preceedingPunctuation: 'none',
289
+ exceptions: ''
290
+ },
291
+ {
292
+ selector: '[1457](00|10|11)',
293
+ namePortion: '$y',
294
+ description: 'Chronological subdivision (R) [600]',
295
+ portion: 'S',
296
+ preceedingPunctuation: 'none',
297
+ exceptions: ''
298
+ },
299
+ {
300
+ selector: '[1457](00|10|11)',
301
+ namePortion: '$z',
302
+ description: 'Geographic subdivision (R) [600]',
303
+ portion: 'S',
304
+ preceedingPunctuation: 'none',
305
+ exceptions: ''
306
+ },
307
+ {
308
+ selector: '[457](00|10|11)',
309
+ namePortion: '$w',
310
+ description: '',
311
+ portion: 'cf',
312
+ preceedingPunctuation: 'none',
313
+ exceptions: ''
314
+ },
315
+ {
316
+ selector: '[1457](00|10|11)',
317
+ namePortion: '$0',
318
+ description: 'Authority record control number (R)',
319
+ portion: 'cf',
320
+ preceedingPunctuation: 'none',
321
+ exceptions: ''
322
+ },
323
+ {
324
+ selector: '7(00|10|11)',
325
+ namePortion: '$2',
326
+ description: 'Source of heading or term (NR)',
327
+ portion: 'cf',
328
+ preceedingPunctuation: 'none',
329
+ exceptions: ''
330
+ },
331
+ {
332
+ selector: '[1457](00|10|11)',
333
+ namePortion: '$5',
334
+ description: 'Institution to which field applies (NR)',
335
+ portion: 'cf',
336
+ preceedingPunctuation: 'none',
337
+ exceptions: ''
338
+ },
339
+ {
340
+ selector: '[1457](00|10|11)',
341
+ namePortion: '$6',
342
+ description: 'Linkage (NR)',
343
+ portion: 'cf',
344
+ preceedingPunctuation: 'none',
345
+ exceptions: ''
346
+ },
347
+ {
348
+ selector: '[1457](00|10|11)',
349
+ namePortion: '$7',
350
+ description: 'Control subfield (NR)',
351
+ portion: 'cf',
352
+ preceedingPunctuation: 'none',
353
+ exceptions: ''
354
+ },
355
+ {
356
+ selector: '[1457](00|10|11)',
357
+ namePortion: '$8',
358
+ description: 'Field link and sequence number (R)',
359
+ portion: 'cf',
360
+ preceedingPunctuation: 'none',
361
+ exceptions: ''
362
+ },
363
+ {
364
+ selector: '[1457](00|10|11)',
365
+ namePortion: '$9',
366
+ description: 'Local control subfield',
367
+ portion: 'cf',
368
+ preceedingPunctuation: 'none',
369
+ exceptions: ''
370
+ }
371
+ ];
372
+ export default autRules;