Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ require: rubocop-rails
inherit_from:
- https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
AllCops:
TargetRubyVersion: 3.0
TargetRubyVersion: 3.2
Rails:
Enabled: true
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ gem "simplecov"
gem "vcr"
gem "webmock"
gem "debug"
gem "fiddle"
424 changes: 169 additions & 255 deletions docs/README.adoc

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions lib/relaton/bibdata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def initialize(bibitem)
end

def docidentifier
@bibitem.docidentifier.first&.id
@bibitem.docidentifier.first&.content&.to_s
end

# def doctype
Expand Down Expand Up @@ -50,10 +50,9 @@ def to_xml(opts = {})
end

def to_h
URL_TYPES.reduce(@bibitem.to_hash) do |h, t|
URL_TYPES.each_with_object(YAML.safe_load(@bibitem.to_yaml)) do |t, h|
value = send t
h[t.to_s] = value
h
h[t.to_s] = value if value
end
end

Expand All @@ -68,19 +67,20 @@ def method_missing(meth, *args)
if @bibitem.respond_to?(meth)
@bibitem.send meth, *args
elsif URL_TYPES.include? meth
link = @bibitem.link.detect do |l|
source = (@bibitem.source || []).detect do |l|
l.type == meth.to_s || (meth == :uri && l.type.nil?)
end
link&.content&.to_s
source&.content&.to_s
elsif URL_TYPES.include? meth.match(/^\w+(?==)/).to_s.to_sym
/^(?<type>\w+)/ =~ meth
link = @bibitem.link.detect do |l|
@bibitem.source ||= []
source = @bibitem.source.detect do |l|
l.type == type || (type == "uri" && l.type.nil?)
end
if link
link.content = args[0]
if source
source.content = args[0]
else
@bibitem.link << RelatonBib::TypedUri.new(type: type, content: args[0])
@bibitem.source << Relaton::Bib::Uri.new(type: type, content: args[0])
end
else
super
Expand Down
20 changes: 9 additions & 11 deletions lib/relaton/cli.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require "fileutils"
require "thor"
require "thor/hollaback"
require_relative "cli/version"
Expand All @@ -19,6 +20,7 @@ class RelatonDb
# @return [Relaton::Db]
def db(dir)
if dir
FileUtils.mkdir_p File.dirname(DBCONF)
File.write DBCONF, dir, encoding: "UTF-8"
@db = Relaton::Db.new dir, nil
else
Expand All @@ -39,19 +41,14 @@ def dbpath

class << self
def version
require "relaton_bib"
require "relaton_iso_bib"
require "relaton/bib"
registry = Relaton::Registry.instance
puts "CLI => #{Relaton::Cli::VERSION}"
puts "relaton => #{Relaton::VERSION}"
puts "relaton-bib => #{RelatonBib::VERSION}"
puts "relaton-iso-bib => #{RelatonIsoBib::VERSION}"
puts "relaton => #{Gem.loaded_specs['relaton'].version}"
puts "relaton-bib => #{Gem.loaded_specs['relaton-bib'].version}"
registry.processors.each_key do |k|
require k.to_s
klass = registry.send(:camel_case, k.to_s)
klass = "#{klass}::VERSION"
version = Kernel.const_get(klass)
puts "#{k.to_s.sub('_', '-')} => #{version}"
name = k.to_s.sub("_", "-")
puts "#{name} => #{Gem.loaded_specs[name].version}"
end
end

Expand All @@ -76,10 +73,11 @@ def relaton(dir)
# @return [RelatonBib::BibliographicItem,
# RelatonIsoBib::IsoBibliongraphicItem]
def parse_xml(doc)
doc.remove_namespaces! if doc.respond_to?(:remove_namespaces!)
if (proc = Cli.processor(doc))
proc.from_xml(doc.to_s)
else
RelatonBib::XMLParser.from_xml(doc.to_s)
Relaton::Bib::Item.from_xml(doc.to_s) rescue nil
end
end

Expand Down
8 changes: 4 additions & 4 deletions lib/relaton/cli/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def convert(file) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"))
item = Relaton::Cli.parse_xml xml
result = if /yaml|yml/.match?(options[:format])
item.to_hash.to_yaml
item.to_yaml
else item.send "to_#{options[:format]}"
end
ext = case options[:format]
Expand Down Expand Up @@ -226,16 +226,16 @@ def fetch_document(code, options) # rubocop:disable Metrics/CyclomaticComplexity
return "No matching bibliographic entry found" unless doc

serialize doc, options[:format]
rescue RelatonBib::RequestError => e
rescue Relaton::RequestError => e
e.message
end

# @param doc [RelatonBib::BibliographicItem]
# @param doc [Relaton::Bib::ItemData]
# @param format [String]
# @return [String]
def serialize(doc, format)
case format
when "yaml", "yml" then doc.to_hash.to_yaml
when "yaml", "yml" then doc.to_yaml
when "bibtex" then doc.to_bibtex
else doc.to_xml bibdata: true
end
Expand Down
12 changes: 6 additions & 6 deletions lib/relaton/cli/relaton_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ def extract_and_write_to_files # rubocop:disable Metrics/AbcSize, Metrics/Method
if (bib = xml.at("//bibdata"))
bib = nokogiri_document(bib.to_xml)
elsif (rfc = xml.at("//rfc"))
require "relaton_ietf/bibxml_parser"
ietf = RelatonIetf::BibXMLParser.fetch_rfc rfc
require "relaton/ietf"
require "relaton/ietf/bibxml_parser"
ietf = Relaton::Ietf::BibXMLParser.parse_rfc rfc.to_xml
bib = nokogiri_document(ietf.to_xml(bibdata: true))
else
next
end

bib.remove_namespaces!
bib.root.add_namespace(nil, "xmlns")

bibdata = Relaton::Bibdata.from_xml(bib.root)
if bibdata
Expand All @@ -147,8 +147,9 @@ def concatenate_files
xml_files.flatten.reduce([]) do |mem, xml|
doc = nokogiri_document(xml[:content])
if (rfc = doc.at("/rfc"))
require "relaton_ietf/bibxml_parser"
ietf = RelatonIetf::BibXMLParser.fetch_rfc rfc
require "relaton/ietf"
require "relaton/ietf/bibxml_parser"
ietf = Relaton::Ietf::BibXMLParser.parse_rfc rfc.to_xml
d = nokogiri_document ietf.to_xml(bibdata: true)
mem << bibdata_instance(d, xml[:file])
elsif %w[bibitem bibdata].include? doc&.root&.name
Expand Down Expand Up @@ -231,7 +232,6 @@ def build_bibdata_relaton(bibdata, file)
# @return [Nokogiri::XML::Document]
def clean_nokogiri_document(document)
document.remove_namespaces!
document.root.add_namespace(nil, "xmlns")
nokogiri_document(document.to_xml)
end

Expand Down
26 changes: 22 additions & 4 deletions lib/relaton/cli/subcommand_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,13 @@ def import(file) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
collfile = File.join directory, options[:collection]
coll = read_collection collfile
xml = Nokogiri::XML File.read(file, encoding: "UTF-8")
xml.remove_namespaces!
if xml.at "relaton-collection"
imported = import_collection(xml)
if coll
coll << Relaton::Bibcollection.from_xml(xml)
coll << imported
else
coll = Relaton::Bibcollection.from_xml(xml)
coll = imported
end
else
coll ||= Relaton::Bibcollection.new({})
Expand All @@ -169,6 +171,22 @@ def export(file)

private

# Parse a namespace-free collection XML document.
# Bibcollection.from_xml expects namespaced docs (via apply_namespace),
# so we use plain XPath on the namespace-stripped document instead.
def import_collection(xml)
title = xml.at("relaton-collection/title")&.text
author = xml.at_xpath(
"./relaton-collection/contributor[role/@type='author']"\
"/organization/name",
)&.text
items = xml.xpath("relaton-collection/relation").map do |rel|
el = rel.at("bibdata") || rel.at("bibitem")
Relaton::Bibdata.from_xml(el || rel)
end.compact
Relaton::Bibcollection.new(title: title, author: author, items: items)
end

# @return [String]
def directory
options.fetch :dir, File.join(Dir.home, ".relaton/collections")
Expand Down Expand Up @@ -231,9 +249,9 @@ def output_item(item)
# @param item [Relaton::Bibdata]
def puts_human_readable_item(item) # rubocop:disable Metrics/AbcSize
puts "Document identifier: #{item.docidentifier}"
puts "Title: #{item.title.first.title.content}"
puts "Title: #{item.title.first.content}"
puts "Status: #{item.status.stage}"
item.date.each { |d| puts "Date #{d.type}: #{d.on || d.from}" }
item.date.each { |d| puts "Date #{d.type}: #{d.at || d.from}" }
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/relaton/cli/util.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Relaton
module Cli
module Util
extend RelatonBib::Util
extend Relaton::Bib::Util
PROGNAME = "relaton-cli".freeze
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/relaton/cli/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Relaton
module Cli
VERSION = "1.20.6".freeze
VERSION = "2.0.0-alpha.1".freeze
end
end
13 changes: 7 additions & 6 deletions lib/relaton/cli/xml_to_html_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,13 @@ def hash_to_liquid(hash)
elsif value.is_a?(Hash) then v = value["content"]
else v = value
end
when "docid"
v = if value.is_a?(Array)
value.detect { |did| did["id"] !~ /^(http|https):\/\// } ||
value.first
else value
end
when "docidentifier"
did = if value.is_a?(Array)
value.detect { |d| (d["id"] || d["content"]).to_s !~ /^(http|https):\/\// } ||
value.first
else value
end
v = did
else v = value
end
[key.to_s, empty2nil(v)]
Expand Down
16 changes: 9 additions & 7 deletions lib/relaton/cli/yaml_convertor.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "yaml"
require "relaton/cli/base_convertor"
require "relaton_bib"
require "relaton/bib"

module Relaton
module Cli
Expand Down Expand Up @@ -33,13 +33,15 @@ def to_xml(file, options = {})
# @return [RelatonBib::BibliographicItem,
# RelatonIso::IsoBiblioraphicItem]
def convert_single_file(content)
flavor = content.dig("ext", "flavor") || doctype(content["docid"])
flavor = content.dig("ext", "flavor") || doctype(content["docidentifier"])
if (processor = Registry.instance.by_type(flavor))
processor.hash_to_bib content
begin
processor.from_yaml content.to_yaml
rescue RuntimeError
Relaton::Bib::Item.from_yaml(content.to_yaml)
end
else
RelatonBib::BibliographicItem.new(
**RelatonBib::HashConverter::hash_to_bib(content)
)
Relaton::Bib::Item.from_yaml(content.to_yaml)
end
end

Expand All @@ -51,7 +53,7 @@ def doctype(docid)
did = docid.is_a?(Array) ? docid.fetch(0) : docid
return unless did

did["type"] || did.fetch("id")&.match(/^\w+/)&.to_s
did["type"] || did.fetch("content")&.match(/^\w+/)&.to_s
end
end

Expand Down
4 changes: 2 additions & 2 deletions relaton-cli.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.required_ruby_version = ">= 3.0.0"
spec.required_ruby_version = Gem::Requirement.new(">= 3.2.0")

spec.add_runtime_dependency "liquid", "~> 5"
spec.add_runtime_dependency "relaton", "~> 1.20.2"
spec.add_runtime_dependency "relaton", "~> 2.0.0-alpha.1"
spec.add_runtime_dependency "thor"
spec.add_runtime_dependency "thor-hollaback"

Expand Down
17 changes: 14 additions & 3 deletions spec/acceptance/relaton_fetch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@

context do
let(:io) { double "IO" }
let(:tmpdir) { Dir.mktmpdir("relaton_test_cache") }

before (:each) do
RSpec::Mocks.space.proxy_for(IO).reset
expect(IO).to receive(:new) do |arg1, arg2, &block|
Expand All @@ -103,12 +105,21 @@
end
end.at_most(2).times

# Isolate from global cache by using a fresh DB in a temp directory
Relaton::Cli::RelatonDb.instance.instance_variable_set(:@db, nil)
Relaton::Cli.relaton(tmpdir)

# Force to download index file
require "relaton/index"
allow_any_instance_of(Relaton::Index::Type).to receive(:actual?).and_return(false)
allow_any_instance_of(Relaton::Index::FileIO).to receive(:check_file).and_return(nil)
end

after(:each) do
Relaton::Cli::RelatonDb.instance.instance_variable_set(:@db, nil)
FileUtils.remove_entry(tmpdir)
end

it "calls fetch and return XML" do
expect(io).to receive(:puts) do |arg|
expect(arg).to match(/^<bibdata type="standard" schema-version="v\d\.\d\.\d">/)
Expand All @@ -123,7 +134,7 @@

it "calls fetch and return YAML" do
expect(io).to receive(:puts) do |arg|
expect(arg).to include "- id: ISO 2146:2010"
expect(arg).to include "- content: ISO 2146:2010"
end
VCR.use_cassette "iso_2146" do
command = ["fetch", "--type", "iso", "--format", "yaml", "ISO 2146"]
Expand Down Expand Up @@ -205,12 +216,12 @@
end

it "raise request error" do
expect(db).to receive(:fetch_std).and_raise RelatonBib::RequestError
expect(db).to receive(:fetch_std).and_raise Relaton::RequestError
expect(Relaton::Cli).to receive(:relaton).and_return(db)
command = Relaton::Cli::Command.new
# expect(command).to receive(:registered_types).and_return ["ISO"]
expect(command.send(:fetch_document, "ISO 2146", type: "ISO")).to eq(
"RelatonBib::RequestError",
"Relaton::RequestError",
)
Relaton::Cli::RelatonDb.instance.instance_variable_set :@db, nil
end
Expand Down
6 changes: 3 additions & 3 deletions spec/assets/templates/_document.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<div class="doc-line">
<div class="doc-identifier">
<h{{ depth }}>
{% if document.html == "" %}
{{ document.docid.id }}
{% if document.html == blank or document.html == nil %}
{{ document.docidentifier.content }}
{% else %}
<a href="{{ document.html }}">{{ document.docid.id }}</a>
<a href="{{ document.html }}">{{ document.docidentifier.content }}</a>
{% endif %}
</h{{ depth }}>
</div>
Expand Down
4 changes: 2 additions & 2 deletions spec/bibdata_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
RSpec.describe Relaton::Bibdata do
subject do
docid = RelatonBib::DocumentIdentifier.new id: %{A/B\\C?D%E*F:G|H"I<J>K.L M/N}
item = RelatonBib::BibliographicItem.new docid: [docid]
docid = Relaton::Bib::Docidentifier.new content: %{A/B\\C?D%E*F:G|H"I<J>K.L M/N}
item = Relaton::Bib::ItemData.new docidentifier: [docid]
Relaton::Bibdata.new(item)
end

Expand Down
Loading
Loading