relaton 2.2.0.pre.alpha.1 → 3.0.0.pre.alpha.2

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 (702) hide show
  1. checksums.yaml +4 -4
  2. data/{docs/README.adoc → README.adoc} +165 -38
  3. data/bin/console +0 -1
  4. data/lib/relaton/3gpp/bibdata.rb +9 -0
  5. data/lib/relaton/3gpp/bibitem.rb +9 -0
  6. data/lib/relaton/3gpp/bibliography.rb +123 -0
  7. data/lib/relaton/3gpp/data_fetcher.rb +303 -0
  8. data/lib/relaton/3gpp/docidentifier.rb +114 -0
  9. data/lib/relaton/3gpp/doctype.rb +9 -0
  10. data/lib/relaton/3gpp/ext.rb +31 -0
  11. data/lib/relaton/3gpp/item.rb +18 -0
  12. data/lib/relaton/3gpp/item_data.rb +15 -0
  13. data/lib/relaton/3gpp/parser.rb +400 -0
  14. data/lib/relaton/3gpp/processor.rb +71 -0
  15. data/lib/relaton/3gpp/release.rb +34 -0
  16. data/lib/relaton/3gpp/util.rb +8 -0
  17. data/lib/relaton/3gpp.rb +29 -0
  18. data/lib/relaton/adobe/bibdata.rb +8 -0
  19. data/lib/relaton/adobe/bibitem.rb +8 -0
  20. data/lib/relaton/adobe/bibliography.rb +92 -0
  21. data/lib/relaton/adobe/docidentifier.rb +49 -0
  22. data/lib/relaton/adobe/doctype.rb +14 -0
  23. data/lib/relaton/adobe/ext.rb +32 -0
  24. data/lib/relaton/adobe/item.rb +15 -0
  25. data/lib/relaton/adobe/item_base.rb +18 -0
  26. data/lib/relaton/adobe/item_data.rb +6 -0
  27. data/lib/relaton/adobe/processor.rb +45 -0
  28. data/lib/relaton/adobe/util.rb +8 -0
  29. data/lib/relaton/adobe.rb +37 -0
  30. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  31. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  32. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  33. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  34. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  35. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
  36. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  37. data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
  38. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  39. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  40. data/lib/relaton/bib/hash_parser_v1.rb +767 -0
  41. data/lib/relaton/bib/item_data.rb +229 -0
  42. data/lib/relaton/bib/model/abstract.rb +16 -0
  43. data/lib/relaton/bib/model/address.rb +22 -0
  44. data/lib/relaton/bib/model/affiliation.rb +16 -0
  45. data/lib/relaton/bib/model/bibdata.rb +11 -0
  46. data/lib/relaton/bib/model/bibdata_shared.rb +12 -0
  47. data/lib/relaton/bib/model/bibitem.rb +11 -0
  48. data/lib/relaton/bib/model/bibitem_shared.rb +12 -0
  49. data/lib/relaton/bib/model/contact.rb +18 -0
  50. data/lib/relaton/bib/model/contribution_info.rb +15 -0
  51. data/lib/relaton/bib/model/contributor.rb +29 -0
  52. data/lib/relaton/bib/model/copyright.rb +27 -0
  53. data/lib/relaton/bib/model/date.rb +31 -0
  54. data/lib/relaton/bib/model/depiction.rb +16 -0
  55. data/lib/relaton/bib/model/docidentifier.rb +49 -0
  56. data/lib/relaton/bib/model/doctype.rb +14 -0
  57. data/lib/relaton/bib/model/edition.rb +14 -0
  58. data/lib/relaton/bib/model/ext.rb +39 -0
  59. data/lib/relaton/bib/model/extent.rb +16 -0
  60. data/lib/relaton/bib/model/formattedref.rb +43 -0
  61. data/lib/relaton/bib/model/full_name_type.rb +64 -0
  62. data/lib/relaton/bib/model/fullname.rb +11 -0
  63. data/lib/relaton/bib/model/ics.rb +49 -0
  64. data/lib/relaton/bib/model/image.rb +28 -0
  65. data/lib/relaton/bib/model/item.rb +96 -0
  66. data/lib/relaton/bib/model/item_base.rb +20 -0
  67. data/lib/relaton/bib/model/item_shared.rb +88 -0
  68. data/lib/relaton/bib/model/keyword.rb +30 -0
  69. data/lib/relaton/bib/model/locality.rb +18 -0
  70. data/lib/relaton/bib/model/locality_stack.rb +14 -0
  71. data/lib/relaton/bib/model/localized_string.rb +48 -0
  72. data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
  73. data/lib/relaton/bib/model/logo.rb +14 -0
  74. data/lib/relaton/bib/model/medium.rb +22 -0
  75. data/lib/relaton/bib/model/note.rb +16 -0
  76. data/lib/relaton/bib/model/organization.rb +13 -0
  77. data/lib/relaton/bib/model/organization_type.rb +42 -0
  78. data/lib/relaton/bib/model/person.rb +36 -0
  79. data/lib/relaton/bib/model/phone.rb +14 -0
  80. data/lib/relaton/bib/model/place.rb +33 -0
  81. data/lib/relaton/bib/model/price.rb +14 -0
  82. data/lib/relaton/bib/model/relation.rb +43 -0
  83. data/lib/relaton/bib/model/series.rb +34 -0
  84. data/lib/relaton/bib/model/size.rb +23 -0
  85. data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
  86. data/lib/relaton/bib/model/status.rb +27 -0
  87. data/lib/relaton/bib/model/structured_identifier.rb +49 -0
  88. data/lib/relaton/bib/model/subdivision.rb +16 -0
  89. data/lib/relaton/bib/model/title.rb +56 -0
  90. data/lib/relaton/bib/model/type/plain_date.rb +16 -0
  91. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  92. data/lib/relaton/bib/model/uri.rb +18 -0
  93. data/lib/relaton/bib/model/validity.rb +16 -0
  94. data/lib/relaton/bib/model/version.rb +43 -0
  95. data/lib/relaton/bib/namespace_helper.rb +21 -0
  96. data/lib/relaton/bib/sanitizer.rb +264 -0
  97. data/lib/relaton/bib/util.rb +18 -0
  98. data/lib/relaton/bib/versions.json +35 -0
  99. data/lib/relaton/bib.rb +46 -0
  100. data/lib/relaton/bipm/bibliography.rb +231 -0
  101. data/lib/relaton/bipm/converter/asciibib.rb +64 -0
  102. data/lib/relaton/bipm/data_fetcher.rb +81 -0
  103. data/lib/relaton/bipm/data_outcomes_parser.rb +656 -0
  104. data/lib/relaton/bipm/id_parser.rb +278 -0
  105. data/lib/relaton/bipm/item_data.rb +47 -0
  106. data/lib/relaton/bipm/model/bibdata.rb +9 -0
  107. data/lib/relaton/bipm/model/bibitem.rb +9 -0
  108. data/lib/relaton/bipm/model/comment_period.rb +13 -0
  109. data/lib/relaton/bipm/model/doctype.rb +12 -0
  110. data/lib/relaton/bipm/model/ext.rb +38 -0
  111. data/lib/relaton/bipm/model/item.rb +11 -0
  112. data/lib/relaton/bipm/model/structured_identifier.rb +36 -0
  113. data/lib/relaton/bipm/processor.rb +69 -0
  114. data/lib/relaton/bipm/rawdata_bipm_metrologia/affiliations.rb +111 -0
  115. data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +172 -0
  116. data/lib/relaton/bipm/rawdata_bipm_metrologia/niso_jats_parser.rb +353 -0
  117. data/lib/relaton/bipm/si_brochure_parser.rb +188 -0
  118. data/lib/relaton/bipm/util.rb +8 -0
  119. data/lib/relaton/bipm.rb +38 -0
  120. data/lib/relaton/bsi/bibliography.rb +196 -0
  121. data/lib/relaton/bsi/hit.rb +28 -0
  122. data/lib/relaton/bsi/hit_collection.rb +113 -0
  123. data/lib/relaton/bsi/item_data.rb +13 -0
  124. data/lib/relaton/bsi/model/bibdata.rb +8 -0
  125. data/lib/relaton/bsi/model/bibitem.rb +8 -0
  126. data/lib/relaton/bsi/model/docidentifier.rb +107 -0
  127. data/lib/relaton/bsi/model/doctype.rb +14 -0
  128. data/lib/relaton/bsi/model/ext.rb +17 -0
  129. data/lib/relaton/bsi/model/item.rb +17 -0
  130. data/lib/relaton/bsi/model/item_base.rb +22 -0
  131. data/lib/relaton/bsi/model/relation.rb +9 -0
  132. data/lib/relaton/bsi/processor.rb +43 -0
  133. data/lib/relaton/bsi/schema.json +24882 -0
  134. data/lib/relaton/bsi/scraper.rb +288 -0
  135. data/lib/relaton/bsi/util.rb +8 -0
  136. data/lib/relaton/bsi.rb +25 -0
  137. data/lib/relaton/calconnect/bibliography.rb +93 -0
  138. data/lib/relaton/calconnect/data_fetcher.rb +174 -0
  139. data/lib/relaton/calconnect/docidentifier.rb +80 -0
  140. data/lib/relaton/calconnect/hit.rb +14 -0
  141. data/lib/relaton/calconnect/hit_collection.rb +92 -0
  142. data/lib/relaton/calconnect/item_data.rb +12 -0
  143. data/lib/relaton/calconnect/model/bibdata.rb +8 -0
  144. data/lib/relaton/calconnect/model/bibitem.rb +8 -0
  145. data/lib/relaton/calconnect/model/doctype.rb +11 -0
  146. data/lib/relaton/calconnect/model/ext.rb +11 -0
  147. data/lib/relaton/calconnect/model/item.rb +20 -0
  148. data/lib/relaton/calconnect/processor.rb +72 -0
  149. data/lib/relaton/calconnect/scraper.rb +87 -0
  150. data/lib/relaton/calconnect/util.rb +8 -0
  151. data/lib/relaton/calconnect.rb +36 -0
  152. data/lib/relaton/ccsds/bibliography.rb +63 -0
  153. data/lib/relaton/ccsds/data/fetcher.rb +252 -0
  154. data/lib/relaton/ccsds/data/iso_references.rb +30 -0
  155. data/lib/relaton/ccsds/data/parser.rb +194 -0
  156. data/lib/relaton/ccsds/hit.rb +24 -0
  157. data/lib/relaton/ccsds/hit_collection.rb +47 -0
  158. data/lib/relaton/ccsds/item_data.rb +9 -0
  159. data/lib/relaton/ccsds/model/bibdata.rb +8 -0
  160. data/lib/relaton/ccsds/model/bibitem.rb +8 -0
  161. data/lib/relaton/ccsds/model/docidentifier.rb +121 -0
  162. data/lib/relaton/ccsds/model/doctype.rb +9 -0
  163. data/lib/relaton/ccsds/model/ext.rb +19 -0
  164. data/lib/relaton/ccsds/model/item.rb +15 -0
  165. data/lib/relaton/ccsds/processor.rb +68 -0
  166. data/lib/relaton/ccsds/util.rb +10 -0
  167. data/lib/relaton/ccsds.rb +33 -0
  168. data/lib/relaton/cen/bibliography.rb +149 -0
  169. data/lib/relaton/cen/committees.yaml +66 -0
  170. data/lib/relaton/cen/hit.rb +31 -0
  171. data/lib/relaton/cen/hit_collection.rb +116 -0
  172. data/lib/relaton/cen/item_data.rb +7 -0
  173. data/lib/relaton/cen/model/bibdata.rb +8 -0
  174. data/lib/relaton/cen/model/bibitem.rb +8 -0
  175. data/lib/relaton/cen/model/docidentifier.rb +100 -0
  176. data/lib/relaton/cen/model/ext.rb +11 -0
  177. data/lib/relaton/cen/model/item.rb +14 -0
  178. data/lib/relaton/cen/model/structured_identifier.rb +9 -0
  179. data/lib/relaton/cen/processor.rb +45 -0
  180. data/lib/relaton/cen/scraper.rb +218 -0
  181. data/lib/relaton/cen/util.rb +8 -0
  182. data/lib/relaton/cen.rb +30 -0
  183. data/lib/relaton/cie/bibdata.rb +8 -0
  184. data/lib/relaton/cie/bibitem.rb +8 -0
  185. data/lib/relaton/cie/bibliography.rb +31 -0
  186. data/lib/relaton/cie/data_fetcher.rb +540 -0
  187. data/lib/relaton/cie/ext.rb +7 -0
  188. data/lib/relaton/cie/item.rb +11 -0
  189. data/lib/relaton/cie/item_data.rb +6 -0
  190. data/lib/relaton/cie/processor.rb +68 -0
  191. data/lib/relaton/cie/scrapper.rb +52 -0
  192. data/lib/relaton/cie/util.rb +8 -0
  193. data/lib/relaton/cie.rb +29 -0
  194. data/lib/relaton/core/array_wrapper.rb +20 -0
  195. data/lib/relaton/core/data_fetcher.rb +244 -0
  196. data/lib/relaton/core/date_parser.rb +42 -0
  197. data/lib/relaton/core/governor.rb +320 -0
  198. data/lib/relaton/core/hash_keys_sybolizer.rb +19 -0
  199. data/lib/relaton/core/hit.rb +49 -0
  200. data/lib/relaton/core/hit_collection.rb +118 -0
  201. data/lib/relaton/core/pacer.rb +134 -0
  202. data/lib/relaton/core/processor.rb +67 -0
  203. data/lib/relaton/core/request_error.rb +14 -0
  204. data/lib/relaton/core/workers_pool.rb +45 -0
  205. data/lib/relaton/core.rb +12 -0
  206. data/lib/relaton/db/registry.rb +44 -4
  207. data/lib/relaton/db.rb +0 -1
  208. data/lib/relaton/doi/crossref.rb +89 -0
  209. data/lib/relaton/doi/parser.rb +921 -0
  210. data/lib/relaton/doi/processor.rb +65 -0
  211. data/lib/relaton/doi/util.rb +8 -0
  212. data/lib/relaton/doi.rb +20 -0
  213. data/lib/relaton/easc/bibdata.rb +8 -0
  214. data/lib/relaton/easc/bibitem.rb +8 -0
  215. data/lib/relaton/easc/bibliography.rb +95 -0
  216. data/lib/relaton/easc/docidentifier.rb +100 -0
  217. data/lib/relaton/easc/doctype.rb +14 -0
  218. data/lib/relaton/easc/ext.rb +44 -0
  219. data/lib/relaton/easc/item.rb +13 -0
  220. data/lib/relaton/easc/item_base.rb +18 -0
  221. data/lib/relaton/easc/item_data.rb +6 -0
  222. data/lib/relaton/easc/processor.rb +46 -0
  223. data/lib/relaton/easc/util.rb +8 -0
  224. data/lib/relaton/easc.rb +35 -0
  225. data/lib/relaton/ecma/bibdata.rb +8 -0
  226. data/lib/relaton/ecma/bibitem.rb +8 -0
  227. data/lib/relaton/ecma/bibliography.rb +149 -0
  228. data/lib/relaton/ecma/data_fetcher.rb +162 -0
  229. data/lib/relaton/ecma/data_parser.rb +49 -0
  230. data/lib/relaton/ecma/docidentifier.rb +124 -0
  231. data/lib/relaton/ecma/edition_parser.rb +80 -0
  232. data/lib/relaton/ecma/ext.rb +7 -0
  233. data/lib/relaton/ecma/item.rb +13 -0
  234. data/lib/relaton/ecma/item_data.rb +6 -0
  235. data/lib/relaton/ecma/memento_parser.rb +60 -0
  236. data/lib/relaton/ecma/page_fetcher.rb +39 -0
  237. data/lib/relaton/ecma/parser_common.rb +33 -0
  238. data/lib/relaton/ecma/processor.rb +69 -0
  239. data/lib/relaton/ecma/standard_parser.rb +134 -0
  240. data/lib/relaton/ecma/util.rb +8 -0
  241. data/lib/relaton/ecma.rb +33 -0
  242. data/lib/relaton/etsi/bibdata.rb +10 -0
  243. data/lib/relaton/etsi/bibitem.rb +10 -0
  244. data/lib/relaton/etsi/bibliography.rb +111 -0
  245. data/lib/relaton/etsi/data_fetcher.rb +167 -0
  246. data/lib/relaton/etsi/data_parser.rb +208 -0
  247. data/lib/relaton/etsi/doctype.rb +30 -0
  248. data/lib/relaton/etsi/ext.rb +31 -0
  249. data/lib/relaton/etsi/item.rb +15 -0
  250. data/lib/relaton/etsi/item_data.rb +6 -0
  251. data/lib/relaton/etsi/processor.rb +71 -0
  252. data/lib/relaton/etsi/pubid.rb +37 -0
  253. data/lib/relaton/etsi/status.rb +13 -0
  254. data/lib/relaton/etsi/util.rb +8 -0
  255. data/lib/relaton/etsi.rb +26 -0
  256. data/lib/relaton/gb/bibdata.rb +8 -0
  257. data/lib/relaton/gb/bibitem.rb +8 -0
  258. data/lib/relaton/gb/bibliography.rb +171 -0
  259. data/lib/relaton/gb/ccs.rb +14 -0
  260. data/lib/relaton/gb/committee.rb +13 -0
  261. data/lib/relaton/gb/docidentifier.rb +72 -0
  262. data/lib/relaton/gb/doctype.rb +9 -0
  263. data/lib/relaton/gb/ext.rb +36 -0
  264. data/lib/relaton/gb/gb_scraper.rb +61 -0
  265. data/lib/relaton/gb/gb_type.rb +20 -0
  266. data/lib/relaton/gb/hit.rb +48 -0
  267. data/lib/relaton/gb/hit_collection.rb +19 -0
  268. data/lib/relaton/gb/item.rb +13 -0
  269. data/lib/relaton/gb/item_data.rb +6 -0
  270. data/lib/relaton/gb/processor.rb +49 -0
  271. data/lib/relaton/gb/project_number.rb +38 -0
  272. data/lib/relaton/gb/scraper.rb +221 -0
  273. data/lib/relaton/gb/sec_scraper.rb +92 -0
  274. data/lib/relaton/gb/stage_name.rb +13 -0
  275. data/lib/relaton/gb/structured_identifier.rb +26 -0
  276. data/lib/relaton/gb/t_scraper.rb +126 -0
  277. data/lib/relaton/gb/util.rb +8 -0
  278. data/lib/relaton/gb/yaml/prefixes.yaml +200 -0
  279. data/lib/relaton/gb.rb +33 -0
  280. data/lib/relaton/gost/bibdata.rb +8 -0
  281. data/lib/relaton/gost/bibitem.rb +8 -0
  282. data/lib/relaton/gost/bibliography.rb +107 -0
  283. data/lib/relaton/gost/docidentifier.rb +80 -0
  284. data/lib/relaton/gost/doctype.rb +16 -0
  285. data/lib/relaton/gost/ext.rb +46 -0
  286. data/lib/relaton/gost/item.rb +15 -0
  287. data/lib/relaton/gost/item_base.rb +18 -0
  288. data/lib/relaton/gost/item_data.rb +6 -0
  289. data/lib/relaton/gost/processor.rb +49 -0
  290. data/lib/relaton/gost/util.rb +8 -0
  291. data/lib/relaton/gost.rb +36 -0
  292. data/lib/relaton/iala/bibdata.rb +8 -0
  293. data/lib/relaton/iala/bibitem.rb +8 -0
  294. data/lib/relaton/iala/bibliography.rb +146 -0
  295. data/lib/relaton/iala/docidentifier.rb +89 -0
  296. data/lib/relaton/iala/doctype.rb +18 -0
  297. data/lib/relaton/iala/ext.rb +32 -0
  298. data/lib/relaton/iala/item.rb +21 -0
  299. data/lib/relaton/iala/item_base.rb +18 -0
  300. data/lib/relaton/iala/item_data.rb +6 -0
  301. data/lib/relaton/iala/processor.rb +43 -0
  302. data/lib/relaton/iala/relation.rb +7 -0
  303. data/lib/relaton/iala/util.rb +8 -0
  304. data/lib/relaton/iala.rb +35 -0
  305. data/lib/relaton/iana/bibdata.rb +8 -0
  306. data/lib/relaton/iana/bibitem.rb +8 -0
  307. data/lib/relaton/iana/bibliography.rb +100 -0
  308. data/lib/relaton/iana/data_fetcher.rb +101 -0
  309. data/lib/relaton/iana/item.rb +7 -0
  310. data/lib/relaton/iana/item_data.rb +6 -0
  311. data/lib/relaton/iana/parser.rb +146 -0
  312. data/lib/relaton/iana/processor.rb +70 -0
  313. data/lib/relaton/iana/util.rb +8 -0
  314. data/lib/relaton/iana.rb +40 -0
  315. data/lib/relaton/iec/bibliography.rb +283 -0
  316. data/lib/relaton/iec/data_fetcher.rb +222 -0
  317. data/lib/relaton/iec/data_parser.rb +391 -0
  318. data/lib/relaton/iec/hit.rb +26 -0
  319. data/lib/relaton/iec/hit_collection.rb +138 -0
  320. data/lib/relaton/iec/item_data.rb +7 -0
  321. data/lib/relaton/iec/model/bibdata.rb +8 -0
  322. data/lib/relaton/iec/model/bibitem.rb +8 -0
  323. data/lib/relaton/iec/model/docidentifier.rb +135 -0
  324. data/lib/relaton/iec/model/doctype.rb +12 -0
  325. data/lib/relaton/iec/model/ext.rb +53 -0
  326. data/lib/relaton/iec/model/item.rb +20 -0
  327. data/lib/relaton/iec/model/item_base.rb +12 -0
  328. data/lib/relaton/iec/model/relation.rb +7 -0
  329. data/lib/relaton/iec/model/stage_name.rb +13 -0
  330. data/lib/relaton/iec/processor.rb +74 -0
  331. data/lib/relaton/iec/statuses.yml +199 -0
  332. data/lib/relaton/iec/util.rb +8 -0
  333. data/lib/relaton/iec.rb +98 -0
  334. data/lib/relaton/ieee/balloting_group.rb +13 -0
  335. data/lib/relaton/ieee/bibdata.rb +8 -0
  336. data/lib/relaton/ieee/bibitem.rb +8 -0
  337. data/lib/relaton/ieee/bibliography.rb +73 -0
  338. data/lib/relaton/ieee/converter/bibxml/from_rfcxml.rb +10 -0
  339. data/lib/relaton/ieee/converter/bibxml/from_rfcxml_referencegroup.rb +10 -0
  340. data/lib/relaton/ieee/converter/bibxml.rb +20 -0
  341. data/lib/relaton/ieee/data_fetcher.rb +771 -0
  342. data/lib/relaton/ieee/doctype.rb +9 -0
  343. data/lib/relaton/ieee/editorial_group.rb +19 -0
  344. data/lib/relaton/ieee/ext.rb +36 -0
  345. data/lib/relaton/ieee/idams_parser.rb +330 -0
  346. data/lib/relaton/ieee/item.rb +11 -0
  347. data/lib/relaton/ieee/item_data.rb +7 -0
  348. data/lib/relaton/ieee/processor.rb +71 -0
  349. data/lib/relaton/ieee/rawbib_id_parser.rb +753 -0
  350. data/lib/relaton/ieee/util.rb +8 -0
  351. data/lib/relaton/ieee.rb +30 -0
  352. data/lib/relaton/ietf/bibdata.rb +8 -0
  353. data/lib/relaton/ietf/bibitem.rb +8 -0
  354. data/lib/relaton/ietf/bibliography.rb +35 -0
  355. data/lib/relaton/ietf/bibxml_parser.rb +232 -0
  356. data/lib/relaton/ietf/data_fetcher.rb +561 -0
  357. data/lib/relaton/ietf/doctype.rb +9 -0
  358. data/lib/relaton/ietf/ext.rb +63 -0
  359. data/lib/relaton/ietf/item.rb +16 -0
  360. data/lib/relaton/ietf/item_base.rb +18 -0
  361. data/lib/relaton/ietf/item_data.rb +6 -0
  362. data/lib/relaton/ietf/processing_instructions.rb +79 -0
  363. data/lib/relaton/ietf/processor.rb +72 -0
  364. data/lib/relaton/ietf/relation.rb +9 -0
  365. data/lib/relaton/ietf/rfc/abstract.rb +19 -0
  366. data/lib/relaton/ietf/rfc/author.rb +21 -0
  367. data/lib/relaton/ietf/rfc/entry.rb +446 -0
  368. data/lib/relaton/ietf/rfc/entry_date.rb +21 -0
  369. data/lib/relaton/ietf/rfc/format.rb +19 -0
  370. data/lib/relaton/ietf/rfc/index.rb +46 -0
  371. data/lib/relaton/ietf/rfc/is_also.rb +21 -0
  372. data/lib/relaton/ietf/rfc/keywords.rb +19 -0
  373. data/lib/relaton/ietf/rfc/rfc_index_namespace.rb +11 -0
  374. data/lib/relaton/ietf/scraper.rb +101 -0
  375. data/lib/relaton/ietf/util.rb +8 -0
  376. data/lib/relaton/ietf/wg_name_resolver.rb +42 -0
  377. data/lib/relaton/ietf.rb +30 -0
  378. data/lib/relaton/iho/bibdata.rb +8 -0
  379. data/lib/relaton/iho/bibitem.rb +8 -0
  380. data/lib/relaton/iho/bibliography.rb +114 -0
  381. data/lib/relaton/iho/comment_period.rb +13 -0
  382. data/lib/relaton/iho/docidentifier.rb +31 -0
  383. data/lib/relaton/iho/doctype.rb +10 -0
  384. data/lib/relaton/iho/ext.rb +20 -0
  385. data/lib/relaton/iho/hash_parser_v1.rb +144 -0
  386. data/lib/relaton/iho/item.rb +20 -0
  387. data/lib/relaton/iho/item_base.rb +18 -0
  388. data/lib/relaton/iho/item_data.rb +6 -0
  389. data/lib/relaton/iho/processor.rb +54 -0
  390. data/lib/relaton/iho/relation.rb +9 -0
  391. data/lib/relaton/iho/structured_identifier.rb +20 -0
  392. data/lib/relaton/iho/util.rb +8 -0
  393. data/lib/relaton/iho.rb +27 -0
  394. data/lib/relaton/index/config.rb +52 -0
  395. data/lib/relaton/index/file_io.rb +305 -0
  396. data/lib/relaton/index/file_storage.rb +66 -0
  397. data/lib/relaton/index/pool.rb +46 -0
  398. data/lib/relaton/index/shard_source.rb +201 -0
  399. data/lib/relaton/index/type.rb +210 -0
  400. data/lib/relaton/index/util.rb +18 -0
  401. data/lib/relaton/index.rb +61 -0
  402. data/lib/relaton/isbn/isbn.rb +61 -0
  403. data/lib/relaton/isbn/open_library.rb +43 -0
  404. data/lib/relaton/isbn/parser.rb +88 -0
  405. data/lib/relaton/isbn/processor.rb +48 -0
  406. data/lib/relaton/isbn/util.rb +8 -0
  407. data/lib/relaton/isbn.rb +19 -0
  408. data/lib/relaton/iso/bibliography.rb +412 -0
  409. data/lib/relaton/iso/data_fetcher.rb +338 -0
  410. data/lib/relaton/iso/data_parser.rb +458 -0
  411. data/lib/relaton/iso/hash_parser_v1.rb +177 -0
  412. data/lib/relaton/iso/hit.rb +57 -0
  413. data/lib/relaton/iso/hit_collection.rb +196 -0
  414. data/lib/relaton/iso/item_data.rb +50 -0
  415. data/lib/relaton/iso/model/bibdata.rb +10 -0
  416. data/lib/relaton/iso/model/bibitem.rb +8 -0
  417. data/lib/relaton/iso/model/contributor.rb +6 -0
  418. data/lib/relaton/iso/model/contributor_info.rb +9 -0
  419. data/lib/relaton/iso/model/docidentifier.rb +146 -0
  420. data/lib/relaton/iso/model/doctype.rb +13 -0
  421. data/lib/relaton/iso/model/ext.rb +35 -0
  422. data/lib/relaton/iso/model/item.rb +17 -0
  423. data/lib/relaton/iso/model/item_base.rb +22 -0
  424. data/lib/relaton/iso/model/organization.rb +9 -0
  425. data/lib/relaton/iso/model/project_number.rb +22 -0
  426. data/lib/relaton/iso/model/relation.rb +9 -0
  427. data/lib/relaton/iso/model/stagename.rb +14 -0
  428. data/lib/relaton/iso/model/structured_identifier.rb +31 -0
  429. data/lib/relaton/iso/processor.rb +85 -0
  430. data/lib/relaton/iso/scraper.rb +635 -0
  431. data/lib/relaton/iso/type/pubid.rb +50 -0
  432. data/lib/relaton/iso/util.rb +8 -0
  433. data/lib/relaton/iso.rb +30 -0
  434. data/lib/relaton/itu/bibliography.rb +95 -0
  435. data/lib/relaton/itu/data_crawler_r.rb +664 -0
  436. data/lib/relaton/itu/data_fetcher.rb +550 -0
  437. data/lib/relaton/itu/data_merge_r.rb +149 -0
  438. data/lib/relaton/itu/data_parser_r.rb +214 -0
  439. data/lib/relaton/itu/data_parser_t.rb +228 -0
  440. data/lib/relaton/itu/family_cache.rb +177 -0
  441. data/lib/relaton/itu/governor.rb +56 -0
  442. data/lib/relaton/itu/hit.rb +28 -0
  443. data/lib/relaton/itu/hit_collection.rb +299 -0
  444. data/lib/relaton/itu/item_data.rb +6 -0
  445. data/lib/relaton/itu/model/approval_stage.rb +13 -0
  446. data/lib/relaton/itu/model/bibdata.rb +8 -0
  447. data/lib/relaton/itu/model/bibitem.rb +8 -0
  448. data/lib/relaton/itu/model/docidentifier.rb +75 -0
  449. data/lib/relaton/itu/model/doctype.rb +13 -0
  450. data/lib/relaton/itu/model/ext.rb +47 -0
  451. data/lib/relaton/itu/model/item.rb +13 -0
  452. data/lib/relaton/itu/model/meeting.rb +13 -0
  453. data/lib/relaton/itu/model/meeting_date.rb +15 -0
  454. data/lib/relaton/itu/model/question.rb +13 -0
  455. data/lib/relaton/itu/model/recommendation_status.rb +11 -0
  456. data/lib/relaton/itu/model/structured_identifier.rb +38 -0
  457. data/lib/relaton/itu/processor.rb +72 -0
  458. data/lib/relaton/itu/pubid.rb +199 -0
  459. data/lib/relaton/itu/radio_regulations_parser.rb +70 -0
  460. data/lib/relaton/itu/recommendation_fields.rb +334 -0
  461. data/lib/relaton/itu/recommendation_parser.rb +30 -0
  462. data/lib/relaton/itu/scraper.rb +203 -0
  463. data/lib/relaton/itu/util.rb +8 -0
  464. data/lib/relaton/itu.rb +34 -0
  465. data/lib/relaton/jcgm/bibdata.rb +8 -0
  466. data/lib/relaton/jcgm/bibitem.rb +8 -0
  467. data/lib/relaton/jcgm/bibliography.rb +97 -0
  468. data/lib/relaton/jcgm/data_fetcher.rb +81 -0
  469. data/lib/relaton/jcgm/docidentifier.rb +102 -0
  470. data/lib/relaton/jcgm/doctype.rb +12 -0
  471. data/lib/relaton/jcgm/ext.rb +23 -0
  472. data/lib/relaton/jcgm/item.rb +20 -0
  473. data/lib/relaton/jcgm/item_base.rb +18 -0
  474. data/lib/relaton/jcgm/item_data.rb +6 -0
  475. data/lib/relaton/jcgm/meetings_parser.rb +175 -0
  476. data/lib/relaton/jcgm/processor.rb +71 -0
  477. data/lib/relaton/jcgm/relation.rb +9 -0
  478. data/lib/relaton/jcgm/structured_identifier.rb +40 -0
  479. data/lib/relaton/jcgm/util.rb +8 -0
  480. data/lib/relaton/jcgm.rb +24 -0
  481. data/lib/relaton/jis/bibdata.rb +8 -0
  482. data/lib/relaton/jis/bibitem.rb +8 -0
  483. data/lib/relaton/jis/bibliography.rb +73 -0
  484. data/lib/relaton/jis/data_fetcher.rb +183 -0
  485. data/lib/relaton/jis/docidentifier.rb +120 -0
  486. data/lib/relaton/jis/doctype.rb +9 -0
  487. data/lib/relaton/jis/ext.rb +13 -0
  488. data/lib/relaton/jis/hit.rb +88 -0
  489. data/lib/relaton/jis/hit_collection.rb +128 -0
  490. data/lib/relaton/jis/item.rb +22 -0
  491. data/lib/relaton/jis/item_base.rb +26 -0
  492. data/lib/relaton/jis/item_data.rb +8 -0
  493. data/lib/relaton/jis/processor.rb +55 -0
  494. data/lib/relaton/jis/relation.rb +11 -0
  495. data/lib/relaton/jis/scraper.rb +232 -0
  496. data/lib/relaton/jis/structured_identifier.rb +13 -0
  497. data/lib/relaton/jis/util.rb +8 -0
  498. data/lib/relaton/jis.rb +32 -0
  499. data/lib/relaton/logger/channels/gh_issue.rb +143 -0
  500. data/lib/relaton/logger/config.rb +34 -0
  501. data/lib/relaton/logger/formatter_json.rb +8 -0
  502. data/lib/relaton/logger/formatter_string.rb +12 -0
  503. data/lib/relaton/logger/log.rb +64 -0
  504. data/lib/relaton/logger/log_device.rb +27 -0
  505. data/lib/relaton/logger/pool.rb +24 -0
  506. data/lib/relaton/logger.rb +18 -0
  507. data/lib/relaton/nist/bibdata.rb +8 -0
  508. data/lib/relaton/nist/bibitem.rb +8 -0
  509. data/lib/relaton/nist/bibliography.rb +191 -0
  510. data/lib/relaton/nist/comment_period.rb +15 -0
  511. data/lib/relaton/nist/data_fetcher.rb +134 -0
  512. data/lib/relaton/nist/date.rb +7 -0
  513. data/lib/relaton/nist/docidentifier.rb +165 -0
  514. data/lib/relaton/nist/doctype.rb +7 -0
  515. data/lib/relaton/nist/ext.rb +16 -0
  516. data/lib/relaton/nist/hit.rb +18 -0
  517. data/lib/relaton/nist/hit_collection.rb +362 -0
  518. data/lib/relaton/nist/item.rb +19 -0
  519. data/lib/relaton/nist/item_base.rb +16 -0
  520. data/lib/relaton/nist/item_data.rb +6 -0
  521. data/lib/relaton/nist/mods_parser.rb +302 -0
  522. data/lib/relaton/nist/processor.rb +69 -0
  523. data/lib/relaton/nist/pubs_export.rb +69 -0
  524. data/lib/relaton/nist/relation.rb +10 -0
  525. data/lib/relaton/nist/scraper.rb +293 -0
  526. data/lib/relaton/nist/series.yaml +49 -0
  527. data/lib/relaton/nist/util.rb +8 -0
  528. data/lib/relaton/nist.rb +34 -0
  529. data/lib/relaton/oasis/bibdata.rb +8 -0
  530. data/lib/relaton/oasis/bibitem.rb +8 -0
  531. data/lib/relaton/oasis/bibliography.rb +201 -0
  532. data/lib/relaton/oasis/browser_agent.rb +71 -0
  533. data/lib/relaton/oasis/data_fetcher.rb +130 -0
  534. data/lib/relaton/oasis/data_parser.rb +305 -0
  535. data/lib/relaton/oasis/data_parser_utils.rb +330 -0
  536. data/lib/relaton/oasis/data_part_parser.rb +239 -0
  537. data/lib/relaton/oasis/docidentifier.rb +54 -0
  538. data/lib/relaton/oasis/doctype.rb +7 -0
  539. data/lib/relaton/oasis/ext.rb +19 -0
  540. data/lib/relaton/oasis/item.rb +14 -0
  541. data/lib/relaton/oasis/item_data.rb +6 -0
  542. data/lib/relaton/oasis/processor.rb +74 -0
  543. data/lib/relaton/oasis/util.rb +8 -0
  544. data/lib/relaton/oasis.rb +41 -0
  545. data/lib/relaton/ogc/bibdata.rb +8 -0
  546. data/lib/relaton/ogc/bibitem.rb +8 -0
  547. data/lib/relaton/ogc/bibliography.rb +64 -0
  548. data/lib/relaton/ogc/data_fetcher.rb +131 -0
  549. data/lib/relaton/ogc/docidentifier.rb +111 -0
  550. data/lib/relaton/ogc/doctype.rb +12 -0
  551. data/lib/relaton/ogc/ext.rb +15 -0
  552. data/lib/relaton/ogc/hit.rb +18 -0
  553. data/lib/relaton/ogc/hit_collection.rb +111 -0
  554. data/lib/relaton/ogc/item.rb +13 -0
  555. data/lib/relaton/ogc/item_data.rb +6 -0
  556. data/lib/relaton/ogc/processor.rb +59 -0
  557. data/lib/relaton/ogc/scraper.rb +225 -0
  558. data/lib/relaton/ogc/util.rb +8 -0
  559. data/lib/relaton/ogc.rb +30 -0
  560. data/lib/relaton/oiml/bibdata.rb +8 -0
  561. data/lib/relaton/oiml/bibitem.rb +8 -0
  562. data/lib/relaton/oiml/bibliography.rb +169 -0
  563. data/lib/relaton/oiml/docidentifier.rb +48 -0
  564. data/lib/relaton/oiml/doctype.rb +13 -0
  565. data/lib/relaton/oiml/ext.rb +42 -0
  566. data/lib/relaton/oiml/item.rb +20 -0
  567. data/lib/relaton/oiml/item_base.rb +18 -0
  568. data/lib/relaton/oiml/item_data.rb +6 -0
  569. data/lib/relaton/oiml/processor.rb +54 -0
  570. data/lib/relaton/oiml/relation.rb +9 -0
  571. data/lib/relaton/oiml/util.rb +8 -0
  572. data/lib/relaton/oiml.rb +24 -0
  573. data/lib/relaton/omg/bibdata.rb +8 -0
  574. data/lib/relaton/omg/bibitem.rb +8 -0
  575. data/lib/relaton/omg/bibliography.rb +31 -0
  576. data/lib/relaton/omg/docidentifier.rb +67 -0
  577. data/lib/relaton/omg/ext.rb +7 -0
  578. data/lib/relaton/omg/item.rb +9 -0
  579. data/lib/relaton/omg/item_data.rb +6 -0
  580. data/lib/relaton/omg/processor.rb +35 -0
  581. data/lib/relaton/omg/scraper.rb +186 -0
  582. data/lib/relaton/omg/util.rb +8 -0
  583. data/lib/relaton/omg.rb +25 -0
  584. data/lib/relaton/plateau/bibdata.rb +8 -0
  585. data/lib/relaton/plateau/bibitem.rb +8 -0
  586. data/lib/relaton/plateau/bibliography.rb +31 -0
  587. data/lib/relaton/plateau/data_fetcher.rb +176 -0
  588. data/lib/relaton/plateau/doctype.rb +7 -0
  589. data/lib/relaton/plateau/ext.rb +23 -0
  590. data/lib/relaton/plateau/handbook_parser.rb +102 -0
  591. data/lib/relaton/plateau/hit.rb +21 -0
  592. data/lib/relaton/plateau/hit_collection.rb +79 -0
  593. data/lib/relaton/plateau/item.rb +12 -0
  594. data/lib/relaton/plateau/item_data.rb +6 -0
  595. data/lib/relaton/plateau/parser.rb +101 -0
  596. data/lib/relaton/plateau/processor.rb +51 -0
  597. data/lib/relaton/plateau/technical_report_parser.rb +98 -0
  598. data/lib/relaton/plateau/util.rb +8 -0
  599. data/lib/relaton/plateau.rb +29 -0
  600. data/lib/relaton/sdo/config.rb +34 -0
  601. data/lib/relaton/sdo/fetcher.rb +52 -0
  602. data/lib/relaton/sdo/logo.rb +95 -0
  603. data/lib/relaton/sdo/name.rb +26 -0
  604. data/lib/relaton/sdo/organization.rb +71 -0
  605. data/lib/relaton/sdo/store.rb +49 -0
  606. data/lib/relaton/sdo.rb +29 -0
  607. data/lib/relaton/un/bibdata.rb +8 -0
  608. data/lib/relaton/un/bibitem.rb +8 -0
  609. data/lib/relaton/un/bibliography.rb +48 -0
  610. data/lib/relaton/un/doctype.rb +10 -0
  611. data/lib/relaton/un/ext.rb +30 -0
  612. data/lib/relaton/un/hit.rb +56 -0
  613. data/lib/relaton/un/hit_collection.rb +61 -0
  614. data/lib/relaton/un/item.rb +11 -0
  615. data/lib/relaton/un/item_data.rb +6 -0
  616. data/lib/relaton/un/parser.rb +108 -0
  617. data/lib/relaton/un/processor.rb +38 -0
  618. data/lib/relaton/un/session.rb +25 -0
  619. data/lib/relaton/un/token_generator.rb +105 -0
  620. data/lib/relaton/un/util.rb +8 -0
  621. data/lib/relaton/un/wasm/decoder.rb +434 -0
  622. data/lib/relaton/un/wasm/instance.rb +101 -0
  623. data/lib/relaton/un/wasm/interpreter.rb +613 -0
  624. data/lib/relaton/un/wasm/memory.rb +112 -0
  625. data/lib/relaton/un/wasm/module.rb +47 -0
  626. data/lib/relaton/un/wasm.rb +17 -0
  627. data/lib/relaton/un/wasm_v_bg.wasm +0 -0
  628. data/lib/relaton/un.rb +28 -0
  629. data/lib/relaton/version.rb +1 -1
  630. data/lib/relaton/w3c/bibdata.rb +8 -0
  631. data/lib/relaton/w3c/bibitem.rb +8 -0
  632. data/lib/relaton/w3c/bibliography.rb +174 -0
  633. data/lib/relaton/w3c/data_fetcher.rb +487 -0
  634. data/lib/relaton/w3c/data_parser.rb +379 -0
  635. data/lib/relaton/w3c/docidentifier.rb +48 -0
  636. data/lib/relaton/w3c/doctype.rb +7 -0
  637. data/lib/relaton/w3c/ext.rb +11 -0
  638. data/lib/relaton/w3c/governor.rb +32 -0
  639. data/lib/relaton/w3c/item.rb +15 -0
  640. data/lib/relaton/w3c/item_data.rb +6 -0
  641. data/lib/relaton/w3c/processor.rb +49 -0
  642. data/lib/relaton/w3c/pubid.rb +85 -0
  643. data/lib/relaton/w3c/safe_realize.rb +148 -0
  644. data/lib/relaton/w3c/util.rb +8 -0
  645. data/lib/relaton/w3c.rb +36 -0
  646. data/lib/relaton/xsf/bibdata.rb +8 -0
  647. data/lib/relaton/xsf/bibitem.rb +8 -0
  648. data/lib/relaton/xsf/bibliography.rb +84 -0
  649. data/lib/relaton/xsf/data_fetcher.rb +106 -0
  650. data/lib/relaton/xsf/docidentifier.rb +46 -0
  651. data/lib/relaton/xsf/hit.rb +17 -0
  652. data/lib/relaton/xsf/hit_collection.rb +52 -0
  653. data/lib/relaton/xsf/item.rb +13 -0
  654. data/lib/relaton/xsf/item_data.rb +6 -0
  655. data/lib/relaton/xsf/processor.rb +51 -0
  656. data/lib/relaton/xsf/util.rb +9 -0
  657. data/lib/relaton/xsf.rb +34 -0
  658. data/lib/relaton-core.rb +1 -0
  659. data/lib/relaton.rb +85 -0
  660. metadata +775 -161
  661. data/.github/workflows/rake.yml +0 -14
  662. data/.github/workflows/release.yml +0 -24
  663. data/.github/workflows/rubocop.yml +0 -48
  664. data/.gitignore +0 -12
  665. data/.rspec +0 -3
  666. data/CLAUDE.md +0 -78
  667. data/Gemfile +0 -29
  668. data/Rakefile +0 -6
  669. data/docs/CHANGELOG.adoc +0 -16
  670. data/docs/VERSIONING_POLICY.adoc +0 -38
  671. data/docs/navigation.adoc +0 -6
  672. data/lib/relaton/db/version.rb +0 -5
  673. data/relaton.gemspec +0 -72
  674. data/spec/relaton/config_spec.rb +0 -10
  675. data/spec/relaton/db_cache_spec.rb +0 -51
  676. data/spec/relaton/db_spec.rb +0 -567
  677. data/spec/relaton/registry_spec.rb +0 -178
  678. data/spec/relaton/util_spec.rb +0 -3
  679. data/spec/relaton_meta_spec.rb +0 -25
  680. data/spec/relaton_spec.rb +0 -800
  681. data/spec/spec_helper.rb +0 -45
  682. data/spec/support/gb_t_20223_2006.xml +0 -33
  683. data/spec/support/iso_111111119115_1.xml +0 -0
  684. data/spec/support/iso_19115_1.xml +0 -115
  685. data/spec/support/iso_19115_2.xml +0 -95
  686. data/spec/support/rfc_8341.xml +0 -46
  687. data/spec/vcr_cassetes/api_relaton_org.yml +0 -121
  688. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +0 -140
  689. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +0 -202
  690. data/spec/vcr_cassetes/cipm_meeting_43.yml +0 -1505
  691. data/spec/vcr_cassetes/gb_t_20223_2006.yml +0 -729
  692. data/spec/vcr_cassetes/iso_111111119115_1.yml +0 -12951
  693. data/spec/vcr_cassetes/iso_19115_1.yml +0 -17334
  694. data/spec/vcr_cassetes/iso_19115_1_2.yml +0 -322
  695. data/spec/vcr_cassetes/iso_19115_1_std.yml +0 -17334
  696. data/spec/vcr_cassetes/iso_19115_all_parts.yml +0 -185
  697. data/spec/vcr_cassetes/iso_19133_2005.yml +0 -144
  698. data/spec/vcr_cassetes/iso_combined_applied.yml +0 -318
  699. data/spec/vcr_cassetes/iso_combined_included.yml +0 -318
  700. data/spec/vcr_cassetes/ogc_19_025r1.yml +0 -374
  701. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +0 -317
  702. data/spec/vcr_cassetes/rfc_8341.yml +0 -1278
@@ -0,0 +1,148 @@
1
+ require "concurrent/map"
2
+ require_relative "governor"
3
+
4
+ module Relaton
5
+ module W3c
6
+ # Thin wrapper over lutaml-hal's `realize`. Successful objects are cached by
7
+ # w3c_api (it caches realized objects keyed by URL), so this only remembers
8
+ # resources that failed terminally and returns nil for them — so one broken
9
+ # link doesn't abort the crawl and isn't re-fetched on every reference.
10
+ #
11
+ # Transient failures are retried upstream first: w3c_api retries 403 (the
12
+ # W3C rate-limit signal) and connection/timeout errors, and lutaml-hal
13
+ # retries 429 and 5xx. By the time an error surfaces here the resource is
14
+ # either genuinely broken (skipped for the rest of the run) or we are still
15
+ # being rate-limited (handed to the Governor).
16
+ #
17
+ # That distinction is the point: a 429 or 403 means "come back later", not
18
+ # "this document does not exist". Recording one as a permanent skip is what
19
+ # silently cost the Aug-2026 relaton-data-w3c crawl 1,412 documents.
20
+ module SafeRealize
21
+ # How many times a rate-limited realize is re-attempted, each behind the
22
+ # governor's shared cooldown, before the resource is written off for this
23
+ # run. Three spans the escalating cooldowns without letting one unlucky
24
+ # href monopolise a worker.
25
+ THROTTLE_ATTEMPTS = 3
26
+
27
+ # Hrefs that failed terminally — one map shared by every includer
28
+ # (DataFetcher and DataParser) since a broken resource is broken for the
29
+ # whole crawl. Initialized eagerly (at load, single-threaded) so the
30
+ # parallel fetcher's first concurrent access can't race a lazy `||=`;
31
+ # Concurrent::Map then handles the concurrent reads/writes.
32
+ @skipped = Concurrent::Map.new
33
+
34
+ # Hrefs lost to rate limiting rather than to a broken resource. Kept apart
35
+ # from @skipped because they measure how incomplete the crawl is, not a
36
+ # property of the resource: DataFetcher refuses to save an index once too
37
+ # many pile up.
38
+ @throttled = Concurrent::Map.new
39
+
40
+ # Shared back-pressure for the whole crawl (see Governor).
41
+ @governor = Governor.new
42
+
43
+ class << self
44
+ attr_reader :skipped, :throttled
45
+ attr_accessor :governor
46
+
47
+ # Start a crawl (or a spec example) from a clean slate. The governor is
48
+ # reset in place, so a reference taken before the reset stays live.
49
+ def reset!
50
+ @skipped.clear
51
+ @throttled.clear
52
+ @governor.reset!
53
+ end
54
+ end
55
+
56
+ # @param parent_resource [Object, nil] the index/page the link came from.
57
+ # When the page was fetched with `embed: true`, its inlined `_embedded`
58
+ # payload lets the link realize from memory instead of issuing an HTTP
59
+ # request. nil (the default) preserves the plain remote-fetch behavior.
60
+ def realize(obj, parent_resource: nil)
61
+ # Once the governor has latched its give-up the run is already lost
62
+ # (DataFetcher#guard_rate_limited raises and nothing is saved) and the
63
+ # host has just banned us, so every further request only extends the
64
+ # ban into the next run. #wait alone stops WAITING, not asking: the
65
+ # 2026-08-31 crawl spent its last 11 minutes firing at a banned host
66
+ # because the per-spec fan-out had no back-pressure of its own.
67
+ #
68
+ # This is the one choke point every request in the crawl passes
69
+ # through, so one check covers DataFetcher#fetch_versions and all
70
+ # seven of DataParser's realize sites. They already tolerate nil —
71
+ # that is the SafeRealize contract.
72
+ return nil if SafeRealize.governor.exhausted?
73
+
74
+ href = resolve_href(obj)
75
+ return nil if SafeRealize.skipped.key?(href)
76
+
77
+ attempt = 0
78
+ begin
79
+ attempt += 1
80
+ SafeRealize.governor.wait
81
+ realized = obj.realize(parent_resource: parent_resource)
82
+ # Only a realize that actually went to the network says anything about
83
+ # the limiter. With a parent_resource, lutaml-hal serves the object
84
+ # straight out of the page's `_embedded` payload and never issues a
85
+ # request (link.rb: "Priority 1: check embedded content first") — and
86
+ # that is the common case, one per specification. Reporting those as
87
+ # successes would clear the cooldown and reset the escalation ladder
88
+ # between every pair of version-history 429s, so the governor could
89
+ # never reach its give-up threshold: exactly the 60s re-trip loop this
90
+ # class exists to break.
91
+ SafeRealize.governor.succeeded! unless parent_resource
92
+ # The document made it into the dataset after all, so it must stop
93
+ # counting against the crawl's throttle budget.
94
+ SafeRealize.throttled.delete(href)
95
+ realized
96
+ rescue *Governor::THROTTLE_ERRORS => e
97
+ retry if record_throttle(href, e, attempt)
98
+ nil
99
+ rescue Lutaml::Hal::ConnectionError, Lutaml::Hal::TimeoutError, Faraday::Error, Net::OpenTimeout => e
100
+ # Network-level failure (already retried by w3c_api). The resource itself
101
+ # is fine, so don't skip it permanently — a later reference can try again.
102
+ Util.warn "Failed to realize object: #{href}, error: #{e.message}"
103
+ nil
104
+ rescue Lutaml::Hal::NotFoundError
105
+ Util.warn "Object not found: #{href}"
106
+ SafeRealize.skipped[href] = true
107
+ nil
108
+ rescue Lutaml::Hal::Error => e
109
+ # Definitive upstream error (5xx, 400/401, …) already retried by
110
+ # w3c_api / lutaml-hal. Skip the broken/unavailable resource rather than
111
+ # re-hitting it for every link that references it. 5xx stays here
112
+ # deliberately: the handful of persistent per-resource 500s a healthy
113
+ # crawl sees are broken records, not throttling, and routing them
114
+ # through the governor would open a pool-wide cooldown for each one.
115
+ Util.warn "Skipping #{href}, upstream error after retries: #{e.message}"
116
+ SafeRealize.skipped[href] = true
117
+ nil
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ #
124
+ # Record a rate-limited attempt and decide whether to try again.
125
+ #
126
+ # @return [Boolean] true to retry — the caller re-enters #realize's begin
127
+ # block, whose #wait sits out the shared cooldown first
128
+ #
129
+ def record_throttle(href, error, attempt)
130
+ gave_up = SafeRealize.governor.throttled!(
131
+ retry_after: Governor.retry_after(error),
132
+ )
133
+ # Once the governor has declared the crawl rate-limited there is nothing
134
+ # to gain from more attempts — the run is about to abort anyway.
135
+ return true if !gave_up && attempt < THROTTLE_ATTEMPTS
136
+
137
+ Util.warn "Throttled out: #{href}, still rate-limited after " \
138
+ "#{attempt} attempt(s): #{error.message}"
139
+ SafeRealize.throttled[href] = true
140
+ false
141
+ end
142
+
143
+ def resolve_href(obj)
144
+ obj.href || obj.links.self.href
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module W3c
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-w3c".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,36 @@
1
+ require "pubid"
2
+ require "pubid/w3c"
3
+ require "relaton/bib"
4
+ require "relaton/index"
5
+ require_relative "version"
6
+ require_relative "w3c/util"
7
+ require_relative "w3c/item"
8
+ require_relative "w3c/bibitem"
9
+ require_relative "w3c/bibdata"
10
+ require_relative "w3c/bibliography"
11
+ # Not used by this gem any more; loaded so relaton-data-w3c's crawler can
12
+ # require "relaton/w3c" and still reach the legacy index-v1 row shape.
13
+ require_relative "w3c/pubid"
14
+
15
+ module Relaton
16
+ module W3c
17
+ # The runtime index is the pubid-backed `index-v2`, whose rows are
18
+ # `Pubid::W3c::Identifier` leaves serialized as `_type: pubid:w3c:*`, built
19
+ # and read via `pubid_class: ::Pubid::W3c::Identifier`. The bespoke
20
+ # `index-v1` is relaton-v2 legacy and is no longer produced here —
21
+ # `relaton-data-w3c`'s crawler emits it from the retained public
22
+ # `Relaton::W3c::PubId`.
23
+ INDEXFILE = "index-v2".freeze
24
+
25
+ class Error < StandardError; end
26
+
27
+ # Returns hash of XML reammar
28
+ # @return [String]
29
+ def self.grammar_hash
30
+ # gem_path = File.expand_path "..", __dir__
31
+ # grammars_path = File.join gem_path, "grammars", "*"
32
+ # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
33
+ Digest::MD5.hexdigest Relaton::VERSION # grammars
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Xsf
3
+ class Bibdata < Item
4
+ model ItemData
5
+ include Bib::BibdataShared
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Xsf
3
+ class Bibitem < Item
4
+ model ItemData
5
+ include Bib::BibitemShared
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,84 @@
1
+ module Relaton
2
+ module Xsf
3
+ module Bibliography
4
+ extend self
5
+
6
+ #
7
+ # Search the index for a reference.
8
+ #
9
+ # The reference is parsed into a `Pubid::Xsf::Identifier` here and the
10
+ # identifier -- never the string -- is what reaches `HitCollection`.
11
+ # `Index::Type#search_candidates` narrows only when its argument is not a
12
+ # `String`, so parsing at the entry point is what lets the lookup binary
13
+ # search; `Core::HitCollection` takes a `String` or a pubid by design.
14
+ #
15
+ # An unrecognized reference **raises**; like ISO, ETSI and 3GPP we let it
16
+ # propagate. relaton-cli rescues `Pubid::Errors::Error` and renders
17
+ # `"..." is not a recognized standards identifier`
18
+ # (`gems/relaton-cli/lib/relaton/cli/command.rb:324`,
19
+ # `subcommand_collection.rb:134`), and `Db#fetch` logs it via the
20
+ # `StandardError` arm at `lib/relaton/db.rb:122`. Rescuing here would
21
+ # collapse "this identifier is malformed" into "no such document", and a
22
+ # caller could no longer tell them apart.
23
+ #
24
+ # There is also deliberately no substring fallback: the old
25
+ # `index.search(ref)` compared a substring of the rendered id, so a bare
26
+ # `001` answered with 11 documents and `#get` took `.first` -- a truncated
27
+ # reference silently resolved to whichever sorted first.
28
+ #
29
+ # @param ref [String] e.g. "XEP 0001", "XEP-0001", "0001"
30
+ #
31
+ # @return [Relaton::Xsf::HitCollection]
32
+ # @raise [Pubid::Errors::ParseError] if the reference is not an XEP id
33
+ #
34
+ def search(ref)
35
+ HitCollection.new(parse_ref(ref)).search
36
+ end
37
+
38
+ def get(code, _year = nil, _opts = {})
39
+ Util.info "Fetching from Relaton repository ...", key: code
40
+ result = search(code)
41
+ if result.empty?
42
+ Util.info "Not found.", key: code
43
+ return
44
+ end
45
+
46
+ bib = result.first.item
47
+ Util.info "Found: `#{bib.docidentifier.first.content}`", key: code
48
+ bib
49
+ end
50
+
51
+ #
52
+ # Parse a user reference into a `Pubid::Xsf::Identifier`, or nil.
53
+ #
54
+ # `Pubid::Xsf` accepts only the canonical `XEP 0001` spelling, so two
55
+ # forms are normalized first:
56
+ #
57
+ # - **`XEP-0001`**, the spelling xmpp.org itself uses everywhere. It did
58
+ # not resolve before either (the substring match compared against
59
+ # `XEP 0001`, which has a space), so this is new support rather than a
60
+ # preserved behaviour.
61
+ # - **A bare `0001`**, which the substring match did resolve, so it has to
62
+ # keep working. The publisher token is added, the W3C idiom.
63
+ #
64
+ # The token match is case-insensitive, so `xep 0001` resolves too.
65
+ #
66
+ # Anything else raises -- see `.search`. `Pubid::Errors::ParseError`
67
+ # includes `Pubid::Errors::Error`, which is the class relaton-cli rescues.
68
+ #
69
+ # @param ref [String]
70
+ # @return [Pubid::Xsf::Identifier]
71
+ # @raise [Pubid::Errors::ParseError]
72
+ #
73
+ def parse_ref(ref)
74
+ ::Pubid::Xsf::Identifier.parse normalize_ref(ref)
75
+ end
76
+
77
+ private
78
+
79
+ def normalize_ref(ref)
80
+ "XEP #{ref.to_s.strip.sub(/\AXEP[-\s]+/i, '')}"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,106 @@
1
+ require "relaton/core"
2
+
3
+ module Relaton
4
+ module Xsf
5
+ class DataFetcher < Relaton::Core::DataFetcher
6
+ # `Core::DataFetcher#log_error` raises unless the flavor overrides it, so
7
+ # `report_errors` is unusable without this. (The ECMA precedent.)
8
+ def log_error(msg)
9
+ Util.error msg
10
+ end
11
+
12
+ def index
13
+ # `pubid_class:` on the producer too: FileIO#save only calls `to_hash`
14
+ # when the value is an instance of it, so without it the crawl writes
15
+ # v1-shaped rows under a v2 name, silently.
16
+ @index ||= Relaton::Index.find_or_create(
17
+ :xsf, file: "#{INDEXFILE}.yaml", pubid_class: ::Pubid::Xsf::Identifier
18
+ )
19
+ end
20
+
21
+ def fetch(_source = nil)
22
+ agent = Mechanize.new
23
+ resp = agent.get "https://xmpp.org/extensions/refs/"
24
+ resp.xpath("//a[contains(@href, 'XEP-')]").each do |link|
25
+ doc = agent.get link[:href]
26
+ bib = Relaton::Bib::Converter::BibXml.to_item doc.body
27
+ save_doc bib
28
+ rescue StandardError => e
29
+ Util.warn "Failed to parse #{link[:href]}: #{e.message}"
30
+ end
31
+ index.save
32
+ report_errors
33
+ end
34
+
35
+ def save_doc(bib)
36
+ return unless bib
37
+
38
+ bib.ext ||= Relaton::Bib::Ext.new
39
+ bib.ext.flavor = "xsf"
40
+
41
+ docid = bib.docidentifier.detect(&:primary) || bib.docidentifier.first
42
+ id = docid&.content
43
+ return unless id
44
+
45
+ # Distinct docids can sanitize to one filename; take a path of our own
46
+ # rather than overwriting the other document (Core#unique_output_file).
47
+ file = unique_output_file id
48
+ if @files.include? file
49
+ # Same reserved path == same id: a genuine duplicate. Checked FIRST,
50
+ # because a disambiguated path stays != output_file forever.
51
+ Util.warn "File #{file} already exists"
52
+ elsif file != output_file(id)
53
+ Util.warn "File #{output_file id} already exists; writing #{file} instead"
54
+ end
55
+ @files << file
56
+ File.write file, serialize(bib), encoding: "UTF-8"
57
+ add_to_index id, file
58
+ end
59
+
60
+ #
61
+ # Index a document under its pubid, skipping one pubid cannot parse.
62
+ #
63
+ # This guard is not optional here. One unparseable row does not fail that
64
+ # row: `Relaton::Index` declares the **whole file** corrupt, deletes it,
65
+ # and hands back an **empty** index. Measured — 519 good rows plus one
66
+ # unparseable id loads as 0 rows, and the only trace is two INFO lines
67
+ # ("Wrong structure of file …", "Considering … corrupt, removing it"). So
68
+ # indexing one bad row silently breaks every XSF lookup, not just its own.
69
+ #
70
+ # A rejection is recorded in `@errors`, which `report_errors` turns into a
71
+ # GitHub issue at the end of the crawl (the 3GPP/ECMA precedent). Nothing
72
+ # in the published corpus trips it today: pubid parses all 520 rows,
73
+ # including the two entries that are pages rather than XEPs — the XEP
74
+ # repository's `README` and its `xep-xxxx` template, which pubid accepts
75
+ # as the literal numbers `README` and `xxxx` while still rejecting
76
+ # anything else non-numeric (`XEP banana`, or a typo like `XEP 00O1`).
77
+ # So a recorded error now means something genuinely new appeared, which
78
+ # is exactly when an issue is worth filing.
79
+ #
80
+ # The data file is written either way, so a document that cannot be
81
+ # indexed is unindexed, never lost.
82
+ #
83
+ # @param docid [String]
84
+ # @param file [String]
85
+ #
86
+ def add_to_index(docid, file)
87
+ index.add_or_update ::Pubid::Xsf::Identifier.parse(docid), file
88
+ rescue StandardError => e
89
+ @errors[docid] =
90
+ "Unparseable primary id `#{docid}` was not indexed (#{e.message})"
91
+ end
92
+
93
+ def to_yaml(bib)
94
+ bib.to_yaml
95
+ end
96
+
97
+ def to_xml(bib)
98
+ bib.to_xml bibdata: true
99
+ end
100
+
101
+ def to_bibxml(bib)
102
+ bib.to_rfcxml
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,46 @@
1
+ module Relaton
2
+ module Xsf
3
+ # An XSF document identifier, backed by `Pubid::Xsf`.
4
+ #
5
+ # Parses its `content` into a `Pubid::Xsf::Identifier` kept in `@pubid`,
6
+ # while the lutaml `content` attribute stays a plain **string** for
7
+ # serialization. Parsing is **soft**: `content=` lazily requires pubid and
8
+ # rescues `LoadError`/`StandardError`, so a missing gem or non-XSF content
9
+ # leaves `@pubid` nil rather than raising during deserialization.
10
+ #
11
+ # **It deliberately implements none of `remove_part!` / `remove_date!` /
12
+ # `to_all_parts!`.** An XEP identifier is a publisher and a number and
13
+ # nothing else — no part, no edition, no date — so there is genuinely
14
+ # nothing for any of them to strip, and `Bib::Docidentifier` already
15
+ # defaults all three to no-ops for exactly that case. Empty overrides here
16
+ # would assert a flavor-specific rule that does not exist. Compare
17
+ # `Relaton::Ogc::Docidentifier`, which overrides `remove_date!` because OGC
18
+ # really does carry a revision.
19
+ #
20
+ # So this class exists for `#pubid`: it gives consumers the structured
21
+ # identifier off a docidentifier, the way every other pubid-backed flavor
22
+ # does, without changing what is serialized.
23
+ class Docidentifier < Bib::Docidentifier
24
+ attr_reader :pubid
25
+
26
+ def initialize(attrs = {}, options = {})
27
+ pubid = attrs.is_a?(Hash) ? attrs.delete(:pubid) : nil
28
+ attrs[:content] ||= pubid.to_s if pubid
29
+ super
30
+ @pubid = pubid if pubid
31
+ end
32
+
33
+ def content=(value)
34
+ super
35
+ return unless value
36
+
37
+ @pubid = begin
38
+ require "pubid"
39
+ ::Pubid::Xsf::Identifier.parse(value)
40
+ rescue LoadError, StandardError
41
+ nil
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ module Relaton
2
+ module Xsf
3
+ class Hit < Relaton::Core::Hit
4
+ def item
5
+ return @doc if @doc
6
+
7
+ agent = Mechanize.new
8
+ resp = agent.get hit[:url]
9
+ hash = YAML.safe_load resp.body
10
+ hash["fetched"] = Date.today.to_s
11
+ @doc = Relaton::Xsf::Item.from_yaml hash.to_yaml
12
+ rescue StandardError => e
13
+ raise Relaton::RequestError, e.message
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+ module Relaton
2
+ module Xsf
3
+ class HitCollection < Relaton::Core::HitCollection
4
+ GHDATA_URL = "https://raw.githubusercontent.com/relaton/relaton-data-xsf/v2/".freeze
5
+
6
+ #
7
+ # Find the index rows for the identifier this collection was built with.
8
+ #
9
+ # `ref` is a `Pubid::Xsf::Identifier` -- `Bibliography.parse_ref` does that
10
+ # step, and raises rather than returning nil for an unrecognized
11
+ # reference. Passing the identifier rather than a string is what enables
12
+ # the binary search on `id.root.number`. The nil guard in `#rows` is
13
+ # defensive only: `Core::HitCollection` permits a nil `ref`, and an empty
14
+ # result beats a NoMethodError if some other caller constructs one.
15
+ #
16
+ # An XEP identifier is only a publisher and a number: no edition, no date,
17
+ # no part. So the reference states everything, and `Type#search`'s default
18
+ # subset match (`Pubid::SubsetMatch`) is a plain equality -- which is the
19
+ # point. Ids are unique, one row per XEP, so there is no selection order
20
+ # to apply either.
21
+ #
22
+ # @return [self]
23
+ #
24
+ def search
25
+ @array = rows.map { |row| Hit.new url: "#{GHDATA_URL}#{row[:file]}" }
26
+ self
27
+ rescue Relaton::RequestError
28
+ raise
29
+ rescue StandardError => e
30
+ raise Relaton::RequestError, e.message
31
+ end
32
+
33
+ def index
34
+ @index ||= Relaton::Index.find_or_create(
35
+ :xsf,
36
+ url: "#{GHDATA_URL}#{INDEXFILE}.zip",
37
+ file: "#{INDEXFILE}.yaml",
38
+ pubid_class: ::Pubid::Xsf::Identifier,
39
+ )
40
+ end
41
+
42
+ private
43
+
44
+ def rows
45
+ return [] unless ref
46
+
47
+ index.search(ref)
48
+ .sort_by { |row| row[:id].to_s }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ require_relative "docidentifier"
2
+
3
+ module Relaton
4
+ module Xsf
5
+ class Item < Bib::Item
6
+ model ItemData
7
+
8
+ # Narrow the inherited `docidentifier` to the flavor's own class, so a
9
+ # deserialized item exposes `#pubid` on each id. (The OGC/ECMA shape.)
10
+ attribute :docidentifier, Docidentifier, collection: true, initialize_empty: true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Relaton
2
+ module Xsf
3
+ class ItemData < Bib::ItemData
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ require "relaton/core/processor"
3
+
4
+ module Relaton
5
+ module Xsf
6
+ class Processor < Relaton::Core::Processor
7
+ attr_reader :idtype
8
+
9
+ def initialize # rubocop:disable Lint/MissingSuper
10
+ @short = :relaton_xsf
11
+ @prefix = "XEP"
12
+ @defaultprefix = %r{^XEP\s}
13
+ @idtype = "XEP"
14
+ @datasets = %w[xep-xmpp]
15
+ @pubid_flavor = :Xsf
16
+ end
17
+
18
+ def get(code, date, opts)
19
+ require_relative "../xsf"
20
+ Relaton::Xsf::Bibliography.get(code, date, opts)
21
+ end
22
+
23
+ def fetch_data(_source, opts)
24
+ require_relative "data_fetcher"
25
+ Relaton::Xsf::DataFetcher.fetch(**opts)
26
+ end
27
+
28
+ def from_xml(xml)
29
+ require_relative "../xsf"
30
+ Relaton::Xsf::Item.from_xml(xml)
31
+ end
32
+
33
+ def from_yaml(yaml)
34
+ require_relative "../xsf"
35
+ Relaton::Xsf::Item.from_yaml(yaml)
36
+ end
37
+
38
+ def grammar_hash
39
+ require_relative "../xsf"
40
+ Relaton::Xsf.grammar_hash
41
+ end
42
+
43
+ def remove_index_file
44
+ require_relative "../xsf"
45
+ Relaton::Index.find_or_create(
46
+ :xsf, url: true, file: "#{INDEXFILE}.yaml"
47
+ ).remove_file
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ module Relaton
2
+ module Xsf
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+
6
+ PROGNAME = "relaton-xsf".freeze
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mechanize"
4
+ # pubid loads with the flavor, for the ::Pubid::Xsf::Identifier that the
5
+ # index code names. Processor#remove_index_file names no pubid class: the
6
+ # delete never reads the index (see lib/relaton/index/CLAUDE.md).
7
+ require "pubid"
8
+ require "relaton/index"
9
+ require "relaton/bib"
10
+ require_relative "version"
11
+ require_relative "xsf/util"
12
+ require_relative "xsf/item_data"
13
+ require_relative "xsf/item"
14
+ require_relative "xsf/bibitem"
15
+ require_relative "xsf/bibdata"
16
+ require_relative "xsf/hit"
17
+ require_relative "xsf/hit_collection"
18
+ require_relative "xsf/bibliography"
19
+
20
+ module Relaton
21
+ module Xsf
22
+ INDEXFILE = "index-v2".freeze
23
+
24
+ class Error < StandardError; end
25
+
26
+ # Your code goes here...
27
+ def self.grammar_hash
28
+ # gem_path = File.expand_path "..", __dir__
29
+ # grammars_path = File.join gem_path, "grammars", "*"
30
+ # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
31
+ Digest::MD5.hexdigest Relaton::VERSION # grammars
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ require_relative "relaton/core"