ttl2html 3.0.0 → 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/version.rb +1 -1
- data/lib/ttl2html.rb +111 -12
- 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/version.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
TTL2HTML::VERSION = "3.
|
|
1
|
+
TTL2HTML::VERSION = "3.1.0"
|
data/lib/ttl2html.rb
CHANGED
|
@@ -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)
|
|
@@ -521,6 +618,8 @@ module TTL2HTML
|
|
|
521
618
|
end
|
|
522
619
|
dir = File.dirname(file)
|
|
523
620
|
FileUtils.mkdir_p(dir) if not File.exist?(dir)
|
|
621
|
+
@cache ||= {}
|
|
622
|
+
@cache[:output_turtle_files] = Set.new
|
|
524
623
|
str = format_turtle(uri)
|
|
525
624
|
str << format_turtle_inverse(uri)
|
|
526
625
|
open(file, "w") do |io|
|
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: 3.
|
|
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-04-
|
|
10
|
+
date: 2026-04-12 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: nokogiri
|