relaton 2.2.0.pre.alpha.1 → 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 (610) 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/registry.rb +4 -4
  188. data/lib/relaton/db.rb +0 -1
  189. data/lib/relaton/doi/crossref.rb +72 -0
  190. data/lib/relaton/doi/parser.rb +827 -0
  191. data/lib/relaton/doi/processor.rb +65 -0
  192. data/lib/relaton/doi/util.rb +8 -0
  193. data/lib/relaton/doi.rb +20 -0
  194. data/lib/relaton/ecma/bibdata.rb +8 -0
  195. data/lib/relaton/ecma/bibitem.rb +8 -0
  196. data/lib/relaton/ecma/bibliography.rb +81 -0
  197. data/lib/relaton/ecma/data_fetcher.rb +103 -0
  198. data/lib/relaton/ecma/data_parser.rb +49 -0
  199. data/lib/relaton/ecma/edition_parser.rb +80 -0
  200. data/lib/relaton/ecma/ext.rb +7 -0
  201. data/lib/relaton/ecma/item.rb +11 -0
  202. data/lib/relaton/ecma/item_data.rb +6 -0
  203. data/lib/relaton/ecma/memento_parser.rb +60 -0
  204. data/lib/relaton/ecma/page_fetcher.rb +27 -0
  205. data/lib/relaton/ecma/parser_common.rb +33 -0
  206. data/lib/relaton/ecma/processor.rb +66 -0
  207. data/lib/relaton/ecma/standard_parser.rb +134 -0
  208. data/lib/relaton/ecma/util.rb +8 -0
  209. data/lib/relaton/ecma.rb +24 -0
  210. data/lib/relaton/etsi/bibdata.rb +10 -0
  211. data/lib/relaton/etsi/bibitem.rb +10 -0
  212. data/lib/relaton/etsi/bibliography.rb +46 -0
  213. data/lib/relaton/etsi/data_fetcher.rb +128 -0
  214. data/lib/relaton/etsi/data_parser.rb +208 -0
  215. data/lib/relaton/etsi/doctype.rb +30 -0
  216. data/lib/relaton/etsi/ext.rb +31 -0
  217. data/lib/relaton/etsi/item.rb +15 -0
  218. data/lib/relaton/etsi/item_data.rb +6 -0
  219. data/lib/relaton/etsi/processor.rb +69 -0
  220. data/lib/relaton/etsi/pubid.rb +37 -0
  221. data/lib/relaton/etsi/status.rb +13 -0
  222. data/lib/relaton/etsi/util.rb +8 -0
  223. data/lib/relaton/etsi.rb +25 -0
  224. data/lib/relaton/gb/bibdata.rb +8 -0
  225. data/lib/relaton/gb/bibitem.rb +8 -0
  226. data/lib/relaton/gb/bibliography.rb +145 -0
  227. data/lib/relaton/gb/ccs.rb +14 -0
  228. data/lib/relaton/gb/committee.rb +13 -0
  229. data/lib/relaton/gb/docidentifier.rb +23 -0
  230. data/lib/relaton/gb/doctype.rb +9 -0
  231. data/lib/relaton/gb/ext.rb +36 -0
  232. data/lib/relaton/gb/gb_scraper.rb +61 -0
  233. data/lib/relaton/gb/gb_type.rb +20 -0
  234. data/lib/relaton/gb/hit.rb +48 -0
  235. data/lib/relaton/gb/hit_collection.rb +19 -0
  236. data/lib/relaton/gb/item.rb +13 -0
  237. data/lib/relaton/gb/item_data.rb +6 -0
  238. data/lib/relaton/gb/processor.rb +46 -0
  239. data/lib/relaton/gb/project_number.rb +38 -0
  240. data/lib/relaton/gb/scraper.rb +204 -0
  241. data/lib/relaton/gb/sec_scraper.rb +92 -0
  242. data/lib/relaton/gb/stage_name.rb +13 -0
  243. data/lib/relaton/gb/structured_identifier.rb +26 -0
  244. data/lib/relaton/gb/t_scraper.rb +126 -0
  245. data/lib/relaton/gb/util.rb +8 -0
  246. data/lib/relaton/gb/yaml/prefixes.yaml +200 -0
  247. data/lib/relaton/gb.rb +33 -0
  248. data/lib/relaton/iana/bibdata.rb +8 -0
  249. data/lib/relaton/iana/bibitem.rb +8 -0
  250. data/lib/relaton/iana/bibliography.rb +47 -0
  251. data/lib/relaton/iana/data_fetcher.rb +71 -0
  252. data/lib/relaton/iana/item.rb +7 -0
  253. data/lib/relaton/iana/item_data.rb +6 -0
  254. data/lib/relaton/iana/parser.rb +146 -0
  255. data/lib/relaton/iana/processor.rb +68 -0
  256. data/lib/relaton/iana/util.rb +8 -0
  257. data/lib/relaton/iana.rb +29 -0
  258. data/lib/relaton/iec/bibliography.rb +283 -0
  259. data/lib/relaton/iec/data_fetcher.rb +216 -0
  260. data/lib/relaton/iec/data_parser.rb +391 -0
  261. data/lib/relaton/iec/hit.rb +26 -0
  262. data/lib/relaton/iec/hit_collection.rb +138 -0
  263. data/lib/relaton/iec/item_data.rb +7 -0
  264. data/lib/relaton/iec/model/bibdata.rb +8 -0
  265. data/lib/relaton/iec/model/bibitem.rb +8 -0
  266. data/lib/relaton/iec/model/docidentifier.rb +131 -0
  267. data/lib/relaton/iec/model/doctype.rb +12 -0
  268. data/lib/relaton/iec/model/ext.rb +53 -0
  269. data/lib/relaton/iec/model/item.rb +20 -0
  270. data/lib/relaton/iec/model/item_base.rb +12 -0
  271. data/lib/relaton/iec/model/relation.rb +7 -0
  272. data/lib/relaton/iec/model/stage_name.rb +13 -0
  273. data/lib/relaton/iec/processor.rb +73 -0
  274. data/lib/relaton/iec/statuses.yml +199 -0
  275. data/lib/relaton/iec/util.rb +8 -0
  276. data/lib/relaton/iec.rb +98 -0
  277. data/lib/relaton/ieee/balloting_group.rb +13 -0
  278. data/lib/relaton/ieee/bibdata.rb +8 -0
  279. data/lib/relaton/ieee/bibitem.rb +8 -0
  280. data/lib/relaton/ieee/bibliography.rb +51 -0
  281. data/lib/relaton/ieee/converter/bibxml/from_rfcxml.rb +10 -0
  282. data/lib/relaton/ieee/converter/bibxml/from_rfcxml_referencegroup.rb +10 -0
  283. data/lib/relaton/ieee/converter/bibxml.rb +20 -0
  284. data/lib/relaton/ieee/data_fetcher.rb +630 -0
  285. data/lib/relaton/ieee/doctype.rb +9 -0
  286. data/lib/relaton/ieee/editorial_group.rb +19 -0
  287. data/lib/relaton/ieee/ext.rb +36 -0
  288. data/lib/relaton/ieee/idams_parser.rb +323 -0
  289. data/lib/relaton/ieee/item.rb +11 -0
  290. data/lib/relaton/ieee/item_data.rb +7 -0
  291. data/lib/relaton/ieee/processor.rb +68 -0
  292. data/lib/relaton/ieee/pub_id.rb +161 -0
  293. data/lib/relaton/ieee/rawbib_id_parser.rb +548 -0
  294. data/lib/relaton/ieee/util.rb +8 -0
  295. data/lib/relaton/ieee.rb +29 -0
  296. data/lib/relaton/ietf/bibdata.rb +8 -0
  297. data/lib/relaton/ietf/bibitem.rb +8 -0
  298. data/lib/relaton/ietf/bibliography.rb +35 -0
  299. data/lib/relaton/ietf/bibxml_parser.rb +232 -0
  300. data/lib/relaton/ietf/data_fetcher.rb +278 -0
  301. data/lib/relaton/ietf/doctype.rb +9 -0
  302. data/lib/relaton/ietf/ext.rb +63 -0
  303. data/lib/relaton/ietf/item.rb +16 -0
  304. data/lib/relaton/ietf/item_base.rb +18 -0
  305. data/lib/relaton/ietf/item_data.rb +6 -0
  306. data/lib/relaton/ietf/processing_instructions.rb +79 -0
  307. data/lib/relaton/ietf/processor.rb +68 -0
  308. data/lib/relaton/ietf/relation.rb +9 -0
  309. data/lib/relaton/ietf/rfc/abstract.rb +19 -0
  310. data/lib/relaton/ietf/rfc/author.rb +21 -0
  311. data/lib/relaton/ietf/rfc/entry.rb +410 -0
  312. data/lib/relaton/ietf/rfc/entry_date.rb +21 -0
  313. data/lib/relaton/ietf/rfc/format.rb +19 -0
  314. data/lib/relaton/ietf/rfc/index.rb +46 -0
  315. data/lib/relaton/ietf/rfc/is_also.rb +21 -0
  316. data/lib/relaton/ietf/rfc/keywords.rb +19 -0
  317. data/lib/relaton/ietf/rfc/rfc_index_namespace.rb +11 -0
  318. data/lib/relaton/ietf/scraper.rb +68 -0
  319. data/lib/relaton/ietf/util.rb +8 -0
  320. data/lib/relaton/ietf/wg_name_resolver.rb +42 -0
  321. data/lib/relaton/ietf.rb +27 -0
  322. data/lib/relaton/iho/bibdata.rb +8 -0
  323. data/lib/relaton/iho/bibitem.rb +8 -0
  324. data/lib/relaton/iho/bibliography.rb +114 -0
  325. data/lib/relaton/iho/comment_period.rb +13 -0
  326. data/lib/relaton/iho/docidentifier.rb +31 -0
  327. data/lib/relaton/iho/doctype.rb +10 -0
  328. data/lib/relaton/iho/ext.rb +20 -0
  329. data/lib/relaton/iho/hash_parser_v1.rb +144 -0
  330. data/lib/relaton/iho/item.rb +20 -0
  331. data/lib/relaton/iho/item_base.rb +18 -0
  332. data/lib/relaton/iho/item_data.rb +6 -0
  333. data/lib/relaton/iho/processor.rb +54 -0
  334. data/lib/relaton/iho/relation.rb +9 -0
  335. data/lib/relaton/iho/structured_identifier.rb +20 -0
  336. data/lib/relaton/iho/util.rb +8 -0
  337. data/lib/relaton/iho.rb +27 -0
  338. data/lib/relaton/index/config.rb +52 -0
  339. data/lib/relaton/index/file_io.rb +305 -0
  340. data/lib/relaton/index/file_storage.rb +61 -0
  341. data/lib/relaton/index/id_number.rb +30 -0
  342. data/lib/relaton/index/pool.rb +41 -0
  343. data/lib/relaton/index/type.rb +159 -0
  344. data/lib/relaton/index/util.rb +18 -0
  345. data/lib/relaton/index.rb +60 -0
  346. data/lib/relaton/isbn/isbn.rb +61 -0
  347. data/lib/relaton/isbn/open_library.rb +43 -0
  348. data/lib/relaton/isbn/parser.rb +88 -0
  349. data/lib/relaton/isbn/processor.rb +48 -0
  350. data/lib/relaton/isbn/util.rb +8 -0
  351. data/lib/relaton/isbn.rb +19 -0
  352. data/lib/relaton/iso/bibliography.rb +407 -0
  353. data/lib/relaton/iso/data_fetcher.rb +338 -0
  354. data/lib/relaton/iso/data_parser.rb +444 -0
  355. data/lib/relaton/iso/hash_parser_v1.rb +177 -0
  356. data/lib/relaton/iso/hit.rb +57 -0
  357. data/lib/relaton/iso/hit_collection.rb +184 -0
  358. data/lib/relaton/iso/item_data.rb +28 -0
  359. data/lib/relaton/iso/model/bibdata.rb +10 -0
  360. data/lib/relaton/iso/model/bibitem.rb +8 -0
  361. data/lib/relaton/iso/model/contributor.rb +6 -0
  362. data/lib/relaton/iso/model/contributor_info.rb +9 -0
  363. data/lib/relaton/iso/model/docidentifier.rb +134 -0
  364. data/lib/relaton/iso/model/doctype.rb +13 -0
  365. data/lib/relaton/iso/model/ext.rb +35 -0
  366. data/lib/relaton/iso/model/item.rb +17 -0
  367. data/lib/relaton/iso/model/item_base.rb +22 -0
  368. data/lib/relaton/iso/model/organization.rb +9 -0
  369. data/lib/relaton/iso/model/project_number.rb +22 -0
  370. data/lib/relaton/iso/model/relation.rb +9 -0
  371. data/lib/relaton/iso/model/stagename.rb +14 -0
  372. data/lib/relaton/iso/model/structured_identifier.rb +31 -0
  373. data/lib/relaton/iso/processor.rb +84 -0
  374. data/lib/relaton/iso/scraper.rb +619 -0
  375. data/lib/relaton/iso/type/pubid.rb +50 -0
  376. data/lib/relaton/iso/util.rb +8 -0
  377. data/lib/relaton/iso.rb +30 -0
  378. data/lib/relaton/itu/bibliography.rb +90 -0
  379. data/lib/relaton/itu/data_fetcher.rb +104 -0
  380. data/lib/relaton/itu/data_parser_r.rb +140 -0
  381. data/lib/relaton/itu/hit.rb +22 -0
  382. data/lib/relaton/itu/hit_collection.rb +127 -0
  383. data/lib/relaton/itu/item_data.rb +6 -0
  384. data/lib/relaton/itu/model/approval_stage.rb +13 -0
  385. data/lib/relaton/itu/model/bibdata.rb +8 -0
  386. data/lib/relaton/itu/model/bibitem.rb +8 -0
  387. data/lib/relaton/itu/model/docidentifier.rb +9 -0
  388. data/lib/relaton/itu/model/doctype.rb +13 -0
  389. data/lib/relaton/itu/model/ext.rb +47 -0
  390. data/lib/relaton/itu/model/item.rb +13 -0
  391. data/lib/relaton/itu/model/meeting.rb +13 -0
  392. data/lib/relaton/itu/model/meeting_date.rb +15 -0
  393. data/lib/relaton/itu/model/question.rb +13 -0
  394. data/lib/relaton/itu/model/recommendation_status.rb +11 -0
  395. data/lib/relaton/itu/model/structured_identifier.rb +19 -0
  396. data/lib/relaton/itu/processor.rb +66 -0
  397. data/lib/relaton/itu/pubid.rb +177 -0
  398. data/lib/relaton/itu/radio_regulations_parser.rb +70 -0
  399. data/lib/relaton/itu/recommendation_parser.rb +161 -0
  400. data/lib/relaton/itu/scraper.rb +193 -0
  401. data/lib/relaton/itu/util.rb +8 -0
  402. data/lib/relaton/itu.rb +33 -0
  403. data/lib/relaton/jis/bibdata.rb +8 -0
  404. data/lib/relaton/jis/bibitem.rb +8 -0
  405. data/lib/relaton/jis/bibliography.rb +75 -0
  406. data/lib/relaton/jis/data_fetcher.rb +181 -0
  407. data/lib/relaton/jis/docidentifier.rb +21 -0
  408. data/lib/relaton/jis/doctype.rb +9 -0
  409. data/lib/relaton/jis/ext.rb +13 -0
  410. data/lib/relaton/jis/hit.rb +93 -0
  411. data/lib/relaton/jis/hit_collection.rb +127 -0
  412. data/lib/relaton/jis/item.rb +22 -0
  413. data/lib/relaton/jis/item_base.rb +26 -0
  414. data/lib/relaton/jis/item_data.rb +8 -0
  415. data/lib/relaton/jis/processor.rb +55 -0
  416. data/lib/relaton/jis/relation.rb +11 -0
  417. data/lib/relaton/jis/scraper.rb +232 -0
  418. data/lib/relaton/jis/structured_identifier.rb +13 -0
  419. data/lib/relaton/jis/util.rb +8 -0
  420. data/lib/relaton/jis.rb +33 -0
  421. data/lib/relaton/logger/channels/gh_issue.rb +78 -0
  422. data/lib/relaton/logger/config.rb +34 -0
  423. data/lib/relaton/logger/formatter_json.rb +8 -0
  424. data/lib/relaton/logger/formatter_string.rb +12 -0
  425. data/lib/relaton/logger/log.rb +64 -0
  426. data/lib/relaton/logger/log_device.rb +27 -0
  427. data/lib/relaton/logger/pool.rb +24 -0
  428. data/lib/relaton/logger.rb +18 -0
  429. data/lib/relaton/nist/bibdata.rb +8 -0
  430. data/lib/relaton/nist/bibitem.rb +8 -0
  431. data/lib/relaton/nist/bibliography.rb +191 -0
  432. data/lib/relaton/nist/comment_period.rb +15 -0
  433. data/lib/relaton/nist/data_fetcher.rb +84 -0
  434. data/lib/relaton/nist/date.rb +7 -0
  435. data/lib/relaton/nist/doctype.rb +7 -0
  436. data/lib/relaton/nist/ext.rb +16 -0
  437. data/lib/relaton/nist/hit.rb +18 -0
  438. data/lib/relaton/nist/hit_collection.rb +362 -0
  439. data/lib/relaton/nist/item.rb +17 -0
  440. data/lib/relaton/nist/item_data.rb +6 -0
  441. data/lib/relaton/nist/mods_parser.rb +276 -0
  442. data/lib/relaton/nist/processor.rb +68 -0
  443. data/lib/relaton/nist/pubs_export.rb +69 -0
  444. data/lib/relaton/nist/relation.rb +7 -0
  445. data/lib/relaton/nist/scraper.rb +290 -0
  446. data/lib/relaton/nist/series.yaml +49 -0
  447. data/lib/relaton/nist/util.rb +8 -0
  448. data/lib/relaton/nist.rb +34 -0
  449. data/lib/relaton/oasis/bibdata.rb +8 -0
  450. data/lib/relaton/oasis/bibitem.rb +8 -0
  451. data/lib/relaton/oasis/bibliography.rb +60 -0
  452. data/lib/relaton/oasis/browser_agent.rb +71 -0
  453. data/lib/relaton/oasis/data_fetcher.rb +94 -0
  454. data/lib/relaton/oasis/data_parser.rb +305 -0
  455. data/lib/relaton/oasis/data_parser_utils.rb +296 -0
  456. data/lib/relaton/oasis/data_part_parser.rb +239 -0
  457. data/lib/relaton/oasis/doctype.rb +7 -0
  458. data/lib/relaton/oasis/ext.rb +19 -0
  459. data/lib/relaton/oasis/item.rb +11 -0
  460. data/lib/relaton/oasis/item_data.rb +6 -0
  461. data/lib/relaton/oasis/processor.rb +68 -0
  462. data/lib/relaton/oasis/util.rb +8 -0
  463. data/lib/relaton/oasis.rb +28 -0
  464. data/lib/relaton/ogc/bibdata.rb +8 -0
  465. data/lib/relaton/ogc/bibitem.rb +8 -0
  466. data/lib/relaton/ogc/bibliography.rb +64 -0
  467. data/lib/relaton/ogc/data_fetcher.rb +110 -0
  468. data/lib/relaton/ogc/docidentifier.rb +6 -0
  469. data/lib/relaton/ogc/doctype.rb +12 -0
  470. data/lib/relaton/ogc/ext.rb +15 -0
  471. data/lib/relaton/ogc/hit.rb +18 -0
  472. data/lib/relaton/ogc/hit_collection.rb +36 -0
  473. data/lib/relaton/ogc/item.rb +13 -0
  474. data/lib/relaton/ogc/item_data.rb +6 -0
  475. data/lib/relaton/ogc/processor.rb +58 -0
  476. data/lib/relaton/ogc/scraper.rb +225 -0
  477. data/lib/relaton/ogc/util.rb +8 -0
  478. data/lib/relaton/ogc.rb +26 -0
  479. data/lib/relaton/oiml/bibdata.rb +8 -0
  480. data/lib/relaton/oiml/bibitem.rb +8 -0
  481. data/lib/relaton/oiml/bibliography.rb +94 -0
  482. data/lib/relaton/oiml/docidentifier.rb +33 -0
  483. data/lib/relaton/oiml/doctype.rb +13 -0
  484. data/lib/relaton/oiml/ext.rb +42 -0
  485. data/lib/relaton/oiml/item.rb +20 -0
  486. data/lib/relaton/oiml/item_base.rb +18 -0
  487. data/lib/relaton/oiml/item_data.rb +6 -0
  488. data/lib/relaton/oiml/processor.rb +54 -0
  489. data/lib/relaton/oiml/relation.rb +9 -0
  490. data/lib/relaton/oiml/util.rb +8 -0
  491. data/lib/relaton/oiml.rb +24 -0
  492. data/lib/relaton/omg/bibdata.rb +8 -0
  493. data/lib/relaton/omg/bibitem.rb +8 -0
  494. data/lib/relaton/omg/bibliography.rb +31 -0
  495. data/lib/relaton/omg/ext.rb +7 -0
  496. data/lib/relaton/omg/item.rb +8 -0
  497. data/lib/relaton/omg/item_data.rb +6 -0
  498. data/lib/relaton/omg/processor.rb +34 -0
  499. data/lib/relaton/omg/scraper.rb +141 -0
  500. data/lib/relaton/omg/util.rb +8 -0
  501. data/lib/relaton/omg.rb +24 -0
  502. data/lib/relaton/plateau/bibdata.rb +8 -0
  503. data/lib/relaton/plateau/bibitem.rb +8 -0
  504. data/lib/relaton/plateau/bibliography.rb +24 -0
  505. data/lib/relaton/plateau/data_fetcher.rb +153 -0
  506. data/lib/relaton/plateau/doctype.rb +7 -0
  507. data/lib/relaton/plateau/ext.rb +23 -0
  508. data/lib/relaton/plateau/handbook_parser.rb +95 -0
  509. data/lib/relaton/plateau/hit.rb +13 -0
  510. data/lib/relaton/plateau/hit_collection.rb +59 -0
  511. data/lib/relaton/plateau/item.rb +12 -0
  512. data/lib/relaton/plateau/item_data.rb +6 -0
  513. data/lib/relaton/plateau/parser.rb +101 -0
  514. data/lib/relaton/plateau/processor.rb +49 -0
  515. data/lib/relaton/plateau/technical_report_parser.rb +91 -0
  516. data/lib/relaton/plateau/util.rb +8 -0
  517. data/lib/relaton/plateau.rb +28 -0
  518. data/lib/relaton/un/bibdata.rb +8 -0
  519. data/lib/relaton/un/bibitem.rb +8 -0
  520. data/lib/relaton/un/bibliography.rb +48 -0
  521. data/lib/relaton/un/doctype.rb +10 -0
  522. data/lib/relaton/un/ext.rb +30 -0
  523. data/lib/relaton/un/hit.rb +56 -0
  524. data/lib/relaton/un/hit_collection.rb +61 -0
  525. data/lib/relaton/un/item.rb +11 -0
  526. data/lib/relaton/un/item_data.rb +6 -0
  527. data/lib/relaton/un/parser.rb +108 -0
  528. data/lib/relaton/un/processor.rb +38 -0
  529. data/lib/relaton/un/session.rb +25 -0
  530. data/lib/relaton/un/token_generator.rb +105 -0
  531. data/lib/relaton/un/util.rb +8 -0
  532. data/lib/relaton/un/wasm/decoder.rb +434 -0
  533. data/lib/relaton/un/wasm/instance.rb +101 -0
  534. data/lib/relaton/un/wasm/interpreter.rb +613 -0
  535. data/lib/relaton/un/wasm/memory.rb +112 -0
  536. data/lib/relaton/un/wasm/module.rb +47 -0
  537. data/lib/relaton/un/wasm.rb +17 -0
  538. data/lib/relaton/un/wasm_v_bg.wasm +0 -0
  539. data/lib/relaton/un.rb +28 -0
  540. data/lib/relaton/version.rb +1 -1
  541. data/lib/relaton/w3c/bibdata.rb +8 -0
  542. data/lib/relaton/w3c/bibitem.rb +8 -0
  543. data/lib/relaton/w3c/bibliography.rb +54 -0
  544. data/lib/relaton/w3c/data_fetcher.rb +309 -0
  545. data/lib/relaton/w3c/data_parser.rb +379 -0
  546. data/lib/relaton/w3c/doctype.rb +7 -0
  547. data/lib/relaton/w3c/ext.rb +11 -0
  548. data/lib/relaton/w3c/item.rb +12 -0
  549. data/lib/relaton/w3c/item_data.rb +6 -0
  550. data/lib/relaton/w3c/processor.rb +49 -0
  551. data/lib/relaton/w3c/pubid.rb +73 -0
  552. data/lib/relaton/w3c/safe_realize.rb +59 -0
  553. data/lib/relaton/w3c/util.rb +8 -0
  554. data/lib/relaton/w3c.rb +25 -0
  555. data/lib/relaton/xsf/bibdata.rb +8 -0
  556. data/lib/relaton/xsf/bibitem.rb +8 -0
  557. data/lib/relaton/xsf/bibliography.rb +24 -0
  558. data/lib/relaton/xsf/data_fetcher.rb +56 -0
  559. data/lib/relaton/xsf/hit.rb +17 -0
  560. data/lib/relaton/xsf/hit_collection.rb +24 -0
  561. data/lib/relaton/xsf/item.rb +7 -0
  562. data/lib/relaton/xsf/item_data.rb +6 -0
  563. data/lib/relaton/xsf/processor.rb +50 -0
  564. data/lib/relaton/xsf/util.rb +9 -0
  565. data/lib/relaton/xsf.rb +30 -0
  566. data/lib/relaton-core.rb +1 -0
  567. data/lib/relaton.rb +43 -0
  568. metadata +673 -170
  569. data/.github/workflows/rake.yml +0 -14
  570. data/.github/workflows/release.yml +0 -24
  571. data/.github/workflows/rubocop.yml +0 -48
  572. data/.gitignore +0 -12
  573. data/.rspec +0 -3
  574. data/CLAUDE.md +0 -78
  575. data/Gemfile +0 -29
  576. data/Rakefile +0 -6
  577. data/docs/CHANGELOG.adoc +0 -16
  578. data/docs/VERSIONING_POLICY.adoc +0 -38
  579. data/docs/navigation.adoc +0 -6
  580. data/lib/relaton/db/version.rb +0 -5
  581. data/relaton.gemspec +0 -72
  582. data/spec/relaton/config_spec.rb +0 -10
  583. data/spec/relaton/db_cache_spec.rb +0 -51
  584. data/spec/relaton/db_spec.rb +0 -567
  585. data/spec/relaton/registry_spec.rb +0 -178
  586. data/spec/relaton/util_spec.rb +0 -3
  587. data/spec/relaton_meta_spec.rb +0 -25
  588. data/spec/relaton_spec.rb +0 -800
  589. data/spec/spec_helper.rb +0 -45
  590. data/spec/support/gb_t_20223_2006.xml +0 -33
  591. data/spec/support/iso_111111119115_1.xml +0 -0
  592. data/spec/support/iso_19115_1.xml +0 -115
  593. data/spec/support/iso_19115_2.xml +0 -95
  594. data/spec/support/rfc_8341.xml +0 -46
  595. data/spec/vcr_cassetes/api_relaton_org.yml +0 -121
  596. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +0 -140
  597. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +0 -202
  598. data/spec/vcr_cassetes/cipm_meeting_43.yml +0 -1505
  599. data/spec/vcr_cassetes/gb_t_20223_2006.yml +0 -729
  600. data/spec/vcr_cassetes/iso_111111119115_1.yml +0 -12951
  601. data/spec/vcr_cassetes/iso_19115_1.yml +0 -17334
  602. data/spec/vcr_cassetes/iso_19115_1_2.yml +0 -322
  603. data/spec/vcr_cassetes/iso_19115_1_std.yml +0 -17334
  604. data/spec/vcr_cassetes/iso_19115_all_parts.yml +0 -185
  605. data/spec/vcr_cassetes/iso_19133_2005.yml +0 -144
  606. data/spec/vcr_cassetes/iso_combined_applied.yml +0 -318
  607. data/spec/vcr_cassetes/iso_combined_included.yml +0 -318
  608. data/spec/vcr_cassetes/ogc_19_025r1.yml +0 -374
  609. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +0 -317
  610. data/spec/vcr_cassetes/rfc_8341.yml +0 -1278
@@ -0,0 +1,827 @@
1
+ module Relaton
2
+ module Doi
3
+ class Parser
4
+ COUNTRIES = %w[USA].freeze
5
+
6
+ TYPES = {
7
+ "book-chapter" => "inbook",
8
+ "book-part" => "inbook",
9
+ "book-section" => "inbook",
10
+ "book-series" => "book",
11
+ "book-set" => "book",
12
+ "book-track" => "inbook",
13
+ "component" => "misc",
14
+ "database" => "dataset",
15
+ "dissertation" => "thesis",
16
+ "edited-book" => "book",
17
+ "grant" => "misc",
18
+ "journal-article" => "article",
19
+ "journal-issue" => "article",
20
+ "journal-volume" => "journal",
21
+ "monograph" => "book",
22
+ "other" => "misc",
23
+ "peer-review" => "article",
24
+ "posted-content" => "dataset",
25
+ "proceedings-article" => "inproceedings",
26
+ "proceedings-series" => "proceedings",
27
+ "reference-book" => "book",
28
+ "reference-entry" => "inbook",
29
+ "report-component" => "techreport",
30
+ "report-series" => "techreport",
31
+ "report" => "techreport",
32
+ }.freeze
33
+
34
+ REALATION_TYPES = {
35
+ "is-cited-by" => "isCitedIn",
36
+ "belongs-to" => "related",
37
+ "is-child-of" => "includedIn",
38
+ "is-expression-of" => "expressionOf",
39
+ "has-expression" => "hasExpression",
40
+ "is-manifestation-of" => "manifestationOf",
41
+ "is-manuscript-of" => "draftOf",
42
+ "has-manuscript" => "hasDraft",
43
+ "is-preprint-of" => "draftOf",
44
+ "has-preprint" => "hasDraft",
45
+ "is-replaced-by" => "obsoletedBy",
46
+ "replaces" => "obsoletes",
47
+ "is-translation-of" => "translatedFrom",
48
+ "has-translation" => "hasTranslation",
49
+ "is-version-of" => "editionOf",
50
+ "has-version" => "hasEdition",
51
+ "is-based-on" => "updates",
52
+ "is-basis-for" => "updatedBy",
53
+ "is-comment-on" => "commentaryOf",
54
+ "has-comment" => "hasCommentary",
55
+ "is-continued-by" => "hasSuccessor",
56
+ "continues" => "successorOf",
57
+ "is-derived-from" => "derives",
58
+ "has-derivation" => "derivedFrom",
59
+ "is-documented-by" => "describedBy",
60
+ "documents" => "describes",
61
+ "is-part-of" => "partOf",
62
+ "has-part" => "hasPart",
63
+ "is-review-of" => "reviewOf",
64
+ "has-review" => "hasReview",
65
+ "references" => "cites",
66
+ "is-referenced-by" => "isCitedIn",
67
+ "requires" => "hasComplement",
68
+ "is-required-by" => "complementOf",
69
+ "is-supplement-to" => "complementOf",
70
+ "is-supplemented-by" => "hasComplement",
71
+ }.freeze
72
+
73
+ ATTRS = %i[type fetched title docidentifier date source abstract contributor place
74
+ ext relation extent series medium].freeze
75
+
76
+ CROSSREF_API_URL = "https://api.crossref.org/works?query=%{query}&filter=%{filter}".freeze
77
+ MAX_RETRIES = 3
78
+
79
+ #
80
+ # Initialize instance.
81
+ #
82
+ # @param [Hash] src The source hash.
83
+ #
84
+ def initialize(src)
85
+ @src = src
86
+ @item = {}
87
+ end
88
+
89
+ #
90
+ # Initialize instance and parse the source hash.
91
+ #
92
+ # @param [Hash] src The source hash.
93
+ #
94
+ # @return [Bib::ItemData] The bibitem.
95
+ #
96
+ def self.parse(src)
97
+ new(src).parse
98
+ end
99
+
100
+ #
101
+ # Parse the source hash.
102
+ #
103
+ # @return [Bib::ItemData] The bibitem.
104
+ #
105
+ def parse
106
+ ATTRS.each { |m| @item[m] = send "parse_#{m}" }
107
+ create_bibitem @src["DOI"], @item
108
+ end
109
+
110
+ #
111
+ # Create a bibitem from the bibitem hash.
112
+ #
113
+ # @param [String] doi The DOI.
114
+ # @param [Hash] bibitem The bibitem hash.
115
+ #
116
+ # @return [Bib::ItemData] The bibitem.
117
+ #
118
+ def create_bibitem(doi, bibitem) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
119
+ doctype_content = @src["type"]
120
+ case doi
121
+ when /\/nist/
122
+ bibitem[:ext] = Nist::Ext.new(doctype: Nist::Doctype.new(content: doctype_content))
123
+ Nist::ItemData.new(**bibitem)
124
+ when /\/rfc\d+/
125
+ bibitem[:ext] = Ietf::Ext.new(doctype: Ietf::Doctype.new(content: doctype_content))
126
+ Ietf::ItemData.new(**bibitem)
127
+ when /\/0026-1394\//
128
+ bibitem[:ext] = Bipm::Ext.new(doctype: Bipm::Doctype.new(content: doctype_content))
129
+ Bipm::ItemData.new(**bibitem)
130
+ when /\/ieee/
131
+ bibitem[:ext] = Ieee::Ext.new(doctype: Ieee::Doctype.new(content: doctype_content))
132
+ Ieee::ItemData.new(**bibitem)
133
+ else Bib::ItemData.new(**bibitem)
134
+ end
135
+ end
136
+
137
+ #
138
+ # Parse the type.
139
+ #
140
+ # @return [String] The type.
141
+ #
142
+ def parse_type
143
+ TYPES[@src["type"]] || @src["type"]
144
+ end
145
+
146
+ #
147
+ # Parse the ext element with doctype.
148
+ #
149
+ # @return [Bib::Ext] The ext element.
150
+ #
151
+ def parse_ext
152
+ Bib::Ext.new doctype: Bib::Doctype.new(content: @src["type"])
153
+ end
154
+
155
+ #
156
+ # Parse the fetched date.
157
+ #
158
+ # @return [String] The fetched date.
159
+ #
160
+ def parse_fetched
161
+ Date.today.to_s
162
+ end
163
+
164
+ #
165
+ # Parse titles from the source hash.
166
+ #
167
+ # @return [Array<Bib::Title>] The titles.
168
+ #
169
+ def parse_title # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
170
+ if @src["title"].is_a?(Array) && @src["title"].any?
171
+ main_sub_titles
172
+ elsif @src["project"].is_a?(Array) && @src["project"].any?
173
+ project_titles
174
+ elsif @src["container-title"].is_a?(Array) && @src["container-title"].size > 1
175
+ @src["container-title"][0..-2].map { |t| create_title t }
176
+ else []
177
+ end
178
+ end
179
+
180
+ #
181
+ # Parse main and subtitle from the source hash.
182
+ #
183
+ # @return [Array<Bib::Title>] The titles.
184
+ #
185
+ def main_sub_titles
186
+ title = @src["title"].map { |t| create_title t }
187
+ Array(@src["subtitle"]).each { |t| title << create_title(t, "subtitle") }
188
+ Array(@src["short-title"]).each { |t| title << create_title(t, "short") }
189
+ title
190
+ end
191
+
192
+ #
193
+ # Fetch titles from the projects.
194
+ #
195
+ # @return [Array<Bib::Title>] The titles.
196
+ #
197
+ def project_titles
198
+ Array(@src["project"]).reduce([]) do |memo, proj|
199
+ memo + Array(proj["project-title"]).map { |t| create_title t["title"] }
200
+ end
201
+ end
202
+
203
+ #
204
+ # Create a title from the title and type.
205
+ #
206
+ # @param [String] title The title content.
207
+ # @param [String] type The title type. Defaults to "main".
208
+ #
209
+ # @return [Bib::Title] The title.
210
+ #
211
+ def create_title(title, type = "main")
212
+ cnt = str_cleanup CGI.unescapeHTML(title)
213
+ Bib::Title.new type: type, content: cnt, script: "Latn"
214
+ end
215
+
216
+ #
217
+ # Parse a docidentifier from the source hash.
218
+ #
219
+ # @return [Array<Bib::Docidentifier>] The docidentifier.
220
+ #
221
+ def parse_docidentifier
222
+ %w[DOI ISBN ISSN].each_with_object([]) do |type, obj|
223
+ prm = type == "DOI"
224
+ Array(@src[type]).each do |id|
225
+ t = issn_type(type, id)
226
+ obj << Bib::Docidentifier.new(type: t, content: id, primary: prm)
227
+ end
228
+ end
229
+ end
230
+
231
+ #
232
+ # Create an ISSN type if it's an ISSN ID.
233
+ #
234
+ # @param [String] type identifier type
235
+ # @param [String] id identifier
236
+ #
237
+ # @return [String] identifier type
238
+ #
239
+ def issn_type(type, id)
240
+ return type unless type == "ISSN"
241
+
242
+ t = @src["issn-type"]&.find { |it| it["value"] == id }&.dig("type")
243
+ t ? "issn.#{t}" : type.downcase
244
+ end
245
+
246
+ #
247
+ # Parce dates from the source hash.
248
+ #
249
+ # @return [Array<Bib::Date>] The dates.
250
+ #
251
+ def parse_date # rubocop:disable Metrics/CyclomaticComplexity
252
+ dates = %w[issued published approved].each_with_object([]) do |type, obj|
253
+ next unless @src.dig(type, "date-parts")&.first&.compact&.any?
254
+
255
+ obj << Bib::Date.new(type: type, at: date_type(type))
256
+ end
257
+ if dates.none?
258
+ dates << Bib::Date.new(type: "created", at: date_type("created"))
259
+ end
260
+ dates
261
+ end
262
+
263
+ #
264
+ # Join date parts into a string.
265
+ #
266
+ # @param [String] type The date type.
267
+ #
268
+ # @return [String] The date string.
269
+ #
270
+ def date_type(type)
271
+ @src[type]["date-parts"][0].map { |d| d.to_s.rjust(2, "0") }.join "-"
272
+ end
273
+
274
+ #
275
+ # Parse source URIs from the source hash.
276
+ #
277
+ # @return [Array<Bib::Uri>] The source URIs.
278
+ #
279
+ def parse_source # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
280
+ disprefered_links = %w[similarity-checking text-mining]
281
+ links = []
282
+ if @src["URL"]
283
+ links << Bib::Uri.new(type: "DOI", content: @src["URL"])
284
+ end
285
+ [@src["link"], @src.dig("resource", "primary")].flatten.compact.each do |l|
286
+ next if disprefered_links.include? l["intended-application"]
287
+
288
+ type = case l["URL"]
289
+ when /\.pdf$/ then "pdf"
290
+ # when /\/rfc\d+$|iopscience\.iop\.org|ieeexplore\.ieee\.org/
291
+ else "src"
292
+ end
293
+ links << Bib::Uri.new(type: type, content: l["URL"]) # if type
294
+ end
295
+ links
296
+ end
297
+
298
+ #
299
+ # Parse abstract from the source hash.
300
+ #
301
+ # @return [Array<Bib::LocalizedMarkedUpString>] The abstract.
302
+ #
303
+ def parse_abstract
304
+ return [] unless @src["abstract"]
305
+
306
+ content = @src["abstract"]
307
+ abstract = Bib::Abstract.new(
308
+ content: content, language: "en", script: "Latn",
309
+ )
310
+ [abstract]
311
+ end
312
+
313
+ #
314
+ # Parse contributors from the source hash.
315
+ #
316
+ # @return [Array<Bib::Contributor>] The contributors.
317
+ #
318
+ def parse_contributor
319
+ contribs = author_investigators
320
+ contribs += authors_editors_translators
321
+ contribs += contribs_from_parent(contribs)
322
+ contribs << contributor(org_publisher, "publisher")
323
+ contribs += org_aurhorizer
324
+ contribs + org_enabler
325
+ end
326
+
327
+ #
328
+ # Create authors investigators from the source hash.
329
+ #
330
+ # @return [Array<Bib::Contributor>] The authors investigators.
331
+ #
332
+ def author_investigators
333
+ Array(@src["project"]).reduce([]) do |memo, proj|
334
+ memo + create_investigators(proj, "lead-investigator") +
335
+ create_investigators(proj, "investigator")
336
+ end
337
+ end
338
+
339
+ #
340
+ # Create investigators from the project.
341
+ #
342
+ # @param [Hash] project The project hash.
343
+ # @param [String] type The investigator type. "lead-investigator" or "investigator".
344
+ #
345
+ # @return [Array<Bib::Contributor>] The investigators.
346
+ #
347
+ def create_investigators(project, type)
348
+ description = type.gsub("-", " ")
349
+ Array(project[type]).map do |inv|
350
+ contributor(create_person(inv), "author", description)
351
+ end
352
+ end
353
+
354
+ #
355
+ # Create authors editors translators from the source hash.
356
+ #
357
+ # @return [Array<Bib::Contributor>] The authors editors translators.
358
+ #
359
+ def authors_editors_translators
360
+ %w[author editor translator].each_with_object([]) do |type, a|
361
+ @src[type]&.each do |c|
362
+ contrib = if c["family"]
363
+ create_person(c)
364
+ else
365
+ create_org(str_cleanup(c["name"]))
366
+ end
367
+ a << contributor(contrib, type)
368
+ end
369
+ end
370
+ end
371
+
372
+ #
373
+ # Fetch authors and editors from parent if they are not present in the book part.
374
+ #
375
+ # @param [Array<Bib::Contributor>] contribs present contributors
376
+ #
377
+ # @return [Array<Bib::Contributor>] contributors with authors and editors from parent
378
+ #
379
+ def contribs_from_parent(contribs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
380
+ return [] unless %w[inbook inproceedings dataset].include?(parse_type) && @src["container-title"]
381
+
382
+ has_authors = contribs.any? { |c| c.role&.any? { |r| r.type == "author" } }
383
+ has_editors = contribs.any? { |c| c.role&.any? { |r| r.type == "editor" } }
384
+ return [] if has_authors && has_editors
385
+
386
+ create_authors_editors(has_authors, "author")
387
+ end
388
+
389
+ #
390
+ # Fetch parent item from Crossref.
391
+ #
392
+ # @return [Hash, nil] parent item
393
+ #
394
+ def parent_item
395
+ @parent_item ||= begin
396
+ query = CGI.escape [@src["container-title"][0], fetch_year].compact.join("+")
397
+ filter = "type:#{%w[book book-set edited-book monograph reference-book].join ',type:'}"
398
+ items = fetch_crossref(query: query, filter: filter)
399
+ items&.detect { |i| i["title"].include? @src["container-title"][0] }
400
+ end
401
+ end
402
+
403
+ #
404
+ # Create authors and editors from parent item.
405
+ #
406
+ # @param [Boolean] has true if authors or editors are present in the book part
407
+ # @param [String] type "author" or "editor"
408
+ #
409
+ # @return [Array<Bib::Contributor>] authors or editors
410
+ #
411
+ def create_authors_editors(has, type)
412
+ return [] if has || !parent_item
413
+
414
+ Array(parent_item[type]).map { |a| contributor(create_person(a), type) }
415
+ end
416
+
417
+ #
418
+ # Cerate an organization publisher from the source hash.
419
+ #
420
+ # @return [Bib::Organization] The organization.
421
+ #
422
+ def org_publisher
423
+ pbr = @src["institution"]&.detect do |i|
424
+ @src["publisher"].include?(i["name"]) ||
425
+ i["name"].include?(@src["publisher"])
426
+ end
427
+ a = pbr["acronym"]&.first if pbr
428
+ create_org(str_cleanup(@src["publisher"]), a)
429
+ end
430
+
431
+ #
432
+ # Clean up trailing punctuation and whitespace from a string.
433
+ #
434
+ # @param [String] str The string to clean up.
435
+ #
436
+ # @return [String] The cleaned up string.
437
+ #
438
+ def str_cleanup(str)
439
+ str.strip.sub(/[,\/\s]+$/, "").sub(/\s:$/, "")
440
+ end
441
+
442
+ #
443
+ # Create an organization with properly typed name and abbreviation.
444
+ #
445
+ # @param [String] name The organization name.
446
+ # @param [String, nil] abbreviation The organization abbreviation.
447
+ #
448
+ # @return [Bib::Organization] The organization.
449
+ #
450
+ def create_org(name, abbreviation = nil)
451
+ n = [Bib::TypedLocalizedString.new(content: name)]
452
+ a = abbreviation ? Bib::LocalizedString.new(content: abbreviation) : nil
453
+ Bib::Organization.new name: n, abbreviation: a
454
+ end
455
+
456
+ #
457
+ # Parse authorizer contributor from the source hash.
458
+ #
459
+ # @return [Array<Bib::Contributor>] The authorizer contributor.
460
+ #
461
+ def org_aurhorizer
462
+ return [] unless @src["standards-body"]
463
+
464
+ name, acronym = @src["standards-body"].values_at("name", "acronym")
465
+ org = create_org(
466
+ CGI.unescapeHTML(name),
467
+ acronym && CGI.unescapeHTML(acronym),
468
+ )
469
+ [contributor(org, "authorizer")]
470
+ end
471
+
472
+ #
473
+ # Parse enabler contributor from the source hash.
474
+ #
475
+ # @return [Array<Bib::Contributor>] The enabler contributor.
476
+ #
477
+ def org_enabler
478
+ Array(@src["project"]).each_with_object([]) do |proj, memo|
479
+ proj["funding"].each do |f|
480
+ memo << create_enabler(f.dig("funder", "name"))
481
+ end
482
+ end + Array(@src["funder"]).map { |f| create_enabler f["name"] }
483
+ end
484
+
485
+ #
486
+ # Create enabler contributor with type "enabler".
487
+ #
488
+ # @param [String] name The funder name.
489
+ #
490
+ # @return [Bib::Contributor] The enabler contributor.
491
+ #
492
+ def create_enabler(name)
493
+ contributor(create_org(name), "enabler")
494
+ end
495
+
496
+ #
497
+ # Create contributor from an entity and a role type.
498
+ #
499
+ # @param [Bib::Person, Bib::Organization] entity The entity.
500
+ # @param [String] type The role type.
501
+ #
502
+ # @return [Bib::Contributor] The contributor.
503
+ #
504
+ def contributor(entity, type, descriprion = nil)
505
+ desc = descriprion ? [Bib::LocalizedMarkedUpString.new(content: descriprion)] : nil
506
+ role = [Bib::Contributor::Role.new(type: type, description: desc)]
507
+ if entity.is_a?(Bib::Person)
508
+ Bib::Contributor.new(role: role, person: entity)
509
+ else
510
+ Bib::Contributor.new(role: role, organization: entity)
511
+ end
512
+ end
513
+
514
+ #
515
+ # Create a person from a person hash.
516
+ #
517
+ # @param [Hash] person The person hash.
518
+ #
519
+ # @return [Bib::Person] The person.
520
+ #
521
+ def create_person(person)
522
+ Bib::Person.new(
523
+ name: create_person_name(person),
524
+ affiliation: create_affiliation(person),
525
+ identifier: person_id(person),
526
+ )
527
+ end
528
+
529
+ #
530
+ # Create person affiliations from a person hash.
531
+ #
532
+ # @param [Hash] person The person hash.
533
+ #
534
+ # @return [Array<Bib::Affiliation>] The affiliations.
535
+ #
536
+ def create_affiliation(person)
537
+ (person["affiliation"] || []).map do |a|
538
+ Bib::Affiliation.new organization: create_org(a["name"])
539
+ end
540
+ end
541
+
542
+ #
543
+ # Create a person full name from a person hash.
544
+ #
545
+ # @param [Hash] person The person hash.
546
+ #
547
+ # @return [Bib::FullName] The full name.
548
+ #
549
+ def create_person_name(person)
550
+ surname = titlecase(person["family"])
551
+ sn = Bib::LocalizedString.new(content: surname, language: "en", script: "Latn")
552
+ Bib::FullName.new(
553
+ surname: sn, forename: forename(person), addition: nameaddition(person),
554
+ completename: completename(person), prefix: nameprefix(person)
555
+ )
556
+ end
557
+
558
+ #
559
+ # Capitalize the first letter of each word in a string except for words that
560
+ # are 2 letters or less.
561
+ #
562
+ # @param [<Type>] str <description>
563
+ #
564
+ # @return [<Type>] <description>
565
+ #
566
+ def titlecase(str)
567
+ str.split.map do |s|
568
+ if s.size > 2 && s.upcase == s && !/\.&/.match?(s)
569
+ s.capitalize
570
+ else
571
+ s
572
+ end
573
+ end.join " "
574
+ end
575
+
576
+ #
577
+ # Create a person name prefix from a person hash.
578
+ #
579
+ # @param [Hash] person The person hash.
580
+ #
581
+ # @return [Array<Bib::LocalizedString>] The name prefix.
582
+ #
583
+ def nameprefix(person)
584
+ return [] unless person["prefix"]
585
+
586
+ [Bib::LocalizedString.new(content: person["prefix"], language: "en", script: "Latn")]
587
+ end
588
+
589
+ #
590
+ # Create a complete name from a person hash.
591
+ #
592
+ # @param [Hash] person The person hash.
593
+ #
594
+ # @return [Bib::LocalizedString] The complete name.
595
+ #
596
+ def completename(person)
597
+ return unless person["name"]
598
+
599
+ Bib::LocalizedString.new(content: person["name"], language: "en", script: "Latn")
600
+ end
601
+
602
+ #
603
+ # Create a forename from a person hash.
604
+ #
605
+ # @param [Hash] person The person hash.
606
+ #
607
+ # @return [Array<Bib::FullNameType::Forename>] The forename.
608
+ #
609
+ def forename(person)
610
+ return [] unless person["given"]
611
+
612
+ fname = titlecase(person["given"])
613
+ [Bib::FullNameType::Forename.new(content: fname, language: "en", script: "Latn")]
614
+ end
615
+
616
+ #
617
+ # Create an addition from a person hash.
618
+ #
619
+ # @param [Hash] person The person hash.
620
+ #
621
+ # @return [Array<Bib::LocalizedString>] The addition.
622
+ #
623
+ def nameaddition(person)
624
+ return [] unless person["suffix"]
625
+
626
+ [Bib::LocalizedString.new(content: person["suffix"], language: "en", script: "Latn")]
627
+ end
628
+
629
+ #
630
+ # Create a person identifier from a person hash.
631
+ #
632
+ # @param [Hash] person The person hash.
633
+ #
634
+ # @return [Array<Bib::Person::Identifier>] The person identifier.
635
+ #
636
+ def person_id(person)
637
+ return [] unless person["ORCID"]
638
+
639
+ [Bib::Person::Identifier.new(type: "orcid", content: person["ORCID"])]
640
+ end
641
+
642
+ #
643
+ # Parse a place from the source hash.
644
+ #
645
+ # @return [Array<Bib::Place>] The place.
646
+ #
647
+ def parse_place # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
648
+ pub_location = @src["publisher-location"] || fetch_location
649
+ return [] unless pub_location
650
+
651
+ pls1, pls2 = pub_location.split(", ")
652
+ pls1 = str_cleanup pls1
653
+ pls2 &&= str_cleanup pls2
654
+ if COUNTRIES.include? pls2
655
+ country = Bib::Place::RegionType.new(content: pls2)
656
+ [Bib::Place.new(city: pls1, country: [country])]
657
+ elsif pls2 && pls2 == pls2&.upcase
658
+ region = Bib::Place::RegionType.new(content: pls2)
659
+ [Bib::Place.new(city: pls1, region: [region])]
660
+ elsif pls1 == pls2 || pls2.nil? || pls2.empty?
661
+ [Bib::Place.new(city: pls1)]
662
+ else
663
+ [Bib::Place.new(city: pls1), Bib::Place.new(city: pls2)]
664
+ end
665
+ end
666
+
667
+ #
668
+ # Fetch location from container.
669
+ #
670
+ # @return [String, nil] The location.
671
+ #
672
+ def fetch_location
673
+ title = @item[:title].first&.content
674
+ qparts = [title, fetch_year, @src["publisher"]]
675
+ query = CGI.escape qparts.compact.join("+").gsub(" ", "+")
676
+ filter = "type:#{%w[book-chapter book-part book-section book-track].join(',type:')}"
677
+ items = fetch_crossref(query: query, filter: filter)
678
+ items&.detect do |i|
679
+ i["publisher-location"] && i["container-title"].include?(title)
680
+ end&.dig("publisher-location")
681
+ end
682
+
683
+ #
684
+ # Parse relations from the source hash.
685
+ #
686
+ # @return [Array<Bib::Relation>] The relations.
687
+ #
688
+ def parse_relation # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
689
+ rels = included_in_relation
690
+ @src["relation"].each_with_object(rels) do |(k, v), a|
691
+ type, desc = relation_type k
692
+ Array(v).each do |r|
693
+ rel_item = Crossref.get_by_id r["id"]
694
+ title = rel_item["title"].map { |t| create_title t }
695
+ docid = Bib::Docidentifier.new(content: r["id"], type: "DOI")
696
+ bib = create_bibitem r["id"], title: title, docidentifier: [docid]
697
+ a << Bib::Relation.new(type: type, description: desc, bibitem: bib)
698
+ end
699
+ end
700
+ end
701
+
702
+ #
703
+ # Transform crossref relation type to relaton relation type.
704
+ #
705
+ # @param [String] crtype The crossref relation type.
706
+ #
707
+ # @return [Array<String>] The relaton relation type and description.
708
+ #
709
+ def relation_type(crtype)
710
+ type = REALATION_TYPES[crtype] || begin
711
+ desc = Bib::LocalizedMarkedUpString.new(content: crtype)
712
+ "related"
713
+ end
714
+ [type, desc]
715
+ end
716
+
717
+ #
718
+ # Create included in relation.
719
+ #
720
+ # @return [Array<Bib::Relation>] The relations.
721
+ #
722
+ def included_in_relation
723
+ types = %w[
724
+ book book-chapter book-part book-section book-track dataset journal-issue
725
+ journal-value proceedings-article reference-entry report-component
726
+ ]
727
+ return [] unless @src["container-title"] && types.include?(@src["type"])
728
+
729
+ @src["container-title"].map do |ct|
730
+ contrib = create_authors_editors false, "editor"
731
+ bib = Bib::ItemBase.new(title: [Bib::Title.new(content: ct)], contributor: contrib)
732
+ Bib::Relation.new(type: "includedIn", bibitem: bib)
733
+ end
734
+ end
735
+
736
+ #
737
+ # Fetch year from the source hash.
738
+ #
739
+ # @return [String] The year.
740
+ #
741
+ def fetch_year
742
+ d = @src["published"] || @src["approved"] || @src["created"]
743
+ d["date-parts"][0][0]
744
+ end
745
+
746
+ #
747
+ # Parse an extent from the source hash.
748
+ #
749
+ # @return [Array<Bib::Extent>] The extent.
750
+ #
751
+ def parse_extent # rubocop:disable Metrics/AbcSize
752
+ extent = []
753
+ extent << Bib::Locality.new(type: "volume", reference_from: @src["volume"]) if @src["volume"]
754
+ extent << Bib::Locality.new(type: "issue", reference_from: @src["issue"]) if @src["issue"]
755
+ if @src["page"]
756
+ from, to = @src["page"].split("-")
757
+ extent << Bib::Locality.new(type: "page", reference_from: from, reference_to: to)
758
+ end
759
+ extent.any? ? [Bib::Extent.new(locality: extent)] : []
760
+ end
761
+
762
+ #
763
+ # Parse a series from the source hash.
764
+ #
765
+ # @return [Array<Bib::Series>] The series.
766
+ #
767
+ def parse_series # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
768
+ types = %w[inbook incollection inproceedings]
769
+ return [] if !@src["container-title"] || types.include?(@item[:type]) || @src["type"] == "report-component"
770
+
771
+ con_ttl = if main_sub_titles.any? || project_titles.any?
772
+ @src["container-title"]
773
+ elsif @src["container-title"].size > 1
774
+ sct = @src["short-container-title"]&.last
775
+ abbrev = Bib::LocalizedString.new(content: sct) if sct
776
+ @src["container-title"][-1..-1]
777
+ else []
778
+ end
779
+ con_ttl.map do |ct|
780
+ title = Bib::Title.new content: ct
781
+ Bib::Series.new title: [title], abbreviation: abbrev
782
+ end
783
+ end
784
+
785
+ #
786
+ # Parse a medium from the source hash.
787
+ #
788
+ # @return [Bib::Medium, nil] The medium.
789
+ #
790
+ def parse_medium
791
+ genre = @src["degree"]&.first
792
+ return unless genre
793
+
794
+ Bib::Medium.new genre: genre
795
+ end
796
+
797
+ #
798
+ # Fetch data from Crossref API with retry logic.
799
+ #
800
+ # @param [String] query The query string.
801
+ # @param [String] filter The filter string.
802
+ #
803
+ # @return [Array<Hash>, nil] Items array from response or nil for 4xx responses.
804
+ #
805
+ # @raise [Relaton::RequestError] If request fails after retries.
806
+ #
807
+ def fetch_crossref(query:, filter:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
808
+ url = format(CROSSREF_API_URL, query: query, filter: filter)
809
+ retries = 0
810
+ begin
811
+ resp = Crossref.agent.get url
812
+ JSON.parse(resp.body).dig("message", "items")
813
+ rescue Mechanize::ResponseCodeError => e
814
+ return nil if e.response_code.start_with?("4")
815
+
816
+ raise Relaton::RequestError, "Crossref request failed: #{e.response_code} #{e.page.body}"
817
+ rescue Net::HTTP::Persistent::Error, Net::HTTPError, Errno::ECONNREFUSED => e
818
+ retries += 1
819
+ retry if retries <= MAX_RETRIES
820
+ raise Relaton::RequestError, "Crossref network error after #{MAX_RETRIES} retries: #{e.message}"
821
+ rescue JSON::ParserError => e
822
+ raise Relaton::RequestError, "Crossref JSON parsing error: #{e.message}"
823
+ end
824
+ end
825
+ end
826
+ end
827
+ end