relaton-ietf 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f9bf4b1db7471743fbce87d242ebd9f8a7a59630
4
+ data.tar.gz: deb0f7674386a76f577671a1f6f883249ffe0beb
5
+ SHA512:
6
+ metadata.gz: fc38e9bdf1be20eaeb09b3b6b42783af101a40ac3f1e3238d46d23a1612cb5dbc8748d43079db05338c0d9dc28ae4998dcd1684f81236367297276675c398876
7
+ data.tar.gz: 38d10c12570ff5836b1421776b8eedde6f3ccc7118ef78b2db4fb25ef51a7a5229600a2eedc7ef5cee7d5a8b1f4e2be59bbc8b1b8d23e5ae8faab38fe6b05a2f
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .vscode/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+ .rubocop-https---raw-githubusercontent-com-riboseinc-oss-guides-master-ci-rubocop-yml
data/.hound.yml ADDED
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ Enabled: true
3
+ config_file: .rubocop.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ # This project follows the Ribose OSS style guide.
2
+ # https://github.com/riboseinc/oss-guides
3
+ # All project-specific additions and overrides should be specified in this file.
4
+
5
+ inherit_from:
6
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
7
+ AllCops:
8
+ TargetRubyVersion: 2.3
9
+ Rails:
10
+ Enabled: true
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ # Auto-generated !!! Do not edit it manually
2
+ # use ci-master https://github.com/metanorma/metanorma-build-scripts
3
+ language: ruby
4
+ cache: bundler
5
+ os:
6
+ - linux
7
+ - osx
8
+ rvm:
9
+ - 2.5
10
+ - 2.4
11
+ - ruby-head
12
+ before_install:
13
+ - gem install bundler -v 2.0.1
14
+ - bundle update
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ Encoding.default_external = Encoding::UTF_8
2
+ Encoding.default_internal = Encoding::UTF_8
3
+
4
+ source "https://rubygems.org"
5
+
6
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
7
+
8
+ # Specify your gem's dependencies in relaton_ietf.gemspec
9
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ relaton-ietf (0.1.0)
5
+ relaton-iso-bib (~> 0.1.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.6.0)
11
+ public_suffix (>= 2.0.2, < 4.0)
12
+ byebug (11.0.1)
13
+ coderay (1.1.2)
14
+ crack (0.4.3)
15
+ safe_yaml (~> 1.0.0)
16
+ debase (0.2.2)
17
+ debase-ruby_core_source (>= 0.10.2)
18
+ debase-ruby_core_source (0.10.4)
19
+ diff-lcs (1.3)
20
+ docile (1.3.1)
21
+ equivalent-xml (0.6.0)
22
+ nokogiri (>= 1.4.3)
23
+ hashdiff (0.4.0)
24
+ isoics (0.1.7)
25
+ json (2.2.0)
26
+ method_source (0.9.2)
27
+ mini_portile2 (2.3.0)
28
+ nokogiri (1.8.5)
29
+ mini_portile2 (~> 2.3.0)
30
+ pry (0.12.2)
31
+ coderay (~> 1.1.0)
32
+ method_source (~> 0.9.0)
33
+ pry-byebug (3.7.0)
34
+ byebug (~> 11.0)
35
+ pry (~> 0.10)
36
+ public_suffix (3.1.0)
37
+ rake (10.5.0)
38
+ relaton-bib (0.1.6)
39
+ addressable
40
+ nokogiri (~> 1.8.4)
41
+ relaton-iso-bib (0.1.0)
42
+ isoics (~> 0.1.6)
43
+ nokogiri (~> 1.8.4)
44
+ relaton-bib (~> 0.1.5)
45
+ ruby_deep_clone (~> 0.8.0)
46
+ rspec (3.8.0)
47
+ rspec-core (~> 3.8.0)
48
+ rspec-expectations (~> 3.8.0)
49
+ rspec-mocks (~> 3.8.0)
50
+ rspec-core (3.8.0)
51
+ rspec-support (~> 3.8.0)
52
+ rspec-expectations (3.8.3)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.8.0)
55
+ rspec-mocks (3.8.0)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.8.0)
58
+ rspec-support (3.8.0)
59
+ ruby-debug-ide (0.6.1)
60
+ rake (>= 0.8.1)
61
+ ruby_deep_clone (0.8.0)
62
+ safe_yaml (1.0.5)
63
+ simplecov (0.16.1)
64
+ docile (~> 1.1)
65
+ json (>= 1.8, < 3)
66
+ simplecov-html (~> 0.10.0)
67
+ simplecov-html (0.10.2)
68
+ vcr (5.0.0)
69
+ webmock (3.5.1)
70
+ addressable (>= 2.3.6)
71
+ crack (>= 0.3.2)
72
+ hashdiff
73
+
74
+ PLATFORMS
75
+ ruby
76
+
77
+ DEPENDENCIES
78
+ bundler (~> 2.0.1)
79
+ debase
80
+ equivalent-xml (~> 0.6)
81
+ pry-byebug
82
+ rake (~> 10.0)
83
+ relaton-ietf!
84
+ rspec (~> 3.0)
85
+ ruby-debug-ide
86
+ simplecov
87
+ vcr
88
+ webmock
89
+
90
+ BUNDLED WITH
91
+ 2.0.1
data/LICENSE.txt ADDED
@@ -0,0 +1,25 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2018, Ribose
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.adoc ADDED
@@ -0,0 +1,124 @@
1
+ = RelatonIetf
2
+
3
+ image:https://img.shields.io/gem/v/relaton-ietf.svg["Gem Version", link="https://rubygems.org/gems/relaton-ietf"]
4
+ image:https://img.shields.io/travis/metanorma/relaton-ietf/master.svg["Build Status", link="https://travis-ci.org/metanorma/relaton-ietf"]
5
+ image:https://ci.appveyor.com/api/projects/status/eirsba4v3nviejs4?svg=true["Appveyor Build Status", link="https://ci.appveyor.com/project/ribose/relaton-ietf"]
6
+ image:https://codeclimate.com/github/metanorma/relaton-ietf/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/relaton-ietf"]
7
+
8
+ _Formerly known as_ `rfcbib`.
9
+
10
+ RelatonIetf is a Ruby gem that search and fetch standards from the https://www.ietf.org[Internet Engineering Task Force (IETF)], including RFCs.
11
+
12
+ The standards scrape form https://www.rfc-editor.org/search/rfc_search.php
13
+
14
+ == Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ [source, ruby]
19
+ ----
20
+ gem 'relaton-ietf'
21
+ ----
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install relaton-ietf
30
+
31
+ == Usage
32
+
33
+ === Search document
34
+
35
+ [source,ruby]
36
+ ----
37
+ require 'relaton_ietf'
38
+
39
+ item = RelatonIetf::IetfBibliography.search 'RFC 8341'
40
+ => #<RelatonIetf::IetfBibliographicItem:0x007fd1875e7f58
41
+ ...
42
+
43
+ # Return nil if document doesn't exist.
44
+ RelatonIetf::IetfBibliography.search '1111'
45
+ 1111.xml: not recognised for RFC
46
+ => nil
47
+ ----
48
+
49
+ === Serialization
50
+
51
+ [source,ruby]
52
+ ----
53
+ item.to_xml
54
+ =>"<bibitem id="RFC8341">
55
+ <fetched>2019-06-05</fetched>
56
+ <title format="text/plain" language="en" script="Latn">Network Configuration Access Control Model</title>
57
+ <uri type="src">https://www.rfc-editor.org/info/rfc8341</uri>
58
+ <docidentifier type="IETF">RFC 8341</docidentifier>
59
+ <docidentifier type="DOI">10.17487/RFC8341</docidentifier>
60
+ <date type="published">
61
+ <on>2018-03</on>
62
+ </date>
63
+ <contributor>
64
+ <role type="author"/>
65
+ <person>
66
+ <name>
67
+ <completename language="en">A. Bierman</completename>
68
+ </name>
69
+ <affiliation>
70
+ <organization>
71
+ <name>IETF</name>
72
+ <abbreviation>IETF</abbreviation>
73
+ </organization>
74
+ </affiliation>
75
+ </person>
76
+ </contributor>
77
+ <contributor>
78
+ <role type="author"/>
79
+ <person>
80
+ <name>
81
+ <completename language="en">M. Bjorklund</completename>
82
+ </name>
83
+ <affiliation>
84
+ <organization>
85
+ <name>IETF</name>
86
+ <abbreviation>IETF</abbreviation>
87
+ </organization>
88
+ </affiliation>
89
+ </person>
90
+ </contributor>
91
+ <language>en</language>
92
+ <script>Latn</script>
93
+ <series type="main">
94
+ <title format="text/plain" language="en" script="Latn">STD</title>
95
+ <number>91</number>
96
+ </series>
97
+ <series type="main">
98
+ <title format="text/plain" language="en" script="Latn">RFC</title>
99
+ <number>8341</number>
100
+ </series>
101
+ </bibitem>"
102
+ ----
103
+ With `bibdata: true` option XML output wrapped with `bibdata` element and `ext` element added.
104
+ [source,ruby]
105
+ ----
106
+ item.to_xml bibdata: true
107
+ =>"<bibdata>
108
+ <fetched>2019-06-05</fetched>
109
+ <title format="text/plain" language="en" script="Latn">Network Configuration Access Control Model</title>
110
+ <uri type="src">https://www.rfc-editor.org/info/rfc8341</uri>
111
+ ...
112
+ <ext>
113
+ <doctype>rfc</doctype>
114
+ </ext>
115
+ </bibdata>"
116
+ ----
117
+
118
+ == Contributing
119
+
120
+ Bug reports and pull requests are welcome on GitHub at https://github.com/metanorma/relaton-ietf.
121
+
122
+ == License
123
+
124
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/appveyor.yml ADDED
@@ -0,0 +1,35 @@
1
+ # Auto-generated !!! Do not edit it manually
2
+ # use ci-master https://github.com/metanorma/metanorma-build-scripts
3
+ version: '{build}'
4
+
5
+ cache:
6
+ - vendor/bundle
7
+
8
+ environment:
9
+ matrix:
10
+ - RUBY_VERSION: 25
11
+ - RUBY_VERSION: 24
12
+ - RUBY_VERSION: _trunk
13
+
14
+ matrix:
15
+ allow_failures:
16
+ - RUBY_VERSION: _trunk
17
+
18
+ install:
19
+ - ps: . { iwr -useb https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/appveyor.ps1 } | iex
20
+ - refreshenv
21
+
22
+ build_script:
23
+ - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
24
+ - set GIT_TERMINAL_PROMPT=0
25
+ - bundle config --local path vendor/bundle
26
+ - bundle update
27
+ - bundle install
28
+
29
+ before_test:
30
+ - ruby -v
31
+ - gem -v
32
+ - bundle -v
33
+
34
+ test_script:
35
+ - bundle exec rake
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "relaton_ietf"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,23 @@
1
+ require "relaton/processor"
2
+ require "relaton_ietf/xml_parser"
3
+
4
+ module Relaton
5
+ module RelatonIetf
6
+ class Processor < Relaton::Processor
7
+ def initialize
8
+ @short = :relaton_ietf
9
+ @prefix = "IETF"
10
+ @defaultprefix = /^RFC /
11
+ @idtype = "IETF"
12
+ end
13
+
14
+ def get(code, date, opts)
15
+ ::RelatonIetf::IetfBibliography.get(code, date, opts)
16
+ end
17
+
18
+ def from_xml(xml)
19
+ ::RelatonIetf::XMLParser.from_xml xml
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "relaton_ietf/version"
4
+ require "relaton_ietf/ietf_bibliography"
5
+ require "relaton_ietf/ietf_bibliographi_item"
6
+ require "relaton_ietf/xml_parser"
7
+
8
+ if defined? Relaton
9
+ require_relative "relaton/processor"
10
+ Relaton::Registry.instance.register(Relaton::RelatonIetf::Processor)
11
+ end
@@ -0,0 +1,25 @@
1
+ module RelatonIetf
2
+ class IetfBibliographicItem < RelatonBib::BibliographicItem
3
+ # @return [String, NilClass]
4
+ attr_reader :doctype
5
+
6
+ def initialize(**args)
7
+ @doctype = args.delete :doctype
8
+ super
9
+ end
10
+
11
+ # @param builder
12
+ # @param opts [Hash]
13
+ # @option opts [Symbol, NilClass] :date_format (:short), :full
14
+ def to_xml(builder = nil, **opts)
15
+ opts[:date_format] ||= :short
16
+ super builder, **opts do |b|
17
+ if opts[:bibdata]
18
+ b.ext do
19
+ b.doctype doctype if doctype
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal:true
2
+
3
+ require "relaton_ietf/scrapper"
4
+
5
+ module RelatonIetf
6
+ # IETF bibliography module
7
+ module IetfBibliography
8
+ class << self
9
+ # @param code [String] the ISO standard Code to look up (e..g "ISO 9000")
10
+ # @return [RelatonIetf::IetfBibliographicItem]
11
+ def search(text)
12
+ Scrapper.scrape_page text
13
+ end
14
+
15
+ # @param code [String] the ISO standard Code to look up (e..g "ISO 9000")
16
+ # @param year [String] the year the standard was published (optional)
17
+ # @param opts [Hash] options; restricted to :all_parts if all-parts reference is required
18
+ # @return [RelatonIetf::IetfBibliographicItem] Relaton of reference
19
+ def get(code, _year = nil, _opts = {})
20
+ search code
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "nokogiri"
5
+ require "relaton_bib"
6
+
7
+ module RelatonIetf
8
+ # rubocop:disable Metrics/ModuleLength
9
+
10
+ # Scrapper module
11
+ module Scrapper
12
+ RFC_URI_PATTERN = "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.CODE"
13
+ ID_URI_PATTERN = "https://xml2rfc.tools.ietf.org/public/rfc/bibxml-ids/reference.CODE"
14
+
15
+ class << self
16
+ # @param text [String]
17
+ # @return [RelatonIetf::IetfBibliographicItem]
18
+ def scrape_page(text)
19
+ # Remove initial "IETF " string if specified
20
+ ref = text.
21
+ gsub(/^IETF /, "").
22
+ sub(" ", ".") + ".xml"
23
+
24
+ case ref
25
+ when /^RFC/
26
+ uri = RFC_URI_PATTERN.dup
27
+ doctype = "rfc"
28
+ when /^I-D/
29
+ uri = ID_URI_PATTERN.dup
30
+ doctype = "internet-draft"
31
+ else
32
+ warn "#{ref}: not recognised for RFC"
33
+ return
34
+ end
35
+
36
+ uri = uri.gsub("CODE", ref)
37
+ begin
38
+ res = Net::HTTP.get_response(URI(uri))
39
+ if res.code != "200"
40
+ warn "No document found at #{uri}"
41
+ return
42
+ end
43
+ doc = Nokogiri::HTML Net::HTTP.get(URI(uri))
44
+ reference = doc.at("//reference")
45
+ return unless reference
46
+
47
+ bib_item reference, doctype
48
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
49
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
50
+ warn "No document found at #{uri}"
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ # rubocop:disable Metrics/MethodLength
57
+
58
+ # @return [RelatonIetf::IetfBibliographicItem]
59
+ def bib_item(reference, doctype)
60
+ RelatonIetf::IetfBibliographicItem.new(
61
+ fetched: Date.today.to_s,
62
+ id: reference[:anchor],
63
+ docid: docids(reference),
64
+ status: status(reference),
65
+ language: [language(reference)],
66
+ script: ["Latn"],
67
+ link: [{ type: "src", content: reference[:target] }],
68
+ titles: titles(reference),
69
+ contributors: contributors(reference),
70
+ dates: dates(reference),
71
+ series: series(reference),
72
+ doctype: doctype,
73
+ )
74
+ end
75
+ # rubocop:enable Metrics/MethodLength
76
+
77
+ # @return [String]
78
+ def language(reference)
79
+ reference[:lang] || "en"
80
+ end
81
+
82
+ # @return [Array<Hash>]
83
+ def titles(reference)
84
+ title = reference.at("./front/title")
85
+ [{ content: title.text, language: language(reference), script: "Latn" }]
86
+ end
87
+
88
+ # @return [Array<Hash>]
89
+ def contributors(reference)
90
+ persons(reference) + organizations(reference)
91
+ end
92
+
93
+ # @return [Array<Hash{Symbol=>RelatonBib::Person,Symbol=>Array<String>}>]
94
+ def persons(reference)
95
+ reference.xpath("./front/author").map do |author|
96
+ entity = RelatonBib::Person.new(
97
+ name: full_name(author, reference),
98
+ affiliation: [affiliation(author)],
99
+ contacts: contacts(author.at("./address")),
100
+ )
101
+ { entity: entity, roles: [contributor_role(author)] }
102
+ end
103
+ end
104
+
105
+ # @return [Array<Hash{Symbol=>RelatonBib::Organization,Symbol=>Array<String>}>]
106
+ def organizations(reference)
107
+ reference.xpath("./seriesinfo").map do |si|
108
+ next unless si[:stream]
109
+
110
+ entity = RelatonBib::Organization.new name: si[:stream]
111
+ { entity: entity, roles: ["author"] }
112
+ end.compact
113
+ end
114
+
115
+ # @param author [Nokogiri::XML::Document]
116
+ # @param ref [Nokogiri::XML::Document]
117
+ # @return [RelatonBib::FullName]
118
+ def full_name(author, ref)
119
+ RelatonBib::FullName.new(
120
+ completename: localized_string(author[:fullname], ref),
121
+ initials: [localized_string(author[:initials], ref)],
122
+ surname: [localized_string(author[:surname], ref)],
123
+ )
124
+ end
125
+
126
+ # @param content [String]
127
+ # @return [RelatonBib::LocalizedString]
128
+ def localized_string(content, ref)
129
+ RelatonBib::LocalizedString.new(content, language(ref))
130
+ end
131
+
132
+ # @param postal [Nokogiri::XML::Document]
133
+ # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
134
+ def contacts(addr)
135
+ contacts = []
136
+ return contacts unless addr
137
+
138
+ postal = addr.at("./postal")
139
+ contacts << address(postal) if postal
140
+ add_contact(contacts, "phone", addr.at("./phone"))
141
+ add_contact(contacts, "email", addr.at("./email"))
142
+ add_contact(contacts, "uri", addr.at("./uri"))
143
+ contacts
144
+ end
145
+
146
+ # @param postal [Nokogiri::XML::Document]
147
+ # @rerurn [RelatonBib::Address]
148
+ def address(postal)
149
+ RelatonBib::Address.new(
150
+ street: [(postal.at("./postalLine") || postal.at("./street"))&.text],
151
+ city: postal.at("./city")&.text,
152
+ postcode: postal.at("./code")&.text,
153
+ country: postal.at("./country")&.text,
154
+ state: postal.at("./region")&.text,
155
+ )
156
+ end
157
+
158
+ # @param type [String] allowed "phone", "email" or "uri"
159
+ # @param value [String]
160
+ def add_contact(contacts, type, value)
161
+ return unless value
162
+
163
+ contacts << RelatonBib::Contact.new(type: type, value: value.text)
164
+ end
165
+
166
+ # @param author [Nokogiri::XML::Document]
167
+ # @return [RelatonBib::Affilation]
168
+ def affiliation(author)
169
+ organization = author.at("./organization")
170
+ RelatonBib::Affilation.new RelatonBib::Organization.new(
171
+ name: organization.text.empty? ? "IETF" : organization.text,
172
+ abbreviation: organization[:abbrev] || "IETF",
173
+ )
174
+ end
175
+
176
+ # @param author [Nokogiri::XML::Document]
177
+ # @return [String]
178
+ def contributor_role(author)
179
+ author[:role] || "author"
180
+ end
181
+
182
+ def month(mon)
183
+ return mon if /^\d+$/ =~ mon
184
+
185
+ Date::MONTHNAMES.index(mon)
186
+ end
187
+
188
+ #
189
+ # Extract date from reference.
190
+ #
191
+ # @return [Array<RelatonBib::BibliographicDate>] published data.
192
+ #
193
+ def dates(reference)
194
+ return unless (date = reference.at "./front/date")
195
+
196
+ d = [date[:year], month(date[:month]),
197
+ (date[:day] || "01")].compact.join "-"
198
+ date = Time.parse(d).strftime "%Y-%m-%d"
199
+ [RelatonBib::BibliographicDate.new(type: "published", on: date)]
200
+ end
201
+
202
+ #
203
+ # Extract document identifiers from reference
204
+ #
205
+ # @return [Array<RelatonBib::DocumentIdentifier>]
206
+ #
207
+ def docids(reference)
208
+ id = reference[:anchor].sub(/^(RFC)/, "\\1 ")
209
+ ret = []
210
+ ret << RelatonBib::DocumentIdentifier.new(type: "IETF", id: id)
211
+ ret + reference.xpath("./seriesinfo").map do |si|
212
+ next unless si[:name] == "DOI"
213
+
214
+ RelatonBib::DocumentIdentifier.new(id: si[:value], type: si[:name])
215
+ end.compact
216
+ end
217
+
218
+ #
219
+ # Extract series form reference
220
+ # @param reference [Nokogiri::XML::Document]
221
+ #
222
+ # @return [Array<RelatonBib::Series>]
223
+ #
224
+ def series(reference)
225
+ reference.xpath("./seriesinfo").map do |si|
226
+ next if si[:name] == "DOI" || si[:stream] || si[:status]
227
+
228
+ RelatonBib::Series.new(
229
+ title: RelatonBib::TypedTitleString.new(
230
+ content: si[:name], language: language(reference), script: "Latn",
231
+ ),
232
+ number: si[:value],
233
+ type: "main",
234
+ )
235
+ end.compact
236
+ end
237
+
238
+ #
239
+ # extract status
240
+ # @param reference [Nokogiri::XML::Document]
241
+ #
242
+ # @return [RelatonBib::DocumentStatus]
243
+ #
244
+ def status(reference)
245
+ st = reference.at("./seriesinfo[@status]")
246
+ return unless st
247
+
248
+ RelatonBib::DocumentStatus.new(
249
+ stage: st[:status],
250
+ )
251
+ end
252
+ end
253
+ end
254
+ # rubocop:enable Metrics/ModuleLength
255
+ end
@@ -0,0 +1,3 @@
1
+ module RelatonIetf
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,24 @@
1
+ require "nokogiri"
2
+
3
+ module RelatonIetf
4
+ class XMLParser < RelatonBib::XMLParser
5
+ class << self
6
+ def from_xml(xml)
7
+ doc = Nokogiri::XML(xml)
8
+ ietfitem = doc.at("/bibitem|/bibdata")
9
+ RelatonIetf::IetfBibliographicItem.new(item_data(ietfitem))
10
+ end
11
+
12
+ private
13
+
14
+ def item_data(ietfitem)
15
+ data = super
16
+ ext = ietfitem.at "./ext"
17
+ return data unless ext
18
+
19
+ data[:doctype] = ext.at("./doctype")&.text
20
+ data
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "relaton_ietf/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "relaton-ietf"
9
+ spec.version = RelatonIetf::VERSION
10
+ spec.authors = ["Ribose Inc."]
11
+ spec.email = ["open.source@ribose.com"]
12
+
13
+ spec.summary = "RelatonIetf: retrieve IETF Standards for bibliographic use "\
14
+ "using the BibliographicItem model"
15
+ spec.description = <<~DESCRIPTION
16
+ RelatonIetf: retrieve IETF Standards for bibliographic use
17
+ using the BibliographicItem model.
18
+
19
+ Formerly known as rfcbib.
20
+ DESCRIPTION
21
+ spec.homepage = "https://github.com/metanorma/relaton-ietf"
22
+ spec.license = "BSD-2-Clause"
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
+ f.match(%r{^(test|spec|features)/})
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
31
+
32
+ spec.add_development_dependency "bundler", "~> 2.0.1"
33
+ spec.add_development_dependency "debase"
34
+ spec.add_development_dependency "equivalent-xml", "~> 0.6"
35
+ spec.add_development_dependency "pry-byebug"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ spec.add_development_dependency "ruby-debug-ide"
39
+ spec.add_development_dependency "simplecov"
40
+ spec.add_development_dependency "vcr"
41
+ spec.add_development_dependency "webmock"
42
+
43
+ spec.add_dependency "relaton-iso-bib", "~> 0.1.0"
44
+ end
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: relaton-ietf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: debase
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: equivalent-xml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-debug-ide
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: vcr
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webmock
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: relaton-iso-bib
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.1.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.1.0
167
+ description: "RelatonIetf: retrieve IETF Standards for bibliographic use \nusing the
168
+ BibliographicItem model.\n\nFormerly known as rfcbib.\n"
169
+ email:
170
+ - open.source@ribose.com
171
+ executables: []
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - ".gitignore"
176
+ - ".hound.yml"
177
+ - ".rspec"
178
+ - ".rubocop.yml"
179
+ - ".travis.yml"
180
+ - Gemfile
181
+ - Gemfile.lock
182
+ - LICENSE.txt
183
+ - README.adoc
184
+ - Rakefile
185
+ - appveyor.yml
186
+ - bin/console
187
+ - bin/setup
188
+ - lib/relaton/processor.rb
189
+ - lib/relaton_ietf.rb
190
+ - lib/relaton_ietf/ietf_bibliographi_item.rb
191
+ - lib/relaton_ietf/ietf_bibliography.rb
192
+ - lib/relaton_ietf/scrapper.rb
193
+ - lib/relaton_ietf/version.rb
194
+ - lib/relaton_ietf/xml_parser.rb
195
+ - relaton_ietf.gemspec
196
+ homepage: https://github.com/metanorma/relaton-ietf
197
+ licenses:
198
+ - BSD-2-Clause
199
+ metadata: {}
200
+ post_install_message:
201
+ rdoc_options: []
202
+ require_paths:
203
+ - lib
204
+ required_ruby_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 2.4.0
209
+ required_rubygems_version: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ requirements: []
215
+ rubyforge_project:
216
+ rubygems_version: 2.6.12
217
+ signing_key:
218
+ specification_version: 4
219
+ summary: 'RelatonIetf: retrieve IETF Standards for bibliographic use using the BibliographicItem
220
+ model'
221
+ test_files: []