relaton-cli 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d4d41d778eecd0614bc7d9f086db2362d594725
4
- data.tar.gz: 5a66a9da159d1c903c35764727e0755e52511919
3
+ metadata.gz: 5ed0978daca08db19cf521cb107ae61dd8813e83
4
+ data.tar.gz: 75351c878a675899a2940445f2bcbdc3a0f6c0c4
5
5
  SHA512:
6
- metadata.gz: 429b613fd45f18bf24a5af73b01c4091dcfbb93e820af393af1b58c338e99a69f34a22adc6ac2a282e250ccf54827eb2fdb02ba5b759be34cc7a2c18fc4f2f21
7
- data.tar.gz: affff06b90bfcd54bc299aedacf129cbf1e12181146fedda6300d6890b12fc7b05ee31492a8b68475da8de09410d55e43b413a8e0c0b46a82469b33bd834a447
6
+ metadata.gz: 1e3aa4062f36e4efa669168efd8d61d19cd3ea0b353829792db1773d86c40d7e78103758c03b726449095d92cf90b8a6dc48b12acb6e40de5686ed56ccc43c48
7
+ data.tar.gz: 81792ae0b803346660ea2f3cc1ccbea871b2223fdc32d13b864238b2f94e3dcc8c63a2a9d0df1ed9a34bd0191c63871af573806bc74ad79406025ee25f2366cc
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
data/.travis.yml CHANGED
@@ -6,11 +6,12 @@ os:
6
6
  - linux
7
7
  - osx
8
8
  rvm:
9
+ - 2.6
9
10
  - 2.5
10
11
  - 2.4
11
12
  - ruby-head
12
13
  before_install:
13
- - gem install bundler -v 2.0.1
14
+ - gem install bundler -v "~> 2"
14
15
  - bundle update
15
16
  matrix:
16
17
  allow_failures:
data/Gemfile.lock ADDED
@@ -0,0 +1,116 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ relaton-cli (0.2.2)
5
+ liquid
6
+ relaton (~> 0.4)
7
+ thor
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.6.0)
13
+ public_suffix (>= 2.0.2, < 4.0)
14
+ algoliasearch (1.26.0)
15
+ httpclient (~> 2.8, >= 2.8.3)
16
+ json (>= 1.5.1)
17
+ byebug (10.0.2)
18
+ cnccs (0.1.3)
19
+ coderay (1.1.2)
20
+ debase (0.2.2)
21
+ debase-ruby_core_source (>= 0.10.2)
22
+ debase-ruby_core_source (0.10.5)
23
+ diff-lcs (1.3)
24
+ equivalent-xml (0.6.0)
25
+ nokogiri (>= 1.4.3)
26
+ gb-agencies (0.0.5)
27
+ httpclient (2.8.3)
28
+ isoics (0.1.7)
29
+ json (2.2.0)
30
+ liquid (4.0.3)
31
+ method_source (0.9.2)
32
+ mini_portile2 (2.4.0)
33
+ mixlib-shellout (2.4.4)
34
+ nokogiri (1.10.3)
35
+ mini_portile2 (~> 2.4.0)
36
+ pry (0.12.2)
37
+ coderay (~> 1.1.0)
38
+ method_source (~> 0.9.0)
39
+ public_suffix (3.1.1)
40
+ rake (12.3.2)
41
+ relaton (0.4.5)
42
+ algoliasearch
43
+ relaton-gb (~> 0.5.0)
44
+ relaton-iec (~> 0.3.0)
45
+ relaton-ietf (~> 0.5.0)
46
+ relaton-iso (~> 0.5.0)
47
+ relaton-iso-bib (~> 0.2.0)
48
+ relaton-itu (~> 0.2.0)
49
+ relaton-nist (~> 0.2.0)
50
+ relaton-bib (0.2.5)
51
+ addressable
52
+ nokogiri (~> 1.10)
53
+ relaton-gb (0.5.2)
54
+ cnccs (~> 0.1.1)
55
+ gb-agencies (~> 0.0.1)
56
+ relaton-iso-bib (~> 0.2.0)
57
+ relaton-iec (0.3.2)
58
+ addressable
59
+ relaton-iso-bib (~> 0.2.0)
60
+ relaton-ietf (0.5.5)
61
+ relaton-iso-bib (~> 0.2.0)
62
+ relaton-iso (0.5.5)
63
+ relaton-iec (~> 0.3.0)
64
+ relaton-iso-bib (~> 0.2.0)
65
+ relaton-iso-bib (0.2.4)
66
+ isoics (~> 0.1.6)
67
+ relaton-bib (~> 0.2.0)
68
+ ruby_deep_clone (~> 0.8.0)
69
+ relaton-itu (0.2.3)
70
+ relaton-iso-bib (~> 0.2.0)
71
+ relaton-nist (0.2.3)
72
+ relaton-bib (~> 0.2.0)
73
+ rubyzip
74
+ rspec (3.8.0)
75
+ rspec-core (~> 3.8.0)
76
+ rspec-expectations (~> 3.8.0)
77
+ rspec-mocks (~> 3.8.0)
78
+ rspec-command (1.0.3)
79
+ mixlib-shellout (~> 2.0)
80
+ rspec (~> 3.2)
81
+ rspec-its (~> 1.2)
82
+ rspec-core (3.8.1)
83
+ rspec-support (~> 3.8.0)
84
+ rspec-expectations (3.8.4)
85
+ diff-lcs (>= 1.2.0, < 2.0)
86
+ rspec-support (~> 3.8.0)
87
+ rspec-its (1.3.0)
88
+ rspec-core (>= 3.0.0)
89
+ rspec-expectations (>= 3.0.0)
90
+ rspec-mocks (3.8.1)
91
+ diff-lcs (>= 1.2.0, < 2.0)
92
+ rspec-support (~> 3.8.0)
93
+ rspec-support (3.8.2)
94
+ ruby-debug-ide (0.7.0)
95
+ rake (>= 0.8.1)
96
+ ruby_deep_clone (0.8.0)
97
+ rubyzip (1.2.3)
98
+ thor (0.20.3)
99
+
100
+ PLATFORMS
101
+ ruby
102
+
103
+ DEPENDENCIES
104
+ byebug (~> 10.0)
105
+ debase
106
+ equivalent-xml (~> 0.6)
107
+ pry
108
+ rake (~> 12.0)
109
+ relaton-cli!
110
+ rspec (~> 3.0)
111
+ rspec-command (~> 1.0.3)
112
+ rspec-core (~> 3.4)
113
+ ruby-debug-ide
114
+
115
+ BUNDLED WITH
116
+ 2.0.1
data/appveyor.yml CHANGED
@@ -7,6 +7,7 @@ cache:
7
7
 
8
8
  environment:
9
9
  matrix:
10
+ - RUBY_VERSION: 26
10
11
  - RUBY_VERSION: 25
11
12
  - RUBY_VERSION: 24
12
13
  - RUBY_VERSION: _trunk
@@ -22,6 +23,7 @@ install:
22
23
  build_script:
23
24
  - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
24
25
  - set GIT_TERMINAL_PROMPT=0
26
+ - gem install bundler -v "~> 2"
25
27
  - bundle config --local path vendor/bundle
26
28
  - bundle update
27
29
  - bundle install
@@ -40,7 +40,7 @@ module Relaton
40
40
  author = find_text("./relaton-collection/contributor[role/@type = 'author']/organization/name", source)
41
41
 
42
42
  items = find_xpath("./relaton-collection/relation", source)&.map do |item|
43
- bibdata = find("./bibdata", item)
43
+ bibdata = find("./bibdata | ./bibitem", item)
44
44
  klass = bibdata ? Bibdata : Bibcollection
45
45
  klass.from_xml(bibdata || item)
46
46
  end
@@ -70,7 +70,7 @@ module Relaton
70
70
  end
71
71
  end
72
72
 
73
- def to_xml
73
+ def to_xml(opts = {})
74
74
  items.sort_by! do |b|
75
75
  b.doc_number
76
76
  end
@@ -89,7 +89,7 @@ module Relaton
89
89
  unless items.empty?
90
90
  items.each do |item|
91
91
  ret += "<relation type='partOf'>"
92
- ret += item.to_xml
92
+ ret += item.to_xml(opts)
93
93
  ret += "</relation>\n"
94
94
  end
95
95
  end
@@ -0,0 +1,119 @@
1
+ require "relaton/element_finder"
2
+
3
+ module Relaton
4
+ class BibcollectionNew
5
+ extend Relaton::ElementFinder
6
+
7
+ ATTRIBS = %i[
8
+ title
9
+ items
10
+ doctype
11
+ author
12
+ ]
13
+
14
+ attr_accessor *ATTRIBS
15
+
16
+ def initialize(options)
17
+ self.items = []
18
+ ATTRIBS.each do |k|
19
+ value = options[k] || options[k.to_s]
20
+ self.send("#{k}=", value)
21
+ end
22
+ self.items = (self.items || []).inject([]) do |acc,item|
23
+ acc << if item.is_a?(::Relaton::BibcollectionNew) ||
24
+ item.is_a?(::RelatonBib::BibliographicItem)
25
+ item
26
+ else
27
+ new_bib_item_class(item)
28
+ end
29
+ end
30
+ self
31
+ end
32
+
33
+ # arbitrary number, must sort after all bib items
34
+ def doc_number
35
+ 9999999
36
+ end
37
+
38
+ def self.from_xml(source)
39
+ title = find_text("./relaton-collection/title", source)
40
+ author = find_text("./relaton-collection/contributor[role/@type = 'author']/organization/name", source)
41
+
42
+ items = find_xpath("./relaton-collection/relation", source)&.map do |item|
43
+ bibdata = find("./bibdata", item)
44
+ klass = bibdata ? Bibdata : BibcollectionNew
45
+ klass.from_xml(bibdata || item)
46
+ end
47
+
48
+ new(title: title, author: author, items: items)
49
+ end
50
+
51
+ def new_bib_item_class(options)
52
+ if options["items"]
53
+ ::Relaton::BibcollectionNew.new(options)
54
+ else
55
+ ::RelatonBib::BibliographicItem.new(options)
56
+ end
57
+ end
58
+
59
+ def items_flattened
60
+ items.sort_by! do |b|
61
+ b.docnumber
62
+ end
63
+
64
+ items.inject([]) do |acc,item|
65
+ if item.is_a? ::Relaton::BibcollectionNew
66
+ acc << item.items_flattened
67
+ else
68
+ acc << item
69
+ end
70
+ end
71
+ end
72
+
73
+ def to_xml(opts)
74
+ items.sort_by! do |b|
75
+ b.docnumber
76
+ end
77
+
78
+ collection_type = if doctype
79
+ "type=\"#{doctype}\""
80
+ else
81
+ 'xmlns="https://open.ribose.com/relaton-xml"'
82
+ end
83
+
84
+ ret = "<relaton-collection #{collection_type}>"
85
+ ret += "<title>#{title}</title>" if title
86
+ if author
87
+ ret += "<contributor><role type='author'/><organization><name>#{author}</name></organization></contributor>"
88
+ end
89
+ unless items.empty?
90
+ items.each do |item|
91
+ ret += "<relation type='partOf'>"
92
+ ret += item.to_xml(opts)
93
+ ret += "</relation>\n"
94
+ end
95
+ end
96
+ ret += "</relaton-collection>\n"
97
+ end
98
+
99
+ def to_yaml
100
+ to_h.to_yaml
101
+ end
102
+
103
+ def to_h
104
+ items.sort_by! do |b|
105
+ b.doc_number
106
+ end
107
+
108
+ a = ATTRIBS.inject({}) do |acc, k|
109
+ acc[k.to_s] = send(k)
110
+ acc
111
+ end
112
+
113
+ a["items"] = a["items"].map(&:to_h)
114
+
115
+ { "root" => a }
116
+ end
117
+
118
+ end
119
+ end
@@ -61,7 +61,7 @@ module Relaton
61
61
  new(Relaton::XmlDocument.parse(source))
62
62
  end
63
63
 
64
- def to_xml
64
+ def to_xml(opts = {})
65
65
  #datetype = stage&.casecmp("published") == 0 ? "published" : "circulated"
66
66
 
67
67
  ret = ref ? "<bibitem id= '#{ref}' type='#{doctype}'>\n" : "<bibdata type='#{doctype}'>\n"
@@ -1,6 +1,7 @@
1
1
  require "fileutils"
2
2
  require "relaton/bibdata"
3
3
  require "relaton/bibcollection"
4
+ require "relaton/bibcollectionnew"
4
5
  require "relaton/cli/xml_to_html_renderer"
5
6
 
6
7
  module Relaton
@@ -12,6 +13,7 @@ module Relaton
12
13
  @outdir = options.fetch(:outdir, nil)
13
14
  @writable = options.fetch(:write, true)
14
15
  @overwrite = options.fetch(:overwrite, true)
16
+ @default_filelabel = 0
15
17
 
16
18
  install_dependencies(options[:require] || [])
17
19
  end
@@ -64,9 +66,16 @@ module Relaton
64
66
  dependencies.each { |dependency| require(dependency) }
65
67
  end
66
68
 
69
+ def item_output(content, format)
70
+ case format.to_sym
71
+ when :to_yaml then content.to_yaml
72
+ when :to_xml then content.to_xml(date_format: :full)
73
+ end
74
+ end
75
+
67
76
  def convert_and_write(content, format)
68
77
  content = convert_content(content)
69
- write_to_a_file(content.send(format.to_sym))
78
+ write_to_a_file(item_output(content, format))
70
79
  write_to_file_collection(content, format.to_sym)
71
80
  end
72
81
 
@@ -79,16 +88,40 @@ module Relaton
79
88
  end
80
89
 
81
90
  def write_to_file_collection(content, format)
82
- if outdir && content.is_a?(Relaton::Bibcollection)
91
+ if outdir && (content.is_a?(Relaton::Bibcollection))
83
92
  FileUtils.mkdir_p(outdir)
84
-
85
93
  content.items_flattened.each do |item|
86
94
  collection = collection_filename(item.docidentifier_code)
87
- write_to_a_file(item.send(format.to_sym), collection)
95
+ write_to_a_file(item_output(item, format), collection)
96
+ end
97
+ end
98
+ if outdir && (content.is_a?(Relaton::BibcollectionNew))
99
+ FileUtils.mkdir_p(outdir)
100
+ content.items_flattened.each do |item|
101
+ collection = collection_filename(extract_docid(item))
102
+ write_to_a_file(item_output(item, format), collection)
88
103
  end
89
104
  end
90
105
  end
91
106
 
107
+ def extract_docid(item)
108
+ @default_filelabel += 1
109
+ item.docidentifier.nil? and return @default_filelabel.to_s
110
+ item.docidentifier.is_a?(Array) or return @default_filelabel.to_s
111
+ item.docidentifier.empty? and return @default_filelabel.to_s
112
+ docidentifier_code(item.docidentifier[0].id)
113
+ end
114
+
115
+ # From http://gavinmiller.io/2016/creating-a-secure-sanitization-function/
116
+ FILENAME_BAD_CHARS = [ '/', '\\', '?', '%', '*', ':', '|', '"', '<', '>', '.', ' ' ]
117
+
118
+ def docidentifier_code(docidentifier)
119
+ return "" if docidentifier.nil?
120
+ a = FILENAME_BAD_CHARS.inject(docidentifier.downcase) do |result, bad_char|
121
+ result.gsub(bad_char, '-')
122
+ end
123
+ end
124
+
92
125
  def extension
93
126
  @extension ||= [".", options.fetch(:extension, default_ext)].join
94
127
  end
@@ -1,6 +1,7 @@
1
1
  require "relaton/cli/relaton_file"
2
2
  require "relaton/cli/xml_convertor"
3
3
  require "relaton/cli/yaml_convertor"
4
+ require "relaton/cli/yaml_convertor_new"
4
5
  require "fcntl"
5
6
 
6
7
  module Relaton
@@ -49,6 +50,17 @@ module Relaton
49
50
  Relaton::Cli::YAMLConvertor.to_xml(filename, options)
50
51
  end
51
52
 
53
+ desc "yaml2xmlnew YAML", "Convert Relaton YAML into Relaton Collection XML or separate files"
54
+ option :extension, aliases: :x, desc: "File extension of Relaton XML files, defaults to 'rxl'"
55
+ option :prefix, aliases: :p, desc: "Filename prefix of individual Relaton XML files, defaults to empty"
56
+ option :outdir, aliases: :o, desc: "Output to the specified directory with individual Relaton Bibdata XML files"
57
+ option :require, aliases: :r, type: :array, desc: "Require LIBRARY prior to execution"
58
+ option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
59
+
60
+ def yaml2xmlnew(filename)
61
+ Relaton::Cli::YAMLConvertorNew.to_xml(filename, options)
62
+ end
63
+
52
64
  desc "xml2yaml XML", "Convert Relaton XML into Relaton Bibdata / Bibcollection YAML (and separate files)"
53
65
  option :extension, aliases: :x, desc: "File extension of Relaton YAML files, defaults to 'yaml'"
54
66
  option :prefix, aliases: :p, desc: "Filename prefix of Relaton XML files, defaults to empty"
@@ -78,11 +90,20 @@ module Relaton
78
90
  Relaton::Cli::YAMLConvertor.to_html(file, style, template)
79
91
  end
80
92
 
93
+ desc "yaml2htmlnew RELATON-INDEX-YAML", "Concatenate Relaton Collection YAML into HTML"
94
+ option :stylesheet, aliases: :s, desc: "Stylesheet file path for rendering HTML index"
95
+ option :templatedir, aliases: :t, desc: "Liquid template directory for rendering Relaton items and collection"
96
+ option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
97
+
98
+ def yaml2htmlnew(file, style = nil, template = nil)
99
+ Relaton::Cli::YAMLConvertorNew.to_html(file, style, template)
100
+ end
101
+
81
102
  private
82
103
 
83
104
  def fetch_document(code, options)
84
105
  if registered_types.include?(options[:type])
85
- doc = Cli.relaton.fetch(code, options[:year])
106
+ doc = Cli.relaton.fetch(code, options[:year]&.to_s)
86
107
  doc ? doc.to_xml : "No matching bibliographic entry found"
87
108
  end
88
109
  rescue RelatonBib::RequestError => e
@@ -116,7 +116,8 @@ module Relaton
116
116
  bib = nokogiri_document(bib.to_xml)
117
117
  elsif (rfc = xml.at("//rfc"))
118
118
  require "relaton_ietf/scrapper"
119
- ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
119
+ #ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
120
+ ietf = RelatonIetf::Scrapper.fetch_rfc rfc
120
121
  bib = nokogiri_document ietf.to_xml(bibdata: true)
121
122
  else
122
123
  next
@@ -139,7 +140,8 @@ module Relaton
139
140
  doc = nokogiri_document(xml[:content])
140
141
  if (rfc = doc.at("//rfc"))
141
142
  require "relaton_ietf/scrapper"
142
- ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
143
+ #ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
144
+ ietf = RelatonIetf::Scrapper.fetch_rfc rfc
143
145
  doc = nokogiri_document ietf.to_xml(bibdata: true)
144
146
  end
145
147
  bibdata_instance(doc, xml[:file]) if doc.root.name == "bibdata"
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Cli
3
- VERSION = "0.2.1".freeze
3
+ VERSION = "0.2.2".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,71 @@
1
+ require "yaml"
2
+ require "relaton/cli/base_convertor"
3
+ require "relaton_bib"
4
+
5
+ module Relaton
6
+ module Cli
7
+ class YAMLConvertorNew < Relaton::Cli::BaseConvertor
8
+ def to_xml
9
+ if writable
10
+ convert_and_write(file_content, :to_xml)
11
+ else
12
+ convert_content(file_content).to_xml(nil, date_format: :full)
13
+ end
14
+ end
15
+
16
+ # Convert to XML
17
+ #
18
+ # This interface allow us to convert any YAML file to XML.
19
+ # It only require us to provide a valid YAML file and it can
20
+ # do converstion using default attributes, but it also allow
21
+ # us to provide custom options to customize this converstion
22
+ # process.
23
+ #
24
+ # @param file [File] The complete path to a YAML file
25
+ # @param options [Hash] Options as hash key, value pairs.
26
+ #
27
+ def self.to_xml(file, options = {})
28
+ new(file, options).to_xml
29
+ end
30
+
31
+ private
32
+
33
+ def default_ext
34
+ "rxl"
35
+ end
36
+
37
+ def file_content
38
+ date_to_string(YAML.load_file(file))
39
+ end
40
+
41
+ def date_to_string(obj)
42
+ obj.is_a? Hash and
43
+ return obj.inject({}){|memo,(k,v)| memo[k] = date_to_string(v); memo}
44
+ obj.is_a? Array and
45
+ return obj.inject([]){|memo,v | memo << date_to_string(v); memo}
46
+ return obj.is_a?(Date) ? obj.to_s : obj
47
+ end
48
+
49
+ def convert_single_file(content)
50
+ RelatonBib::BibliographicItem.new(RelatonBib::hash_to_bib(content))
51
+ end
52
+
53
+ def convert_collection(content)
54
+ if content.has_key?("root")
55
+ content["root"]["items"] = content["root"]["items"].map do |i|
56
+ RelatonBib::hash_to_bib(i)
57
+ end
58
+ Relaton::BibcollectionNew.new(content["root"])
59
+ end
60
+ end
61
+
62
+ def xml_content(_raw_file)
63
+ convert_content(file_content).to_xml(date_format: :full)
64
+ end
65
+
66
+ def convert_content(content)
67
+ convert_collection(content) || convert_single_file(content)
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/relaton-cli.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require_relative "relaton/bibcollection"
2
+ require_relative "relaton/bibcollectionnew"
2
3
  require_relative "relaton/bibdata"
3
4
  require_relative "relaton/element_finder"
4
5
  require_relative "relaton/xml_document"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.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: 2019-06-28 00:00:00.000000000 Z
11
+ date: 2019-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -194,6 +194,7 @@ files:
194
194
  - ".travis.yml"
195
195
  - CHANGELOG.md
196
196
  - Gemfile
197
+ - Gemfile.lock
197
198
  - LICENSE
198
199
  - Rakefile
199
200
  - appveyor.yml
@@ -205,6 +206,7 @@ files:
205
206
  - i18n.yaml
206
207
  - lib/relaton-cli.rb
207
208
  - lib/relaton/bibcollection.rb
209
+ - lib/relaton/bibcollectionnew.rb
208
210
  - lib/relaton/bibdata.rb
209
211
  - lib/relaton/cli.rb
210
212
  - lib/relaton/cli/_document.liquid
@@ -216,6 +218,7 @@ files:
216
218
  - lib/relaton/cli/xml_convertor.rb
217
219
  - lib/relaton/cli/xml_to_html_renderer.rb
218
220
  - lib/relaton/cli/yaml_convertor.rb
221
+ - lib/relaton/cli/yaml_convertor_new.rb
219
222
  - lib/relaton/element_finder.rb
220
223
  - lib/relaton/xml_document.rb
221
224
  - relaton-cli.gemspec