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 the mechanism of the TEI Garage API used internally by Roma (the TEI ODD editor) 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. It provides the following capabilities for processing ODD files in particular:

  • ODD to Compiled ODD conversion
  • Compiled ODD to RELAX NG schema conversion
  • ODD to HTML documentation 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 Documentation Generation

ODDODDC(CompiledODD)TEIxHTML

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

ODDODDC(CompiledODD)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:

<c/o<<cnc/c/ovo<<<<<co<<<<<cnenppppponpppppovrvrrrrrnvrrrrrneseoooooveooooovrirppppperpppppesoseeeeerseeeeerinirrrrrsirrrrrsosotttttiotttttin>nyyyyyonyyyyyosnn>iiiiii>iiiiii>ndddddndddddd=====d=====e"""""e"""""xoooopxoooop=xxxxl=xxxxl"gggg."gggg.0aaaap1aaaap"rrrrs"rrrrs>aaaan>aaaanggggcggggceeee.eeee.....d....dggltlggltleeae.eeae.ttnxettnxeIOgtgIOgtgmn"Oemn"Oeal>n.al>n.gijltgijltenayeenayese<"ise<"i"I/>."I/>.>mpfp>mptpfararfarrragoloagouolepsflepefsseeisse<ie"r<le"r/l<>t/e<>tpe/fypN/fyrNpa>rapa>oarlomrlpmospeoseepeesperse<r"e<t"r/t>r/y>tpydtp>dyr>eyre>of>ofpapaeueurlrltttty<y<>/>/pprrooppeerrttyy>>

Meaning of each property:

  • oxgarage.getImages: Whether to include images
  • oxgarage.getOnlineImages: Whether to fetch online images
  • oxgarage.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 Bash Script

Below is a Bash script that uses the TEI Garage API to convert ODD files:

####OOifBD#i#ef!DUfiAIfli/TUoDTSRHRibEsu_P[E_T[NfiIatFUeee_NMe#P#A#ceGe#P#A#cengpIT-ccxNAL"cRPuc[cRPuc/GeuL_zhhiAM$hOAIcrhhOAIcrhba:tETootMEOoPP_Ulo"oPP_Uloar-=Y"E=UEIUR-"$EIUR-"sat"P$""1=$T"RRL-F$"O"RRL-F$"hg/y$EOU$(PCTLs{HUCTLs{Recp1=Ds(dUoI=uATToI=uANoe""DaobiTnE"pPMPnE"pPGAn:$_guar_vShlILUvShlIPv2FetsnTeH=to_TeR=to_sIeh"I:peaYrT't"aUd_rN't"aUcrtLunmPtM<p$dRoTtG<p$dRh使tmE$taeEiLcOs{=LcYicOs{=Le-l"0-m"noD:D@}uPnoD:D@}mote"gnD/I"?mEg-nD/I"?ado]y$=v/R$pe"v/R$pOdrop"OOet_OrnOtet_OrsD.de$D"DreNDot=DereNDoaDsrd:ODhDsOiADpaDxsOiADpvhn-D_tiDgM_et"tiDgM_eeg[fhDFmtoDaEFrirtOoDaEFrdit_IlonCr}ItononnCr}Ito-lmFL"sa/Linglsa/LitdzelIEH>g$Ee"Ry>g$Eeod>L"]T<e{"ssN<e{"s-"oE);McT.B=a]GtcR.B=$f$r"LoEtA\$v;roEtA\${iOotnIeS{esunLeS{DlUurhdviEPdtcevAiEPIeTtnoeoe-_RhheX-_RR>PpgdncrcNOteerNcNO_Uu"dusx.APonmsG.APNTt)miHoMEaioMEAo_-eoTrER$.orERMuTtnnMg}T{.ng}TEtYytL/.ID./.I}pPpaiehEI"ierE/uEetngtSRngnS$t">idem}_deg}{-"oe-l"Ne-""Bt]nxw"AxwAy;.=eM=e\Sp."b\E"bEet.0s}0s_>h""e/"eNe>r$>rAn<v{<vMpiBpiErcArc}oeSoe.p/Ep/reC_eCnroNrogtnAtn"yvMyveEeir}irds.ds=ih=i"ot"oonmonxslxsg/"g/aOaOrDrDaDaDg%g%e3e3.A.AgtgteeeetxtxItItm%m%a3a3gAgAexexsmsm"l"l>/>/fOfOaDaDlDlDsCsCe%e%<3<3/A/Aptptrereoxoxptpte%e%r3r3tAtAyxyx>m>m<l<lp/p/rTrroEoepIple%ear3rxtAtnytyge%ixi3dtdA=%=a"3"poAopxxxlgmgialacr/raaxatghgieteo.m.nglg%e%e3t3tAOAOxnanmlpllipi-nlnreieeIcIlmamaataxgigneoegsns/"%"c>3>ofAfnaxavlhlestsremes<l<i/%/op2pnrBr"oxopmpeler/rtctyoy>n><v<peprrrosopipeoernrt"tyyiidd==""ooxxggaarraaggee..llaanngg"">>jjaa<<//pprrooppeerrttyy>><<pprrooppeerrttyyiidd==""ooxxggaarraaggee..tteexxttOOnnllyy"">>ftarlusee<<//pprrooppeerrttyy>><<pprrooppeerrttyyiidd==""ppll..ppssnncc..ddll..eeggee..tteeii..pprrooffiilleeNNaammeess"">>ddeeffaauulltt<<//pprrooppeerrttyy>><<//ccoonnvveerrssiioonn>><<ccoonnvveerrssiioonniinnddeexx==""11"">><<pprrooppeerrttyyiidd==""ooxxggaarraaggee..ggeettIImmaaggeess"">>ffaallssee<<//pprrooppeerrttyy>><<pprrooppeerrttyyiidd==""ooxxggaarraaggee..ggeettOOnnlliinneeIImmaaggeess"">>ffaallssee<<//pprrooppeerrttyy>><<pprrooppeerrttyyiidd==""ooxxggaarraaggee..llaanngg"">>jjaa<<//pprrooppeerrttyy>><<pprrooppeerrttyyiidd==""ooxxggaarraaggee..tteexxttOOnnllyy"">>tfraules<e/<p/rporpoepretryt>y<>p<rporpoepretrytyidi=d"=p"lp.lp.spnscn.cd.ld.le.geeg.et.etie.ip.rporfoiflielNeaNmaemse"s>"d>edfeafualutl<t/<p/rporpoepretryt>y<>/<c/ocnovnevresrisoino>n<>/<c/ocnovnevresrisoinosn>s'>'

Python Implementation Example

For cases requiring more flexible processing, Python can also be used:

#iiffdi!mmrref/ppoofuoommsrrc"TA"#tp#iea#w_iooicrttpuo"Er"er/flpinfdufo/arn"Ig"xocAsitadtnbsrtlvstpoPoe_hml_poviyehleG:oo_e<<nIuee:eeufpprieeeppsfuupsensqliraduorc/c/vtnxnxroiarefl_nrryittryr/uibtrdtntococepdtdtlplriss_(iisl_pisteeb._a_plinonorup#peeanpresnn.etun._nspogfuyev<<<<<nv<<<<<nsto=o==nsmtoe#oopr:ppr=ytteytteovtiadeitsepppppvepppppvi_iri(s(nsuurerre=s((x=p_(xdsmrdl_X=rrrrrrerrrrrreotnnnfo=fspttitiit.""iet"idpps(AetM=sooooorsooooornyt.gt.'d="eoppnunnu"aUtsyOt(yoeoP:yL'ipppppsipppppssphrhd{Cnuutrttr_rs(y=pu(otrdIptfoeeeeeioeeeeei>e=t=nt_'{o=stt(n((n_gao1set1dhtidOer'nrrrrronrrrrro'mgtfu'ne__ffrmvgu).sp)dom_使D:u'tttttntttttn'='l''pippvr.ff"o"eNa)etaynu_nPpfDe'iyyyyy>iyyyyy>'=O'OsllreesiiSuEsoi:prsotf3aoi''<nnDD:eoorqtllutrpnn!ug.titrlhcdiiiiidiiiii'DD/,aptuaeecproe_=ptvatlhteOtioedddddedddddh%%/deiet.cuon_y-[riye,Dmfnx=====x=====t33t''rnsu=wetrs"3tt1gnp,qDlv="""""="""""mAAer:tgtsrs_:e::hy]veuo'oe"oooop"ooooplttibis_Pisf.op[[oouur0xxxxl1xxxxl'eeg'fe{.catfi{tne2'muttts"gggg."gggg.:xxa)}sopoteulre:]huteppi>aaaap>aaaapttr'dodh_leexctspuuorrrrsrrrrs%%aa:dse(blstohmtuttnaaaanaaaan33gs_toyyp)ntlt_'_sggggcggggcAAepf(=dtovm'b_trt>eeee.eeee.xx.fria=desnel,etyny....d....dmmt:olp_sasrypgpggltlggltlllepei2f(veto''pe'eeeae.eeae.//ie}_0ire._rrhe=ttnxettnxeOO-ru0ledsont)'=IOgtgIOgtgDDcttr:estdrgmh=mn"Oemn"OeDD.iol)ptadn'ltal>n.al>n.CCoe,.oot.g]'m'gijltgijlt%%rs{wnup":lrenayeenaye33g}ofis{sy)o'nse<"ise<"iAA/uiteo_r)g"I/>."I/>.ttetlh.uc:'>mp{p>mp{peegpe_ctoo'fartrfartrxxeussopddreagoeoagoeott-t=unuednllepxflepxf%%w_fftt}-gsssetisseti33etife_"f'ee"r_le"r_lAAbylinf)i"<>toe<>toexxspextil)'/fynN/fynNmmees()lefpa>lapa>lallr.,ee>arlymrlym//vux}los}eos}eTrippt"spe<spe<sEecpa))oee</"e</"Ileeru'r/p>r/p>%a/rattprdtprd3xC(mpyroeyroeAno)su>opf>opftgn}=tpeapeae%v.p-eruerux3e.atrtlrtltAr.rytyttyt%as"apy><y><3pi)me>/>/Apos>ppxln)"rrmis)oolc/pp/a{eexterrhintttodyymnp>>l%o%3i3AnAxtam}pl/p-clroienclvaaetxrinsogin'o%n3'Axhtml%2Bxml'

Error Handling and Notes

1. API Response Validation

When conversion fails, TEI Garage may return an HTML error page. Always validate the response:

#iffigreceecaxphtiot-"q"$1E{"rOHrUToTTrPPUoTSc_tcFauItrLurEse}"d""d$u{rOiUnTgPUcTo_nFvIeLrEs}i"o;n"then

2. File Size Limitations

The TEI Garage API has upload file size limitations (usually a few MB). For large ODD files, consider using local conversion tools (such as Saxon-HE).

3. Network Timeout

Conversion processing can take time, so appropriate timeout settings are necessary:

#cucrUlRL-max-time300-soutput.html

Batch Conversion of Multiple Files

Example script for batch converting multiple ODD files:

##fd!oo/rnbeioe#eendc/cc/OdhHcchhbD_oTooooaDfMnnsi"Lvv""hlPeeC-erRrro-oNttm-icG--p"neoolsddesddti..eonssddghhd$;$""oo$$dddoododdd__ddff__iifflliieell".ee.""."hrtnmgl

API Endpoint URL Structure

The TEI Garage API endpoint has the following structure:

https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion

0

Each part is specified in URL-encoded format:

  • ODD%3Atext%3Axml = ODD:text:xml
  • ODDC%3Atext%3Axml = ODDC:text:xml (Compiled ODD)
  • TEI%3Atext%3Axml = TEI:text:xml
  • xhtml%3Aapplication%3Axhtml%2Bxml = xhtml:application:xhtml+xml
  • relaxng%3Aapplication%3Axml-relaxng = relaxng:application:xml-relaxng

Other Conversion Options

TEI Garage supports various other conversions:

ODD to XSD (XML Schema)

https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion

1

ODD to DTD

https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion

2

ODD to Schematron

https://teigarage.tei-c.org/ege-webservice/Conversions/ODD%3Atext%3Axml/ODDC%3Atext%3Axml/TEI%3Atext%3Axml/xhtml%3Aapplication%3Axhtml%2Bxml/conversion

3

Summary

By using the TEI Garage API directly, you can automate ODD file conversion without going through Roma. The benefits of this approach:

  1. Automation: Can be integrated into CI/CD pipelines
  2. Batch processing: Easy batch conversion of multiple files
  3. Customization: Fine-grained control over conversion parameters
  4. Language-independent: Can be executed in any environment where curl is available

In particular, combining ODD file version control with automated builds enables building an efficient development workflow while maintaining consistency between schemas and documentation.

References