relaton-ietf 1.8.0 → 1.9.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.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -11
- data/.rubocop.yml +3 -1
- data/README.adoc +50 -0
- data/grammars/biblio.rng +1 -0
- data/grammars/ietf.rng +3 -0
- data/grammars/isodoc.rng +72 -10
- data/lib/relaton_ietf/committee.rb +8 -0
- data/lib/relaton_ietf/data_fetcher.rb +130 -0
- data/lib/relaton_ietf/ietf_bibliographic_item.rb +2 -2
- data/lib/relaton_ietf/processor.rb +14 -1
- data/lib/relaton_ietf/rfc_entry.rb +186 -0
- data/lib/relaton_ietf/rfc_index_entry.rb +60 -0
- data/lib/relaton_ietf/scrapper.rb +354 -346
- data/lib/relaton_ietf/version.rb +1 -1
- data/lib/relaton_ietf/xml_parser.rb +1 -1
- data/lib/relaton_ietf.rb +2 -0
- data/relaton_ietf.gemspec +3 -4
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05a6c063cec7b11a826ebe390cc8ebc70974504a70098886a9ac815036428314
|
4
|
+
data.tar.gz: e99a83cfdc93c51e58af1c50baba6a4b518a1895da6a7949cb4fa2e500b56f0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10ec58d5177d45a71079daee30517c3ea040cf5b231ff5fb0688c10818ba7d77b0cd5e61cec478739851a1a460d4b37cec8dcb1d4ce3b53ae2a84bca3300348f
|
7
|
+
data.tar.gz: 4fda1bcdab90ddc307f11d9684016b625d2f7c7221aeb25b9f7fcc1b1679f65b2829833fd982df913e8a7f0dfc910522bf2905dd7555c8da30e80cfa64ae18fb
|
data/.github/workflows/rake.yml
CHANGED
@@ -16,19 +16,9 @@ jobs:
|
|
16
16
|
strategy:
|
17
17
|
fail-fast: false
|
18
18
|
matrix:
|
19
|
-
ruby: [
|
19
|
+
ruby: ['3.0', '2.7', '2.6', '2.5' ]
|
20
20
|
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
21
21
|
experimental: [ false ]
|
22
|
-
include:
|
23
|
-
- ruby: '3.0'
|
24
|
-
os: 'ubuntu-latest'
|
25
|
-
experimental: true
|
26
|
-
- ruby: '3.0'
|
27
|
-
os: 'windows-latest'
|
28
|
-
experimental: true
|
29
|
-
- ruby: '3.0'
|
30
|
-
os: 'macos-latest'
|
31
|
-
experimental: true
|
32
22
|
steps:
|
33
23
|
- uses: actions/checkout@v2
|
34
24
|
with:
|
data/.rubocop.yml
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
# https://github.com/riboseinc/oss-guides
|
3
3
|
# All project-specific additions and overrides should be specified in this file.
|
4
4
|
|
5
|
+
require: rubocop-rails
|
6
|
+
|
5
7
|
inherit_from:
|
6
8
|
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
|
7
9
|
AllCops:
|
8
|
-
TargetRubyVersion: 2.
|
10
|
+
TargetRubyVersion: 2.5
|
9
11
|
Rails:
|
10
12
|
Enabled: false
|
data/README.adoc
CHANGED
@@ -90,6 +90,21 @@ item.to_xml bibdata: true
|
|
90
90
|
</bibdata>"
|
91
91
|
----
|
92
92
|
|
93
|
+
=== Typed links
|
94
|
+
|
95
|
+
IETF documents may have `src`, `xml`, and `doi` link type.
|
96
|
+
|
97
|
+
* `src` - web pulication
|
98
|
+
* `xml` - BibXML publication
|
99
|
+
* `doi` - DOI reference
|
100
|
+
|
101
|
+
[source,ruby]
|
102
|
+
----
|
103
|
+
item.link
|
104
|
+
=> [#<RelatonBib::TypedUri:0x00007fe8b287a120 @content=#<Addressable::URI:0x7e4 URI:https://raw.githubusercontent.com/relaton/relaton-data-ietf/master/data/reference.RFC.8341.xml>, @type="xml">,
|
105
|
+
#<RelatonBib::TypedUri:0x00007fe8b2237ec0 @content=#<Addressable::URI:0x7f8 URI:https://www.rfc-editor.org/info/rfc8341>, @type="src">]
|
106
|
+
----
|
107
|
+
|
93
108
|
=== Parse a file locally
|
94
109
|
|
95
110
|
[source,ruby]
|
@@ -118,6 +133,41 @@ RelatonIetf::IetfBibliographicItem.from_hash hash
|
|
118
133
|
...
|
119
134
|
----
|
120
135
|
|
136
|
+
=== Fetch data
|
137
|
+
|
138
|
+
There is a IETF datasets what can be converted into RelatonXML/BibXML/BibYAML formats:
|
139
|
+
|
140
|
+
- `ietf-rfcsubseries` - https://www.rfc-editor.org/rfc-index.xml (`<bcp-entry>`, `<fyi-entry>`, `<std-entry>`)
|
141
|
+
- `ietf-internet-drafts` - https://www.ietf.org/lib/dt/sprint/bibxml-ids.tgz
|
142
|
+
- `ietf-rfc-entries` - https://www.rfc-editor.org/rfc-index.xml (`<rfc-entry>`)
|
143
|
+
|
144
|
+
The method `RelatonIetf::DataFetcher.fetch(source, output: "data", format: "yaml")` converts all the documents from the dataset and save them to the `./data` folder in YAML format.
|
145
|
+
|
146
|
+
Arguments:
|
147
|
+
|
148
|
+
- `source` - dataset name (`ietf-rfcsubseries` or `ietf-internet-drafts`)
|
149
|
+
- `output` - folder to save documents (default './data').
|
150
|
+
- `format` - format in which the documents are saved. Possimle formats are: `yaml`, `xml`, `bibxml` (default `yaml`).
|
151
|
+
|
152
|
+
For `ietf-rfcsubseries` dataset only special XML format is supported:
|
153
|
+
|
154
|
+
[sourse.xml]
|
155
|
+
----
|
156
|
+
<referencegroup anchor="BCP14" target="https://www.rfc-editor.org/info/bcp14">
|
157
|
+
<xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.2119.xml" />
|
158
|
+
<xi:include href="https://www.rfc-editor.org/refs/bibxml/reference.RFC.8174.xml" />
|
159
|
+
</referencegroup>
|
160
|
+
----
|
161
|
+
|
162
|
+
[source,ruby]
|
163
|
+
----
|
164
|
+
RelatonIetf::DataFetcher.fetch "ietf-internet-drafts"
|
165
|
+
Started at: 2021-12-17 10:23:20 +0100
|
166
|
+
Stopped at: 2021-12-17 10:29:19 +0100
|
167
|
+
Done in: 360 sec.
|
168
|
+
=> nil
|
169
|
+
----
|
170
|
+
|
121
171
|
== Contributing
|
122
172
|
|
123
173
|
Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/relaton-ietf.
|
data/grammars/biblio.rng
CHANGED
data/grammars/ietf.rng
CHANGED
data/grammars/isodoc.rng
CHANGED
@@ -45,6 +45,11 @@
|
|
45
45
|
<optional>
|
46
46
|
<attribute name="alt"/>
|
47
47
|
</optional>
|
48
|
+
<optional>
|
49
|
+
<attribute name="updatetype">
|
50
|
+
<data type="boolean"/>
|
51
|
+
</attribute>
|
52
|
+
</optional>
|
48
53
|
<text/>
|
49
54
|
</element>
|
50
55
|
</define>
|
@@ -199,6 +204,18 @@
|
|
199
204
|
</zeroOrMore>
|
200
205
|
</element>
|
201
206
|
</define>
|
207
|
+
<define name="dt">
|
208
|
+
<element name="dt">
|
209
|
+
<optional>
|
210
|
+
<attribute name="id">
|
211
|
+
<data type="ID"/>
|
212
|
+
</attribute>
|
213
|
+
</optional>
|
214
|
+
<zeroOrMore>
|
215
|
+
<ref name="TextElement"/>
|
216
|
+
</zeroOrMore>
|
217
|
+
</element>
|
218
|
+
</define>
|
202
219
|
<define name="example">
|
203
220
|
<element name="example">
|
204
221
|
<attribute name="id">
|
@@ -543,6 +560,9 @@
|
|
543
560
|
</define>
|
544
561
|
<define name="BibDataExtensionType">
|
545
562
|
<ref name="doctype"/>
|
563
|
+
<optional>
|
564
|
+
<ref name="docsubtype"/>
|
565
|
+
</optional>
|
546
566
|
<optional>
|
547
567
|
<ref name="editorialgroup"/>
|
548
568
|
</optional>
|
@@ -890,6 +910,14 @@
|
|
890
910
|
</define>
|
891
911
|
</include>
|
892
912
|
<!-- end overrides -->
|
913
|
+
<define name="docsubtype">
|
914
|
+
<element name="subdoctype">
|
915
|
+
<ref name="DocumentSubtype"/>
|
916
|
+
</element>
|
917
|
+
</define>
|
918
|
+
<define name="DocumentSubtype">
|
919
|
+
<text/>
|
920
|
+
</define>
|
893
921
|
<define name="colgroup">
|
894
922
|
<element name="colgroup">
|
895
923
|
<oneOrMore>
|
@@ -939,7 +967,34 @@
|
|
939
967
|
<define name="concept">
|
940
968
|
<element name="concept">
|
941
969
|
<optional>
|
942
|
-
<attribute name="
|
970
|
+
<attribute name="ital">
|
971
|
+
<data type="boolean"/>
|
972
|
+
</attribute>
|
973
|
+
</optional>
|
974
|
+
<optional>
|
975
|
+
<attribute name="ref">
|
976
|
+
<data type="boolean"/>
|
977
|
+
</attribute>
|
978
|
+
</optional>
|
979
|
+
<optional>
|
980
|
+
<element name="refterm">
|
981
|
+
<zeroOrMore>
|
982
|
+
<choice>
|
983
|
+
<ref name="PureTextElement"/>
|
984
|
+
<ref name="stem"/>
|
985
|
+
</choice>
|
986
|
+
</zeroOrMore>
|
987
|
+
</element>
|
988
|
+
</optional>
|
989
|
+
<optional>
|
990
|
+
<element name="renderterm">
|
991
|
+
<zeroOrMore>
|
992
|
+
<choice>
|
993
|
+
<ref name="PureTextElement"/>
|
994
|
+
<ref name="stem"/>
|
995
|
+
</choice>
|
996
|
+
</zeroOrMore>
|
997
|
+
</element>
|
943
998
|
</optional>
|
944
999
|
<choice>
|
945
1000
|
<ref name="eref"/>
|
@@ -965,6 +1020,9 @@
|
|
965
1020
|
</attribute>
|
966
1021
|
<attribute name="name"/>
|
967
1022
|
<attribute name="action"/>
|
1023
|
+
<optional>
|
1024
|
+
<attribute name="class"/>
|
1025
|
+
</optional>
|
968
1026
|
<zeroOrMore>
|
969
1027
|
<choice>
|
970
1028
|
<ref name="TextElement"/>
|
@@ -1191,13 +1249,17 @@
|
|
1191
1249
|
</define>
|
1192
1250
|
<define name="IsoWorkgroup">
|
1193
1251
|
<optional>
|
1194
|
-
<attribute name="number"
|
1195
|
-
<data type="int"/>
|
1196
|
-
</attribute>
|
1252
|
+
<attribute name="number"/>
|
1197
1253
|
</optional>
|
1198
1254
|
<optional>
|
1199
1255
|
<attribute name="type"/>
|
1200
1256
|
</optional>
|
1257
|
+
<optional>
|
1258
|
+
<attribute name="identifier"/>
|
1259
|
+
</optional>
|
1260
|
+
<optional>
|
1261
|
+
<attribute name="prefix"/>
|
1262
|
+
</optional>
|
1201
1263
|
<text/>
|
1202
1264
|
</define>
|
1203
1265
|
<define name="ics">
|
@@ -1459,26 +1521,26 @@
|
|
1459
1521
|
<optional>
|
1460
1522
|
<ref name="section-title"/>
|
1461
1523
|
</optional>
|
1462
|
-
<
|
1524
|
+
<choice>
|
1463
1525
|
<choice>
|
1464
1526
|
<group>
|
1465
|
-
<
|
1527
|
+
<oneOrMore>
|
1466
1528
|
<ref name="BasicBlock"/>
|
1467
|
-
</
|
1529
|
+
</oneOrMore>
|
1468
1530
|
<zeroOrMore>
|
1469
1531
|
<ref name="note"/>
|
1470
1532
|
</zeroOrMore>
|
1471
1533
|
</group>
|
1472
1534
|
<ref name="amend"/>
|
1473
1535
|
</choice>
|
1474
|
-
<
|
1536
|
+
<oneOrMore>
|
1475
1537
|
<choice>
|
1476
1538
|
<ref name="clause-subsection"/>
|
1477
1539
|
<ref name="terms"/>
|
1478
1540
|
<ref name="definitions"/>
|
1479
1541
|
</choice>
|
1480
|
-
</
|
1481
|
-
</
|
1542
|
+
</oneOrMore>
|
1543
|
+
</choice>
|
1482
1544
|
</define>
|
1483
1545
|
<define name="Annex-Section">
|
1484
1546
|
<optional>
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rubygems/package"
|
3
|
+
require "zlib"
|
4
|
+
require "relaton_ietf/rfc_index_entry"
|
5
|
+
require "relaton_ietf/rfc_entry"
|
6
|
+
|
7
|
+
module RelatonIetf
|
8
|
+
class DataFetcher
|
9
|
+
#
|
10
|
+
# Data fetcher initializer
|
11
|
+
#
|
12
|
+
# @param [String] source source name
|
13
|
+
# @param [String] output directory to save files
|
14
|
+
# @param [String] format format of output files (xml, yaml, bibxml);
|
15
|
+
# for ietf-rfcsubseries source only: xml
|
16
|
+
#
|
17
|
+
def initialize(source, output, format)
|
18
|
+
@source = source
|
19
|
+
@output = output
|
20
|
+
@format = source == "ietf-rfcsubseries" ? "rfcxml" : format
|
21
|
+
@ext = @format.sub(/^bib|^rfc/, "")
|
22
|
+
@files = []
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Initialize fetcher and run fetch
|
27
|
+
#
|
28
|
+
# @param [String] source source name
|
29
|
+
# @param [Strin] output directory to save files, default: "data"
|
30
|
+
# @param [Strin] format format of output files (xml, yaml, bibxml);
|
31
|
+
# default: yaml; for ietf-rfcsubseries source only: xml
|
32
|
+
#
|
33
|
+
def self.fetch(source, output: "data", format: "yaml")
|
34
|
+
t1 = Time.now
|
35
|
+
puts "Started at: #{t1}"
|
36
|
+
FileUtils.mkdir_p output unless Dir.exist? output
|
37
|
+
new(source, output, format).fetch
|
38
|
+
t2 = Time.now
|
39
|
+
puts "Stopped at: #{t2}"
|
40
|
+
puts "Done in: #{(t2 - t1).round} sec."
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Fetch documents
|
45
|
+
#
|
46
|
+
def fetch
|
47
|
+
case @source
|
48
|
+
when "ietf-rfcsubseries" then fetch_ieft_rfcsubseries
|
49
|
+
when "ietf-internet-drafts" then fetch_ieft_internet_drafts
|
50
|
+
when "ietf-rfc-entries" then fetch_ieft_rfcs
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Fetches ietf-rfcsubseries documents
|
56
|
+
#
|
57
|
+
def fetch_ieft_rfcsubseries
|
58
|
+
rfc_index.xpath("xmlns:bcp-entry|xmlns:fyi-entry|xmlns:std-entry").each do |doc|
|
59
|
+
save_doc RfcIndexEntry.parse(doc)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Fetches ietf-internet-drafts documents
|
65
|
+
#
|
66
|
+
def fetch_ieft_internet_drafts # rubocop:disable Metrics/MethodLength
|
67
|
+
gz = OpenURI.open_uri("https://www.ietf.org/lib/dt/sprint/bibxml-ids.tgz")
|
68
|
+
z = Zlib::GzipReader.new(gz)
|
69
|
+
io = StringIO.new(z.read)
|
70
|
+
z.close
|
71
|
+
Gem::Package::TarReader.new io do |tar|
|
72
|
+
tar.each do |tarfile|
|
73
|
+
next if tarfile.directory?
|
74
|
+
|
75
|
+
save_doc RelatonBib::BibXMLParser.parse(tarfile.read)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def fetch_ieft_rfcs
|
81
|
+
rfc_index.xpath("xmlns:rfc-entry").each do |doc|
|
82
|
+
save_doc RfcEntry.parse(doc)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def rfc_index
|
87
|
+
uri = URI "https://www.rfc-editor.org/rfc-index.xml"
|
88
|
+
Nokogiri::XML(Net::HTTP.get(uri)).at("/xmlns:rfc-index")
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Save document to file
|
93
|
+
#
|
94
|
+
# @param [RelatonIetf::RfcIndexEntry, nil] rfc index entry
|
95
|
+
#
|
96
|
+
def save_doc(entry) # rubocop:disable Metrics/MethodLength
|
97
|
+
return unless entry
|
98
|
+
|
99
|
+
c = case @format
|
100
|
+
when "xml" then entry.to_xml(bibdata: true)
|
101
|
+
when "yaml" then entry.to_hash.to_yaml
|
102
|
+
when "rfcxml" then entry.to_xml
|
103
|
+
else entry.send("to_#{@format}")
|
104
|
+
end
|
105
|
+
file = file_name entry
|
106
|
+
if @files.include? file
|
107
|
+
warn "File #{file} already exists. Document: #{entry.docnumber}"
|
108
|
+
else
|
109
|
+
@files << file
|
110
|
+
end
|
111
|
+
File.write file, c, encoding: "UTF-8"
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Generate file name
|
116
|
+
#
|
117
|
+
# @param [RelatonIetf::RfcIndexEntry] entry
|
118
|
+
#
|
119
|
+
# @return [String] file name
|
120
|
+
#
|
121
|
+
def file_name(entry)
|
122
|
+
id = if entry.respond_to? :docidentifier
|
123
|
+
entry.docidentifier.detect { |i| i.type == "Internet-Draft" }&.id
|
124
|
+
end
|
125
|
+
id ||= entry.docnumber
|
126
|
+
name = id.gsub(/[\s,:\/]/, "_").squeeze("_").upcase
|
127
|
+
File.join @output, "#{name}.#{@ext}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -21,7 +21,7 @@ module RelatonIetf
|
|
21
21
|
# @return [RelatonIetf::IetfBibliographicItem]
|
22
22
|
def self.from_hash(hash)
|
23
23
|
item_hash = ::RelatonIetf::HashConverter.hash_to_bib(hash)
|
24
|
-
new
|
24
|
+
new(**item_hash)
|
25
25
|
end
|
26
26
|
|
27
27
|
# @param opts [Hash]
|
@@ -32,7 +32,7 @@ module RelatonIetf
|
|
32
32
|
# @return [String] XML
|
33
33
|
def to_xml(**opts)
|
34
34
|
opts[:date_format] ||= :short
|
35
|
-
super
|
35
|
+
super(**opts)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -3,11 +3,12 @@ require "relaton_ietf/xml_parser"
|
|
3
3
|
|
4
4
|
module RelatonIetf
|
5
5
|
class Processor < Relaton::Processor
|
6
|
-
def initialize
|
6
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
7
7
|
@short = :relaton_ietf
|
8
8
|
@prefix = "IETF"
|
9
9
|
@defaultprefix = /^RFC /
|
10
10
|
@idtype = "IETF"
|
11
|
+
@datasets = %w[ietf-rfcsubseries ietf-internet-drafts ietf-rfc-entries]
|
11
12
|
end
|
12
13
|
|
13
14
|
# @param code [String]
|
@@ -18,6 +19,18 @@ module RelatonIetf
|
|
18
19
|
::RelatonIetf::IetfBibliography.get(code, date, opts)
|
19
20
|
end
|
20
21
|
|
22
|
+
#
|
23
|
+
# Fetch all the documents from https://www.rfc-editor.org/rfc-index.xml
|
24
|
+
#
|
25
|
+
# @param [String] source source name
|
26
|
+
# @param [Hash] opts
|
27
|
+
# @option opts [String] :output directory to output documents
|
28
|
+
# @option opts [String] :format
|
29
|
+
#
|
30
|
+
def fetch_data(source, opts)
|
31
|
+
DataFetcher.fetch(source, **opts)
|
32
|
+
end
|
33
|
+
|
21
34
|
# @param xml [String]
|
22
35
|
# @return [RelatonIetf::IetfBibliographicItem]
|
23
36
|
def from_xml(xml)
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module RelatonIetf
|
2
|
+
class RfcEntry
|
3
|
+
#
|
4
|
+
# Initalize parser
|
5
|
+
#
|
6
|
+
# @param [Nokogiri::XML::Element] doc document
|
7
|
+
#
|
8
|
+
def initialize(doc)
|
9
|
+
@doc = doc
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Initialize parser & parse document
|
14
|
+
#
|
15
|
+
# @param [Nokogiri::XML::Element] doc document
|
16
|
+
#
|
17
|
+
# @return [RelatonIetf::IetfBibliographicItem] bib item
|
18
|
+
#
|
19
|
+
def self.parse(doc)
|
20
|
+
new(doc).parse
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Parse document
|
25
|
+
#
|
26
|
+
# @return [RelatonIetf::IetfBibliographicItem] bib item
|
27
|
+
#
|
28
|
+
def parse # rubocop:disable Metrics/MethodLength
|
29
|
+
IetfBibliographicItem.new(
|
30
|
+
type: "standard",
|
31
|
+
language: ["en"],
|
32
|
+
script: ["Latn"],
|
33
|
+
fetched: Date.today.to_s,
|
34
|
+
docid: parse_docid,
|
35
|
+
docnumber: code,
|
36
|
+
title: parse_title,
|
37
|
+
link: parse_link,
|
38
|
+
date: parse_date,
|
39
|
+
contributor: parse_contributor,
|
40
|
+
keyword: parse_keyword,
|
41
|
+
abstract: parse_abstract,
|
42
|
+
relation: parse_relation,
|
43
|
+
status: parse_status,
|
44
|
+
editorialgroup: parse_editorialgroup,
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Parse document identifiers
|
50
|
+
#
|
51
|
+
# @return [Array<RelatonBib::DocumentIdettifier>] document identifiers
|
52
|
+
#
|
53
|
+
def parse_docid
|
54
|
+
ids = [RelatonBib::DocumentIdentifier.new(id: pub_id, type: "IETF")]
|
55
|
+
doi = @doc.at("./xmlns:doi").text
|
56
|
+
ids << RelatonBib::DocumentIdentifier.new(id: doi, type: "DOI")
|
57
|
+
ids
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Parse document title
|
62
|
+
#
|
63
|
+
# @return [Array<RelatonBib::TypedTileString>] document title
|
64
|
+
#
|
65
|
+
def parse_title
|
66
|
+
content = @doc.at("./xmlns:title").text
|
67
|
+
[RelatonBib::TypedTitleString.new(content: content, type: "main")]
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Create PubID
|
72
|
+
#
|
73
|
+
# @return [String] PubID
|
74
|
+
#
|
75
|
+
def pub_id
|
76
|
+
"IETF #{code}"
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Parse document code
|
81
|
+
#
|
82
|
+
# @return [String] document code
|
83
|
+
#
|
84
|
+
def code
|
85
|
+
@doc.at("./xmlns:doc-id").text
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Create link
|
90
|
+
#
|
91
|
+
# @return [Array<RelatonBib::TypedUri>]
|
92
|
+
#
|
93
|
+
def parse_link
|
94
|
+
num = code[-4..-1].sub(/^0+/, "")
|
95
|
+
url = "https://www.rfc-editor.org/info/rfc#{num}"
|
96
|
+
[RelatonBib::TypedUri.new(content: url, type: "src")]
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Parse document date
|
101
|
+
#
|
102
|
+
# @return [Array<RelatonBib::BibliographicDate>] document date
|
103
|
+
#
|
104
|
+
def parse_date
|
105
|
+
@doc.xpath("./xmlns:date").map do |date|
|
106
|
+
month = date.at("./xmlns:month").text
|
107
|
+
year = date.at("./xmlns:year").text
|
108
|
+
on = "#{year}-#{Date::MONTHNAMES.index(month).to_s.rjust(2, '0')}"
|
109
|
+
RelatonBib::BibliographicDate.new(on: on, type: "published")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Parse document contributors
|
115
|
+
#
|
116
|
+
# @return [Array<RelatonBib::ContributionInfo>] document contributors
|
117
|
+
#
|
118
|
+
def parse_contributor
|
119
|
+
@doc.xpath("./xmlns:author").map do |contributor|
|
120
|
+
n = contributor.at("./xmlns:name").text
|
121
|
+
name = RelatonBib::LocalizedString.new( n, "en", "Latn")
|
122
|
+
fname = RelatonBib::FullName.new(completename: name)
|
123
|
+
person = RelatonBib::Person.new(name: fname)
|
124
|
+
RelatonBib::ContributionInfo.new(entity: person, role: [{ type: "author" }])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Parse document keywords
|
130
|
+
#
|
131
|
+
# @return [Array<String>] document keywords
|
132
|
+
#
|
133
|
+
def parse_keyword
|
134
|
+
@doc.xpath("./xmlns:keywords/xmlns:kw").map &:text
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Parse document abstract
|
139
|
+
#
|
140
|
+
# @return [Array<RelatonBib::FormattedString>] document abstract
|
141
|
+
#
|
142
|
+
def parse_abstract
|
143
|
+
@doc.xpath("./xmlns:abstract").map do |c|
|
144
|
+
RelatonBib::FormattedString.new(content: c.text, language: "en",
|
145
|
+
script: "Latn", format: "text/html")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Parse document relations
|
151
|
+
#
|
152
|
+
# @return [Arra<RelatonBib::DocumentRelation>] document relations
|
153
|
+
#
|
154
|
+
def parse_relation
|
155
|
+
types = { "updates" => "updates", "obsoleted-by" => "obsoletedBy"}
|
156
|
+
@doc.xpath("./xmlns:updates/xmlns:doc-id|./xmlns:obsoleted-by/xmlns:doc-id").map do |r|
|
157
|
+
fref = RelatonBib::FormattedRef.new(content: r.text)
|
158
|
+
bib = IetfBibliographicItem.new(formattedref: fref)
|
159
|
+
RelatonBib::DocumentRelation.new(type: types[r.parent.name], bibitem: bib)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Parse document status
|
165
|
+
#
|
166
|
+
# @return [RelatonBib::DocuemntStatus] document status
|
167
|
+
#
|
168
|
+
def parse_status
|
169
|
+
stage = @doc.at("./xmlns:current-status").text
|
170
|
+
RelatonBib::DocumentStatus.new(stage: stage)
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# Parse document editorial group
|
175
|
+
#
|
176
|
+
# @return [RelatonBib::EditorialGroup] document editorial group
|
177
|
+
#
|
178
|
+
def parse_editorialgroup
|
179
|
+
tc = @doc.xpath("./xmlns:wg_acronym").map do |wg|
|
180
|
+
wg = RelatonBib::WorkGroup.new(name: wg.text)
|
181
|
+
RelatonBib::TechnicalCommittee.new(wg)
|
182
|
+
end
|
183
|
+
RelatonBib::EditorialGroup.new(tc)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|