ttl2html 1.3.1 → 1.3.2
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 +13 -1
- data/lib/ttl2html/version.rb +1 -1
- data/lib/ttl2html.rb +76 -16
- data/locales/en.yml +6 -0
- data/locales/ja.yml +6 -0
- data/templates/about.html.erb +26 -9
- data/templates/index.html.erb +27 -3
- data/templates/layout.html.erb +2 -2
- data/templates/version.html.erb +28 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 536529ac6440329179bab71d30e570dc92efb464526f5a0a019c59823f67098c
|
4
|
+
data.tar.gz: 4f251ed59bc227e77f80fe3ea88ea1e14e99c10ece1bb7b156d0b19f98518663
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e760bdb6848470e2e2327803e7f527684fa8e703f053cd0fda5eadc374bcaa7aeb837064f018a353f2e7c80b4845994db26106c8b139cdde9bf4e6c501f1254
|
7
|
+
data.tar.gz: 7cb13bd5ae523ef8ac62c843f27f1ce5f65efd70e035c35f35b6062e104b5c89e87d19c8ac4e7778ca0ce6b9881e1bbca92c5c34cda37793cc96add9679d66ff
|
data/lib/ttl2html/template.rb
CHANGED
@@ -4,12 +4,14 @@ require "fileutils"
|
|
4
4
|
require "pathname"
|
5
5
|
require "erb"
|
6
6
|
require "i18n"
|
7
|
+
require "action_view"
|
7
8
|
|
8
9
|
module TTL2HTML
|
9
10
|
class Template
|
10
11
|
attr_reader :param
|
11
12
|
include ERB::Util
|
12
13
|
include I18n::Base
|
14
|
+
include ActionView::Helpers::NumberHelper
|
13
15
|
def initialize(template, param = {})
|
14
16
|
@template = template
|
15
17
|
@param = param.dup
|
@@ -156,6 +158,12 @@ module TTL2HTML
|
|
156
158
|
dest_uri
|
157
159
|
end
|
158
160
|
end
|
161
|
+
def html_title(param)
|
162
|
+
titles = []
|
163
|
+
titles << param[:title]
|
164
|
+
titles << param[:site_title]
|
165
|
+
titles.compact.join(" - ")
|
166
|
+
end
|
159
167
|
def shorten_title(title, length = 140)
|
160
168
|
if title.length > length
|
161
169
|
title[0..length] + "..."
|
@@ -248,5 +256,9 @@ module TTL2HTML
|
|
248
256
|
end
|
249
257
|
to_html_raw("triples.html.erb", param_local)
|
250
258
|
end
|
259
|
+
def format_version_info(version)
|
260
|
+
param_local = @param.dup.merge(data: version)
|
261
|
+
to_html_raw("version.html.erb", param_local)
|
262
|
+
end
|
251
263
|
end
|
252
|
-
end
|
264
|
+
end
|
data/lib/ttl2html/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
TTL2HTML::VERSION = "1.3.
|
1
|
+
TTL2HTML::VERSION = "1.3.2"
|
data/lib/ttl2html.rb
CHANGED
@@ -105,11 +105,16 @@ module TTL2HTML
|
|
105
105
|
result
|
106
106
|
end
|
107
107
|
|
108
|
-
def each_data
|
108
|
+
def each_data(label = :each_data)
|
109
|
+
progressbar = ProgressBar.create(title: label,
|
110
|
+
total: @data.size,
|
111
|
+
format: "(%t) %a %e %P% Processed: %c from %C")
|
109
112
|
@data.each do |uri, v|
|
113
|
+
progressbar.increment
|
110
114
|
next if not uri.start_with? @config[:base_uri]
|
111
115
|
yield uri, v
|
112
116
|
end
|
117
|
+
progressbar.finish
|
113
118
|
end
|
114
119
|
def output_html_files
|
115
120
|
template = Template.new("", @config)
|
@@ -117,6 +122,8 @@ module TTL2HTML
|
|
117
122
|
RDF::URI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
|
118
123
|
RDF::URI("http://www.w3.org/ns/shacl#NodeShape")])
|
119
124
|
labels = shapes2labels(shapes)
|
125
|
+
versions = extract_versions
|
126
|
+
toplevel = extract_toplevel
|
120
127
|
@config[:labels_with_class] ||= {}
|
121
128
|
labels.each do |klass, props|
|
122
129
|
props.each do |property, label|
|
@@ -129,11 +136,7 @@ module TTL2HTML
|
|
129
136
|
end
|
130
137
|
end
|
131
138
|
@config[:orders_with_class] = shapes2orders(shapes)
|
132
|
-
|
133
|
-
total: @data.size,
|
134
|
-
format: "(%t) %a %e %P% Processed: %c from %C")
|
135
|
-
each_data do |uri, v|
|
136
|
-
progressbar.increment
|
139
|
+
each_data(:output_html_files) do |uri, v|
|
137
140
|
template = Template.new("default.html.erb", @config)
|
138
141
|
param = @config.dup
|
139
142
|
param[:uri] = uri
|
@@ -152,7 +155,6 @@ module TTL2HTML
|
|
152
155
|
end
|
153
156
|
template.output_to(file, param)
|
154
157
|
end
|
155
|
-
progressbar.finish
|
156
158
|
index_html = "index.html"
|
157
159
|
index_html = File.join(@config[:output_dir], "index.html") if @config[:output_dir]
|
158
160
|
if @config.has_key? :top_class
|
@@ -166,6 +168,8 @@ module TTL2HTML
|
|
166
168
|
template = Template.new("index.html.erb", @config)
|
167
169
|
param = @config.dup
|
168
170
|
param[:data_global] = @data
|
171
|
+
param[:versions] = versions
|
172
|
+
param[:toplevel] = toplevel
|
169
173
|
subjects.sort.each do |subject|
|
170
174
|
param[:index_data] ||= []
|
171
175
|
param[:index_data] << subject.to_s
|
@@ -173,13 +177,15 @@ module TTL2HTML
|
|
173
177
|
template.output_to(index_html, param)
|
174
178
|
end
|
175
179
|
end
|
176
|
-
if shapes.size > 0
|
180
|
+
if shapes.size > 0 or versions.size > 0 or toplevel.size > 0
|
177
181
|
about_html = @config[:about_file] || "about.html"
|
178
182
|
about_html = File.join(@config[:output_dir], about_html) if @config[:output_dir]
|
179
183
|
template = Template.new("about.html.erb", @config)
|
180
184
|
param = @config.dup
|
181
185
|
param[:data_global] = @data
|
182
|
-
param[:
|
186
|
+
param[:versions] = versions
|
187
|
+
param[:toplevel] = toplevel
|
188
|
+
param[:shapes] = {}
|
183
189
|
shapes.subjects.each do |subject|
|
184
190
|
label = comment = nil
|
185
191
|
target_class = @data[subject.to_s]["http://www.w3.org/ns/shacl#targetClass"]
|
@@ -194,7 +200,7 @@ module TTL2HTML
|
|
194
200
|
else
|
195
201
|
label = template.get_title(@data[subject.to_s])
|
196
202
|
end
|
197
|
-
param[:
|
203
|
+
param[:shapes][subject] = {
|
198
204
|
label: label,
|
199
205
|
comment: comment,
|
200
206
|
html: template.expand_shape(@data, subject.to_s, @prefix),
|
@@ -265,12 +271,67 @@ module TTL2HTML
|
|
265
271
|
orders
|
266
272
|
end
|
267
273
|
|
274
|
+
def extract_versions
|
275
|
+
versions = []
|
276
|
+
["http://purl.org/pav/hasVersion", "http://purl.org/pav/hasCurrentVersion", "http://purl.org/dc/terms/hasVersion"].each do |prop|
|
277
|
+
objects = @graph.query([nil, RDF::URI(prop), nil]).objects
|
278
|
+
objects.each do |o|
|
279
|
+
uri = o.to_s
|
280
|
+
version = @data[uri]
|
281
|
+
next if not version
|
282
|
+
next if not version["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"].include? "http://rdfs.org/ns/void#Dataset"
|
283
|
+
description = version["http://purl.org/dc/terms/description"]
|
284
|
+
if not description
|
285
|
+
qrev = version["http://www.w3.org/ns/prov#qualifiedRevision"]&.first
|
286
|
+
if description = @data[qrev]
|
287
|
+
description = @data[qrev]["http://www.w3.org/2000/01/rdf-schema#comment"]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
subset = []
|
291
|
+
if version["http://rdfs.org/ns/void#subset"]
|
292
|
+
version["http://rdfs.org/ns/void#subset"].each do |s|
|
293
|
+
subset << @data[s]["http://rdfs.org/ns/void#dataDump"].first
|
294
|
+
end
|
295
|
+
end
|
296
|
+
date = version["http://purl.org/pav/createdOn"]&.first
|
297
|
+
date = version["http://purl.org/dc/terms/issued"]&.first if date.nil?
|
298
|
+
versions << {
|
299
|
+
uri: uri,
|
300
|
+
version: version["http://purl.org/pav/version"]&.first,
|
301
|
+
triples: version["http://rdfs.org/ns/void#triples"]&.first,
|
302
|
+
datadump: version["http://rdfs.org/ns/void#dataDump"]&.first,
|
303
|
+
bytesize: version["http://www.w3.org/ns/dcat#byteSize"]&.first,
|
304
|
+
date: date,
|
305
|
+
description: description,
|
306
|
+
subset: subset,
|
307
|
+
}
|
308
|
+
end
|
309
|
+
end
|
310
|
+
versions.sort_by{|v| [ v[:date], v[:uri] ] }
|
311
|
+
end
|
312
|
+
def extract_toplevel
|
313
|
+
result = {}
|
314
|
+
toplevel = @graph.query([nil, RDF::URI("http://purl.org/pav/hasCurrentVersion"), nil]).subjects.first
|
315
|
+
data = @data[toplevel.to_s]
|
316
|
+
if toplevel
|
317
|
+
license = {}
|
318
|
+
if data["http://purl.org/dc/terms/license"]
|
319
|
+
license_data = @data[data["http://purl.org/dc/terms/license"].first]
|
320
|
+
license[:url] = license_data["http://www.w3.org/1999/02/22-rdf-syntax-ns#value"]&.first
|
321
|
+
license[:icon] = license_data["http://xmlns.com/foaf/0.1/thumbnail"]&.first
|
322
|
+
license[:label] = license_data["http://www.w3.org/2000/01/rdf-schema#label"]
|
323
|
+
end
|
324
|
+
result = {
|
325
|
+
uri: toplevel.to_s,
|
326
|
+
description: data["http://purl.org/dc/terms/description"],
|
327
|
+
license: license,
|
328
|
+
}
|
329
|
+
end
|
330
|
+
result
|
331
|
+
end
|
332
|
+
|
268
333
|
def output_turtle_files
|
269
|
-
|
270
|
-
total: @data.size,
|
271
|
-
format: "(%t) %a %e %P% Processed: %c from %C")
|
272
|
-
each_data do |uri, v|
|
273
|
-
progressbar.increment
|
334
|
+
each_data(:output_turtle_files) do |uri, v|
|
274
335
|
file = uri_mapping_to_path(uri, ".ttl")
|
275
336
|
if @config[:output_dir]
|
276
337
|
Dir.mkdir @config[:output_dir] if not File.exist? @config[:output_dir]
|
@@ -282,7 +343,6 @@ module TTL2HTML
|
|
282
343
|
io.puts str.strip
|
283
344
|
end
|
284
345
|
end
|
285
|
-
progressbar.finish
|
286
346
|
end
|
287
347
|
def uri_mapping_to_path(uri, suffix = ".html")
|
288
348
|
path = nil
|
data/locales/en.yml
CHANGED
@@ -3,11 +3,17 @@ en:
|
|
3
3
|
title: "About %{title}"
|
4
4
|
The properties for the textbook resources are as follows:
|
5
5
|
shape-note: "The properties for the %{resource} resources are as follows:"
|
6
|
+
versions: Versions
|
7
|
+
version-release: "Version %{version} released."
|
8
|
+
version-triples: "%{triples} triples"
|
6
9
|
default:
|
7
10
|
details: Details
|
8
11
|
inverse_data: Referred resources
|
9
12
|
index:
|
10
13
|
list: "List of %{resource}"
|
14
|
+
latest-news: "Latest news"
|
15
|
+
past-versions: "Past versions"
|
16
|
+
license-text: "This dataset is freely usable as <a href=\"%{url}\">%{label}</a>"
|
11
17
|
layout:
|
12
18
|
rdf-data: RDF data
|
13
19
|
shape-table:
|
data/locales/ja.yml
CHANGED
@@ -2,11 +2,17 @@ ja:
|
|
2
2
|
about:
|
3
3
|
title: "%{title}について"
|
4
4
|
shape-note: "%{resource}リソースが持つプロパティを下表に示します"
|
5
|
+
versions: 更新履歴
|
6
|
+
version-release: "バージョン%{version}を公開。"
|
7
|
+
version-triples: "%{triples}トリプル"
|
5
8
|
default:
|
6
9
|
details: 詳細情報
|
7
10
|
inverse_data: 被参照情報
|
8
11
|
index:
|
9
12
|
list: "%{resource} 一覧"
|
13
|
+
latest-news: 最新のお知らせ
|
14
|
+
past-versions: 過去の更新履歴
|
15
|
+
license-text: "このデータセットは<a href=\"%{url}\">%{label}</a>として自由に利用できます。"
|
10
16
|
layout:
|
11
17
|
rdf-data: RDFデータ
|
12
18
|
shape-table:
|
data/templates/about.html.erb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
<div class="jumbotron">
|
2
2
|
<div class="container">
|
3
3
|
<h1><%=h t("about.title", title: param[:site_title]) %></h1>
|
4
|
+
<%- if param[:toplevel] and param[:toplevel][:description] -%>
|
5
|
+
<p><%= get_language_literal(param[:toplevel][:description]) %></p>
|
6
|
+
<%- end -%>
|
4
7
|
</div>
|
5
8
|
</div>
|
6
9
|
<div class="container">
|
@@ -10,18 +13,32 @@
|
|
10
13
|
<ol class="breadcrumb">
|
11
14
|
<li class="breadcrumb-item"><a href="./"><i class="bi bi-house-door-fill"></i> Home</a></li>
|
12
15
|
<li class="breadcrumb-item active" aria-current="page"><%=h t("about.title", title: param[:site_title]) %></li>
|
13
|
-
|
14
|
-
|
16
|
+
</ol>
|
17
|
+
</nav>
|
18
|
+
</div>
|
15
19
|
</div>
|
20
|
+
<%- if param[:shapes] -%>
|
16
21
|
<div class="row">
|
17
22
|
<div class="col-md">
|
18
|
-
<%- param[:
|
19
|
-
<h3><%=h param[:
|
20
|
-
<p><%= param[:
|
21
|
-
<p><%=h t("about.shape-note", resource: param[:
|
22
|
-
<%= param[:
|
23
|
+
<%- param[:shapes].keys.sort.each do |shape| -%>
|
24
|
+
<h3><%=h param[:shapes][shape][:label] %></h3>
|
25
|
+
<p><%= param[:shapes][shape][:comment] %></p>
|
26
|
+
<p><%=h t("about.shape-note", resource: param[:shapes][shape][:label]) %></p>
|
27
|
+
<%= param[:shapes][shape][:html] -%>
|
23
28
|
<%- end -%>
|
24
29
|
</div>
|
25
30
|
</div>
|
26
|
-
|
27
|
-
|
31
|
+
<%- end -%>
|
32
|
+
<%- if param[:versions] -%>
|
33
|
+
<div class="row">
|
34
|
+
<div class="col-md">
|
35
|
+
<h2 id="versions"><%=h t("about.versions") %> <i class="bi bi-info-circle"></i></h2>
|
36
|
+
<dl>
|
37
|
+
<%- param[:versions].reverse_each do |version| -%>
|
38
|
+
<%= format_version_info(version) %>
|
39
|
+
<%- end -%>
|
40
|
+
</dl>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
<%- end -%>
|
44
|
+
</div>
|
data/templates/index.html.erb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
<div class="jumbotron">
|
2
2
|
<div class="container">
|
3
3
|
<h1><%=h param[:site_title] %></h1>
|
4
|
+
<%- if param[:toplevel] and param[:toplevel][:description] -%>
|
5
|
+
<p><%= get_language_literal(param[:toplevel][:description]) %></p>
|
6
|
+
<%- end -%>
|
4
7
|
<p><i class="bi bi-link-45deg"></i> <a href="<%=h param[:base_uri] %>"><%=h param[:base_uri] %></a></p>
|
5
8
|
</div>
|
6
9
|
</div>
|
@@ -9,10 +12,31 @@
|
|
9
12
|
<div class="col-md-12">
|
10
13
|
<h2><%=h t("index.list", resource: param[:class_label]) %></h2>
|
11
14
|
<ul>
|
12
|
-
|
15
|
+
<%- param[:index_data].each do |e| -%>
|
13
16
|
<li><%= format_object(e, param[:data_global]) %></li>
|
14
|
-
|
17
|
+
<%- end -%>
|
15
18
|
</ul>
|
16
19
|
</div>
|
17
20
|
</div>
|
18
|
-
|
21
|
+
<%- if param[:versions].size > 0 -%>
|
22
|
+
<div class="row">
|
23
|
+
<div class="col-md">
|
24
|
+
<h2 id="versions"><%=h t("index.latest-news") %> <i class="bi bi-info-circle"></i></h2>
|
25
|
+
<dl>
|
26
|
+
<%= format_version_info(param[:versions].last) %>
|
27
|
+
</dl>
|
28
|
+
<%- if param[:versions].size > 1 -%>
|
29
|
+
<p><a href="about#versions">» <%=h t("index.past-versions") %></a></p>
|
30
|
+
<%- end -%>
|
31
|
+
<%- if param[:toplevel] and param[:toplevel][:license] -%>
|
32
|
+
<p>
|
33
|
+
<%- if param[:toplevel][:license][:icon] -%>
|
34
|
+
<a href="<%=h param[:toplevel][:license][:url] %>"><img src="<%=h param[:toplevel][:license][:icon] %>"></a>
|
35
|
+
<%- end -%>
|
36
|
+
<%= t("index.license-text", label: get_language_literal(param[:toplevel][:license][:label]), url: param[:toplevel][:license][:url]) %>
|
37
|
+
</p>
|
38
|
+
<%- end -%>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
<%- end -%>
|
42
|
+
</div>
|
data/templates/layout.html.erb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
|
7
7
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
|
8
8
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
|
9
|
-
<title
|
9
|
+
<title><%=h html_title(param) %></title>
|
10
10
|
<meta name="twitter:card" content="summary">
|
11
|
-
<meta name="twitter:title" content="
|
11
|
+
<meta name="twitter:title" content="<%=h html_title(param) %>">
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<dt><%=h param[:data][:date] %></dt>
|
2
|
+
<dd><%=h t("about.version-release", version: param[:data][:version]) %></dd>
|
3
|
+
<dd><%=h get_language_literal(param[:data][:description]) %></dd>
|
4
|
+
<%- if param[:data][:datadump] -%>
|
5
|
+
<dd><ul>
|
6
|
+
<li><a href="<%=h param[:data][:datadump] %>"><%=h File.basename(param[:data][:datadump]) %></a>
|
7
|
+
<%-
|
8
|
+
fileinfo = []
|
9
|
+
if param[:data][:triples]
|
10
|
+
fileinfo << t("about.version-triples", triples: number_with_delimiter(param[:data][:triples].to_i))
|
11
|
+
end
|
12
|
+
if param[:data][:bytesize]
|
13
|
+
fileinfo << number_to_human_size(param[:data][:bytesize])
|
14
|
+
end
|
15
|
+
-%>
|
16
|
+
<%- if fileinfo.size > 0 -%>
|
17
|
+
(<%=h fileinfo.join(", ") %>)
|
18
|
+
<%- end -%>
|
19
|
+
<%- if param[:data][:subset].size > 0 -%>
|
20
|
+
<ul>
|
21
|
+
<%- param[:data][:subset].each do |subset| -%>
|
22
|
+
<li><a href="<%=h subset %>"><%=h File.basename(subset) %></a></li>
|
23
|
+
<%- end -%>
|
24
|
+
</ul>
|
25
|
+
</li>
|
26
|
+
<%- end -%>
|
27
|
+
</dd>
|
28
|
+
<%- end -%>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ttl2html
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masao Takaku
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: actionview
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rspec
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,6 +160,7 @@ files:
|
|
146
160
|
- templates/layout.html.erb
|
147
161
|
- templates/shape-table.html.erb
|
148
162
|
- templates/triples.html.erb
|
163
|
+
- templates/version.html.erb
|
149
164
|
homepage: https://github.com/masao/ttl2html
|
150
165
|
licenses:
|
151
166
|
- MIT
|
@@ -165,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
180
|
- !ruby/object:Gem::Version
|
166
181
|
version: '0'
|
167
182
|
requirements: []
|
168
|
-
rubygems_version: 3.2.
|
183
|
+
rubygems_version: 3.2.32
|
169
184
|
signing_key:
|
170
185
|
specification_version: 4
|
171
186
|
summary: ttl2html
|