An open API service indexing awesome lists of open source software.

https://github.com/jptmoore/maniiifest

Typesafe IIIF presentation v3 parsing without external dependencies
https://github.com/jptmoore/maniiifest

iiif iiif-presentation-3 manifest parser

Last synced: 8 months ago
JSON representation

Typesafe IIIF presentation v3 parsing without external dependencies

Awesome Lists containing this project

README

          

# Maniiifest

## Description

Maniiifest provides methods to parse and manipulate [IIIF Presentation API 3.0](https://iiif.io/api/presentation/3.0/) specification and [W3C web annotations](https://www.w3.org/TR/annotation-model/). 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](https://raw.githubusercontent.com/jptmoore/maniiifest/main/src/specification.atd).

A typechecker/validator built using maniiifest is available online [here](https://maniiifest.onrender.com/).

## Installation

Install the package using npm:

```sh
npm install maniiifest --save-dev
```

## Usage

Import and use the functions in your TypeScript project:

```typescript
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:

```typescript
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

Documentation for the current supported get methods and generators available [here](https://jptmoore.github.io/maniiifest/classes/Maniiifest.html). If you would like to see other methods added please raise an issue.

## Tutorial

In this example we will use generators to work with a complex collection that nests manifests within it.

```typescript
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:

```sh
❯ 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.
```typescript
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](https://iiif.io/api/extension/georef/) extension.

```typescript
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](https://github.com/jptmoore/maniiitest).

## Scripts

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

## License

This project is licensed under the MIT License.