はじめに

IIIF(International Image Interoperability Framework)を利用したデジタルアーカイブでは、複数巻や複数章で構成される資料を1つのManifestにまとめることがあります。このような場合、各巻・各章の冒頭ページへのリンクを作成したいというニーズがあります。

今回、IIIF Manifestから各巻(range/structure)のlabel最初のCanvas URL を抽出するシンプルなWebツールを作成しました。

ツールURL : https://nakamura196.github.io/iiif-manifest-extractor/

GitHub : https://github.com/nakamura196/iiif-manifest-extractor

機能

  • 複数のManifest URLを一括処理(1行に1つのURL)
  • 各巻・各章のlabelと最初のCanvas URLを一覧表示
  • CSV/JSON形式でのエクスポート
  • 処理進捗のリアルタイム表示

使い方

  1. ツールを開く
  2. Manifest URLをテキストエリアに入力(複数行可)
  3. 「抽出」ボタンをクリック
  4. 結果が表形式で表示される
  5. 必要に応じてCSV/JSONでダウンロード

サンプル

以下のManifest URLで動作を確認できます。複数URLを入力することで、一括処理の動作も確認できます。

国立国会図書館デジタルコレクション「校異源氏物語」:

https://dl.ndl.go.jp/api/iiif/3437686/manifest.json
https://dl.ndl.go.jp/api/iiif/3437687/manifest.json

これらのManifestは源氏物語の各帖(きりつほ、ははきゝ、うつせみ、わかむらさき…など)がstructuresに定義されており、各帖の冒頭ページを抽出できます。

2つのManifest URLを入力することで、複数のManifestを一括で処理し、結果をまとめてCSV出力できることを確認できます。

技術的な仕組み

IIIF Presentation API v2のstructures

IIIF Presentation API v2では、structuresプロパティを使って論理的な構造(目次)を定義できます。

{
  "structures": [
    {
      "@type": "sc:Range",
      "label": "目次",
      "ranges": ["range1", "range2", ...]
    },
    {
      "@id": "range1",
      "@type": "sc:Range",
      "label": "きりつほ",
      "canvases": [
        "https://example.com/canvas/p1",
        "https://example.com/canvas/p2",
        ...
      ]
    }
  ]
}

本ツールでは、structures内の各rangeから:

  1. label(巻名・章名など)
  2. canvases配列の最初の要素(冒頭ページのCanvas URL)

を抽出しています。

フォールバック処理

structuresが存在しない場合は、sequences[0].canvasesの最初の要素を取得するフォールバック処理を実装しています。

制限事項

  • IIIF Presentation API v2のみ対応 : v3形式のManifest(itemsを使用するもの)には対応していません
  • CORS制限 : Manifestを提供するサーバーがCORSを許可している必要があります

実装

純粋なHTML/CSS/JavaScriptで構成されており、サーバーサイドの処理は不要です。GitHub Pagesで静的にホスティングしています。

主要な処理の流れ:

// Manifestを取得
const response = await fetch(url);
const manifest = await response.json();

// structuresから各rangeを抽出
if (manifest.structures) {
  for (const structure of manifest.structures) {
    // 親range(rangesを持つもの)はスキップ
    if (structure.ranges && structure.ranges.length > 0) {
      continue;
    }
    // canvasesを持つrangeを処理
    if (structure.canvases && structure.canvases.length > 0) {
      const label = structure.label;
      const firstCanvas = structure.canvases[0];
      // 抽出データに追加
    }
  }
}

おわりに

このツールは、デジタルアーカイブにおける資料へのリンク作成作業を効率化するために作成しました。シンプルな構成のため、必要に応じてカスタマイズも容易です。

ご質問やフィードバックがあれば、GitHubのIssueでお知らせください。

参考