Introduction to IIIF

(The International Image Interoperability Framework)

 

 

Tiziana Mancinelli

 

Venice Centre for Digital and Public Humanities

AIMS OF THIS LABORATORY

 

  1.  Introduction to IIIF and its advantages
  2. An overview of the three API
    • Image API
    • Presentation API
  3. Brief introduction on how to expose your image content through a IIIF-enabled image server and the many server options.
  4. viewers and clients to work with IIIF
  5. 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?

 

Let's have a look at this collection:

 

https://cudl.lib.cam.ac.uk/collections/rcs150

In case, you can also download:

 

https://github.com/2SC1815J/open-in-iiif-viewer

 

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.

Complete list of specifications

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

 

  1. Select with pct the text on the right side
  2. Rotate the image so as to read the text in the right way

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

 

  1. Install the Chrome browser if you don't already have it: https://www.google.com/chrome/
  2. Download and install the Web Server for Chrome Plugin
  3. Create a directory somewhere convenient (e.g., on your desktop) to store your manifests in
  4. Turn the server on using the slider control.
  5. In the server's control panel, click "CHOOSE FOLDER" and select the directory you just created
  6. Click "Show Advanced Options" and check "Set CORS headers"

 

 

 

 

 

 

 

  1. 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.

  2. 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

  1. Click the "Manifest Metadata" header in the right-hand column. Edit the Label. Supply a label for your manifest.
  2. 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

  1. Copy the Manifest to the Web Server Folder
  2. 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

Use the Bodleian Manifest

Editor to create a manifest

  1. 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.

  1. Provide a short description of this manifest -- the content is up to you.
  2. Modify the attribution to the manifest that names the source of the images
  3. Add the viewingHint to indicate that the item is paged (i.e., should display in two-up book reader mode)
  4. Assert a Creative Commons 4.0 by-nc-sa license.
  5. 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.

  1. Provide a short description of this manifest -- the content is up to you.
  2. Modify the attribution to the manifest that names the source of the images
  3. Add the viewingHint to indicate that the item is paged (i.e., should display in two-up book reader mode)
  4. Assert a Creative Commons 4.0 by-nc-sa license.
  5. 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.

 

  1.     Copy the JSON below into your Manifest (manifest.json)
  2.     Replace $YOUR_CANVAS_ID with the @id of your first Canvas
  3.    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

Openseadragon

Openseadragon

List of some Libraries

Biblissima

Cambridge Library

Vaticana

Europeana

 

Openseadragon

Exercise

Biblissima

Cambridge Library

Vaticana

Europeana

  

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

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
  1.  Mirador
  2.  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?

  1. 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;
  2. 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?

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

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:

  1. Let's read the xquery
  2. Make the function for <p>
  3. add the typeswitch
  4. Recall it in the HTML tag

Let's enjoy coding!

 

 

 

Exercise:

  1. Let's read the xquery
  2. Make the function for <p>
1
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

1
case element(tei:p)
      return local:applyTemplateP($node)

Let's enjoy coding!

 

 

 

Exercise:

4. Recall it in the HTML tag

1
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/>

 

1

Let's enjoy coding!

 

 

 

You can download the entire Xquery script!

Exercise 3 and add it OpenSeaDragon

 

 

1

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

By Tiziana Mancinelli