relaton 3.0.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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +57 -1
  3. data/bin/console +0 -1
  4. data/lib/relaton/3gpp/bibliography.rb +82 -7
  5. data/lib/relaton/3gpp/data_fetcher.rb +51 -3
  6. data/lib/relaton/3gpp/docidentifier.rb +114 -0
  7. data/lib/relaton/3gpp/item.rb +6 -0
  8. data/lib/relaton/3gpp/parser.rb +1 -1
  9. data/lib/relaton/3gpp/processor.rb +4 -1
  10. data/lib/relaton/3gpp.rb +5 -1
  11. data/lib/relaton/adobe/bibdata.rb +8 -0
  12. data/lib/relaton/adobe/bibitem.rb +8 -0
  13. data/lib/relaton/adobe/bibliography.rb +92 -0
  14. data/lib/relaton/adobe/docidentifier.rb +49 -0
  15. data/lib/relaton/adobe/doctype.rb +14 -0
  16. data/lib/relaton/adobe/ext.rb +32 -0
  17. data/lib/relaton/adobe/item.rb +15 -0
  18. data/lib/relaton/adobe/item_base.rb +18 -0
  19. data/lib/relaton/adobe/item_data.rb +6 -0
  20. data/lib/relaton/adobe/processor.rb +45 -0
  21. data/lib/relaton/adobe/util.rb +8 -0
  22. data/lib/relaton/adobe.rb +37 -0
  23. data/lib/relaton/bib/model/address.rb +2 -2
  24. data/lib/relaton/bib/model/docidentifier.rb +24 -9
  25. data/lib/relaton/bib/model/localized_string.rb +1 -1
  26. data/lib/relaton/bib/model/structured_identifier.rb +10 -9
  27. data/lib/relaton/bib/sanitizer.rb +202 -6
  28. data/lib/relaton/bib.rb +0 -2
  29. data/lib/relaton/bipm/bibliography.rb +159 -10
  30. data/lib/relaton/bipm/data_fetcher.rb +26 -2
  31. data/lib/relaton/bipm/data_outcomes_parser.rb +3 -4
  32. data/lib/relaton/bipm/id_parser.rb +5 -4
  33. data/lib/relaton/bipm/model/structured_identifier.rb +21 -0
  34. data/lib/relaton/bipm/processor.rb +2 -2
  35. data/lib/relaton/bipm/rawdata_bipm_metrologia/fetcher.rb +2 -4
  36. data/lib/relaton/bipm/si_brochure_parser.rb +5 -3
  37. data/lib/relaton/bipm.rb +7 -1
  38. data/lib/relaton/bsi/bibliography.rb +115 -43
  39. data/lib/relaton/bsi/hit.rb +14 -0
  40. data/lib/relaton/bsi/hit_collection.rb +15 -16
  41. data/lib/relaton/bsi/model/docidentifier.rb +99 -1
  42. data/lib/relaton/bsi/processor.rb +1 -0
  43. data/lib/relaton/calconnect/bibliography.rb +12 -14
  44. data/lib/relaton/calconnect/data_fetcher.rb +77 -9
  45. data/lib/relaton/calconnect/docidentifier.rb +80 -0
  46. data/lib/relaton/calconnect/hit_collection.rb +65 -57
  47. data/lib/relaton/calconnect/model/item.rb +7 -0
  48. data/lib/relaton/calconnect/processor.rb +7 -1
  49. data/lib/relaton/calconnect.rb +11 -1
  50. data/lib/relaton/ccsds/data/fetcher.rb +17 -12
  51. data/lib/relaton/ccsds/data/parser.rb +1 -1
  52. data/lib/relaton/ccsds/hit_collection.rb +6 -1
  53. data/lib/relaton/ccsds/model/docidentifier.rb +121 -0
  54. data/lib/relaton/ccsds/model/item.rb +2 -0
  55. data/lib/relaton/cen/bibliography.rb +75 -47
  56. data/lib/relaton/cen/hit.rb +16 -1
  57. data/lib/relaton/cen/hit_collection.rb +59 -11
  58. data/lib/relaton/cen/model/docidentifier.rb +92 -1
  59. data/lib/relaton/cen/processor.rb +13 -8
  60. data/lib/relaton/cen/scraper.rb +13 -5
  61. data/lib/relaton/cen.rb +1 -0
  62. data/lib/relaton/cie/data_fetcher.rb +215 -30
  63. data/lib/relaton/cie/processor.rb +3 -1
  64. data/lib/relaton/cie/scrapper.rb +15 -2
  65. data/lib/relaton/cie.rb +2 -1
  66. data/lib/relaton/core/data_fetcher.rb +150 -3
  67. data/lib/relaton/core/governor.rb +320 -0
  68. data/lib/relaton/core/pacer.rb +134 -0
  69. data/lib/relaton/core/processor.rb +19 -0
  70. data/lib/relaton/core/request_error.rb +14 -0
  71. data/lib/relaton/core.rb +3 -0
  72. data/lib/relaton/db/registry.rb +41 -1
  73. data/lib/relaton/doi/crossref.rb +19 -2
  74. data/lib/relaton/doi/parser.rb +109 -15
  75. data/lib/relaton/easc/bibdata.rb +8 -0
  76. data/lib/relaton/easc/bibitem.rb +8 -0
  77. data/lib/relaton/easc/bibliography.rb +95 -0
  78. data/lib/relaton/easc/docidentifier.rb +100 -0
  79. data/lib/relaton/easc/doctype.rb +14 -0
  80. data/lib/relaton/easc/ext.rb +44 -0
  81. data/lib/relaton/easc/item.rb +13 -0
  82. data/lib/relaton/easc/item_base.rb +18 -0
  83. data/lib/relaton/easc/item_data.rb +6 -0
  84. data/lib/relaton/easc/processor.rb +46 -0
  85. data/lib/relaton/easc/util.rb +8 -0
  86. data/lib/relaton/easc.rb +35 -0
  87. data/lib/relaton/ecma/bibliography.rb +93 -25
  88. data/lib/relaton/ecma/data_fetcher.rb +71 -12
  89. data/lib/relaton/ecma/docidentifier.rb +124 -0
  90. data/lib/relaton/ecma/item.rb +2 -0
  91. data/lib/relaton/ecma/memento_parser.rb +1 -1
  92. data/lib/relaton/ecma/page_fetcher.rb +15 -3
  93. data/lib/relaton/ecma/parser_common.rb +2 -2
  94. data/lib/relaton/ecma/processor.rb +4 -1
  95. data/lib/relaton/ecma/standard_parser.rb +2 -2
  96. data/lib/relaton/ecma.rb +10 -1
  97. data/lib/relaton/etsi/bibliography.rb +67 -2
  98. data/lib/relaton/etsi/data_fetcher.rb +43 -4
  99. data/lib/relaton/etsi/processor.rb +3 -1
  100. data/lib/relaton/etsi.rb +2 -1
  101. data/lib/relaton/gb/bibliography.rb +55 -29
  102. data/lib/relaton/gb/docidentifier.rb +58 -9
  103. data/lib/relaton/gb/processor.rb +3 -0
  104. data/lib/relaton/gb/scraper.rb +27 -10
  105. data/lib/relaton/gost/bibdata.rb +8 -0
  106. data/lib/relaton/gost/bibitem.rb +8 -0
  107. data/lib/relaton/gost/bibliography.rb +107 -0
  108. data/lib/relaton/gost/docidentifier.rb +80 -0
  109. data/lib/relaton/gost/doctype.rb +16 -0
  110. data/lib/relaton/gost/ext.rb +46 -0
  111. data/lib/relaton/gost/item.rb +15 -0
  112. data/lib/relaton/gost/item_base.rb +18 -0
  113. data/lib/relaton/gost/item_data.rb +6 -0
  114. data/lib/relaton/gost/processor.rb +49 -0
  115. data/lib/relaton/gost/util.rb +8 -0
  116. data/lib/relaton/gost.rb +36 -0
  117. data/lib/relaton/iala/bibdata.rb +8 -0
  118. data/lib/relaton/iala/bibitem.rb +8 -0
  119. data/lib/relaton/iala/bibliography.rb +146 -0
  120. data/lib/relaton/iala/docidentifier.rb +89 -0
  121. data/lib/relaton/iala/doctype.rb +18 -0
  122. data/lib/relaton/iala/ext.rb +32 -0
  123. data/lib/relaton/iala/item.rb +21 -0
  124. data/lib/relaton/iala/item_base.rb +18 -0
  125. data/lib/relaton/iala/item_data.rb +6 -0
  126. data/lib/relaton/iala/processor.rb +43 -0
  127. data/lib/relaton/iala/relation.rb +7 -0
  128. data/lib/relaton/iala/util.rb +8 -0
  129. data/lib/relaton/iala.rb +35 -0
  130. data/lib/relaton/iana/bibliography.rb +67 -14
  131. data/lib/relaton/iana/data_fetcher.rb +35 -5
  132. data/lib/relaton/iana/processor.rb +3 -1
  133. data/lib/relaton/iana.rb +12 -1
  134. data/lib/relaton/iec/data_fetcher.rb +7 -1
  135. data/lib/relaton/iec/hit_collection.rb +1 -1
  136. data/lib/relaton/iec/model/docidentifier.rb +9 -5
  137. data/lib/relaton/iec/model/ext.rb +2 -2
  138. data/lib/relaton/iec/processor.rb +1 -0
  139. data/lib/relaton/ieee/bibliography.rb +25 -3
  140. data/lib/relaton/ieee/data_fetcher.rb +158 -17
  141. data/lib/relaton/ieee/idams_parser.rb +18 -11
  142. data/lib/relaton/ieee/processor.rb +4 -1
  143. data/lib/relaton/ieee/rawbib_id_parser.rb +291 -86
  144. data/lib/relaton/ieee.rb +2 -1
  145. data/lib/relaton/ietf/data_fetcher.rb +295 -12
  146. data/lib/relaton/ietf/processor.rb +7 -3
  147. data/lib/relaton/ietf/rfc/entry.rb +39 -3
  148. data/lib/relaton/ietf/scraper.rb +69 -36
  149. data/lib/relaton/ietf.rb +4 -1
  150. data/lib/relaton/iho/bibliography.rb +1 -1
  151. data/lib/relaton/iho/docidentifier.rb +1 -1
  152. data/lib/relaton/index/file_io.rb +11 -11
  153. data/lib/relaton/index/file_storage.rb +6 -1
  154. data/lib/relaton/index/pool.rb +6 -1
  155. data/lib/relaton/index/shard_source.rb +201 -0
  156. data/lib/relaton/index/type.rb +63 -12
  157. data/lib/relaton/index.rb +2 -1
  158. data/lib/relaton/iso/bibliography.rb +20 -15
  159. data/lib/relaton/iso/data_fetcher.rb +3 -3
  160. data/lib/relaton/iso/data_parser.rb +17 -3
  161. data/lib/relaton/iso/hit_collection.rb +27 -15
  162. data/lib/relaton/iso/item_data.rb +22 -0
  163. data/lib/relaton/iso/model/docidentifier.rb +24 -12
  164. data/lib/relaton/iso/processor.rb +1 -0
  165. data/lib/relaton/iso/scraper.rb +19 -3
  166. data/lib/relaton/itu/bibliography.rb +9 -4
  167. data/lib/relaton/itu/data_crawler_r.rb +664 -0
  168. data/lib/relaton/itu/data_fetcher.rb +496 -50
  169. data/lib/relaton/itu/data_merge_r.rb +149 -0
  170. data/lib/relaton/itu/data_parser_r.rb +163 -89
  171. data/lib/relaton/itu/data_parser_t.rb +228 -0
  172. data/lib/relaton/itu/family_cache.rb +177 -0
  173. data/lib/relaton/itu/governor.rb +56 -0
  174. data/lib/relaton/itu/hit.rb +9 -3
  175. data/lib/relaton/itu/hit_collection.rb +258 -86
  176. data/lib/relaton/itu/model/docidentifier.rb +67 -1
  177. data/lib/relaton/itu/model/structured_identifier.rb +19 -0
  178. data/lib/relaton/itu/processor.rb +10 -4
  179. data/lib/relaton/itu/pubid.rb +27 -5
  180. data/lib/relaton/itu/recommendation_fields.rb +334 -0
  181. data/lib/relaton/itu/recommendation_parser.rb +18 -149
  182. data/lib/relaton/itu/scraper.rb +13 -3
  183. data/lib/relaton/itu.rb +2 -1
  184. data/lib/relaton/jcgm/bibdata.rb +8 -0
  185. data/lib/relaton/jcgm/bibitem.rb +8 -0
  186. data/lib/relaton/jcgm/bibliography.rb +97 -0
  187. data/lib/relaton/jcgm/data_fetcher.rb +81 -0
  188. data/lib/relaton/jcgm/docidentifier.rb +102 -0
  189. data/lib/relaton/jcgm/doctype.rb +12 -0
  190. data/lib/relaton/jcgm/ext.rb +23 -0
  191. data/lib/relaton/jcgm/item.rb +20 -0
  192. data/lib/relaton/jcgm/item_base.rb +18 -0
  193. data/lib/relaton/jcgm/item_data.rb +6 -0
  194. data/lib/relaton/jcgm/meetings_parser.rb +175 -0
  195. data/lib/relaton/jcgm/processor.rb +71 -0
  196. data/lib/relaton/jcgm/relation.rb +9 -0
  197. data/lib/relaton/jcgm/structured_identifier.rb +40 -0
  198. data/lib/relaton/jcgm/util.rb +8 -0
  199. data/lib/relaton/jcgm.rb +24 -0
  200. data/lib/relaton/jis/bibliography.rb +8 -10
  201. data/lib/relaton/jis/data_fetcher.rb +21 -19
  202. data/lib/relaton/jis/docidentifier.rb +104 -5
  203. data/lib/relaton/jis/hit.rb +18 -23
  204. data/lib/relaton/jis/hit_collection.rb +19 -18
  205. data/lib/relaton/jis/processor.rb +1 -1
  206. data/lib/relaton/jis.rb +2 -3
  207. data/lib/relaton/logger/channels/gh_issue.rb +78 -13
  208. data/lib/relaton/nist/data_fetcher.rb +63 -13
  209. data/lib/relaton/nist/docidentifier.rb +165 -0
  210. data/lib/relaton/nist/item.rb +2 -0
  211. data/lib/relaton/nist/item_base.rb +16 -0
  212. data/lib/relaton/nist/mods_parser.rb +38 -12
  213. data/lib/relaton/nist/processor.rb +2 -1
  214. data/lib/relaton/nist/relation.rb +3 -0
  215. data/lib/relaton/nist/scraper.rb +6 -3
  216. data/lib/relaton/oasis/bibliography.rb +147 -6
  217. data/lib/relaton/oasis/data_fetcher.rb +41 -5
  218. data/lib/relaton/oasis/data_parser_utils.rb +37 -3
  219. data/lib/relaton/oasis/docidentifier.rb +54 -0
  220. data/lib/relaton/oasis/item.rb +3 -0
  221. data/lib/relaton/oasis/processor.rb +7 -1
  222. data/lib/relaton/oasis.rb +14 -1
  223. data/lib/relaton/ogc/data_fetcher.rb +23 -2
  224. data/lib/relaton/ogc/docidentifier.rb +105 -0
  225. data/lib/relaton/ogc/hit_collection.rb +78 -3
  226. data/lib/relaton/ogc/processor.rb +2 -1
  227. data/lib/relaton/ogc.rb +5 -1
  228. data/lib/relaton/oiml/bibliography.rb +90 -15
  229. data/lib/relaton/oiml/docidentifier.rb +18 -3
  230. data/lib/relaton/omg/docidentifier.rb +67 -0
  231. data/lib/relaton/omg/item.rb +1 -0
  232. data/lib/relaton/omg/processor.rb +1 -0
  233. data/lib/relaton/omg/scraper.rb +61 -16
  234. data/lib/relaton/omg.rb +1 -0
  235. data/lib/relaton/plateau/bibliography.rb +10 -3
  236. data/lib/relaton/plateau/data_fetcher.rb +25 -2
  237. data/lib/relaton/plateau/handbook_parser.rb +8 -1
  238. data/lib/relaton/plateau/hit.rb +10 -2
  239. data/lib/relaton/plateau/hit_collection.rb +31 -11
  240. data/lib/relaton/plateau/processor.rb +3 -1
  241. data/lib/relaton/plateau/technical_report_parser.rb +8 -1
  242. data/lib/relaton/plateau.rb +2 -1
  243. data/lib/relaton/sdo/config.rb +34 -0
  244. data/lib/relaton/sdo/fetcher.rb +52 -0
  245. data/lib/relaton/sdo/logo.rb +95 -0
  246. data/lib/relaton/sdo/name.rb +26 -0
  247. data/lib/relaton/sdo/organization.rb +71 -0
  248. data/lib/relaton/sdo/store.rb +49 -0
  249. data/lib/relaton/sdo.rb +29 -0
  250. data/lib/relaton/version.rb +1 -1
  251. data/lib/relaton/w3c/bibliography.rb +132 -12
  252. data/lib/relaton/w3c/data_fetcher.rb +194 -16
  253. data/lib/relaton/w3c/data_parser.rb +3 -3
  254. data/lib/relaton/w3c/docidentifier.rb +48 -0
  255. data/lib/relaton/w3c/governor.rb +32 -0
  256. data/lib/relaton/w3c/item.rb +3 -0
  257. data/lib/relaton/w3c/pubid.rb +12 -0
  258. data/lib/relaton/w3c/safe_realize.rb +110 -21
  259. data/lib/relaton/w3c.rb +12 -1
  260. data/lib/relaton/xsf/bibliography.rb +61 -1
  261. data/lib/relaton/xsf/data_fetcher.rb +55 -5
  262. data/lib/relaton/xsf/docidentifier.rb +46 -0
  263. data/lib/relaton/xsf/hit_collection.rb +31 -3
  264. data/lib/relaton/xsf/item.rb +6 -0
  265. data/lib/relaton/xsf/processor.rb +1 -0
  266. data/lib/relaton/xsf.rb +5 -1
  267. data/lib/relaton.rb +42 -0
  268. metadata +135 -24
  269. data/lib/relaton/ieee/pub_id.rb +0 -161
  270. data/lib/relaton/index/id_number.rb +0 -30
@@ -1,5 +1,3 @@
1
- require_relative "pub_id"
2
-
3
1
  module Relaton
4
2
  module Ieee
5
3
  module RawbibIdParser
@@ -8,15 +6,105 @@ module Relaton
8
6
  APPROV = '(?:\s(?:Unapproved|Approved))?'.freeze
9
7
  STD = "(?<std>\s(?i)Std.?(?-i))?".freeze
10
8
 
9
+ # Recurring OCR/spelling variants of month names seen in the raw IEEE
10
+ # dataset, mapped to a name Ruby's Date tables recognise.
11
+ MONTH_TYPOS = {
12
+ "sept" => "sep", "feburary" => "february", "novemer" => "november",
13
+ "octobor" => "october", "janurary" => "january"
14
+ }.freeze
15
+
16
+ #
17
+ # Parse a raw IEEE `normtitle` into a pubid identifier.
11
18
  #
12
- # Parse normtitle
19
+ # pubid-first: most normtitles are canonical enough that
20
+ # `::Pubid::Ieee::Identifier.parse` handles them directly. The bespoke
21
+ # `#parse_fallback` regex pipeline only runs for the messy remainder — it
22
+ # normalizes the vendor string into a canonical form (via the private
23
+ # `Renderer`) that pubid can then parse. Either way the return value is a
24
+ # `::Pubid::Ieee::Identifier` (or nil when neither can make sense of it).
13
25
  #
14
26
  # @param [String] normtitle document element "normtitle"
15
27
  # @param [String] stdnumber document element "stdnumber"
16
28
  #
17
- # @return [RelatonIeee::PubId, nil]
29
+ # @return [::Pubid::Ieee::Identifier, nil]
30
+ #
31
+ def parse(normtitle, stdnumber)
32
+ # Bespoke canonical string is the faithfulness reference: for the ~6% of
33
+ # normtitles pubid can't parse directly it's the recovery source, and for
34
+ # the rest it guards against pubid parsing but silently dropping a digit.
35
+ rendered = parse_fallback(normtitle, stdnumber)
36
+ ref = rendered&.to_id
37
+ [pubid_parse(normtitle), (ref && pubid_parse(ref))].compact.each do |pid|
38
+ return pid if ref.nil? || faithful?(pid.to_s, ref)
39
+ end
40
+ rendered # neither pubid parse kept every digit — keep the bespoke id
41
+ end
42
+
43
+ #
44
+ # True when `pid` is not a real IEEE designation but a leading fragment
45
+ # of the document's own title, coined by a generic {#parse_fallback}
46
+ # branch built for a genuine catalog number (e.g. "IEEE 802.3") that
47
+ # also happens to match a short title's opening words ("WEB 3.0: The
48
+ # Evolution of ..." -> `WEB 3.0`). Restricting this to the unvalidated
49
+ # `Renderer` fallback (never a pubid grammar match) is what keeps a
50
+ # genuine, correctly-resolved standard safe: measured over 9,091
51
+ # successfully-parsed records in the raw corpus, 7 real standards whose
52
+ # title happens to literally start with their own real designation
53
+ # (`IEEE Std 1636.99-2013, IEEE Standard for ...`) resolve to a real
54
+ # `::Pubid::Ieee::Identifier`, never a `Renderer`, so they are never
55
+ # flagged. `DataFetcher#no_standard_number?` catches most title-fragment
56
+ # records upfront by `publicationsubtype`, but that list can't cover
57
+ # every vendor subtype spelling, so this is a second, subtype-agnostic
58
+ # guard on the resolved id itself. Requiring a real ISBN keeps a
59
+ # genuine `Renderer` id (the ~1.3% that miss the faithfulness guard;
60
+ # see {#parse}) whose title coincidentally starts with it from being
61
+ # discarded.
62
+ #
63
+ # @param [::Pubid::Ieee::Identifier, Renderer, nil] pid
64
+ # @param [String, nil] title the document's own (non-normtitle) title
65
+ # @param [Boolean] isbn_present whether the document carries a real ISBN
18
66
  #
19
- def parse(normtitle, stdnumber) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
67
+ # @return [Boolean]
68
+ #
69
+ def fabricated_title_id?(pid, title, isbn_present)
70
+ return false unless pid.is_a?(Renderer)
71
+
72
+ !!(title && isbn_present && title.start_with?(pid.to_s))
73
+ end
74
+
75
+ # Parse a canonical id string into a pubid identifier, or nil on failure.
76
+ def pubid_parse(str)
77
+ ::Pubid::Ieee::Identifier.parse(str)
78
+ rescue StandardError
79
+ nil
80
+ end
81
+
82
+ MONTHS_RE = /\b(?:jan(?:uary)?|feb(?:ruary)?|mar(?:ch)?|apr(?:il)?|may|jun(?:e)?|jul(?:y)?|aug(?:ust)?|sep(?:t)?(?:ember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\b/i # rubocop:disable Layout/LineLength
83
+
84
+ # Date-independent digit multiset of an id (strips month names, years, and a
85
+ # trailing numeric month), so date reformatting doesn't count as a change.
86
+ def id_digits(str)
87
+ t = str.gsub(MONTHS_RE, " ").gsub(/(?:19|20)\d{2}/, " ").gsub(/-\s*\d{1,2}(?=\D*\z)/, " ")
88
+ t.gsub(/\D/, "").chars
89
+ end
90
+
91
+ # True when the pubid rendering kept every (non-date) digit of the bespoke
92
+ # reference — i.e. pubid didn't drop a draft/part/number digit. Digit-level
93
+ # (not token-level) so a benign re-split like `P1476/D4` vs `P14764` counts
94
+ # as faithful (same digits) while a real loss (`/D3.0` -> `/D.0`) does not.
95
+ def faithful?(pubid_str, ref_str)
96
+ have = id_digits(pubid_str).tally
97
+ id_digits(ref_str).tally.all? { |d, c| have.fetch(d, 0) >= c }
98
+ end
99
+
100
+ #
101
+ # Fallback: map a messy normtitle to an internal {Renderer} whose `.to_id`
102
+ # is a canonical string pubid can parse. Only the ~12% of normtitles pubid
103
+ # can't parse directly reach here.
104
+ #
105
+ # @return [Renderer, nil]
106
+ #
107
+ def parse_fallback(normtitle, stdnumber) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
20
108
  case normtitle.sub(/^ISO\s(?=\/)/, "ISO").sub(/^ANSI\/\s(?=IEEE)/, "ANSI/")
21
109
  # when "2012 NESC Handbook, Seventh Edition" then "NESC HBK ED7.2012"
22
110
  # when "2017 NESC(R) Handbook, Premier Edition" then "NESC HBK ED1.2017"
@@ -25,105 +113,105 @@ module Relaton
25
113
  # when /^(\d+HistoricalData)-(\d{4})/ then "IEEE #{$1}.#{$2}"
26
114
  # when /^(\d+)\.(\w+)\sBattery\sLife\sImprovement/ then "IEEE #{$1}-#{$2}"
27
115
  # when /^(\d+)\.(\w+)-(\d{4})\s\(Amendment/ then "IEEE #{$1}-#{$2}.#{$3}"
28
- when "A.I.E.E. No. 15 May-1928" then PubId.new(publisher: "AIEE", number: "15", year: "1928", month: "05")
116
+ when "A.I.E.E. No. 15 May-1928" then Renderer.new(publisher: "AIEE", number: "15", year: "1928", month: "05")
29
117
  # when "AIEE Nos 72 and 73 - 1932" then "AIEE 72_73.1932"
30
- when "IEEE Std P1073.1.3.4/D3.0" then PubId.new(publisher: "IEEE", std: true, number: "P11073", part: "00101") # "IEEE Std P11073-00101"
31
- # when "P1073.1.3.4/D3.0" then PubId.new(publisher: "IEEE", number: "P1073", part: "1-3-4", draft: "3.0") # "IEEE P1073-1-3-4/D3.0"
32
- when "IEEE P1073.2.1.1/D08" then PubId.new(publisher: "ISO/IEEE", number: "P1073", part: "2-1-1", draft: "08") # "ISO/IEEE P1073-2-1-1/D08"
118
+ when "IEEE Std P1073.1.3.4/D3.0" then Renderer.new(publisher: "IEEE", std: true, number: "P11073", part: "00101") # "IEEE Std P11073-00101"
119
+ # when "P1073.1.3.4/D3.0" then Renderer.new(publisher: "IEEE", number: "P1073", part: "1-3-4", draft: "3.0") # "IEEE P1073-1-3-4/D3.0"
120
+ when "IEEE P1073.2.1.1/D08" then Renderer.new(publisher: "ISO/IEEE", number: "P1073", part: "2-1-1", draft: "08") # "ISO/IEEE P1073-2-1-1/D08"
33
121
  when "IEEE P802.1Qbu/03.0, July 2015" # "IEEE P802.1Qbu/D3.0.2015"
34
- PubId.new(publisher: "IEEE", number: "P802", part: "1Qbu", draft: "3.0", year: "2015")
122
+ Renderer.new(publisher: "IEEE", number: "P802", part: "1Qbu", draft: "3.0", year: "2015")
35
123
  when "IEEE P11073-10422/04, November 2015" # "IEEE P11073-10422/D04.2015"
36
- PubId.new(publisher: "IEEE", number: "P11073", part: "10422", draft: "04", year: "2015")
124
+ Renderer.new(publisher: "IEEE", number: "P11073", part: "10422", draft: "04", year: "2015")
37
125
  when "IEEE P802.11aqTM/013.0 October 2017" # "IEEE P802-11aqTM/D13.0.2017"
38
- PubId.new(publisher: "IEEE", number: "P802", part: "11aqTM", draft: "13.0", year: "2017")
126
+ Renderer.new(publisher: "IEEE", number: "P802", part: "11aqTM", draft: "13.0", year: "2017")
39
127
  when "IEEE P844.3/C22.2 293.3/D0, August 2018" # "IEEE P844-3/C22.2-293.3/D0.2018"
40
- PubId.new([{ publisher: "IEEE", number: "P844", part: "3" },
128
+ Renderer.new([{ publisher: "IEEE", number: "P844", part: "3" },
41
129
  { number: "C22.2", part: "293.3", dtaft: "0", year: "2018" }])
42
130
  when "IEEE P844.3/C22.2 293.3/D1, November 2018" # "IEEE P844.3/C22.2 293.3/D1.2018"
43
- PubId.new([{ publisher: "IEEE", number: "P844", part: "3" },
131
+ Renderer.new([{ publisher: "IEEE", number: "P844", part: "3" },
44
132
  { number: "C22.2", part: "293.3", draft: "1", year: "2018" }])
45
- when "AIEE No 431 (105) -1958" then PubId.new(publisher: "AIEE", number: "431", year: "1958") # "AIEE 431.1958"
46
- when "IEEE 1076-CONC-I99O" then PubId.new(publisher: "IEEE", number: "1076", year: "199O") # "IEEE 1076.199O"
133
+ when "AIEE No 431 (105) -1958" then Renderer.new(publisher: "AIEE", number: "431", year: "1958") # "AIEE 431.1958"
134
+ when "IEEE 1076-CONC-I99O" then Renderer.new(publisher: "IEEE", number: "1076", year: "199O") # "IEEE 1076.199O"
47
135
  when "IEEE Std 960-1993, IEEE Std 1177-1993" # "IEEE 960/1177.1993"
48
- PubId.new([{ publisher: "IEEE", std: true, number: "960" }, { number: "1177", year: "1993" }])
136
+ Renderer.new([{ publisher: "IEEE", std: true, number: "960" }, { number: "1177", year: "1993" }])
49
137
  when "IEEE P802.11ajD8.0, August 2017" # "IEEE P802-11aj/D8.0.2017"
50
- PubId.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "8.0", year: "2017")
138
+ Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "8.0", year: "2017")
51
139
  when "IEEE P802.11ajD9.0, November 2017" # "IEEE P802-11aj/D9.0.2017"
52
- PubId.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "9.0", year: "2017")
140
+ Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "9.0", year: "2017")
53
141
  when "ISO/IEC/IEEE P29119-4-DISMay2013" # "ISO/IEC/IEEE DIS P29119-4.2013"
54
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013")
142
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013")
55
143
  when "IEEE-P15026-3-DIS-January 2015" # "IEEE DIS P15026-3.2015"
56
- PubId.new(publisher: "IEEE", stage: "DIS", number: "P15026", year: "2015")
144
+ Renderer.new(publisher: "IEEE", stage: "DIS", number: "P15026", year: "2015")
57
145
  when "ANSI/IEEE PC63.7/D rev17, December 2014" # "ANSI/IEEE PC63-7/D/REV-17.2014"
58
- PubId.new(publisher: "ANSI/IEEE", number: "PC63", part: "7", draft: "", rev: "17", year: "2014")
146
+ Renderer.new(publisher: "ANSI/IEEE", number: "PC63", part: "7", draft: "", rev: "17", year: "2014")
59
147
  when "IEC/IEEE P62271-37-013:2015 D13.4" # "IEC/IEEE P62271-37-013/D13.4.2015"
60
- PubId.new(publisher: "IEC/IEEE", number: "P62271", part: "37-013", draft: "13.4", year: "2015")
148
+ Renderer.new(publisher: "IEC/IEEE", number: "P62271", part: "37-013", draft: "13.4", year: "2015")
61
149
  when "PC37.30.2/D043 Rev 18, May 2015" # "IEEE PC37-30-2/D043/REV-18.2015"
62
- PubId.new(publisher: "IEEE", number: "PC37", part: "30-2", draft: "043", rev: "18", year: "2015")
150
+ Renderer.new(publisher: "IEEE", number: "PC37", part: "30-2", draft: "043", rev: "18", year: "2015")
63
151
  when "IEC/IEEE FDIS 62582-5 IEC/IEEE 2015" # "IEC/IEEE FDIS 62582-5.2015"
64
- PubId.new(publisher: "IEC/IEEE", stage: "FDIS", number: "62582", part: "5", year: "2015")
152
+ Renderer.new(publisher: "IEC/IEEE", stage: "FDIS", number: "62582", part: "5", year: "2015")
65
153
  when "ISO/IEC/IEEE P15289:2016, 3rd Ed FDIS/D2" # "ISO/IEC/IEEE FDIS P15289/E3/D2.2016"
66
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "FDIS", number: "P15289", part: "", edition: "3", draft: "2", year: "2016")
154
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "FDIS", number: "P15289", part: "", edition: "3", draft: "2", year: "2016")
67
155
  when "IEEE P802.15.4REVi/D09, April 2011 (Revision of IEEE Std 802.15.4-2006)"
68
- PubId.new(publisher: "IEEE", number: "P802", part: "15.4", rev: "i", draft: "09", year: "2013", month: "04", approval: "Approved")
156
+ Renderer.new(publisher: "IEEE", number: "P802", part: "15.4", rev: "i", draft: "09", year: "2013", month: "04", approval: "Approved")
69
157
  when "Draft IEEE P802.15.4REVi/D09, April 2011 (Revision of IEEE Std 802.15.4-2006)"
70
- PubId.new(publisher: "IEEE", number: "P802", part: "15.4", rev: "i", draft: "09", year: "2011", month: "04")
158
+ Renderer.new(publisher: "IEEE", number: "P802", part: "15.4", rev: "i", draft: "09", year: "2011", month: "04")
71
159
  when "ISO/IEC/IEEE DIS P42020:201x(E), June 2017"
72
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P42020", year: "2017", month: "06")
160
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P42020", year: "2017", month: "06")
73
161
  when "IEEE/IEC P62582 CD2 proposal, May 2017"
74
- PubId.new(publisher: "IEEE/IEC", number: "P62582", stage: "CD2", year: "2017", month: "05")
162
+ Renderer.new(publisher: "IEEE/IEC", number: "P62582", stage: "CD2", year: "2017", month: "05")
75
163
  when "ISO/IEC/IEEE P16326:201x WD.4a, July 2017"
76
- PubId.new(publisher: "ISO/IEC/IEEE", number: "P16326", draft: "4a", year: "2017", month: "07")
164
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "P16326", draft: "4a", year: "2017", month: "07")
77
165
  when "ISO/IEC/IEEE CD.1 P21839, October 2017"
78
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "CD1", number: "P21839", year: "2017", month: "10")
166
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "CD1", number: "P21839", year: "2017", month: "10")
79
167
  when "IEEE P3001.2/D5, August 2017"
80
- PubId.new(publisher: "IEEE", number: "P3001", part: "2", draft: "5", year: "2017", month: "01")
168
+ Renderer.new(publisher: "IEEE", number: "P3001", part: "2", draft: "5", year: "2017", month: "01")
81
169
  when "P3001.2/D5, August 2017"
82
- PubId.new(publisher: "IEEE", number: "P3001", part: "2", draft: "5", year: "2017", month: "12")
170
+ Renderer.new(publisher: "IEEE", number: "P3001", part: "2", draft: "5", year: "2017", month: "12")
83
171
  when "ISO/IEC/IEEE P16326:201x WD5, December 2017"
84
- PubId.new(publisher: "ISO/IEC/IEEE", number: "P16326", draft: "5", year: "2017", month: "12")
172
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "P16326", draft: "5", year: "2017", month: "12")
85
173
  when "ISO/IEC/IEEE DIS P16326/201x, December 2018"
86
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P16326", year: "2018", month: "12")
174
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P16326", year: "2018", month: "12")
87
175
  when "ISO/IEC/IEEE/P21839, 2019(E)"
88
- PubId.new(publisher: "ISO/IEC/IEEE", number: "P21839", year: "2019")
176
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "P21839", year: "2019")
89
177
  when "ISO/IEC/IEEE P42020/V1.9, August 2018"
90
- PubId.new(publisher: "ISO/IEC/IEEE", number: "P42020", year: "2018", month: "08")
178
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "P42020", year: "2018", month: "08")
91
179
  when "ISO/IEC/IEEE CD2 P12207-2: 201x(E), February 2019"
92
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "CD2", number: "P12207", part: "2", year: "2019", month: "02")
180
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "CD2", number: "P12207", part: "2", year: "2019", month: "02")
93
181
  when "ISO/IEC/IEEE P42010.WD4:2019(E)"
94
- PubId.new(publisher: "ISO/IEC/IEEE", number: "P42010", draft: "4", year: "2019")
182
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "P42010", draft: "4", year: "2019")
95
183
  when "IEC/IEEE P63195_CDV/V3, February 2020"
96
- PubId.new(publisher: "IEC/IEEE", number: "P63195", stage: "CDV", year: "2020", month: "02")
184
+ Renderer.new(publisher: "IEC/IEEE", number: "P63195", stage: "CDV", year: "2020", month: "02")
97
185
  when "IEEE/ISO/IEC P42010.CD1-V1.0, April 2020"
98
- PubId.new(publisher: "IEEE/ISO/IEC", number: "P42010", stage: "CD1", year: "2020", month: "04")
186
+ Renderer.new(publisher: "IEEE/ISO/IEC", number: "P42010", stage: "CD1", year: "2020", month: "04")
99
187
  when "ISO/IEC/IEEE/P16085_DIS, March 2020"
100
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P16085", year: "2020", month: "03")
188
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P16085", year: "2020", month: "03")
101
189
  when "ANSI/IEEE Std: Outdoor Apparatus Bushings"
102
- PubId.new(publisher: "ANSI/IEEE", std: true, number: "21", year: "1976", month: "11")
190
+ Renderer.new(publisher: "ANSI/IEEE", std: true, number: "21", year: "1976", month: "11")
103
191
  when "Unapproved Draft Std ISO/IEC FDIS 15288:2007(E) IEEE P15288/D3,"
104
- PubId.new(publisher: "ISO/IEC/IEEE", stage: "FDIS", std: true, number: "P15288", draft: "3", year: "2007")
192
+ Renderer.new(publisher: "ISO/IEC/IEEE", stage: "FDIS", std: true, number: "P15288", draft: "3", year: "2007")
105
193
  when "Draft National Electrical Safety Code, January 2016"
106
- PubId.new(publisher: "IEEE", number: "PC2", year: "2016", month: "01")
107
- when "ANSI/IEEE-ANS-7-4.3.2-1982" then PubId.new(publisher: "ANSI/IEEE/ANS", number: "7", part: "4-3-2", year: "1982")
194
+ Renderer.new(publisher: "IEEE", number: "PC2", year: "2016", month: "01")
195
+ when "ANSI/IEEE-ANS-7-4.3.2-1982" then Renderer.new(publisher: "ANSI/IEEE/ANS", number: "7", part: "4-3-2", year: "1982")
108
196
  when "IEEE Unapproved Draft Std P802.1AB/REVD2.2, Dec 2007" # "IEEE P802.1AB/REV/D2.2.2007"
109
- PubId.new(publisher: "IEEE", std: true, number: "P802", part: "1AB", rev: "", draft: "2.2", year: "2007", month: "12")
197
+ Renderer.new(publisher: "IEEE", std: true, number: "P802", part: "1AB", rev: "", draft: "2.2", year: "2007", month: "12")
110
198
  when "International Standard ISO/IEC 8802-9: 1996(E) ANSI/IEEE Std 802.9, 1996 Edition"
111
- PubId.new(publisher: "ISO/IEC/IEEE", std: true, number: "802", part: "9", year: "1996")
199
+ Renderer.new(publisher: "ISO/IEC/IEEE", std: true, number: "802", part: "9", year: "1996")
112
200
  when "ISO/IEC13210: 1994 (E) ANSI/IEEE Std 1003.3-1991"
113
- PubId.new(publisher: "ISO/IEC/IEEE", number: "13210", year: "1994")
114
- when "J-STD-016-1995" then PubId.new(publisher: "IEEE", number: "016", year: "1995")
201
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "13210", year: "1994")
202
+ when "J-STD-016-1995" then Renderer.new(publisher: "IEEE", number: "016", year: "1995")
115
203
  when "Std 802.1ak-2007 (Amendment to IEEE Std 802.1QTM-2005)"
116
- PubId.new(publisher: "IEEE", std: true, number: "802", part: "1ak", year: "2007")
204
+ Renderer.new(publisher: "IEEE", std: true, number: "802", part: "1ak", year: "2007")
117
205
  when "IS0/IEC/IEEE 8802-11:2012/Amd.5:2015(E) (Adoption of IEEE Std 802.11af-2014)"
118
- PubId.new(publisher: "ISO/IEC/IEEE", number: "802", part: "11", year: "2012", amd: "5", year_amendment: "2015")
206
+ Renderer.new(publisher: "ISO/IEC/IEEE", number: "802", part: "11", year: "2012", amd: "5", year_amendment: "2015")
119
207
  when "National Electrical Safety Code, C2-2012 - Redline"
120
- PubId.new(publisher: "IEEE", number: "C2", year: "2012", redline: "true")
121
- when "National Electrical Safety Code, C2-2012" then PubId.new(publisher: "IEEE", number: "C2", year: "2012")
122
- when "2012 NESC Handbook, Seventh Edition" then PubId.new(publisher: "NESC", number: "HBK", year: "2012")
208
+ Renderer.new(publisher: "IEEE", number: "C2", year: "2012", redline: "true")
209
+ when "National Electrical Safety Code, C2-2012" then Renderer.new(publisher: "IEEE", number: "C2", year: "2012")
210
+ when "2012 NESC Handbook, Seventh Edition" then Renderer.new(publisher: "NESC", number: "HBK", year: "2012")
123
211
  when /^Amendment to IEEE Std 802\.11-2007 as amended by IEEE Std 802\.11k-2008/
124
- PubId.new(publisher: "IEEE", std: true, number: "802", part: "11u", year: "2007")
125
- when "Std 11073-10417-2009" then PubId.new(publisher: "IEEE", std: true, number: "11073", part: "10417", year: "2009")
126
- when "Nuclear EQ Sourcebook and Supplement" then PubId.new publisher: "IEEE", number: "7438946"
212
+ Renderer.new(publisher: "IEEE", std: true, number: "802", part: "11u", year: "2007")
213
+ when "Std 11073-10417-2009" then Renderer.new(publisher: "IEEE", std: true, number: "11073", part: "10417", year: "2009")
214
+ when "Nuclear EQ Sourcebook and Supplement" then Renderer.new publisher: "IEEE", number: "7438946"
127
215
 
128
216
  # drop all with <standard_id>0</standard_id>
129
217
  # when "IEEE Std P1671/D5, June 2006", "IEEE Std PC37.100.1/D8, Dec 2006",
@@ -137,12 +225,12 @@ module Relaton
137
225
 
138
226
  # publisher1, number1, part1, publisher2, number2, part2, draft, year
139
227
  when /^([A-Z\/]+)\s(\w+)[-.](\d+)\/(\w+)\s(\w+)[-.](\d+)_D([\d.]+),\s\w+\s(\d{4})/
140
- PubId.new([{ publisher: $1, number: $2, part: $3 },
228
+ Renderer.new([{ publisher: $1, number: $2, part: $3 },
141
229
  { publisher: $4, number: $5, part: $6, draft: dn($7), year: $8 }])
142
230
 
143
231
  # publisher1, number1, part1, number2, part2, draft, year, month
144
232
  when /^([A-Z\/]+)\s(\w+)[.-]([\w.-]+)\/(\w+)[.-]([[:alnum:].-]+)[\/_]D([\w.]+),\s(\w+)\s(\d{4})/
145
- PubId.new([{ publisher: $1, number: $2, part: sp($3) }, { number: $4, part: sp($5), draft: dn($6), year: $8, month: mn($7) }])
233
+ Renderer.new([{ publisher: $1, number: $2, part: sp($3) }, { number: $4, part: sp($5), draft: dn($6), year: $8, month: mn($7) }])
146
234
 
147
235
  # publisher, approval, number, part, corrigendum, draft, year
148
236
  when /^(?<publisher>[A-Z\/]+)#{APPROVAL}(?:\sDraft)?\sStd\s(?<number>\w+)\.(?<part>\d+)-\d{4}[^\/]*\/Cor\s?(?<corr>\d)\/(?<draft>D[\d\.]+),\s(?:\w+\s)?(?<year>\d{4})/o
@@ -154,7 +242,7 @@ module Relaton
154
242
 
155
243
  # publidsher1, number1, year1 publisher2, number2, draft, year2
156
244
  when /^([A-Z\/]+)\s(\w+)-(\d{4})\/([A-Z]+)\s([[:alnum:]]+)_D([\w.]+),\s(\d{4})/
157
- PubId.new([{ publisher: $1, number: $2, year: $3 }, { publisher: $4, number: $5, draft: dn($6), year: $7 }])
245
+ Renderer.new([{ publisher: $1, number: $2, year: $3 }, { publisher: $4, number: $5, draft: dn($6), year: $7 }])
158
246
 
159
247
  when /^(?<publisher>[A-Z\/]+)\s#{STAGE}\s(?<number>\w+)[.-](?<part>[[:alnum:].-]+)[\s\/_]ED(?<edition>[\w.]+),\s(?<month>\w+)\s(?<year>\d{4})/o
160
248
  create_pubid(Regexp.last_match)
@@ -163,20 +251,20 @@ module Relaton
163
251
  when /^(?<publisher1>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}\s(?<number1>\w+)\/(?<publisher2>[A-Z]+)\s(?<number2>[[:alnum:]]+)_D(?<draft>[\d\.]+),\s\w+\s(?<year>\d{4})/o,
164
252
  /^(?<publisher1>[A-Z\/]+)\s(?<number1>\w+)\sand\s(?<publisher2>[A-Z]+)(?:\sGuideline)?\s(?<number2>[[:alnum:]]+)\/D(?<draft>[\d\.]+),\s\w+\s(?<year>\d{4})/o
165
253
  nc = Regexp.last_match.named_captures
166
- PubId.new([{ publisher: nc["publisher1"], std: !!nc["std"], number: nc["number1"] },
254
+ Renderer.new([{ publisher: nc["publisher1"], std: !!nc["std"], number: nc["number1"] },
167
255
  { publisher: nc["publisher2"], number: nc["number2"], draft: dn(nc["draft"]), year: nc["year"] }])
168
256
 
169
257
  # publidsher1, number1, part, publisher2, number2, year
170
258
  when /^([A-Z\/]+)\s(\w+)\.(\d+)_(\w+)\s(\w+),\s(\d{4})/ # "#{$1} #{$2}-#{$3}/#{$4} #{$5}.#{$6}"
171
- PubId.new([{ publisher: $1, number: $2, part: $3 }, { publisher: $4, number: $5, year: $6 }])
259
+ Renderer.new([{ publisher: $1, number: $2, part: $3 }, { publisher: $4, number: $5, year: $6 }])
172
260
 
173
261
  # publisher, number1, part1, number2, part2, draft
174
262
  when /^([A-Z\/]+)\s(\w+)[.-](\d+)\/(\w+)\.(\d+)[\/_]D([\d.]+)/ # "#{$1} #{$2}-#{$3}/#{$4}-#{$5}/D#{$6}"
175
- PubId.new([{ publisher: $1, number: $2, part: $3 }, { number: $4, part: $5, draft: dn($6) }])
263
+ Renderer.new([{ publisher: $1, number: $2, part: $3 }, { number: $4, part: $5, draft: dn($6) }])
176
264
 
177
265
  # publidsher, number1, part1, number2, part2, year
178
266
  when /^([A-Z\/]+)\sStd\s(\w+)\.(\w+)\/(\w+)\.(\w+)\/INT\s\w+\s(\d{4})/
179
- PubId.new([{ publisher: $1, number: $2, part: $3 }, { number: $4, part: $5, year: $6 }])
267
+ Renderer.new([{ publisher: $1, number: $2, part: $3 }, { number: $4, part: $5, year: $6 }])
180
268
 
181
269
  # publisher, number, part, corrigendum, draft, year
182
270
  when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}\s(?<number>\w+)[.-](?<part>[\d-]+)\/Cor\s?(?<corr>\d)[\/_]D(?<draft>[\d\.]+),\s(?:\w+\s)?(?<year>\d{4})/o,
@@ -184,10 +272,12 @@ module Relaton
184
272
  /^(?<publisher>[A-Z\/]+)\s(?<number>\w+)\.(?<part>[[:alnum:].]+)[-_]Cor[\s-]?(?<corr>\d)\/D(?<draft>[\d.]+),?\s\w+\s(?<year>\d{4})/
185
273
  create_pubid(Regexp.last_match)
186
274
  when /^([A-Z\/]+)\s(\w+)\.(\d+)-\d{4}\/Cor(\d)-(\d{4})\/D([\d.]+)/ # "#{$1} #{$2}-#{$3}/Cor#{$4}/D#{$6}.#{$5}"
187
- PubId.new(publisher: $1, number: $2, part: $3, corr: $4, draft: dn($6), year: $5)
275
+ Renderer.new(publisher: $1, number: $2, part: $3, corr: $4, draft: dn($6), year: $5)
188
276
 
189
- # publisher, status, number, part, draft, year, month
190
- when /^(?<publisher>[A-Z\/]+)(?<status>\sActive)#{APPROV}(?:\sDraft)?#{STD}\s(?<number>\w+)[.-](?<part>[[:alnum:]\.]+)\s?[\/_]D(?<draft>[\w\.]+),?\s(?<month>\w+)(?:\s\d{1,2},)?\s?(?<year>\d{2,4})/o
277
+ # publisher, number, part, draft, year, month. The bare "Active" status
278
+ # word is matched but NOT captured — folding it into the id rendered a
279
+ # stray token and a double space (`IEEE Active Std ...`) pubid rejects.
280
+ when /^(?<publisher>[A-Z\/]+)(?:\sActive)#{APPROV}(?:\sDraft)?#{STD}\s(?<number>\w+)[.-](?<part>[[:alnum:]\.]+)\s?[\/_]D(?<draft>[\w\.]+),?\s(?<month>\w+)(?:\s\d{1,2},)?\s?(?<year>\d{2,4})/o
191
281
  create_pubid(Regexp.last_match)
192
282
 
193
283
  # publisher, approval, number, part, draft, year, month
@@ -246,11 +336,11 @@ module Relaton
246
336
 
247
337
  # number, part, draft, year, month
248
338
  when /(\w+)[.-]([[:alnum:].]+)[\/\s_]D([\d.]+)(?:,?\s|_)([[:alpha:]]+)[\s_]?(\d{4})/
249
- PubId.new(publisher: "IEEE", number: $1, part: sp($2), draft: dn($3), year: $5, month: mn($4))
339
+ Renderer.new(publisher: "IEEE", number: $1, part: sp($2), draft: dn($3), year: $5, month: mn($4))
250
340
 
251
341
  # number, corrigendum, draft, year, month
252
342
  when /^(\w+)-\d{4}[\/_]Cor\s?(\d)[\/_]D([\w.]+),\s(\w+)\s(\d{4})/
253
- PubId.new(publisher: "IEEE", number: $1, corr: $2, draft: dn($3), month: mn($4), year: $5)
343
+ Renderer.new(publisher: "IEEE", number: $1, corr: $2, draft: dn($3), month: mn($4), year: $5)
254
344
 
255
345
  # publisher, number, corrigendum, draft, year
256
346
  when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?\sStd\s(?<number>\w+)(?:-\d{4})?[\/_]Cor\s?(?<corr>\d)\/D(?<draft>[\d\.]+),\s\w+\s(?<year>\d{4})/o
@@ -258,7 +348,7 @@ module Relaton
258
348
 
259
349
  # publisher, number, part, rev, corrigendum, draft
260
350
  when /^([A-Z\/]+)\s(\w+)\.(\w+)-\d{4}-Rev\/Cor(\d)\/D([\d.]+)/
261
- PubId.new(publisher: $1, number: $2, part: $3, rev: "", corr: $4, draft: dn($5))
351
+ Renderer.new(publisher: $1, number: $2, part: $3, rev: "", corr: $4, draft: dn($5))
262
352
 
263
353
  # publisher, number, part, corrigendum, draft
264
354
  when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}\s(?<number>\w+)\.(?<part>[\w.]+)\/[Cc]or\s?(?<corr>\d)\/D(?<draft>[\w\.]+)/o,
@@ -362,7 +452,7 @@ module Relaton
362
452
  # publisher, number, edition, year
363
453
  when /^([A-Z\/]+)\s(\w+)\s(\w+)\sEdition,\s\w+\s(\d+)/,
364
454
  /^([A-Z\/]+)\s(\w+)[\/_]ED([\d.]+),\s(\d{4})/
365
- PubId.new(publisher: $1, number: $2, edition: en($3), year: $4)
455
+ Renderer.new(publisher: $1, number: $2, edition: en($3), year: $4)
366
456
 
367
457
  # publisher, number, part, conformance, draft
368
458
  when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}\s(?<number>\w+)\.(?<part>[[:alnum:].]+)[\/-]Conformance(?<conformance>\d+)[\/_]D(?<draft>[\w\.]+)/o
@@ -436,27 +526,35 @@ module Relaton
436
526
 
437
527
  # number, part, year
438
528
  when /^(\d{2})\sIRE\s(\w+)[\s.](\w+)/ # "IRE #{$2}-#{$3}.#{yn $1}"
439
- PubId.new(publisher: "IRE", number: $2, part: $3, year: yn($1))
440
- when /^(\w+)\.(\w+)-(|d{4})/ then PubId.new(publisher: "IEEE", number: $1, part: $2, year: $3)
529
+ Renderer.new(publisher: "IRE", number: $2, part: $3, year: yn($1))
530
+ when /^(\w+)\.(\w+)-(|d{4})/ then Renderer.new(publisher: "IEEE", number: $1, part: $2, year: $3)
441
531
 
442
532
  # number, year
443
- when /^(\w+)-(\d{4})\D/ then PubId.new(publisher: "IEEE", number: $1, year: $2)
533
+ when /^(\w+)-(\d{4})\D/ then Renderer.new(publisher: "IEEE", number: $1, year: $2)
444
534
 
445
- # publisher, number
446
- when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}(?:\sNo\.?)?\s(?<number>\w+)/o
535
+ # publisher, number. The number must have a digit: otherwise a title
536
+ # such as "A Call to Action ..." gives the id `A Call`.
537
+ when /^(?<publisher>[A-Z\/]+)#{APPROV}(?:\sDraft)?#{STD}(?:\sNo\.?)?\s(?<number>[[:alpha:]]*\d\w*)/o
447
538
  create_pubid(Regexp.last_match)
448
539
 
449
540
  else
450
- Util.warn %{Use stdnumber "#{stdnumber}" for normtitle "#{normtitle}"}
451
- PubId.new(publisher: "IEEE", srd: true, number: stdnumber)
541
+ # Last resort: fall back to the raw stdnumber. (#parse runs this for
542
+ # every doc as the faithfulness reference, so no warning here — an
543
+ # unparseable id surfaces downstream as a nil docnumber.) A record
544
+ # with no standard number (a white paper, a research document) has a
545
+ # category here, e.g. "White Paper". It gets no id, because all such
546
+ # records would otherwise share one id, and so one output file.
547
+ if stdnumber.to_s.match?(/\d/)
548
+ Renderer.new(publisher: "IEEE", number: stdnumber)
549
+ end
452
550
  end
453
- rescue ArgumentError => e
454
- e
551
+ rescue ArgumentError
552
+ nil
455
553
  end
456
554
 
457
555
  def create_pubid(regex_match)
458
556
  args = regex_match.named_captures
459
- PubId.new(
557
+ Renderer.new(
460
558
  publisher: args["publisher"] || "IEEE",
461
559
  std: !!args["std"],
462
560
  number: args["number"],
@@ -517,10 +615,19 @@ module Relaton
517
615
  def mn(month)
518
616
  return if month.nil?
519
617
 
520
- n = Date::ABBR_MONTHNAMES.index(month) || Date::MONTHNAMES.index(month)
521
- return month unless n
618
+ s = month.to_s.strip
619
+ return s.rjust(2, "0") if s.match?(/\A\d{1,2}\z/) # already numeric
522
620
 
523
- n.to_s.rjust 2, "0"
621
+ # Letters only — drops trailing day/garble digits (e.g. "Sep20" -> "sep").
622
+ key = s.downcase[/\A[a-z]+/]
623
+ return unless key
624
+
625
+ key = MONTH_TYPOS[key] || key
626
+ cap = key.capitalize
627
+ n = Date::ABBR_MONTHNAMES.index(cap) || Date::MONTHNAMES.index(cap)
628
+ # Genuine miss: omit the month (a date-less id parses; a name-suffixed
629
+ # one does not) rather than leak an unparseable name into the id.
630
+ n&.to_s&.rjust(2, "0")
524
631
  end
525
632
 
526
633
  #
@@ -542,6 +649,104 @@ module Relaton
542
649
  draftnum && draftnum.sub(/^\./, "").gsub("-", ".")
543
650
  end
544
651
 
652
+ # Internal fallback renderer. Turns the fields extracted by #parse_fallback
653
+ # into the canonical relaton id string that #parse hands to pubid — it is
654
+ # NOT a public identifier type (pubid's `::Pubid::Ieee::Identifier` is the
655
+ # identifier abstraction). Kept private because the fallback still needs to
656
+ # normalize the ~12% of normtitles pubid can't parse directly.
657
+ class Renderer
658
+ class Id
659
+ # Series IEEE registers as trademarks, so they take ® rather than ™.
660
+ # Mirrors pubid's rule (metanorma/pubid#322): the series is read off
661
+ # the *number*, with a leading project `P` stripped, so `P802.8` counts
662
+ # as 802 while a letter series like `C802.1` does not.
663
+ REGISTERED_SERIES = %w[802 8802 2030].freeze
664
+ # 8802 is the ISO-adopted form of 802 and carries ® on the number
665
+ # alone; every other registered series also needs IEEE as (co)publisher,
666
+ # so `AIEE Std No. 802` and `ANSI 802.1-1985` stay ™.
667
+ ISO_ADOPTED_SERIES = "8802".freeze
668
+
669
+ attr_reader :number, :publisher, :std, :stage, :part, :status, :approval,
670
+ :edition, :draft, :rev, :corr, :amd, :redline, :year, :month
671
+
672
+ def initialize(number:, **args) # rubocop:disable Metrics/AbcSize
673
+ @number = number
674
+ @publisher = args[:publisher]
675
+ @std = args[:std]
676
+ @stage = args[:stage]
677
+ @part = args[:part]
678
+ @status = args[:status]
679
+ @approval = args[:approval]
680
+ @edition = args[:edition]
681
+ @draft = args[:draft]
682
+ @rev = args[:rev]
683
+ @corr = args[:corr]
684
+ @amd = args[:amd]
685
+ @year = args[:year]
686
+ @month = args[:month]
687
+ @redline = args[:redline]
688
+ end
689
+
690
+ def to_s(trademark: false) # rubocop:disable Metrics/AbcSize
691
+ out = number
692
+ out = "Std #{out}" if std
693
+ out = "#{stage} #{out}" if stage
694
+ out = "#{approval} #{out}" if approval
695
+ out = "#{status} #{out}" if status
696
+ out = "#{publisher} #{out}" if publisher
697
+ out += ".#{part}" if part
698
+ out += trademark_symbol if trademark
699
+ out += edition_to_s + draft_to_s + rev_to_s + corr_to_s + amd_to_s
700
+ out + year_to_s + month_to_s + redline_to_s
701
+ end
702
+
703
+ # ® for a registered series, ™ otherwise. See REGISTERED_SERIES.
704
+ def trademark_symbol
705
+ series = number.to_s.sub(/\AP/, "")[/\A\d+/]
706
+ return "™" unless REGISTERED_SERIES.include?(series)
707
+ return "®" if series == ISO_ADOPTED_SERIES
708
+
709
+ publisher.to_s.split("/").include?("IEEE") ? "®" : "™"
710
+ end
711
+
712
+ def edition_to_s = edition ? "/E-#{edition}" : ""
713
+ def draft_to_s = draft ? "/D-#{draft}" : ""
714
+ def rev_to_s = rev ? "/R-#{rev}" : ""
715
+ def corr_to_s = corr ? "/Cor#{corr}" : ""
716
+ def amd_to_s = amd ? "/Amd #{amd}" : ""
717
+ def year_to_s = year ? "-#{year}" : ""
718
+ def month_to_s = month ? "-#{month}" : ""
719
+ def redline_to_s = redline ? " Redline" : ""
720
+ end
721
+
722
+ def initialize(pubid)
723
+ @pubid = (pubid.is_a?(Array) ? pubid : [pubid]).map { |id| Id.new(**id) }
724
+ end
725
+
726
+ # Full id string (all numbers joined). Used when the faithfulness guard
727
+ # keeps the bespoke id because pubid dropped a digit.
728
+ def to_s(trademark: false)
729
+ @pubid.map { |id| id.to_s(trademark: trademark) }.join("/")
730
+ end
731
+
732
+ # Canonical id string. For a dual-numbered id, the second number
733
+ # contributes only the suffix components the first one lacks.
734
+ def to_id # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
735
+ out = @pubid[0].to_s
736
+ if @pubid.size > 1
737
+ out += @pubid[1].edition_to_s if @pubid[0].edition.nil?
738
+ out += @pubid[1].draft_to_s if @pubid[0].draft.nil?
739
+ out += @pubid[1].rev_to_s if @pubid[0].rev.nil?
740
+ out += @pubid[1].corr_to_s if @pubid[0].corr.nil?
741
+ out += @pubid[1].amd_to_s if @pubid[0].amd.nil?
742
+ out += @pubid[1].year_to_s if @pubid[0].year.nil?
743
+ out += @pubid[1].month_to_s if @pubid[0].month.nil?
744
+ out += @pubid[1].redline_to_s unless @pubid[0].redline
745
+ end
746
+ out
747
+ end
748
+ end
749
+
545
750
  extend RawbibIdParser
546
751
  end
547
752
  end
data/lib/relaton/ieee.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "digest/md5"
2
2
  require "faraday"
3
3
  require "yaml"
4
+ require "pubid"
4
5
  require "relaton/index"
5
6
  require "relaton/bib"
6
7
  require_relative "version"
@@ -15,7 +16,7 @@ module Relaton
15
16
  module Ieee
16
17
  class Error < StandardError; end
17
18
 
18
- INDEXFILE = "index-v1".freeze
19
+ INDEXFILE = "index-v2".freeze
19
20
 
20
21
  # Returns hash of XML reammar
21
22
  # @return [String]