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,20 @@
1
+ module Relaton
2
+ module Iho
3
+ class StructuredIdentifier < Lutaml::Model::Serializable
4
+ attribute :docnumber, :string
5
+ attribute :part, :string
6
+ attribute :annexid, :string
7
+ attribute :appendixid, :string
8
+ attribute :supplementid, :string
9
+
10
+ xml do
11
+ root "structuredidentifier"
12
+ map_element "docnumber", to: :docnumber
13
+ map_element "part", to: :part
14
+ map_element "annexid", to: :annexid
15
+ map_element "appendixid", to: :appendixid
16
+ map_element "supplementid", to: :supplementid
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Iho
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-iho".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ require "relaton/bib"
2
+ require "relaton/index"
3
+ require "pubid"
4
+ require_relative "version"
5
+ require_relative "iho/util"
6
+ require_relative "iho/docidentifier"
7
+ require_relative "iho/item"
8
+ require_relative "iho/bibitem"
9
+ require_relative "iho/bibdata"
10
+ require_relative "iho/bibliography"
11
+
12
+ module Relaton
13
+ module Iho
14
+ INDEXFILE = "index-v3".freeze
15
+
16
+ class Error < StandardError; end
17
+
18
+ # Returns hash of XML reammar
19
+ # @return [String]
20
+ def self.grammar_hash
21
+ # gem_path = File.expand_path "..", __dir__
22
+ # grammars_path = File.join gem_path, "grammars", "*"
23
+ # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
24
+ Digest::MD5.hexdigest Relaton::VERSION # grammars
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,52 @@
1
+ module Relaton
2
+ module Index
3
+ #
4
+ # Configuration class for Relaton::Index
5
+ #
6
+ class Config
7
+ attr_reader :storage, :storage_dir, :filename
8
+
9
+ #
10
+ # Set default values
11
+ #
12
+ def initialize
13
+ @storage = FileStorage
14
+ @storage_dir = Dir.home
15
+ @filename = "index.yaml"
16
+ end
17
+
18
+ #
19
+ # Set storage
20
+ #
21
+ # @param [#ctime, #read, #write] storage storage object
22
+ #
23
+ # @return [void]
24
+ #
25
+ def storage=(storage)
26
+ @storage = storage
27
+ end
28
+
29
+ #
30
+ # Set storage directory
31
+ #
32
+ # @param [String] dir storage directory
33
+ #
34
+ # @return [void]
35
+ #
36
+ def storage_dir=(dir)
37
+ @storage_dir = dir
38
+ end
39
+
40
+ #
41
+ # Set filename
42
+ #
43
+ # @param [String] filename filename
44
+ #
45
+ # @return [void]
46
+ #
47
+ def filename=(filename)
48
+ @filename = filename
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,305 @@
1
+ module Relaton
2
+ module Index
3
+ #
4
+ # File IO class is used to read and write index files.
5
+ # In searh mode url is used to fetch index from external repository and save it to storage.
6
+ # In index mode url should be nil.
7
+ #
8
+ class FileIO
9
+ include IdNumber
10
+
11
+ # Raised internally when a deserialized id cannot be parsed or is not
12
+ # understood by the pubid class; `#load_index` rescues it to trigger the
13
+ # wrong-structure handling (re-download, or stop and log).
14
+ class InvalidIndexError < StandardError; end
15
+
16
+ attr_reader :url, :pubid_class
17
+ attr_accessor :sorted
18
+
19
+ @@file_locks = {}
20
+ @@file_locks_mutex = Mutex.new
21
+
22
+ #
23
+ # Initialize FileIO
24
+ #
25
+ # @param [String] dir falvor specific local directory in ~/.relaton to store index
26
+ # @param [String, Boolean, nil] url
27
+ # if String then the URL is used to fetch an index from a Git repository
28
+ # and save it to the storage (if not exists, or older than 24 hours)
29
+ # if true then the index is read from the storage (used to remove index file)
30
+ # if nil then the fiename is used to read and write file (used to create indes in GH actions)
31
+ # @param [Pubid::Identifier] pubid class for deserialization
32
+ #
33
+ # `id_keys` is accepted for backward compatibility but no longer used: the
34
+ # index format is now validated by round-tripping a sample of ids through
35
+ # the pubid class (see #check_serialization), which understands the pubid
36
+ # v2 (lutaml) `_type` serialization that the old key-allowlist could not.
37
+ def initialize(dir, url, filename, _id_keys = nil, pubid_class = nil)
38
+ @dir = dir
39
+ @url = url
40
+ @filename = filename
41
+ @pubid_class = pubid_class
42
+ @sorted = false
43
+ end
44
+
45
+ #
46
+ # If url is String, check if index file exists and is not older than 24
47
+ # hours. If not, fetch index from external repository and save it to
48
+ # storage.
49
+ # If url is true, read index from path to local file.
50
+ # If url is nil, read index from filename.
51
+ #
52
+ # @return [Array<Hash>] index
53
+ #
54
+ def read
55
+ case url
56
+ when String
57
+ with_file_lock do
58
+ check_file || fetch_and_save
59
+ end
60
+ else
61
+ read_file || []
62
+ end
63
+ end
64
+
65
+ def file
66
+ @file ||= url ? path_to_local_file : @filename
67
+ end
68
+
69
+ #
70
+ # Create path to local file
71
+ #
72
+ # @return [<Type>] <description>
73
+ #
74
+ def path_to_local_file
75
+ File.join(Index.config.storage_dir, ".relaton", @dir, @filename)
76
+ end
77
+
78
+ #
79
+ # Check if index file exists and is not older than 24 hours
80
+ #
81
+ # @return [Array<Hash>, nil] index or nil
82
+ #
83
+ def check_file
84
+ ctime = Index.config.storage.ctime(file)
85
+ return unless ctime && ctime > Time.now - 86400
86
+
87
+ read_file
88
+ end
89
+
90
+ #
91
+ # Check if index has correct format
92
+ #
93
+ # @param [Array<Hash>] index index to check
94
+ #
95
+ # @return [Boolean] <description>
96
+ #
97
+ # Structural check only. Per-id serialization is validated during
98
+ # deserialization (see #deserialize_id), which reuses the `from_hash` the
99
+ # index load performs anyway, so every row is checked at no extra parse
100
+ # cost.
101
+ def check_format(index)
102
+ check_basic_format(index)
103
+ end
104
+
105
+ def check_basic_format(index)
106
+ return false unless index.is_a? Array
107
+
108
+ keys = %i[file id]
109
+ index.all? { |item| item.respond_to?(:keys) && item.keys.sort == keys }
110
+ end
111
+
112
+ # An id is supported when `from_hash` either resolves it to a concrete
113
+ # type (a subclass — the polymorphic `_type` matched) or round-trips
114
+ # losslessly through `to_hash`. The subclass clause covers valid entries
115
+ # pubid cannot fully rebuild on re-serialize (e.g. ISO directives drop a
116
+ # redundant subgroup number); the round-trip clause covers pubid classes
117
+ # without a subclass hierarchy. A wrong-format/garbled id satisfies
118
+ # neither: it falls back to the bare base class and fails to round-trip.
119
+ def id_supported?(obj, raw)
120
+ # A concrete subtype means pubid recognized the `_type`; accept without
121
+ # round-tripping. This both skips the false positive for valid-but-lossy
122
+ # types (e.g. ISO directives) and avoids the costly hash compare for the
123
+ # ~all rows that resolve to a subtype (it would otherwise add ~33%).
124
+ return true unless obj.instance_of?(@pubid_class)
125
+
126
+ normalize(obj.to_hash) == normalize(raw)
127
+ rescue StandardError
128
+ false
129
+ end
130
+
131
+ # Stringify hash keys and scalar values so the comparison ignores YAML
132
+ # scalar typing (e.g. 1 vs "1") and string/symbol key differences, while
133
+ # still detecting dropped/added keys or genuinely changed values.
134
+ def normalize(value)
135
+ case value
136
+ when Hash then value.to_h { |k, v| [k.to_s, normalize(v)] }
137
+ when Array then value.map { |v| normalize(v) }
138
+ when nil then nil
139
+ else value.to_s
140
+ end
141
+ end
142
+
143
+ #
144
+ # Read index from storage
145
+ #
146
+ # @return [Array<Hash>] index
147
+ #
148
+ def read_file
149
+ yaml = Index.config.storage.read(file)
150
+ return unless yaml
151
+
152
+ load_index(yaml) || []
153
+ end
154
+
155
+ # Deserialize and sort by the same narrowing key Type#search bsearches
156
+ # on, so binary search always has a consistent total order. The published
157
+ # index is only approximately sorted (generated under pubid 1.x base
158
+ # semantics); merely detecting sortedness left bsearch disabled and every
159
+ # search a full O(n) scan. Sorting here is one-time per load.
160
+ def deserialize_pubid(index)
161
+ return index unless @pubid_class
162
+
163
+ deserialized = index.map do |r|
164
+ { id: deserialize_id(r[:id]), file: r[:file] }
165
+ end
166
+ warn_unless_sorted(deserialized)
167
+ deserialized.sort_by! { |r| get_id_number(r[:id]) }
168
+ @sorted = true
169
+ deserialized
170
+ end
171
+
172
+ # Deserialize one id and verify pubid understands it. Reuses the
173
+ # `from_hash` deserialization the load performs anyway, so validating every
174
+ # row costs only the `to_hash`/compare for ids that need the round-trip
175
+ # clause. Raises InvalidIndexError when an id cannot be parsed or is
176
+ # unsupported, so `#load_index` rejects (and re-downloads) the whole index.
177
+ def deserialize_id(raw)
178
+ obj = @pubid_class.from_hash(raw)
179
+ rescue StandardError => e
180
+ raise InvalidIndexError, "cannot parse id #{raw.inspect}: #{e.message}"
181
+ else
182
+ return obj if id_supported?(obj, raw)
183
+
184
+ raise InvalidIndexError, "unsupported id #{raw.inspect}"
185
+ end
186
+
187
+ # Log when the loaded index is not already in get_id_number order, so the
188
+ # in-memory sort above (and the underlying not-sorted index file) is
189
+ # visible. Stops at the first out-of-order pair.
190
+ def warn_unless_sorted(index)
191
+ prev = nil
192
+ index.each do |r|
193
+ num = get_id_number(r[:id])
194
+ if prev && prev > num
195
+ Util.warn "Index file `#{file}` is not sorted by id number; " \
196
+ "sorting #{index.size} entries in memory.", progname
197
+ return
198
+ end
199
+ prev = num
200
+ end
201
+ end
202
+
203
+ def warn_local_index_error(reason)
204
+ Util.info "#{reason} file `#{file}`", progname
205
+ if url.is_a? String
206
+ Util.info "Considering `#{file}` file corrupt, re-downloading from `#{url}`", progname
207
+ else
208
+ Util.info "Considering `#{file}` file corrupt, removing it.", progname
209
+ remove
210
+ end
211
+ end
212
+
213
+ def progname
214
+ @progname ||= "relaton-#{@dir}"
215
+ end
216
+
217
+ def load_index(yaml, save = false)
218
+ index = YAML.safe_load(yaml, permitted_classes: [Symbol])
219
+ save index if save
220
+ return deserialize_pubid(index) if check_format(index)
221
+
222
+ report_invalid_index(save, "Wrong structure of")
223
+ rescue Psych::SyntaxError
224
+ report_invalid_index(save, "YAML parsing error when reading")
225
+ rescue InvalidIndexError
226
+ report_invalid_index(save, "Wrong structure of")
227
+ end
228
+
229
+ def report_invalid_index(save, reason)
230
+ if save
231
+ warn_remote_index_error reason
232
+ else
233
+ warn_local_index_error reason
234
+ end
235
+ end
236
+
237
+ #
238
+ # Fetch index from external repository and save it to storage
239
+ #
240
+ # @return [Array<Hash>] index
241
+ #
242
+ def fetch_and_save
243
+ uri = URI.parse(url)
244
+ body = Net::HTTP.get(uri)
245
+ yaml = nil
246
+ Zip::File.open_buffer(body) do |zip|
247
+ entry = zip.entries.first
248
+ yaml = entry.get_input_stream.read
249
+ end
250
+ Util.info "Downloaded index from `#{url}`", progname
251
+ load_index(yaml, true)
252
+ end
253
+
254
+ def warn_remote_index_error(reason)
255
+ Util.info "#{reason} newly downloaded file `#{file}` at `#{url}`, " \
256
+ "the remote index seems to be invalid. Please report this " \
257
+ "issue at https://github.com/relaton/relaton-cli.", progname
258
+ end
259
+
260
+ #
261
+ # Save index to storage
262
+ #
263
+ # @param [Array<Hash>] index index to save
264
+ #
265
+ # @return [void]
266
+ #
267
+ def save(index)
268
+ yaml = sort_structured_index(index).map do |item|
269
+ item.transform_values do |value|
270
+ @pubid_class && value.is_a?(@pubid_class) ? value.to_hash : value
271
+ end
272
+ end.to_yaml
273
+ Index.config.storage.write file, yaml
274
+ end
275
+
276
+ def sort_structured_index(index)
277
+ if @pubid_class && index.first&.dig(:id).is_a?(@pubid_class)
278
+ index.sort_by { |item| get_id_number item[:id] }
279
+ else
280
+ index
281
+ end
282
+ end
283
+
284
+ #
285
+ # Remove index file from storage
286
+ #
287
+ # @return [Array]
288
+ #
289
+ def remove
290
+ Index.config.storage.remove file
291
+ []
292
+ end
293
+
294
+ private
295
+
296
+ def with_file_lock(&)
297
+ @@file_locks_mutex.synchronize do
298
+ @@file_locks[file] ||= Mutex.new
299
+ end
300
+
301
+ @@file_locks[file].synchronize(&)
302
+ end
303
+ end
304
+ end
305
+ end
@@ -0,0 +1,61 @@
1
+ module Relaton
2
+ module Index
3
+ #
4
+ # File storage module contains methods to read and write files
5
+ #
6
+ module FileStorage
7
+ #
8
+ # Return file creation time
9
+ #
10
+ # @param [String] file file path
11
+ #
12
+ # @return [Time, nil] file creation time or nil if file does not exist
13
+ #
14
+ def ctime(file)
15
+ File.exist?(file) && File.ctime(file)
16
+ end
17
+
18
+ #
19
+ # Read file
20
+ #
21
+ # @param [String] file file path
22
+ #
23
+ # @return [String, nil] file content or nil if file does not exist
24
+ #
25
+ def read(file)
26
+ return unless File.exist?(file)
27
+
28
+ File.read file, encoding: "UTF-8"
29
+ end
30
+
31
+ #
32
+ # Write file
33
+ #
34
+ # @param [String] file file path
35
+ # @param [String] data content to write
36
+ #
37
+ # @return [void]
38
+ #
39
+ def write(file, data)
40
+ dir = File.dirname file
41
+ FileUtils.mkdir_p dir
42
+ File.write file, data, encoding: "UTF-8"
43
+ end
44
+
45
+ #
46
+ # Remove file
47
+ #
48
+ # @param [String] file file path
49
+ #
50
+ # @return [void]
51
+ #
52
+ def remove(file)
53
+ return unless File.exist? file
54
+
55
+ File.delete file
56
+ end
57
+
58
+ extend self
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ module Relaton
2
+ module Index
3
+ # Shared narrowing/sort key for structured (pubid) index ids. Type uses it
4
+ # for binary-search narrowing; FileIO uses it to sort the index and detect
5
+ # sortedness. The two MUST agree, so the rule lives in one place.
6
+ module IdNumber
7
+ # One-level narrowing key: a supplement/amendment is filed under its
8
+ # immediate parent's number, everything else under its own number.
9
+ #
10
+ # Pubid 2.x exposes the parent via `.base_identifier` (the LutaML
11
+ # `Pubid::Iso::Identifiers::*` classes that relaton loads at runtime). A
12
+ # standalone `require "pubid-iso"` can instead surface the legacy
13
+ # `Pubid::Iso::Identifier::*` classes, which use `.base`; we accept either
14
+ # so the key is stable in both load orders. The wrong accessor silently
15
+ # falls through to the row's own number and breaks bsearch narrowing.
16
+ def get_id_number(id)
17
+ base = id_base(id)
18
+ ((base && base.number) || id.number).to_s
19
+ end
20
+
21
+ def id_base(id)
22
+ if id.respond_to?(:base_identifier) && id.base_identifier
23
+ id.base_identifier
24
+ elsif id.respond_to?(:base) && id.base
25
+ id.base
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ module Relaton
2
+ module Index
3
+ #
4
+ # Pool of indexes
5
+ #
6
+ class Pool
7
+ def initialize
8
+ @pool = {}
9
+ end
10
+
11
+ #
12
+ # Return index by type, create if not exists
13
+ #
14
+ # @param [String] type <description>
15
+ # @param [String, nil] url external URL to index, used to fetch index for searching files
16
+ # @param [String, nil] file output file name
17
+ # @param [Array<Symbol>, nil] id_keys keys to check if index is correct
18
+ #
19
+ # @return [Relaton::Index::Type] typed index
20
+ #
21
+ def type(type, **args)
22
+ if @pool[type.upcase.to_sym]&.actual?(**args)
23
+ @pool[type.upcase.to_sym]
24
+ else
25
+ @pool[type.upcase.to_sym] = Type.new(type, args[:url], args[:file], args[:id_keys], args[:pubid_class])
26
+ end
27
+ end
28
+
29
+ #
30
+ # Remove index by type from pool
31
+ #
32
+ # @param [String] type index type
33
+ #
34
+ # @return [void]
35
+ #
36
+ def remove(type)
37
+ @pool.delete type.upcase.to_sym
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,159 @@
1
+ module Relaton
2
+ module Index
3
+ #
4
+ # Relaton::Index::Type is a class for indexing Relaton files.
5
+ #
6
+ class Type
7
+ include IdNumber
8
+
9
+ #
10
+ # Initialize a new Relaton::Index::Type object
11
+ #
12
+ # @param [String, Symbol] type type of index (ISO, IEC, etc.)
13
+ # @param [String, nil] url external URL to index, used to fetch index for searching files
14
+ # @param [String, nil] file output file name
15
+ # @param [Array<Symbol>] id_keys keys of identifier to be used for sorting index
16
+ # format of index file is checked if id_keys all is provided at least in one of the IDs
17
+ # @param [Pubid::Identifier, nil] pubid class for deserialization
18
+ #
19
+ def initialize(type, url = nil, file = nil, id_keys = nil, pubid_class = nil) # rubocop:disable Metrics/ParameterLists
20
+ @file = file
21
+ filename = file || Index.config.filename
22
+ @file_io = FileIO.new type.to_s.downcase, url, filename, id_keys, pubid_class
23
+ end
24
+
25
+ def index
26
+ @index ||= @file_io.read
27
+ end
28
+
29
+ #
30
+ # Check if index is actual. If url or file is given, check if it is equal to
31
+ # index url or file.
32
+ #
33
+ # @param [Hash] **args arguments
34
+ # @option args [String, nil] :url external URL to index, used to fetch index for searching files
35
+ # @option args [String, nil] :file output file name
36
+ #
37
+ # @return [Boolean] true if index is actual, false otherwise
38
+ #
39
+ def actual?(**args)
40
+ (!args.key?(:url) || args[:url] == @file_io.url) && (!args.key?(:file) || args[:file] == @file)
41
+ end
42
+
43
+ #
44
+ # Add or update index item
45
+ #
46
+ # @param [Pubid::Identifier] id document ID
47
+ # @param [String] file file name of the document
48
+ #
49
+ # @return [void]
50
+ #
51
+ def add_or_update(id, file)
52
+ key = id.to_s
53
+ item = id_lookup[key]
54
+ if item
55
+ item[:file] = file
56
+ else
57
+ new_item = { id: id, file: file }
58
+ index << new_item
59
+ id_lookup[key] = new_item
60
+ @file_io.sorted = false
61
+ end
62
+ end
63
+
64
+ #
65
+ # Search index for a given ID
66
+ #
67
+ # @param [String, Pubid::Identifier] id ID to search for
68
+ #
69
+ # @return [Array<Hash>] search results
70
+ #
71
+ def search(id = nil, &block)
72
+ items = search_candidates(id)
73
+ return items.select(&block) if block
74
+
75
+ items.select { |i| match_item(i, id) }
76
+ end
77
+
78
+ #
79
+ # Save index to storage
80
+ #
81
+ # @return [void]
82
+ #
83
+ def save
84
+ @file_io.save(@index || [])
85
+ end
86
+
87
+ #
88
+ # Remove index file from storage and clear index
89
+ #
90
+ # @return [void]
91
+ #
92
+ def remove_file
93
+ @file_io.remove
94
+ @index = nil
95
+ @id_lookup = nil
96
+ end
97
+
98
+ #
99
+ # Remove all index items
100
+ #
101
+ # @return [void]
102
+ #
103
+ def remove_all
104
+ @index = []
105
+ @id_lookup = nil
106
+ @file_io.sorted = true
107
+ end
108
+
109
+ private
110
+
111
+ def id_lookup
112
+ @id_lookup ||= index.each_with_object({}) do |item, h|
113
+ h[item[:id].to_s] = item
114
+ end
115
+ end
116
+
117
+ def search_candidates(id)
118
+ # index needs to be created to check if sorted
119
+ idx = index
120
+ if @file_io.sorted && id && !id.is_a?(String)
121
+ candidates_by_number(id)
122
+ else
123
+ idx
124
+ end
125
+ end
126
+
127
+ def candidates_by_number(id)
128
+ target = get_id_number(id)
129
+ left = bsearch_left(target)
130
+ return [] unless left
131
+
132
+ right = bsearch_right(target)
133
+ index[left...right]
134
+ end
135
+
136
+ def bsearch_left(target)
137
+ index.bsearch_index do |item|
138
+ get_id_number(item[:id]) >= target
139
+ end
140
+ end
141
+
142
+ def bsearch_right(target)
143
+ index.bsearch_index do |item|
144
+ get_id_number(item[:id]) > target
145
+ end || index.size
146
+ end
147
+
148
+ def match_item(item, id)
149
+ if item[:id].is_a?(String)
150
+ item[:id].include?(id.is_a?(String) ? id : id.to_s)
151
+ elsif id.is_a?(String)
152
+ item[:id].to_s.include?(id)
153
+ else
154
+ item[:id] == id
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end