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,134 @@
1
+ module Relaton
2
+ module Ecma
3
+ class StandardParser
4
+ include ParserCommon
5
+
6
+ ATTRS = %i[docidentifier title date source abstract relation edition ext].freeze
7
+
8
+ # @param [Nokogiri::XML::Element] hit document hit
9
+ # @param [Mechanize::Page] doc fetched document page
10
+ # @param [Hash] errors error tracking hash
11
+ def initialize(hit:, doc:, errors: {})
12
+ @hit = hit
13
+ @doc = doc
14
+ @errors = errors
15
+ end
16
+
17
+ # @return [Hash] bibliographic item attributes
18
+ def to_bib_hash
19
+ bib = default_bib_hash
20
+ ATTRS.each { |a| bib[a] = send "fetch_#{a}" }
21
+ bib
22
+ end
23
+
24
+ # @return [Array] precomputed translation sources
25
+ def translation_source
26
+ @translation_source ||= parse_translation_source
27
+ end
28
+
29
+ # @return [Array<Relaton::Ecma::Docidentifier>]
30
+ def fetch_docidentifier
31
+ result = super(@hit.text)
32
+ @errors[:standard_docidentifier] &&= result.empty?
33
+ result
34
+ end
35
+
36
+ # @return [Array<Relaton::Bib::Title>]
37
+ def fetch_title
38
+ result = @doc.xpath('//p[@class="ecma-item-short-description"]').map do |t|
39
+ Bib::Title.new(content: t.text.strip, language: "en", script: "Latn")
40
+ end
41
+ @errors[:standard_title] &&= result.empty?
42
+ result
43
+ end
44
+
45
+ # @return [Array<Relaton::Bib::LocalizedMarkedUpString>]
46
+ def fetch_abstract
47
+ content = @doc.xpath('//div[@class="ecma-item-content"]/p').map do |a|
48
+ a.text.strip.squeeze(" ").gsub("\r\n", "")
49
+ end.join "\n"
50
+ return [] if content.empty?
51
+
52
+ result = [Bib::Abstract.new(content: content, language: "en", script: "Latn")]
53
+ @errors[:standard_abstract] &&= result.empty?
54
+ result
55
+ end
56
+
57
+ # @return [Array<Relaton::Bib::Date>]
58
+ def fetch_date
59
+ result = @doc.xpath('//p[@class="ecma-item-edition"]').map do |d|
60
+ date = d.text.split(", ").last
61
+ Bib::Date.new type: "published", at: date
62
+ end
63
+ @errors[:standard_date] &&= result.empty?
64
+ result
65
+ end
66
+
67
+ # @return [Array<Relaton::Bib::Uri>]
68
+ def fetch_source # rubocop:disable Metrics/AbcSize
69
+ source = []
70
+ source << Bib::Uri.new(type: "src", content: @hit[:href]) if @hit[:href]
71
+ ref = @doc.at('//div[@class="ecma-item-content-wrapper"]/span/a',
72
+ '//div[@class="ecma-item-content-wrapper"]/a')
73
+ source << Bib::Uri.new(type: "pdf", content: ref[:href]) if ref
74
+ result = source + edition_translation_source(fetch_edition_content)
75
+ @errors[:standard_source] &&= result.empty?
76
+ result
77
+ end
78
+
79
+ # @return [Array<Relaton::Bib::Relation>]
80
+ def fetch_relation # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
81
+ edition_parser = EditionParser.new(doc: @doc, bib: {}, errors: @errors)
82
+ result = @doc.xpath("//ul[@class='ecma-item-archives']/li").filter_map do |rel|
83
+ ref, ed, date, vol = edition_parser.edition_id_parts rel.at("span").text
84
+ next if ed.nil? || ed.empty?
85
+
86
+ docid = Docidentifier.new(type: "ECMA", content: ref, primary: true)
87
+ source = rel.xpath("span/a").map { |l| Bib::Uri.new type: "pdf", content: l[:href] }
88
+ edition = Bib::Edition.new content: ed
89
+ extent = edition_parser.create_extent(vol)
90
+ @errors[:standard_relation_extent] &&= extent.nil?
91
+ bibitem = ItemData.new(
92
+ docidentifier: [docid], formattedref: Bib::Formattedref.new(content: ref), date: date, edition: edition,
93
+ source: source, extent: extent
94
+ )
95
+ Bib::Relation.new(type: "updates", bibitem: bibitem)
96
+ end
97
+ @errors[:standard_relation] &&= result.empty?
98
+ result
99
+ end
100
+
101
+ # @return [Relaton::Bib::Edition, nil]
102
+ def fetch_edition
103
+ cnt = fetch_edition_content
104
+ result = Bib::Edition.new(content: cnt) if cnt && !cnt.empty?
105
+ @errors[:standard_edition] &&= result.nil?
106
+ result
107
+ end
108
+
109
+ private
110
+
111
+ def fetch_edition_content
112
+ @doc.at('//p[@class="ecma-item-edition"]')&.text&.match(/^\d+(?=(?:st|nd|th|rd))/)&.to_s
113
+ end
114
+
115
+ def edition_translation_source(edition)
116
+ translation_source.select { |s| s[:ed] == edition }.map { |s| s[:source] }
117
+ end
118
+
119
+ def parse_translation_source
120
+ return [] unless @doc
121
+
122
+ @doc.xpath("//h2[.='Translations']/following-sibling::ul/li").map do |l|
123
+ a = l.at("span/a")
124
+ id = l.at("span").text
125
+ %r{\w+[\d-]+,\s(?<lang>\w+)\sversion,\s(?<ed>[\d.]+)(?:st|nd|rd|th)\sedition} =~ id
126
+ case lang
127
+ when "Japanese"
128
+ { ed: ed, source: Bib::Uri.new(type: "pdf", language: "ja", script: "Jpan", content: a[:href]) }
129
+ end
130
+ end.compact
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,8 @@
1
+ module Relaton
2
+ module Ecma
3
+ module Util
4
+ extend Relaton::Bib::Util
5
+ PROGNAME = "relaton-ecma".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ # Not lazy: DataFetcher names ::Pubid::Ecma::Identifier as the index
2
+ # `pubid_class:`, and Docidentifier parses every docid through it.
3
+ # (The IANA/IHO/IALA/OGC form; spec/relaton/lazy_loading_spec.rb guards that
4
+ # this file is not itself loaded when a Db is built.)
5
+ require "pubid"
6
+ require "relaton/index"
7
+ require "relaton/bib"
8
+ require_relative "version"
9
+ require_relative "ecma/util"
10
+ require_relative "ecma/item_data"
11
+ require_relative "ecma/item"
12
+ require_relative "ecma/bibitem"
13
+ require_relative "ecma/bibdata"
14
+ require_relative "ecma/bibliography"
15
+
16
+ module Relaton
17
+ module Ecma
18
+ # The one index this flavor builds and reads: pubid-keyed rows
19
+ # (`_type: pubid:ecma:*`), via `pubid_class: ::Pubid::Ecma::Identifier`.
20
+ # `relaton-data-ecma`'s crawler derives the legacy `index-v1` from these
21
+ # rows for released consumers, so it is not produced or read here.
22
+ INDEXFILE = "index-v2".freeze
23
+
24
+ # Returns hash of XML reammar
25
+ # @return [String]
26
+ def self.grammar_hash
27
+ # gem_path = File.expand_path "..", __dir__
28
+ # grammars_path = File.join gem_path, "grammars", "*"
29
+ # grammars = Dir[grammars_path].sort.map { |gp| File.read gp }.join
30
+ Digest::MD5.hexdigest Relaton::VERSION # grammars
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "item"
2
+
3
+ module Relaton
4
+ module Etsi
5
+ class Bibdata < Item
6
+ model ItemData
7
+ include Bib::BibdataShared
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "item"
2
+
3
+ module Relaton
4
+ module Etsi
5
+ class Bibitem < Item
6
+ model ItemData
7
+ include Bib::BibitemShared
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Etsi
5
+ # Methods for search IANA standards.
6
+ module Bibliography
7
+ SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-etsi/refs/heads/v2/"
8
+
9
+ # @param text [String]
10
+ # @return [Relaton::Etsi::ItemData, nil]
11
+ def search(text) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
12
+ # An unrecognized reference raises Pubid::Errors::ParseError; like
13
+ # ISO we let it propagate — the CLI turns it into a friendly message
14
+ # and API callers rescue it themselves. Valid partial refs parse with
15
+ # the omitted refinements (version/date/part) left blank.
16
+ pubid = ::Pubid::Etsi.parse text
17
+
18
+ index = Relaton::Index.find_or_create :etsi, url: "#{SOURCE}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml",
19
+ pubid_class: ::Pubid::Etsi::Identifier
20
+ row = best_match(index, pubid)
21
+ return unless row
22
+
23
+ url = "#{SOURCE}#{row[:file]}"
24
+ resp = Net::HTTP.get_response URI(url)
25
+ return unless resp.code == "200"
26
+
27
+ Item.from_yaml(resp.body).tap { |item| item.fetched = Date.today.to_s }
28
+ rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
29
+ EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
30
+ Net::ProtocolError, Errno::ETIMEDOUT => e
31
+ raise Relaton::RequestError, e.message
32
+ end
33
+
34
+ # Match the reference against the index and return the most recent edition.
35
+ #
36
+ # The rows are selected with pubid's subset match `pubid === row`. A
37
+ # version or a date that the reference omits matches any value, so a
38
+ # bare `ETSI GS ZSM 012` matches every edition, while a fully-qualified
39
+ # ref matches only that edition. The class must be identical, so a base
40
+ # reference such as `ETSI ETR 310` does not reach its amendment or
41
+ # corrigendum (`ETR 310/C1`).
42
+ # The pubid — not a String — is passed to `index.search` so the index
43
+ # narrows candidates by number via binary search; each row's `:id` is
44
+ # already a Pubid::Etsi identifier (deserialized via `pubid_class`).
45
+ # `max_by` on `edition_key` picks the latest edition among the matches.
46
+ #
47
+ # pubid declares `parts` strict for ETSI, so a part-less reference asks
48
+ # for every part by matching each row **without its parts** (see
49
+ # #comparable). `#to_all_parts` cannot serve here: a
50
+ # `Pubid::AllPartsIdentifier` compares the document alone, so it also
51
+ # drops the version and the date, and
52
+ # `ETSI GR ZSM 011 V1.1.1 (2023-02)` would answer with V2.1.1.
53
+ #
54
+ # @param index [Relaton::Index::Type]
55
+ # @param pubid [::Pubid::Etsi::Identifier]
56
+ # @return [Hash, nil] the winning index row (`{ id:, file: }`)
57
+ def best_match(index, pubid)
58
+ all_parts = pubid.code&.parts.to_a.empty?
59
+ index.search(pubid) { |row| pubid === comparable(row[:id], all_parts) }
60
+ .max_by { |row| edition_key(row[:id]) }
61
+ end
62
+
63
+ # The row as the reference sees it: without its parts when the reference
64
+ # names none, unchanged otherwise. `#exclude` returns a copy, so the
65
+ # cached index id is untouched.
66
+ #
67
+ # @param id [::Pubid::Etsi::Identifier]
68
+ # @param all_parts [Boolean] the reference names no part
69
+ # @return [::Pubid::Etsi::Identifier]
70
+ def comparable(id, all_parts)
71
+ all_parts ? id.exclude(:part, :subpart, :parts) : id
72
+ end
73
+
74
+ # Sort key for one edition: the version numbers, then the publication date.
75
+ #
76
+ # ETSI versions are not zero-padded, so a comparison of the rendered id
77
+ # orders `V9.0.0` above `V19.0.0` and `ed.9` above `ed.11`, and a bare
78
+ # reference then resolves to an old edition. `Pubid::Etsi::Identifier` is
79
+ # not `Comparable` and its `<=>` returns nil, so the key comes from the
80
+ # parsed components: `version.version` holds the bare numbers (`"19.0.0"`,
81
+ # or `"9"` for the `ed.9` form) and `date` renders as `yyyy-mm`. Both
82
+ # delegate to `base` on a corrigendum/amendment id, so every row shape
83
+ # keys the same way. A missing version or date gives `[]` / `""`, which
84
+ # sort below any real value — hence the `.to_s` outside each `&.` chain.
85
+ #
86
+ # @param id [::Pubid::Etsi::Identifier]
87
+ # @return [Array(Array<Integer>, String)]
88
+ def edition_key(id)
89
+ [(id.version&.version).to_s.split(".").map(&:to_i), id.date.to_s]
90
+ end
91
+
92
+ # @param ref [String] the ETSI standard Code to look up
93
+ # @param year [String, nil] year
94
+ # @param opts [Hash] options
95
+ # @return [Relaton::Etsi::ItemData, nil]
96
+ def get(ref, _year = nil, _opts = {})
97
+ Util.info "Fetching from Relaton repository ...", key: ref
98
+ result = search(ref)
99
+ unless result
100
+ Util.info "Not found.", key: ref
101
+ return
102
+ end
103
+
104
+ Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
105
+ result
106
+ end
107
+
108
+ extend Bibliography
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,167 @@
1
+ require "date"
2
+ require "json"
3
+ require "mechanize"
4
+ require "relaton/core"
5
+ require "relaton/index"
6
+ require_relative "../etsi"
7
+ require_relative "data_parser"
8
+
9
+ module Relaton
10
+ module Etsi
11
+ class DataFetcher < Core::DataFetcher
12
+ PAGE_SIZE = 50
13
+
14
+ # `version=1` keeps the superseded EDITIONS of a document in the result
15
+ # set; `version=0` returns only the current edition of each branch. The
16
+ # status flags below are a separate axis and already permissive, so this
17
+ # is what makes e.g. all three editions of `ETSI EN 319 142-1` retrievable
18
+ # instead of one. It also makes the crawl about 2.4 times larger — see
19
+ # lib/relaton/etsi/CLAUDE.md before changing it back.
20
+ SOURCEURL = "https://www.etsi.org/custom/standardssearch/data.php?format=json&includeScope=1&" \
21
+ "page=%<page>s&search=&title=1&etsiNumber=1&content=1&version=1&onApproval=1&published=1&" \
22
+ "withdrawn=1&historical=1&isCurrent=1&superseded=1&startDate=1988-01-15&endDate=%<date>s&" \
23
+ "harmonized=0&keyword=&TB=&stdType=&frequency=&mandate=&collection=&sort=1&x=%<timestamp>s".freeze
24
+
25
+ def index
26
+ @index ||= Relaton::Index.find_or_create(
27
+ :etsi, file: "#{INDEXFILE}.yaml", pubid_class: ::Pubid::Etsi::Identifier
28
+ )
29
+ end
30
+
31
+ def log_error(msg)
32
+ Util.error msg
33
+ end
34
+
35
+ #
36
+ # Fetch all ETSI documents from the ETSI website.
37
+ #
38
+ # @param [Object] _source unused, required by superclass interface
39
+ #
40
+ def fetch(_source = nil)
41
+ first_page = fetch_page(1)
42
+ process_records(first_page)
43
+ fetch_remaining_pages(first_page)
44
+ index.save
45
+ report_errors
46
+ end
47
+
48
+ def fetch_remaining_pages(first_page)
49
+ total = first_page.first ? first_page.first["total_count"].to_i : 0
50
+ total_pages = (total / PAGE_SIZE.to_f).ceil
51
+ (2..total_pages).each do |page|
52
+ records = fetch_page(page)
53
+ break if records.empty?
54
+
55
+ process_records(records)
56
+ end
57
+ end
58
+
59
+ def fetch_page(page)
60
+ date = Time.now.to_date + 1
61
+ timestamp = (Time.now.to_f * 1000).to_i
62
+ url = format(SOURCEURL, page: page, date: date, timestamp: timestamp)
63
+ JSON.parse(fetch_with_retry(url))
64
+ end
65
+
66
+ def process_records(records)
67
+ records.each do |record|
68
+ save DataParser.new(normalize(record), @errors).parse
69
+ end
70
+ end
71
+
72
+ def normalize(record)
73
+ {
74
+ "ETSI deliverable" => record["ETSI_DELIVERABLE"],
75
+ "title" => record["TITLE"],
76
+ "Details link" => "https://webapp.etsi.org/workprogram/Report_WorkItem.asp?WKI_ID=#{record['wki_id']}",
77
+ "PDF link" => "https://www.etsi.org/deliver/#{record['EDSpathname']}#{record['EDSPDFfilename']}",
78
+ "Status" => derive_status(record),
79
+ "Keywords" => record["Keywords"].to_s,
80
+ "Technical body" => record["TB"],
81
+ "Scope" => record["Scope"],
82
+ }
83
+ end
84
+
85
+ def derive_status(record)
86
+ return "Withdrawn" if record["ACTION_TYPE"] == "WD"
87
+
88
+ code = record["STATUS_CODE"].to_i
89
+ return "On Approval" if code < 12
90
+ return "Historical" if code == 13
91
+
92
+ "Published"
93
+ end
94
+
95
+ NETWORK_ERRORS = [
96
+ Mechanize::Error, Net::OpenTimeout, Net::ReadTimeout,
97
+ SocketError, Errno::ECONNRESET
98
+ ].freeze
99
+
100
+ def fetch_with_retry(url, retries: 3, delay: 2) # rubocop:disable Metrics/MethodLength
101
+ attempt = 0
102
+ begin
103
+ Mechanize.new.get(url).body
104
+ rescue *NETWORK_ERRORS => e
105
+ attempt += 1
106
+ if attempt <= retries
107
+ Util.info "Fetch failed (#{e.message}), " \
108
+ "retrying (#{attempt}/#{retries})..."
109
+ sleep delay * attempt
110
+ retry
111
+ end
112
+ raise
113
+ end
114
+ end
115
+
116
+ def save(bib)
117
+ id = bib.docidentifier.first.content
118
+ pid = pubid(id) or return # skip ids pubid can't parse/serialize
119
+
120
+ # Distinct docids can sanitize to one filename (`output_file` collapses
121
+ # `/`, `-`, `.`, `:` and `()` alike, and ETSI ids use all of them), which
122
+ # used to overwrite silently. Take a path of our own. There is no @files
123
+ # here, so a repeat of the SAME id still resolves to one path and
124
+ # overwrites itself, as before.
125
+ file = unique_output_file id
126
+ if file != output_file(id)
127
+ Util.warn "File #{output_file id} already exists. Docid: #{id}. Writing #{file} instead."
128
+ end
129
+ File.write file, serialize(bib), encoding: "UTF-8"
130
+ index.add_or_update pid, file
131
+ end
132
+
133
+ #
134
+ # Parse an ETSI docid into a Pubid::Etsi identifier, or nil when it can't
135
+ # be parsed or serialized. Storing the pubid object (not its hash) lets
136
+ # Relaton::Index sort the index by id number and serialize each id to its
137
+ # `_type: pubid:etsi:*` hash on save. A single unindexable id must never
138
+ # abort the crawl or corrupt the index, so it is skipped defensively
139
+ # (mirrors Relaton::Nist#pubid / Relaton::Jcgm#add_to_index). ETSI's whole
140
+ # published corpus parses on the pinned pubid; the guard protects against a
141
+ # future malformed record.
142
+ #
143
+ # @param [String] id docidentifier content, e.g. "ETSI GS ZSM 012 V1.1.1 (2022-12)"
144
+ # @return [::Pubid::Etsi::Identifier, nil]
145
+ #
146
+ def pubid(id)
147
+ pid = ::Pubid::Etsi.parse id
148
+ pid.to_hash # skip ids whose to_hash raises so index.save can't fail
149
+ pid
150
+ rescue StandardError
151
+ nil
152
+ end
153
+
154
+ def to_yaml(bib)
155
+ bib.to_yaml
156
+ end
157
+
158
+ def to_xml(bib)
159
+ bib.to_xml bibdata: true
160
+ end
161
+
162
+ def to_bibxml(bib)
163
+ bib.to_rfcxml
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,208 @@
1
+ require_relative "pubid"
2
+ module Relaton
3
+ module Etsi
4
+ class DataParser
5
+ ATTRS = %i[
6
+ title docnumber source date docidentifier version status contributor
7
+ keyword ext abstract language script
8
+ ].freeze
9
+
10
+ def initialize(row, errors = {})
11
+ @row = row
12
+ @errors = errors
13
+ end
14
+
15
+ def parse
16
+ args = ATTRS.to_h { |attr| [attr, send(attr)] }
17
+ ItemData.new(type: "standard", **args)
18
+ end
19
+
20
+ def pubid
21
+ return @pubid if defined?(@pubid)
22
+
23
+ unless @row["ETSI deliverable"]
24
+ @errors[:pubid] &&= true
25
+ @pubid = nil
26
+ return @pubid
27
+ end
28
+
29
+ @errors[:pubid] &&= false
30
+ @pubid = PubId.parse(@row["ETSI deliverable"])
31
+ end
32
+
33
+ def title
34
+ result = if @row["title"]
35
+ [Bib::Title.new(
36
+ content: @row["title"], language: "en", script: "Latn",
37
+ )]
38
+ else
39
+ []
40
+ end
41
+ @errors[:title] &&= result.empty?
42
+ result
43
+ end
44
+
45
+ def docnumber
46
+ @row["ETSI deliverable"]
47
+ end
48
+
49
+ def source
50
+ urls = []
51
+ if @row["Details link"]
52
+ urls << Bib::Uri.new(content: @row["Details link"], type: "src")
53
+ end
54
+ if @row["PDF link"]
55
+ urls << Bib::Uri.new(content: @row["PDF link"], type: "pdf")
56
+ end
57
+ @errors[:source] &&= urls.empty?
58
+ urls
59
+ end
60
+
61
+ def date
62
+ result = if pubid&.date
63
+ [Bib::Date.new(type: "published", at: pubid.date)]
64
+ else
65
+ []
66
+ end
67
+ @errors[:date] &&= result.empty?
68
+ result
69
+ end
70
+
71
+ def docidentifier
72
+ result = if @row["ETSI deliverable"]
73
+ [Bib::Docidentifier.new(
74
+ content: @row["ETSI deliverable"],
75
+ type: "ETSI",
76
+ primary: true,
77
+ )]
78
+ else
79
+ []
80
+ end
81
+ @errors[:docidentifier] &&= result.empty?
82
+ result
83
+ end
84
+
85
+ def version
86
+ return [] unless pubid&.version
87
+
88
+ [Bib::Version.new(draft: pubid.version)]
89
+ end
90
+
91
+ def status
92
+ unless @row["Status"]
93
+ @errors[:status] &&= true
94
+ return
95
+ end
96
+
97
+ stage = @row["Status"]
98
+ if stage == "On Approval"
99
+ stage = "#{pubid&.type} approval"
100
+ end
101
+ @errors[:status] &&= false
102
+ Status.new(stage: stage)
103
+ end
104
+
105
+ def contributor
106
+ contribs = [publisher_contributor]
107
+ contribs << committee_contributor if @row["Technical body"]
108
+ contribs
109
+ end
110
+
111
+ def publisher_contributor
112
+ org = Bib::Organization.new(
113
+ name: [etsi_org_name], abbreviation: etsi_abbreviation,
114
+ )
115
+ role = Bib::Contributor::Role.new(type: "publisher")
116
+ Bib::Contributor.new(organization: org, role: [role])
117
+ end
118
+
119
+ def etsi_org_name
120
+ Bib::TypedLocalizedString.new(
121
+ content: "European Telecommunications Standards Institute",
122
+ language: "en",
123
+ script: "Latn",
124
+ )
125
+ end
126
+
127
+ def etsi_abbreviation
128
+ Bib::LocalizedString.new(
129
+ content: "ETSI",
130
+ language: "en",
131
+ script: "Latn",
132
+ )
133
+ end
134
+
135
+ def committee_contributor
136
+ desc = Bib::LocalizedMarkedUpString.new(content: "committee")
137
+ role = Bib::Contributor::Role.new(
138
+ type: "author", description: [desc],
139
+ )
140
+ Bib::Contributor.new(organization: committee_org, role: [role])
141
+ end
142
+
143
+ def committee_org
144
+ Bib::Organization.new(
145
+ name: [etsi_name],
146
+ abbreviation: etsi_abbreviation,
147
+ subdivision: [technical_committee_subdivision],
148
+ )
149
+ end
150
+
151
+ def etsi_name
152
+ Bib::TypedLocalizedString.new(
153
+ content: "European Telecommunications Standards Institute",
154
+ )
155
+ end
156
+
157
+ def technical_committee_subdivision
158
+ Bib::Subdivision.new(
159
+ name: [Bib::TypedLocalizedString.new(
160
+ content: @row["Technical body"],
161
+ )],
162
+ type: "technical-committee",
163
+ )
164
+ end
165
+
166
+ def keyword
167
+ unless @row["Keywords"]
168
+ @errors[:keyword] &&= true
169
+ return []
170
+ end
171
+
172
+ result = @row["Keywords"].split(",").map do |kw|
173
+ Bib::Keyword.new(vocab: Bib::LocalizedString.new(content: kw.strip, language: "en", script: "Latn"))
174
+ end
175
+ @errors[:keyword] &&= result.empty?
176
+ result
177
+ end
178
+
179
+ def ext
180
+ Ext.new(doctype: doctype, flavor: "etsi")
181
+ end
182
+
183
+ def doctype
184
+ return unless pubid
185
+
186
+ Doctype.create_from_abbreviation pubid.type
187
+ end
188
+
189
+ def abstract
190
+ result = if @row["Scope"]
191
+ [Bib::Abstract.new(content: @row["Scope"], language: "en", script: "Latn")]
192
+ else
193
+ []
194
+ end
195
+ @errors[:abstract] &&= result.empty?
196
+ result
197
+ end
198
+
199
+ def language
200
+ ["en"]
201
+ end
202
+
203
+ def script
204
+ ["Latn"]
205
+ end
206
+ end
207
+ end
208
+ end