relaton-cli 1.0.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/docs/README.adoc +2 -1
- data/lib/relaton-cli.rb +7 -1
- data/lib/relaton/bibcollection.rb +35 -30
- data/lib/relaton/bibdata.rb +22 -26
- data/lib/relaton/cli/base_convertor.rb +15 -7
- data/lib/relaton/cli/command.rb +1 -10
- data/lib/relaton/cli/relaton_file.rb +20 -9
- data/lib/relaton/cli/version.rb +1 -1
- data/lib/relaton/cli/xml_convertor.rb +1 -11
- data/lib/relaton/cli/xml_to_html_renderer.rb +32 -12
- data/relaton-cli.gemspec +1 -1
- data/templates/_document.liquid +10 -5
- metadata +4 -6
- data/lib/relaton/cli/_document.liquid +0 -82
- data/lib/relaton/cli/_index.liquid +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 189c177f77c4ebd844d4df2dbe9deb987d90443e3e91ff50d8ebf1a7ce8d3685
|
4
|
+
data.tar.gz: 73a886c43a4b0262a6f96725143a5714dae88440715122a36360e343d753ea56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d7e76cfa44de6d91dc4ce1f631c68b845fa152de4ecbfa76a5deebb59e706784c0f0a5c1dea302336e153d751217e612f42c324498336390ce67891f4f773fa
|
7
|
+
data.tar.gz: ea44768cba9f5a88b46f03c588237d0de5fe91d0fb4952b5761236fafcabe1ec5992b921ecbd87052e3082e0f45c24ee074409825c0f32f934055ffac7eb2b93
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/docs/README.adoc
CHANGED
@@ -43,12 +43,13 @@ suports an additional `-x` or `--extension` options to use different extension.
|
|
43
43
|
|
44
44
|
[source,console]
|
45
45
|
----
|
46
|
-
$ relaton fetch CODE -t TYPE -y YEAR
|
46
|
+
$ relaton fetch CODE -t TYPE -f FORMAT -y YEAR
|
47
47
|
----
|
48
48
|
|
49
49
|
Fetch the Relaton XML entry corresponding to the document identifier `CODE`.
|
50
50
|
|
51
51
|
* `YEAR` is optional, and specifies the year of publication of the standard.
|
52
|
+
* `FORMAT` is optional, and specifies the output format; the recognised values for `FORMAT` are `xml` (default), `bibtex`.
|
52
53
|
* `TYPE` specifies the standards class library to be used, that the identifier is part of; the recognised
|
53
54
|
values for `TYPE` are `isobib`, `ietfbib`, `iecbib`, `gbbib`.
|
54
55
|
|
data/lib/relaton-cli.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
require_relative "relaton/bibcollection"
|
2
2
|
require_relative "relaton/bibdata"
|
3
3
|
require_relative "relaton/element_finder"
|
4
|
-
require_relative "relaton/xml_document"
|
4
|
+
# require_relative "relaton/xml_document"
|
5
|
+
require_relative "relaton/cli/yaml_convertor"
|
6
|
+
|
7
|
+
module Relaton
|
8
|
+
module Cli
|
9
|
+
end
|
10
|
+
end
|
@@ -4,15 +4,12 @@ module Relaton
|
|
4
4
|
class Bibcollection
|
5
5
|
extend Relaton::ElementFinder
|
6
6
|
|
7
|
-
ATTRIBS = %i[
|
8
|
-
title
|
9
|
-
items
|
10
|
-
doctype
|
11
|
-
author
|
12
|
-
].freeze
|
7
|
+
ATTRIBS = %i[title items doctype author].freeze
|
13
8
|
|
14
9
|
attr_accessor *ATTRIBS
|
15
10
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
12
|
+
|
16
13
|
def initialize(options)
|
17
14
|
self.items = []
|
18
15
|
ATTRIBS.each do |k|
|
@@ -20,30 +17,38 @@ module Relaton
|
|
20
17
|
send("#{k}=", value)
|
21
18
|
end
|
22
19
|
self.items = (items || []).reduce([]) do |acc, item|
|
23
|
-
acc << if item.is_a?(
|
20
|
+
acc << if item.is_a?(Bibcollection) || item.is_a?(Bibdata)
|
24
21
|
item
|
25
22
|
else new_bib_item_class(item)
|
26
23
|
end
|
27
24
|
end
|
28
25
|
end
|
26
|
+
# rubocop:enable Metrics/MethodLength
|
29
27
|
|
30
28
|
# arbitrary number, must sort after all bib items
|
31
29
|
def doc_number
|
32
30
|
9999999
|
33
31
|
end
|
34
32
|
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
34
|
+
|
35
|
+
# @param source [Nokogiri::XML::Element]
|
35
36
|
def self.from_xml(source)
|
36
37
|
title = find_text("./relaton-collection/title", source)
|
37
|
-
author = find_text(
|
38
|
+
author = find_text(
|
39
|
+
"./relaton-collection/contributor[role/@type='author']/organization/name",
|
40
|
+
source,
|
41
|
+
)
|
38
42
|
|
39
43
|
items = find_xpath("./relaton-collection/relation", source)&.map do |item|
|
40
|
-
bibdata = find("./bibdata", item)
|
44
|
+
bibdata = find("./bibdata|./bibitem", item)
|
41
45
|
klass = bibdata ? Bibdata : Bibcollection
|
42
46
|
klass.from_xml(bibdata || item)
|
43
47
|
end
|
44
48
|
|
45
49
|
new(title: title, author: author, items: items)
|
46
50
|
end
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
47
52
|
|
48
53
|
def new_bib_item_class(options)
|
49
54
|
if options.is_a?(Hash) && options["items"]
|
@@ -54,34 +59,35 @@ module Relaton
|
|
54
59
|
end
|
55
60
|
|
56
61
|
def items_flattened
|
57
|
-
items.sort_by!
|
58
|
-
b.docnumber
|
59
|
-
end
|
62
|
+
items.sort_by! &:docnumber
|
60
63
|
|
61
|
-
items.
|
62
|
-
if item.is_a? ::Relaton::Bibcollection
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
items.reduce([]) do |acc,item|
|
65
|
+
acc << if item.is_a? ::Relaton::Bibcollection
|
66
|
+
item.items_flattened
|
67
|
+
else
|
68
|
+
item
|
69
|
+
end
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
73
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
74
|
+
|
75
|
+
# @param opts [Hash]
|
76
|
+
# @return [String] XML
|
70
77
|
def to_xml(opts = {})
|
71
|
-
items.sort_by!
|
72
|
-
b.doc_number
|
73
|
-
end
|
78
|
+
items.sort_by! &:doc_number
|
74
79
|
|
75
80
|
collection_type = if doctype
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
81
|
+
"type=\"#{doctype}\""
|
82
|
+
else
|
83
|
+
'xmlns="https://open.ribose.com/relaton-xml"'
|
84
|
+
end
|
80
85
|
|
81
86
|
ret = "<relaton-collection #{collection_type}>"
|
82
87
|
ret += "<title>#{title}</title>" if title
|
83
88
|
if author
|
84
|
-
ret += "<contributor><role type='author'/><organization><name
|
89
|
+
ret += "<contributor><role type='author'/><organization><name>"\
|
90
|
+
"#{author}</name></organization></contributor>"
|
85
91
|
end
|
86
92
|
unless items.empty?
|
87
93
|
items.each do |item|
|
@@ -92,17 +98,16 @@ module Relaton
|
|
92
98
|
end
|
93
99
|
ret += "</relaton-collection>\n"
|
94
100
|
end
|
101
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
95
102
|
|
96
103
|
def to_yaml
|
97
104
|
to_h.to_yaml
|
98
105
|
end
|
99
106
|
|
100
107
|
def to_h
|
101
|
-
items.sort_by!
|
102
|
-
b.doc_number
|
103
|
-
end
|
108
|
+
items.sort_by! &:doc_number
|
104
109
|
|
105
|
-
a = ATTRIBS.
|
110
|
+
a = ATTRIBS.reduce({}) do |acc, k|
|
106
111
|
acc[k.to_s] = send(k)
|
107
112
|
acc
|
108
113
|
end
|
data/lib/relaton/bibdata.rb
CHANGED
@@ -2,7 +2,7 @@ require "date"
|
|
2
2
|
|
3
3
|
module Relaton
|
4
4
|
class Bibdata
|
5
|
-
URL_TYPES = %i[uri xml pdf doc html rxl txt]
|
5
|
+
URL_TYPES = %i[uri xml pdf doc html rxl txt].freeze
|
6
6
|
|
7
7
|
attr_reader :bibitem
|
8
8
|
|
@@ -10,18 +10,6 @@ module Relaton
|
|
10
10
|
@bibitem = bibitem
|
11
11
|
end
|
12
12
|
|
13
|
-
# def method_missing(method, *args)
|
14
|
-
# %r{(?<m>\w+)=$} =~ method
|
15
|
-
# return unless m && %w[xml pdf doc html rxl txt].include?(m)
|
16
|
-
|
17
|
-
# uri = @bibitem.link.detect { |u| u.type == m }
|
18
|
-
# if uri
|
19
|
-
# uri.content = args[0]
|
20
|
-
# else
|
21
|
-
# @bibitem.link << RelatonBib::TypedUri.new(type: m, content: args[0])
|
22
|
-
# end
|
23
|
-
# end
|
24
|
-
|
25
13
|
def docidentifier
|
26
14
|
@bibitem.docidentifier.first&.id
|
27
15
|
end
|
@@ -31,16 +19,18 @@ module Relaton
|
|
31
19
|
# end
|
32
20
|
|
33
21
|
# From http://gavinmiller.io/2016/creating-a-secure-sanitization-function/
|
34
|
-
FILENAME_BAD_CHARS = [
|
22
|
+
FILENAME_BAD_CHARS = ["/", '\\', "?", "%", "*", ":", "|", '"', "<", ">",
|
23
|
+
".", " "].freeze
|
35
24
|
|
36
25
|
def docidentifier_code
|
37
26
|
return "" if docidentifier.nil?
|
38
|
-
|
39
|
-
|
27
|
+
|
28
|
+
FILENAME_BAD_CHARS.reduce(docidentifier.downcase) do |result, bad_char|
|
29
|
+
result.gsub(bad_char, "-")
|
40
30
|
end
|
41
31
|
end
|
42
32
|
|
43
|
-
DOC_NUMBER_REGEX = /([\w\/]+)\s+(\d+):?(\d*)
|
33
|
+
DOC_NUMBER_REGEX = /([\w\/]+)\s+(\d+):?(\d*)/.freeze
|
44
34
|
def doc_number
|
45
35
|
docidentifier&.match(DOC_NUMBER_REGEX) ? $2.to_i : 999999
|
46
36
|
end
|
@@ -51,18 +41,15 @@ module Relaton
|
|
51
41
|
end
|
52
42
|
|
53
43
|
def to_xml(opts = {})
|
54
|
-
options = { bibdata: true, date_format: :full }.merge
|
44
|
+
options = { bibdata: true, date_format: :full }.merge(
|
45
|
+
opts.select { |k, _v| k.is_a? Symbol },
|
46
|
+
)
|
55
47
|
@bibitem.to_xml nil, **options
|
56
|
-
|
57
|
-
# #datetype = stage&.casecmp("published") == 0 ? "published" : "circulated"
|
58
|
-
|
59
|
-
# ret = ref ? "<bibitem id= '#{ref}' type='#{doctype}'>\n" : "<bibdata type='#{doctype}'>\n"
|
60
|
-
# ret += "<fetched>#{Date.today.to_s}</fetched>\n"
|
61
48
|
end
|
62
49
|
|
63
50
|
def to_h
|
64
51
|
URL_TYPES.reduce({ items: [] }.merge(@bibitem.to_hash)) do |h, t|
|
65
|
-
value =
|
52
|
+
value = send t
|
66
53
|
h[t.to_s] = value
|
67
54
|
h
|
68
55
|
end
|
@@ -72,15 +59,22 @@ module Relaton
|
|
72
59
|
to_h.to_yaml
|
73
60
|
end
|
74
61
|
|
62
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
63
|
+
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity, Style/MissingRespondToMissing
|
64
|
+
|
75
65
|
def method_missing(meth, *args)
|
76
66
|
if @bibitem.respond_to?(meth)
|
77
67
|
@bibitem.send meth, *args
|
78
68
|
elsif URL_TYPES.include? meth
|
79
|
-
link = @bibitem.link.detect
|
69
|
+
link = @bibitem.link.detect do |l|
|
70
|
+
l.type == meth.to_s || meth == :uri && l.type.nil?
|
71
|
+
end
|
80
72
|
link&.content&.to_s
|
81
73
|
elsif URL_TYPES.include? meth.match(/^\w+(?==)/).to_s.to_sym
|
82
74
|
/^(?<type>\w+)/ =~ meth
|
83
|
-
link = @bibitem.link.detect
|
75
|
+
link = @bibitem.link.detect do |l|
|
76
|
+
l.type == type || type == "uri" && l.type.nil?
|
77
|
+
end
|
84
78
|
if link
|
85
79
|
link.content = args[0]
|
86
80
|
else
|
@@ -90,5 +84,7 @@ module Relaton
|
|
90
84
|
super
|
91
85
|
end
|
92
86
|
end
|
87
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
88
|
+
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity, Style/MissingRespondToMissing
|
93
89
|
end
|
94
90
|
end
|
@@ -17,6 +17,7 @@ module Relaton
|
|
17
17
|
install_dependencies(options[:require] || [])
|
18
18
|
end
|
19
19
|
|
20
|
+
# @return [String] HTML
|
20
21
|
def to_html
|
21
22
|
content = convert_to_html
|
22
23
|
write_to_a_file(content)
|
@@ -32,12 +33,13 @@ module Relaton
|
|
32
33
|
# @param style [String] Stylesheet file path for styles
|
33
34
|
# @param template [String] The liquid tempalte directory
|
34
35
|
#
|
36
|
+
# @return [String] HTML
|
35
37
|
def self.to_html(file, style = nil, template = nil)
|
36
38
|
new(
|
37
39
|
file,
|
38
40
|
style: style || File.join(File.dirname(__FILE__), "../../../templates/index-style.css"),
|
39
41
|
template: template || File.join(File.dirname(__FILE__), "../../../templates/"),
|
40
|
-
extension: "html"
|
42
|
+
extension: "html",
|
41
43
|
).to_html
|
42
44
|
end
|
43
45
|
|
@@ -45,6 +47,7 @@ module Relaton
|
|
45
47
|
|
46
48
|
attr_reader :file, :outdir, :options, :writable, :overwrite
|
47
49
|
|
50
|
+
# @return [String] HTML
|
48
51
|
def convert_to_html
|
49
52
|
Relaton::Cli::XmlToHtmlRenderer.render(
|
50
53
|
xml_content(file),
|
@@ -53,6 +56,9 @@ module Relaton
|
|
53
56
|
)
|
54
57
|
end
|
55
58
|
|
59
|
+
# @param file [String] path to a file
|
60
|
+
# @return [String] the file's content
|
61
|
+
# @return [String] HTML
|
56
62
|
def xml_content(file)
|
57
63
|
File.read(file, encoding: "utf-8")
|
58
64
|
end
|
@@ -92,7 +98,7 @@ module Relaton
|
|
92
98
|
# write_to_a_file(item_output(item, format), collection)
|
93
99
|
# end
|
94
100
|
# end
|
95
|
-
if outdir &&
|
101
|
+
if outdir && content.is_a?(Relaton::Bibcollection)
|
96
102
|
FileUtils.mkdir_p(outdir)
|
97
103
|
content.items_flattened.each do |item|
|
98
104
|
collection = collection_filename(extract_docid(item))
|
@@ -103,19 +109,21 @@ module Relaton
|
|
103
109
|
|
104
110
|
def extract_docid(item)
|
105
111
|
@default_filelabel += 1
|
106
|
-
item.docidentifier.nil?
|
112
|
+
item.docidentifier.nil? && (return @default_filelabel.to_s)
|
107
113
|
# item.docidentifier.is_a?(Array) or return @default_filelabel.to_s
|
108
|
-
item.docidentifier.empty?
|
114
|
+
item.docidentifier.empty? && (return @default_filelabel.to_s)
|
109
115
|
docidentifier_code(item.docidentifier)
|
110
116
|
end
|
111
117
|
|
112
118
|
# From http://gavinmiller.io/2016/creating-a-secure-sanitization-function/
|
113
|
-
FILENAME_BAD_CHARS = [
|
119
|
+
FILENAME_BAD_CHARS = ["/", '\\', "?", '%", "*", ":', "|", '"', "<", ">",
|
120
|
+
".", " "].freeze
|
114
121
|
|
115
122
|
def docidentifier_code(docidentifier)
|
116
123
|
return "" if docidentifier.nil?
|
117
|
-
|
118
|
-
|
124
|
+
|
125
|
+
FILENAME_BAD_CHARS.reduce(docidentifier.downcase) do |result, bad_char|
|
126
|
+
result.gsub(bad_char, "-")
|
119
127
|
end
|
120
128
|
end
|
121
129
|
|
data/lib/relaton/cli/command.rb
CHANGED
@@ -73,16 +73,7 @@ module Relaton
|
|
73
73
|
Relaton::Cli::XMLConvertor.to_html(file, style, template)
|
74
74
|
end
|
75
75
|
|
76
|
-
|
77
|
-
# option :stylesheet, aliases: :s, desc: "Stylesheet file path for rendering HTML index"
|
78
|
-
# option :templatedir, aliases: :t, desc: "Liquid template directory for rendering Relaton items and collection"
|
79
|
-
# option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
|
80
|
-
|
81
|
-
# def yaml2html(file, style = nil, template = nil)
|
82
|
-
# Relaton::Cli::YAMLConvertor.to_html(file, style, template)
|
83
|
-
# end
|
84
|
-
|
85
|
-
desc "yaml2htmlnew RELATON-INDEX-YAML", "Concatenate Relaton Collection YAML into HTML"
|
76
|
+
desc "yaml2html RELATON-INDEX-YAML", "Concatenate Relaton Collection YAML into HTML"
|
86
77
|
option :stylesheet, aliases: :s, desc: "Stylesheet file path for rendering HTML index"
|
87
78
|
option :templatedir, aliases: :t, desc: "Liquid template directory for rendering Relaton items and collection"
|
88
79
|
option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
|
@@ -89,6 +89,9 @@ module Relaton
|
|
89
89
|
)
|
90
90
|
end
|
91
91
|
|
92
|
+
# @param document [String] XML
|
93
|
+
# @param file [String, nil] path to file
|
94
|
+
# @return [Nokogiri::XML::Document]
|
92
95
|
def nokogiri_document(document, file = nil)
|
93
96
|
document ||= File.read(file, encoding: "utf-8")
|
94
97
|
Nokogiri.XML(document)
|
@@ -115,7 +118,6 @@ module Relaton
|
|
115
118
|
bib = nokogiri_document(bib.to_xml)
|
116
119
|
elsif (rfc = xml.at("//rfc"))
|
117
120
|
require "relaton_ietf/scrapper"
|
118
|
-
#ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
|
119
121
|
ietf = RelatonIetf::Scrapper.fetch_rfc rfc
|
120
122
|
bib = nokogiri_document ietf.to_xml(bibdata: true)
|
121
123
|
else
|
@@ -137,16 +139,18 @@ module Relaton
|
|
137
139
|
def concatenate_files
|
138
140
|
xml_files = [convert_rxl_to_xml, convert_yamls_to_xml, convert_xml_to_xml]
|
139
141
|
|
140
|
-
xml_files.flatten.
|
142
|
+
xml_files.flatten.reduce([]) do |mem, xml|
|
141
143
|
doc = nokogiri_document(xml[:content])
|
142
|
-
if (rfc = doc.at("
|
144
|
+
if (rfc = doc.at("/rfc"))
|
143
145
|
require "relaton_ietf/scrapper"
|
144
|
-
#ietf = RelatonIetf::Scrapper.bib_item rfc, "rfc"
|
145
146
|
ietf = RelatonIetf::Scrapper.fetch_rfc rfc
|
146
|
-
|
147
|
+
d = nokogiri_document ietf.to_xml(bibdata: true)
|
148
|
+
mem << bibdata_instance(d, xml[:file])
|
149
|
+
elsif %w[bibitem bibdata].include? doc&.root&.name
|
150
|
+
mem << bibdata_instance(doc, xml[:file])
|
151
|
+
else mem
|
147
152
|
end
|
148
|
-
|
149
|
-
end.compact
|
153
|
+
end.uniq &:id
|
150
154
|
end
|
151
155
|
|
152
156
|
def concatenate_and_write_to_files
|
@@ -163,7 +167,7 @@ module Relaton
|
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
166
|
-
def find_available_bibrxl_file(name,
|
170
|
+
def find_available_bibrxl_file(name, _ouputdir, content)
|
167
171
|
if options[:extension] == "yaml" || options[:extension] == "yml"
|
168
172
|
bib_rxl = Pathname.new([outdir, name].join("/")).sub_ext(".rxl")
|
169
173
|
content.bib_rxl = bib_rxl.to_s if File.file?(bib_rxl)
|
@@ -182,6 +186,9 @@ module Relaton
|
|
182
186
|
end
|
183
187
|
end
|
184
188
|
|
189
|
+
# @param document [Nokogiri::XML::Document]
|
190
|
+
# @param file [String] path to file
|
191
|
+
# @return [Relaton::Bibdata]
|
185
192
|
def bibdata_instance(document, file)
|
186
193
|
document = clean_nokogiri_document(document)
|
187
194
|
bibdata = Relaton::Bibdata.from_xml document.root
|
@@ -190,6 +197,8 @@ module Relaton
|
|
190
197
|
bibdata
|
191
198
|
end
|
192
199
|
|
200
|
+
# @param bibdata [Relaton::Bibdata]
|
201
|
+
# @param file [String] path to file
|
193
202
|
def build_bibdata_relaton(bibdata, file)
|
194
203
|
["xml", "pdf", "doc", "html", "rxl", "txt"].each do |type|
|
195
204
|
file = Pathname.new(file).sub_ext(".#{type}")
|
@@ -202,6 +211,8 @@ module Relaton
|
|
202
211
|
# has an xmlns. We don't want to change the code for bibdata
|
203
212
|
# hence this hack #bibdata_doc.root['xmlns'] = "xmlns"
|
204
213
|
#
|
214
|
+
# @param document [Nokogiri::XML::Document]
|
215
|
+
# @return [Nokogiri::XML::Document]
|
205
216
|
def clean_nokogiri_document(document)
|
206
217
|
document.remove_namespaces!
|
207
218
|
document.root.add_namespace(nil, "xmlns")
|
@@ -256,7 +267,7 @@ module Relaton
|
|
256
267
|
|
257
268
|
def replace_bad_characters(string)
|
258
269
|
bad_chars = ["/", "\\", "?", "%", "*", ":", "|", '"', "<", ">", ".", " "]
|
259
|
-
bad_chars.
|
270
|
+
bad_chars.reduce(string.downcase) { |res, char| res.gsub(char, "-") }
|
260
271
|
end
|
261
272
|
end
|
262
273
|
end
|
data/lib/relaton/cli/version.rb
CHANGED
@@ -32,20 +32,10 @@ module Relaton
|
|
32
32
|
# @param content [Nokogiri::XML::Document]
|
33
33
|
# @return [Hash]
|
34
34
|
def convert_content(content)
|
35
|
-
if content.root.name
|
35
|
+
if %w[bibitem bibdata].include? content.root.name
|
36
36
|
Bibdata.from_xml(content)
|
37
|
-
# Relaton::Cli.parse_xml(content).to_hash
|
38
37
|
else
|
39
38
|
Bibcollection.from_xml(content)
|
40
|
-
# title = content.at("relaton-collection/title").text
|
41
|
-
# author = content.at("relaton-collection/contributor/organization/name").text
|
42
|
-
# collection = { "root" => { "title" => title, "author" => author } }
|
43
|
-
|
44
|
-
# collection["root"]["items"] = content.xpath("//bibdata").map do |bib|
|
45
|
-
# Relaton::Cli.parse_xml(bib).to_hash
|
46
|
-
# end
|
47
|
-
|
48
|
-
# collection
|
49
39
|
end
|
50
40
|
end
|
51
41
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "nokogiri"
|
2
2
|
require "liquid"
|
3
|
-
require
|
3
|
+
require "pp"
|
4
4
|
|
5
5
|
module Relaton::Cli
|
6
6
|
class XmlToHtmlRenderer
|
@@ -10,16 +10,16 @@ module Relaton::Cli
|
|
10
10
|
init_liquid_template_and_filesystem
|
11
11
|
end
|
12
12
|
|
13
|
+
# @param index_xml [String] Relaton XML
|
14
|
+
# @return [String] HTML
|
13
15
|
def render(index_xml)
|
14
16
|
Liquid::Template.
|
15
17
|
parse(template).
|
16
|
-
render(build_liquid_document(index_xml)
|
18
|
+
render(build_liquid_document(index_xml))
|
17
19
|
end
|
18
20
|
|
19
21
|
def uri_for_extension(uri, extension)
|
20
|
-
|
21
|
-
uri.sub(/\.[^.]+$/, ".#{extension.to_s}")
|
22
|
-
end
|
22
|
+
uri&.sub(/\.[^.]+$/, ".#{extension}")
|
23
23
|
end
|
24
24
|
|
25
25
|
# Render HTML
|
@@ -28,6 +28,9 @@ module Relaton::Cli
|
|
28
28
|
# using the specified liquid template and stylesheets. It
|
29
29
|
# also do some minor clean during this conversion.
|
30
30
|
#
|
31
|
+
# @param file [String] Relaton XML
|
32
|
+
# @param options [Hash]
|
33
|
+
# @return [String] HTML
|
31
34
|
def self.render(file, options)
|
32
35
|
new(options).render(file)
|
33
36
|
end
|
@@ -40,16 +43,17 @@ module Relaton::Cli
|
|
40
43
|
File.read(file, encoding: "utf-8")
|
41
44
|
end
|
42
45
|
|
46
|
+
# @param source [String] Relaton XML
|
43
47
|
def build_liquid_document(source)
|
44
48
|
bibcollection = build_bibcollection(source)
|
45
49
|
|
46
|
-
hash_to_liquid(
|
50
|
+
hash_to_liquid(
|
47
51
|
depth: 2,
|
48
52
|
css: stylesheet,
|
49
53
|
title: bibcollection.title,
|
50
54
|
author: bibcollection.author,
|
51
|
-
documents: document_items(bibcollection)
|
52
|
-
|
55
|
+
documents: document_items(bibcollection),
|
56
|
+
)
|
53
57
|
end
|
54
58
|
|
55
59
|
def init_liquid_template_and_filesystem
|
@@ -59,7 +63,17 @@ module Relaton::Cli
|
|
59
63
|
Liquid::Template.file_system = file_system
|
60
64
|
end
|
61
65
|
|
66
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
67
|
+
|
62
68
|
# TODO: This should be recursive, but it's not
|
69
|
+
# @param hash [Hash]
|
70
|
+
# @option hash [Integer] :dept
|
71
|
+
# @option hash [String] :css path to stylesheet file
|
72
|
+
# @option hash [String] :title
|
73
|
+
# @option hash [String] :author
|
74
|
+
# @option hash [Array<Hash>] :documents
|
75
|
+
#
|
76
|
+
# @return [Hash]
|
63
77
|
def hash_to_liquid(hash)
|
64
78
|
hash.map do |key, value|
|
65
79
|
case key
|
@@ -71,24 +85,30 @@ module Relaton::Cli
|
|
71
85
|
else v = value
|
72
86
|
end
|
73
87
|
when "docid"
|
74
|
-
if value.is_a?(Array)
|
75
|
-
|
76
|
-
|
77
|
-
|
88
|
+
v = if value.is_a?(Array)
|
89
|
+
value.detect { |did| did["id"] !~ /^(http|https):\/\// } ||
|
90
|
+
value.first
|
91
|
+
else value
|
92
|
+
end
|
78
93
|
else v = value
|
79
94
|
end
|
80
95
|
[key.to_s, empty2nil(v)]
|
81
96
|
end.to_h
|
82
97
|
end
|
98
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
83
99
|
|
84
100
|
def empty2nil(value)
|
85
101
|
value unless value.is_a?(String) && value.empty? && !value.nil?
|
86
102
|
end
|
87
103
|
|
104
|
+
# @param source [String] Relaton XML
|
105
|
+
# @return [Relaton::Bibcollection]
|
88
106
|
def build_bibcollection(source)
|
89
107
|
Relaton::Bibcollection.from_xml(Nokogiri::XML(source))
|
90
108
|
end
|
91
109
|
|
110
|
+
# @param bibcollection [Relaton::Bibcollection]
|
111
|
+
# @return [Array<Hash>]
|
92
112
|
def document_items(bibcollection)
|
93
113
|
bibcollection.to_h["root"]["items"].map { |item| hash_to_liquid(item) }
|
94
114
|
end
|
data/relaton-cli.gemspec
CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency "simplecov"
|
35
35
|
|
36
36
|
spec.add_runtime_dependency "liquid"
|
37
|
-
spec.add_runtime_dependency "relaton", "~> 1.
|
37
|
+
spec.add_runtime_dependency "relaton", "~> 1.1.0"
|
38
38
|
spec.add_runtime_dependency "thor"
|
39
39
|
# spec.add_runtime_dependency 'byebug'
|
40
40
|
end
|
data/templates/_document.liquid
CHANGED
@@ -32,12 +32,17 @@
|
|
32
32
|
</h{{ depth | plus: 1 }}>
|
33
33
|
</div>
|
34
34
|
|
35
|
-
<div class="doc-info {{ document.docstatus.stage | downcase }}">
|
36
|
-
<div class="doc-stage {{ document.docstatus.stage | downcase }}">
|
37
|
-
{{ document.docstatus.stage }}
|
35
|
+
<div class="doc-info {{ document.docstatus.stage.value | downcase }}">
|
36
|
+
<div class="doc-stage {{ document.docstatus.stage.value | downcase }}">
|
37
|
+
{{ document.docstatus.stage.abbreviation }}
|
38
|
+
{% if document.docstatus.substage %}
|
39
|
+
{{ document.docstatus.stage.value }}.{{ document.docstatus.substage.value }}
|
40
|
+
{% else %}
|
41
|
+
{{ document.docstatus.stage.value }}
|
42
|
+
{% endif %}
|
38
43
|
</div>
|
39
44
|
<div class="doc-dates">
|
40
|
-
{% unless document.docstatus.stage == "published" %}
|
45
|
+
{% unless document.docstatus.stage.value == "published" %}
|
41
46
|
<div class="doc-updated">
|
42
47
|
{% else %}
|
43
48
|
<div class="doc-published">
|
@@ -49,7 +54,7 @@
|
|
49
54
|
|
50
55
|
<div class="doc-bib">
|
51
56
|
<div class="doc-bib-relaton">
|
52
|
-
<a href="{{ document.
|
57
|
+
<a href="{{ document.rxl }}">Relaton XML</a>
|
53
58
|
</div>
|
54
59
|
</div>
|
55
60
|
|
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: 1.
|
4
|
+
version: 1.1.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: 2020-
|
11
|
+
date: 2020-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
173
|
+
version: 1.1.0
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: 1.
|
180
|
+
version: 1.1.0
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: thor
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -223,8 +223,6 @@ files:
|
|
223
223
|
- lib/relaton/bibcollection.rb
|
224
224
|
- lib/relaton/bibdata.rb
|
225
225
|
- lib/relaton/cli.rb
|
226
|
-
- lib/relaton/cli/_document.liquid
|
227
|
-
- lib/relaton/cli/_index.liquid
|
228
226
|
- lib/relaton/cli/base_convertor.rb
|
229
227
|
- lib/relaton/cli/command.rb
|
230
228
|
- lib/relaton/cli/relaton_file.rb
|
@@ -1,82 +0,0 @@
|
|
1
|
-
{%- if document.items.size > 0 -%}
|
2
|
-
<div class="doc-section">
|
3
|
-
{%- else -%}
|
4
|
-
<div class="document">
|
5
|
-
{%- endif -%}
|
6
|
-
|
7
|
-
<div class="doc-line">
|
8
|
-
<div class="doc-identifier">
|
9
|
-
<h{{ depth }}>
|
10
|
-
{% if document.html == "" %}
|
11
|
-
{{ document.docid.id }}
|
12
|
-
{% else %}
|
13
|
-
<a href="{{ document.html }}">{{ document.docid.id }}</a>
|
14
|
-
{% endif %}
|
15
|
-
</h{{ depth }}>
|
16
|
-
</div>
|
17
|
-
|
18
|
-
<div class="doc-type-wrap">
|
19
|
-
<div class="doc-type {{ document.type | downcase | split: " " | join: "-" }}">
|
20
|
-
{{ document.type }}
|
21
|
-
</div>
|
22
|
-
</div>
|
23
|
-
</div>
|
24
|
-
|
25
|
-
<div class="doc-title">
|
26
|
-
<h{{ depth | plus: 1 }}>
|
27
|
-
{% if document.html == blank or document.html == nil %}
|
28
|
-
{{ document.title }}
|
29
|
-
{% else %}
|
30
|
-
<a href="{{ document.html }}">{{ document.title }}</a>
|
31
|
-
{% endif %}
|
32
|
-
</h{{ depth | plus: 1 }}>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<div class="doc-info {{ document.docstatus.stage | downcase }}">
|
36
|
-
<div class="doc-stage {{ document.docstatus.stage | downcase }}">
|
37
|
-
{{ document.docstatus.stage }}
|
38
|
-
</div>
|
39
|
-
<div class="doc-dates">
|
40
|
-
{% unless document.docstatus.stage == "published" %}
|
41
|
-
<div class="doc-updated">
|
42
|
-
{% else %}
|
43
|
-
<div class="doc-published">
|
44
|
-
{% endunless %}
|
45
|
-
{{ document.revdate }}
|
46
|
-
</div>
|
47
|
-
</div>
|
48
|
-
</div>
|
49
|
-
|
50
|
-
<div class="doc-bib">
|
51
|
-
<div class="doc-bib-relaton">
|
52
|
-
<a href="{{ document.relaton }}">Relaton XML</a>
|
53
|
-
</div>
|
54
|
-
</div>
|
55
|
-
|
56
|
-
<div class="doc-access">
|
57
|
-
{% unless document.html == blank or document.html == nil %}
|
58
|
-
<div class="doc-access-button-html">
|
59
|
-
<a href="{{ document.html }}">HTML</a>
|
60
|
-
</div>
|
61
|
-
{% endunless %}
|
62
|
-
{% unless document.pdf == blank or document.pdf == nil %}
|
63
|
-
<div class="doc-access-button-pdf">
|
64
|
-
<a href="{{ document.pdf }}">PDF</a>
|
65
|
-
</div>
|
66
|
-
{% endunless %}
|
67
|
-
{% unless document.doc == blank or document.doc == nil %}
|
68
|
-
<div class="doc-access-button-doc">
|
69
|
-
<a href="{{ document.doc }}">Word</a>
|
70
|
-
</div>
|
71
|
-
{% endunless %}
|
72
|
-
{% unless document.xml == blank or document.xml == nil %}
|
73
|
-
<div class="doc-access-button-xml">
|
74
|
-
<a href="{{ document.xml }}">XML</a>
|
75
|
-
</div>
|
76
|
-
{% endunless %}
|
77
|
-
</div>
|
78
|
-
</div>
|
79
|
-
|
80
|
-
{%- if document.items.size > 0 -%}
|
81
|
-
{%- include 'document' for document.items -%}
|
82
|
-
{%- endif -%}
|
@@ -1,53 +0,0 @@
|
|
1
|
-
<!DOCTYPE HTML>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title>{{ title }}</title>
|
5
|
-
<style>
|
6
|
-
<!--
|
7
|
-
{{ css }}
|
8
|
-
-->
|
9
|
-
</style>
|
10
|
-
<meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
|
11
|
-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
|
12
|
-
<script src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js" type="text/javascript"></script>
|
13
|
-
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i|Space+Mono:400,700|Overpass:300,300i,600,900|Ek+Mukta:200" rel="stylesheet" type="text/css"/>
|
14
|
-
<link href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous"/>
|
15
|
-
<link href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous"/>
|
16
|
-
</head>
|
17
|
-
<body>
|
18
|
-
<header>
|
19
|
-
<div id="topbar-inner">
|
20
|
-
<div id="title-bar"><span>{{ author }}</span></div>
|
21
|
-
</div>
|
22
|
-
<div class="title-section">
|
23
|
-
<div class="coverpage">
|
24
|
-
<div class="wrapper-top">
|
25
|
-
<div class="coverpage-doc-identity">
|
26
|
-
<div class="coverpage-title"><span class="title-first">{{ title }}</span></div>
|
27
|
-
</div>
|
28
|
-
</div>
|
29
|
-
</div>
|
30
|
-
</div>
|
31
|
-
</header>
|
32
|
-
<main class="main-section">
|
33
|
-
{% include 'document' for documents %}
|
34
|
-
</main>
|
35
|
-
<footer>
|
36
|
-
<div class="copyright">
|
37
|
-
<p class="year">© {{ author }}</p>
|
38
|
-
<p class="message">All rights reserved. Unless otherwise specified, no part of this publication may be reproduced or utilized otherwise in any form or by any means, electronic or mechanical, including photocopying, or posting on the internet or an intranet, without prior written permission.</p>
|
39
|
-
</div>
|
40
|
-
</footer>
|
41
|
-
<script>
|
42
|
-
$(document).ready(function() {
|
43
|
-
$('[id^=toc]').each(function () {
|
44
|
-
var currentToc = $(this);
|
45
|
-
var url = window.location.href;
|
46
|
-
currentToc.wrap("<a href='" + url + "#" + currentToc.attr("id") + "' <\/a>");
|
47
|
-
});
|
48
|
-
});
|
49
|
-
anchors.options = { placement: 'left' };
|
50
|
-
anchors.add('h1, h2, h3, h4');
|
51
|
-
</script>
|
52
|
-
</body>
|
53
|
-
</html>
|