UNPKG

maniiifest

Version:

Typesafe IIIF presentation v3 manifest and collection parsing without external dependencies

163 lines (129 loc) 5.61 kB
# 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.