Maniiifest provides methods to parse and manipulate IIIF Presentation API 3.0 specification and W3C web annotations. It ensures type safety and offers utility functions for working with IIIF data. Maniiifest takes a parser generator approach to generating TypeScript type definitions using a domain-specific language (DSL). The current specification is available here.
A typechecker/validator built using maniiifest is available online here.
Install the package using npm:
npm install maniiifest --save-dev
Import and use the functions in your TypeScript project:
import { Maniiifest } from 'maniiifest';
const manifest = {
"id": "https://iiif.io/api/cookbook/recipe/0032-collection/manifest-02.json",
"type": "Manifest",
"label": { "en": ["Northeaster"] }
}
const parser = new Maniiifest(manifest);
const label = parser.getManifestLabelByLanguage('en');
console.log(label?.['en']);
To parse web annotations you need to provide the type of annotation to the constructor. For example:
const annotationParser = new Maniiifest(annotation, "Annotation");
const annotationPageParser = new Maniiifest(annotation_page, "AnnotationPage");
const annotationCollectionParser = new Maniiifest(annotation_collection, "AnnotationCollection");
The aim is to support the most relevant subset of the W3C standard as used within IIIF manifests.
Documentation for the current supported get methods and generators available here. If you would like to see other methods added please raise an issue.
In this example we will use generators to work with a complex collection that nests manifests within it.
import { Maniiifest } from 'maniiifest';
async function main() {
const response = await fetch('https://iiif.wellcomecollection.org/presentation/b19974760');
const jsonData = await response.json();
const parser = new Maniiifest(jsonData);
const manifests = parser.iterateCollectionManifest();
let count = 0;
for (const item of manifests) {
if (count >= 25) break;
const manifestRef = new Maniiifest(item);
const metadata = manifestRef.iterateManifestMetadata();
for (const item of metadata) {
console.log(item);
}
count++;
}
}
main()
The output will be the metadata from the first 25 manifests:
❯ ts-node tutorial.ts
{ label: { en: [ 'Volume' ] }, value: { none: [ '1' ] } }
{ label: { en: [ 'Year' ] }, value: { none: [ '1859' ] } }
{ label: { en: [ 'Month' ] }, value: { en: [ 'September' ] } }
{
label: { en: [ 'DisplayDate' ] },
value: { en: [ '15. September 1859' ] }
}
{ label: { en: [ 'Volume' ] }, value: { none: [ '1' ] } }
{ label: { en: [ 'Year' ] }, value: { none: [ '1859' ] } }
{ label: { en: [ 'Month' ] }, value: { en: [ 'October' ] } }
.....
In this example we will work with externally referenced W3C annotations.
import { Maniiifest } from 'maniiifest';
async function main() {
const response = await fetch('https://iiif.io/api/cookbook/recipe/0269-embedded-or-referenced-annotations/manifest.json');
const jsonData = await response.json();
const parser = new Maniiifest(jsonData);
const annotationPages = parser.iterateManifestCanvasW3cAnnotationPage();
for (const annotationPage of annotationPages) {
const response = await fetch(annotationPage.id);
const jsonData = await response.json();
const parser = new Maniiifest(jsonData, "AnnotationPage");
const annotations = parser.iterateAnnotationPageAnnotation();
for (const annotation of annotations) {
console.log(annotation.body?.value);
}
}
}
main()
The output will the commenting value from the single annotation:
Göttinger Marktplatz mit Gänseliesel Brunnen
In this example we will work with an annotation that uses the georeference extension.
import { Maniiifest } from 'maniiifest';
async function main() {
const response = await fetch('https://annotations.allmaps.org/maps/cde9210870a2652a');
const jsonData = await response.json();
const annotation = new Maniiifest(jsonData, "Annotation");
const points = Array.from(annotation.iterateAnnotationGeometryPointCoordinates());
for (let i = 0; i < points.length; i += 2) {
console.log(`x: ${points[i]}, y: ${points[i + 1]}`);
}
}
main()
The output will be all the point coordinates:
x: -70.9375518, y: 42.4811769
x: -70.9398138, y: 42.4825027
x: -70.9403993, y: 42.4821228
x: -70.9434097, y: 42.480079
x: -70.9373183, y: 42.4793787
x: -70.9454651, y: 42.4765122
x: -70.9364491, y: 42.4804618
x: -70.9377961, y: 42.4788144
x: -70.935966, y: 42.4809988
x: -70.9390062, y: 42.4772977
x: -70.9398389, y: 42.4815905
x: -70.9369067, y: 42.4798999
More examples of parsing complex manifests and collections can be found here.
npm run build
: Compile the TypeScript code.npm run test
: Run the tests using Jest.npm start
: Run the example script.npm run generate-docs
: Generate documentation using TypeDoc.
This project is licensed under the MIT License.