relaton-ietf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []