relaton-etsi 2.1.1 → 2.1.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.
- checksums.yaml +4 -4
- data/CLAUDE.md +1 -1
- data/README.adoc +18 -0
- data/lib/relaton/etsi/bibliography.rb +64 -1
- data/lib/relaton/etsi/version.rb +1 -1
- data/relaton-etsi.gemspec +44 -0
- metadata +3 -7
- data/grammars/basicdoc.rng +0 -2140
- data/grammars/biblio-standoc.rng +0 -268
- data/grammars/biblio.rng +0 -2125
- data/grammars/relaton-etsi-compile.rng +0 -11
- data/grammars/relaton-etsi.rng +0 -113
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: abf8bf4e0aa5207f1a957ebca5b69ebd3a44857a4f8fbc0f17d9f3d9617bb174
|
|
4
|
+
data.tar.gz: f1ae62b230c9a6a32e4037b26690c2668890c9e8911d9665a7e46176628c3a98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7ee42ae9e44aa09dcc8c3e822eed2e1d5e78454a2faecc552060f61471fa3bc927edd92cdd5736403ef28fed9e3701413c902bb6e6a48fda8d2e10fc0a557ca
|
|
7
|
+
data.tar.gz: a0cc870769279fd8a0c0f2448cd107b22245fa43dffa133df7cc7ddd4fe711295fb51b981aa1b3389d0ca75f133f4c6b90f776fa7be51f03102d9a175a785d5d
|
data/CLAUDE.md
CHANGED
|
@@ -60,7 +60,7 @@ Uses Lutaml for serialization:
|
|
|
60
60
|
|
|
61
61
|
### Data Flow
|
|
62
62
|
|
|
63
|
-
1. `Bibliography.get(ref)` searches the relaton-data-etsi index
|
|
63
|
+
1. `Bibliography.get(ref)` searches the relaton-data-etsi index. `Bibliography#best_match` keeps the rows that match the whole document number, then picks the highest version, and among equal versions the latest date. The index matches a String query with `include?`, so this filter is what stops `ETSI TS 103 1` from matching `ETSI TS 103 104`.
|
|
64
64
|
2. Fetches YAML from GitHub, converts to `Item` using `from_yaml`
|
|
65
65
|
3. `DataFetcher.fetch` pulls CSV from etsi.org, parses with `DataParser`, saves to output folder
|
|
66
66
|
|
data/README.adoc
CHANGED
|
@@ -37,6 +37,24 @@ item = Relaton::Etsi::Bibliography.get("ETSI GS ZSM 012 V1.1.1")
|
|
|
37
37
|
...
|
|
38
38
|
----
|
|
39
39
|
|
|
40
|
+
=== Reference matching
|
|
41
|
+
|
|
42
|
+
A reference matches a whole ETSI document number. Neither `ETSI TS 103 1` nor
|
|
43
|
+
`ETSI TS 103` matches `ETSI TS 103 104`. A reference without a part number
|
|
44
|
+
matches every part of the document. The `ETSI` prefix is optional.
|
|
45
|
+
|
|
46
|
+
A reference without a version returns the newest edition of the document. A
|
|
47
|
+
reference with a version and a date returns that edition.
|
|
48
|
+
|
|
49
|
+
[source,ruby]
|
|
50
|
+
----
|
|
51
|
+
Relaton::Etsi::Bibliography.get("ETSI EN 319 401")
|
|
52
|
+
[relaton-etsi] INFO: (ETSI EN 319 401) Found: `ETSI EN 319 401 V3.2.1 (2026-01)`
|
|
53
|
+
|
|
54
|
+
Relaton::Etsi::Bibliography.get("ETSI EN 319 401 V2.3.1 (2021-05)")
|
|
55
|
+
[relaton-etsi] INFO: (ETSI EN 319 401 V2.3.1 (2021-05)) Found: `ETSI EN 319 401 V2.3.1 (2021-05)`
|
|
56
|
+
----
|
|
57
|
+
|
|
40
58
|
=== XML serialization
|
|
41
59
|
|
|
42
60
|
[source,ruby]
|
|
@@ -6,11 +6,16 @@ module Relaton
|
|
|
6
6
|
module Bibliography
|
|
7
7
|
SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-etsi/refs/heads/v2/"
|
|
8
8
|
|
|
9
|
+
# What follows the document number in an index id: the part numbers, then
|
|
10
|
+
# the version. A reference matches a whole number only, so a part number
|
|
11
|
+
# is optional but a group of digits of the number is not.
|
|
12
|
+
SUFFIX = /\A(?:-\d+)*\s(?:V\d|ed\.\d)/
|
|
13
|
+
|
|
9
14
|
# @param text [String]
|
|
10
15
|
# @return [Relaton::Etsi::ItemData, nil]
|
|
11
16
|
def search(text) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
12
17
|
index = Relaton::Index.find_or_create :etsi, url: "#{SOURCE}index-v1.zip", file: INDEX_FILE
|
|
13
|
-
row = index
|
|
18
|
+
row = best_match(index, text)
|
|
14
19
|
return unless row
|
|
15
20
|
|
|
16
21
|
url = "#{SOURCE}#{row[:file]}"
|
|
@@ -40,6 +45,64 @@ module Relaton
|
|
|
40
45
|
result
|
|
41
46
|
end
|
|
42
47
|
|
|
48
|
+
# Match the reference against the index and return the newest edition.
|
|
49
|
+
#
|
|
50
|
+
# An index id renders as `ETSI <type> <number> <V1.2.3|ed.4> (<yyyy-mm>)`.
|
|
51
|
+
# The index matches a String query with `include?`, so a bare reference
|
|
52
|
+
# matches every edition of the document, but also longer numbers. The
|
|
53
|
+
# `matches?` filter drops the longer numbers, then `edition_key` picks the
|
|
54
|
+
# highest version, and among equal versions the latest date.
|
|
55
|
+
#
|
|
56
|
+
# @param index [Relaton::Index::Type]
|
|
57
|
+
# @param text [String] the reference
|
|
58
|
+
# @return [Hash, nil] the winning index row (`{ id:, file: }`)
|
|
59
|
+
def best_match(index, text)
|
|
60
|
+
ref = normalize(text)
|
|
61
|
+
index.search(ref)
|
|
62
|
+
.select { |row| matches? ref, row[:id] }
|
|
63
|
+
.max_by { |row| edition_key row[:id] }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
# Every index id has the `ETSI` prefix. A reference can omit it.
|
|
69
|
+
#
|
|
70
|
+
# @param text [String] the reference
|
|
71
|
+
# @return [String]
|
|
72
|
+
def normalize(text)
|
|
73
|
+
ref = text.strip.squeeze(" ").sub(/\AETSI\s+/i, "")
|
|
74
|
+
"ETSI #{ref}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# `ETSI EN 319 142` matches every part of the document. Neither
|
|
78
|
+
# `ETSI EN 319 14` nor `ETSI EN 319` matches anything: the first stops
|
|
79
|
+
# inside a group of digits, the second stops before the last group.
|
|
80
|
+
#
|
|
81
|
+
# @param ref [String] the normalized reference
|
|
82
|
+
# @param id [String] the index id
|
|
83
|
+
# @return [Boolean]
|
|
84
|
+
def matches?(ref, id)
|
|
85
|
+
return true if id == ref
|
|
86
|
+
|
|
87
|
+
rest = id[ref.length..]
|
|
88
|
+
!rest.nil? && rest.match?(SUFFIX)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Sort key of one edition. The numbers keep `V19.0.0` above `V9.0.0` and
|
|
92
|
+
# `ed.11` above `ed.9`, which a comparison of the strings does not. The id
|
|
93
|
+
# is the last element to make the order of equal editions stable.
|
|
94
|
+
#
|
|
95
|
+
# A `V` version and an `ed.` edition give keys of a different length. No
|
|
96
|
+
# ETSI document has the two forms together, and `matches?` keeps the rows
|
|
97
|
+
# of one document number only, so the two forms do not meet here.
|
|
98
|
+
#
|
|
99
|
+
# @param id [String] the index id
|
|
100
|
+
# @return [Array]
|
|
101
|
+
def edition_key(id)
|
|
102
|
+
version = id[/\sV(\d+(?:\.\d+)*)/, 1] || id[/\sed\.(\d+)/, 1] || ""
|
|
103
|
+
[version.split(".").map(&:to_i), id[/\((\d{4}-\d{2})\)/, 1].to_s, id]
|
|
104
|
+
end
|
|
105
|
+
|
|
43
106
|
extend Bibliography
|
|
44
107
|
end
|
|
45
108
|
end
|
data/lib/relaton/etsi/version.rb
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/relaton/etsi/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
6
|
+
spec.name = "relaton-etsi"
|
|
7
|
+
spec.version = Relaton::Etsi::VERSION
|
|
8
|
+
spec.authors = ["Ribose Inc."]
|
|
9
|
+
spec.email = ["open.source@ribose.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Relaton::Etsi: retrieve ETSI Standards for bibliographic " \
|
|
12
|
+
"using the BibliographicItem model"
|
|
13
|
+
spec.description = "Relaton::Etsi: retrieve ETSI Standards for bibliographic " \
|
|
14
|
+
"using the BibliographicItem model"
|
|
15
|
+
spec.homepage = "https://github.com/relaton/relaton-etsi"
|
|
16
|
+
spec.license = "BSD-2-Clause"
|
|
17
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.2.0")
|
|
18
|
+
|
|
19
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
|
20
|
+
|
|
21
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
22
|
+
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
|
23
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
|
24
|
+
|
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
27
|
+
spec.files = Dir.chdir(__dir__) do
|
|
28
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
29
|
+
(File.expand_path(f) == __FILE__) ||
|
|
30
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
spec.bindir = "exe"
|
|
34
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
35
|
+
spec.require_paths = ["lib"]
|
|
36
|
+
|
|
37
|
+
spec.add_dependency "mechanize", "~> 2.8"
|
|
38
|
+
spec.add_dependency "relaton-bib", "~> 2.1.0"
|
|
39
|
+
spec.add_dependency "relaton-core", "~> 0.0.13"
|
|
40
|
+
spec.add_dependency "relaton-index", "~> 0.2.7"
|
|
41
|
+
|
|
42
|
+
# For more information and examples about making a new gem, check out our
|
|
43
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
44
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relaton-etsi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.2
|
|
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-
|
|
11
|
+
date: 2026-08-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mechanize
|
|
@@ -80,11 +80,6 @@ files:
|
|
|
80
80
|
- LICENSE.txt
|
|
81
81
|
- README.adoc
|
|
82
82
|
- Rakefile
|
|
83
|
-
- grammars/basicdoc.rng
|
|
84
|
-
- grammars/biblio-standoc.rng
|
|
85
|
-
- grammars/biblio.rng
|
|
86
|
-
- grammars/relaton-etsi-compile.rng
|
|
87
|
-
- grammars/relaton-etsi.rng
|
|
88
83
|
- lib/relaton/etsi.rb
|
|
89
84
|
- lib/relaton/etsi/bibdata.rb
|
|
90
85
|
- lib/relaton/etsi/bibitem.rb
|
|
@@ -100,6 +95,7 @@ files:
|
|
|
100
95
|
- lib/relaton/etsi/status.rb
|
|
101
96
|
- lib/relaton/etsi/util.rb
|
|
102
97
|
- lib/relaton/etsi/version.rb
|
|
98
|
+
- relaton-etsi.gemspec
|
|
103
99
|
- sig/relaton_etsi.rbs
|
|
104
100
|
homepage: https://github.com/relaton/relaton-etsi
|
|
105
101
|
licenses:
|