pubid 2.0.0.pre.alpha.29 → 2.0.0.pre.alpha.30

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.
@@ -5,6 +5,17 @@ module Pubid
5
5
  # Builder class for constructing IEEE identifier scheme from parsed data
6
6
  # Single Responsibility: Transform parsed data into identifier objects
7
7
  class Builder
8
+ # The month_name vocabulary the REV date embed canonicalizes numeric
9
+ # (the parg rule's exact spellings, dots already stripped).
10
+ REV_MONTH_NUMBERS = {
11
+ "January" => "01", "February" => "02", "March" => "03",
12
+ "April" => "04", "May" => "05", "June" => "06", "July" => "07",
13
+ "August" => "08", "September" => "09", "Sept" => "09",
14
+ "October" => "10", "November" => "11", "December" => "12",
15
+ "Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04",
16
+ "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09",
17
+ "Oct" => "10", "Nov" => "11", "Dec" => "12",
18
+ }.freeze
8
19
  attr_accessor :original_input
9
20
  attr_reader :identifier_class
10
21
 
@@ -287,6 +298,24 @@ module Pubid
287
298
  end
288
299
  dash = parsed_hash[:dash_year] ? parsed_hash : nil
289
300
  dash ||= drafts.find { |d| d.is_a?(Hash) && d[:dash_year] }
301
+ if dash.nil? && parsed_hash[:draft]
302
+ # A numeric month trailing a draft is the draft's own date: it
303
+ # embeds in the designator ("D09, 04 2011" -> "D09-2011-04")
304
+ # rather than printing the long-format comma face (a month name
305
+ # keeps the comma, "D7.2, Nov 2006") — pubid ruling 2026-10-13.
306
+ m = parsed_hash[:month] || parsed_hash[:trailing_month]
307
+ y = parsed_hash[:year] || parsed_hash[:trailing_year]
308
+ if m.to_s.match?(/\A\d{1,2}\z/) && y
309
+ host = drafts.find { |d| d.is_a?(Hash) && d[:draft_version] }
310
+ if host
311
+ host[:draft_version] = [host[:draft_version], y, m].compact.join("-")
312
+ parsed_hash.delete(:month)
313
+ parsed_hash.delete(:year)
314
+ parsed_hash.delete(:trailing_month)
315
+ parsed_hash.delete(:trailing_year)
316
+ end
317
+ end
318
+ end
290
319
  if dash && parsed_hash[:year].nil?
291
320
  joined = drafts.filter_map { |d| d.is_a?(Hash) ? d[:draft_version] : nil }
292
321
  .map { |v| v.is_a?(Hash) ? v[:value] : v.to_s }.join
@@ -297,6 +326,15 @@ module Pubid
297
326
  dash_led = joined.start_with?("-")
298
327
  if bare_joint_draft && dash_led
299
328
  parsed_hash[:part] = { value: dash[:dash_year] }
329
+ elsif dash[:dash_month] &&
330
+ (host = drafts.find { |d| d.is_a?(Hash) && d[:draft_version] })
331
+ # The draft's own numeric date embeds in the designator
332
+ # ("D2-2015-04") — the "D2, 04 2015" comma spelling
333
+ # normalizes onto it (pubid ruling 2026-10-13).
334
+ host[:draft_version] =
335
+ [joined, dash[:dash_year], dash[:dash_month]].compact.join("-")
336
+ dash.delete(:dash_year)
337
+ dash.delete(:dash_month)
300
338
  elsif dash[:dash_month] || dash_led
301
339
  parsed_hash[:year] = dash[:dash_year]
302
340
  parsed_hash[:month] = dash[:dash_month]
@@ -307,9 +345,16 @@ module Pubid
307
345
  # draft version misses the D-registry), no separate year.
308
346
  host = drafts.find { |d| d.is_a?(Hash) && d[:draft_version] }
309
347
  if host
310
- host[:draft_version] = "#{joined}-#{dash[:dash_year]}"
348
+ # The draft's own numeric date embeds in the designator
349
+ # ("D9-2006", and with its month "D2-2015-04") — the
350
+ # "D2, 04 2015" comma spelling normalizes onto it.
351
+ host[:draft_version] =
352
+ [joined, dash[:dash_year], dash[:dash_month]].compact.join("-")
311
353
  dash.delete(:dash_year)
312
354
  dash.delete(:dash_month)
355
+ # the hyphenated "/D-2-2007" spelling's year the spine
356
+ # captured at top level is the draft's own — vacate it
357
+ parsed_hash.delete(:year) if parsed_hash[:year] == dash[:dash_year]
313
358
  else
314
359
  parsed_hash[:year] = dash[:dash_year]
315
360
  parsed_hash[:month] = dash[:dash_month]
@@ -1548,6 +1593,8 @@ module Pubid
1548
1593
  # Optional attributes (excluding part/subpart since they're in code)
1549
1594
  extract_optional(parsed, attributes, :edition)
1550
1595
  extract_optional(parsed, attributes, :revision)
1596
+ extract_optional(parsed, attributes, :rev_sep)
1597
+ attributes[:rev_bare] = true if parsed[:rev_bare]
1551
1598
 
1552
1599
  # Month/day - always extract if present (but not if already extracted from year)
1553
1600
  unless attributes[:edition_month]
@@ -1663,8 +1710,9 @@ module Pubid
1663
1710
 
1664
1711
  if version
1665
1712
  # relaton's hyphenated "/D-2" spelling captures the dash inside
1666
- # draft_version; the stage registry keys on "D2".
1667
- draft_abbr = "D#{version.to_s.sub(/\A-/, "")}"
1713
+ # draft_version; the stage registry keys on "D2". A date-embedded
1714
+ # version ("3-2017-07") keys on its leading ordinal.
1715
+ draft_abbr = "D#{version.to_s.sub(/\A-/, "").sub(/-\d{4}(-\d{2})?\z/, "")}"
1668
1716
  # Check if this specific draft stage is in registry
1669
1717
  stage = Pubid::Ieee.locate_stage(draft_abbr)
1670
1718
  return draft_abbr if stage&.abbr&.include?(draft_abbr)
@@ -1804,6 +1852,18 @@ module Pubid
1804
1852
  year = extract_value(draft_data[:year]) if draft_data[:year]
1805
1853
  day = extract_value(draft_data[:day]) if draft_data[:day]
1806
1854
 
1855
+ # A REV-carrying draft embeds its print date into the designator
1856
+ # with the month canonicalized numeric (pubid ruling 2026-10-14):
1857
+ # "P802.11-REVmc/D8.0, Aug 2016" renders ".../D8.0-2016-08".
1858
+ # Drafts without a REV keep the comma face.
1859
+ if (attributes[:revision] || attributes[:rev_bare]) && month && year
1860
+ number = REV_MONTH_NUMBERS[month.to_s.delete(".")]
1861
+ if number && version
1862
+ version = "#{version}-#{year}-#{number}"
1863
+ month = year = day = nil
1864
+ end
1865
+ end
1866
+
1807
1867
  # Detect comma before month and space before draft by checking the original input
1808
1868
  if original_input
1809
1869
  if month
@@ -36,6 +36,12 @@ module Pubid
36
36
  # "Rev<id>". `::Pubid::Identifier` has no `revision` attribute, so this is
37
37
  # free of the number/stage multi-flavor collision landmine.
38
38
  attribute :revision, :string
39
+ # The lettered revision's printed separator ("P802.11-REVmc" keeps its
40
+ # dash; a glued "REVi" stays glued) and the bare-word marker (no id
41
+ # after "Rev" — "802.1AR-Rev/D2.2" keeps "Rev"). pubid ruling
42
+ # 2026-10-14.
43
+ attribute :rev_sep, :string
44
+ attribute :rev_bare, :boolean
39
45
  attribute :edition, :string # Edition 1.0
40
46
  attribute :month, :string
41
47
  # Provenance flag (pubid#517): the month arrived glued to the identity
@@ -216,7 +222,7 @@ module Pubid
216
222
  # (renderer.rb's `"Edition #{edition} #{year}-#{edition_month}"`),
217
223
  # which survived even though its sibling `year` is already stripped.
218
224
  def self.all_parts_edition_keys
219
- super + %i[revision reaffirmed edition_month]
225
+ super + %i[revision rev_sep rev_bare reaffirmed edition_month]
220
226
  end
221
227
 
222
228
  # Inverse of the to_hash compaction: expand a scalar `stage` back into the
@@ -201,8 +201,12 @@ module Pubid
201
201
 
202
202
  # Append the numbered/lettered revision inline, in IEEE's native
203
203
  # position — right after the code number and before the draft
204
- # ("P802.16Rev2/D3"). Keeps a revision distinct from its base standard.
205
- result += "Rev#{id.revision}" if id.revision
204
+ # ("P802.16Rev2/D3"). Keeps a revision distinct from its base
205
+ # standard. The lettered id keeps its printed separator
206
+ # ("P802.11-REVmc" renders "P802.11-Revmc"); the bare word with
207
+ # no id still prints "Rev" (pubid ruling 2026-10-14).
208
+ result += "#{id.rev_sep}Rev#{id.revision}" if id.revision
209
+ result += "#{id.rev_sep}Rev" if id.rev_bare
206
210
 
207
211
  # Append draft to code - with or without space based on original
208
212
  # format. An exactly-IEC/IEEE co-published reference prints only the
data/lib/pubid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pubid
4
- VERSION = "2.0.0.pre.alpha.29"
4
+ VERSION = "2.0.0.pre.alpha.30"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre.alpha.29
4
+ version: 2.0.0.pre.alpha.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-12 00:00:00.000000000 Z
11
+ date: 2026-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -484,6 +484,8 @@ files:
484
484
  - lib/pubid/evs/builder.rb
485
485
  - lib/pubid/evs/identifier.rb
486
486
  - lib/pubid/evs/identifiers.rb
487
+ - lib/pubid/evs/identifiers/estonian_standard.rb
488
+ - lib/pubid/evs/identifiers/international_adoption.rb
487
489
  - lib/pubid/evs/identifiers/national_adoption.rb
488
490
  - lib/pubid/evs/parser.rb
489
491
  - lib/pubid/evs/renderer.rb