relaton 2.1.0 → 3.0.0.pre.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (625) hide show
  1. checksums.yaml +4 -4
  2. data/{docs/README.adoc → README.adoc} +109 -38
  3. data/lib/relaton/3gpp/bibdata.rb +9 -0
  4. data/lib/relaton/3gpp/bibitem.rb +9 -0
  5. data/lib/relaton/3gpp/bibliography.rb +48 -0
  6. data/lib/relaton/3gpp/data_fetcher.rb +255 -0
  7. data/lib/relaton/3gpp/doctype.rb +9 -0
  8. data/lib/relaton/3gpp/ext.rb +31 -0
  9. data/lib/relaton/3gpp/item.rb +12 -0
  10. data/lib/relaton/3gpp/item_data.rb +15 -0
  11. data/lib/relaton/3gpp/parser.rb +400 -0
  12. data/lib/relaton/3gpp/processor.rb +68 -0
  13. data/lib/relaton/3gpp/release.rb +34 -0
  14. data/lib/relaton/3gpp/util.rb +8 -0
  15. data/lib/relaton/3gpp.rb +25 -0
  16. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  17. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  18. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  19. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  20. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  21. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
  22. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  23. data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
  24. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  25. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  26. data/lib/relaton/bib/hash_parser_v1.rb +767 -0
  27. data/lib/relaton/bib/item_data.rb +229 -0
  28. data/lib/relaton/bib/model/abstract.rb +16 -0
  29. data/lib/relaton/bib/model/address.rb +22 -0
  30. data/lib/relaton/bib/model/affiliation.rb +16 -0
  31. data/lib/relaton/bib/model/bibdata.rb +11 -0
  32. data/lib/relaton/bib/model/bibdata_shared.rb +12 -0
  33. data/lib/relaton/bib/model/bibitem.rb +11 -0
  34. data/lib/relaton/bib/model/bibitem_shared.rb +12 -0
  35. data/lib/relaton/bib/model/contact.rb +18 -0
  36. data/lib/relaton/bib/model/contribution_info.rb +15 -0
  37. data/lib/relaton/bib/model/contributor.rb +29 -0
  38. data/lib/relaton/bib/model/copyright.rb +27 -0
  39. data/lib/relaton/bib/model/date.rb +31 -0
  40. data/lib/relaton/bib/model/depiction.rb +16 -0
  41. data/lib/relaton/bib/model/docidentifier.rb +34 -0
  42. data/lib/relaton/bib/model/doctype.rb +14 -0
  43. data/lib/relaton/bib/model/edition.rb +14 -0
  44. data/lib/relaton/bib/model/ext.rb +39 -0
  45. data/lib/relaton/bib/model/extent.rb +16 -0
  46. data/lib/relaton/bib/model/formattedref.rb +43 -0
  47. data/lib/relaton/bib/model/full_name_type.rb +64 -0
  48. data/lib/relaton/bib/model/fullname.rb +11 -0
  49. data/lib/relaton/bib/model/ics.rb +49 -0
  50. data/lib/relaton/bib/model/image.rb +28 -0
  51. data/lib/relaton/bib/model/item.rb +96 -0
  52. data/lib/relaton/bib/model/item_base.rb +20 -0
  53. data/lib/relaton/bib/model/item_shared.rb +88 -0
  54. data/lib/relaton/bib/model/keyword.rb +30 -0
  55. data/lib/relaton/bib/model/locality.rb +18 -0
  56. data/lib/relaton/bib/model/locality_stack.rb +14 -0
  57. data/lib/relaton/bib/model/localized_string.rb +48 -0
  58. data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
  59. data/lib/relaton/bib/model/logo.rb +14 -0
  60. data/lib/relaton/bib/model/medium.rb +22 -0
  61. data/lib/relaton/bib/model/note.rb +16 -0
  62. data/lib/relaton/bib/model/organization.rb +13 -0
  63. data/lib/relaton/bib/model/organization_type.rb +42 -0
  64. data/lib/relaton/bib/model/person.rb +36 -0
  65. data/lib/relaton/bib/model/phone.rb +14 -0
  66. data/lib/relaton/bib/model/place.rb +33 -0
  67. data/lib/relaton/bib/model/price.rb +14 -0
  68. data/lib/relaton/bib/model/relation.rb +43 -0
  69. data/lib/relaton/bib/model/series.rb +34 -0
  70. data/lib/relaton/bib/model/size.rb +23 -0
  71. data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
  72. data/lib/relaton/bib/model/status.rb +27 -0
  73. data/lib/relaton/bib/model/structured_identifier.rb +48 -0
  74. data/lib/relaton/bib/model/subdivision.rb +16 -0
  75. data/lib/relaton/bib/model/title.rb +56 -0
  76. data/lib/relaton/bib/model/type/plain_date.rb +16 -0
  77. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  78. data/lib/relaton/bib/model/uri.rb +18 -0
  79. data/lib/relaton/bib/model/validity.rb +16 -0
  80. data/lib/relaton/bib/model/version.rb +43 -0
  81. data/lib/relaton/bib/namespace_helper.rb +21 -0
  82. data/lib/relaton/bib/sanitizer.rb +68 -0
  83. data/lib/relaton/bib/util.rb +18 -0
  84. data/lib/relaton/bib/versions.json +35 -0
  85. data/lib/relaton/bib.rb +48 -0
  86. data/lib/relaton/bipm/bibliography.rb +82 -0
  87. data/lib/relaton/bipm/converter/asciibib.rb +64 -0
  88. data/lib/relaton/bipm/data_fetcher.rb +57 -0
  89. data/lib/relaton/bipm/data_outcomes_parser.rb +657 -0
  90. data/lib/relaton/bipm/id_parser.rb +277 -0
  91. data/lib/relaton/bipm/item_data.rb +47 -0
  92. data/lib/relaton/bipm/model/bibdata.rb +9 -0
  93. data/lib/relaton/bipm/model/bibitem.rb +9 -0
  94. data/lib/relaton/bipm/model/comment_period.rb +13 -0
  95. data/lib/relaton/bipm/model/doctype.rb +12 -0
  96. data/lib/relaton/bipm/model/ext.rb +38 -0
  97. data/lib/relaton/bipm/model/item.rb +11 -0
  98. data/lib/relaton/bipm/model/structured_identifier.rb +15 -0
  99. data/lib/relaton/bipm/processor.rb +69 -0
  100. data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +111 -0
  101. data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +174 -0
  102. data/lib/relaton/bipm/rawdata_bipm_metrologia/niso_jats_parser.rb +353 -0
  103. data/lib/relaton/bipm/si_brochure_parser.rb +186 -0
  104. data/lib/relaton/bipm/util.rb +8 -0
  105. data/lib/relaton/bipm.rb +32 -0
  106. data/lib/relaton/bsi/bibliography.rb +124 -0
  107. data/lib/relaton/bsi/hit.rb +14 -0
  108. data/lib/relaton/bsi/hit_collection.rb +114 -0
  109. data/lib/relaton/bsi/item_data.rb +13 -0
  110. data/lib/relaton/bsi/model/bibdata.rb +8 -0
  111. data/lib/relaton/bsi/model/bibitem.rb +8 -0
  112. data/lib/relaton/bsi/model/docidentifier.rb +9 -0
  113. data/lib/relaton/bsi/model/doctype.rb +14 -0
  114. data/lib/relaton/bsi/model/ext.rb +17 -0
  115. data/lib/relaton/bsi/model/item.rb +17 -0
  116. data/lib/relaton/bsi/model/item_base.rb +22 -0
  117. data/lib/relaton/bsi/model/relation.rb +9 -0
  118. data/lib/relaton/bsi/processor.rb +42 -0
  119. data/lib/relaton/bsi/schema.json +24882 -0
  120. data/lib/relaton/bsi/scraper.rb +288 -0
  121. data/lib/relaton/bsi/util.rb +8 -0
  122. data/lib/relaton/bsi.rb +25 -0
  123. data/lib/relaton/calconnect/bibliography.rb +95 -0
  124. data/lib/relaton/calconnect/data_fetcher.rb +106 -0
  125. data/lib/relaton/calconnect/hit.rb +14 -0
  126. data/lib/relaton/calconnect/hit_collection.rb +84 -0
  127. data/lib/relaton/calconnect/item_data.rb +12 -0
  128. data/lib/relaton/calconnect/model/bibdata.rb +8 -0
  129. data/lib/relaton/calconnect/model/bibitem.rb +8 -0
  130. data/lib/relaton/calconnect/model/doctype.rb +11 -0
  131. data/lib/relaton/calconnect/model/ext.rb +11 -0
  132. data/lib/relaton/calconnect/model/item.rb +13 -0
  133. data/lib/relaton/calconnect/processor.rb +66 -0
  134. data/lib/relaton/calconnect/scraper.rb +87 -0
  135. data/lib/relaton/calconnect/util.rb +8 -0
  136. data/lib/relaton/calconnect.rb +26 -0
  137. data/lib/relaton/ccsds/bibliography.rb +63 -0
  138. data/lib/relaton/ccsds/data/fetcher.rb +247 -0
  139. data/lib/relaton/ccsds/data/iso_references.rb +30 -0
  140. data/lib/relaton/ccsds/data/parser.rb +194 -0
  141. data/lib/relaton/ccsds/hit.rb +24 -0
  142. data/lib/relaton/ccsds/hit_collection.rb +42 -0
  143. data/lib/relaton/ccsds/item_data.rb +9 -0
  144. data/lib/relaton/ccsds/model/bibdata.rb +8 -0
  145. data/lib/relaton/ccsds/model/bibitem.rb +8 -0
  146. data/lib/relaton/ccsds/model/doctype.rb +9 -0
  147. data/lib/relaton/ccsds/model/ext.rb +19 -0
  148. data/lib/relaton/ccsds/model/item.rb +13 -0
  149. data/lib/relaton/ccsds/processor.rb +68 -0
  150. data/lib/relaton/ccsds/util.rb +10 -0
  151. data/lib/relaton/ccsds.rb +33 -0
  152. data/lib/relaton/cen/bibliography.rb +121 -0
  153. data/lib/relaton/cen/committees.yaml +66 -0
  154. data/lib/relaton/cen/hit.rb +16 -0
  155. data/lib/relaton/cen/hit_collection.rb +68 -0
  156. data/lib/relaton/cen/item_data.rb +7 -0
  157. data/lib/relaton/cen/model/bibdata.rb +8 -0
  158. data/lib/relaton/cen/model/bibitem.rb +8 -0
  159. data/lib/relaton/cen/model/docidentifier.rb +9 -0
  160. data/lib/relaton/cen/model/ext.rb +11 -0
  161. data/lib/relaton/cen/model/item.rb +14 -0
  162. data/lib/relaton/cen/model/structured_identifier.rb +9 -0
  163. data/lib/relaton/cen/processor.rb +40 -0
  164. data/lib/relaton/cen/scraper.rb +210 -0
  165. data/lib/relaton/cen/util.rb +8 -0
  166. data/lib/relaton/cen.rb +29 -0
  167. data/lib/relaton/cie/bibdata.rb +8 -0
  168. data/lib/relaton/cie/bibitem.rb +8 -0
  169. data/lib/relaton/cie/bibliography.rb +31 -0
  170. data/lib/relaton/cie/data_fetcher.rb +355 -0
  171. data/lib/relaton/cie/ext.rb +7 -0
  172. data/lib/relaton/cie/item.rb +11 -0
  173. data/lib/relaton/cie/item_data.rb +6 -0
  174. data/lib/relaton/cie/processor.rb +66 -0
  175. data/lib/relaton/cie/scrapper.rb +39 -0
  176. data/lib/relaton/cie/util.rb +8 -0
  177. data/lib/relaton/cie.rb +28 -0
  178. data/lib/relaton/core/array_wrapper.rb +20 -0
  179. data/lib/relaton/core/data_fetcher.rb +97 -0
  180. data/lib/relaton/core/date_parser.rb +42 -0
  181. data/lib/relaton/core/hash_keys_sybolizer.rb +19 -0
  182. data/lib/relaton/core/hit.rb +49 -0
  183. data/lib/relaton/core/hit_collection.rb +118 -0
  184. data/lib/relaton/core/processor.rb +48 -0
  185. data/lib/relaton/core/workers_pool.rb +45 -0
  186. data/lib/relaton/core.rb +9 -0
  187. data/lib/relaton/db/cache.rb +232 -0
  188. data/lib/relaton/db/config.rb +24 -0
  189. data/lib/relaton/db/registry.rb +119 -0
  190. data/lib/relaton/db/util.rb +9 -0
  191. data/lib/relaton/db/workers_pool.rb +22 -0
  192. data/lib/relaton/db.rb +20 -206
  193. data/lib/relaton/doi/crossref.rb +72 -0
  194. data/lib/relaton/doi/parser.rb +827 -0
  195. data/lib/relaton/doi/processor.rb +65 -0
  196. data/lib/relaton/doi/util.rb +8 -0
  197. data/lib/relaton/doi.rb +20 -0
  198. data/lib/relaton/ecma/bibdata.rb +8 -0
  199. data/lib/relaton/ecma/bibitem.rb +8 -0
  200. data/lib/relaton/ecma/bibliography.rb +81 -0
  201. data/lib/relaton/ecma/data_fetcher.rb +103 -0
  202. data/lib/relaton/ecma/data_parser.rb +49 -0
  203. data/lib/relaton/ecma/edition_parser.rb +80 -0
  204. data/lib/relaton/ecma/ext.rb +7 -0
  205. data/lib/relaton/ecma/item.rb +11 -0
  206. data/lib/relaton/ecma/item_data.rb +6 -0
  207. data/lib/relaton/ecma/memento_parser.rb +60 -0
  208. data/lib/relaton/ecma/page_fetcher.rb +27 -0
  209. data/lib/relaton/ecma/parser_common.rb +33 -0
  210. data/lib/relaton/ecma/processor.rb +66 -0
  211. data/lib/relaton/ecma/standard_parser.rb +134 -0
  212. data/lib/relaton/ecma/util.rb +8 -0
  213. data/lib/relaton/ecma.rb +24 -0
  214. data/lib/relaton/etsi/bibdata.rb +10 -0
  215. data/lib/relaton/etsi/bibitem.rb +10 -0
  216. data/lib/relaton/etsi/bibliography.rb +46 -0
  217. data/lib/relaton/etsi/data_fetcher.rb +128 -0
  218. data/lib/relaton/etsi/data_parser.rb +208 -0
  219. data/lib/relaton/etsi/doctype.rb +30 -0
  220. data/lib/relaton/etsi/ext.rb +31 -0
  221. data/lib/relaton/etsi/item.rb +15 -0
  222. data/lib/relaton/etsi/item_data.rb +6 -0
  223. data/lib/relaton/etsi/processor.rb +69 -0
  224. data/lib/relaton/etsi/pubid.rb +37 -0
  225. data/lib/relaton/etsi/status.rb +13 -0
  226. data/lib/relaton/etsi/util.rb +8 -0
  227. data/lib/relaton/etsi.rb +25 -0
  228. data/lib/relaton/gb/bibdata.rb +8 -0
  229. data/lib/relaton/gb/bibitem.rb +8 -0
  230. data/lib/relaton/gb/bibliography.rb +145 -0
  231. data/lib/relaton/gb/ccs.rb +14 -0
  232. data/lib/relaton/gb/committee.rb +13 -0
  233. data/lib/relaton/gb/docidentifier.rb +23 -0
  234. data/lib/relaton/gb/doctype.rb +9 -0
  235. data/lib/relaton/gb/ext.rb +36 -0
  236. data/lib/relaton/gb/gb_scraper.rb +61 -0
  237. data/lib/relaton/gb/gb_type.rb +20 -0
  238. data/lib/relaton/gb/hit.rb +48 -0
  239. data/lib/relaton/gb/hit_collection.rb +19 -0
  240. data/lib/relaton/gb/item.rb +13 -0
  241. data/lib/relaton/gb/item_data.rb +6 -0
  242. data/lib/relaton/gb/processor.rb +46 -0
  243. data/lib/relaton/gb/project_number.rb +38 -0
  244. data/lib/relaton/gb/scraper.rb +204 -0
  245. data/lib/relaton/gb/sec_scraper.rb +92 -0
  246. data/lib/relaton/gb/stage_name.rb +13 -0
  247. data/lib/relaton/gb/structured_identifier.rb +26 -0
  248. data/lib/relaton/gb/t_scraper.rb +126 -0
  249. data/lib/relaton/gb/util.rb +8 -0
  250. data/lib/relaton/gb/yaml/prefixes.yaml +200 -0
  251. data/lib/relaton/gb.rb +33 -0
  252. data/lib/relaton/iana/bibdata.rb +8 -0
  253. data/lib/relaton/iana/bibitem.rb +8 -0
  254. data/lib/relaton/iana/bibliography.rb +47 -0
  255. data/lib/relaton/iana/data_fetcher.rb +71 -0
  256. data/lib/relaton/iana/item.rb +7 -0
  257. data/lib/relaton/iana/item_data.rb +6 -0
  258. data/lib/relaton/iana/parser.rb +146 -0
  259. data/lib/relaton/iana/processor.rb +68 -0
  260. data/lib/relaton/iana/util.rb +8 -0
  261. data/lib/relaton/iana.rb +29 -0
  262. data/lib/relaton/iec/bibliography.rb +283 -0
  263. data/lib/relaton/iec/data_fetcher.rb +216 -0
  264. data/lib/relaton/iec/data_parser.rb +391 -0
  265. data/lib/relaton/iec/hit.rb +26 -0
  266. data/lib/relaton/iec/hit_collection.rb +138 -0
  267. data/lib/relaton/iec/item_data.rb +7 -0
  268. data/lib/relaton/iec/model/bibdata.rb +8 -0
  269. data/lib/relaton/iec/model/bibitem.rb +8 -0
  270. data/lib/relaton/iec/model/docidentifier.rb +131 -0
  271. data/lib/relaton/iec/model/doctype.rb +12 -0
  272. data/lib/relaton/iec/model/ext.rb +53 -0
  273. data/lib/relaton/iec/model/item.rb +20 -0
  274. data/lib/relaton/iec/model/item_base.rb +12 -0
  275. data/lib/relaton/iec/model/relation.rb +7 -0
  276. data/lib/relaton/iec/model/stage_name.rb +13 -0
  277. data/lib/relaton/iec/processor.rb +73 -0
  278. data/lib/relaton/iec/statuses.yml +199 -0
  279. data/lib/relaton/iec/util.rb +8 -0
  280. data/lib/relaton/iec.rb +98 -0
  281. data/lib/relaton/ieee/balloting_group.rb +13 -0
  282. data/lib/relaton/ieee/bibdata.rb +8 -0
  283. data/lib/relaton/ieee/bibitem.rb +8 -0
  284. data/lib/relaton/ieee/bibliography.rb +51 -0
  285. data/lib/relaton/ieee/converter/bibxml/from_rfcxml.rb +10 -0
  286. data/lib/relaton/ieee/converter/bibxml/from_rfcxml_referencegroup.rb +10 -0
  287. data/lib/relaton/ieee/converter/bibxml.rb +20 -0
  288. data/lib/relaton/ieee/data_fetcher.rb +630 -0
  289. data/lib/relaton/ieee/doctype.rb +9 -0
  290. data/lib/relaton/ieee/editorial_group.rb +19 -0
  291. data/lib/relaton/ieee/ext.rb +36 -0
  292. data/lib/relaton/ieee/idams_parser.rb +323 -0
  293. data/lib/relaton/ieee/item.rb +11 -0
  294. data/lib/relaton/ieee/item_data.rb +7 -0
  295. data/lib/relaton/ieee/processor.rb +68 -0
  296. data/lib/relaton/ieee/pub_id.rb +161 -0
  297. data/lib/relaton/ieee/rawbib_id_parser.rb +548 -0
  298. data/lib/relaton/ieee/util.rb +8 -0
  299. data/lib/relaton/ieee.rb +29 -0
  300. data/lib/relaton/ietf/bibdata.rb +8 -0
  301. data/lib/relaton/ietf/bibitem.rb +8 -0
  302. data/lib/relaton/ietf/bibliography.rb +35 -0
  303. data/lib/relaton/ietf/bibxml_parser.rb +232 -0
  304. data/lib/relaton/ietf/data_fetcher.rb +278 -0
  305. data/lib/relaton/ietf/doctype.rb +9 -0
  306. data/lib/relaton/ietf/ext.rb +63 -0
  307. data/lib/relaton/ietf/item.rb +16 -0
  308. data/lib/relaton/ietf/item_base.rb +18 -0
  309. data/lib/relaton/ietf/item_data.rb +6 -0
  310. data/lib/relaton/ietf/processing_instructions.rb +79 -0
  311. data/lib/relaton/ietf/processor.rb +68 -0
  312. data/lib/relaton/ietf/relation.rb +9 -0
  313. data/lib/relaton/ietf/rfc/abstract.rb +19 -0
  314. data/lib/relaton/ietf/rfc/author.rb +21 -0
  315. data/lib/relaton/ietf/rfc/entry.rb +410 -0
  316. data/lib/relaton/ietf/rfc/entry_date.rb +21 -0
  317. data/lib/relaton/ietf/rfc/format.rb +19 -0
  318. data/lib/relaton/ietf/rfc/index.rb +46 -0
  319. data/lib/relaton/ietf/rfc/is_also.rb +21 -0
  320. data/lib/relaton/ietf/rfc/keywords.rb +19 -0
  321. data/lib/relaton/ietf/rfc/rfc_index_namespace.rb +11 -0
  322. data/lib/relaton/ietf/scraper.rb +68 -0
  323. data/lib/relaton/ietf/util.rb +8 -0
  324. data/lib/relaton/ietf/wg_name_resolver.rb +42 -0
  325. data/lib/relaton/ietf.rb +27 -0
  326. data/lib/relaton/iho/bibdata.rb +8 -0
  327. data/lib/relaton/iho/bibitem.rb +8 -0
  328. data/lib/relaton/iho/bibliography.rb +114 -0
  329. data/lib/relaton/iho/comment_period.rb +13 -0
  330. data/lib/relaton/iho/docidentifier.rb +31 -0
  331. data/lib/relaton/iho/doctype.rb +10 -0
  332. data/lib/relaton/iho/ext.rb +20 -0
  333. data/lib/relaton/iho/hash_parser_v1.rb +144 -0
  334. data/lib/relaton/iho/item.rb +20 -0
  335. data/lib/relaton/iho/item_base.rb +18 -0
  336. data/lib/relaton/iho/item_data.rb +6 -0
  337. data/lib/relaton/iho/processor.rb +54 -0
  338. data/lib/relaton/iho/relation.rb +9 -0
  339. data/lib/relaton/iho/structured_identifier.rb +20 -0
  340. data/lib/relaton/iho/util.rb +8 -0
  341. data/lib/relaton/iho.rb +27 -0
  342. data/lib/relaton/index/config.rb +52 -0
  343. data/lib/relaton/index/file_io.rb +305 -0
  344. data/lib/relaton/index/file_storage.rb +61 -0
  345. data/lib/relaton/index/id_number.rb +30 -0
  346. data/lib/relaton/index/pool.rb +41 -0
  347. data/lib/relaton/index/type.rb +159 -0
  348. data/lib/relaton/index/util.rb +18 -0
  349. data/lib/relaton/index.rb +60 -0
  350. data/lib/relaton/isbn/isbn.rb +61 -0
  351. data/lib/relaton/isbn/open_library.rb +43 -0
  352. data/lib/relaton/isbn/parser.rb +88 -0
  353. data/lib/relaton/isbn/processor.rb +48 -0
  354. data/lib/relaton/isbn/util.rb +8 -0
  355. data/lib/relaton/isbn.rb +19 -0
  356. data/lib/relaton/iso/bibliography.rb +407 -0
  357. data/lib/relaton/iso/data_fetcher.rb +338 -0
  358. data/lib/relaton/iso/data_parser.rb +444 -0
  359. data/lib/relaton/iso/hash_parser_v1.rb +177 -0
  360. data/lib/relaton/iso/hit.rb +57 -0
  361. data/lib/relaton/iso/hit_collection.rb +184 -0
  362. data/lib/relaton/iso/item_data.rb +28 -0
  363. data/lib/relaton/iso/model/bibdata.rb +10 -0
  364. data/lib/relaton/iso/model/bibitem.rb +8 -0
  365. data/lib/relaton/iso/model/contributor.rb +6 -0
  366. data/lib/relaton/iso/model/contributor_info.rb +9 -0
  367. data/lib/relaton/iso/model/docidentifier.rb +134 -0
  368. data/lib/relaton/iso/model/doctype.rb +13 -0
  369. data/lib/relaton/iso/model/ext.rb +35 -0
  370. data/lib/relaton/iso/model/item.rb +17 -0
  371. data/lib/relaton/iso/model/item_base.rb +22 -0
  372. data/lib/relaton/iso/model/organization.rb +9 -0
  373. data/lib/relaton/iso/model/project_number.rb +22 -0
  374. data/lib/relaton/iso/model/relation.rb +9 -0
  375. data/lib/relaton/iso/model/stagename.rb +14 -0
  376. data/lib/relaton/iso/model/structured_identifier.rb +31 -0
  377. data/lib/relaton/iso/processor.rb +84 -0
  378. data/lib/relaton/iso/scraper.rb +619 -0
  379. data/lib/relaton/iso/type/pubid.rb +50 -0
  380. data/lib/relaton/iso/util.rb +8 -0
  381. data/lib/relaton/iso.rb +30 -0
  382. data/lib/relaton/itu/bibliography.rb +90 -0
  383. data/lib/relaton/itu/data_fetcher.rb +104 -0
  384. data/lib/relaton/itu/data_parser_r.rb +140 -0
  385. data/lib/relaton/itu/hit.rb +22 -0
  386. data/lib/relaton/itu/hit_collection.rb +127 -0
  387. data/lib/relaton/itu/item_data.rb +6 -0
  388. data/lib/relaton/itu/model/approval_stage.rb +13 -0
  389. data/lib/relaton/itu/model/bibdata.rb +8 -0
  390. data/lib/relaton/itu/model/bibitem.rb +8 -0
  391. data/lib/relaton/itu/model/docidentifier.rb +9 -0
  392. data/lib/relaton/itu/model/doctype.rb +13 -0
  393. data/lib/relaton/itu/model/ext.rb +47 -0
  394. data/lib/relaton/itu/model/item.rb +13 -0
  395. data/lib/relaton/itu/model/meeting.rb +13 -0
  396. data/lib/relaton/itu/model/meeting_date.rb +15 -0
  397. data/lib/relaton/itu/model/question.rb +13 -0
  398. data/lib/relaton/itu/model/recommendation_status.rb +11 -0
  399. data/lib/relaton/itu/model/structured_identifier.rb +19 -0
  400. data/lib/relaton/itu/processor.rb +66 -0
  401. data/lib/relaton/itu/pubid.rb +177 -0
  402. data/lib/relaton/itu/radio_regulations_parser.rb +70 -0
  403. data/lib/relaton/itu/recommendation_parser.rb +161 -0
  404. data/lib/relaton/itu/scraper.rb +193 -0
  405. data/lib/relaton/itu/util.rb +8 -0
  406. data/lib/relaton/itu.rb +33 -0
  407. data/lib/relaton/jis/bibdata.rb +8 -0
  408. data/lib/relaton/jis/bibitem.rb +8 -0
  409. data/lib/relaton/jis/bibliography.rb +75 -0
  410. data/lib/relaton/jis/data_fetcher.rb +181 -0
  411. data/lib/relaton/jis/docidentifier.rb +21 -0
  412. data/lib/relaton/jis/doctype.rb +9 -0
  413. data/lib/relaton/jis/ext.rb +13 -0
  414. data/lib/relaton/jis/hit.rb +93 -0
  415. data/lib/relaton/jis/hit_collection.rb +127 -0
  416. data/lib/relaton/jis/item.rb +22 -0
  417. data/lib/relaton/jis/item_base.rb +26 -0
  418. data/lib/relaton/jis/item_data.rb +8 -0
  419. data/lib/relaton/jis/processor.rb +55 -0
  420. data/lib/relaton/jis/relation.rb +11 -0
  421. data/lib/relaton/jis/scraper.rb +232 -0
  422. data/lib/relaton/jis/structured_identifier.rb +13 -0
  423. data/lib/relaton/jis/util.rb +8 -0
  424. data/lib/relaton/jis.rb +33 -0
  425. data/lib/relaton/logger/channels/gh_issue.rb +78 -0
  426. data/lib/relaton/logger/config.rb +34 -0
  427. data/lib/relaton/logger/formatter_json.rb +8 -0
  428. data/lib/relaton/logger/formatter_string.rb +12 -0
  429. data/lib/relaton/logger/log.rb +64 -0
  430. data/lib/relaton/logger/log_device.rb +27 -0
  431. data/lib/relaton/logger/pool.rb +24 -0
  432. data/lib/relaton/logger.rb +18 -0
  433. data/lib/relaton/nist/bibdata.rb +8 -0
  434. data/lib/relaton/nist/bibitem.rb +8 -0
  435. data/lib/relaton/nist/bibliography.rb +191 -0
  436. data/lib/relaton/nist/comment_period.rb +15 -0
  437. data/lib/relaton/nist/data_fetcher.rb +84 -0
  438. data/lib/relaton/nist/date.rb +7 -0
  439. data/lib/relaton/nist/doctype.rb +7 -0
  440. data/lib/relaton/nist/ext.rb +16 -0
  441. data/lib/relaton/nist/hit.rb +18 -0
  442. data/lib/relaton/nist/hit_collection.rb +362 -0
  443. data/lib/relaton/nist/item.rb +17 -0
  444. data/lib/relaton/nist/item_data.rb +6 -0
  445. data/lib/relaton/nist/mods_parser.rb +276 -0
  446. data/lib/relaton/nist/processor.rb +68 -0
  447. data/lib/relaton/nist/pubs_export.rb +69 -0
  448. data/lib/relaton/nist/relation.rb +7 -0
  449. data/lib/relaton/nist/scraper.rb +290 -0
  450. data/lib/relaton/nist/series.yaml +49 -0
  451. data/lib/relaton/nist/util.rb +8 -0
  452. data/lib/relaton/nist.rb +34 -0
  453. data/lib/relaton/oasis/bibdata.rb +8 -0
  454. data/lib/relaton/oasis/bibitem.rb +8 -0
  455. data/lib/relaton/oasis/bibliography.rb +60 -0
  456. data/lib/relaton/oasis/browser_agent.rb +71 -0
  457. data/lib/relaton/oasis/data_fetcher.rb +94 -0
  458. data/lib/relaton/oasis/data_parser.rb +305 -0
  459. data/lib/relaton/oasis/data_parser_utils.rb +296 -0
  460. data/lib/relaton/oasis/data_part_parser.rb +239 -0
  461. data/lib/relaton/oasis/doctype.rb +7 -0
  462. data/lib/relaton/oasis/ext.rb +19 -0
  463. data/lib/relaton/oasis/item.rb +11 -0
  464. data/lib/relaton/oasis/item_data.rb +6 -0
  465. data/lib/relaton/oasis/processor.rb +68 -0
  466. data/lib/relaton/oasis/util.rb +8 -0
  467. data/lib/relaton/oasis.rb +28 -0
  468. data/lib/relaton/ogc/bibdata.rb +8 -0
  469. data/lib/relaton/ogc/bibitem.rb +8 -0
  470. data/lib/relaton/ogc/bibliography.rb +64 -0
  471. data/lib/relaton/ogc/data_fetcher.rb +110 -0
  472. data/lib/relaton/ogc/docidentifier.rb +6 -0
  473. data/lib/relaton/ogc/doctype.rb +12 -0
  474. data/lib/relaton/ogc/ext.rb +15 -0
  475. data/lib/relaton/ogc/hit.rb +18 -0
  476. data/lib/relaton/ogc/hit_collection.rb +36 -0
  477. data/lib/relaton/ogc/item.rb +13 -0
  478. data/lib/relaton/ogc/item_data.rb +6 -0
  479. data/lib/relaton/ogc/processor.rb +58 -0
  480. data/lib/relaton/ogc/scraper.rb +225 -0
  481. data/lib/relaton/ogc/util.rb +8 -0
  482. data/lib/relaton/ogc.rb +26 -0
  483. data/lib/relaton/oiml/bibdata.rb +8 -0
  484. data/lib/relaton/oiml/bibitem.rb +8 -0
  485. data/lib/relaton/oiml/bibliography.rb +94 -0
  486. data/lib/relaton/oiml/docidentifier.rb +33 -0
  487. data/lib/relaton/oiml/doctype.rb +13 -0
  488. data/lib/relaton/oiml/ext.rb +42 -0
  489. data/lib/relaton/oiml/item.rb +20 -0
  490. data/lib/relaton/oiml/item_base.rb +18 -0
  491. data/lib/relaton/oiml/item_data.rb +6 -0
  492. data/lib/relaton/oiml/processor.rb +54 -0
  493. data/lib/relaton/oiml/relation.rb +9 -0
  494. data/lib/relaton/oiml/util.rb +8 -0
  495. data/lib/relaton/oiml.rb +24 -0
  496. data/lib/relaton/omg/bibdata.rb +8 -0
  497. data/lib/relaton/omg/bibitem.rb +8 -0
  498. data/lib/relaton/omg/bibliography.rb +31 -0
  499. data/lib/relaton/omg/ext.rb +7 -0
  500. data/lib/relaton/omg/item.rb +8 -0
  501. data/lib/relaton/omg/item_data.rb +6 -0
  502. data/lib/relaton/omg/processor.rb +34 -0
  503. data/lib/relaton/omg/scraper.rb +141 -0
  504. data/lib/relaton/omg/util.rb +8 -0
  505. data/lib/relaton/omg.rb +24 -0
  506. data/lib/relaton/plateau/bibdata.rb +8 -0
  507. data/lib/relaton/plateau/bibitem.rb +8 -0
  508. data/lib/relaton/plateau/bibliography.rb +24 -0
  509. data/lib/relaton/plateau/data_fetcher.rb +153 -0
  510. data/lib/relaton/plateau/doctype.rb +7 -0
  511. data/lib/relaton/plateau/ext.rb +23 -0
  512. data/lib/relaton/plateau/handbook_parser.rb +95 -0
  513. data/lib/relaton/plateau/hit.rb +13 -0
  514. data/lib/relaton/plateau/hit_collection.rb +59 -0
  515. data/lib/relaton/plateau/item.rb +12 -0
  516. data/lib/relaton/plateau/item_data.rb +6 -0
  517. data/lib/relaton/plateau/parser.rb +101 -0
  518. data/lib/relaton/plateau/processor.rb +49 -0
  519. data/lib/relaton/plateau/technical_report_parser.rb +91 -0
  520. data/lib/relaton/plateau/util.rb +8 -0
  521. data/lib/relaton/plateau.rb +28 -0
  522. data/lib/relaton/un/bibdata.rb +8 -0
  523. data/lib/relaton/un/bibitem.rb +8 -0
  524. data/lib/relaton/un/bibliography.rb +48 -0
  525. data/lib/relaton/un/doctype.rb +10 -0
  526. data/lib/relaton/un/ext.rb +30 -0
  527. data/lib/relaton/un/hit.rb +56 -0
  528. data/lib/relaton/un/hit_collection.rb +61 -0
  529. data/lib/relaton/un/item.rb +11 -0
  530. data/lib/relaton/un/item_data.rb +6 -0
  531. data/lib/relaton/un/parser.rb +108 -0
  532. data/lib/relaton/un/processor.rb +38 -0
  533. data/lib/relaton/un/session.rb +25 -0
  534. data/lib/relaton/un/token_generator.rb +105 -0
  535. data/lib/relaton/un/util.rb +8 -0
  536. data/lib/relaton/un/wasm/decoder.rb +434 -0
  537. data/lib/relaton/un/wasm/instance.rb +101 -0
  538. data/lib/relaton/un/wasm/interpreter.rb +613 -0
  539. data/lib/relaton/un/wasm/memory.rb +112 -0
  540. data/lib/relaton/un/wasm/module.rb +47 -0
  541. data/lib/relaton/un/wasm.rb +17 -0
  542. data/lib/relaton/un/wasm_v_bg.wasm +0 -0
  543. data/lib/relaton/un.rb +28 -0
  544. data/lib/relaton/version.rb +1 -1
  545. data/lib/relaton/w3c/bibdata.rb +8 -0
  546. data/lib/relaton/w3c/bibitem.rb +8 -0
  547. data/lib/relaton/w3c/bibliography.rb +54 -0
  548. data/lib/relaton/w3c/data_fetcher.rb +309 -0
  549. data/lib/relaton/w3c/data_parser.rb +379 -0
  550. data/lib/relaton/w3c/doctype.rb +7 -0
  551. data/lib/relaton/w3c/ext.rb +11 -0
  552. data/lib/relaton/w3c/item.rb +12 -0
  553. data/lib/relaton/w3c/item_data.rb +6 -0
  554. data/lib/relaton/w3c/processor.rb +49 -0
  555. data/lib/relaton/w3c/pubid.rb +73 -0
  556. data/lib/relaton/w3c/safe_realize.rb +59 -0
  557. data/lib/relaton/w3c/util.rb +8 -0
  558. data/lib/relaton/w3c.rb +25 -0
  559. data/lib/relaton/xsf/bibdata.rb +8 -0
  560. data/lib/relaton/xsf/bibitem.rb +8 -0
  561. data/lib/relaton/xsf/bibliography.rb +24 -0
  562. data/lib/relaton/xsf/data_fetcher.rb +56 -0
  563. data/lib/relaton/xsf/hit.rb +17 -0
  564. data/lib/relaton/xsf/hit_collection.rb +24 -0
  565. data/lib/relaton/xsf/item.rb +7 -0
  566. data/lib/relaton/xsf/item_data.rb +6 -0
  567. data/lib/relaton/xsf/processor.rb +50 -0
  568. data/lib/relaton/xsf/util.rb +9 -0
  569. data/lib/relaton/xsf.rb +30 -0
  570. data/lib/relaton-core.rb +1 -0
  571. data/lib/relaton.rb +44 -9
  572. metadata +708 -150
  573. data/.github/workflows/rake.yml +0 -14
  574. data/.github/workflows/release.yml +0 -24
  575. data/.github/workflows/rubocop.yml +0 -48
  576. data/.gitignore +0 -12
  577. data/.rspec +0 -3
  578. data/.rubocop.yml +0 -12
  579. data/CLAUDE.md +0 -70
  580. data/Gemfile +0 -21
  581. data/Rakefile +0 -6
  582. data/docs/CHANGELOG.adoc +0 -16
  583. data/docs/VERSIONING_POLICY.adoc +0 -38
  584. data/docs/navigation.adoc +0 -6
  585. data/lib/relaton/config.rb +0 -24
  586. data/lib/relaton/db_cache.rb +0 -230
  587. data/lib/relaton/registry.rb +0 -118
  588. data/lib/relaton/util.rb +0 -7
  589. data/lib/relaton/workers_pool.rb +0 -21
  590. data/relaton.gemspec +0 -61
  591. data/spec/relaton/config_spec.rb +0 -10
  592. data/spec/relaton/db_cache_spec.rb +0 -51
  593. data/spec/relaton/db_spec.rb +0 -556
  594. data/spec/relaton/registry_spec.rb +0 -178
  595. data/spec/relaton/util_spec.rb +0 -3
  596. data/spec/relaton_spec.rb +0 -725
  597. data/spec/spec_helper.rb +0 -45
  598. data/spec/support/gb_t_20223_2006.xml +0 -33
  599. data/spec/support/iso_111111119115_1.xml +0 -0
  600. data/spec/support/iso_19115_1.xml +0 -115
  601. data/spec/support/iso_19115_2.xml +0 -95
  602. data/spec/support/rfc_8341.xml +0 -46
  603. data/spec/vcr_cassetes/3gpp_tr_00_01u_umts_3_0_0.yml +0 -12720
  604. data/spec/vcr_cassetes/api_relaton_org.yml +0 -121
  605. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +0 -143
  606. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +0 -199
  607. data/spec/vcr_cassetes/cie_001_1980.yml +0 -401
  608. data/spec/vcr_cassetes/cipm_meeting_43.yml +0 -1513
  609. data/spec/vcr_cassetes/doi_10_6028_nist_ir_8245.yml +0 -86
  610. data/spec/vcr_cassetes/ecma_6.yml +0 -112
  611. data/spec/vcr_cassetes/en_10160_1999.yml +0 -13624
  612. data/spec/vcr_cassetes/gb_t_20223_2006.yml +0 -733
  613. data/spec/vcr_cassetes/ieee_528_2019.yml +0 -2786
  614. data/spec/vcr_cassetes/iso_111111119115_1.yml +0 -12951
  615. data/spec/vcr_cassetes/iso_19115_1.yml +0 -13177
  616. data/spec/vcr_cassetes/iso_19115_1_2.yml +0 -369
  617. data/spec/vcr_cassetes/iso_19115_1_std.yml +0 -13177
  618. data/spec/vcr_cassetes/iso_19115_all_parts.yml +0 -229
  619. data/spec/vcr_cassetes/iso_19133_2005.yml +0 -148
  620. data/spec/vcr_cassetes/iso_combined_applied.yml +0 -364
  621. data/spec/vcr_cassetes/iso_combined_included.yml +0 -364
  622. data/spec/vcr_cassetes/iso_dis.yml +0 -157
  623. data/spec/vcr_cassetes/ogc_19_025r1.yml +0 -371
  624. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +0 -317
  625. data/spec/vcr_cassetes/rfc_8341.yml +0 -1272
@@ -0,0 +1,362 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zip"
4
+ require "fileutils"
5
+ require "addressable/uri"
6
+ require "net/http"
7
+
8
+ module Relaton
9
+ module Nist
10
+ class HitCollection < Core::HitCollection
11
+ include Core::DateParser
12
+
13
+ GHNISTDATA = "https://raw.githubusercontent.com/relaton/relaton-data-nist/v2/"
14
+
15
+ attr_reader :reference
16
+ attr_accessor :array
17
+
18
+ #
19
+ # @param [String] ref reference
20
+ # @param [String, nil] year reference
21
+ # @param [Hash] opts options
22
+ # @option opts [String] :stage stage of document
23
+ #
24
+ def initialize(ref, year = nil, opts = {})
25
+ super(ref, year)
26
+ @reference = ref
27
+ @opts = opts
28
+ end
29
+
30
+ #
31
+ # Create hits collection instance and search hits
32
+ #
33
+ # @param [String] ref reference
34
+ # @param [String, nil] year reference
35
+ # @param [Hash] opts options
36
+ # @option opts [String] :stage stage of document
37
+ #
38
+ # @return [Relaton::Nist::HitCollection] hits collection
39
+ #
40
+ def self.search(ref, year = nil, opts = {})
41
+ new(ref, year, opts).search
42
+ end
43
+
44
+ #
45
+ # Search nist in JSON file or GitHub repo
46
+ #
47
+ # @return [Relaton::Nist::HitCollection] hits collection
48
+ #
49
+ def search
50
+ @array = from_json
51
+ @array = from_ga unless @array.any?
52
+ sort_hits!
53
+ end
54
+
55
+ #
56
+ # Filter hits by reference's parts
57
+ #
58
+ # @return [Array<Relaton::Nist::Hit>] hits
59
+ #
60
+ def search_filter # rubocop:disable Metrics/MethodLength
61
+ refid = ::Pubid::Nist::Identifier.parse(@reference)
62
+ parts = exclude_parts refid
63
+ arr = @array.select do |item|
64
+ pubid = ::Pubid::Nist::Identifier.parse(item.hit[:code])
65
+ pubid.exclude(*parts) == refid
66
+ rescue StandardError
67
+ item.hit[:code] == ref
68
+ end
69
+ rescue StandardError
70
+ arr = @array.select { |item| item.hit[:code] == ref }
71
+ ensure
72
+ dup = self.dup
73
+ dup.array = arr
74
+ return dup
75
+ end
76
+
77
+ # The edition/revision/version attributes that together identify a
78
+ # specific edition of a document. Treated as one unit when deciding
79
+ # whether a reference is "incomplete" (no edition given).
80
+ EDITION_FAMILY = %i[
81
+ edition edition_component revision revision_year revision_month
82
+ version version_component edition_year
83
+ ].freeze
84
+
85
+ def exclude_parts(pubid)
86
+ # Pubid 2.x exposes update via two slots (:update and :update_component),
87
+ # and pubs_export_id assigns to update_component — so checking only
88
+ # :update misses the case where the indexed pubid carries the update
89
+ # info there. Same logic for both legacy and component slots.
90
+ parts = %i[stage update update_component].select do |part|
91
+ pubid.respond_to?(part) && pubid.send(part).nil?
92
+ end
93
+
94
+ # Incomplete reference: no edition/revision/version specified (e.g.
95
+ # "NIST SP 800-60v1"). Exclude the whole edition family so it matches
96
+ # any edition; result selection (sort_hits! + results_filter) then
97
+ # picks the latest/preferred one.
98
+ if EDITION_FAMILY.all? { |p| !pubid.respond_to?(p) || pubid.send(p).nil? }
99
+ parts += EDITION_FAMILY
100
+ end
101
+ parts
102
+ end
103
+
104
+ private
105
+
106
+ def code_parts(code) # rubocop:disable Metrics/MethodLength
107
+ {
108
+ series: match(/(?<val>(?:SP|FIPS|CSWP|IR|ITL\sBulletin|White\sPaper))\s/, code),
109
+ code: match(/(?<val>[0-9-]+(?:(?!(?:ver|r|v|pt)\d|-add\d?)[A-Za-z-])*|Research\sLibrary)/, code),
110
+ prt: match(/(?:pt|\sPart\s)(?<val>\d+)/, code),
111
+ vol: match(/(?:v|\sVol\.\s)(?<val>\d+)/, code),
112
+ ver: match(/(?:ver|\sVer\.\s|Version\s)(?<val>[\d.]+)/, code),
113
+ rev: match(/(?:r|Rev\.\s)(?<val>\d+)/, code),
114
+ add: match(/(?:-add|\sAdd)(?:endum)?(?<val>\d*)/, code),
115
+ draft: !match(/\((?:Retired\s)?Draft\)/, code).nil?,
116
+ }
117
+ end
118
+
119
+ def doi_parts(json) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
120
+ return unless json && json["doi"]
121
+
122
+ id = json["doi"].split("/").last
123
+ {
124
+ series: match(/(?:SP|FIPS|CSWP|IR|ITL\sBulletin|White\sPaper)(?=\.)/, id),
125
+ code: match(/(?<=\.)\d+(?:-\d+)*(?:[[:alpha:]](?!\d|raft|er|t?\d))?/, id),
126
+ prt: match(/pt?(?<val>\d+)/, id),
127
+ vol: match(/v(?<val>\d+)(?!\.\d)/, id),
128
+ ver: match(/v(?:er)?(?<val>[\d.]+)/, id),
129
+ rev: match(/r(?<val>\d+)/, id),
130
+ add: match(/-Add(?<val>\d*)/, id),
131
+ draft: !match(/\.ipd|-draft/, id).nil?,
132
+ }
133
+ end
134
+
135
+ #
136
+ # Parse reference parts
137
+ #
138
+ # @return [Hash] reference parts
139
+ #
140
+ def refparts # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
141
+ @refparts ||= {
142
+ perfix: match(/^(NIST|NBS)/, ref),
143
+ series: match(/(SP|FIPS|CSWP|IR|ITL\sBulletin|White\sPaper)(?=\.|\s)/, ref),
144
+ code: match(/(?<=\.|\s)[0-9-]+(?:(?!(ver|r|v|pt)\d|-add\d?)[A-Za-z-])*|Research\sLibrary/, ref),
145
+ prt: match(/(?:(?<dl>\.)?pt(?(<dl>)-)|\sPart\s)(?<val>[A-Z\d]+)/, ref),
146
+ vol: match(/(?:(?<dl>\.)?v(?(<dl>)-)|\sVol\.\s)(?<val>\d+)/, ref),
147
+ ver: match(/(?:(?<dl>\.)?\s?ver|\sVer\.\s)(?<val>\d(?(<dl>)[-\d]|[.\d])*)/, ref)&.gsub(/-/, "."),
148
+ rev: match(/(?:(?:(?<dl>\.)|[^a-z])r|\sRev\.\s)(?(<dl>)-)(?<val>\d+)/, ref),
149
+ add: match(/(?:(?<dl>\.)?add|\/Add|\sAdd)(?(<dl>)-)(?<val>\d*)/, ref),
150
+ draft: !(match(/\((?:Draft|PD)\)/, ref).nil? && @opts[:stage].nil?),
151
+ }
152
+ end
153
+
154
+ #
155
+ # Match regex to reference
156
+ #
157
+ # @param [Regexp] regex regex
158
+ # @param [String] code reference
159
+ #
160
+ # @return [String, nil] matched string
161
+ #
162
+ def match(regex, code)
163
+ m = regex.match(code)
164
+ return unless m
165
+
166
+ m.named_captures["val"] || m.to_s
167
+ end
168
+
169
+ #
170
+ # Generate reference from parts
171
+ #
172
+ # @return [String] reference
173
+ #
174
+ def full_ref # rubocop:disable Metrics/AbcSize
175
+ @full_ref ||= begin
176
+ r = [refparts[:perfix], refparts[:series], refparts[:code]].compact.join " "
177
+ r += "pt#{refparts[:prt]}" if refparts[:prt]
178
+ r += "ver#{refparts[:ver]}" if refparts[:ver]
179
+ r += "v#{refparts[:vol]}" if refparts[:vol]
180
+ r += "r#{refparts[:rev]}" if refparts[:rev]
181
+ r += "-add#{refparts[:add]}" if refparts[:add]
182
+ r
183
+ end
184
+ end
185
+
186
+ #
187
+ # Sort hits by sort_value and release date
188
+ #
189
+ # @return [self] sorted hits collection
190
+ #
191
+ def sort_hits!
192
+ @array.sort! do |a, b|
193
+ base_a, upd_a = base_and_update(a.hit[:code])
194
+ base_b, upd_b = base_and_update(b.hit[:code])
195
+
196
+ cmp = base_a <=> base_b
197
+ next cmp unless cmp.zero?
198
+
199
+ # Same base code: prefer higher /UpdN (latest update wins).
200
+ cmp = upd_b <=> upd_a
201
+ next cmp unless cmp.zero?
202
+
203
+ b.hit[:release_date] <=> a.hit[:release_date]
204
+ end
205
+ self
206
+ end
207
+
208
+ # Split a code like "NIST FIPS 140-2/Upd2" into ["NIST FIPS 140-2", 2].
209
+ # Codes without an update suffix return update 0.
210
+ def base_and_update(code)
211
+ code = code.to_s
212
+ if (m = code.match(%r{\A(.*?)/Upd(\d+)\z}))
213
+ [m[1], m[2].to_i]
214
+ else
215
+ [code, 0]
216
+ end
217
+ end
218
+
219
+ def pubid(id = ref)
220
+ Pubid::Nist::Identifier.parse(id).to_s
221
+ rescue StandardError
222
+ id
223
+ end
224
+
225
+ #
226
+ # Get hit from GitHub repo
227
+ #
228
+ # @return [Array<Relaton::Nist::Hit>] hits
229
+ #
230
+ def from_ga # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
231
+ Util.info "Fetching from Relaton repository ...", key: @reference
232
+ # Parse the reference so index.search narrows candidates by number via
233
+ # binary search; fall back to the raw string for index lookup if pubid
234
+ # can't parse it.
235
+ r = begin
236
+ ::Pubid::Nist::Identifier.parse(@reference)
237
+ rescue StandardError
238
+ @reference
239
+ end
240
+
241
+ index = Relaton::Index.find_or_create(
242
+ :nist, url: "#{GHNISTDATA}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml",
243
+ pubid_class: ::Pubid::Nist::Identifier
244
+ )
245
+ # search(r) narrows candidates by number via binary search; the block
246
+ # keeps the broad family match (this doc and all its editions/parts)
247
+ # the old string index gave via substring, leaving finer filtering to
248
+ # search_filter.
249
+ needle = r.to_s
250
+ rows = index.search(r) { |row| row[:id].to_s.include?(needle) }
251
+ .sort_by { |row| row[:id].to_s }
252
+
253
+ rows.map do |row|
254
+ # index-v2 stores Pubid objects; the rest of the pipeline (search_filter,
255
+ # Hit, Scraper) works on string codes, so stringify at the boundary.
256
+ Hit.new({ code: row[:id].to_s, path: row[:file] }, self)
257
+ end
258
+ rescue OpenURI::HTTPError => e
259
+ return [] if e.io.status[0] == "404"
260
+
261
+ raise e
262
+ end
263
+
264
+ #
265
+ # Fetches data from json
266
+ #
267
+ # @return [Array<Relaton::Nist::Hit>] hits
268
+ #
269
+ def from_json # rubocop:disable Metrics/AbcSize
270
+ Util.info "Fetching from csrc.nist.gov ...", key: @reference
271
+ select_data.map do |h|
272
+ /(?<series>(?<=-)\w+$)/ =~ h["series"]
273
+ title = [h["title-main"], h["title-sub"]].compact.join " - "
274
+ release_date = parse_date(h["published-date"], str: false)
275
+ Hit.new({ code: pubs_export_id(h), series: series.upcase, title: title, url: h["uri"],
276
+ status: h["status"], release_date: release_date, json: h }, self)
277
+ end
278
+ end
279
+
280
+ def pubs_export_id(json) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
281
+ if json && json["doi"]
282
+ json["doi"].sub(/^10.6028\//, "")
283
+ else
284
+ json["docidentifier"]
285
+ end => id
286
+
287
+ id.sub!(/(?:-draft\d*|\.\wpd)$/, "")
288
+ id = id.gsub(".", " ").sub(/-Add(\d*)$/, ' Add.\1') if id.match?(/-Add\d*$/)
289
+ # Normalize to space-separated form so pubid 2.x parses as
290
+ # parsed_format=:short and renders without dots; also force the
291
+ # "NIST " prefix so publisher_was_parsed is set.
292
+ parse_input = id.gsub(/\bNIST\./, "NIST ")
293
+ parse_input = "NIST #{parse_input}" unless parse_input.start_with?("NIST ")
294
+ pid = ::Pubid::Nist::Identifier.parse(parse_input)
295
+
296
+ # Canonicalize edition spelling: DOI-derived codes are already short
297
+ # ("…r2"), but no-DOI drafts come from the verbose docidentifier
298
+ # ("… Rev. 2") and pubid preserves that spelling via original_prefix.
299
+ # Drop it so every code renders the canonical short form.
300
+ pid.edition.original_prefix = nil if pid.respond_to?(:edition) && pid.edition
301
+
302
+ # Stage: URI is authoritative, fall back to iteration. "final" => no stage.
303
+ uri_stage = json["uri"] && json["uri"][%r{/(final|ipd|fpd|\dpd)(?:-\(\d+\))?(?:/|$)}, 1]
304
+ stage_src = uri_stage || json["iteration"]
305
+ case stage_src
306
+ when nil, "final"
307
+ # no stage — "final" means published
308
+ when "fpd"
309
+ pid.stage = ::Pubid::Nist::Components::Stage.new id: "f", type: "pd"
310
+ when /\A(\w)pd\z/
311
+ pid.stage = ::Pubid::Nist::Components::Stage.new id: Regexp.last_match(1), type: "pd"
312
+ end
313
+
314
+ /\/upd(?<upd>\d+)\// =~ json["uri"]
315
+ # In pubid 2.x render paths the Update is read from
316
+ # update_component (Components::Update), not the legacy :update
317
+ # slot — assigning to :update would render as "-upd/Upd2" via the
318
+ # elsif fallback path in Base#to_short_style.
319
+ pid.update_component = ::Pubid::Nist::Components::Update.new(number: upd) if upd
320
+ pid.to_s
321
+ rescue StandardError
322
+ id += " #{json["iteration"]}" if json["iteration"] && json["iteration"] != "final"
323
+ id
324
+ end
325
+
326
+ #
327
+ # Select data from json
328
+ #
329
+ # @return [Array<Hash>] selected data
330
+ #
331
+ def select_data # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength,Metrics/PerceivedComplexity
332
+ return [] unless refparts[:code]
333
+
334
+ r = "#{refparts[:series]} #{refparts[:code]}"
335
+ d = parse_date(year, str: false) if year
336
+ PubsExport.instance.data.select do |doc|
337
+ next unless match_year?(doc, d)
338
+
339
+ doc["docidentifier"].include?(r) || doc["docidentifier"].include?(full_ref)
340
+ end
341
+ end
342
+
343
+ #
344
+ # Check if issued date is match to year
345
+ #
346
+ # @param doc [Hash] document's metadata
347
+ # @param date [Date] first day of year
348
+ #
349
+ # @return [Boolean]
350
+ #
351
+ def match_year?(doc, date)
352
+ return true unless year
353
+
354
+ d = doc["issued-date"] || doc["published-date"]
355
+ pidate = parse_date(d, str: false)
356
+ pidate.between? date, date.next_year.prev_day
357
+ rescue ::Date::Error, TypeError
358
+ false
359
+ end
360
+ end
361
+ end
362
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "date"
2
+ require_relative "ext"
3
+
4
+ module Relaton
5
+ module Nist
6
+ class Relation < Bib::Relation
7
+ end
8
+
9
+ class Item < Bib::Item
10
+ model ItemData
11
+
12
+ attribute :date, Date, collection: true
13
+ attribute :relation, Relation, collection: true, initialize_empty: true
14
+ attribute :ext, Ext
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module Relaton
2
+ module Nist
3
+ class ItemData < Bib::ItemData
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pubid"
4
+ require "loc_mods"
5
+
6
+ module Relaton
7
+ module Nist
8
+ class ModsParser
9
+ RELATION_TYPES = {
10
+ "otherVersion" => "editionOf",
11
+ "preceding" => "updates",
12
+ "succeeding" => "updatedBy",
13
+ }.freeze
14
+
15
+ ATTRS = %i[type docidentifier title source abstract date contributor
16
+ relation place series].freeze
17
+
18
+ def initialize(doc, series, errors = {})
19
+ @doc = doc
20
+ @series = series
21
+ @errors = errors
22
+ end
23
+
24
+ # @return [Bib::ItemData]
25
+ def parse
26
+ args = ATTRS.each_with_object({}) do |attr, hash|
27
+ hash[attr] = send("parse_#{attr}")
28
+ end
29
+ args[:ext] = Ext.new(doctype: parse_doctype, flavor: "nilst")
30
+ ItemData.new(**args)
31
+ end
32
+
33
+ def parse_type = "standard"
34
+
35
+ # @return [Array<Bib::Docidentifier>]
36
+ def parse_docidentifier
37
+ ids = [
38
+ { type: "NIST", content: pub_id, primary: true },
39
+ { type: "DOI", content: parse_doi },
40
+ ].reject { |id| id[:content].nil? || id[:content].empty? }
41
+ @errors[:docidentifier] &&= ids.empty?
42
+ ids.map { |id| Bib::Docidentifier.new(**id) }
43
+ end
44
+
45
+ # @return [String]
46
+ def pub_id = get_id_from_str parse_doi
47
+
48
+ def get_id_from_str(str)
49
+ return if str.nil? || str.empty?
50
+
51
+ # DOIs arrive dotted ("NIST.HB.135e2022-upd1"); that MR-style form
52
+ # parses through a path that skips UpdateCodes date lookup and drops
53
+ # letter suffixes. Space the leading "PUB.SERIES." prefix so it parses
54
+ # like the canonical short form (only the separator dots are touched,
55
+ # not any inside the number). Then force :human rendering.
56
+ spaced = str.sub(/\A(NIST|NBS)\.([A-Z][A-Za-z]*)\./, '\1 \2 ')
57
+ ::Pubid::Nist::Identifier.parse(spaced).to_s(format: :human)
58
+ rescue Parslet::ParseFailed
59
+ str.gsub(".", " ").sub(/^[\D]+/, &:upcase)
60
+ end
61
+
62
+ # @return [String]
63
+ def replace_wrong_doi(id)
64
+ case id
65
+ when "NBS.CIRC.sup" then "NBS.CIRC.24e7sup"
66
+ when "NBS.CIRC.supJun1925-Jun1926" then "NBS.CIRC.24e7sup2"
67
+ when "NBS.CIRC.supJun1925-Jun1927" then "NBS.CIRC.24e7sup3"
68
+ when "NBS.CIRC.24supJuly1922" then "NBS.CIRC.24e6sup"
69
+ when "NBS.CIRC.24supJan1924" then "NBS.CIRC.24e6sup2"
70
+ else id
71
+ end
72
+ end
73
+
74
+ def parse_doi
75
+ url = @doc.location.reduce(nil) { |m, l| m || l.url.detect { |u| u.usage == "primary display" } }
76
+ return if url.nil?
77
+
78
+ id = remove_doi_prefix(url.content)
79
+ return if id.nil?
80
+
81
+ replace_wrong_doi(id)
82
+ end
83
+
84
+ def remove_doi_prefix(id) = id.match(/10\.6028\/(.+)/)&.send(:[], 1)
85
+
86
+ # @return [Array<Bib::Title>]
87
+ def parse_title
88
+ title = @doc.title_info.reduce([]) do |a, ti|
89
+ next a if ti.type == "alternative"
90
+
91
+ a += ti.title.map { |t| create_title(t, "title-main", ti.non_sort&.first) }
92
+ next a unless ti.sub_title
93
+
94
+ a + ti.sub_title.map { |t| create_title(t, "title-part") }
95
+ end
96
+ if title.size > 1
97
+ content = title.map { |t| t.content }.join(" - ")
98
+ title << create_title(content, "main")
99
+ elsif title.size == 1
100
+ title[0].instance_variable_set :@type, "main"
101
+ end
102
+ @errors[:title] &&= title.empty?
103
+ title
104
+ end
105
+
106
+ def create_title(title, type, non_sort = nil)
107
+ content = title.gsub("\n", " ").squeeze(" ").strip
108
+ content = "#{non_sort.content}#{content}".squeeze(" ") if non_sort
109
+ Bib::Title.new content: content, type: type, language: "en", script: "Latn"
110
+ end
111
+
112
+ def parse_source
113
+ source = @doc.location.map do |location|
114
+ url = location.url.first
115
+ type = url.usage == "primary display" ? "doi" : "src"
116
+ Bib::Uri.new content: url.content, type: type
117
+ end
118
+ @errors[:source] &&= source.empty?
119
+ source
120
+ end
121
+
122
+ def parse_abstract
123
+ abstract = Array(@doc.abstract).map do |a|
124
+ content = a.content.gsub("\n", " ").squeeze(" ").strip
125
+ Bib::Abstract.new content: content, language: "en",
126
+ script: "Latn"
127
+ end
128
+ @errors[:abstract] &&= abstract.empty?
129
+ abstract
130
+ end
131
+
132
+ def parse_date
133
+ date = @doc.origin_info[0].date_issued.map do |di|
134
+ create_date(di, "issued")
135
+ end.compact
136
+ @errors[:date] &&= date.empty?
137
+ date
138
+ end
139
+
140
+ def create_date(date, type)
141
+ Date.new type: type, at: decode_date(date)
142
+ rescue ::Date::Error
143
+ end
144
+
145
+ def decode_date(date)
146
+ if date.encoding == "marc" && date.content.size == 6
147
+ ::Date.strptime(date.content, "%y%m%d").to_s
148
+ elsif date.encoding == "iso8601"
149
+ ::Date.strptime(date.content, "%Y%m%d").to_s
150
+ else date.content
151
+ end
152
+ end
153
+
154
+ def parse_doctype = Doctype.new(content: "standard")
155
+
156
+ def parse_contributor
157
+ # exclude primary contributors to avoid duplication
158
+ contributor = @doc.name.reject { |n| n.usage == "primary" }.map do |name|
159
+ entity, default_role = create_entity(name)
160
+ next unless entity
161
+
162
+ role = (name.role || []).reduce([]) do |a, r|
163
+ a + r.role_term.map { |rt| Bib::Contributor::Role.new(type: rt.content) }
164
+ end
165
+ role << Bib::Contributor::Role.new(type: default_role) if role.empty?
166
+ create_contributor(entity, role)
167
+ end.compact
168
+ @errors[:contributor] &&= contributor.empty?
169
+ contributor
170
+ end
171
+
172
+ def create_contributor(entity, role)
173
+ case entity
174
+ when Bib::Person
175
+ Bib::Contributor.new(role: role, person: entity)
176
+ when Bib::Organization
177
+ Bib::Contributor.new(role: role, organization: entity)
178
+ end
179
+ end
180
+
181
+ def create_entity(name)
182
+ case name.type
183
+ when "personal" then [create_person(name), "author"]
184
+ when "corporate" then [create_org(name), "publisher"]
185
+ end
186
+ end
187
+
188
+ def create_person(name)
189
+ # exclude typed name parts because they are not actual name parts
190
+ cname = name.name_part.reject(&:type).map(&:content).join(" ")
191
+ completename = Bib::LocalizedString.new(content: cname, language: "en")
192
+ fname = Bib::FullName.new(completename: completename)
193
+ name_id = name.name_identifier&.first
194
+ identifier = []
195
+ if name_id
196
+ identifier << Bib::Person::Identifier.new(type: "uri",
197
+ content: name_id.content)
198
+ end
199
+ Bib::Person.new(name: fname, identifier: identifier)
200
+ end
201
+
202
+ def create_org(name)
203
+ names = name.name_part.reject(&:type).map do |n|
204
+ Bib::TypedLocalizedString.new(
205
+ content: n.content.gsub("\n", " ").squeeze(" ").strip,
206
+ )
207
+ end
208
+ url = name.name_identifier&.first&.content
209
+ identifier = []
210
+ if url
211
+ identifier << Bib::OrganizationType::Identifier.new(type: "uri",
212
+ content: url)
213
+ end
214
+ Bib::Organization.new(name: names, identifier: identifier)
215
+ end
216
+
217
+ def parse_relation
218
+ relations = Array(@doc.related_item).reject { |ri| ri.type == "series" }.filter_map do |ri|
219
+ type = RELATION_TYPES[ri.type]
220
+ bibitem = create_related_item(ri)
221
+ Relation.new(type: type, bibitem: bibitem) if bibitem
222
+ end
223
+ @errors[:relation] &&= relations.empty?
224
+ relations
225
+ end
226
+
227
+ def create_related_item(item)
228
+ item_id = get_id_from_str related_item_id(item)
229
+ return if item_id.nil? || item_id.empty?
230
+
231
+ docid = Bib::Docidentifier.new(type: "NIST", content: item_id)
232
+ fref = Bib::Formattedref.new(content: item_id)
233
+ ItemData.new(docidentifier: [docid], formattedref: fref)
234
+ end
235
+
236
+ def related_item_id(item)
237
+ if item.other_type && item.other_type[0..6] == "10.6028"
238
+ item.other_type
239
+ else
240
+ item.name[0].name_part[0].content
241
+ end => id
242
+ doi = remove_doi_prefix(id)
243
+ return if doi.nil?
244
+
245
+ replace_wrong_doi(doi)
246
+ end
247
+
248
+ def parse_place
249
+ place = @doc.origin_info.select { |p| p.event_type == "publisher" }.map do |p|
250
+ pl = p.place[0].place_term[0].content
251
+ /(?<city>\w+), (?<state>\w+)/ =~ pl
252
+ Bib::Place.new(city: city, region: create_region(state))
253
+ end
254
+ @errors[:place] &&= place.empty?
255
+ place
256
+ end
257
+
258
+ def create_region(state)
259
+ [Bib::Place::RegionType.new(iso: state)]
260
+ rescue ArgumentError
261
+ []
262
+ end
263
+
264
+ def parse_series
265
+ series = Array(@doc.related_item).select { |ri| ri.type == "series" }.map do |ri|
266
+ tinfo = ri.title_info[0]
267
+ tcontent = tinfo.title[0].strip
268
+ title = Bib::Title.new(content: tcontent)
269
+ Bib::Series.new(title: [title], number: tinfo.part_number&.first)
270
+ end
271
+ @errors[:series] &&= series.empty?
272
+ series
273
+ end
274
+ end
275
+ end
276
+ end