ttl2html 1.0.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abc6dcc7ac8d23455d722dae7c9667f18ee48b7c7c797687922c5493037535d5
4
- data.tar.gz: aa6d348addb6bfe3b95cc024da7d8dcb7639d532bbd337eac0b42321bc7687d9
3
+ metadata.gz: 6d6db7238da3700fba83d389bdab577f9bacc2c5da65f993612731716ac4899a
4
+ data.tar.gz: 1804e3b40f344e00618699202d331e03e2e5324519626df62389fc739925fe82
5
5
  SHA512:
6
- metadata.gz: 733765aed31be6e74dc2f27acc18764385e09a08932f4d1413aa89369640a89426357f1c8395cef1746dfb24f85df41858b4b9a6ba2ed0768d6b401fa7c985a0
7
- data.tar.gz: c44db48f508966a30b7953b0425c5f3d72ad1b07c69bb4f0ae5f22894486793f50c8504135a9b3bba812ce57bed5273025c898fb461389b497522c2ea5b843a7
6
+ metadata.gz: 7bbcc86b1acc04ad04c8a5f98b11fe020366630b7fc3ad99067e7de19853afd3311e7534fe80facc150490a784d2e96600b20e43e66f6da7aa1380a1fe8c2163
7
+ data.tar.gz: c93964d3ef71fa6e300e8634ae49a3dd5f083f737ac3d0ae3224c9493b5d7bdb8846f6a95b1803110eab1b16971b951a38c802522c0a1099f30c16d11910632f
@@ -3,16 +3,21 @@
3
3
  require "fileutils"
4
4
  require "pathname"
5
5
  require "erb"
6
+ require "i18n"
6
7
 
7
8
  module TTL2HTML
8
9
  class Template
9
10
  attr_reader :param
10
11
  include ERB::Util
12
+ include I18n::Base
11
13
  def initialize(template, param = {})
12
14
  @template = template
13
- @param = param
15
+ @param = param.dup
14
16
  @template_path = [ Dir.pwd, File.join(Dir.pwd, "templates") ]
15
17
  @template_path << File.join(File.dirname(__FILE__), "..", "..", "templates")
18
+ I18n.load_path << Dir[File.join(File.dirname(__FILE__), "..", "..", "locales") + "/*.yml"]
19
+ I18n.load_path << Dir[File.expand_path("locales") + "/*.yml"]
20
+ I18n.locale = @param[:locale] if @param[:locale]
16
21
  end
17
22
  def output_to(file, param = {})
18
23
  @param.update(param)
@@ -92,9 +97,9 @@ module TTL2HTML
92
97
  {
93
98
  path: path,
94
99
  shorten_path: shorten_path,
95
- name: data[property]["http://www.w3.org/ns/shacl#name"].first,
100
+ name: get_language_literal(data[property]["http://www.w3.org/ns/shacl#name"]),
96
101
  example: data[property]["http://www.w3.org/2004/02/skos/core#example"] ? data[property]["http://www.w3.org/2004/02/skos/core#example"].first : nil,
97
- description: data[property]["http://www.w3.org/ns/shacl#description"] ? data[property]["http://www.w3.org/ns/shacl#description"].first : nil,
102
+ description: get_language_literal(data[property]["http://www.w3.org/ns/shacl#description"]),
98
103
  required: data[property]["http://www.w3.org/ns/shacl#minCount"] ? data[property]["http://www.w3.org/ns/shacl#minCount"].first.to_i > 0 : false,
99
104
  repeatable: repeatable,
100
105
  nodeKind: data[property]["http://www.w3.org/ns/shacl#nodeKind"] ? data[property]["http://www.w3.org/ns/shacl#nodeKind"].first : nil,
@@ -108,6 +113,33 @@ module TTL2HTML
108
113
  end
109
114
 
110
115
  # helper method:
116
+ def uri_mapping_to_path(uri, suffix = ".html")
117
+ path = nil
118
+ if @param[:uri_mappings]
119
+ @param[:uri_mappings].each do |mapping|
120
+ local_file = uri.sub(@param[:base_uri], "")
121
+ if mapping["regexp"] =~ local_file
122
+ path = local_file.sub(mapping["regexp"], mapping["path"])
123
+ end
124
+ end
125
+ end
126
+ if path.nil?
127
+ if suffix == ".html"
128
+ if @param[:data_global] and @param[:data_global].keys.find{|e| e.start_with?(uri + "/") }
129
+ path = uri + "/index"
130
+ elsif uri.end_with?("/")
131
+ path = uri + "index"
132
+ else
133
+ path = uri
134
+ end
135
+ else
136
+ path = uri
137
+ end
138
+ end
139
+ path = path.sub(@param[:base_uri], "") if @param[:base_uri]
140
+ path << suffix
141
+ path
142
+ end
111
143
  def relative_path(dest)
112
144
  src = @param[:output_file]
113
145
  src = Pathname.new(src).relative_path_from(Pathname.new(@param[:output_dir])) if @param[:output_dir]
@@ -118,14 +150,29 @@ module TTL2HTML
118
150
  def relative_path_uri(dest_uri, base_uri)
119
151
  if dest_uri.start_with? base_uri
120
152
  dest = dest_uri.sub(base_uri, "")
153
+ dest = uri_mapping_to_path(dest, "")
121
154
  relative_path(dest)
122
155
  else
123
156
  dest_uri
124
157
  end
125
158
  end
159
+ def shorten_title(title, length = 140)
160
+ if title.length > length
161
+ title[0..length] + "..."
162
+ else
163
+ title
164
+ end
165
+ end
126
166
  def get_title(data, default_title = "no title")
167
+ if @param[:title_property_perclass] and data["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]
168
+ @param[:title_property_perclass].each do |klass, property|
169
+ if data["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"].include?(klass) and data[property]
170
+ return shorten_title(get_language_literal(data[property]))
171
+ end
172
+ end
173
+ end
127
174
  if @param[:title_property] and data[@param[:title_property]]
128
- return get_language_literal(data[@param[:title_property]])
175
+ return shorten_title(get_language_literal(data[@param[:title_property]]))
129
176
  end
130
177
  %w(
131
178
  http://www.w3.org/2000/01/rdf-schema#label
@@ -134,13 +181,17 @@ module TTL2HTML
134
181
  http://schema.org/name
135
182
  http://www.w3.org/2004/02/skos/core#prefLabel
136
183
  ).each do |property|
137
- return get_language_literal(data[property]) if data[property]
184
+ return shorten_title(get_language_literal(data[property])) if data[property]
138
185
  end
139
186
  default_title
140
187
  end
141
188
  def get_language_literal(object)
142
189
  if object.respond_to? :has_key?
143
- object.values.first
190
+ if object.has_key?(I18n.locale)
191
+ object[I18n.locale]
192
+ else
193
+ object.values.first
194
+ end
144
195
  elsif object.is_a? Array
145
196
  object.first
146
197
  else
@@ -157,7 +208,7 @@ module TTL2HTML
157
208
  def format_object(object, data)
158
209
  if object =~ /\Ahttps?:\/\//
159
210
  rel_path = relative_path_uri(object, param[:base_uri])
160
- if data[object]
211
+ if param[:data_global][object]
161
212
  "<a href=\"#{rel_path}\">#{get_title(param[:data_global][object]) or object}</a>"
162
213
  else
163
214
  "<a href=\"#{rel_path}\">#{object}</a>"
@@ -168,8 +219,9 @@ module TTL2HTML
168
219
  object
169
220
  end
170
221
  end
171
- def format_triples(triples)
222
+ def format_triples(triples, type = :default)
172
223
  param_local = @param.dup.merge(data: triples)
224
+ param_local[:type] = type
173
225
  if @param[:labels_with_class] and triples["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]
174
226
  @param[:labels_with_class].reverse_each do |k, v|
175
227
  triples["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"].each do |entity_class|
@@ -185,4 +237,4 @@ module TTL2HTML
185
237
  to_html_raw("triples.html.erb", param_local)
186
238
  end
187
239
  end
188
- end
240
+ end
@@ -1 +1 @@
1
- TTL2HTML::VERSION = "1.0.0"
1
+ TTL2HTML::VERSION = "1.3.0"
data/lib/ttl2html.rb CHANGED
@@ -10,9 +10,7 @@ require "ttl2html/template"
10
10
 
11
11
  module TTL2HTML
12
12
  class App
13
- using ProgressBar::Refinements::Enumerator
14
13
  def initialize(config = "config.yml")
15
- @template = {}
16
14
  @config = load_config(config)
17
15
  if not @config[:base_uri]
18
16
  raise "load_config: base_uri not found"
@@ -68,49 +66,41 @@ module TTL2HTML
68
66
  def format_turtle(subject, depth = 1)
69
67
  turtle = RDF::Turtle::Writer.new
70
68
  result = ""
71
- if subject.iri?
72
- result << "<#{subject}>\n#{" "*depth}"
73
- else
69
+ if subject =~ /^_:/
74
70
  result << "[\n#{" "*depth}"
71
+ else
72
+ result << "<#{subject}>\n#{" "*depth}"
75
73
  end
76
- result << @graph.query([subject, nil, nil]).predicates.sort.map do |predicate|
74
+ result << @data[subject.to_s].keys.sort.map do |predicate|
77
75
  str = "<#{predicate}> "
78
- str << @graph.query([subject, predicate, nil]).objects.sort_by do |object|
79
- if object.resource? and not object.iri? # blank node:
80
- @graph.query([object, nil, nil]).statements.sort_by{|e|
81
- [ e.predicate, e.object ]
82
- }.map{|e|
83
- [ e.predicate, e.object ]
84
- }
85
- else
86
- object
87
- end
88
- end.map do |object|
89
- if object.resource? and not object.iri? # blank node:
76
+ str << @data[subject.to_s][predicate].sort.map do |object|
77
+ if object =~ /^_:/ # blank node:
90
78
  format_turtle(object, depth + 1)
79
+ elsif object =~ RDF::URI::IRI
80
+ turtle.format_uri(RDF::URI.new object)
81
+ elsif object.respond_to?(:first) and object.first.kind_of?(Symbol)
82
+ turtle.format_literal(RDF::Literal.new(object[1], language: object[0]))
91
83
  else
92
- case object
93
- when RDF::URI
94
- turtle.format_uri(object)
95
- else
96
- turtle.format_literal(object)
97
- end
84
+ turtle.format_literal(object)
98
85
  end
99
86
  end.join(", ")
100
87
  str
101
88
  end.join(";\n#{" "*depth}")
102
- result << " ." if subject.iri?
89
+ result << " ." if not subject =~ /^_:/
103
90
  result << "\n"
104
- result << "#{" "*(depth-1)}]" if not subject.iri?
91
+ result << "#{" "*(depth-1)}]" if subject =~ /^_:/
105
92
  result
106
93
  end
107
94
  def format_turtle_inverse(object)
108
- turtle = RDF::Turtle::Writer.new
109
95
  result = ""
110
- @graph.query([nil, nil, object]).statements.sort_by do |e|
111
- [ e.subject, e.predicate, object ]
112
- end.map do |e|
113
- result << "<#{e.subject}> <#{e.predicate}> <#{object}>.\n"
96
+ return result if not object.start_with? @config[:base_uri]
97
+ return result if not @data_inverse.has_key? object
98
+ turtle = RDF::Turtle::Writer.new
99
+ @data_inverse[object].keys.sort.each do |predicate|
100
+ @data_inverse[object.to_s][predicate].sort.each do |subject|
101
+ next if subject =~ /^_:/
102
+ result << "<#{subject}> <#{predicate}> <#{object}>.\n"
103
+ end
114
104
  end
115
105
  result
116
106
  end
@@ -122,40 +112,46 @@ module TTL2HTML
122
112
  end
123
113
  end
124
114
  def output_html_files
115
+ template = Template.new("", @config)
116
+ shapes = @graph.query([nil,
117
+ RDF::URI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
118
+ RDF::URI("http://www.w3.org/ns/shacl#NodeShape")])
119
+ labels = shapes2labels(shapes)
120
+ @config[:labels_with_class] ||= {}
121
+ labels.each do |klass, props|
122
+ props.each do |property, label|
123
+ @config[:labels_with_class][klass] ||= {}
124
+ if @config[:labels_with_class][klass][property]
125
+ next
126
+ else
127
+ @config[:labels_with_class][klass][property] = template.get_language_literal(label)
128
+ end
129
+ end
130
+ end
131
+ progressbar = ProgressBar.create(title: :output_html_files,
132
+ total: @data.size,
133
+ format: "(%t) %a %e %P% Processed: %c from %C")
125
134
  each_data do |uri, v|
135
+ progressbar.increment
126
136
  template = Template.new("default.html.erb", @config)
127
137
  param = @config.dup
128
138
  param[:uri] = uri
139
+ param[:turtle_uri] = uri_mapping_to_path(uri, ".ttl")
129
140
  param[:data] = v
130
141
  param[:data_inverse] = @data_inverse[uri]
131
142
  param[:data_global] = @data
132
143
  param[:title] = template.get_title(v)
133
- file = nil
134
- if @config[:uri_mappings]
135
- @config[:uri_mappings].each do |mapping|
136
- local_file = uri.sub(@config[:base_uri], "")
137
- if mapping["regexp"] =~ local_file
138
- file = local_file.sub(mapping["regexp"], mapping["path"])
139
- end
140
- end
141
- end
142
- if file.nil?
143
- if @data.keys.find{|e| e.start_with?(uri + "/") }
144
- file = uri + "/index.html"
145
- elsif uri.end_with?("/")
146
- file = uri + "index.html"
147
- else
148
- file = uri + ".html"
149
- end
144
+ if param[:breadcrumbs]
145
+ param[:breadcrumbs_items] = build_breadcrumbs(uri, template)
150
146
  end
151
- #p uri, param
152
- file = file.sub(@config[:base_uri], "")
147
+ file = uri_mapping_to_path(uri, ".html")
153
148
  if @config[:output_dir]
154
149
  Dir.mkdir @config[:output_dir] if not File.exist? @config[:output_dir]
155
150
  file = File.join(@config[:output_dir], file)
156
151
  end
157
152
  template.output_to(file, param)
158
153
  end
154
+ progressbar.finish
159
155
  index_html = "index.html"
160
156
  index_html = File.join(@config[:output_dir], "index.html") if @config[:output_dir]
161
157
  if @config.has_key? :top_class
@@ -176,9 +172,6 @@ module TTL2HTML
176
172
  template.output_to(index_html, param)
177
173
  end
178
174
  end
179
- shapes = @graph.query([nil,
180
- RDF::URI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
181
- RDF::URI("http://www.w3.org/ns/shacl#NodeShape")])
182
175
  if shapes.size > 0
183
176
  about_html = @config[:about_file] || "about.html"
184
177
  about_html = File.join(@config[:output_dir], about_html) if @config[:output_dir]
@@ -187,36 +180,121 @@ module TTL2HTML
187
180
  param[:data_global] = @data
188
181
  param[:content] = {}
189
182
  shapes.subjects.each do |subject|
190
- label = nil
183
+ label = comment = nil
191
184
  target_class = @data[subject.to_s]["http://www.w3.org/ns/shacl#targetClass"]
192
185
  if target_class
193
- label = template.get_title(@data[target_class.first], nil) if @data[target_class.first]
194
- label = template.format_property(target_class.first) if label.nil?
186
+ target_class = target_class.first
187
+ if @data[target_class]
188
+ label = template.get_title(@data[target_class], nil)
189
+ comment = @data[target_class]["http://www.w3.org/2000/01/rdf-schema#comment"]&.first
190
+ else
191
+ label = template.format_property(target_class)
192
+ end
195
193
  else
196
194
  label = template.get_title(@data[subject.to_s])
197
195
  end
198
196
  param[:content][subject] = {
199
197
  label: label,
198
+ comment: comment,
200
199
  html: template.expand_shape(@data, subject.to_s, @prefix),
201
200
  }
202
201
  end
203
202
  template.output_to(about_html, param)
204
203
  end
205
204
  end
205
+
206
+ def build_breadcrumbs(uri, template, depth = 0)
207
+ results = []
208
+ data = @data[uri]
209
+ if @config[:breadcrumbs]
210
+ if depth == 0
211
+ first_label = template.get_title(data)
212
+ first_label = data[@config[:breadcrumbs].first["label"]].first if @config[:breadcrumbs].first["label"] and data[@config[:breadcrumbs].first["label"]]
213
+ results << { label: first_label }
214
+ end
215
+ @config[:breadcrumbs].each do |e|
216
+ data_target = data
217
+ data_target = @data_inverse[uri] if e["inverse"]
218
+ if data_target and data_target[e["property"]]
219
+ data_target[e["property"]].each do |parent|
220
+ data_parent = @data[parent]
221
+ label = template.get_title(data_parent)
222
+ label = data_parent[e["label"]].first if e["label"] and data_parent[e["label"]]
223
+ results << {
224
+ uri: parent,
225
+ label: label,
226
+ }
227
+ results += build_breadcrumbs(parent, template, depth + 1)
228
+ end
229
+ return results
230
+ end
231
+ end
232
+ end
233
+ results
234
+ end
235
+
236
+ def shapes2labels(shapes)
237
+ labels = {}
238
+ shapes.subjects.each do |shape|
239
+ target_class = @data[shape.to_s]["http://www.w3.org/ns/shacl#targetClass"]&.first
240
+ if target_class
241
+ @data[shape.to_s]["http://www.w3.org/ns/shacl#property"].each do |property|
242
+ path = @data[property]["http://www.w3.org/ns/shacl#path"].first
243
+ name = @data[property]["http://www.w3.org/ns/shacl#name"]
244
+ labels[target_class] ||= {}
245
+ labels[target_class][path] = name
246
+ end
247
+ end
248
+ end
249
+ labels
250
+ end
251
+
206
252
  def output_turtle_files
253
+ progressbar = ProgressBar.create(title: :output_turtle_files,
254
+ total: @data.size,
255
+ format: "(%t) %a %e %P% Processed: %c from %C")
207
256
  each_data do |uri, v|
208
- file = uri.sub(@config[:base_uri], "")
209
- file << ".ttl"
257
+ progressbar.increment
258
+ file = uri_mapping_to_path(uri, ".ttl")
210
259
  if @config[:output_dir]
211
260
  Dir.mkdir @config[:output_dir] if not File.exist? @config[:output_dir]
212
261
  file = File.join(@config[:output_dir], file)
213
262
  end
214
- str = format_turtle(RDF::URI.new uri)
215
- str << format_turtle_inverse(RDF::URI.new uri)
263
+ str = format_turtle(uri)
264
+ str << format_turtle_inverse(uri)
216
265
  open(file, "w") do |io|
217
266
  io.puts str.strip
218
267
  end
219
268
  end
269
+ progressbar.finish
270
+ end
271
+ def uri_mapping_to_path(uri, suffix = ".html")
272
+ path = nil
273
+ if @config[:uri_mappings]
274
+ @config[:uri_mappings].each do |mapping|
275
+ local_file = uri.sub(@config[:base_uri], "")
276
+ if mapping["regexp"] =~ local_file
277
+ path = local_file.sub(mapping["regexp"], mapping["path"])
278
+ end
279
+ end
280
+ end
281
+ if path.nil?
282
+ if suffix == ".html"
283
+ if @data.keys.find{|e| e.start_with?(uri + "/") }
284
+ path = uri + "/index"
285
+ elsif uri.end_with?("/")
286
+ path = uri + "index"
287
+ else
288
+ path = uri
289
+ end
290
+ else
291
+ path = uri
292
+ end
293
+ end
294
+ path = path.sub(@config[:base_uri], "")
295
+ path << suffix
296
+ #p [uri, path]
297
+ path
220
298
  end
221
299
  def cleanup
222
300
  @data.select do |uri, v|
@@ -224,15 +302,10 @@ module TTL2HTML
224
302
  end.sort_by do |uri, v|
225
303
  -(uri.size)
226
304
  end.each do |uri, v|
227
- if @data.keys.find{|e| e.start_with?(uri + "/") }
228
- file = uri + "/index.html"
229
- else
230
- file = uri + ".html"
231
- end
232
- html_file = file.sub(@config[:base_uri], "")
305
+ html_file = uri_mapping_to_path(uri, ".html")
233
306
  html_file = File.join(@config[:output_dir], html_file) if @config[:output_dir]
234
307
  File.unlink html_file
235
- ttl_file = uri.sub(@config[:base_uri], "") + ".ttl"
308
+ ttl_file = uri_mapping_to_path(uri, ".ttl")
236
309
  ttl_file = File.join(@config[:output_dir], ttl_file) if @config[:output_dir]
237
310
  File.unlink ttl_file
238
311
  dir = uri.sub(@config[:base_uri], "")
data/locales/en.yml ADDED
@@ -0,0 +1,28 @@
1
+ en:
2
+ about:
3
+ title: "About %{title}"
4
+ The properties for the textbook resources are as follows:
5
+ shape-note: "The properties for the %{resource} resources are as follows:"
6
+ default:
7
+ details: Details
8
+ inverse_data: Referred resources
9
+ index:
10
+ list: "List of %{resource}"
11
+ layout:
12
+ rdf-data: RDF data
13
+ shape-table:
14
+ header:
15
+ property-name: "Property name"
16
+ description: "Description"
17
+ example: "Example of the property value(s)"
18
+ required: "Required?"
19
+ repeatable: "Repeatable?"
20
+ note: "Notes"
21
+ required: "Required"
22
+ repeatable: "Repeatable"
23
+ optional: "Optional"
24
+ non-repeatable: "Non repeatable"
25
+ blank-node-structure: "The structural contents of a blank node are as follows:"
26
+ blank-node-or-structure: "The structural contents of a blank node are either of the followings:"
27
+ triples:
28
+ inverse_refered: "Referred to as '%{property}' from:"
data/locales/ja.yml ADDED
@@ -0,0 +1,27 @@
1
+ ja:
2
+ about:
3
+ title: "%{title}について"
4
+ shape-note: "%{resource}リソースが持つプロパティを下表に示します"
5
+ default:
6
+ details: 詳細情報
7
+ inverse_data: 被参照情報
8
+ index:
9
+ list: "%{resource} 一覧"
10
+ layout:
11
+ rdf-data: RDFデータ
12
+ shape-table:
13
+ header:
14
+ property-name: プロパティ名
15
+ description: 説明
16
+ example: プロパティ値の例
17
+ required: 必須・省略の別
18
+ repeatable: 繰り返しの有無
19
+ note: 備考
20
+ required: 必須
21
+ repeatable: 繰り返し有り
22
+ optional: 省略可能
23
+ non-repeatable: 繰り返し無し
24
+ blank-node-structure: ブランクノードの内容は以下の内容からなる構造を持ちます。
25
+ blank-node-or-structure: ブランクノードの内容は以下のいずれかの内容からなる構造を持ちます。
26
+ triples:
27
+ inverse_refered: "'%{property}'としての参照元:"
@@ -1,24 +1,23 @@
1
1
  <div class="jumbotron">
2
2
  <div class="container">
3
- <h1><%=h param[:site_title] %>について</h1>
3
+ <h1><%=h t("about.title", title: param[:site_title]) %></h1>
4
4
  </div>
5
5
  </div>
6
+ <nav aria-label="breadcrumb">
7
+ <ol class="breadcrumb">
8
+ <li class="breadcrumb-item"><a href="./"><i class="bi bi-house-door-fill"></i> Home</a></li>
9
+ <li class="breadcrumb-item active" aria-current="page"><%=h t("about.title", title: param[:site_title]) %></li>
10
+ </ol>
11
+ </nav>
6
12
  <div class="container">
7
13
  <div class="row">
8
- <div class="col-md-12">
9
- <ol class="breadcrumb">
10
- <li><a href="./"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> Home</a></li>
11
- <li class="active"><%=h param[:site_title] %>について</li>
12
- </ol>
13
- </div>
14
- </div>
15
-
16
- <div class="row">
17
- <div class="col-md-10">
14
+ <div class="col-md">
18
15
  <%- param[:content].keys.sort.each do |shape| -%>
19
- <h3><%=h param[:content][shape][:label] %>をあらわすリソース</h3>
20
- <p><%=h param[:content][shape][:label] %>リソースが持つプロパティを下表に示します</p>
16
+ <h3><%=h param[:content][shape][:label] %></h3>
17
+ <p><%= param[:content][shape][:comment] %></p>
18
+ <p><%=h t("about.shape-note", resource: param[:content][shape][:label]) %></p>
21
19
  <%= param[:content][shape][:html] -%>
22
20
  <%- end -%>
23
21
  </div>
24
22
  </div>
23
+ </div>
@@ -1,22 +1,42 @@
1
1
  <div class="jumbotron">
2
2
  <div class="container">
3
3
  <h1><%=h param[:title] %></h1>
4
- <p><small><span class="glyphicon glyphicon-link"></span> <a href="<%=h param[:uri] %>"><%=h param[:uri] %></a></small></p>
4
+ <p><i class="bi bi-link-45deg"></i> <a href="<%=h param[:uri] %>"><%=h param[:uri] %></a></p>
5
5
  </div>
6
6
  </div>
7
7
  <div class="container">
8
+ <%- if param[:breadcrumbs] -%>
8
9
  <div class="row">
9
10
  <div class="col-md-12">
10
- <h2>詳細情報</h2>
11
+ <nav aria-label="breadcrumb">
12
+ <ol class="breadcrumb">
13
+ <li class="breadcrumb-item"><a href="./"><i class="bi bi-house-door-fill"></i> Home</a></li>
14
+ <%- param[:breadcrumbs_items].reverse.each_with_index do |e, i| -%>
15
+ <li class="breadcrumb-item<%= ' active' if i == param[:breadcrumbs_items].size-1 %>" aria-current="page">
16
+ <%- if e[:uri] -%>
17
+ <a href="<%=h e[:uri] %>"><%=h e[:label] %></a>
18
+ <%- else -%>
19
+ <%=h e[:label] %>
20
+ <%- end -%>
21
+ </li>
22
+ <%- end -%>
23
+ </ol>
24
+ </nav>
25
+ </div>
26
+ </div>
27
+ <%- end -%>
28
+ <div class="row">
29
+ <div class="col-md-12">
30
+ <h2><%=h t("default.details") %></h2>
11
31
  <%= format_triples(param[:data]) %>
12
32
  </div>
13
33
  </div>
14
- <% if param[:data_inverse] %>
34
+ <%- if param[:data_inverse] -%>
15
35
  <div class="row inverse">
16
36
  <div class="col-md-12">
17
- <h2>被参照情報</h2>
18
- <%= format_triples(param[:data_inverse]) %>
37
+ <h2><%=h t("default.inverse_data") %></h2>
38
+ <%= format_triples(param[:data_inverse], :inverse) %>
19
39
  </div>
20
40
  </div>
21
- <% end %>
22
- </div>
41
+ <%- end -%>
42
+ </div>
@@ -1,13 +1,13 @@
1
1
  <div class="jumbotron">
2
2
  <div class="container">
3
3
  <h1><%=h param[:site_title] %></h1>
4
- <p><small><span class="glyphicon glyphicon-link"></span> <a href="<%=h param[:base_uri] %>"><%=h param[:base_uri] %></a></small></p>
4
+ <p><i class="bi bi-link-45deg"></i> <a href="<%=h param[:base_uri] %>"><%=h param[:base_uri] %></a></p>
5
5
  </div>
6
6
  </div>
7
7
  <div class="container">
8
8
  <div class="row">
9
9
  <div class="col-md-12">
10
- <h2><%=h param[:class_label] %> 一覧</h2>
10
+ <h2><%=h t("index.list", resource: param[:class_label]) %></h2>
11
11
  <ul>
12
12
  <% param[:index_data].each do |e| %>
13
13
  <li><%= format_object(e, param[:data_global]) %></li>
@@ -4,17 +4,25 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
6
  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
7
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
7
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
8
9
  <title><% if param[:title] %><%=h param[:title] %><% end %><% if param[:site_title] %> - <%=h param[:site_title] %><% end %></title>
9
10
  <meta name="twitter:card" content="summary">
10
11
  <meta name="twitter:title" content="<% if param[:title] %><%=h param[:title] %><% end %><% if param[:site_title] %> - <%=h param[:site_title] %><% end %>">
11
12
  </head>
12
13
  <body>
13
- <nav class="navbar navbar-inverse">
14
- <div class="container">
15
- <ul class="nav navbar-nav navbar-right">
16
- <li<%= ' class="active"' if param[:active] == :home %>><a class="navbar-brand" href="/">Home</a></li>
17
- <li<%= ' class="active"' if param[:active] == :about %>><a href="/about">About</a></li>
14
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
15
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
16
+ <span class="navbar-toggler-icon"></span>
17
+ </button>
18
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
19
+ <ul class="navbar-nav mr-auto">
20
+ <li class="nav-item<%= ' class="active"' if param[:active] == :home %>">
21
+ <a class="navbar-brand" href="/">Home</a>
22
+ </li>
23
+ <li class="nav-item<%= ' class="active"' if param[:active] == :about %>">
24
+ <a class="navbar-brand" href="/about">About</a>
25
+ </li>
18
26
  </ul>
19
27
  </div>
20
28
  </nav>
@@ -22,13 +30,13 @@
22
30
  <hr>
23
31
  <footer>
24
32
  <%- if param[:uri] -%>
25
- <p class="pull-right"><a href="<%=h param[:uri] %>.ttl"><img src="https://www.w3.org/RDF/icons/rdf_flyer.24" alt="RDFデータ"></a></p>
33
+ <p class="text-right"><a href="<%=h relative_path(param[:turtle_uri]) %>"><img src="https://www.w3.org/RDF/icons/rdf_flyer.24" alt="<%=h t("layout.rdf-data") %>"></a></p>
26
34
  <%- end -%>
27
35
  </footer>
28
36
 
29
37
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
30
- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
31
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
32
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
38
+ <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
39
+ <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
40
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
33
41
  </body>
34
42
  </html>
@@ -1,6 +1,11 @@
1
1
  <table class="table table-condensed">
2
2
  <tr>
3
- <th>プロパティ名</th><th>説明</th><th>プロパティ値の例</th><th>必須・省略の別<br>繰り返しの有無</th><th>備考</th>
3
+ <th><%=h t('shape-table.header.property-name') %></th>
4
+ <th><%=h t('shape-table.header.description') %></th>
5
+ <th><%=h t('shape-table.header.example') %></th>
6
+ <th><%=h t('shape-table.header.required') %><br>
7
+ <%=h t('shape-table.header.repeatable') %></th>
8
+ <th><%=h t('shape-table.header.note') %></th>
4
9
  </tr>
5
10
  <tbody>
6
11
  <%- param[:properties].each do |property| -%>
@@ -10,7 +15,7 @@
10
15
  <%- else -%>
11
16
  <td><code><%=h property[:shorten_path] %></code></td>
12
17
  <%- end -%>
13
- <td><%= property[:name_ja] %></td>
18
+ <td><%= property[:name] %></td>
14
19
  <%- if property[:nodeKind] == "http://www.w3.org/ns/shacl#IRI" -%>
15
20
  <td class="url"><%= property[:example] %></td>
16
21
  <%- else -%>
@@ -19,31 +24,31 @@
19
24
  <td>
20
25
  <div>
21
26
  <%- if property[:required] -%>
22
- <strong>必須</strong>
27
+ <strong><%=h t('shape-table.required') %></strong>
23
28
  <%- else -%>
24
- 省略可能
29
+ <%=h t('shape-table.optional') %>
25
30
  <%- end -%>
26
31
  </div>
27
32
  <div>
28
33
  <%- if property[:repeatable] -%>
29
- 繰り返し有り
34
+ <%=h t('shape-table.repeatable') %>
30
35
  <%- else -%>
31
- 繰り返し無し
36
+ <%=h t('shape-table.non-repeatable') %>
32
37
  <%- end -%>
33
38
  </div>
34
39
  </td>
35
- <td><%= property[:description_ja] %></td>
40
+ <td><%= property[:description] %></td>
36
41
  </tr>
37
42
  <%- if property[:nodeKind] == "http://www.w3.org/ns/shacl#BlankNode" -%>
38
43
  <tr>
39
44
  <td colspan="4">
40
45
  <%- if property[:node_mode] == :or -%>
41
- ブランクノードの内容は以下のいずれかの内容からなる構造を持ちます。
46
+ <%=h t("shape-table.blank-node-or-structure") %>
42
47
  <%- property[:nodes].each do |e| -%>
43
48
  <div class="blank_node"><%= e.sub(/class="table"/, 'class="table table-condensed"') %></div>
44
49
  <%- end -%>
45
50
  <%- else -%>
46
- ブランクノードの内容は以下の構造を持ちます。
51
+ <%=h t("shape-table.blank-node-structure") %>
47
52
  <div class="blank_node"><%= property[:nodes].sub(/class="table"/, 'class="table table-condensed"') %></div>
48
53
  <%- end -%>
49
54
  </td>
@@ -1,16 +1,20 @@
1
- <dl>
2
- <% param[:data].each do |k, v| %>
3
- <dt><%=h format_property(k, param[:labels]) %></dt>
4
- <% if v.respond_to? :has_key? %>
5
- <% v.each do |lang, v2| %>
6
- <dd lang="<%=h lang %>"><%= format_object v2, param[:data] %></dd>
1
+ <dl class="row">
2
+ <%- param[:data].each do |k, v| -%>
3
+ <%- if param[:type] == :inverse -%>
4
+ <dt class="col-sm-3"><%=h t('triples.inverse_refered', property: format_property(k, param[:labels])) %></dt>
5
+ <%- else -%>
6
+ <dt class="col-sm-3"><%=h format_property(k, param[:labels]) %></dt>
7
+ <%- end -%>
8
+ <%- if v.respond_to? :has_key? -%>
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[:data] %></dd>
7
11
  <% end %>
8
- <% elsif v.size > 1 %>
9
- <% v.each do |v2| %>
10
- <dd><%= format_object v2, param[:data] %></dd>
11
- <% end %>
12
- <% else %>
13
- <dd><%= format_object v.first, param[:data] %></dd>
14
- <% end %>
12
+ <%- elsif v.size > 1 -%>
13
+ <%- v.each_with_index do |v2, idx| -%>
14
+ <dd class="col-sm-9<%= ' offset-sm-3' if idx > 0 %>"><%= format_object v2, param[:data] %></dd>
15
+ <%- end -%>
16
+ <%- else -%>
17
+ <dd class="col-sm-9"><%= format_object v.first, param[:data] %></dd>
18
+ <%- end -%>
15
19
  <%- end -%>
16
- </dl>
20
+ </dl>
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.0.0
4
+ version: 1.3.0
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-11-13 00:00:00.000000000 Z
11
+ date: 2021-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: i18n
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: ruby-progressbar
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -124,6 +138,8 @@ files:
124
138
  - lib/ttl2html/template.rb
125
139
  - lib/ttl2html/version.rb
126
140
  - lib/xlsx2shape.rb
141
+ - locales/en.yml
142
+ - locales/ja.yml
127
143
  - templates/about.html.erb
128
144
  - templates/default.html.erb
129
145
  - templates/index.html.erb