Introduction to IIIF
(The International Image Interoperability Framework)
Tiziana Mancinelli
Venice Centre for Digital and Public Humanities
AIMS OF THIS LABORATORY
- Introduction to IIIF and its advantages
- An overview of the three API
- Image API
- Presentation API
- Brief introduction on how to expose your image content through a IIIF-enabled image server and the many server options.
- viewers and clients to work with IIIF
- Open Sea Dragon and Mirador
Basic concepts
- What is IIIF?
- Why is this project very useful?
- What does IIIF do?
- How does IIIF work?
It stands for International Image Interoperability Framework
It is a model for presenting and annotating digital representations of objects
It is a set of application programming interfaces (APIs) based on open web standards and defined in specifications derived from shared real world use cases.
It is also a community that implements those APIs and specifications in software, both server and client. Additionally it exposes interoperable content!
What is IIIF?
What is IIIF?
The International Image Interoperability Framework is a set of shared application programming interface (API) specifications for interoperable functionality in digital image repositories.
WhY (are we all crazy about) IIIF?
IIIF has the following goals:
- To give scholars an unprecedented level of uniform and rich access to image-based resources hosted around the world.
- To define a set of common application programming interfaces that support interoperability between image repositories.
- To develop, cultivate and document shared technologies, such as image servers and web clients, that provide a world-class user experience in viewing, comparing, manipulating and annotating images
WhY (are we all crazy about) IIIF?
Many libraries, archives, organizations, and museums store and provide access to images. Images transmit scholarship, culture, and understanding. There are a lot of great reasons to adopt IIIF, first and foremost, you don't need to keep solving common problems
WhY (are we all crazy about) IIIF?
We have done a really good job digitising our cultural heritage and put it online.
However, images are:
- different formats
- disjointed
- slow
- locked up
- and it is expensive and requires lots of space
- I am locked into my image delivery software
- I need a newer, faster image server
- I want deep zoom
- I want to allow users to visually compare objects in the collection
- I want to make it easy for my users to cite and share my images
- I want to allow visitors to annotate my images online
- I want to allow embedding of my images in blogs and web pages
These things should not have to be invented each time.
WhY (are we all crazy about) IIIF?
WhY (are we all crazy about) IIIF?
Otherwise it would be a word of silos and dupliation
What does iiiF do?
Why (are we all crazy for) IIIF?
IIIF frees up your images to be creatively reused. Because scaling, cropping and zooming become trivial operations, you’re free to concentrate on the important task of providing a great user experience.
You also benefit from great image viewing software written and maintained by other people, so no need to reinvent the wheel.
Why (are we all crazy for) IIIF?
Using JSON-LD, linked data, and standard W3C web protocols such as Web Annotation, IIIF makes it easy to parse and share digital image data, migrate across technology systems, and provide enhanced image access for scholars and researchers. In short, IIIF enables better, faster and cheaper image delivery.
What does iiiF do?
What does iiiF do?
- High-resolution images
- Large scale images
- Cite and share but also share a region of that
- Images can be delivered straightforwardly through IIIFs:
- Compare images and also across istitutions
HOW DOES III HELP?
- It defines metadata standards for dealing with high-resolution images
- providing a consistent API for accessing images
- the metadata that surrounds them and how to present and associate images together.
IIIF Specifications
The IIIF technical specifications are the glue that holds things together for image interoperability.
IIIF provides two core APIs:
- Image API (I want to get image pixels)
- Presentation API (I want to display the images)
There are several more APIs that IIIF supports including Search and Authentication. This workshop will focus on the Image and Presentation APIs.
Our first API:
IMAGE API
The Image API provides for a standardized way to request and deliver images. This can be as simple as, give me the original image to give me an upside down tiled version of the image in gif format. The IIIF Image API is restful and allows for images to be served dynamically or from a static cache (implementation details).
https://iiif.io/api/image/2.1/compliance/#status-of-this-document
IMAGE API
Images are requested using URI templates that have the following
syntax:
https://example.org/{id}/{region}/{size}/{rotation}/{quality}.{fmt}
https://example.org/{id}/info.json
International Image Interoperability Framework
This solution allows a client to "point" to an image available on the Web by requesting, at the same time, the supply of the same by the server with specific formal parameters explicitly expressed in the formulation of the same URI according to this syntax:
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
The first API developed within the IIIF project concerns the identification of an image and its specifications through a URI conveyed through the HTTP or HTTPS protocols.
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://stacks.stanford.edu/image/iiif/hd288rd1737%252F0090_496-34/full/full/0/default.jpg
https:// | {scheme}:// |
---|---|
stacks.stanford.edu/ | {server} |
image/iiif/ | {/prefix}/ |
hd288rd1737%252F0090_496-34/ | {identifier}/ |
full/ | {region}/ |
full/ | {size}/ |
0/ | {rotation}/ |
default | {quality} |
.jpg | .{format} |
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
https:// | {scheme}:// |
---|---|
images.lib.cam.ac.uk | {server} |
/iiif/ | {/prefix}/ |
MS-ORCS-00001-00002-000-00001.jp2 | {identifier}/ |
full/ | {region}/ |
full/ | {size}/ |
0/ | {rotation}/ |
default | {quality} |
.jpg | .{format} |
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
https:// | {scheme}:// |
---|---|
images.lib.cam.ac.uk | {server} |
/iiif/ | {/prefix}/ |
MS-ORCS-00001-00002-000-00001.jp2 | {identifier}/ |
full/ | {region}/ |
full/ | {size}/ |
0/ | {rotation}/ |
default | {quality} |
.jpg | .{format} |
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
https:// | {scheme}:// |
---|---|
images.lib.cam.ac.uk | {server} |
/iiif/ | {/prefix}/ |
MS-ORCS-00001-00002-000-00001.jp2 | {identifier}/ |
full/ | {region}/ |
full/ | {size}/ |
0/ | {rotation}/ |
default | {quality} |
.jpg | .{format} |
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
https:// | {scheme}:// |
---|---|
images.lib.cam.ac.uk | {server} |
/iiif/ | {/prefix}/ |
MS-ORCS-00001-00002-000-00001.jp2 | {identifier}/ |
full/ | {region}/ |
full/ | {size}/ |
0/ | {rotation}/ |
default | {quality} |
.jpg | .{format} |
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
INFO.JSON
JSON-LD
JSON-LD is a lightweight Linked Data format. It is easy for humans to read and write. It is based on the already successful JSON format and provides a way to help JSON data interoperate at Web-scale. JSON-LD is an ideal data format for programming environments, REST Web services, and unstructured databases such as CouchDB and MongoDB.
INFO.JSON
{
"@context" : "http://iiif.io/api/image/2/context.json",
"@id" : "http://iiif.thembi.me/10r/",
"protocol" : "http://iiif.io/api/image",
"width" : 1944,
"height" : 2592,
"sizes" : [
{ "width" : 121, "height" : 162 },
{ "width" : 243, "height" : 324 },
{ "width" : 486, "height" : 648 }
],
"tiles" : [
{ "width" : 256, "height" : 256, "scaleFactors" : [ 1, 2, 4, 8, 16 ] }
],
"profile" : [
"http://iiif.io/api/image/2/level1.json",
{ "formats" : [ "jpg" ],
"qualities" : [ "native","color","gray" ],
"supports" : ["regionByPct","regionSquare","sizeByForcedWh","sizeByWh","sizeAboveFull","rotationBy90s","mirroring"] }
]
Exercise:
From this image:
https://images.lib.cam.ac.uk/iiif/MS-ORCS-00001-00002-000-00001.jp2/full/full/0/default.jpg
- https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.lib.harvard.edu/ids/iiif/25286607
https://iiif.bodleian.ox.ac.uk/iiif/image/5359a811-63e4-49d7-8cc1-e6b4308a7969
IIIF Presentation API 2.1.1
The primary requirements for the Presentation API are to provide an order for these views, the resources needed to display a representation of the view, and the descriptive information needed to allow the user to understand what is being seen.
The principles of Linked Data and the Architecture of the Web are adopted in order to provide a distributed and interoperable system. The Shared Canvas data model and JSON-LD are leveraged to create an easy-to-implement, JSON-based format.
Why a Presentation API?
http://iiif.io/api/presentation/2.1/#introduction
- Many images for one object
- book
- painting photograph and x-ray
- Human presentation
- Navigation and ordering
- Display of metadata
- Links to related resources
- Platform for annotation
- Embedding resources in blogs and other web pages
Shared Canvas
http://iiif.io/model/shared-canvas/1.0/
A canvas is a coordinate space on which images can be painted. Images are painted onto a canvas through annotation. In the simple case we're only painting a single image annotation so that it fills the whole canvas.
We call it a shared canvas because it allows for painting multiple images onto the same canvas as well as overlaying additional annotations.
Shared Canvas
http://iiif.io/model/shared-canvas/1.0/
Think of a canvas as an empty presentation slide. You can put a page image on the canvas via annotation:
Shared Canvas
http://iiif.io/model/shared-canvas/1.0/
Once you have a base image painted onto the canvas you can then apply further annotations like transcriptions, translations, scholarly commentary.
IIIF Presentation API 2.1.1
/info.json
Where is in the image you have just worked with?
The presentation API links the info.json
Just add: info.json
The objective of the IIIF Presentation API is to provide the information necessary to allow a rich, online viewing environment for primarily image-based objects to be presented to a human user [...]. (Yu 2011, 467).
This is the sole purpose of the API and therefore the descriptive information is given in a way that is intended for humans to read, but not semantically available to machines (Yu 2011, 467).
[... It] explicitly does not aim to provide metadata that would drive discovery of the digitized objects reated for a specific development domain and normally contains a set of common and reusable building blocks so that developers can use, extend, or customize for their specific business logic (Yu 2011, 467)
Let's have some fun with the Manifest
Manifest
The overall description of the structure and properties of the digital representation of an object. It carries information needed for the viewer to present the digitized content to the user, such as a title and other descriptive information about the object or the intellectual work that it conveys. Each manifest describes how to present a single object such as a book, a photograph, or a statue.
Let's have some fun with the Manifest
Sequence
The order of the views of the object. Multiple sequences are allowed to cover situations when there are multiple equally valid orders through the content, such as when a manuscript’s pages are rebound or archival collections are reordered.
Let's have some fun with the Manifest
Canvas
A virtual container that represents a page or view and has content resources associated with it or with parts of it. The canvas provides a frame of reference for the layout of the content. The concept of a canvas is borrowed from standards like PDF and HTML, or applications like Photoshop and Powerpoint, where the display starts from a blank canvas and images, text and other resources are “painted” on to it.
Content
Content resources such as images or texts that are associated with a canvas.
What is a manifest?
Essentially, a manifest is just a JSON-LD file that consists of several main sections, most of which are optional depending on your use-case.
1.2. Terminology This specification uses the following terms:
- embedded: When a resource (A) is embedded within an embedding resource (B), the complete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will not result in additional information. Example: Canvas A is embedded in Manifest B.
- referenced: When a resource (A) is referenced from a referencing resource (B), an incomplete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will result in additional information. Example: Manifest A is referenced from Collection B.
- HTTP(S): The HTTP or HTTPS URI scheme and internet protocol.
Text
Creating a Basic Manifest
In this section we'll create a manifest by hand step by step.
In most cases in production you won't actually be creating manifests by hand. You will probably have different systems and workflows from other institutions so will need to determine the best way for you to create manifests.
Creating a Basic Manifest
- Identifier @id
- Basic Description
- Sequence
- Canvas
- Image Annotation
- Image Service
- Metadata
- License
Creating a Basic Manifest
Web server for Chrome
- Install the Chrome browser if you don't already have it: https://www.google.com/chrome/
- Download and install the Web Server for Chrome Plugin
- Create a directory somewhere convenient (e.g., on your desktop) to store your manifests in
- Turn the server on using the slider control.
- In the server's control panel, click "CHOOSE FOLDER" and select the directory you just created
- Click "Show Advanced Options" and check "Set CORS headers"
-
Navigate to the editor. If any of your info.json URLs begin with HTTP, use the HTTP version. See the Note on Mixed Content section at the bottom of this page for more information.
- HTTP version at text and bytes
- HTTPS version at the Bodleian
-
Add at least two Canvases to your Manifest. The option to add a Canvas is below the main image preview, to the left.
- Click the "Canvas Metadata" expander in the right-hand column.
- Click "Add an Image". Choose the option to supply the info.json URL and enter the URL for your first image
- Edit the Canvas Label and provide an appropriate label for your immage
- Repeat these steps to add additional Canvases and images as desired
Use the Bodleian Manifest
Editor to create a manifest
- Click the "Manifest Metadata" header in the right-hand column. Edit the Label. Supply a label for your manifest.
- Click "Save Manifest" at the top of the right hand column. Click "Donwload Manifest" in the dialog box.
Use the Bodleian Manifest
Editor to create a manifest
- Copy the Manifest to the Web Server Folder
- Review the Manifest
-
View the Manifest JSON at http://127.0.0.1:8887/manifest.json in your browser:
- Find Manifest label
- Explore the Manifest structure:
- Sequence
- Canvas
- @id
- label
- Annotation
- IIIF Image API service
- Canvas
- Sequence
-
Use the Bodleian Manifest
Editor to create a manifest
-
- Scroll down to "View a IIIF Manifest".
- Paste the URL http://127.0.0.1:8887/manifest.json into the text box and click "View".
- You should see your manifest in the Universal Viewer.
- Navigate to the Universal Viewer web page.
-
Copy the downloaded Manifest to the folder you created when setting up the Web Server for Chrome. Name the file manifest.json
View the Manifest JSON
Visit the URL http://127.0.0.1:8887/manifest.json You should see the Manifest's JSON.
Use the Bodleian Manifest
Editor to create a manifest
There are some important elements of the Manifest that we did not add or edit using theonline editor. The goal of this exercise will be to edit or add them manually. Each task is linked to the specification for the property that you will need to edit or add to the Manifest.
- Provide a short description of this manifest -- the content is up to you.
- Modify the attribution to the manifest that names the source of the images
- Add the viewingHint to indicate that the item is paged (i.e., should display in two-up book reader mode)
- Assert a Creative Commons 4.0 by-nc-sa license.
- Add properties to the metadata following the pattern described in Language of Property Values.
Edit Your Manifest
There are some important elements of the Manifest that we did not add or edit using theonline editor. The goal of this exercise will be to edit or add them manually. Each task is linked to the specification for the property that you will need to edit or add to the Manifest.
- Provide a short description of this manifest -- the content is up to you.
- Modify the attribution to the manifest that names the source of the images
- Add the viewingHint to indicate that the item is paged (i.e., should display in two-up book reader mode)
- Assert a Creative Commons 4.0 by-nc-sa license.
- Add properties to the metadata following the pattern described in Language of Property Values.
Edit Your Manifest
It is possible to provide information about the structure of the content within the Manifest. For instance, you might want to group Canvases depicting pages of a book by chapter, or of a play by act and scene. The Range is the Presentation API mechanism for describing this type of structure. In this exercise we will add Range-based navigation to your Manifest.
ADD STRUCTURE
Gather Canvas Identifiers
Find the @id of each Canvas you created in your Manifest. Your structural mapping will reference the Canvases by their @ids.
- Copy the JSON below into your Manifest (manifest.json)
- Replace $YOUR_CANVAS_ID with the @id of your first Canvas
- Save the file
Create the Structures
"structures": [
{
"@id": "http://example.org/iiif/book1/range/r0",
"@type": "sc:Range",
"label": "Table of Contents",
"members": [
{
"@id": "http://example.org/iiif/book1/range/r1",
"@type": "sc:Range",
"label": "Introduction"
}
]
},
{
"@id": "http://example.org/iiif/book1/range/r1",
"@type": "sc:Range",
"label": "Introduction",
"canvases": ["$YOUR_CANVAS_ID"]
}
]
International Image Interoperability Framework
At this point, the parameters expressly defined by IIIF for the supply of images come into play, which must be listed in the order required
The parameters of the Image Request URI include region, size, rotation, quality and format, which define the characteristics of the returned image. These are described in detail in Image Request Parameters
{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
IIIF Clients
Openseadragon
It is a viewer that supports only API Image
Openseadragon
Download from my GitHub:
https://github.com/tmancinelli/digitaltext2022
Openseadragon
API documentation: https://openseadragon.github.io/docs/
Openseadragon
List of some Libraries
Openseadragon
Exercise
Take one of them - go to the manifest and get an URL of an image and paste it on the index.html
Openseadragon
Rotation
Take one of them - go to the manifest and get an URL of an image and paste it on the index.html
Can you add the rotation?
degrees: 90, showRotationControl: true,
MIRADOR
Mirador home page: http://projectmirador.org/
Open the Mirador site and click on the "try a live demo" button.
You'll see some sample content. Click the "x" to close one of the windows. Click the upper-lefthand dropdown to "Replace Object".
MIRADOR
Download the file on my GitHub:
https://github.com/tmancinelli/tutorial_Bologna_2020/tree/master/mirador1
MIRADOR
Expose this file through a local web server
python -m SimpleHTTPServer 8000
Or
python -m http.server [<portNo>]
MIRADOR
Exercise
- Change the image, adding your manifest.json
IIIF & TEI
AIMS of this last laboratory
- Going to sort some problems out
- Mirador
- Finish the Xquery exercise
- Include OpenSeaDragon on our XSLT (and if we have time Mirador too)
- Include Mirador on our XSLT (let's skip the XQUERY)
IIIF & TEI
On our Frankstein XML:
<facsimile>
<graphic xml:id="p21r"
url="https://iiif.bodleian.ox.ac.uk/iiif/image/5359a811-63e4-49d7-8cc1-e6b4308a7969/full/full/0/default.jpg">
</facsimile>
How can we use the manifest?
Let's going to see Paolo Monella's example:
http://www1.unipa.it/paolo.monella/romualdus/xml/chronicon.xml
How can we use the manifest?
- the first approach consists in linking to the digital images of the manuscript from within the TEI XML source, for example with the TEI attribute @facs;
- with the second approach, the whole TEI XML transcription is included in the IIIF metadata as an "Annotation".
Paolo Monella (http://www1.unipa.it/paolo.monella/reires2019/)
How can we use the manifest?
Perhaps on the MsDesc?
https://tei-c.org/release/doc/tei-p5-doc/en/html/ref-msDesc.html
How can we use the manifest?
OpenSeaDragon:
<graphic xml:id="p21r" url="https:canvas"></graphic>
</facsimile>
Mirador:
<facsimile facs="manifest.json">
<graphic xml:id="p21r" url="https:canvas"></graphic>
</facsimile>
How can we use the manifest?
Let's make our Frankenstein better
Let's make our Frankenstein better
Do you remember your XSLT?
Let's get it back!
Let's make our Frankenstein better
Let's also get our OpenSeaDragon file.
How can we put them together?
1. Let's look at the value of the URL attribute. Is that right?
Let's make our Frankenstein better
1. Let's look at the value of the URL attribute. Is that right?
Go to the manifest: https://iiif.bodleian.ox.ac.uk/iiif/manifest/53fd0f29-d482-46e1-aa9d-37829b49987d.json
Let'sgo back to Xquery
1. download the file:
https://github.com/tmancinelli/tutorial_Bologna_2020/tree/master/xquery/exercise1
Let'sgo back to Xquery
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
Let'sgo back to Xquery functions!
(: Yeah! :)
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
If you cannot find the XQuery function you need, you can write your own.
Let'sgo back to Xquery functions!
(: Yeah! :)
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
- Use the declare function keyword
- The name of the function must be prefixed
- The data type of the parameters are mostly the same as the data types defined in XML Schema
- The body of the function must be surrounded by curly braces
Let'sgo back to Xquery functions!
(: Yeah! :)
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
- Use the declare function keyword
- The name of the function must be prefixed local:
Let'sgo back to Xquery functions!
(: Yeah! :)
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
- The data type of the parameters are mostly the same as the datatypes defined in XML Schema
- Each variable (anyone) has a type (doesn't matter which one). In some languages, you can reassign the variable and you can change the datatype. In Python, for instance, you can set a variable as a string and then you can reassign as interger
Let'sgo back to Xquery functions!
An example with Python:
a = 123
type(a) # this will print 'int'
a = "hello world"
type(a) # this will print 'str'
An example with Javascript:
let a = 123;
console.log(typeof a); // this will show 'number'
a = "hello world";
console.log(typeof a); // this will show 'string'
Let'sgo back to Xquery functions!
declare function prefix:function_name($parameter as datatype) as returnDatatype
{
...function code here...
};
If a variable is a string you cannot set as interger and viceversa.
- Xquery supports type definition in functions.
- All of this is OPTIONAL!
- If you do n't want to specifies as type, Xquery will do this work for you.
Why is it better to define a type?
1. To write better your code
2. make it understandable for the other will read it
Let'sgo back to Xquery functions!
declare function local:sumvalues($a as xs:integer, $b as xs:integer) as xs:integer {
let $sum := $a + $b
return $sum
};
let $foo := local:sumvalues(1, 2)
return $foo
The return datatype means:
what the function return value is in that datatype
Just to make it clear once again:
declare function local:maybeSumValues($a as xs:integer, $b as xs:integer) as xs:integer {
let $sum := $a + $b
return if ($sum > 10)
then -1
else $sum
};
let $foo := local:maybeSumValues(1, 2)
return $foo
Let's enjoy coding!
declare function local:countHands($node as node()) {
count($node//*[@hand])
};
let $root := doc("Frankenstein-v1c5-transcription.xml")
return <p>Corrections: {local:countHands($root)}</p>
Let's enjoy coding!
declare function local:showMyType($a) {
typeswitch ($a)
case xs:string
return "This is a STRING!"
case xs:integer
return "This is a NUMBER!"
default
return "I don't know"
};
let $foo := local:showMyType("hi")
return $foo
Let's enjoy coding!
Exercise:
- Let's read the xquery
- Make the function for <p>
- add the typeswitch
- Recall it in the HTML tag
Let's enjoy coding!
Exercise:
- Let's read the xquery
- Make the function for <p>
declare function local:applyTemplateP($nodes as node()*) as node()* {
for $node in $nodes
return
<p>{local:applyTemplates($node/node())}</p>
};
Let's enjoy coding!
Exercise:
3. add the typeswitch
case element(tei:p)
return local:applyTemplateP($node)
Let's enjoy coding!
Exercise:
4. Recall it in the HTML tag
let $teiP := $root//tei:div//tei:p
return local:applyTemplateP($teiP)
Let's enjoy coding!
Exercise 2
1. Make a function to transform <lb> to <br/>
Let's enjoy coding!
You can download the entire Xquery script!
Exercise 3 and add it OpenSeaDragon
mirador
Let's work with your XSLT:
1. Add this script:
<script src="https://unpkg.com/mirador@beta/dist/mirador.min.js"></script>
Where?
mirador
2. Add the manifest in your TEI:
<facsimile facs="https://iiif.bodleian.ox.ac.uk/iiif/manifest/53fd0f29-d482-46e1-aa9d-37829b49987d.json">
<graphic xml:id="p21r" url="https://iiif.bodleian.ox.ac.uk/iiif/canvas/ac06667a-e105-4781-ad5d-209cad1c2ba8.json"></graphic>
</facsimile>
mirador
3. Add a bit of javacript to run Mirador
[...]
<div id="mirador" style="width: 400px; height: 600px;"></div>
<script type="text/javascript">
var mirador = Mirador.viewer({
"id": "mirador",
"windows": [
{
"manifestId": "<xsl:value-of select="//tei:facsimile/@facs"/>",
"canvasId": "<xsl:value-of select="//tei:facsimile/tei:graphic/@url"/>",
"thumbnailNavigationPosition": 'far-bottom'
}
]
});
</script>
[...]
tiziana.mancinelli@unive.it
@tizmancinelli
IIIF / Bologna 2020
By Tiziana Mancinelli
IIIF / Bologna 2020
- 563