pubid 2.0.2 → 2.0.3

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/data/ieee/update_codes.yaml +2 -2
  3. data/data/parg/aiee.json +1 -1
  4. data/data/parg/aiee.parg +99 -9
  5. data/data/parg/iala.json +1 -1
  6. data/data/parg/ieee.json +1 -1
  7. data/data/parg/ire.json +1 -1
  8. data/data/parg/ire.parg +51 -12
  9. data/data/parg/iso.json +1 -1
  10. data/data/parg/iso.parg +751 -0
  11. data/data/parg/jis.json +1 -1
  12. data/data/parg/nesc.json +1 -1
  13. data/data/parg/nesc.parg +97 -12
  14. data/data/parg/parg.json +1 -1
  15. data/lib/pubid/iala/builder.rb +48 -39
  16. data/lib/pubid/iala/identifier.rb +1 -1
  17. data/lib/pubid/ieee/CLAUDE.md +2 -0
  18. data/lib/pubid/ieee/aiee/identifier.rb +1 -1
  19. data/lib/pubid/ieee/builder.rb +175 -28
  20. data/lib/pubid/ieee/components/code.rb +46 -7
  21. data/lib/pubid/ieee/identifiers/base.rb +4 -1
  22. data/lib/pubid/ieee/identifiers/joint_development.rb +7 -3
  23. data/lib/pubid/ieee/ire/identifier.rb +1 -1
  24. data/lib/pubid/ieee/nesc/builder.rb +1 -1
  25. data/lib/pubid/ieee/project_renderer.rb +5 -1
  26. data/lib/pubid/ieee/renderer.rb +4 -2
  27. data/lib/pubid/ieee/urn_generator.rb +4 -1
  28. data/lib/pubid/iho/CLAUDE.md +15 -6
  29. data/lib/pubid/iho/urn_generator.rb +9 -6
  30. data/lib/pubid/iho/urn_parser.rb +43 -40
  31. data/lib/pubid/iso/CLAUDE.md +66 -0
  32. data/lib/pubid/iso/builder.rb +228 -14
  33. data/lib/pubid/iso/identifier.rb +22 -12
  34. data/lib/pubid/iso/normalizer.rb +5 -4
  35. data/lib/pubid/iso/urn_parser.rb +13 -8
  36. data/lib/pubid/jis/CLAUDE.md +36 -0
  37. data/lib/pubid/jis/builder.rb +12 -12
  38. data/lib/pubid/jis/identifier.rb +11 -1
  39. data/lib/pubid/jis/identifiers/welding_engineering_standard.rb +35 -0
  40. data/lib/pubid/jis/identifiers.rb +2 -0
  41. data/lib/pubid/jis/renderer.rb +1 -1
  42. data/lib/pubid/jis/supplement_identifier.rb +5 -5
  43. data/lib/pubid/jis/urn_parser.rb +2 -1
  44. data/lib/pubid/jis.rb +3 -2
  45. data/lib/pubid/version.rb +1 -1
  46. metadata +5 -2
@@ -0,0 +1,751 @@
1
+ # Pubid ISO flavor — port of lib/pubid/iso/parser.rb (pubid monorepo).
2
+ #
3
+ # Scope: the full identifier root — NSB stage prefixes (FprISO, WD/ISO),
4
+ # TC documents (ISO/TC 184/SC 4/WG 3 N 123), directives (plain,
5
+ # supplement, bundled "DIR 1 + IEC SUP"), JCGM, legacy ISO/R forms
6
+ # (including supplements), the three-level supplement chains
7
+ # (/Amd/../Cor/../Amd..), the copublisher identifier spine, and the
8
+ # joint "ISO x|IDF y" form. The IDF grammar is imported via `use idf`
9
+ # so the artifact exposes the idf.identifier entry beside identifier;
10
+ # the joint's IDF side itself is spelled with the inlined idf_* rules
11
+ # below, whose captures carry the idf_ prefix so they never collide
12
+ # with the ISO ones and can bind as scalars.
13
+ #
14
+ # Edition 2 with typed model bindings: every capture the builder
15
+ # consumes is bound. Supplement layers capture into position-scoped
16
+ # names (supp_* on the first supplement, supp2_* on the second,
17
+ # supp3_* on the third, isor_supp_* on an ISO/R supplement,
18
+ # dsupp_*/bs1_/bs2_/bs3_ on directive supplements, idf_*/idf_supp_* on the
19
+ # joint's IDF side): captures are collected globally by name, so shared
20
+ # names across layers would collapse the layer's number/date onto the
21
+ # base's. The base document's own edition is base_edition wherever a
22
+ # supplement layer's third_part can carry its own edition.
23
+
24
+ use idf
25
+
26
+ grammar PubidIso version "0.4.0" edition 2 {
27
+
28
+ # ---- lexical (pubid/parser/common_parse_rules.rb + ISO override) ----
29
+ digit = %x30-39
30
+ digits = 1*digit
31
+ letter = %x41-5A / %x61-7A
32
+ lower = %x61-7A
33
+ word_digit = %x30-39 / %x41-5A / %x61-7A
34
+ word_char = %x30-39 / %x41-5A / %x61-7A / %x5F
35
+ space = " "
36
+ dash = "-" / "‑" / "‐"
37
+ dot = "."
38
+ slash = "/"
39
+ colon = ":"
40
+
41
+ century = "19" / "20"
42
+ year_digits = century 2*digit !digit
43
+ month_digits = 2*digit
44
+ day_digits = 2*digit
45
+
46
+ # ---- stage-abbreviation vocabularies (uncaptured; capture sites
47
+ # inline the alt so the capture holds one scalar span) ----
48
+ typed_stage_abbrev = alt from_table "typed_stages" column "abbr"
49
+ supp_stage_abbrev = alt from_table "typed_stages_supplements" column "abbr"
50
+ directives_stage_abbrev = alt from_table "directives_typed_stages" column "abbr"
51
+ directives_supp_stage_abbrev = alt from_table "directives_supplements_typed_stages" column "abbr"
52
+ idf_stage_abbrev = alt from_table "idf_typed_stages" column "abbr"
53
+ idf_supp_stage_abbrev = alt from_table "idf_typed_stages_supplements" column "abbr"
54
+
55
+ # ---- publishers and copublishers ----
56
+ ## The leading organization token. Copublishers follow after a slash;
57
+ ## the whole tail captures as ONE scalar span ("/IEC/IEEE") because
58
+ ## the engine's array-group harvest pads non-firing reps with empty
59
+ ## hashes (parsanol-ruby#399) — the builder splits the span.
60
+ publisher = ("ISO" / "IEC") as publisher
61
+ organization = alt from_table "organizations" column "name"
62
+ ## At least one item: the optional around [copublishers] keeps the
63
+ ## key absent when the identifier has no copublisher (a zero-width
64
+ ## capture would bind an empty array, not a scalar span).
65
+ copublishers = {
66
+ (
67
+ (slash [space] (alt from_table "organizations" column "name"))
68
+ *(slash [space] (alt from_table "organizations" column "name"))
69
+ ) as copublishers
70
+ }
71
+ prefix_sole_publisher = publisher
72
+ prefix_with_copublishers = prefix_sole_publisher [space] [copublishers]
73
+
74
+ # ---- number and parts ----
75
+ ## number/part bodies inlined at every capture site so each capture
76
+ ## holds one scalar span; part_legacy's negative lookahead keeps a
77
+ ## "/Amd"-style tail from being read as a legacy slash part.
78
+ part_modern_body = dash [space] 1*word_digit *(dash 1*word_digit)
79
+ part_legacy_body = slash [space] !supp_stage_abbrev 1*word_digit
80
+ number_with_part = {
81
+ (
82
+ (1*5digit)
83
+ [
84
+ (
85
+ (dash [space] 1*word_digit *(dash 1*word_digit))
86
+ / (slash [space] !supp_stage_abbrev 1*word_digit)
87
+ )
88
+ ]
89
+ ) as number_with_part
90
+ }
91
+
92
+ # ---- stage iteration: "ISO 11243.1" ----
93
+ stage_iteration = dot digit as stage_iteration
94
+
95
+ # ---- date: ":2005-02", ":--", ":—", legacy dash form ----
96
+ date_core = (("--" / "—")) as undated_marker / (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as date
97
+ date = (colon / dash) [date_core]
98
+
99
+ second_part = {
100
+ number_with_part
101
+ [stage_iteration]
102
+ [[space] date]
103
+ }
104
+
105
+ # ---- typed stages ----
106
+ type_with_stage = {
107
+ (
108
+ (alt from_table "typed_stages" column "abbr")
109
+ ) as type_with_stage
110
+ [digit as stage_iteration space]
111
+ }
112
+
113
+ # ---- third part: edition, language, all-parts ----
114
+ edition_body = ("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit]
115
+ edition = {
116
+ (
117
+ (("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit])
118
+ ) as edition
119
+ }
120
+ lang_word = 1*letter [","]
121
+ # Separator-first: "(E/F)" and "(E,F)" only parse if each code item
122
+ # claims its following separator before the bare-word alternative
123
+ # commits (PEG ordered choice — parslet retries fewer iterations, PG
124
+ # does not).
125
+ lang_sep = slash / ","
126
+ lang_code = %x45 / %x46 / %x41 / %x52 / %x44 / %x53
127
+ languages = {
128
+ (
129
+ *( ((%x45 / %x46 / %x41 / %x52 / %x44 / %x53) [(slash / ",")]) / (1*letter [","]) )
130
+ ) as languages
131
+ }
132
+ language = "(" languages ")"
133
+ all_parts = "(all parts)" as all_parts
134
+ third_part_edition = [space] [edition]
135
+ third_part = third_part_edition [language] [space] [all_parts]
136
+
137
+ # ---- guide prefix ----
138
+ guide_prefix = "Guide" / "GUIDE"
139
+
140
+ # ---- the copublisher identifier form ----
141
+ identifier_copublishers_no_third = {
142
+ [ (("Guide" / "GUIDE") as type_with_stage_fr) space ]
143
+ [prefix_with_copublishers]
144
+ [space]
145
+ [slash]
146
+ [type_with_stage]
147
+ [space]
148
+ second_part
149
+ third_part_edition
150
+ }
151
+ identifier_copublishers = identifier_copublishers_no_third third_part
152
+
153
+ # The supplement-base variant: identical, but the edition captures as
154
+ # base_edition so the supplement layer's own third_part edition is the
155
+ # top-level one.
156
+ base_third_part_edition = {
157
+ [space] [
158
+ (
159
+ (("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit])
160
+ ) as base_edition
161
+ ]
162
+ }
163
+ supplement_base_no_third = {
164
+ [ (("Guide" / "GUIDE") as type_with_stage_fr) space ]
165
+ [prefix_with_copublishers]
166
+ [space]
167
+ [slash]
168
+ [type_with_stage]
169
+ [space]
170
+ second_part
171
+ base_third_part_edition
172
+ }
173
+
174
+ # ---- JCGM: "JCGM 200:2008(F)" ----
175
+ jcgm_identifier = "JCGM" as publisher space second_part third_part
176
+
177
+ # ---- NSB stage prefixes: "FprISO 105-A03", "WD/ISO 10360-5:2000" ----
178
+ nsb_iso_identifier = {
179
+ (
180
+ ("Fpr" as nsb_stage) prefix_sole_publisher [space] [copublishers] [space] [type_with_stage] [space] second_part third_part
181
+ )
182
+ /
183
+ (
184
+ ("WD" as nsb_stage) slash prefix_sole_publisher [space] [copublishers] [space] [type_with_stage] [space] second_part third_part
185
+ )
186
+ }
187
+
188
+ # ---- TC documents: "ISO/TC 184/SC 4/WG 3 N 123" ----
189
+ tc_type = (alt from_table "tc_types" column "name") as tc_type
190
+ wg_type = (alt from_table "wg_types" column "name") as wg_type
191
+ sc_type = ("SC/QC" / "SC") as sc_type
192
+ tc_subcommittee_part = {
193
+ (
194
+ slash sc_type space (1*digit) as sc_number slash wg_type space (1*digit) as wg_number
195
+ )
196
+ /
197
+ (
198
+ slash sc_type space (1*digit) as sc_number
199
+ )
200
+ }
201
+ tc_document = prefix_sole_publisher (slash / space) tc_type space (1*digit) as tc_number [tc_subcommittee_part] space "N" [space] (1*digit) as number [(colon (("19" / "20") 2*digit !digit) as year)]
202
+ bare_tc_document = {
203
+ (1*digit) as tc_number
204
+ slash sc_type space (1*digit) as sc_number
205
+ [ slash wg_type space (1*digit) as wg_number ]
206
+ space "N" [space] (1*digit) as number
207
+ [(colon (("19" / "20") 2*digit !digit) as year)]
208
+ }
209
+
210
+ # ---- legacy ISO/R ----
211
+ iso_r_prefix = ("ISO/R") as iso_r_prefix
212
+ iso_r_identifier = iso_r_prefix space second_part third_part
213
+ iso_r_supplement_separator = slash / ([space] "—" [space]) / (space dash space)
214
+ iso_r_supplement_identifier = {
215
+ iso_r_prefix space second_part
216
+ iso_r_supplement_separator
217
+ (
218
+ (alt from_table "typed_stages_supplements" column "abbr")
219
+ ) as isor_supp_type_with_stage
220
+ [space] supplement_second_part_isor
221
+ third_part
222
+ }
223
+
224
+ # ---- supplements (up to three levels) ----
225
+ ## ISO/R supplement layer second_part: isor_supp_* names.
226
+ supplement_second_part_isor = {
227
+ (
228
+ (
229
+ (1*5digit)
230
+ [
231
+ (
232
+ (dash [space] 1*word_digit *(dash 1*word_digit))
233
+ / (slash [space] !supp_stage_abbrev 1*word_digit)
234
+ )
235
+ ]
236
+ ) as isor_supp_number_with_part
237
+ )
238
+ [ dot digit as isor_supp_stage_iteration ]
239
+ [
240
+ [space] (
241
+ (colon / dash) [
242
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as isor_supp_date
243
+ / (("--" / "—")) as isor_supp_undated_marker
244
+ ]
245
+ )
246
+ ]
247
+ }
248
+
249
+ ## First supplement layer: /Amd 1:2021 after the base designation.
250
+ supplement_second_part = {
251
+ (
252
+ (
253
+ (1*5digit)
254
+ [
255
+ (
256
+ (dash [space] 1*word_digit *(dash 1*word_digit))
257
+ / (slash [space] !supp_stage_abbrev 1*word_digit)
258
+ )
259
+ ]
260
+ ) as supp_number_with_part
261
+ )
262
+ [ dot digit as supp_stage_iteration ]
263
+ [
264
+ [space] (
265
+ (colon / dash) [
266
+ (
267
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)])
268
+ ) as supp_date
269
+ / (("--" / "—")) as supp_undated_marker
270
+ ]
271
+ )
272
+ ]
273
+ }
274
+ supplement_type_with_stage = {
275
+ (
276
+ (alt from_table "typed_stages_supplements" column "abbr")
277
+ ) as supp_type_with_stage
278
+ }
279
+ supp_date_tail = {
280
+ (colon / dash) [
281
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as supp_date
282
+ / (("--" / "—")) as supp_undated_marker
283
+ ]
284
+ }
285
+ supplement_identifier_no_third = {
286
+ supplement_base_no_third
287
+ slash supplement_type_with_stage
288
+ [
289
+ ( [space] supplement_second_part )
290
+ / ( dot (1*digit) as supp_number )
291
+ / ( [space] supp_date_tail )
292
+ ]
293
+ }
294
+ supplement_identifier = supplement_identifier_no_third third_part
295
+
296
+ ## Second supplement layer (/Amd1:2018/Cor1:2019): supp2_* names.
297
+ supplement_second_part2 = {
298
+ (
299
+ (
300
+ (1*5digit)
301
+ [
302
+ (
303
+ (dash [space] 1*word_digit *(dash 1*word_digit))
304
+ / (slash [space] !supp_stage_abbrev 1*word_digit)
305
+ )
306
+ ]
307
+ ) as supp2_number_with_part
308
+ )
309
+ [ dot digit as supp2_stage_iteration ]
310
+ [
311
+ [space] (
312
+ (colon / dash) [
313
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as supp2_date
314
+ / (("--" / "—")) as supp2_undated_marker
315
+ ]
316
+ )
317
+ ]
318
+ }
319
+ supplement_type_with_stage2 = {
320
+ (
321
+ (alt from_table "typed_stages_supplements" column "abbr")
322
+ ) as supp2_type_with_stage
323
+ }
324
+ supplement_third_part2_edition = {
325
+ [space] [
326
+ (
327
+ (("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit])
328
+ ) as supp2_edition
329
+ ]
330
+ }
331
+ language2 = "(" ( ( *( ((%x45 / %x46 / %x41 / %x52 / %x44 / %x53) [(slash / ",")]) / (1*letter [","]) ) ) as supp2_languages ) ")"
332
+ supplement_third_part2 = {
333
+ supplement_third_part2_edition
334
+ [ (language2) ]
335
+ [space]
336
+ [ (("(all parts)")) as supp2_all_parts ]
337
+ }
338
+ supplement_supplement_identifier = {
339
+ supplement_identifier_no_third
340
+ slash supplement_type_with_stage2
341
+ (
342
+ ( [space] supplement_second_part2 supplement_third_part2 )
343
+ / ( dot (1*digit) as supp2_number supplement_third_part2 )
344
+ )
345
+ }
346
+
347
+ ## Third supplement layer (/Cor1:2014 riding a two-level chain): supp3_*.
348
+ supplement_second_part3 = {
349
+ (
350
+ (
351
+ (1*5digit)
352
+ [
353
+ (
354
+ (dash [space] 1*word_digit *(dash 1*word_digit))
355
+ / (slash [space] !supp_stage_abbrev 1*word_digit)
356
+ )
357
+ ]
358
+ ) as supp3_number_with_part
359
+ )
360
+ [ dot digit as supp3_stage_iteration ]
361
+ [
362
+ [space] (
363
+ (colon / dash) [
364
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as supp3_date
365
+ / (("--" / "—")) as supp3_undated_marker
366
+ ]
367
+ )
368
+ ]
369
+ }
370
+ supplement_type_with_stage3 = {
371
+ (
372
+ (alt from_table "typed_stages_supplements" column "abbr")
373
+ ) as supp3_type_with_stage
374
+ }
375
+ supplement_third_part3_edition = {
376
+ [space] [
377
+ (
378
+ (("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit])
379
+ ) as supp3_edition
380
+ ]
381
+ }
382
+ language3 = "(" ( ( *( ((%x45 / %x46 / %x41 / %x52 / %x44 / %x53) [(slash / ",")]) / (1*letter [","]) ) ) as supp3_languages ) ")"
383
+ supplement_third_part3 = {
384
+ supplement_third_part3_edition
385
+ [ (language3) ]
386
+ [space]
387
+ [ (("(all parts)")) as supp3_all_parts ]
388
+ }
389
+ supplement_supplement_supplement_identifier = {
390
+ supplement_supplement_identifier
391
+ slash supplement_type_with_stage3
392
+ (
393
+ ( [space] supplement_second_part3 supplement_third_part3 )
394
+ / ( dot (1*digit) as supp3_number supplement_third_part3 )
395
+ )
396
+ }
397
+
398
+ # ---- directives: "ISO/IEC DIR 1", "ISO/IEC JTC 1 DIR", supplements,
399
+ # bundled "ISO/IEC DIR 1:2022 + IEC SUP:2022" ----
400
+ directives_publisher_subgroup = ("JTC 1") as subgroup
401
+ directives_number_with_part = {
402
+ (
403
+ (1*5digit)
404
+ [ (space ("ISO" / "IEC") !slash !(space "SUP")) ]
405
+ ) as number_with_part
406
+ }
407
+ directives_identifier_no_third = {
408
+ prefix_with_copublishers
409
+ [space]
410
+ [ (directives_publisher_subgroup) space ]
411
+ (
412
+ (alt from_table "directives_typed_stages" column "abbr")
413
+ ) as type_with_stage
414
+ [ space directives_publisher_subgroup !(space "SUP") ]
415
+ [
416
+ [space directives_number_with_part]
417
+ [(colon date)]
418
+ ]
419
+ }
420
+ directives_identifier = directives_identifier_no_third [third_part] [space] [date]
421
+
422
+ ## Non-bundled directives supplement (ISO/IEC DIR 1 ISO SUP): dsupp_*.
423
+ directives_supp_publisher = ("ISO/IEC" / "ISO" / "IEC" / "JTC 1") as dsupp_publisher
424
+ dsupp_date_tail = {
425
+ (colon / dash) [
426
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as dsupp_date
427
+ / (("--" / "—")) as dsupp_undated_marker
428
+ ]
429
+ }
430
+ directives_supplement_part_no_third = {
431
+ [ ([space] "--" [space] "Consolidated" space) ]
432
+ directives_supp_publisher
433
+ ( space (alt from_table "directives_supplements_typed_stages" column "abbr") as dsupp_type_with_stage )
434
+ [ dsupp_date_tail ]
435
+ }
436
+ dsupp_third_part_edition = {
437
+ [space] [
438
+ (
439
+ (("Edition" / "Ed." / "ED" / "Ed") [space] [1*digit])
440
+ ) as dsupp_edition
441
+ ]
442
+ }
443
+ dsupp_language = "(" ( ( *( ((%x45 / %x46 / %x41 / %x52 / %x44 / %x53) [(slash / ",")]) / (1*letter [","]) ) ) as dsupp_languages ) ")"
444
+ directives_supplement_part = {
445
+ directives_supplement_part_no_third
446
+ dsupp_third_part_edition
447
+ [ (dsupp_language) ]
448
+ [space]
449
+ [ (("(all parts)")) as dsupp_all_parts ]
450
+ }
451
+ directives_supplement_identifier = directives_identifier_no_third [space] directives_supplement_part
452
+
453
+ ## Bundled directives ("DIR 1:2022 + IEC SUP:2022"): the base document
454
+ ## keeps the plain names, and each bundle item captures into its own
455
+ ## position-scoped prefix (bs1_* on the first, bs2_*/bs3_* on the
456
+ ## second and third). The engine's array-group harvest pads non-firing
457
+ ## reps with empty hashes (parsanol-ruby#399), so bundle items cannot
458
+ ## collect through an array binding; three items bound. The source
459
+ ## parser's 1* accepted any count — a fourth "+ SUP" item now fails
460
+ ## to parse rather than mis-bind.
461
+ directives_base_document = {
462
+ directives_identifier_no_third
463
+ [[third_part] [space]]
464
+ [[date] [space]]
465
+ }
466
+ bs1_publisher = ("ISO/IEC" / "ISO" / "IEC" / "JTC 1") as bs1_publisher
467
+ bs1_date_tail = {
468
+ (colon / dash) [
469
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as bs1_date
470
+ / (("--" / "—")) as bs1_undated_marker
471
+ ]
472
+ }
473
+ bundled_supplement1 = {
474
+ "+ "
475
+ [ ([space] "--" [space] "Consolidated" space) ]
476
+ bs1_publisher
477
+ ( space (alt from_table "directives_supplements_typed_stages" column "abbr") as bs1_type_with_stage )
478
+ [ bs1_date_tail ]
479
+ }
480
+ bs2_publisher = ("ISO/IEC" / "ISO" / "IEC" / "JTC 1") as bs2_publisher
481
+ bs2_date_tail = {
482
+ (colon / dash) [
483
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as bs2_date
484
+ / (("--" / "—")) as bs2_undated_marker
485
+ ]
486
+ }
487
+ bundled_supplement2 = {
488
+ "+ "
489
+ [ ([space] "--" [space] "Consolidated" space) ]
490
+ bs2_publisher
491
+ ( space (alt from_table "directives_supplements_typed_stages" column "abbr") as bs2_type_with_stage )
492
+ [ bs2_date_tail ]
493
+ }
494
+ bs3_publisher = ("ISO/IEC" / "ISO" / "IEC" / "JTC 1") as bs3_publisher
495
+ bs3_date_tail = {
496
+ (colon / dash) [
497
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as bs3_date
498
+ / (("--" / "—")) as bs3_undated_marker
499
+ ]
500
+ }
501
+ bundled_supplement3 = {
502
+ "+ "
503
+ [ ([space] "--" [space] "Consolidated" space) ]
504
+ bs3_publisher
505
+ ( space (alt from_table "directives_supplements_typed_stages" column "abbr") as bs3_type_with_stage )
506
+ [ bs3_date_tail ]
507
+ }
508
+ directives_bundled_identifier = {
509
+ directives_base_document
510
+ bundled_supplement1
511
+ [bundled_supplement2]
512
+ [bundled_supplement3]
513
+ }
514
+ directives_identifiers = directives_bundled_identifier / directives_supplement_identifier / directives_identifier
515
+
516
+ # ---- joint: "ISO 5537|IDF 26" — the IDF grammar's rules inlined
517
+ # under idf_* names (captures must not collide with the ISO ones) ----
518
+ idf_publisher = ("IDF") as idf_publisher
519
+ idf_number_with_part = {
520
+ (
521
+ (1*5word_char)
522
+ [ (dash [space] 1*word_char *1(dash 1*word_char)) ]
523
+ ) as idf_number_with_part
524
+ }
525
+ idf_stage_iteration = dot digit as idf_stage_iteration
526
+ idf_date = {
527
+ (
528
+ (
529
+ (("19" / "20") 2*digit !digit)
530
+ [(dash 2*digit)]
531
+ [(dash 2*digit)]
532
+ )
533
+ ) as idf_date
534
+ }
535
+ idf_second_part = {
536
+ idf_number_with_part
537
+ [idf_stage_iteration]
538
+ [space]
539
+ [ (colon idf_date) ]
540
+ }
541
+ idf_language = {
542
+ "(" (
543
+ (
544
+ *( 1*lower [","] / ((%x45 / %x46 / %x41 / %x52 / %x44 / %x53) [slash]) )
545
+ ) as idf_languages
546
+ ) ")"
547
+ }
548
+ idf_all_parts = ("(all parts)") as idf_all_parts
549
+ idf_third_part = [space] [idf_language] [idf_all_parts]
550
+ idf_type_with_stage = {
551
+ (
552
+ (alt from_table "idf_typed_stages" column "abbr")
553
+ ) as idf_type_with_stage
554
+ [digit as idf_stage_iteration space]
555
+ }
556
+ idf_identifier_publisher_no_third = {
557
+ idf_publisher
558
+ [space]
559
+ [slash]
560
+ [idf_type_with_stage]
561
+ [space]
562
+ idf_second_part
563
+ }
564
+ ## IDF supplement side of the joint (a true IDF supplement keeps its
565
+ ## fields under idf_supp_*2 names).
566
+ idf_supp_type_with_stage = {
567
+ (
568
+ (alt from_table "idf_typed_stages_supplements" column "abbr")
569
+ ) as idf_supp_type_with_stage
570
+ }
571
+ idf_supp_number_with_part2 = {
572
+ (
573
+ (1*5word_char)
574
+ [ (dash [space] 1*word_char *1(dash 1*word_char)) ]
575
+ ) as idf_supp_number_with_part2
576
+ }
577
+ idf_supp_stage_iteration2 = dot digit as idf_supp_stage_iteration2
578
+ idf_supp_date2 = {
579
+ (
580
+ (
581
+ (("19" / "20") 2*digit !digit)
582
+ [(dash 2*digit)]
583
+ [(dash 2*digit)]
584
+ )
585
+ ) as idf_supp_date2
586
+ }
587
+ idf_supplement_identifier = {
588
+ idf_identifier_publisher_no_third
589
+ [space] slash [space]
590
+ idf_supp_type_with_stage
591
+ [space]
592
+ idf_supp_number_with_part2
593
+ [ dot digit as idf_supp_stage_iteration2 ]
594
+ [
595
+ [space] (
596
+ (colon / dash) [
597
+ (("19" / "20") 2*digit !digit [(dash 2*digit)] [(dash 2*digit)]) as idf_supp_date2
598
+ / (("--" / "—")) as idf_supp_undated_marker
599
+ ]
600
+ )
601
+ ]
602
+ [space] [idf_language] [idf_all_parts]
603
+ }
604
+ joint_idf_identifier = idf_supplement_identifier / idf_identifier_publisher_no_third idf_third_part
605
+ joint_identifier = {
606
+ supplement_base_no_third
607
+ [space] "|" [space]
608
+ joint_idf_identifier
609
+ }
610
+
611
+ ## The ISO identifier root: common-text twin form first, then the
612
+ ## single spine.
613
+ identifier = {
614
+ bare_tc_document
615
+ / nsb_iso_identifier
616
+ / tc_document
617
+ / directives_identifiers
618
+ / jcgm_identifier
619
+ / iso_r_supplement_identifier
620
+ / iso_r_identifier
621
+ / supplement_supplement_supplement_identifier
622
+ / supplement_supplement_identifier
623
+ / supplement_identifier
624
+ / joint_identifier
625
+ / identifier_copublishers
626
+ }
627
+
628
+ entry identifier: identifier
629
+
630
+ bindings identifier {
631
+ publisher -> publisher (string)
632
+ publisher -> publisher_name (string) preprocess: publisher_names
633
+ copublishers -> copublishers (string)
634
+ type_with_stage -> type_with_stage (string)
635
+ type_with_stage_fr -> type_with_stage_fr (string)
636
+ base_edition -> base_edition (string)
637
+ nsb_stage -> nsb_stage (string)
638
+ iso_r_prefix -> iso_r_prefix (string)
639
+ number_with_part -> number_with_part (string)
640
+ stage_iteration -> stage_iteration (string)
641
+ date -> date (string)
642
+ undated_marker -> undated_marker (string)
643
+ edition -> edition (string)
644
+ languages -> languages (string)
645
+ all_parts -> all_parts (string)
646
+ year -> year (string)
647
+ tc_type -> tc_type (string)
648
+ tc_number -> tc_number (string)
649
+ sc_type -> sc_type (string)
650
+ sc_number -> sc_number (string)
651
+ wg_type -> wg_type (string)
652
+ wg_number -> wg_number (string)
653
+ number -> number (string)
654
+ subgroup -> subgroup (string)
655
+ supp_type_with_stage -> supp_type_with_stage (string)
656
+ supp_number_with_part -> supp_number_with_part (string)
657
+ supp_stage_iteration -> supp_stage_iteration (string)
658
+ supp_number -> supp_number (string)
659
+ supp_date -> supp_date (string)
660
+ supp_undated_marker -> supp_undated_marker (string)
661
+ supp2_type_with_stage -> supp2_type_with_stage (string)
662
+ supp2_number_with_part -> supp2_number_with_part (string)
663
+ supp2_stage_iteration -> supp2_stage_iteration (string)
664
+ supp2_number -> supp2_number (string)
665
+ supp2_date -> supp2_date (string)
666
+ supp2_undated_marker -> supp2_undated_marker (string)
667
+ supp2_edition -> supp2_edition (string)
668
+ supp2_languages -> supp2_languages (string)
669
+ supp2_all_parts -> supp2_all_parts (string)
670
+ supp3_type_with_stage -> supp3_type_with_stage (string)
671
+ supp3_number_with_part -> supp3_number_with_part (string)
672
+ supp3_stage_iteration -> supp3_stage_iteration (string)
673
+ supp3_number -> supp3_number (string)
674
+ supp3_date -> supp3_date (string)
675
+ supp3_undated_marker -> supp3_undated_marker (string)
676
+ supp3_edition -> supp3_edition (string)
677
+ supp3_languages -> supp3_languages (string)
678
+ supp3_all_parts -> supp3_all_parts (string)
679
+ isor_supp_type_with_stage -> isor_supp_type_with_stage (string)
680
+ isor_supp_number_with_part -> isor_supp_number_with_part (string)
681
+ isor_supp_stage_iteration -> isor_supp_stage_iteration (string)
682
+ isor_supp_date -> isor_supp_date (string)
683
+ isor_supp_undated_marker -> isor_supp_undated_marker (string)
684
+ dsupp_publisher -> dsupp_publisher (string)
685
+ dsupp_type_with_stage -> dsupp_type_with_stage (string)
686
+ dsupp_date -> dsupp_date (string)
687
+ dsupp_undated_marker -> dsupp_undated_marker (string)
688
+ dsupp_edition -> dsupp_edition (string)
689
+ dsupp_languages -> dsupp_languages (string)
690
+ dsupp_all_parts -> dsupp_all_parts (string)
691
+ bs1_publisher -> bs1_publisher (string)
692
+ bs1_type_with_stage -> bs1_type_with_stage (string)
693
+ bs1_date -> bs1_date (string)
694
+ bs1_undated_marker -> bs1_undated_marker (string)
695
+ bs2_publisher -> bs2_publisher (string)
696
+ bs2_type_with_stage -> bs2_type_with_stage (string)
697
+ bs2_date -> bs2_date (string)
698
+ bs2_undated_marker -> bs2_undated_marker (string)
699
+ bs3_publisher -> bs3_publisher (string)
700
+ bs3_type_with_stage -> bs3_type_with_stage (string)
701
+ bs3_date -> bs3_date (string)
702
+ bs3_undated_marker -> bs3_undated_marker (string)
703
+ idf_publisher -> idf_publisher (string)
704
+ idf_type_with_stage -> idf_type_with_stage (string)
705
+ idf_stage_iteration -> idf_stage_iteration (string)
706
+ idf_number_with_part -> idf_number_with_part (string)
707
+ idf_date -> idf_date (string)
708
+ idf_languages -> idf_languages (string)
709
+ idf_all_parts -> idf_all_parts (string)
710
+ idf_supp_type_with_stage -> idf_supp_type_with_stage (string)
711
+ idf_supp_number_with_part2 -> idf_supp_number_with_part2 (string)
712
+ idf_supp_stage_iteration2 -> idf_supp_stage_iteration2 (string)
713
+ idf_supp_date2 -> idf_supp_date2 (string)
714
+ idf_supp_undated_marker -> idf_supp_undated_marker (string)
715
+ }
716
+
717
+ ## In-file grammar tests: run at compile time, embedded in the artifact,
718
+ ## and re-runnable by every consumer (accept / reject / example with
719
+ ## expected bound captures).
720
+ test {
721
+ accept "ISO 8601-1:2019"
722
+ accept "ISO/IEC WD TS 25025"
723
+ accept "ISO/WD Study 42010"
724
+ accept "ISO/WDS 42010"
725
+ accept "Guide ISO/CEI 51:1999"
726
+ accept "ISO/IEC DIR 1:2022 + IEC SUP:2022"
727
+ accept "184/SC 4/WG 12 N10291"
728
+ accept "ISO 5537|IDF 26"
729
+ accept "ISO 4055/Amd 1:2021"
730
+ accept "ISO/R 9:1962"
731
+ reject "nonsense"
732
+ example "ISO/IEC WD TS 25025" { publisher: "ISO" }
733
+ example "JCGM 200:2008(F)" { publisher: "JCGM" }
734
+ }
735
+ }
736
+
737
+ preprocess publisher_names {
738
+ table_lookup iso_publishers abbrev -> name
739
+ }
740
+
741
+ derive urn "urn:iso:std:{number_with_part}:{date}"
742
+
743
+ render default {
744
+ field publisher
745
+ literal "-"
746
+ field number_with_part
747
+ cond date {
748
+ literal ":"
749
+ field date
750
+ }
751
+ }