metanorma-utils 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f5af94c8279744e0a0b72c5ab787493ac267594dfed2995fce689dbc1b23d59e
4
+ data.tar.gz: 1dd672778666043bd46933a470c25969d1687a13f416ae0eeb724949b1adce9a
5
+ SHA512:
6
+ metadata.gz: d4f49c7aaa75452179e3a926f2c1d47d8b31cc028f943719900fa16ee3401ec1fdf09355192f43a6d6329e5a26dca8557d3215f17c632ebd24a7c8dd2397338d
7
+ data.tar.gz: 11b38464fbbd28332163e8cc1d46d96b0e27223bbf0f38e6e5520675f30758d5e14b0bdf244b2c241740d6e713b07414ce8315e2c83bec7fa871beabc662049e
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ Encoding.default_external = Encoding::UTF_8
2
+ Encoding.default_internal = Encoding::UTF_8
3
+
4
+ source "https://rubygems.org"
5
+ git_source(:github) { |repo| "https://github.com/#{repo}" }
6
+
7
+ gemspec
8
+
9
+ if File.exist? 'Gemfile.devel'
10
+ eval File.read('Gemfile.devel'), nil, 'Gemfile.devel' # rubocop:disable Security/Eval
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2021, Metanorma
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
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. 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.
@@ -0,0 +1,9 @@
1
+ # metanorma-utils
2
+
3
+ image:https://img.shields.io/gem/v/metanorma-utils.svg["Gem Version", link="https://rubygems.org/gems/metanorma-utils"]
4
+ image:https://github.com/metanorma/metanorma-utils/workflows/rake/badge.svg["Build Status", link="https://github.com/metanorma/metanorma-utils/actions?workflow=rake"]
5
+ image:https://codeclimate.com/github/metanorma/metanorma-utils/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/metanorma-utils"]
6
+ image:https://img.shields.io/github/issues-pr-raw/metanorma/metanorma-utils.svg["Pull Requests", link="https://github.com/metanorma/metanorma-utils/pulls"]
7
+ image:https://img.shields.io/github/commits-since/metanorma/metanorma-utils/latest.svg["Commits since latest",link="https://github.com/metanorma/metanorma-utils/releases"]
8
+
9
+ Utilities methods for http://metanorma.com[Metanorma] stack
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'isodoc/gem_tasks'
4
+
5
+ IsoDoc::GemTasks.install
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require "pathname"
10
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
11
+ "../../Gemfile", Pathname.new(__FILE__).realpath
12
+ )
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
18
+
@@ -0,0 +1,3 @@
1
+ require_relative "utils/version"
2
+ require_relative "utils/main"
3
+ require_relative "utils/log"
@@ -0,0 +1,59 @@
1
+ module Metanorma
2
+ module Utils
3
+ class Log
4
+ def initialize
5
+ @log = {}
6
+ end
7
+
8
+ def add(category, loc, msg)
9
+ return if @novalid
10
+ @log[category] = [] unless @log[category]
11
+ @log[category] << { location: current_location(loc), message: msg,
12
+ context: context(loc) }
13
+ loc = loc.nil? ? "" : "(#{current_location(loc)}): "
14
+ warn "#{category}: #{loc}#{msg}"
15
+ end
16
+
17
+ def current_location(n)
18
+ return "" if n.nil?
19
+ return n if n.is_a? String
20
+ return "Asciidoctor Line #{"%06d" % n.lineno}" if n.respond_to?(:lineno) &&
21
+ !n.lineno.nil? && !n.lineno.empty?
22
+ return "XML Line #{"%06d" % n.line}" if n.respond_to?(:line) &&
23
+ !n.line.nil?
24
+ return "ID #{n.id}" if n.respond_to?(:id) && !n.id.nil?
25
+ while !n.nil? &&
26
+ (!n.respond_to?(:level) || n.level.positive?) &&
27
+ (!n.respond_to?(:context) || n.context != :section)
28
+ n = n.parent
29
+ return "Section: #{n.title}" if n&.respond_to?(:context) &&
30
+ n&.context == :section
31
+ end
32
+ "??"
33
+ end
34
+
35
+ def context(n)
36
+ return nil if n.is_a? String
37
+ n.respond_to?(:to_xml) and return n.to_xml
38
+ n.respond_to?(:to_s) and return n.to_s
39
+ nil
40
+ end
41
+
42
+ def write(file)
43
+ File.open(file, "w:UTF-8") do |f|
44
+ f.puts "#{file} errors"
45
+ @log.keys.each do |key|
46
+ f.puts "\n\n== #{key}\n\n"
47
+ @log[key].sort do |a, b|
48
+ a[:location] <=> b[:location]
49
+ end.each do |n|
50
+ loc = n[:location] ? "(#{n[:location]}): " : ""
51
+ f.puts "#{loc}#{n[:message]}"
52
+ n[:context]&.split(/\n/)&.first(5)&.each { |l| f.puts "\t#{l}" }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,113 @@
1
+ require "asciidoctor"
2
+ require "sterile"
3
+ require "uuidtools"
4
+
5
+ module Metanorma
6
+ module Utils
7
+ NAMECHAR = "\u0000-\u0022\u0024\u002c\u002f\u003a-\u0040\\u005b-\u005e"\
8
+ "\u0060\u007b-\u00b6\u00b8-\u00bf\u00d7\u00f7\u037e\u2000-\u200b"\
9
+ "\u200e-\u203e\u2041-\u206f\u2190-\u2bff\u2ff0-\u3000".freeze
10
+ #"\ud800-\uf8ff\ufdd0-\ufdef\ufffe-\uffff".freeze
11
+ NAMESTARTCHAR = "\\u002d\u002e\u0030-\u0039\u00b7\u0300-\u036f"\
12
+ "\u203f-\u2040".freeze
13
+
14
+ class << self
15
+ def to_ncname(s)
16
+ start = s[0]
17
+ ret1 = %r([#{NAMECHAR}#]).match(start) ? "_" :
18
+ (%r([#{NAMESTARTCHAR}#]).match(start) ? "_#{start}" : start)
19
+ ret2 = s[1..-1] || ""
20
+ ret = (ret1 || "") + ret2.gsub(%r([#{NAMECHAR}#]), "_")
21
+ ret
22
+ end
23
+
24
+ def anchor_or_uuid(node = nil)
25
+ uuid = UUIDTools::UUID.random_create
26
+ node.nil? || node.id.nil? || node.id.empty? ? "_" + uuid : node.id
27
+ end
28
+
29
+ def asciidoc_sub(x)
30
+ return nil if x.nil?
31
+ return "" if x.empty?
32
+ d = Asciidoctor::Document.new(x.lines.entries, { header_footer: false, backend: :html })
33
+ b = d.parse.blocks.first
34
+ b.apply_subs(b.source)
35
+ end
36
+
37
+ def localdir(node)
38
+ docfile = node.attr("docfile")
39
+ docfile.nil? ? './' : Pathname.new(docfile).parent.to_s + '/'
40
+ end
41
+
42
+ # TODO needs internationalisation
43
+ def smartformat(n)
44
+ n.gsub(/ --? /, "&#8201;&#8212;&#8201;").
45
+ gsub(/--/, "&#8212;").smart_format.gsub(/</, "&lt;").gsub(/>/, "&gt;")
46
+ end
47
+
48
+ def endash_date(elem)
49
+ elem.traverse do |n|
50
+ n.text? and n.replace(n.text.gsub(/\s+--?\s+/, "&#8211;").gsub(/--/, "&#8211;"))
51
+ end
52
+ end
53
+
54
+ # Set hash value using keys path
55
+ # mod from https://stackoverflow.com/a/42425884
56
+ def set_nested_value(hash, keys, new_val)
57
+ key = keys[0]
58
+ if keys.length == 1
59
+ hash[key] = hash[key].is_a?(Array) ? (hash[key] << new_val) :
60
+ hash[key].nil? ? new_val : [hash[key], new_val]
61
+ else
62
+ if hash[key].is_a?(Array)
63
+ hash[key] << {} if hash[key].empty? || !hash[key][-1].is_a?(Hash)
64
+ hash[key][-1] = {} if hash[key][-1].nil?
65
+ set_nested_value(hash[key][-1], keys[1..-1], new_val)
66
+ elsif hash[key].nil? || hash[key].empty?
67
+ hash[key] = {}
68
+ set_nested_value(hash[key], keys[1..-1], new_val)
69
+ elsif hash[key].is_a?(Hash) && !hash[key][keys[1]]
70
+ set_nested_value(hash[key], keys[1..-1], new_val)
71
+ elsif !hash[key][keys[1]]
72
+ hash[key] = [hash[key], {}]
73
+ set_nested_value(hash[key][-1], keys[1..-1], new_val)
74
+ else
75
+ set_nested_value(hash[key], keys[1..-1], new_val)
76
+ end
77
+ end
78
+ hash
79
+ end
80
+
81
+ # not currently used
82
+ def flatten_rawtext_lines(node, result)
83
+ node.lines.each do |x|
84
+ if node.respond_to?(:context) && (node.context == :literal ||
85
+ node.context == :listing)
86
+ result << x.gsub(/</, "&lt;").gsub(/>/, "&gt;")
87
+ else
88
+ # strip not only HTML <tag>, and Asciidoc xrefs <<xref>>
89
+ result << x.gsub(/<[^>]*>+/, "")
90
+ end
91
+ end
92
+ result
93
+ end
94
+
95
+ # not currently used
96
+ # if node contains blocks, flatten them into a single line;
97
+ # and extract only raw text
98
+ def flatten_rawtext(node)
99
+ result = []
100
+ if node.respond_to?(:blocks) && node.blocks?
101
+ node.blocks.each { |b| result << flatten_rawtext(b) }
102
+ elsif node.respond_to?(:lines)
103
+ result = flatten_rawtext_lines(node, result)
104
+ elsif node.respond_to?(:text)
105
+ result << node.text.gsub(/<[^>]*>+/, "")
106
+ else
107
+ result << node.content.gsub(/<[^>]*>+/, "")
108
+ end
109
+ result.reject(&:empty?)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,5 @@
1
+ module Metanorma
2
+ module Utils
3
+ VERSION = "1.0.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "utils/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "metanorma-utils"
9
+ spec.version = Metanorma::Utils::VERSION
10
+ spec.authors = ["Ribose Inc."]
11
+ spec.email = ["open.source@ribose.com"]
12
+
13
+ spec.summary = "metanorma-utils "
14
+ spec.description = <<~DESCRIPTION
15
+ metanorma-utils provides utilities for the Metanorma stack
16
+ DESCRIPTION
17
+
18
+ spec.homepage = "https://github.com/metanorma/metanorma-utils"
19
+ spec.license = "BSD-2-Clause"
20
+
21
+ spec.bindir = "bin"
22
+ spec.require_paths = ["lib"]
23
+ spec.files = `git ls-files`.split("\n")
24
+ spec.test_files = `git ls-files -- {spec}/*`.split("\n")
25
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
26
+
27
+ spec.add_dependency "sterile", "~> 1.0.14"
28
+ spec.add_dependency "concurrent-ruby"
29
+ spec.add_dependency "nokogiri", "~> 1.10.4"
30
+ spec.add_dependency "asciidoctor", "~> 2.0.0"
31
+ spec.add_dependency "uuidtools"
32
+
33
+ spec.add_development_dependency "byebug"
34
+ spec.add_development_dependency "equivalent-xml", "~> 0.6"
35
+ spec.add_development_dependency "guard", "~> 2.14"
36
+ spec.add_development_dependency "guard-rspec", "~> 4.7"
37
+ spec.add_development_dependency "rake", "~> 12.0"
38
+ spec.add_development_dependency "rspec", "~> 3.6"
39
+ spec.add_development_dependency "rubocop", "= 0.54.0"
40
+ spec.add_development_dependency "simplecov", "~> 0.15"
41
+ spec.add_development_dependency "timecop", "~> 0.9"
42
+ spec.add_development_dependency "vcr", "~> 5.0.0"
43
+ spec.add_development_dependency "webmock"
44
+ end
@@ -0,0 +1,34 @@
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end
5
+ require "rspec/matchers"
6
+ require "equivalent-xml"
7
+ require "metanorma-utils"
8
+
9
+ RSpec.configure do |config|
10
+ # Enable flags like --only-failures and --next-failure
11
+ config.example_status_persistence_file_path = ".rspec_status"
12
+
13
+ # Disable RSpec exposing methods globally on `Module` and `main`
14
+ config.disable_monkey_patching!
15
+
16
+ config.expect_with :rspec do |c|
17
+ c.syntax = :expect
18
+ end
19
+ end
20
+
21
+ class Dummy
22
+ attr_accessor :id
23
+ attr_accessor :docfile
24
+ def initialize(id = nil)
25
+ @id = id
26
+ end
27
+
28
+ def attr(x)
29
+ case x
30
+ when "docfile" then @docfile
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,110 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+
4
+ RSpec.describe Metanorma::Utils do
5
+ it "has a version number" do
6
+ expect(Metanorma::Utils::VERSION).not_to be nil
7
+ end
8
+
9
+ it "normalises anchors" do
10
+ expect(Metanorma::Utils.to_ncname("/:ab")).to eq "__ab"
11
+ end
12
+
13
+ it "sets metanorma IDs if not provided" do
14
+ expect(Metanorma::Utils.anchor_or_uuid()).to match (/^_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
15
+ expect(Metanorma::Utils.anchor_or_uuid(Dummy.new(nil))).to match (/^_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
16
+ expect(Metanorma::Utils.anchor_or_uuid(Dummy.new(""))).to match (/^_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
17
+ expect(Metanorma::Utils.anchor_or_uuid(Dummy.new("A"))).to eq "A"
18
+ end
19
+
20
+ it "applies Asciidoctor substitutions" do
21
+ expect(Metanorma::Utils.asciidoc_sub("A -- B")).to eq "A&#8201;&#8212;&#8201;B"
22
+ end
23
+
24
+ it "finds file path of docfile" do
25
+ d = Dummy.new
26
+ expect(Metanorma::Utils.localdir(d)).to eq "./"
27
+ d.docfile = "spec/utils_spec.rb"
28
+ expect(Metanorma::Utils.localdir(d)).to eq "spec/"
29
+ end
30
+
31
+ it "applies smart formatting" do
32
+ expect(Metanorma::Utils.smartformat("A - B A -- B A--B '80s '80' <A>")).to eq "A&#8201;&#8212;&#8201;B A&#8201;&#8212;&#8201;B A&#8212;B ’80s ‘80’ &lt;A&gt;"
33
+ end
34
+
35
+ it "applies en-dash normalisation" do
36
+ a = Nokogiri::XML(<<~INPUT)
37
+ <container>
38
+ <a>A -- B A - B</a>
39
+ <b>A--B</b>
40
+ </container>
41
+ INPUT
42
+ Metanorma::Utils.endash_date(a)
43
+ expect(a.to_xml).to be_equivalent_to <<~OUTPUT
44
+ <?xml version=\"1.0\"?>
45
+ <container><a>A&#x2013;B A&#x2013;B</a><b>A&#x2013;B</b></container>
46
+ OUTPUT
47
+ end
48
+
49
+ it "sets hash values by dotted key path" do
50
+ a = {}
51
+ a = Metanorma::Utils.set_nested_value(a, ["X"], "x")
52
+ a = Metanorma::Utils.set_nested_value(a, ["X1"], 9)
53
+ a = Metanorma::Utils.set_nested_value(a, ["X2"], [3])
54
+ a = Metanorma::Utils.set_nested_value(a, ["X3"], {"a" =>"b"})
55
+ expect(a.to_s).to be_equivalent_to <<~OUTPUT
56
+ {"X"=>"x", "X1"=>9, "X2"=>[3], "X3"=>{"a"=>"b"}}
57
+ OUTPUT
58
+ a = Metanorma::Utils.set_nested_value(a, ["X2"], 4)
59
+ a = Metanorma::Utils.set_nested_value(a, ["X1"], 4)
60
+ expect(a.to_s).to be_equivalent_to <<~OUTPUT
61
+ {"X"=>"x", "X1"=>[9, 4], "X2"=>[3, 4], "X3"=>{"a"=>"b"}}
62
+ OUTPUT
63
+ a = Metanorma::Utils.set_nested_value(a, ["X2", "A"], 5)
64
+ a = Metanorma::Utils.set_nested_value(a, ["X2a"], [])
65
+ a = Metanorma::Utils.set_nested_value(a, ["X2a", "A"], 6)
66
+ a = Metanorma::Utils.set_nested_value(a, ["X4", "A"], 10)
67
+ a = Metanorma::Utils.set_nested_value(a, ["X3", "A"], 7)
68
+ a = Metanorma::Utils.set_nested_value(a, ["X3", "a"], 8)
69
+ a = Metanorma::Utils.set_nested_value(a, ["X1", "a"], 11)
70
+ expect(a.to_s).to be_equivalent_to <<~OUTPUT
71
+ {"X"=>"x", "X1"=>[9, 4, {"a"=>11}], "X2"=>[3, 4, {"A"=>5}], "X3"=>{"a"=>["b", 8], "A"=>7}, "X2a"=>[{"A"=>6}], "X4"=>{"A"=>10}}
72
+ OUTPUT
73
+ end
74
+
75
+ # not testing Asciidoctor log extraction here
76
+ it "generates log" do
77
+ xml = Nokogiri::XML(<<~INPUT)
78
+ <xml>
79
+ <a>
80
+ <b>
81
+ c
82
+ </b></a></xml>
83
+ INPUT
84
+ FileUtils.rm_f("log.txt")
85
+ log = Metanorma::Utils::Log.new
86
+ log.add("Category 1", nil, "Message 1")
87
+ log.add("Category 1", "node", "Message 2")
88
+ log.add("Category 2", xml.at("//xml/a/b"), "Message 3")
89
+ log.write("log.txt")
90
+ expect(File.exist?("log.txt")).to be true
91
+ file = File.read("log.txt", encoding: "utf-8")
92
+ expect(file).to eq <<~OUTPUT
93
+ log.txt errors
94
+
95
+
96
+ == Category 1
97
+
98
+ (): Message 1
99
+ (node): Message 2
100
+
101
+
102
+ == Category 2
103
+
104
+ (XML Line 000003): Message 3
105
+ <b>
106
+ c
107
+ </b>
108
+ OUTPUT
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,281 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metanorma-utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sterile
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.14
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.14
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.10.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.10.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: asciidoctor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: uuidtools
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: equivalent-xml
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.14'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.14'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '4.7'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '4.7'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rake
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '12.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '12.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.6'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.6'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '='
172
+ - !ruby/object:Gem::Version
173
+ version: 0.54.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - '='
179
+ - !ruby/object:Gem::Version
180
+ version: 0.54.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.15'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.15'
195
+ - !ruby/object:Gem::Dependency
196
+ name: timecop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.9'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.9'
209
+ - !ruby/object:Gem::Dependency
210
+ name: vcr
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: 5.0.0
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: 5.0.0
223
+ - !ruby/object:Gem::Dependency
224
+ name: webmock
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: 'metanorma-utils provides utilities for the Metanorma stack
238
+
239
+ '
240
+ email:
241
+ - open.source@ribose.com
242
+ executables: []
243
+ extensions: []
244
+ extra_rdoc_files: []
245
+ files:
246
+ - Gemfile
247
+ - LICENSE
248
+ - README.adoc
249
+ - Rakefile
250
+ - bin/rspec
251
+ - lib/metanorma-utils.rb
252
+ - lib/utils/log.rb
253
+ - lib/utils/main.rb
254
+ - lib/utils/version.rb
255
+ - metanorma-utils.gemspec
256
+ - spec/spec_helper.rb
257
+ - spec/utils_spec.rb
258
+ homepage: https://github.com/metanorma/metanorma-utils
259
+ licenses:
260
+ - BSD-2-Clause
261
+ metadata: {}
262
+ post_install_message:
263
+ rdoc_options: []
264
+ require_paths:
265
+ - lib
266
+ required_ruby_version: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - ">="
269
+ - !ruby/object:Gem::Version
270
+ version: 2.4.0
271
+ required_rubygems_version: !ruby/object:Gem::Requirement
272
+ requirements:
273
+ - - ">="
274
+ - !ruby/object:Gem::Version
275
+ version: '0'
276
+ requirements: []
277
+ rubygems_version: 3.0.3
278
+ signing_key:
279
+ specification_version: 4
280
+ summary: metanorma-utils
281
+ test_files: []