Skip to content

Commit 24d336c

Browse files
authored
Merge branch 'prezi-4' into p4-auto-arrays
2 parents bedf08a + 94c7b72 commit 24d336c

File tree

6 files changed

+502
-168
lines changed

6 files changed

+502
-168
lines changed

source/_includes/code_example.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% assign _title = include.title | default: 'Full JSON example' %}
2+
{% assign _target = include.target | default: "_blank" %}
3+
4+
<div class="code-example">
5+
<div class="code-example__header">
6+
<a href="example/{{ include.src }}" target="{{ _target }}">{{ _title }}</a></div>
7+
{% highlight json %}
8+
{% include_lines presentation/4.0/example/{{ include.src }} from:{{ include.from }} to:{{ include.to }} %}
9+
{% endhighlight %}
10+
</div>

source/_includes/links.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,92 @@
306306
[recipe-segment-image-part]: {{ site.api_url | absolute_url }}/cookbook/segment-image-part/ "Annotating part of an image to a canvas"
307307
[slack]: http://bit.ly/iiif-slack
308308
[web-arch]: http://www.w3.org/TR/webarch/ "Architecture of the World Wide Web"
309+
310+
311+
<!-- Link definitions for Presentation API 4.0 model references -->
312+
<!-- Generated by scripts/link_code_references.py -->
313+
314+
[prezi-40-model-Agent]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Agent
315+
[prezi-40-model-AmbientAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AmbientAudio
316+
[prezi-40-model-AnimationSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnimationSelector
317+
[prezi-40-model-Annotation]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Annotation
318+
[prezi-40-model-AnnotationCollection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnnotationCollection
319+
[prezi-40-model-AnnotationPage]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnnotationPage
320+
[prezi-40-model-Canvas]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Canvas
321+
[prezi-40-model-Choice]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Choice
322+
[prezi-40-model-Collection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Collection
323+
[prezi-40-model-FragmentSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#FragmentSelector
324+
[prezi-40-model-Manifest]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Manifest
325+
[prezi-40-model-OrthographicCamera]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#OrthographicCamera
326+
[prezi-40-model-PerspectiveCamera]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PerspectiveCamera
327+
[prezi-40-model-PointAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PointAudio
328+
[prezi-40-model-PointSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PointSelector
329+
[prezi-40-model-Range]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Range
330+
[prezi-40-model-RotateTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#RotateTransform
331+
[prezi-40-model-ScaleTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#ScaleTransform
332+
[prezi-40-model-Scene]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Scene
333+
[prezi-40-model-Service]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Service
334+
[prezi-40-model-SpecificResource]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpecificResource
335+
[prezi-40-model-SpotAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpotAudio
336+
[prezi-40-model-SpotLight]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpotLight
337+
[prezi-40-model-SvgSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SvgSelector
338+
[prezi-40-model-TextualBody]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#TextualBody
339+
[prezi-40-model-Timeline]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Timeline
340+
[prezi-40-model-TranslateTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#TranslateTransform
341+
[prezi-40-model-WktSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#WktSelector
342+
[prezi-40-model-accompanyingContainer]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#accompanyingContainer
343+
[prezi-40-model-action]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#action
344+
[prezi-40-model-angle]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#angle
345+
[prezi-40-model-annotations]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#annotations
346+
[prezi-40-model-backgroundColor]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#backgroundColor
347+
[prezi-40-model-behavior]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#behavior
348+
[prezi-40-model-body]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#body
349+
[prezi-40-model-color]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#color
350+
[prezi-40-model-duration]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#duration
351+
[prezi-40-model-exclude]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#exclude
352+
[prezi-40-model-far]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#far
353+
[prezi-40-model-fieldOfView]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#fieldOfView
354+
[prezi-40-model-format]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#format
355+
[prezi-40-model-height]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#height
356+
[prezi-40-model-homepage]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#homepage
357+
[prezi-40-model-id]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#id
358+
[prezi-40-model-instant]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#instant
359+
[prezi-40-model-intensity]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#intensity
360+
[prezi-40-model-interactionMode]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#interactionMode
361+
[prezi-40-model-items]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#items
362+
[prezi-40-model-label]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#label
363+
[prezi-40-model-language]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#language
364+
[prezi-40-model-lookAt]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#lookAt
365+
[prezi-40-model-metadata]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#metadata
366+
[prezi-40-model-motivation]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#motivation
367+
[prezi-40-model-navDate]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#navDate
368+
[prezi-40-model-navPlace]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#navPlace
369+
[prezi-40-model-near]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#near
370+
[prezi-40-model-placeholderContainer]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#placeholderContainer
371+
[prezi-40-model-position]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#position
372+
[prezi-40-model-profile]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#profile
373+
[prezi-40-model-provider]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#provider
374+
[prezi-40-model-provides]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#provides
375+
[prezi-40-model-refinedBy]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#refinedBy
376+
[prezi-40-model-rendering]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#rendering
377+
[prezi-40-model-requiredStatement]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#requiredStatement
378+
[prezi-40-model-rights]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#rights
379+
[prezi-40-model-service]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#service
380+
[prezi-40-model-source]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#source
381+
[prezi-40-model-spatialScale]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#spatialScale
382+
[prezi-40-model-start]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#start
383+
[prezi-40-model-structures]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#structures
384+
[prezi-40-model-summary]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#summary
385+
[prezi-40-model-supplementary]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#supplementary
386+
[prezi-40-model-target]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#target
387+
[prezi-40-model-temporalScale]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#temporalScale
388+
[prezi-40-model-thumbnail]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#thumbnail
389+
[prezi-40-model-timeMode]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#timeMode
390+
[prezi-40-model-transform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#transform
391+
[prezi-40-model-type]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#type
392+
[prezi-40-model-viewingDirection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#viewingDirection
393+
[prezi-40-model-volume]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#volume
394+
[prezi-40-model-width]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#width
395+
[prezi-40-model-x]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#x
396+
[prezi-40-model-y]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#y
397+
[prezi-40-model-z]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#z

source/_plugins/include_lines.rb

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
require 'liquid'
2+
3+
module Jekyll
4+
class IncludeLinesTag < Liquid::Tag
5+
def initialize(tag_name, markup, tokens)
6+
super
7+
@markup = markup.to_s.strip
8+
end
9+
10+
def render(context)
11+
site = context.registers[:site]
12+
source = site.source
13+
14+
rendered_markup = Liquid::Template.parse(@markup).render(context)
15+
path, options = parse_markup(rendered_markup)
16+
raise ArgumentError, "include_lines: missing file path" if path.nil? || path.empty?
17+
18+
from = integer_option(options, 'from')
19+
to = integer_option(options, 'to')
20+
start = integer_option(options, 'start')
21+
finish = integer_option(options, 'end')
22+
23+
from ||= start
24+
to ||= finish
25+
26+
format = true
27+
if options.key?('format')
28+
format = boolean_option(options, 'format')
29+
end
30+
indent = integer_option(options, 'indent')
31+
32+
unless from && to
33+
raise ArgumentError, "include_lines: must specify from/to (1-indexed), e.g. {% include_lines path from:11 to:35 %}"
34+
end
35+
36+
if from < 1 || to < 1
37+
raise ArgumentError, "include_lines: from/to must be >= 1 (got from:#{from} to:#{to})"
38+
end
39+
40+
if to < from
41+
raise ArgumentError, "include_lines: to must be >= from (got from:#{from} to:#{to})"
42+
end
43+
44+
absolute_path = File.expand_path(path, source)
45+
unless absolute_path.start_with?(File.expand_path(source) + File::SEPARATOR)
46+
raise ArgumentError, "include_lines: path must be within the site source directory"
47+
end
48+
49+
unless File.file?(absolute_path)
50+
raise ArgumentError, "include_lines: file not found: #{path}"
51+
end
52+
53+
lines = File.read(absolute_path, encoding: 'UTF-8').split("\n", -1)
54+
max_line = lines.length
55+
56+
if from > max_line
57+
raise ArgumentError, "include_lines: from (#{from}) is beyond end of file (#{max_line} lines): #{path}"
58+
end
59+
60+
to = [to, max_line].min
61+
62+
selected = lines[(from - 1)..(to - 1)]
63+
64+
if format
65+
selected = dedent_lines(selected)
66+
end
67+
68+
if indent && indent > 0
69+
prefix = ' ' * indent
70+
selected = selected.map { |l| l.strip.empty? ? l : (prefix + l) }
71+
end
72+
73+
selected.join("\n")
74+
rescue StandardError => e
75+
if defined?(Jekyll) && Jekyll.respond_to?(:logger) && Jekyll.logger
76+
Jekyll.logger.error("include_lines:", e.message)
77+
end
78+
raise
79+
end
80+
81+
private
82+
83+
def parse_markup(markup)
84+
tokens = markup.scan(/\"[^\"]+\"|\'[^\']+\'|\S+/)
85+
return [nil, {}] if tokens.empty?
86+
87+
path_token = tokens.shift
88+
path = unquote(path_token)
89+
90+
options = {}
91+
tokens.each do |t|
92+
key, value = t.split(':', 2)
93+
next if value.nil?
94+
options[key] = unquote(value)
95+
end
96+
97+
[path, options]
98+
end
99+
100+
def unquote(value)
101+
v = value.to_s
102+
if (v.start_with?('"') && v.end_with?('"')) || (v.start_with?("'") && v.end_with?("'"))
103+
v[1..-2]
104+
else
105+
v
106+
end
107+
end
108+
109+
def integer_option(options, key)
110+
return nil unless options.key?(key)
111+
Integer(options[key])
112+
rescue ArgumentError
113+
raise ArgumentError, "include_lines: #{key} must be an integer (got #{options[key].inspect})"
114+
end
115+
116+
def boolean_option(options, key)
117+
return nil unless options.key?(key)
118+
119+
v = options[key].to_s.strip.downcase
120+
return true if %w[1 true yes y on].include?(v)
121+
return false if %w[0 false no n off].include?(v)
122+
123+
raise ArgumentError, "include_lines: #{key} must be a boolean (got #{options[key].inspect})"
124+
end
125+
126+
def dedent_lines(lines)
127+
non_empty = lines.reject { |l| l.strip.empty? }
128+
return lines if non_empty.empty?
129+
130+
min_indent = non_empty.map { |l| l[/\A[ \t]*/].length }.min
131+
return lines if min_indent.nil? || min_indent.zero?
132+
133+
lines.map do |l|
134+
l.strip.empty? ? l : l[min_indent..]
135+
end
136+
end
137+
end
138+
end
139+
140+
Liquid::Template.register_tag('include_lines', Jekyll::IncludeLinesTag)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"@context": "http://iiif.io/api/presentation/4/context.json",
3+
"id": "https://iiif.io/api/presentation/4.0/example/02_timeline.json",
4+
"type": "Manifest",
5+
"label": {
6+
"en": [
7+
"Simplest Audio Example (IIIF Presentation v4)"
8+
]
9+
},
10+
"items": [
11+
{
12+
"id": "https://iiif.io/api/presentation/4.0/example/02",
13+
"type": "Timeline",
14+
"duration": 1985.024,
15+
"items": [
16+
{
17+
"id": "https://iiif.io/api/presentation/4.0/example/02/page",
18+
"type": "AnnotationPage",
19+
"items": [
20+
{
21+
"id": "https://iiif.io/api/presentation/4.0/example/02/page/anno",
22+
"type": "Annotation",
23+
"motivation": "painting",
24+
"body": {
25+
"id": "https://fixtures.iiif.io/audio/indiana/mahler-symphony-3/CD1/medium/128Kbps.mp4",
26+
"type": "Sound",
27+
"format": "audio/mp4",
28+
"duration": 1985.024
29+
},
30+
"target": "https://iiif.io/api/presentation/4.0/example/02"
31+
}
32+
]
33+
}
34+
]
35+
}
36+
]
37+
}

0 commit comments

Comments
 (0)