relaton-cli 1.0.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/docs/README.adoc +2 -1
- data/lib/relaton-cli.rb +7 -1
- data/lib/relaton/bibcollection.rb +34 -29
- data/lib/relaton/bibdata.rb +17 -9
- data/lib/relaton/cli/base_convertor.rb +15 -7
- data/lib/relaton/cli/command.rb +12 -11
- data/lib/relaton/cli/relaton_file.rb +20 -6
- data/lib/relaton/cli/version.rb +1 -1
- data/lib/relaton/cli/xml_convertor.rb +1 -1
- data/lib/relaton/cli/xml_to_html_renderer.rb +32 -12
- data/relaton-cli.gemspec +1 -1
- data/templates/_document.liquid +9 -4
- 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: d8049656d1afb46e4ba336f812b0eb6261525e64b6d127b313c03a8c5ce4c72e
|
4
|
+
data.tar.gz: bcfa7ebc31360fd27f2ccb2f21f1e864fc283433bdba045ff6c8e7393aabc25b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a49edaeb34c75d64fcdb63ac642a3882086c0d994f169a0691f9f86fe27b7a1be4680f2295bbf80301b6089d76154bdfa734364ecbb2909ee0d630dd4cc616a
|
7
|
+
data.tar.gz: 2ead71208ec783d66af83bfcc89901d3d9da70e441d9464cb6f5f6b57838c5e5cde8bec940d4856804abe0260e60c6e30cfda9c7becec50c60a0b31fc66edf63
|
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,21 +17,28 @@ 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
44
|
bibdata = find("./bibdata", item)
|
@@ -44,6 +48,7 @@ module Relaton
|
|
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
|
|
@@ -31,16 +31,18 @@ module Relaton
|
|
31
31
|
# end
|
32
32
|
|
33
33
|
# From http://gavinmiller.io/2016/creating-a-secure-sanitization-function/
|
34
|
-
FILENAME_BAD_CHARS = [
|
34
|
+
FILENAME_BAD_CHARS = ["/", '\\', "?", "%", "*", ":", "|", '"', "<", ">",
|
35
|
+
".", " "].freeze
|
35
36
|
|
36
37
|
def docidentifier_code
|
37
38
|
return "" if docidentifier.nil?
|
38
|
-
|
39
|
-
|
39
|
+
|
40
|
+
FILENAME_BAD_CHARS.reduce(docidentifier.downcase) do |result, bad_char|
|
41
|
+
result.gsub(bad_char, "-")
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
DOC_NUMBER_REGEX = /([\w\/]+)\s+(\d+):?(\d*)
|
45
|
+
DOC_NUMBER_REGEX = /([\w\/]+)\s+(\d+):?(\d*)/.freeze
|
44
46
|
def doc_number
|
45
47
|
docidentifier&.match(DOC_NUMBER_REGEX) ? $2.to_i : 999999
|
46
48
|
end
|
@@ -51,7 +53,9 @@ module Relaton
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def to_xml(opts = {})
|
54
|
-
options = { bibdata: true, date_format: :full }.merge
|
56
|
+
options = { bibdata: true, date_format: :full }.merge(
|
57
|
+
opts.select { |k, _v| k.is_a? Symbol },
|
58
|
+
)
|
55
59
|
@bibitem.to_xml nil, **options
|
56
60
|
|
57
61
|
# #datetype = stage&.casecmp("published") == 0 ? "published" : "circulated"
|
@@ -62,7 +66,7 @@ module Relaton
|
|
62
66
|
|
63
67
|
def to_h
|
64
68
|
URL_TYPES.reduce({ items: [] }.merge(@bibitem.to_hash)) do |h, t|
|
65
|
-
value =
|
69
|
+
value = send t
|
66
70
|
h[t.to_s] = value
|
67
71
|
h
|
68
72
|
end
|
@@ -76,11 +80,15 @@ module Relaton
|
|
76
80
|
if @bibitem.respond_to?(meth)
|
77
81
|
@bibitem.send meth, *args
|
78
82
|
elsif URL_TYPES.include? meth
|
79
|
-
link = @bibitem.link.detect
|
83
|
+
link = @bibitem.link.detect do |l|
|
84
|
+
l.type == meth.to_s || meth == :uri && l.type.nil?
|
85
|
+
end
|
80
86
|
link&.content&.to_s
|
81
87
|
elsif URL_TYPES.include? meth.match(/^\w+(?==)/).to_s.to_sym
|
82
88
|
/^(?<type>\w+)/ =~ meth
|
83
|
-
link = @bibitem.link.detect
|
89
|
+
link = @bibitem.link.detect do |l|
|
90
|
+
l.type == type || type == "uri" && l.type.nil?
|
91
|
+
end
|
84
92
|
if link
|
85
93
|
link.content = args[0]
|
86
94
|
else
|
@@ -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
@@ -8,6 +8,7 @@ module Relaton
|
|
8
8
|
class Command < Thor
|
9
9
|
desc "fetch CODE", "Fetch Relaton XML for Standard identifier CODE"
|
10
10
|
option :type, aliases: :t, required: true, desc: "Type of standard to get bibliographic entry for"
|
11
|
+
option :format, aliases: :f, desc: "Output format (xml, bibtex). Default xml."
|
11
12
|
option :year, aliases: :y, type: :numeric, desc: "Year the standard was published"
|
12
13
|
|
13
14
|
def fetch(code)
|
@@ -72,16 +73,7 @@ module Relaton
|
|
72
73
|
Relaton::Cli::XMLConvertor.to_html(file, style, template)
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
-
# option :stylesheet, aliases: :s, desc: "Stylesheet file path for rendering HTML index"
|
77
|
-
# option :templatedir, aliases: :t, desc: "Liquid template directory for rendering Relaton items and collection"
|
78
|
-
# option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
|
79
|
-
|
80
|
-
# def yaml2html(file, style = nil, template = nil)
|
81
|
-
# Relaton::Cli::YAMLConvertor.to_html(file, style, template)
|
82
|
-
# end
|
83
|
-
|
84
|
-
desc "yaml2htmlnew RELATON-INDEX-YAML", "Concatenate Relaton Collection YAML into HTML"
|
76
|
+
desc "yaml2html RELATON-INDEX-YAML", "Concatenate Relaton Collection YAML into HTML"
|
85
77
|
option :stylesheet, aliases: :s, desc: "Stylesheet file path for rendering HTML index"
|
86
78
|
option :templatedir, aliases: :t, desc: "Liquid template directory for rendering Relaton items and collection"
|
87
79
|
option :overwrite, aliases: :f, type: :boolean, default: false, desc: "Overwrite the existing file"
|
@@ -92,10 +84,19 @@ module Relaton
|
|
92
84
|
|
93
85
|
private
|
94
86
|
|
87
|
+
# @param code [String]
|
88
|
+
# @param options [Hash]
|
89
|
+
# @option options [String] :type
|
90
|
+
# @option options [String, NilClass] :format
|
91
|
+
# @option options [Integer, NilClass] :year
|
95
92
|
def fetch_document(code, options)
|
96
93
|
if registered_types.include?(options[:type])
|
97
94
|
doc = Cli.relaton.fetch(code, options[:year]&.to_s)
|
98
|
-
|
95
|
+
if doc
|
96
|
+
options[:format] == "bibtex" ? doc.to_bibtex : doc.to_xml
|
97
|
+
else
|
98
|
+
"No matching bibliographic entry found"
|
99
|
+
end
|
99
100
|
end
|
100
101
|
rescue RelatonBib::RequestError => e
|
101
102
|
e.message
|
@@ -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)
|
@@ -137,15 +140,19 @@ module Relaton
|
|
137
140
|
def concatenate_files
|
138
141
|
xml_files = [convert_rxl_to_xml, convert_yamls_to_xml, convert_xml_to_xml]
|
139
142
|
|
140
|
-
xml_files.flatten.
|
143
|
+
xml_files.flatten.reduce([]) do |mem, xml|
|
141
144
|
doc = nokogiri_document(xml[:content])
|
142
|
-
if (
|
145
|
+
if (refs = doc.xpath("//rfc//reference")).any?
|
143
146
|
require "relaton_ietf/scrapper"
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
+
mem + refs.map do |rfc|
|
148
|
+
ietf = RelatonIetf::Scrapper.fetch_rfc rfc
|
149
|
+
d = nokogiri_document ietf.to_xml(bibdata: true)
|
150
|
+
bibdata_instance(d, xml[:file])
|
151
|
+
end
|
152
|
+
elsif doc&.root&.name == "bibdata"
|
153
|
+
mem << bibdata_instance(doc, xml[:file])
|
154
|
+
else mem
|
147
155
|
end
|
148
|
-
bibdata_instance(doc, xml[:file]) if doc&.root&.name == "bibdata"
|
149
156
|
end.compact
|
150
157
|
end
|
151
158
|
|
@@ -182,6 +189,9 @@ module Relaton
|
|
182
189
|
end
|
183
190
|
end
|
184
191
|
|
192
|
+
# @param document [Nokogiri::XML::Document]
|
193
|
+
# @param file [String] path to file
|
194
|
+
# @return [Relaton::Bibdata]
|
185
195
|
def bibdata_instance(document, file)
|
186
196
|
document = clean_nokogiri_document(document)
|
187
197
|
bibdata = Relaton::Bibdata.from_xml document.root
|
@@ -190,6 +200,8 @@ module Relaton
|
|
190
200
|
bibdata
|
191
201
|
end
|
192
202
|
|
203
|
+
# @param bibdata [Relaton::Bibdata]
|
204
|
+
# @param file [String] path to file
|
193
205
|
def build_bibdata_relaton(bibdata, file)
|
194
206
|
["xml", "pdf", "doc", "html", "rxl", "txt"].each do |type|
|
195
207
|
file = Pathname.new(file).sub_ext(".#{type}")
|
@@ -202,6 +214,8 @@ module Relaton
|
|
202
214
|
# has an xmlns. We don't want to change the code for bibdata
|
203
215
|
# hence this hack #bibdata_doc.root['xmlns'] = "xmlns"
|
204
216
|
#
|
217
|
+
# @param document [Nokogiri::XML::Document]
|
218
|
+
# @return [Nokogiri::XML::Document]
|
205
219
|
def clean_nokogiri_document(document)
|
206
220
|
document.remove_namespaces!
|
207
221
|
document.root.add_namespace(nil, "xmlns")
|
data/lib/relaton/cli/version.rb
CHANGED
@@ -32,7 +32,7 @@ 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
37
|
# Relaton::Cli.parse_xml(content).to_hash
|
38
38
|
else
|
@@ -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">
|
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.1
|
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-10 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>
|