pubid 2.0.0 → 2.0.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/data/parg/adobe.json +1 -1
  3. data/data/parg/aiee.json +1 -1
  4. data/data/parg/amca.json +1 -1
  5. data/data/parg/ansi.json +1 -1
  6. data/data/parg/api.json +1 -1
  7. data/data/parg/ashrae.json +1 -1
  8. data/data/parg/asme.json +1 -1
  9. data/data/parg/astm.json +1 -1
  10. data/data/parg/bipm.json +1 -1
  11. data/data/parg/bsi.json +1 -1
  12. data/data/parg/calconnect.json +1 -1
  13. data/data/parg/ccsds.json +1 -1
  14. data/data/parg/cen_cenelec.json +1 -1
  15. data/data/parg/cie.json +1 -1
  16. data/data/parg/csa.json +1 -1
  17. data/data/parg/doi.json +1 -1
  18. data/data/parg/easc.json +1 -1
  19. data/data/parg/ecma.json +1 -1
  20. data/data/parg/etsi.json +1 -1
  21. data/data/parg/evs.json +1 -1
  22. data/data/parg/gb.json +1 -1
  23. data/data/parg/gost.json +1 -1
  24. data/data/parg/iala.json +1 -1
  25. data/data/parg/iana.json +1 -1
  26. data/data/parg/idf.json +1 -1
  27. data/data/parg/iec.json +1 -1
  28. data/data/parg/ieee.json +1 -29571
  29. data/data/parg/ietf.json +1 -1
  30. data/data/parg/iho.json +1 -0
  31. data/data/parg/ire.json +1 -1
  32. data/data/parg/isbn.json +1 -1
  33. data/data/parg/iso.json +1 -8510
  34. data/data/parg/itu.json +1 -1
  35. data/data/parg/jcgm.json +1 -1
  36. data/data/parg/jis.json +1 -1
  37. data/data/parg/nesc.json +1 -1
  38. data/data/parg/nist.json +1 -9588
  39. data/data/parg/oasis.json +1 -1
  40. data/data/parg/ogc.json +1 -1
  41. data/data/parg/oiml.json +1 -1
  42. data/data/parg/omg.json +1 -1
  43. data/data/parg/parg.json +1 -1
  44. data/data/parg/plateau.json +1 -1
  45. data/data/parg/sae.json +1 -1
  46. data/data/parg/tables/typed_stages.yaml +1 -0
  47. data/data/parg/tgpp.json +1 -1
  48. data/data/parg/un.json +1 -1
  49. data/data/parg/w3c.json +1 -1
  50. data/data/parg/xsf.json +1 -1
  51. data/lib/pubid/adobe/identifier.rb +1 -1
  52. data/lib/pubid/adobe/parser.rb +2 -113
  53. data/lib/pubid/amca/identifiers/base.rb +1 -1
  54. data/lib/pubid/amca/parser.rb +1 -145
  55. data/lib/pubid/ansi/identifier.rb +1 -1
  56. data/lib/pubid/ansi/parser.rb +1 -82
  57. data/lib/pubid/api/builder.rb +32 -1
  58. data/lib/pubid/api/identifier.rb +1 -1
  59. data/lib/pubid/api/parser.rb +1 -131
  60. data/lib/pubid/ashrae/identifiers/base.rb +1 -1
  61. data/lib/pubid/ashrae/parser.rb +3 -710
  62. data/lib/pubid/asme/builder.rb +6 -4
  63. data/lib/pubid/asme/identifier.rb +1 -2
  64. data/lib/pubid/asme/parser.rb +1 -328
  65. data/lib/pubid/astm/builder.rb +12 -3
  66. data/lib/pubid/astm/identifier.rb +1 -2
  67. data/lib/pubid/astm/parser.rb +1 -227
  68. data/lib/pubid/bipm/identifier.rb +8 -1
  69. data/lib/pubid/bipm/parser.rb +2 -224
  70. data/lib/pubid/bsi/builder.rb +2 -4
  71. data/lib/pubid/bsi/parser.rb +1 -666
  72. data/lib/pubid/bsi/single_identifier.rb +38 -1
  73. data/lib/pubid/calconnect/identifier.rb +1 -1
  74. data/lib/pubid/calconnect/parser.rb +2 -40
  75. data/lib/pubid/ccsds/identifier.rb +1 -1
  76. data/lib/pubid/ccsds/parser.rb +1 -66
  77. data/lib/pubid/cen_cenelec/identifier.rb +16 -1
  78. data/lib/pubid/cen_cenelec/parser.rb +3 -136
  79. data/lib/pubid/cie/identifier.rb +1 -1
  80. data/lib/pubid/cie/parser.rb +3 -378
  81. data/lib/pubid/conformance.rb +1 -1
  82. data/lib/pubid/csa/builder.rb +41 -18
  83. data/lib/pubid/csa/identifier.rb +12 -4
  84. data/lib/pubid/csa/identifiers/amendment.rb +28 -0
  85. data/lib/pubid/csa/identifiers.rb +1 -0
  86. data/lib/pubid/csa/parser.rb +16 -397
  87. data/lib/pubid/doi/identifier.rb +1 -1
  88. data/lib/pubid/doi/parser.rb +2 -37
  89. data/lib/pubid/easc/builder.rb +1 -1
  90. data/lib/pubid/easc/identifier.rb +1 -1
  91. data/lib/pubid/easc/parser.rb +2 -70
  92. data/lib/pubid/ecma/CLAUDE.md +8 -1
  93. data/lib/pubid/ecma/identifier.rb +13 -8
  94. data/lib/pubid/ecma/parser.rb +2 -54
  95. data/lib/pubid/ecma/renderer.rb +3 -7
  96. data/lib/pubid/errors.rb +18 -13
  97. data/lib/pubid/etsi/builder.rb +8 -5
  98. data/lib/pubid/etsi/identifiers/base.rb +1 -1
  99. data/lib/pubid/etsi/parser.rb +1 -132
  100. data/lib/pubid/evs/identifier.rb +7 -0
  101. data/lib/pubid/evs/parser.rb +1 -8
  102. data/lib/pubid/evs.rb +1 -1
  103. data/lib/pubid/gb/identifier.rb +7 -1
  104. data/lib/pubid/gb/parser.rb +2 -51
  105. data/lib/pubid/gost/identifier.rb +9 -1
  106. data/lib/pubid/gost/parser.rb +4 -81
  107. data/lib/pubid/iala/parser.rb +2 -121
  108. data/lib/pubid/iana/identifier.rb +1 -1
  109. data/lib/pubid/iana/parser.rb +2 -24
  110. data/lib/pubid/identifier.rb +78 -1
  111. data/lib/pubid/idf/builder.rb +42 -0
  112. data/lib/pubid/idf/identifier.rb +1 -1
  113. data/lib/pubid/idf/parser.rb +1 -137
  114. data/lib/pubid/idf.rb +1 -2
  115. data/lib/pubid/iec/builder.rb +158 -50
  116. data/lib/pubid/iec/identifier.rb +1 -1
  117. data/lib/pubid/iec/parser.rb +3 -430
  118. data/lib/pubid/ieee/aiee/identifier.rb +2 -1
  119. data/lib/pubid/ieee/aiee.rb +0 -1
  120. data/lib/pubid/ieee/builder.rb +2 -2
  121. data/lib/pubid/ieee/identifiers/base.rb +1 -1
  122. data/lib/pubid/ieee/ire/identifier.rb +2 -1
  123. data/lib/pubid/ieee/ire.rb +0 -1
  124. data/lib/pubid/ieee/nesc.rb +0 -1
  125. data/lib/pubid/ieee/parser.rb +1 -1257
  126. data/lib/pubid/ietf/identifiers/base.rb +17 -1
  127. data/lib/pubid/ietf/parser.rb +2 -47
  128. data/lib/pubid/ietf/renderer.rb +17 -2
  129. data/lib/pubid/iho/CLAUDE.md +89 -0
  130. data/lib/pubid/iho/builder.rb +4 -1
  131. data/lib/pubid/iho/identifiers/base.rb +28 -2
  132. data/lib/pubid/iho/renderer.rb +8 -0
  133. data/lib/pubid/iho/urn_generator.rb +11 -1
  134. data/lib/pubid/iho/urn_parser.rb +21 -11
  135. data/lib/pubid/iho.rb +0 -1
  136. data/lib/pubid/isbn/identifier.rb +1 -1
  137. data/lib/pubid/isbn/parser.rb +2 -31
  138. data/lib/pubid/iso/builder.rb +1 -1
  139. data/lib/pubid/iso/identifiers/directives.rb +6 -3
  140. data/lib/pubid/iso/identifiers/guide.rb +6 -3
  141. data/lib/pubid/iso/identifiers/international_standard.rb +3 -1
  142. data/lib/pubid/iso/identifiers/international_workshop_agreement.rb +6 -3
  143. data/lib/pubid/iso/normalizer.rb +1 -1
  144. data/lib/pubid/iso/parser.rb +1 -539
  145. data/lib/pubid/iso/supplement_identifier.rb +6 -3
  146. data/lib/pubid/iso/utilities.rb +4 -5
  147. data/lib/pubid/iso.rb +1 -19
  148. data/lib/pubid/itu/builder.rb +36 -20
  149. data/lib/pubid/itu/identifiers/base.rb +15 -2
  150. data/lib/pubid/itu/parser.rb +1 -775
  151. data/lib/pubid/jcgm/builder.rb +35 -0
  152. data/lib/pubid/jcgm/parser.rb +1 -151
  153. data/lib/pubid/jcgm.rb +1 -2
  154. data/lib/pubid/jis/builder.rb +18 -29
  155. data/lib/pubid/jis/identifier.rb +1 -1
  156. data/lib/pubid/jis/parser.rb +1 -128
  157. data/lib/pubid/nist/builder.rb +5 -1
  158. data/lib/pubid/nist/caster.rb +13 -3
  159. data/lib/pubid/nist/identifiers/base.rb +37 -2
  160. data/lib/pubid/nist/identifiers/circular.rb +2 -2
  161. data/lib/pubid/nist/identifiers/circular_supplement.rb +2 -2
  162. data/lib/pubid/nist/identifiers/commercial_standards_monthly.rb +2 -2
  163. data/lib/pubid/nist/identifiers/crpl_report.rb +2 -2
  164. data/lib/pubid/nist/identifiers/handbook.rb +2 -2
  165. data/lib/pubid/nist/identifiers/internal_report.rb +2 -2
  166. data/lib/pubid/nist/identifiers/miscellaneous_publication.rb +2 -2
  167. data/lib/pubid/nist/identifiers/monograph.rb +2 -2
  168. data/lib/pubid/nist/identifiers/report.rb +2 -2
  169. data/lib/pubid/nist/parser.rb +19 -775
  170. data/lib/pubid/nist/router.rb +4 -1
  171. data/lib/pubid/nist/supplement_identifier.rb +2 -2
  172. data/lib/pubid/oasis/identifier.rb +1 -1
  173. data/lib/pubid/oasis/parser.rb +2 -16
  174. data/lib/pubid/ogc/identifier.rb +1 -1
  175. data/lib/pubid/ogc/parser.rb +2 -26
  176. data/lib/pubid/oiml/identifiers/certification_system.rb +7 -0
  177. data/lib/pubid/oiml/identifiers/dual_published.rb +2 -2
  178. data/lib/pubid/oiml/parser.rb +1 -303
  179. data/lib/pubid/oiml.rb +1 -2
  180. data/lib/pubid/omg/identifier.rb +6 -1
  181. data/lib/pubid/omg/parser.rb +2 -76
  182. data/lib/pubid/parg/artifact.rb +22 -3
  183. data/lib/pubid/parg/model.rb +98 -0
  184. data/lib/pubid/parg.rb +1 -0
  185. data/lib/pubid/parser.rb +5 -4
  186. data/lib/pubid/parsers/mr_string.rb +1 -1
  187. data/lib/pubid/plateau/parser.rb +1 -66
  188. data/lib/pubid/plateau.rb +1 -2
  189. data/lib/pubid/renderers/directives_renderer.rb +1 -1
  190. data/lib/pubid/renderers/iwa_renderer.rb +1 -1
  191. data/lib/pubid/renderers/publisher_stripper.rb +82 -0
  192. data/lib/pubid/renderers/supplement_renderer.rb +1 -1
  193. data/lib/pubid/renderers.rb +1 -0
  194. data/lib/pubid/sae/identifiers/base.rb +1 -1
  195. data/lib/pubid/sae/parser.rb +1 -48
  196. data/lib/pubid/tgpp/identifier.rb +1 -1
  197. data/lib/pubid/tgpp/parser.rb +2 -59
  198. data/lib/pubid/un/identifier.rb +1 -1
  199. data/lib/pubid/un/parser.rb +1 -18
  200. data/lib/pubid/version.rb +1 -1
  201. data/lib/pubid/w3c/identifier.rb +1 -1
  202. data/lib/pubid/w3c/parser.rb +2 -27
  203. data/lib/pubid/xsf/identifier.rb +11 -7
  204. data/lib/pubid/xsf/parser.rb +3 -31
  205. data/lib/pubid/xsf/renderer.rb +2 -4
  206. data/lib/pubid.rb +8 -9
  207. metadata +15 -25
  208. data/lib/pubid/ieee/aiee/parser.rb +0 -130
  209. data/lib/pubid/ieee/ire/parser.rb +0 -109
  210. data/lib/pubid/ieee/nesc/parser.rb +0 -155
  211. data/lib/pubid/iho/parser.rb +0 -68
  212. data/lib/pubid/parser/common_parse_methods.rb +0 -13
  213. data/lib/pubid/parser/common_parse_rules.rb +0 -56
  214. data/lib/pubid/parser/grammar.rb +0 -96
@@ -1,237 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "parslet"
4
-
5
3
  module Pubid
6
4
  module Bipm
7
- # Parslet grammar for the four BIPM identifier families. The root branches
5
+ # Grammar for the four BIPM identifier families. The root branches
8
6
  # by leading token / shape; each alternative is wrapped in a distinct key
9
7
  # (:committee_short, :meeting_en, …) so the Builder can dispatch on the
10
8
  # matched branch without re-inspecting the string.
11
9
  #
12
10
  # Group and type-word alternations are built from the shared vocabularies on
13
11
  # {Identifier} (sorted longest-first so e.g. "CCTF" is tried before "CCT").
14
- class Parser < ::Pubid::Parser::Grammar
15
- # --- primitives ---
16
- rule(:space) { str(" ") }
17
- rule(:digits) { match["0-9"].repeat(1) }
18
- rule(:alnum) { match["0-9A-Za-z"].repeat(1) }
19
- # Number, preserved as a string: digits with optional hyphenated parts.
20
- rule(:number) do
21
- (digits >> (str("-") >> digits).repeat).as(:number)
22
- end
23
- rule(:year) { match["0-9"].repeat(4, 4).as(:year) }
24
- # "E"/"F" as BIPM prints them, plus the two-letter codes consumer
25
- # references use (longest first, so "EN" is never read as a bare "E").
26
- rule(:lang) do
27
- (str("EN") | str("FR") | match["EF"]).as(:language)
28
- end
29
- # "(YYYY)" or "(YYYY, E)"
30
- rule(:year_paren) do
31
- str("(") >> year >> (str(", ") >> lang).maybe >> str(")")
32
- end
33
- rule(:year_paren_nolang) { str("(") >> year >> str(")") }
34
-
35
- # Longest-first alternation over a list of literal tokens, so a token that
36
- # is a prefix of another (e.g. "CCT" of "CCTF") never shadows it.
37
- def alternation(tokens)
38
- tokens.sort_by { |t| -t.length }.map { |t| str(t) }.reduce(:|)
39
- end
40
-
41
- rule(:group) { alternation(Identifier::PARSEABLE_GROUPS).as(:group) }
42
-
43
- rule(:type_abbrev) do
44
- alternation(Identifier::TYPE_CODES).as(:type_word)
45
- end
46
- rule(:type_name_en) do
47
- names = Identifier::TYPE_NAME_EN.values.uniq + ["Declaration"]
48
- alternation(names).as(:type_word)
49
- end
50
- rule(:type_name_fr) do
51
- names = Identifier::TYPE_NAME_FR.values.uniq + ["Déclaration"]
52
- alternation(names).as(:type_word)
53
- end
54
- rule(:connective) { str("de la") | str("du") }
55
- rule(:ordinal) { str("st") | str("nd") | str("rd") | str("th") }
56
- # The word naming a meeting in French. BIPM prints it lowercase; a
57
- # consumer reference capitalizes it, as relaton's `Id::TYPES` does.
58
- rule(:meeting_word_fr) { str("Réunion") | str("réunion") }
59
-
60
- # --- committee documents ---
61
- # The trailing "(YYYY)" date is optional (`.maybe`) so a partial reference
62
- # that omits it — e.g. "CCTF REC 2" — still parses, leaving :year absent.
63
- rule(:committee_short) do
64
- (group >> space >> type_abbrev >>
65
- (space >> number).maybe >> (space >> year_paren).maybe)
66
- .as(:committee_short)
67
- end
68
- rule(:committee_long_en) do
69
- (group >> space >> type_name_en >>
70
- (space >> number).maybe >> (space >> year_paren_nolang).maybe)
71
- .as(:committee_long_en)
72
- end
73
- rule(:committee_long_fr) do
74
- (type_name_fr >> (space >> number).maybe >> space >>
75
- connective >> space >> group >> (space >> year_paren_nolang).maybe)
76
- .as(:committee_long_fr)
77
- end
78
- # Loose consumer form: a French type name in the English (group-leading)
79
- # word order, e.g. "CIPM Décision 101-1 (2012)". BIPM never prints this,
80
- # so it renders back as the canonical "Décision 101-1 du CIPM (2012)".
81
- # Tried after `committee_long_en`, which is what keeps the words both
82
- # languages share ("Action", "Statement") English.
83
- rule(:committee_group_fr) do
84
- (group >> space >> type_name_fr >>
85
- (space >> number).maybe >> (space >> year_paren_nolang).maybe)
86
- .as(:committee_long_fr)
87
- end
88
-
89
- # Bare MRA-interpretation form: a group directly followed by a document
90
- # number with no type word (e.g. "CIPM 2005-06"). Tried last, so typed
91
- # committee documents and meetings always win; only fires when a digit
92
- # follows the group and the string is fully consumed.
93
- rule(:committee_bare) do
94
- (group >> space >> number >> (space >> year_paren).maybe)
95
- .as(:committee_bare)
96
- end
97
-
98
- # --- meetings ---
99
- # Canonical: "<group> <n><ordinal> Meeting [(YYYY)]". The second branch is
100
- # the loose consumer word order "<group> Meeting <n>", which relaton's
101
- # bespoke grammar accepts; both build the same tree, so the loose form
102
- # renders back in the canonical spelling.
103
- rule(:meeting_en) do
104
- ((group >> space >> number >> ordinal >> space >> str("Meeting") >>
105
- (space >> year_paren).maybe) |
106
- (group >> space >> str("Meeting") >> space >> number >>
107
- (space >> year_paren).maybe)).as(:meeting_en)
108
- end
109
- # Canonical: "<group> <n><sup>e</sup> réunion [(YYYY)]". The second and
110
- # third branches are the loose consumer spellings — the plain "e" ordinal
111
- # and the "<group> Réunion <n>" word order.
112
- rule(:meeting_fr) do
113
- ((group >> space >> number >> str("<sup>e</sup>") >> space >>
114
- str("réunion") >> (space >> year_paren).maybe) |
115
- (group >> space >> number >> str("e") >> space >> meeting_word_fr >>
116
- (space >> year_paren).maybe) |
117
- (group >> space >> meeting_word_fr >> space >> number >>
118
- (space >> year_paren).maybe)).as(:meeting_fr)
119
- end
120
-
121
- # --- Metrologia journal ---
122
- rule(:metrologia) do
123
- (str("Metrologia") >>
124
- (space >> digits.as(:volume) >>
125
- (space >> alnum.as(:issue) >>
126
- (space >> alnum.as(:article)).maybe).maybe).maybe).as(:metrologia)
127
- end
128
-
129
- # --- SI Brochure ---
130
- rule(:edition) { (digits >> str("e")).as(:edition) }
131
- rule(:version) { (str("v") >> match["0-9."].repeat(1)).as(:version) }
132
- rule(:years) { (digits >> (str("/") >> digits).maybe).as(:years) }
133
- # The "BIPM " prefix is optional, as it is on the variant and section
134
- # rules: `si-brochure.yaml` stores the docnumber WITHOUT it, and
135
- # `Relaton::Bipm::Bibliography.search` strips a leading "BIPM " before it
136
- # ever reaches pubid. Either spelling renders back with the prefix.
137
- rule(:si_brochure) do
138
- ((str("BIPM SI Brochure") | str("SI Brochure")) >> space >>
139
- (str("sur le SI") >> space).maybe >>
140
- edition >> space >> version >> space >>
141
- str("(") >> years >> str(", ") >> lang >> str(")")).as(:si_brochure)
142
- end
143
-
144
- # --- SI Brochure appendices / derived products ---
145
- # The full primary-docidentifier content the relaton crawler indexes by,
146
- # e.g. "BIPM SI Brochure Appendix 3" / "…Concise" / "…FAQ". The bare
147
- # "SI Brochure Appendix 3" docnumber form is accepted too (rendered back
148
- # with the "BIPM " prefix, matching the base SI Brochure record).
149
- rule(:brochure_variant) do
150
- ((str("Appendix") >> space >> digits) | str("Concise") | str("FAQ"))
151
- .as(:variant)
152
- end
153
- rule(:si_brochure_variant) do
154
- ((str("BIPM SI Brochure") | str("SI Brochure")) >> space >>
155
- brochure_variant).as(:si_brochure_variant)
156
- end
157
-
158
- # Bare and sectioned SI Brochure references: "SI Brochure",
159
- # "SI Brochure Part 1". Neither names an edition, so both are partial
160
- # references whose `number` stays nil and which wildcard every edition —
161
- # the same reading a date-less "CCTF REC 2" gets. "Part N" points at a
162
- # section INSIDE the brochure, not a separate record, so it rides in the
163
- # shared `part` attribute and stays out of the index key, exactly as the
164
- # MEP/guide "Part N.M" tail does. Listed after the edition and variant
165
- # rules for readability, not for correctness: Parslet threads
166
- # `consume_all` down through an alternation, so an alternative that
167
- # matches only a PREFIX ("SI Brochure" of "SI Brochure Concise") counts
168
- # as a failure and the next one is tried whatever the order. Order only
169
- # decides between two alternatives that BOTH consume the whole input.
170
- rule(:si_brochure_section) do
171
- ((str("BIPM SI Brochure") | str("SI Brochure")) >>
172
- (space >> str("Part") >> space >> digits.as(:part)).maybe)
173
- .as(:si_brochure_section)
174
- end
175
-
176
- # Shared "Appendix N [Annex N] Part N[.M]" tail carried by the full
177
- # docidentifier content of MEPs and CC guides (the "Appendix 2 Part 1.1"
178
- # or "Appendix 2 Annex 2 Part 1" suffix on "BIPM SI MEP …" etc.).
179
- rule(:appendix_part) do
180
- str("Appendix") >> space >> digits.as(:appendix) >>
181
- (space >> str("Annex") >> space >> digits.as(:annex)).maybe >>
182
- space >> str("Part") >> space >>
183
- (digits >> (str(".") >> digits).maybe).as(:part)
184
- end
185
-
186
- # --- Mises en pratique (MEP) ---
187
- # Two index-relevant spellings: the short docnumber ("SI MEP S1",
188
- # "Rapport BIPM-2019/05") and the full "BIPM …" primary-docidentifier
189
- # content the crawler actually keys on ("BIPM SI MEP S1 Appendix 2 Part
190
- # 1.1"). The renderer reproduces whichever the identifier carries.
191
- rule(:mep_code) { match["0-9A-Za-z"].repeat(1).as(:mep_code) }
192
- rule(:report_code) do
193
- (str("BIPM-") >> digits >> str("/") >> digits).as(:report_code)
194
- end
195
- rule(:mep_body) do
196
- (str("SI MEP") >> space >> mep_code) |
197
- (str("Rapport") >> space >> report_code)
198
- end
199
- rule(:mep) do
200
- ((str("BIPM") >> space >> mep_body >> space >> appendix_part) |
201
- mep_body).as(:mep)
202
- end
203
-
204
- # --- Consultative-Committee guides ---
205
- # "<committee>-GD-<kind>-<number>" (e.g. "CCL-GD-MeP-1"), and its full
206
- # "BIPM … Appendix 2 Part 2.2" content form. <kind> is "MeP" (mise en
207
- # pratique) or "RSI" (réalisation du SI). Reuses the shared `group`
208
- # (committee) and `number` (trailing sequence).
209
- rule(:guide_kind) { (str("MeP") | str("RSI")).as(:guide_kind) }
210
- rule(:guide_body) do
211
- group >> str("-GD-") >> guide_kind >> str("-") >> digits.as(:number)
212
- end
213
- rule(:guide) do
214
- ((str("BIPM") >> space >> guide_body >> space >> appendix_part) |
215
- guide_body).as(:guide)
216
- end
217
-
218
- # After a leading group token, the shape after the first space decides:
219
- # a digit → meeting; a type word → committee.
220
- rule(:group_leading) do
221
- meeting_en | meeting_fr | committee_short | committee_long_en |
222
- committee_group_fr | committee_bare
223
- end
224
-
225
- rule(:identifier) do
226
- metrologia | si_brochure | si_brochure_variant | si_brochure_section |
227
- mep | guide | committee_long_fr | group_leading
228
- end
229
-
230
- root(:identifier)
231
-
232
- def self.parse(input)
233
- new.parse(input)
234
- end
12
+ class Parser
235
13
  end
236
14
  end
237
15
  end
@@ -684,8 +684,7 @@ module Pubid
684
684
  # Handle nested hash from parser (when using .as with alternatives)
685
685
  data = data[:supplement_document] if data[:supplement_document].is_a?(Hash)
686
686
 
687
- # Extract values from nested hashes (parser returns {:number => {:number => "1000"}})
688
- number_val = data[:number][:number] if data[:number].is_a?(Hash)
687
+ number_val = data[:number].to_s if data[:number]
689
688
  iteration_val = data[:iteration][:iteration][0][:iteration] if data[:iteration].is_a?(Hash) && data[:iteration][:iteration].is_a?(Array) && data[:iteration][:iteration].any?
690
689
  iteration_val = nil if iteration_val.is_a?(String) && iteration_val.empty?
691
690
  parts_val = data[:parts][:parts] if data[:parts].is_a?(Hash)
@@ -734,8 +733,7 @@ module Pubid
734
733
  end
735
734
 
736
735
  def build_addendum_document(data)
737
- # Extract values from nested hashes (parser returns {:number => {:number => "1000"}})
738
- number_val = data[:number][:number] if data[:number].is_a?(Hash)
736
+ number_val = data[:number].to_s if data[:number]
739
737
  iteration_val = data[:iteration][:iteration][0][:iteration] if data[:iteration].is_a?(Hash) && data[:iteration][:iteration].is_a?(Array) && data[:iteration][:iteration].any?
740
738
  iteration_val = nil if iteration_val.is_a?(String) && iteration_val.empty?
741
739
  parts_val = data[:parts][:parts] if data[:parts].is_a?(Hash)