Introduction
Generating schemas (RNG) and documentation (HTML) from TEI (Text Encoding Initiative) ODD (One Document Does it all) files is an important process in TEI projects. This article analyzes how the TEI Garage API, used internally by Roma (the TEI ODD editor), works and introduces how to call the API directly from scripts to convert ODD files.
What Is TEI Garage?
TEI Garage is a web service provided by the TEI community that can perform conversions between various formats. For ODD file processing in particular, it provides the following features:
- ODD to Compiled ODD conversion
- Compiled ODD to RELAX NG schema conversion
- ODD to HTML document conversion
- Many other format conversions
Analyzing Roma’s Internal Behavior
By observing Roma’s network traffic, we found that it uses the following conversion chains:
For HTML Document Generation
ODD → ODDC (Compiled ODD) → TEI → xHTML
Actual API endpoint:
https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion
For RNG Schema Generation
ODD → ODDC (Compiled ODD) → RELAXNG
Actual API endpoint:
https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/relaxng%3Aapplication%3Axml-relaxng/conversion
Conversion Parameter Details
Roma sends properties in the following XML format during conversion:
conversions>
conversion index="0">
property id="oxgarage.getImages">falseproperty>
property id="oxgarage.getOnlineImages">falseproperty>
property id="oxgarage.lang">japroperty>
property id="oxgarage.textOnly">falseproperty>
property id="pl.psnc.dl.ege.tei.profileNames">defaultproperty>
conversion>
conversion index="1">
property id="oxgarage.getImages">falseproperty>
property id="oxgarage.getOnlineImages">falseproperty>
property id="oxgarage.lang">japroperty>
property id="oxgarage.textOnly">trueproperty>
property id="pl.psnc.dl.ege.tei.profileNames">defaultproperty>
conversion>
conversions>
Meaning of each property:
oxgarage.getImages: Whether to include imagesoxgarage.getOnlineImages: Whether to fetch online imagesoxgarage.lang: Output language (ja=Japanese, en=English)oxgarage.textOnly: Whether to output text only (recommended to set to true for RNG generation)pl.psnc.dl.ege.tei.profileNames: Profile to use (usually default)
Implementation: Automated Conversion with a Bash Script
The following is a Bash script that converts ODD files using the TEI Garage API:
#!/bin/bash
# ODD conversion script using the TEI Garage API
# Usage: ./convert-odd.sh
# output-type: html or rng
ODD_FILE="$1"
OUTPUT_TYPE="$2"
if [ -z "$ODD_FILE" ] || [ -z "$OUTPUT_TYPE" ]; then
echo "Usage: $0 "
echo " output-type: html or rng"
exit 1
fi
BASE_NAME=$(basename "$ODD_FILE" .odd)
DIR_NAME=$(dirname "$ODD_FILE")
# HTML conversion
if [ "$OUTPUT_TYPE" = "html" ]; then
echo "Converting ODD to HTML documentation..."
# Conversion properties (for HTML)
PROPERTIES='falsefalsejafalsedefaultfalsefalsejafalsedefault'
# API endpoint (ODD → ODDC → TEI → xHTML)
API_URL="https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion"
# Upload file and convert with cURL
curl -s -o "${DIR_NAME}/${BASE_NAME}.html" \
-F upload=@"$ODD_FILE" \
"${API_URL}?properties=${PROPERTIES}"
echo "HTML documentation saved to ${DIR_NAME}/${BASE_NAME}.html"
# RNG conversion
elif [ "$OUTPUT_TYPE" = "rng" ]; then
echo "Converting ODD to RNG schema..."
# Conversion properties (for RNG - textOnly set to true)
PROPERTIES='falsefalsejatruedefaultfalsefalsejatruedefault'
# API endpoint (ODD → ODDC → RELAXNG)
API_URL="https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/relaxng%3Aapplication%3Axml-relaxng/conversion"
# Upload file and convert with cURL
curl -s -o "${DIR_NAME}/${BASE_NAME}.rng" \
-F upload=@"$ODD_FILE" \
"${API_URL}?properties=${PROPERTIES}"
echo "RNG schema saved to ${DIR_NAME}/${BASE_NAME}.rng"
fi
Python Implementation Example
For more flexible processing, Python can also be used:
#!/usr/bin/env python3
import sys
import requests
from pathlib import Path
from urllib.parse import quote
def convert_odd(odd_file, output_type='html'):
"""
Convert an ODD file using the TEI Garage API
Args:
odd_file: Path to the ODD file
output_type: 'html' or 'rng'
"""
# Prepare conversion properties in XML format
text_only = 'true' if output_type == 'rng' else 'false'
properties = f'''
false
false
ja
{text_only}
default
false
false
ja
{text_only}
default
'''
# Set the API endpoint
if output_type == 'html':
endpoint = 'ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml'
ext = '.html'
else: # rng
endpoint = 'ODD%3Atext%3Axml/ODDC%3Atext%3Axml/relaxng%3Aapplication%3Axml-relaxng'
ext = '.rng'
api_url = f'https://teigarage.tei-c.org/ege-webservice/Conversions/{endpoint}/conversion'
# Upload file and convert
with open(odd_file, 'rb') as f:
files = {'upload': f}
params = {'properties': properties}
print(f"Converting {odd_file} to {output_type.upper()}...")
response = requests.post(api_url, files=files, params=params)
if response.status_code == 200:
# Save the output file
output_file = Path(odd_file).with_suffix(ext)
output_file.write_bytes(response.content)
print(f"Successfully saved to {output_file}")
return output_file
else:
print(f"Error: {response.status_code}")
print(response.text)
return None
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python convert_odd.py ")
print(" output-type: html or rng")
sys.exit(1)
odd_file = sys.argv[1]
output_type = sys.argv[2]
if output_type not in ['html', 'rng']:
print("Output type must be 'html' or 'rng'")
sys.exit(1)
convert_odd(odd_file, output_type)
Error Handling and Notes
1. Validating API Responses
When conversion fails, TEI Garage may return an HTML error page. Always validate the response:
# Error checking example
if grep -q "HTTP Status" "${OUTPUT_FILE}"; then
echo "Error occurred during conversion"
cat "${OUTPUT_FILE}"
exit 1
fi
2. File Size Limitations
The TEI Garage API has upload file size limitations (typically a few MB). For large ODD files, consider using local conversion tools (such as Saxon-HE).
3. Network Timeouts
Since conversion processing can take time, appropriate timeout settings are needed:
# cURL timeout setting example
curl --max-time 300 -s -o output.html ...
Batch Conversion of Multiple Files
A script example for batch-converting multiple ODD files:
#!/bin/bash
# Convert all ODD files
for odd_file in *.odd; do
echo "Processing $odd_file..."
# Generate both HTML and RNG
./convert-odd.sh "$odd_file" html
./convert-odd.sh "$odd_file" rng
echo "Completed $odd_file"
echo "---"
done
API Endpoint URL Structure
TEI Garage API endpoints have the following structure:
https://teigarage.tei-c.org/ege-webservice/Conversions/{input-format}/{intermediate-format1}/{intermediate-format2}/{output-format}/conversion
Each part is specified in URL-encoded format:
ODD%3Atext%3Axml=ODD:text:xmlODDC%3Atext%3Axml=ODDC:text:xml(Compiled ODD)TEI%3Atext%3Axml=TEI:text:xmlxhtml%3Aapplication%3Axhtml%2Bxml=xhtml:application:xhtml+xmlrelaxng%3Aapplication%3Axml-relaxng=relaxng:application:xml-relaxng
Other Conversion Options
TEI Garage supports various other conversions:
ODD to XSD (XML Schema)
API_URL="https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/xsd%3Aapplication%3Axml-xsd/conversion"
ODD to DTD
API_URL="https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/dtd%3Aapplication%3Axml-dtd/conversion"
ODD to Schematron
API_URL="https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/sch%3Atext%3Axml/conversion"
Summary
By using the TEI Garage API directly, ODD file conversion can be automated without going through Roma. The benefits of this approach:
- Automation: Can be integrated into CI/CD pipelines
- Batch processing: Easy batch conversion of multiple files
- Customization: Fine-grained control over conversion parameters
- Language-independent: Can be executed anywhere curl is available
In particular, by combining version control of ODD files with automated builds, you can build an efficient development workflow while maintaining consistency between schemas and documentation.