👻

TEI古典籍ビューワをカスタマイズして判読不能箇所(gap)を表示する

に公開

はじめに

東アジアの古典籍をデジタル化する際、TEI(Text Encoding Initiative)ガイドラインに準拠したXMLでマークアップすることが一般的になっています。一般財団法人人文情報学研究所が開発した「TEI古典籍ビューワ」は、このようなTEI/XMLファイルをブラウザで簡単に表示できる便利なツールです。

今回、このビューワをカスタマイズして、判読不能箇所を示す<gap>タグの表示に対応しました。本記事では、そのカスタマイズ方法を紹介します。

課題:gapタグが表示されない

古典籍のデジタル化において、虫損や破損などにより判読できない箇所は<gap>タグでマークアップします。

<gap reason="illegible" quantity="2" unit="character"/>

しかし、標準のTEI古典籍ビューワでは、このタグが適切に表示されません。そこで、判読不能な文字数分の黒四角(■)を表示し、マウスホバーで理由を確認できるようにカスタマイズしました。

カスタマイズの方針

TEI古典籍ビューワは以下のファイル構成になっています。

├── index.html
├── app.min.js      ← ビューワ本体(minify済み)
├── app.min.css
├── app_conf.js     ← 設定ファイル
└── lib/            ← 依存ライブラリ

app.min.jsを直接編集すると、本体のアップデート時に変更が失われてしまいます。そこで、app_conf.jsのみを編集することで、本体との互換性を保ちながらカスタマイズを実現しました。

実装方法

1. MutationObserverによるDOM監視

TEI古典籍ビューワはXMLをパースしてDOMに変換します。この変換後のタイミングで<gap>タグを処理するため、MutationObserverを使用してDOM変更を監視します。

// MutationObserverでDOM変更を監視
const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
        mutation.addedNodes.forEach(node => {
            if (node.nodeType === Node.ELEMENT_NODE) {
                processGapElements(node);
            }
        });
    });
});

// body_resultの監視を開始
document.addEventListener('DOMContentLoaded', () => {
    const bodyResult = document.getElementById('body_result');
    if (bodyResult) {
        observer.observe(bodyResult, { childList: true, subtree: true });
    }
});

2. gapタグの処理

<gap>タグを検出したら、quantity属性の値に応じて黒四角を表示し、reason属性をツールチップとして設定します。

function processGapElements(container) {
    const gaps = container.querySelectorAll('gap, .gap, [data-original-tag-name="gap"]');
    gaps.forEach(gap => {
        // 既に処理済みの場合はスキップ
        if (gap.dataset.gapProcessed) return;
        gap.dataset.gapProcessed = 'true';

        // 属性から値を取得
        const quantity = parseInt(gap.getAttribute('quantity') || '1', 10);
        const reason = gap.getAttribute('reason') || '';

        // ■をquantity分だけ生成
        const placeholder = '■'.repeat(quantity);
        gap.textContent = placeholder;

        // ツールチップの設定(日本語化)
        const reasonMap = {
            'illegible': '判読不能',
            'damage': '破損',
            'worm': '虫損',
            'omitted': '省略',
            'cancelled': '抹消',
            'lost': '欠損'
        };
        const reasonText = reasonMap[reason] || reason;
        if (reasonText) {
            gap.setAttribute('title', reasonText);
        }
        gap.style.color = '#333';
        gap.style.cursor = 'help';
    });
}

ポイント:属性の取得方法

TEI古典籍ビューワがXMLをHTMLに変換する際、属性の扱いは要素によって異なります。<gap>タグの場合、XML属性がそのまま保持されるため、getAttribute()で直接取得できます。

// XMLの属性名がそのまま保持されている場合
const quantity = gap.getAttribute('quantity');

// data-*形式に変換される場合はdatasetを使用
const quantity = gap.dataset.quantity;

実際のDOM構造をブラウザの開発者ツールで確認することが重要です。

追加カスタマイズ

同様の手法で、以下の機能も追加しました。

GETパラメータによる高さ指定

テキスト表示部の高さをURLパラメータで指定できるようにしました。

index.html?height=800
const params = new URLSearchParams(window.location.search);
const height = params.get('height');
if (height) {
    const heightValue = parseInt(height, 10);
    if (!isNaN(heightValue) && heightValue > 0) {
        document.getElementById('text_body').style.height = heightValue + 'px';
    }
}

ページタイトルの設定

TEI/XMLに複数の<title>要素がある場合、1つ目のタイトルをページタイトルに設定します(デフォルトでは最後のタイトルが使用されます)。

<titleStmt>
  <title>メインタイトル</title>  <!-- これがページタイトルになる -->
  <title type="sub">副題</title>
</titleStmt>

書誌情報(sourceDesc/bibl)の表示改善

<sourceDesc>内の<bibl>要素を見やすく整形するため、CSSで各要素にラベルを付けてブロック表示にしました。

.sourceDesc .bibl title,
.sourceDesc .bibl editor,
.sourceDesc .bibl publisher,
.sourceDesc .bibl date,
.sourceDesc .bibl idno,
.sourceDesc .bibl note {
    display: block;
    margin-bottom: 0.3em;
}
.sourceDesc .bibl title::before { content: "【書名】"; font-weight: bold; }
.sourceDesc .bibl editor::before { content: "【編者】"; font-weight: bold; }
.sourceDesc .bibl publisher::before { content: "【出版者】"; font-weight: bold; }
/* ... */

これにより、以下のような見やすい表示になります:

【書名】○○○○
【編者】△△△△
【出版者】□□堂
【年代】江戸時代
【請求記号】A100:123
【所蔵】○○図書館 △△文庫

まとめ

TEI古典籍ビューワは、設定ファイルapp_conf.jsを編集することで柔軟にカスタマイズできます。今回紹介したMutationObserverを使った手法は、他のTEIタグへの対応にも応用可能です。

カスタマイズしたコードは以下のリポジトリで公開しています。

参考リンク

謝辞

TEI古典籍ビューワを開発・公開されている永崎研宣氏(一般財団法人人文情報学研究所)、本間淳氏(フェリックス・スタイル)に感謝いたします。

Discussion