ttl2html 3.2.1 → 3.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba8e10380abeb01499c02f9d6f2eedc7ad6e36d876fbb71e457529c824fe1a11
4
- data.tar.gz: 1a774fb36a6b550f1d98106dd51439455c3f4ba5ccb34e0d89cbf905a9e7f481
3
+ metadata.gz: 6dd0b43f30e76da300f3b274bbb61c373971ee2ccdf39eb73260281f92ede9ab
4
+ data.tar.gz: 9495394ea8849bf3ee4b504db967e1617e39d1f6adab79693f8ebc6e5da372a9
5
5
  SHA512:
6
- metadata.gz: ce92faf8d3d04972844feb4e2f779bb672aadedfbe489b55d50952d34776e8d6b66798932640eeeaf15c385a0b09a7cedb98b5436b54a57dc740315d459a97cd
7
- data.tar.gz: 5bdc9429e03ed993030fb1030f9c1b52213feb726b9f49d572365f11f68b309bb9766f4978d085e7497bb50661231cb7d421efa6b18c090c31b4a7f7eefd9f2b
6
+ metadata.gz: 95fe91a4347194c0ef8ea2630617769984f2d6fc3cb94af663554b6d7321b3dc3f7748256c0c8fbf11efee903a01789a83ab73af55d2513689a2bb17239f7049
7
+ data.tar.gz: d03723dc65d280de442265ba848a7d84469daaffa32e584d5c84a6526684d82fb1aa6f6f5aa0685de236744e51868526baf77e00fd6709163140c222f102feb2
@@ -141,22 +141,23 @@ module TTL2HTML
141
141
  else
142
142
  dest.sub!(/^\/+/, "")
143
143
  #p [:relative_path, src, dest]
144
- if @param[:output_dir]
145
- src = Pathname.new(src).relative_path_from(Pathname.new(@param[:output_dir]))
146
- else
147
- src = Pathname.new(File.expand_path(src)).relative_path_from(Pathname.new(File.expand_path(".")))
148
- end
149
- path = Pathname(dest).relative_path_from(Pathname(File.dirname src))
150
- if @param[:output_dir] and File.directory?(File.join(@param[:output_dir], path))
151
- path = path.to_s + "/"
152
- elsif File.directory?(path)
153
- path = path.to_s + "/"
154
- end
144
+ # src is always passed as an absolute path.
145
+ base_dir = Pathname.pwd
146
+ base_dir = Pathname.new(@param[:output_dir]).expand_path if @param[:output_dir]
147
+ # src is always passed as an absolute path, but normalize it to remove
148
+ # any "." or ".." components before calling relative_path_from.
149
+ src_path = Pathname.new(src).expand_path
150
+ src_relative = src_path.relative_path_from(base_dir)
151
+ path = Pathname.new(dest).relative_path_from(src_relative.dirname)
152
+ path = "#{path}/" if base_dir.join(dest).cleanpath.directory?
155
153
  end
156
154
  #p [ :relative_path, path, dest, src ]
157
155
  path
158
156
  end
159
157
  def relative_path_uri(src, dest_uri, base_uri = @param[:base_uri])
158
+ # A relative link cannot be calculated without the source output file.
159
+ # Fall back to the original absolute URI.
160
+ return dest_uri unless src
160
161
  if dest_uri.start_with? base_uri
161
162
  dest = dest_uri.sub(base_uri, "")
162
163
  dest = uri_mapping_to_path(dest, @param, "")
@@ -1 +1 @@
1
- TTL2HTML::VERSION = "3.2.1"
1
+ TTL2HTML::VERSION = "3.2.2"
data/lib/ttl2html.rb CHANGED
@@ -78,33 +78,39 @@ module TTL2HTML
78
78
  SCHEMA_POSITION_URI_S = "https://schema.org/position"
79
79
  SHACL_ORDER_URI = "http://www.w3.org/ns/shacl#order"
80
80
  def sort_key_for_resource(resource)
81
+ @cache ||= {}
82
+ @cache[:sort_key_for_resource] ||= {}
83
+ resource_s = resource.to_s
84
+ return @cache[:sort_key_for_resource][resource_s] if @cache[:sort_key_for_resource].key?(resource_s)
85
+
81
86
  qb_order = Float::INFINITY
82
87
  schema_position = Float::INFINITY
83
88
  shacl_order = Float::INFINITY
84
- if @data[resource.to_s]
85
- qb_order = @data[resource.to_s][QB_ORDER_URI].first.to_i if @data[resource.to_s][QB_ORDER_URI]
86
- schema_position = @data[resource.to_s][SCHEMA_POSITION_URI].first.to_i if @data[resource.to_s][SCHEMA_POSITION_URI]
87
- schema_position = @data[resource.to_s][SCHEMA_POSITION_URI_S].first.to_i if @data[resource.to_s][SCHEMA_POSITION_URI_S]
88
- shacl_order = @data[resource.to_s][SHACL_ORDER_URI].first.to_i if @data[resource.to_s][SHACL_ORDER_URI]
89
- end
90
- if resource.to_s =~ /^_:/ and @data[resource.to_s]
91
- resource_str = "{" + @data[resource.to_s].sort_by do |p, o|
89
+ if @data[resource_s]
90
+ qb_order = @data[resource_s][QB_ORDER_URI].first.to_i if @data[resource_s][QB_ORDER_URI]
91
+ schema_position = @data[resource_s][SCHEMA_POSITION_URI].first.to_i if @data[resource_s][SCHEMA_POSITION_URI]
92
+ schema_position = @data[resource_s][SCHEMA_POSITION_URI_S].first.to_i if @data[resource_s][SCHEMA_POSITION_URI_S]
93
+ shacl_order = @data[resource_s][SHACL_ORDER_URI].first.to_i if @data[resource_s][SHACL_ORDER_URI]
94
+ end
95
+ value = if resource_s =~ /^_:/ and @data[resource_s]
96
+ resource_str = "{" + @data[resource_s].sort_by do |p, o|
92
97
  [p, o]
93
98
  end.join("\t") + "}"
94
99
  [ schema_position, qb_order, shacl_order, resource_str ]
95
100
  else
96
- [ schema_position, qb_order, shacl_order, resource.to_s ]
101
+ [ schema_position, qb_order, shacl_order, resource_s ]
97
102
  end
103
+ @cache[:sort_key_for_resource][resource_s] = value
98
104
  end
99
105
  def format_uri(uri, writer = RDF::Turtle::Writer.new(nil, prefixes: @prefix))
100
106
  result = writer.format_uri(RDF::URI(uri))
101
107
  if result =~ /^#{RDF::Turtle::Terminals::PN_PREFIX}?:/
102
108
  @used_prefixes << result.split(":").first
109
+ #STDERR.puts [uri, @used_prefixes].inspect
103
110
  end
104
111
  result
105
112
  end
106
- def format_turtle(subject, depth = 1, force = false)
107
- turtle_writer = RDF::Turtle::Writer.new(nil, prefixes: @prefix)
113
+ def format_turtle(subject, depth = 1, force = false, turtle_writer = RDF::Turtle::Writer.new(nil, prefixes: @prefix))
108
114
  result = ""
109
115
  #p [:format_turtle, subject, depth, force]
110
116
  return result if !force && @cache[:output_turtle_files].include?(subject)
@@ -114,14 +120,15 @@ module TTL2HTML
114
120
  result << format_uri(subject) << "\n#{" "*depth}"
115
121
  end
116
122
  result << @data[subject.to_s].keys.sort.map do |predicate|
117
- str = format_uri(predicate, turtle_writer) << " "
123
+ str = format_uri(predicate, turtle_writer).dup
124
+ str << " "
118
125
  #p [subject, predicate, @data[subject.to_s][predicate]]
119
126
  str << @data[subject.to_s][predicate].sort_by do |object|
120
127
  #p [subject, predicate, object, depth]
121
128
  sort_key_for_resource(object)
122
129
  end.map do |object|
123
130
  if /^_:/ =~ object.to_s # blank node:
124
- format_turtle(object, depth + 1, force)
131
+ format_turtle(object, depth + 1, force, turtle_writer)
125
132
  elsif RDF::URI::IRI =~ object.to_s
126
133
  format_uri(object, turtle_writer)
127
134
  else
@@ -204,9 +211,16 @@ module TTL2HTML
204
211
  end
205
212
  def find_inverse_roots(by_subject)
206
213
  all_subjects = by_subject.keys
207
- all_objects = by_subject.values.flat_map { |preds| preds.values.flatten }.uniq
214
+ all_object_ids = Set.new
215
+ by_subject.each_value do |predicates|
216
+ predicates.each_value do |objects|
217
+ objects.each do |object|
218
+ all_object_ids << object.to_s
219
+ end
220
+ end
221
+ end
208
222
  roots = all_subjects.reject do |subject|
209
- all_objects.include?(subject)
223
+ all_object_ids.include?(subject.to_s)
210
224
  end
211
225
  roots.sort_by { |subject| sort_key_for_resource(subject) }
212
226
  end
@@ -423,8 +437,8 @@ module TTL2HTML
423
437
  data = @data[uri]
424
438
  if @config[:breadcrumbs]
425
439
  if depth == 0
426
- first_label = template.get_title(data)
427
- first_label = data[@config[:breadcrumbs].first["label"]].first if @config[:breadcrumbs].first["label"] and data[@config[:breadcrumbs].first["label"]]
440
+ label_prop = @config[:breadcrumbs].first["label"]
441
+ first_label = breadcrumb_label(data, template, label_prop)
428
442
  results << { label: first_label }
429
443
  end
430
444
  @config[:breadcrumbs].each do |e|
@@ -461,14 +475,20 @@ module TTL2HTML
461
475
  end
462
476
  def build_breadcrumbs_sub(parent, template, label_prop = nil)
463
477
  data_parent = @data[parent]
464
- label = template.get_title(data_parent)
465
- label = data_parent[label_prop].first if label_prop and data_parent[label_prop]
466
478
  {
467
479
  uri: parent,
468
- label: label,
480
+ label: breadcrumb_label(data_parent, template, label_prop),
469
481
  }
470
482
  end
471
-
483
+ def breadcrumb_label(data, template, label_prop = nil)
484
+ default_label = template.get_title(data)
485
+ Array(label_prop).each do |property|
486
+ #p [property, data[property]]
487
+ values = data[property]
488
+ return values.first if values && !values.empty?
489
+ end
490
+ default_label
491
+ end
472
492
  def shapes_parse(shapes)
473
493
  shapes.each do |shape|
474
494
  target_class = @data[shape]["http://www.w3.org/ns/shacl#targetClass"]&.first
@@ -659,7 +679,8 @@ module TTL2HTML
659
679
  @cache ||= {}
660
680
  @cache[:output_turtle_files] = Set.new
661
681
  @used_prefixes = Set.new
662
- str = format_turtle(uri)
682
+ turtle_writer = RDF::Turtle::Writer.new(nil, prefixes: @prefix)
683
+ str = format_turtle(uri, 1, false, turtle_writer)
663
684
  str << format_turtle_inverse(uri)
664
685
  File.open(file, "w") do |io|
665
686
  @used_prefixes.each do |prefix|
@@ -77,7 +77,11 @@
77
77
  <ol class="breadcrumb">
78
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>
79
79
  <%- param[:breadcrumbs_items].reverse.each_with_index do |e, i| -%>
80
- <li class="breadcrumb-item<%= ' active' if i == param[:breadcrumbs_items].size-1 %>" aria-current="page">
80
+ <%- if i == param[:breadcrumbs_items].size-1 -%>
81
+ <li class="breadcrumb-item active" aria-current="page">
82
+ <%- else -%>
83
+ <li class="breadcrumb-item">
84
+ <%- end -%>
81
85
  <%- if e[:uri] -%>
82
86
  <a href="<%=h relative_path_uri(param[:output_file], e[:uri]) %>"><%=h e[:label] %></a>
83
87
  <%- else -%>
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.2.1
4
+ version: 3.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masao Takaku
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-05 00:00:00.000000000 Z
10
+ date: 2026-07-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: nokogiri