ttl2html 2.3.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ttl2html/template.rb +29 -26
- data/lib/ttl2html/util.rb +32 -17
- data/lib/ttl2html/version.rb +1 -1
- data/lib/ttl2html.rb +132 -17
- data/locales/en.yml +1 -0
- data/locales/ja.yml +1 -0
- data/templates/about.html.erb +1 -1
- data/templates/default.html.erb +67 -5
- data/templates/index-list.html.erb +2 -2
- data/templates/index.html.erb +2 -2
- data/templates/layout.html.erb +7 -7
- data/templates/triples-blank.html.erb +2 -2
- data/templates/triples-inverse.html.erb +4 -4
- data/templates/triples.html.erb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d7254a4cc200e719bbb09c33d88dea4a22a8360e1c6453085f5331d541320b82
|
|
4
|
+
data.tar.gz: 43385ec41709d6b8a552dfe7bb2c2d7186b1142b0655bd8480b2fc0b91b336d8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0be4d1d1550a1eb410ffb8747eeffbd8b3154a297966cb99cde5ecb6c249973a8c345e88b01ab8cd7c1c791064ea78b6708ad7bc1579231b2f5424b8643af709
|
|
7
|
+
data.tar.gz: a5ec01247b296e2be84d110e4742412152465f9925223950211ca99a5c9f6112ebe81820fa6a422589f8cf45f5d41ecfb3b619c33e833694b9811cb80fb86541
|
data/lib/ttl2html/template.rb
CHANGED
|
@@ -9,7 +9,6 @@ require "nokogiri"
|
|
|
9
9
|
|
|
10
10
|
module TTL2HTML
|
|
11
11
|
class Template
|
|
12
|
-
attr_reader :param
|
|
13
12
|
include ERB::Util
|
|
14
13
|
include I18n::Base
|
|
15
14
|
include ActionView::Helpers::NumberHelper
|
|
@@ -20,15 +19,15 @@ module TTL2HTML
|
|
|
20
19
|
@template_path << File.join(File.dirname(__FILE__), "..", "..", "templates")
|
|
21
20
|
I18n.load_path << Dir[File.join(File.dirname(__FILE__), "..", "..", "locales") + "/*.yml"]
|
|
22
21
|
I18n.load_path << Dir[File.expand_path("locales") + "/*.yml"]
|
|
23
|
-
I18n.locale = @param[:locale] if @param[:locale]
|
|
22
|
+
I18n.locale = @param[:locale].to_sym if @param[:locale]
|
|
24
23
|
end
|
|
25
24
|
def output_to(file, param = {})
|
|
26
|
-
@param.
|
|
27
|
-
|
|
25
|
+
param = @param.merge(param)
|
|
26
|
+
param[:output_file] = file
|
|
28
27
|
dir = File.dirname(file)
|
|
29
28
|
FileUtils.mkdir_p(dir) if not File.exist?(dir)
|
|
30
|
-
open(file, "w") do |io|
|
|
31
|
-
io.print to_html(
|
|
29
|
+
File.open(file, "w") do |io|
|
|
30
|
+
io.print to_html(param)
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
def to_html(param)
|
|
@@ -37,9 +36,9 @@ module TTL2HTML
|
|
|
37
36
|
to_html_raw(layout_fname, param)
|
|
38
37
|
end
|
|
39
38
|
def to_html_raw(template, param)
|
|
40
|
-
@param.
|
|
39
|
+
param = @param.merge(param)
|
|
41
40
|
template = find_template_path(template)
|
|
42
|
-
tmpl = open(template){|io| io.read }
|
|
41
|
+
tmpl = File.open(template) { |io| io.read }
|
|
43
42
|
erb = ERB.new(tmpl, trim_mode: "-")
|
|
44
43
|
erb.filename = template
|
|
45
44
|
erb.result(binding)
|
|
@@ -121,13 +120,12 @@ module TTL2HTML
|
|
|
121
120
|
|
|
122
121
|
# helper method:
|
|
123
122
|
include TTL2HTML::Util
|
|
124
|
-
def relative_path(dest)
|
|
123
|
+
def relative_path(src, dest)
|
|
125
124
|
path = nil
|
|
126
125
|
dest_uri = RDF::IRI.parse(dest)
|
|
127
126
|
if dest_uri.absolute?
|
|
128
127
|
path = dest
|
|
129
128
|
else
|
|
130
|
-
src = @param[:output_file]
|
|
131
129
|
src = Pathname.new(src).relative_path_from(Pathname.new(@param[:output_dir])) if @param[:output_dir]
|
|
132
130
|
path = Pathname(dest).relative_path_from(Pathname(File.dirname src))
|
|
133
131
|
if @param[:output_dir] and File.directory?(Pathname.new(@param[:output_dir]) + path)
|
|
@@ -139,11 +137,11 @@ module TTL2HTML
|
|
|
139
137
|
#p [ :relative_path, path, dest, src ]
|
|
140
138
|
path
|
|
141
139
|
end
|
|
142
|
-
def relative_path_uri(dest_uri, base_uri = @param[:base_uri])
|
|
140
|
+
def relative_path_uri(src, dest_uri, base_uri = @param[:base_uri])
|
|
143
141
|
if dest_uri.start_with? base_uri
|
|
144
142
|
dest = dest_uri.sub(base_uri, "")
|
|
145
143
|
dest = uri_mapping_to_path(dest, @param, "")
|
|
146
|
-
relative_path(dest)
|
|
144
|
+
relative_path(src, dest)
|
|
147
145
|
else
|
|
148
146
|
dest_uri
|
|
149
147
|
end
|
|
@@ -196,20 +194,23 @@ module TTL2HTML
|
|
|
196
194
|
object
|
|
197
195
|
end
|
|
198
196
|
end
|
|
199
|
-
def format_property(property,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
197
|
+
def format_property(property, param, subject = nil)
|
|
198
|
+
param = @param.merge(param)
|
|
199
|
+
subject = param[:blank_subject] if not subject and param[:blank_subject]
|
|
200
|
+
subject_class = param[:data_global][subject][RDF.type.to_s]&.first if subject
|
|
201
|
+
if subject_class and param[:labels_with_class][subject_class] and param[:labels_with_class][subject_class][property]
|
|
202
|
+
param[:labels_with_class][subject_class][property]
|
|
203
|
+
elsif param[:labels] and param[:labels][property]
|
|
204
|
+
param[:labels][property]
|
|
206
205
|
else
|
|
207
206
|
property.split(/[\/\#]/).last.capitalize
|
|
208
207
|
end
|
|
209
208
|
end
|
|
210
|
-
def format_object(object,
|
|
209
|
+
def format_object(object, param)
|
|
210
|
+
type = param[:type] || {}
|
|
211
|
+
data = param[:data] || {}
|
|
211
212
|
if /\Ahttps?:\/\// =~ object.to_s
|
|
212
|
-
rel_path = relative_path_uri(
|
|
213
|
+
rel_path = relative_path_uri(param[:output_file], object)
|
|
213
214
|
if param[:data_global][object]
|
|
214
215
|
result = "<a href=\"#{rel_path}\">#{get_title(param[:data_global][object]) or ERB::Util.html_escape(object)}</a>"
|
|
215
216
|
subtitle = get_subtitle(param[:data_global][object])
|
|
@@ -223,16 +224,17 @@ module TTL2HTML
|
|
|
223
224
|
end
|
|
224
225
|
elsif /\A_:/ =~ object.to_s and param[:data_global][object]
|
|
225
226
|
if type[:inverse] and param[:data_inverse_global][object]
|
|
226
|
-
format_triples(param[:data_inverse_global][object], inverse: true, blank: true)
|
|
227
|
+
format_triples(param[:data_inverse_global][object], param, inverse: true, blank: true)
|
|
227
228
|
else
|
|
228
|
-
format_triples(param[:data_global][object], blank: true)
|
|
229
|
+
format_triples(param[:data_global][object], param, blank: true)
|
|
229
230
|
end
|
|
230
231
|
else
|
|
231
232
|
ERB::Util.html_escape object
|
|
232
233
|
end
|
|
233
234
|
end
|
|
234
|
-
def format_triples(triples, type = {})
|
|
235
|
-
param_local = @param.dup.merge(
|
|
235
|
+
def format_triples(triples, param, type = {})
|
|
236
|
+
param_local = @param.dup.merge(param)
|
|
237
|
+
param_local = param_local.merge(data: triples)
|
|
236
238
|
param_local[:type] = type
|
|
237
239
|
if @param[:labels_with_class] and triples["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]
|
|
238
240
|
@param[:labels_with_class].reverse_each do |k, v|
|
|
@@ -324,6 +326,7 @@ module TTL2HTML
|
|
|
324
326
|
value && !(value.respond_to?(:empty?) && value.empty?)
|
|
325
327
|
end
|
|
326
328
|
def sort_criteria(val, data_global)
|
|
329
|
+
raise "sort_criteria got nil." if data_global.nil?
|
|
327
330
|
resource = data_global[val]
|
|
328
331
|
results = []
|
|
329
332
|
[
|
|
@@ -350,4 +353,4 @@ module TTL2HTML
|
|
|
350
353
|
results
|
|
351
354
|
end
|
|
352
355
|
end
|
|
353
|
-
end
|
|
356
|
+
end
|
data/lib/ttl2html/util.rb
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
1
|
module TTL2HTML
|
|
2
2
|
module Util
|
|
3
|
-
def
|
|
4
|
-
|
|
3
|
+
def make_mapping_uris_cache(param)
|
|
4
|
+
@path_cache = Set.new
|
|
5
|
+
data = @data || @param[:data_global] || @param[:data] || {}
|
|
6
|
+
data.keys.each do |uri|
|
|
7
|
+
local_path = _uri_mapping_to_path(uri, param)
|
|
8
|
+
# 親パスをすべて抽出してSetに追加
|
|
9
|
+
idx = 0
|
|
10
|
+
while (idx = local_path.index("/", idx))
|
|
11
|
+
parent = local_path[0...idx]
|
|
12
|
+
@path_cache << parent unless parent.empty?
|
|
13
|
+
idx += 1
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
@path_cache
|
|
17
|
+
end
|
|
18
|
+
def _uri_mapping_to_path(uri, param, suffix = ".html")
|
|
19
|
+
local_path = uri.sub(param[:base_uri], "")
|
|
5
20
|
if param[:uri_mappings]
|
|
6
21
|
param[:uri_mappings].each do |mapping|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
22
|
+
if mapping["regexp"] =~ local_path
|
|
23
|
+
#p [mapping["regexp"], local_path]
|
|
24
|
+
local_path = local_path.sub(mapping["regexp"], mapping["path"])
|
|
25
|
+
#p [mapping["regexp"], local_path]
|
|
10
26
|
end
|
|
11
27
|
end
|
|
12
28
|
end
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
path
|
|
29
|
+
local_path
|
|
30
|
+
end
|
|
31
|
+
def uri_mapping_to_path(uri, param, suffix = ".html")
|
|
32
|
+
path = nil
|
|
33
|
+
@path_cache ||= make_mapping_uris_cache(param)
|
|
34
|
+
path = _uri_mapping_to_path(uri, param, suffix)
|
|
35
|
+
if suffix == ".html"
|
|
36
|
+
if @path_cache.include? path
|
|
37
|
+
path += "/index"
|
|
38
|
+
elsif path.end_with?("/")
|
|
39
|
+
path += "index"
|
|
24
40
|
end
|
|
25
41
|
end
|
|
26
|
-
path = path.sub(param[:base_uri], "")
|
|
27
42
|
path << suffix
|
|
28
43
|
#p [uri, path]
|
|
29
44
|
path
|
data/lib/ttl2html/version.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
TTL2HTML::VERSION = "
|
|
1
|
+
TTL2HTML::VERSION = "3.1.0"
|
data/lib/ttl2html.rb
CHANGED
|
@@ -27,7 +27,7 @@ module TTL2HTML
|
|
|
27
27
|
|
|
28
28
|
def load_config(file)
|
|
29
29
|
config = { output_turtle: true }
|
|
30
|
-
open(file) do |io|
|
|
30
|
+
File.open(file) do |io|
|
|
31
31
|
YAML.safe_load(io, permitted_classes: [Regexp]).each do |k, v|
|
|
32
32
|
config[k.intern] = v
|
|
33
33
|
end
|
|
@@ -72,9 +72,11 @@ module TTL2HTML
|
|
|
72
72
|
$stderr.puts "#{count} triples. #{subjects.size} subjects."
|
|
73
73
|
@data
|
|
74
74
|
end
|
|
75
|
-
def format_turtle(subject, depth = 1)
|
|
75
|
+
def format_turtle(subject, depth = 1, force = false)
|
|
76
76
|
turtle = RDF::Turtle::Writer.new
|
|
77
77
|
result = ""
|
|
78
|
+
#p [:format_turtle, subject, depth, force]
|
|
79
|
+
return result if !force && @cache[:output_turtle_files].include?(subject)
|
|
78
80
|
if subject =~ /^_:/
|
|
79
81
|
result << "[\n#{" "*depth}"
|
|
80
82
|
else
|
|
@@ -92,14 +94,14 @@ module TTL2HTML
|
|
|
92
94
|
[ @data[object.to_s][schema_position] ? @data[object.to_s][schema_position].first.to_i : Float::INFINITY,
|
|
93
95
|
@data[object.to_s][qb_order] ? @data[object.to_s][qb_order].first.to_i : Float::INFINITY,
|
|
94
96
|
@data[object.to_s][shacl_order] ? @data[object.to_s][shacl_order].first.to_i : Float::INFINITY,
|
|
95
|
-
format_turtle(object, depth + 1)
|
|
97
|
+
format_turtle(object, depth + 1, true)
|
|
96
98
|
]
|
|
97
99
|
else
|
|
98
100
|
[Float::INFINITY, Float::INFINITY, Float::INFINITY, object.to_s]
|
|
99
101
|
end
|
|
100
102
|
end.map do |object|
|
|
101
103
|
if /^_:/ =~ object.to_s # blank node:
|
|
102
|
-
format_turtle(object, depth + 1)
|
|
104
|
+
format_turtle(object, depth + 1, force)
|
|
103
105
|
elsif RDF::URI::IRI =~ object.to_s
|
|
104
106
|
turtle.format_uri(RDF::URI.new object)
|
|
105
107
|
elsif object.respond_to?(:first) and object.first.kind_of?(Symbol)
|
|
@@ -110,22 +112,117 @@ module TTL2HTML
|
|
|
110
112
|
end.join(", ")
|
|
111
113
|
str
|
|
112
114
|
end.join(";\n#{" "*depth}")
|
|
113
|
-
result << "
|
|
115
|
+
result << "." if not subject =~ /^_:/
|
|
114
116
|
result << "\n"
|
|
115
117
|
result << "#{" "*(depth-1)}]" if subject =~ /^_:/
|
|
118
|
+
@cache[:output_turtle_files] << subject unless force
|
|
116
119
|
result
|
|
117
120
|
end
|
|
118
121
|
def format_turtle_inverse(object)
|
|
119
|
-
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
triples = collect_inverse_triples(object)
|
|
123
|
+
return "" if triples.empty?
|
|
124
|
+
by_subject = build_subject_index(triples)
|
|
125
|
+
ref_count = build_object_ref_count(triples)
|
|
126
|
+
roots = find_inverse_roots(by_subject)
|
|
127
|
+
roots.map do |root|
|
|
128
|
+
"#{format_inverse_subject(root, by_subject, ref_count, Set.new, 1)}.\n"
|
|
129
|
+
end.join
|
|
130
|
+
end
|
|
131
|
+
def collect_inverse_triples(object, triples = Set.new, visited = Set.new)
|
|
132
|
+
return triples if object.to_s.start_with?("_:")
|
|
133
|
+
return triples unless object.to_s.start_with?(@config[:base_uri].to_s)
|
|
134
|
+
return triples unless @data_inverse.key?(object.to_s)
|
|
135
|
+
return triples if visited.include?(object.to_s)
|
|
136
|
+
visited << object.to_s
|
|
137
|
+
@data_inverse[object.to_s].each do |predicate, subjects|
|
|
138
|
+
subjects.each do |subject|
|
|
139
|
+
triples << [subject.to_s, predicate.to_s, object.to_s]
|
|
140
|
+
collect_inverse_triples_for_bnode(subject.to_s, triples, visited) if subject.to_s.start_with?("_:")
|
|
126
141
|
end
|
|
127
142
|
end
|
|
128
|
-
|
|
143
|
+
triples
|
|
144
|
+
end
|
|
145
|
+
def collect_inverse_triples_for_bnode(node, triples, visited)
|
|
146
|
+
return triples unless @data_inverse.key?(node)
|
|
147
|
+
return triples if visited.include?(node)
|
|
148
|
+
visited << node
|
|
149
|
+
@data_inverse[node].each do |predicate, subjects|
|
|
150
|
+
subjects.each do |subject|
|
|
151
|
+
triples << [subject.to_s, predicate.to_s, node]
|
|
152
|
+
collect_inverse_triples_for_bnode(subject.to_s, triples, visited) if subject.to_s.start_with?("_:")
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
triples
|
|
156
|
+
end
|
|
157
|
+
def build_subject_index(triples)
|
|
158
|
+
by_subject = Hash.new { |h, k| h[k] = Hash.new { |hh, kk| hh[kk] = [] } }
|
|
159
|
+
triples.each do |subject, predicate, object|
|
|
160
|
+
by_subject[subject][predicate] << object
|
|
161
|
+
end
|
|
162
|
+
by_subject.each_value do |predicates|
|
|
163
|
+
predicates.each_value(&:uniq!)
|
|
164
|
+
end
|
|
165
|
+
by_subject
|
|
166
|
+
end
|
|
167
|
+
def build_object_ref_count(triples)
|
|
168
|
+
count = Hash.new(0)
|
|
169
|
+
triples.each do |_subject, _predicate, object|
|
|
170
|
+
count[object] += 1 if object.to_s.start_with?("_:")
|
|
171
|
+
end
|
|
172
|
+
count
|
|
173
|
+
end
|
|
174
|
+
def find_inverse_roots(by_subject)
|
|
175
|
+
all_subjects = by_subject.keys
|
|
176
|
+
all_objects = by_subject.values.flat_map { |preds| preds.values.flatten }.uniq
|
|
177
|
+
all_subjects.reject do |subject|
|
|
178
|
+
subject.start_with?("_:") || all_objects.include?(subject)
|
|
179
|
+
end.sort
|
|
180
|
+
end
|
|
181
|
+
def format_inverse_subject(subject, by_subject, ref_count, visited, depth = 1)
|
|
182
|
+
props = by_subject[subject]
|
|
183
|
+
return format_node(subject) if props.nil? || props.empty?
|
|
184
|
+
indent = " " * (depth - 1)
|
|
185
|
+
inner = " " * depth
|
|
186
|
+
if subject.start_with?("_:")
|
|
187
|
+
return "[]" if visited.include?(subject)
|
|
188
|
+
visited = visited.dup
|
|
189
|
+
visited << subject
|
|
190
|
+
head = "[\n#{inner}"
|
|
191
|
+
tail = "\n#{indent}]"
|
|
192
|
+
else
|
|
193
|
+
head = "<#{subject}> "
|
|
194
|
+
tail = ""
|
|
195
|
+
end
|
|
196
|
+
body = props.keys.sort.map do |predicate|
|
|
197
|
+
objects = props[predicate].sort.map do |object|
|
|
198
|
+
format_inverse_object(object, by_subject, ref_count, visited, depth + 1)
|
|
199
|
+
end.join(", ")
|
|
200
|
+
"<#{predicate}> #{objects}"
|
|
201
|
+
end.join(";\n#{inner}")
|
|
202
|
+
head + body + tail
|
|
203
|
+
end
|
|
204
|
+
def format_inverse_object(object, by_subject, ref_count, visited, depth = 1)
|
|
205
|
+
if object.to_s.start_with?("_:") && by_subject.key?(object.to_s)
|
|
206
|
+
if ref_count[object.to_s] <= 1
|
|
207
|
+
format_inverse_subject(object.to_s, by_subject, ref_count, visited, depth)
|
|
208
|
+
else
|
|
209
|
+
object.to_s
|
|
210
|
+
end
|
|
211
|
+
else
|
|
212
|
+
format_node(object)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
def format_node(value)
|
|
216
|
+
turtle = RDF::Turtle::Writer.new
|
|
217
|
+
if value.to_s.start_with?("_:")
|
|
218
|
+
value.to_s
|
|
219
|
+
elsif RDF::URI::IRI =~ value.to_s
|
|
220
|
+
"<#{value}>"
|
|
221
|
+
elsif value.respond_to?(:first) && value.first.kind_of?(Symbol)
|
|
222
|
+
turtle.format_literal(RDF::Literal.new(value[1], language: value[0]))
|
|
223
|
+
else
|
|
224
|
+
turtle.format_literal(value)
|
|
225
|
+
end
|
|
129
226
|
end
|
|
130
227
|
|
|
131
228
|
def each_data(label = :each_data)
|
|
@@ -135,7 +232,9 @@ module TTL2HTML
|
|
|
135
232
|
format: "(%t) %a %e %P% Processed: %c from %C"
|
|
136
233
|
}
|
|
137
234
|
data = @data.keys.sort_by do|uri|
|
|
138
|
-
|
|
235
|
+
local_path = uri_mapping_to_path(uri, @config, ".html")
|
|
236
|
+
#p [ local_path.size, local_path.count("/"), local_path ]
|
|
237
|
+
[ local_path.size, local_path.count("/"), local_path ]
|
|
139
238
|
end.reverse
|
|
140
239
|
Parallel.each(data, progress: progressbar_options) do |uri|
|
|
141
240
|
next if not uri.start_with? @config[:base_uri]
|
|
@@ -168,8 +267,8 @@ module TTL2HTML
|
|
|
168
267
|
end
|
|
169
268
|
@config[:orders_with_class] = shapes2orders(shapes)
|
|
170
269
|
Dir.mkdir @config[:output_dir] if @config[:output_dir] and not File.exist? @config[:output_dir]
|
|
270
|
+
template = Template.new("default.html.erb", @config)
|
|
171
271
|
each_data(:output_html_files) do |uri, v|
|
|
172
|
-
template = Template.new("default.html.erb", @config)
|
|
173
272
|
param = @config.dup
|
|
174
273
|
param[:uri] = uri
|
|
175
274
|
param[:turtle_uri] = uri + ".ttl"
|
|
@@ -185,6 +284,7 @@ module TTL2HTML
|
|
|
185
284
|
param[:breadcrumbs_items] = build_breadcrumbs(uri, template)
|
|
186
285
|
end
|
|
187
286
|
file = uri_mapping_to_path(uri, @config, ".html")
|
|
287
|
+
#p [:each_data, uri, file]
|
|
188
288
|
if @config[:output_dir]
|
|
189
289
|
file = File.join(@config[:output_dir], file)
|
|
190
290
|
end
|
|
@@ -262,7 +362,7 @@ module TTL2HTML
|
|
|
262
362
|
label = template.get_title(@data[target_class], nil)
|
|
263
363
|
comment = template.get_language_literal(@data[target_class]["http://www.w3.org/2000/01/rdf-schema#comment"]) if @data[target_class]["http://www.w3.org/2000/01/rdf-schema#comment"]
|
|
264
364
|
else
|
|
265
|
-
label = template.format_property(target_class)
|
|
365
|
+
label = template.format_property(target_class, param)
|
|
266
366
|
end
|
|
267
367
|
else
|
|
268
368
|
label = template.get_title(@data[subject.to_s])
|
|
@@ -518,6 +618,8 @@ module TTL2HTML
|
|
|
518
618
|
end
|
|
519
619
|
dir = File.dirname(file)
|
|
520
620
|
FileUtils.mkdir_p(dir) if not File.exist?(dir)
|
|
621
|
+
@cache ||= {}
|
|
622
|
+
@cache[:output_turtle_files] = Set.new
|
|
521
623
|
str = format_turtle(uri)
|
|
522
624
|
str << format_turtle_inverse(uri)
|
|
523
625
|
open(file, "w") do |io|
|
|
@@ -532,6 +634,7 @@ module TTL2HTML
|
|
|
532
634
|
end
|
|
533
635
|
|
|
534
636
|
def cleanup
|
|
637
|
+
dirs = []
|
|
535
638
|
@data.select do |uri, v|
|
|
536
639
|
uri.start_with? @config[:base_uri]
|
|
537
640
|
end.sort_by do |uri, v|
|
|
@@ -539,19 +642,31 @@ module TTL2HTML
|
|
|
539
642
|
end.each do |uri, v|
|
|
540
643
|
html_file = uri_mapping_to_path(uri, @config, ".html")
|
|
541
644
|
html_file = File.join(@config[:output_dir], html_file) if @config[:output_dir]
|
|
645
|
+
dirs << File.dirname(html_file)
|
|
542
646
|
File.unlink html_file if File.exist? html_file
|
|
543
647
|
ttl_file = uri_mapping_to_path(uri, @config, ".ttl")
|
|
544
648
|
ttl_file = File.join(@config[:output_dir], ttl_file) if @config[:output_dir]
|
|
545
649
|
File.unlink ttl_file if File.exist? ttl_file
|
|
546
650
|
dir = uri.sub(@config[:base_uri], "")
|
|
547
651
|
dir = File.join(@config[:output_dir], dir) if @config[:output_dir]
|
|
548
|
-
|
|
652
|
+
dirs << dir
|
|
549
653
|
end
|
|
550
654
|
index_html = "index.html"
|
|
551
655
|
index_html = File.join(@config[:output_dir], "index.html") if @config[:output_dir]
|
|
552
656
|
if @config[:top_class] and File.exist? index_html
|
|
553
657
|
File.unlink index_html
|
|
554
658
|
end
|
|
659
|
+
about_html = (@config[:about_file] || "about.html")
|
|
660
|
+
about_html = File.join(@config[:output_dir], about_html) if @config[:output_dir]
|
|
661
|
+
File.unlink about_html if File.exist? about_html
|
|
662
|
+
|
|
663
|
+
dirs = dirs.uniq.sort_by{|e| -(e.size) }
|
|
664
|
+
#p dirs
|
|
665
|
+
dirs.each do |dir|
|
|
666
|
+
next if dir == "." # failsafe...
|
|
667
|
+
next if dir == @config[:output_dir] # failsafe...
|
|
668
|
+
FileUtils.remove_entry_secure(dir) if File.exist? dir
|
|
669
|
+
end
|
|
555
670
|
end
|
|
556
671
|
end
|
|
557
672
|
|
data/locales/en.yml
CHANGED
data/locales/ja.yml
CHANGED
data/templates/about.html.erb
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
<%- if param[:shapes].size > 0 -%>
|
|
37
37
|
<h2 id="shapes"><%=h t("about.shape-heading") %></h2>
|
|
38
38
|
<%- param[:shapes].keys.sort_by{|k| param[:shapes][k][:order] }.each do |shape| -%>
|
|
39
|
-
<h3 id="<%=h relative_path_uri(shape) %>"><%=h param[:shapes][shape][:label] %></h3>
|
|
39
|
+
<h3 id="<%=h relative_path_uri(param[:output_file], shape) %>"><%=h param[:shapes][shape][:label] %></h3>
|
|
40
40
|
<%- if param[:shapes][shape][:target_class] -%>
|
|
41
41
|
<ul><li><%= t("about.shape-target") %>: <a href="<%=h param[:shapes][shape][:target_class] %>"><%=h param[:shapes][shape][:target_class] %></a></li></ul>
|
|
42
42
|
<%- end -%>
|
data/templates/default.html.erb
CHANGED
|
@@ -4,7 +4,69 @@
|
|
|
4
4
|
<%- if param[:subtitle] -%>
|
|
5
5
|
<p class="lead"><%= param[:subtitle] %></p>
|
|
6
6
|
<%- end -%>
|
|
7
|
-
<p
|
|
7
|
+
<p>
|
|
8
|
+
<i class="bi bi-link-45deg"></i> <a href="<%=h param[:uri] %>"><%=h param[:uri] %></a>
|
|
9
|
+
<%- if param[:enable_copy_link_button] -%>
|
|
10
|
+
<button id="copy-link" class="btn btn-sm btn-outline-secondary" aria-live="polite">
|
|
11
|
+
<i class="bi bi-copy"></i> <span class="copy-link-text"><%=h t("default.copy-link") %></span>
|
|
12
|
+
</button>
|
|
13
|
+
<%- end -%>
|
|
14
|
+
</p>
|
|
15
|
+
<%- if param[:enable_copy_link_button] -%>
|
|
16
|
+
<script>
|
|
17
|
+
(() => {
|
|
18
|
+
const btn = document.getElementById("copy-link");
|
|
19
|
+
const url = '<%=h param[:uri] %>';
|
|
20
|
+
const originalHTML = btn.innerHTML;
|
|
21
|
+
let timerId = null;
|
|
22
|
+
async function copyText(text) {
|
|
23
|
+
// Clipboard API, or fallback
|
|
24
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
25
|
+
await navigator.clipboard.writeText(text);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const ta = document.createElement("textarea");
|
|
29
|
+
ta.value = text;
|
|
30
|
+
ta.style.position = "fixed";
|
|
31
|
+
ta.style.left = "-9999px";
|
|
32
|
+
document.body.appendChild(ta);
|
|
33
|
+
ta.select();
|
|
34
|
+
document.execCommand("copy");
|
|
35
|
+
document.body.removeChild(ta);
|
|
36
|
+
}
|
|
37
|
+
function setCopiedState() {
|
|
38
|
+
btn.innerHTML = `<i class="bi bi-check2"></i> <span class="btn-label">Copied!</span>`;
|
|
39
|
+
btn.classList.remove("btn-outline-secondary");
|
|
40
|
+
btn.classList.add("btn-outline-success");
|
|
41
|
+
}
|
|
42
|
+
function resetState() {
|
|
43
|
+
btn.innerHTML = originalHTML;
|
|
44
|
+
btn.classList.remove("btn-outline-success");
|
|
45
|
+
btn.classList.add("btn-outline-secondary");
|
|
46
|
+
}
|
|
47
|
+
btn.addEventListener("click", async () => {
|
|
48
|
+
btn.disabled = true;
|
|
49
|
+
try {
|
|
50
|
+
await copyText(url);
|
|
51
|
+
setCopiedState();
|
|
52
|
+
clearTimeout(timerId);
|
|
53
|
+
timerId = setTimeout(() => {
|
|
54
|
+
resetState();
|
|
55
|
+
btn.disabled = false;
|
|
56
|
+
}, 1500);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// fail...
|
|
59
|
+
btn.innerHTML = `<span class="btn-label">Copy failed...</span>`;
|
|
60
|
+
clearTimeout(timerId);
|
|
61
|
+
timerId = setTimeout(() => {
|
|
62
|
+
resetState();
|
|
63
|
+
btn.disabled = false;
|
|
64
|
+
}, 1500);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
})();
|
|
68
|
+
</script>
|
|
69
|
+
<%- end -%>
|
|
8
70
|
</div>
|
|
9
71
|
</div>
|
|
10
72
|
<div class="container">
|
|
@@ -13,11 +75,11 @@
|
|
|
13
75
|
<div class="col-md-12">
|
|
14
76
|
<nav aria-label="breadcrumb">
|
|
15
77
|
<ol class="breadcrumb">
|
|
16
|
-
<li class="breadcrumb-item"><a href="<%=h relative_path_uri(param[:base_uri]) %>"><i class="bi bi-house-door-fill"></i> Home</a></li>
|
|
78
|
+
<li class="breadcrumb-item"><a href="<%=h relative_path_uri(param[:output_file], param[:base_uri]) %>"><i class="bi bi-house-door-fill"></i> Home</a></li>
|
|
17
79
|
<%- param[:breadcrumbs_items].reverse.each_with_index do |e, i| -%>
|
|
18
80
|
<li class="breadcrumb-item<%= ' active' if i == param[:breadcrumbs_items].size-1 %>" aria-current="page">
|
|
19
81
|
<%- if e[:uri] -%>
|
|
20
|
-
<a href="<%=h relative_path_uri(e[:uri]) %>"><%=h e[:label] %></a>
|
|
82
|
+
<a href="<%=h relative_path_uri(param[:output_file], e[:uri]) %>"><%=h e[:label] %></a>
|
|
21
83
|
<%- else -%>
|
|
22
84
|
<%=h e[:label] %>
|
|
23
85
|
<%- end -%>
|
|
@@ -31,7 +93,7 @@
|
|
|
31
93
|
<div class="row">
|
|
32
94
|
<div class="col-md-12">
|
|
33
95
|
<h2><%=h t("default.details") %></h2>
|
|
34
|
-
<%= format_triples(param[:data]) %>
|
|
96
|
+
<%= format_triples(param[:data], param) %>
|
|
35
97
|
</div>
|
|
36
98
|
</div>
|
|
37
99
|
<%- if param[:additional_content] -%>
|
|
@@ -41,7 +103,7 @@
|
|
|
41
103
|
<div class="row inverse">
|
|
42
104
|
<div class="col-md-12">
|
|
43
105
|
<h2><%=h t("default.inverse_data") %></h2>
|
|
44
|
-
<%= format_triples(param[:data_inverse], inverse: true) %>
|
|
106
|
+
<%= format_triples(param[:data_inverse], param, inverse: true) %>
|
|
45
107
|
</div>
|
|
46
108
|
</div>
|
|
47
109
|
<%- end -%>
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
<ul>
|
|
5
5
|
<%- param[:index_data].each do |e| -%>
|
|
6
6
|
<%- e.each do |s, o| -%>
|
|
7
|
-
<li><%= format_object(s, param
|
|
7
|
+
<li><%= format_object(s, param) %>
|
|
8
8
|
<%- if o and o.size > 0 -%>
|
|
9
9
|
<ul>
|
|
10
10
|
<%- o.each do |o2| -%>
|
|
11
|
-
<li><%= format_object(o2.to_s, param
|
|
11
|
+
<li><%= format_object(o2.to_s, param) %></li>
|
|
12
12
|
<%- end -%>
|
|
13
13
|
</ul>
|
|
14
14
|
<%- end -%>
|
data/templates/index.html.erb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<%- end -%>
|
|
10
10
|
<p><i class="bi bi-link-45deg"></i> <a href="<%=h param[:base_uri] %>"><%=h param[:base_uri] %></a></p>
|
|
11
11
|
<%- if param[:about_file] -%>
|
|
12
|
-
<p><a class="btn btn-info" href="<%=h relative_path(param[:about_file]) %>"><%=h t("about.title", title: param[:site_title]) %> »</a></p>
|
|
12
|
+
<p><a class="btn btn-info" href="<%=h relative_path(param[:output_file], param[:about_file]) %>"><%=h t("about.title", title: param[:site_title]) %> »</a></p>
|
|
13
13
|
<%- end -%>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<%= format_version_info(param[:versions].last) %>
|
|
24
24
|
</dl>
|
|
25
25
|
<%- if param[:about_file] and param[:versions].size > 1 -%>
|
|
26
|
-
<p><a href="<%=h relative_path(param[:about_file]) %>#versions">» <%=h t("index.past-versions") %></a></p>
|
|
26
|
+
<p><a href="<%=h relative_path(param[:output_file], param[:about_file]) %>#versions">» <%=h t("index.past-versions") %></a></p>
|
|
27
27
|
<%- end -%>
|
|
28
28
|
<%- if param[:toplevel] and not param[:toplevel][:license].empty? -%>
|
|
29
29
|
<p class="license">
|
data/templates/layout.html.erb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc/dist/bootstrap-toc.min.css">
|
|
10
10
|
<%- end -%>
|
|
11
11
|
<%- Array(param[:css_file]).each do |file| -%>
|
|
12
|
-
<link rel="stylesheet" href="<%=h relative_path(file) %>">
|
|
12
|
+
<link rel="stylesheet" href="<%=h relative_path(param[:output_file], file) %>">
|
|
13
13
|
<%- end -%>
|
|
14
14
|
<%- if param[:custom_css] -%>
|
|
15
15
|
<style type="text/css"><%=h param[:custom_css] %></style>
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
<body<%= ' data-spy="scroll" data-target="#toc"' if @template == "about.html.erb" and param[:about_toc] %>>
|
|
52
52
|
<nav class="navbar navbar-expand-lg <%=h param[:navbar_class] || "navbar-light" %>">
|
|
53
53
|
<%- if param[:logo] -%>
|
|
54
|
-
<a class="navbar-brand" href="<%=h relative_path_uri(param[:base_uri]) %>">
|
|
55
|
-
<img src="<%=h relative_path(param[:logo]) %>" style="max-height: 54px" alt="<%=h param[:site_title] %>">
|
|
54
|
+
<a class="navbar-brand" href="<%=h relative_path_uri(param[:output_file], param[:base_uri]) %>">
|
|
55
|
+
<img src="<%=h relative_path(param[:output_file], param[:logo]) %>" style="max-height: 54px" alt="<%=h param[:site_title] %>">
|
|
56
56
|
</a>
|
|
57
57
|
<%- end -%>
|
|
58
58
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
@@ -61,16 +61,16 @@
|
|
|
61
61
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
62
62
|
<ul class="navbar-nav mr-auto">
|
|
63
63
|
<li class="nav-item<%= ' active' if @template == "index.html.erb" %>">
|
|
64
|
-
<a class="nav-link" href="<%=h relative_path_uri(param[:base_uri]) %>">Home</a>
|
|
64
|
+
<a class="nav-link" href="<%=h relative_path_uri(param[:output_file], param[:base_uri]) %>">Home</a>
|
|
65
65
|
</li>
|
|
66
66
|
<%- if param[:about_file] -%>
|
|
67
67
|
<li class="nav-item<%= ' active' if @template == "about.html.erb" %>">
|
|
68
|
-
<a class="nav-link" href="<%=h relative_path(param[:about_file]) %>">About</a>
|
|
68
|
+
<a class="nav-link" href="<%=h relative_path(param[:output_file], param[:about_file]) %>">About</a>
|
|
69
69
|
</li>
|
|
70
70
|
<%- end -%>
|
|
71
71
|
<%- if param[:additional_link] -%>
|
|
72
72
|
<%- param[:additional_link].each do |link| -%>
|
|
73
|
-
<li class="nav-item"><a class="nav-link" href="<%=h link["href"] %>"><%=h link["label"] %></a></li>
|
|
73
|
+
<li class="nav-item"><a class="nav-link" href="<%=h relative_path_uri(param[:output_file], link["href"]) %>"><%=h link["label"] %></a></li>
|
|
74
74
|
<%- end -%>
|
|
75
75
|
<%- end -%>
|
|
76
76
|
</ul>
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
<script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc/dist/bootstrap-toc.min.js"></script>
|
|
104
104
|
<%- end -%>
|
|
105
105
|
<%- Array(param[:javascript_file]).each do |file| -%>
|
|
106
|
-
<script src="<%=h relative_path(file) %>"></script>
|
|
106
|
+
<script src="<%=h relative_path(param[:output_file], file) %>"></script>
|
|
107
107
|
<%- end -%>
|
|
108
108
|
</body>
|
|
109
109
|
</html>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
<dl class="row border">
|
|
2
|
-
<dt class="col-sm-3"><%= format_object(param[:blank_subject], param
|
|
3
|
-
<dd class="col-sm-9"><%= format_triples(param[:blank_triples]) %></dd>
|
|
2
|
+
<dt class="col-sm-3"><%= format_object(param[:blank_subject], param) %></dt>
|
|
3
|
+
<dd class="col-sm-9"><%= format_triples(param[:blank_triples], param) %></dd>
|
|
4
4
|
</dl>
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
order = Float::INFINITY if order.nil?
|
|
5
5
|
[ order, k ]
|
|
6
6
|
}.each do |k, v| -%>
|
|
7
|
-
<dt class="col-sm-3"><%=h t('triples.inverse_refered', property: format_property(k, param
|
|
7
|
+
<dt class="col-sm-3"><%=h t('triples.inverse_refered', property: format_property(k, param, v.first)) %></dt>
|
|
8
8
|
<%- if v.respond_to? :has_key? -%>
|
|
9
9
|
<% v.each_with_index do |v2, idx| %>
|
|
10
|
-
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" lang="<%=h v2[0] %>"><%= format_object v2[1], param
|
|
10
|
+
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" lang="<%=h v2[0] %>"><%= format_object v2[1], param %></dd>
|
|
11
11
|
<% end %>
|
|
12
12
|
<%- elsif v.size > 1 -%>
|
|
13
13
|
<%- v.each_with_index do |v2, idx| -%>
|
|
14
|
-
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>"><%= format_object v2, param
|
|
14
|
+
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>"><%= format_object v2, param %></dd>
|
|
15
15
|
<%- end -%>
|
|
16
16
|
<%- else -%>
|
|
17
|
-
<dd class="col-sm-9"><%= format_object v.first, param
|
|
17
|
+
<dd class="col-sm-9"><%= format_object v.first, param %></dd>
|
|
18
18
|
<%- end -%>
|
|
19
19
|
<%- end -%>
|
|
20
20
|
</dl>
|
data/templates/triples.html.erb
CHANGED
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
order = Float::INFINITY if order.nil?
|
|
10
10
|
[ order, k ]
|
|
11
11
|
}.each do |k, v| -%>
|
|
12
|
-
<dt class="col-sm-3"><%=h format_property(k, param
|
|
12
|
+
<dt class="col-sm-3"><%=h format_property(k, param) %></dt>
|
|
13
13
|
<%- v.sort_by{|e| sort_criteria(e, param[:data_global]) }.each_with_index do |v2, idx| -%>
|
|
14
14
|
<%- if v2.respond_to? :language and v2.language? -%>
|
|
15
|
-
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" lang="<%=h v2.language %>" itemprop="<%=h k %>"><%= format_object v2, param
|
|
15
|
+
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" lang="<%=h v2.language %>" itemprop="<%=h k %>"><%= format_object v2, param %></dd>
|
|
16
16
|
<%- elsif /\Ahttps?:\/\// =~ v2.to_s -%>
|
|
17
17
|
<%- itemtypes = param[:data_global][v2.to_s] ? param[:data_global][v2.to_s][RDF.type.to_s].to_a.join(" ") : "" -%>
|
|
18
|
-
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" itemscope itemprop="<%=h k %>" itemid="<%=h v2.to_s %>"<% unless itemtypes.empty? %> itemtype="<%=h itemtypes %>"<% end %>><%= format_object v2, param
|
|
18
|
+
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" itemscope itemprop="<%=h k %>" itemid="<%=h v2.to_s %>"<% unless itemtypes.empty? %> itemtype="<%=h itemtypes %>"<% end %>><%= format_object v2, param %></dd>
|
|
19
19
|
<%- else -%>
|
|
20
|
-
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" itemprop="<%=h k %>"><%= format_object v2, param
|
|
20
|
+
<dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>" itemprop="<%=h k %>"><%= format_object v2, param %></dd>
|
|
21
21
|
<%- end -%>
|
|
22
22
|
<%- end -%>
|
|
23
23
|
<%- end -%>
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ttl2html
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Masao Takaku
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-04-12 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: nokogiri
|