A prototype viewer for synchronized visualization of TEI/XML documents and high-resolution IIIF images.
- Split-View Display: TEI text on the left, IIIF images on the right
- Synchronized Pagination: Based on
<pb facs>elements in TEI - Zoom and Pan: Smooth navigation of high-resolution images with OpenSeadragon
- Intelligent Rendering: Automatic TEI → HTML transformation with semantic styles
- IIIF Protocol: International standard for image interoperability
pip-viewer/
├── frontend/ # React + Vite application
│ ├── src/
│ │ ├── components/ # XMLViewer, ImageViewer, Pagination
│ │ ├── services/ # TEI parser, IIIF service
│ │ └── hooks/ # usePagination
│ └── public/
│ ├── sample-data/ # Sample TEI files
│ ├── manifest.json # IIIF manifest (links to external images)
│ └── images/ # Optional: local images (fallback)
└── README.md # This file
- Frontend: React 18 + Vite
- Image Viewer: OpenSeadragon 5.0
- Standard: TEI (Text Encoding Initiative) + IIIF
- Image Source: IIIF Manifest (loads images from external IIIF servers)
- Zero external dependencies: No Java, no IIIF server required
- Node.js 18 or higher (download here)
That's it! No Java, no external servers, no complexity.
Check if you have Node.js:
node --versionNever used a terminal before? → See SIMPLE-SETUP.md for complete beginner instructions.
Experienced users:
# 1. Clone the repository
git clone https://github.com/friendlynihilist/pip-viewer.git
cd pip-viewer/frontend
# 2. Install dependencies
npm install
# 3. Start the application
npm run devOpen http://localhost:5173 in your browser.
To stop: press Ctrl+C
This viewer supports two ways to load images:
If you have a IIIF manifest with your manuscript images hosted on a IIIF server:
- Copy your IIIF manifest to
frontend/public/manifest.json - Make sure your TEI XML references match the canvas order (e.g.,
seq1.jpgfor first canvas,seq2.jpgfor second, etc.) - Copy your TEI XML to
frontend/public/sample-data/your-file.xml - Edit
frontend/src/components/App.jsx(line ~36):const data = await parseTEI('/sample-data/your-file.xml');
Benefits: No need to host images locally, works on static hosting (Netlify, etc.), uses high-resolution IIIF images.
If you don't have a IIIF manifest:
- Copy your manuscript images to
frontend/public/images/ - Images should be named to match your TEI references (e.g.,
seq1.jpg,seq2.jpg) - Copy your TEI XML to
frontend/public/sample-data/your-file.xml - Edit
frontend/src/components/App.jsxas above
For detailed beginner instructions, see: SIMPLE-SETUP.md
- Open browser at
http://localhost:5173 - The viewer automatically loads the sample file
sample.xml - Use pagination controls at the bottom to navigate:
- Previous/Next: Navigate between pages
- Go to page: Jump directly to a specific page
- In the right panel:
- Zoom: Mouse wheel or +/- buttons
- Pan: Drag with mouse
- Reset: Double-click
The viewer requires TEI documents with the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title>Document Title</title>
<author>Author Name</author>
</titleStmt>
<!-- other metadata -->
</fileDesc>
</teiHeader>
<!-- Optional: image map -->
<facsimile>
<surface xml:id="page1">
<graphic url="page-1.jpg"/>
</surface>
</facsimile>
<text>
<body>
<!-- Page break with image reference -->
<pb facs="#page1"/>
<p>Content of the first page...</p>
<pb facs="#page2"/>
<p>Content of the second page...</p>
</body>
</text>
</TEI>The viewer automatically transforms the following TEI elements into HTML:
| TEI Element | HTML Output | Notes |
|---|---|---|
<p> |
<p> |
Paragraph |
<head> |
<h3> |
Heading |
<lb/> |
<br/> |
Line break |
<pb facs="..."/> |
- | Page break (used for pagination) |
<hi rend="italic"> |
<em> |
Italic |
<hi rend="bold"> |
<strong> |
Bold |
<quote> |
<blockquote> |
Quote |
<list> |
<ul> |
List |
<item> |
<li> |
List item |
<note> |
<aside> |
Note |
<foreign> |
<em> |
Foreign language text |
<title> |
<cite> |
Work title |
Edit frontend/vite.config.js:
export default defineConfig({
server: {
port: 3000, // change port
}
})Problem: Right panel shows "Unable to load image" error
Solutions:
- Make sure your images are in
frontend/public/images/ - Check that image file names match the references in your TEI XML exactly
- Image names are case-sensitive on Mac/Linux
- Check browser console (F12) for detailed errors
Problem: "Unable to load TEI document" error
Solutions:
- Make sure the file is in
frontend/public/sample-data/ - Check XML syntax (must be well-formed)
- Open browser console (F12) to see detailed errors
cd frontend
npm run buildThe compiled files will be in frontend/dist/. Serve with a static web server (nginx, Apache, etc.).
The viewer is designed to be extensible. Future developments could include:
- IIIF Annotations: Integration with Annotorious or Mirador
- Full-Text Search: Search within TEI text with highlighting
- Multi-Document: Managing collections of documents
- Export: Export annotations in W3C Web Annotation format
- Scroll Synchronization: Parallel scrolling between text and image
- Version Comparison: Side-by-side visualization of different versions
frontend/src/
├── components/
│ ├── App.jsx # Main component, layout
│ ├── XMLViewer.jsx # TEI text display
│ ├── ImageViewer.jsx # OpenSeadragon integration
│ └── Pagination.jsx # Navigation controls
├── services/
│ ├── xmlParser.js # TEI parser, page extraction
│ └── iiifService.js # Image URL management
└── hooks/
└── usePagination.js # Pagination state hook
xmlParser.js:
parseTEI(path): Loads and parses TEI documentextractPages(doc): Extracts pages based on<pb>elementsextractMetadata(doc): Extracts metadata from<teiHeader>
iiifService.js:
loadManifest(): Loads IIIF manifest from/manifest.jsonbuildImageMap(): Maps image IDs (seq1.jpg, seq2.jpg) to IIIF URLs from manifestbuildImageUrl(id): Builds image URL (from manifest or local fallback)buildTileSource(id): Creates tile source for OpenSeadragon (IIIF info.json URL)
usePagination.js:
- React hook for managing pagination state and synchronization
Contributions are welcome! Areas for improvement:
- Support for more TEI elements
- File upload interface
- Annotation system
- Full-text search
- Automated tests
- Accessibility (ARIA, keyboard navigation)
MIT License - see LICENSE file for details.
Carlo Teo Pedretti
- TEI Consortium
- OpenSeadragon Team
- React and Vite communities