はじめに# TEI(Text Encoding Initiative)のODD(One Document Does it all)ファイルから、スキーマ(RNG)やドキュメント(HTML)を生成する作業は、TEIプロジェクトにおいて重要な工程です。本記事では、Roma(TEIのODDエディタ)が内部で使用しているTEI Garage APIの仕組みを解析し、スクリプトから直接APIを呼び出してODDを変換する方法を紹介します。
TEI Garageとは# TEI Garageは、TEIコミュニティが提供するWebサービスで、様々なフォーマット間の変換を行うことができます。特にODDファイルの処理において、以下の機能を提供しています:
ODD → Compiled ODD への変換 Compiled ODD → RELAX NG スキーマへの変換 ODD → HTML ドキュメントへの変換 その他多数のフォーマット変換 Romaの内部動作を解析# Romaのネットワークトラフィックを観察すると、以下のような変換チェーンを使用していることがわかりました:
HTMLドキュメント生成の場合# O D D → O D D C ( C o m p i l e d O D D ) → T E I → x H T M L
実際のAPIエンドポイント:
h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / T E I % 3 A t e x t % 3 A x m l / x h t m l % 3 A a p p l i c a t i o n % 3 A x h t m l % 2 B x m l / c o n v e r s i o n
RNGスキーマ生成の場合# O D D → O D D C ( C o m p i l e d O D D ) → R E L A X N G
実際のAPIエンドポイント:
h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / r e l a x n g % 3 A a p p l i c a t i o n % 3 A x m l - r e l a x n g / c o n v e r s i o n
変換パラメータの詳細# Romaは変換時に以下のようなXML形式のプロパティを送信しています:
< c / o < < c n c / c / o v o < < < < < c o < < < < < c n e n p p p p p o n p p p p p o v r v r r r r r n v r r r r r n e s e o o o o o v e o o o o o v r i r p p p p p e r p p p p p e s o s e e e e e r s e e e e e r i n i r r r r r s i r r r r r s o s o t t t t t i o t t t t t i n > n y y y y y o n y y y y y o s n n > i i i i i i > i i i i i i > n d d d d d n d d d d d d = = = = = d = = = = = e " " " " " e " " " " " x o o o o p x o o o o p = x x x x l = x x x x l " g g g g . " g g g g . 0 a a a a p 1 a a a a p " r r r r s " r r r r s > a a a a n > a a a a n g g g g c g g g g c e e e e . e e e e . . . . . d . . . . d g g l t l g g l t l e e a e . e e a e . t t n x e t t n x e I O g t g I O g t g m n " O e m n " O e a l > n . a l > n . g i j l t g i j l t e n a y e e n a y e s e < " i s e < " i " I / > . " I / > . > m p f p > m p t p f a r a r f a r r r a g o l o a g o u o l e p s f l e p e f s s e e i s s e < i e " r < l e " r / l < > t / e < > t p e / f y p N / f y r N p a > r a p a > o a r l o m r l p m o s p e o s e e p e e s p e r s e < r " e < t " r / t > r / y > t p y d t p > d y r > e y r e > o f > o f p a p a e u e u r l r l t t t t y < y < > / > / p p r r o o p p e e r r t t y y > > 各プロパティの意味:
oxgarage.getImages: 画像を含めるかどうかoxgarage.getOnlineImages: オンライン画像を取得するかどうかoxgarage.lang: 出力言語(ja=日本語、en=英語)oxgarage.textOnly: テキストのみの出力にするか(RNG生成時はtrue推奨)pl.psnc.dl.ege.tei.profileNames: 使用するプロファイル(通常はdefault)実装:Bashスクリプトによる自動変換# 以下は、TEI Garage APIを使用してODDファイルを変換するBashスクリプトです:
# # # # O O i f B D # i # e f ! D U f i A I f l i / T U o D T S R H R i b E s u _ P [ E _ T [ N f i I a t F U e e e _ N M e # P # A # c e G e # P # A # c e n g p I T - c c x N A L " c R P u c 変 [ c R P u c / G e u L _ z h h i A M 変 $ h 変 O A I c r h 換 h 変 O A I c r h b a : t E T o o t M E 換 O o 換 P P _ U l o " o 換 P P _ U l o a r - = Y " E = U プ E I U R - " $ プ E I U R - " s a t " P $ " " 1 = $ T " ロ R エ R L - F $ " O " ロ R エ R L - F $ " h g / y $ E O U $ ( P C パ T ン L で s { H U C パ T ン L で s { R e c p 1 = D s ( d U o テ I ド = フ u A T T o テ I ド = フ u A N o e " " D a o b i T n ィ E ポ " ァ p P M P n ィ E ポ " ァ p P G A n : $ _ g u a r _ v ( S イ h イ l I L U v ( S イ h イ l I P v 2 F e t s n T e H = ン t ル o _ T e R = ン t ル o _ s I e h " I : p e a Y r T ' ト t を " a U d _ r N ' ト t を " a U c を r t L u n m P t M < ( p ア $ d R o T t G < ( p ア $ d R h 使 t m E $ t a e E i L c O s ッ { = L c Y i 用 c O s ッ { = L e 用 - l " 0 - m " n 用 o D : プ D @ } u P n o D : プ D @ } m し o t e " g ) n D / ロ I " ? m E g - n D / ロ I " ? a た d o ] y $ = v / ー R $ p e " v / ー R $ p O d r o p " O O e → t ド _ O r n O t e → t ド _ O r s D . d e $ D " D r e し N D o t = D e r e し N D o a D s r d : O D h D s O i て A D p a D x s O i て A D p v 変 h n - D _ t i D g 変 M _ e t " t i D g 変 M _ e e 換 g [ f h D F m t o D a 換 E F r i r t O o D a 換 E F r d ス i t _ I l o n C r } I t o n o n n C r } I t ク o - l m F L " s a / L i n g l s a / L i t リ d z e l I E H > → g $ E e " R y > → g $ E e o プ d > L " ] T < e { " s s N を < e { " s ト - " o E ) ; M c T . B = a ] G t c R . B = $ f $ r " L o E t A \ $ v ; r o E t A \ $ { i O o t n I e S { e s u n L e S { D l U u r h d v i E P d t c e v A i E P I e T t n o e o e → - _ R h h に e X - _ R R > P p g d n c r c N O t e e ) r N c N O _ U u " d u s x . A P o n m s G . A P N T t ) m i H o M E a i ) o M E A o _ - e o T r E R $ . o r E R M u T t n n M g } T { . n g } T E t Y y t L / . I D . / . I } p P p a i ) e h E I " i e r E / u E e t n g t S R n g n S $ t " > i d e m } _ d e g } { - " o e - l " N e - " " B t ] n x w " A x w A y ; . = e M = e \ S p . " b \ E " b E e t . 0 s } 0 s _ > h " " e / " e N e > r $ > r A n < v { < v M p i B p i E r c A r c } o e S o e . p / E p / r e C _ e C n r o N r o g t n A t n " y v M y v e E e i r } i r d s . d s = i h = i " o t " o o n m o n x s l x s g / " g / a O a O r D r D a D a D g % g % e 3 e 3 . A . A g t g t e e e e t x t x I t I t m % m % a 3 a 3 g A g A e x e x s m s m " l " l > / > / f O f O a D a D l D l D s C s C e % e % < 3 < 3 / A / A p t p t r e r e o x o x p t p t e % e % r 3 r 3 t A t A y x y x > m > m < l < l p / p / r T r r o E o e p I p l e % e a r 3 r x t A t n y t y g e % i x i 3 d t d A = % = a " 3 " p o A o p x x x l g m g i a l a c r / r a a x a t g h g i e t e o . m . n g l g % e % e 3 t 3 t A O A O x n a n m l p l l i p i - n l n r e i e e I c I l m a m a a t a x g i g n e o e g s n s / " % " c > 3 > o f A f n a x a v l h l e s t s r e m e s < l < i / % / o p 2 p n r B r " o x o p m p e l e r / r t c t y o y > n > < v < p e p r r r o s o p i p e o e r n r t " t y y i i d d = = " " o o x x g g a a r r a a g g e e . . l l a a n n g g " " > > j j a a < < / / p p r r o o p p e e r r t t y y > > < < p p r r o o p p e e r r t t y y i i d d = = " " o o x x g g a a r r a a g g e e . . t t e e x x t t O O n n l l y y " " > > f t a r l u s e e < < / / p p r r o o p p e e r r t t y y > > < < p p r r o o p p e e r r t t y y i i d d = = " " p p l l . . p p s s n n c c . . d d l l . . e e g g e e . . t t e e i i . . p p r r o o f f i i l l e e N N a a m m e e s s " " > > d d e e f f a a u u l l t t < < / / p p r r o o p p e e r r t t y y > > < < / / c c o o n n v v e e r r s s i i o o n n > > < < c c o o n n v v e e r r s s i i o o n n i i n n d d e e x x = = " " 1 1 " " > > < < p p r r o o p p e e r r t t y y i i d d = = " " o o x x g g a a r r a a g g e e . . g g e e t t I I m m a a g g e e s s " " > > f f a a l l s s e e < < / / p p r r o o p p e e r r t t y y > > < < p p r r o o p p e e r r t t y y i i d d = = " " o o x x g g a a r r a a g g e e . . g g e e t t O O n n l l i i n n e e I I m m a a g g e e s s " " > > f f a a l l s s e e < < / / p p r r o o p p e e r r t t y y > > < < p p r r o o p p e e r r t t y y i i d d = = " " o o x x g g a a r r a a g g e e . . l l a a n n g g " " > > j j a a < < / / p p r r o o p p e e r r t t y y > > < < p p r r o o p p e e r r t t y y i i d d = = " " o o x x g g a a r r a a g g e e . . t t e e x x t t O O n n l l y y " " > > t f r a u l e s < e / < p / r p o r p o e p r e t r y t > y < > p < r p o r p o e p r e t r y t y i d i = d " = p " l p . l p . s p n s c n . c d . l d . l e . g e e g . e t . e t i e . i p . r p o r f o i f l i e l N e a N m a e m s e " s > " d > e d f e a f u a l u t l < t / < p / r p o r p o e p r e t r y t > y < > / < c / o c n o v n e v r e s r i s o i n o > n < > / < c / o c n o v n e v r e s r i s o i n o s n > s ' > ' Pythonによる実装例# より柔軟な処理が必要な場合は、Pythonを使用することもできます:
# i i f f d i ! m m r r e f / p p o o f u o o m m s r r c " T A " # t p # i e a # w _ i o o i c r t t p u o " E r " e r / f l p i n f d u f o / a r n " I g " 変 x o c A s i フ t a d t n b s r t l v s 換 t p o P o e _ ァ h m l _ p o v i y e h l e G : o o プ _ e < < n I u e e : e e u イ f p p r i e e e p p s f u u p s e n s q l i r a d u ロ o r c / c / v エ t n x n x r ル o i a r e f l _ n r r y i t t r y r / u i b t r d t パ n t o c o c e ン p d t d t l を p l r i s s _ ( i i s l _ p i s t e e b . _ a _ p テ l i n o n o r ド u p # p ア e e a n p r e s n n . e t u n . _ n s p o g f u ィ y e v < < < < < n v < < < < < n s ポ t o = o = = ッ n s m t o e # o o p r : p p r = y t t e y t t e o v t i a d e i t を s e p p p p p v e p p p p p v i イ _ i r i プ ( s ( n s u u r e r r e = s ( ( x = p _ ( x d s m r d l _ X = r r r r r r e r r r r r r e o ン t n n n f ロ o = f s p 出 t t i t i i t . " " i e t " i d p p s ( A e t M = s o o o o o r s o o o o o r n ト y t . g t . ' ー d = " e o 力 p p n u n n u " a U t s y O t ( y o e o P : y L ' i p p p p p s i p p p p p s s を p h r h ド d { C n フ u u t r t t r _ r s ( y = p u ( o t r d I p 形 t f o e e e e e i o e e e e e i > 設 e = t = n t し _ ' { o = s ァ t t ( n ( ( n _ g a o 1 s e t 1 d h t i d を O e 式 r ' n r r r r r o n r r r r r o ' 定 m g t て f u ' n e イ _ _ f f r m v g u ) . s p ) d o m _ 使 D : で u ' t t t t t n t t t t t n ' = ' l ' ' p 変 i p p v r . ル f f " o " e N a ) e t a y n u _ n P p f 用 D 準 e ' i y y y y y > i y y y y y > ' = O ' O s 換 l l r e e s を i i S u E s o i : p r s o t f 3 a o i し フ ' 備 ' < n n D D : e o o r q t 保 l l u t r p n n ! u g . t i t r l て ァ h c d i i i i i d i i i i i ' D D / , a p t u a 存 e e c p r o e _ = p t v a t l h t e O イ t i o e d d d d d e d d d d d h % % / d e i e t . c u o n _ y - [ r i y e , D ル m f n x = = = = = x = = = = = t 3 3 t ' ' r n s u = w e t r s " 3 t t 1 g n p , q D の l v = " " " " " = " " " " " m A A e r : t g t s r s _ : e : : h y ] v e u o フ パ ' o e " o o o o p " o o o o p l t t i b i s _ P i s f . o p [ [ o o u ァ ス u r 0 x x x x l 1 x x x x l ' e e g ' f e { . c a t f i { t n e 2 ' m u t t イ ま t s " g g g g . " g g g g . : x x a ) } s o p o t e u l r e : ] h u t e p ル た p i > a a a a p > a a a a p t t r ' d o d h _ l e e x c t s p u を は u o r r r r s r r r r s % % a a : d s e ( b l s t o h m t u t 変 t n a a a a n a a a a n 3 3 g s _ t o y y p ) n t l t _ 換 ' _ s g g g g c g g g g c A A e p f ( = d t o v m ' b _ t r t > e e e e . e e e e . x x . f r i a = d e s n e l , e t y n y . . . . d . . . . d m m t : o l p _ s a s r y p g p g g l t l g g l t l l l e p e i 2 f ( v e t o ' ' p e ' e e e a e . e e a e . / / i e } _ 0 i r e . _ r r h e = t t n x e t t n x e O O - r u 0 l e d s o n t ) ' = I O g t g I O g t g D D c t t r : e s t d r g m h = m n " O e m n " O e D D . i o l ) p t a d n ' l t a l > n . a l > n . C C o e , . o o t . g ] ' m ' g i j l t g i j l t % % r s { w n u p " : l r e n a y e e n a y e 3 3 g } o f i s { s y ) o ' n s e < " i s e < " i A A / u i t e o _ r ) g " I / > . " I / > . t t e t l h . u c : ' > m p { p > m p { p e e g p e _ c t o o ' f a r t r f a r t r x x e u s s o p d d r e a g o e o a g o e o t t - t = u n u e d n l l e p x f l e p x f % % w _ f f t t } - g s s s e t i s s e t i 3 3 e t i f e _ " f ' e e " r _ l e " r _ l A A b y l i n f ) i " < > t o e < > t o e x x s p e x t i l ) ' / f y n N / f y n N m m e e s ( ) l e f p a > l a p a > l a l l r . , e e > a r l y m r l y m / / v u x } l o s } e o s } e T r i p p t " s p e < s p e < s E e c p a ) ) o e e < / " e < / " I l e e r u ' r / p > r / p > % a / r a t t p r d t p r d 3 x C ( m p y r o e y r o e A n o ) s u > o p f > o p f t g n } = t p e a p e a e % v . p - e r u e r u x 3 e . a t r t l r t l t A r . r y t y t t y t % a s " a p y > < y > < 3 p i ) m e > / > / A p o s > p p x l n ) " r r m i s ) o o l c / p p / a { e e x t e r r h i n t t t o d y y m n p > > l % o % 3 i 3 A n A x t a m } p l / p - c l r o i e n c l v a a e t x r i n s o g i n ' o % n 3 ' A x h t m l % 2 B x m l ' エラーハンドリングと注意点# 1. APIレスポンスの検証# 変換が失敗した場合、TEI GarageはHTMLエラーページを返すことがあります。必ず応答を検証してください:
# i f f i エ ラ g ー r e c e チ e c a x ェ p h t i ッ o t ク - " の q " $ 1 例 E { " r O H r U T o T T r P P U o T S c _ t c F a u I t r L u r E s e } " d " " d $ u { r O i U n T g P U c T o _ n F v I e L r E s } i " o ; n " t h e n
2. ファイルサイズの制限# TEI Garage APIには、アップロードファイルサイズの制限があります(通常は数MB程度)。大きなODDファイルの場合は、ローカルでの変換ツール(Saxon-HEなど)の使用を検討してください。
3. ネットワークタイムアウト# 変換処理には時間がかかることがあるため、適切なタイムアウト設定が必要です:
# c u c r U l R L の - タ m イ a ム x ア - ウ t ト i 設 m 定 e 例 3 0 0 - s o u t p u t . h t m l 複数ファイルの一括変換# 複数のODDファイルを一括変換する場合のスクリプト例:
# # f d ! o o / す r n b べ e i て o e # e e n の d c / c c / O d h H c c h h b D _ o T o o o o a D f M n n s フ i " L v v " " h ァ l P と e e C - イ e r R r r o - ル o N t t m - を i c G - - p " 変 n e の o o l 換 s 両 d d e s 方 d d t i を . . e o n 生 s s d d g 成 h h d $ ; $ " " o o $ $ d d d o o d o d d d _ _ d d f f _ _ i i f f l l i i e e l l " . e e . " " . " h r t n m g l APIエンドポイントのURL構造# TEI GarageのAPIエンドポイントは、以下の構造を持っています:
h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / T E I % 3 A t e x t % 3 A x m l / x h t m l % 3 A a p p l i c a t i o n % 3 A x h t m l % 2 B x m l / c o n v e r s i o n
0
各部分はURLエンコードされた形式で指定します:
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他の変換オプション# TEI Garageは他にも様々な変換をサポートしています:
ODD → XSD (XML Schema)# h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / T E I % 3 A t e x t % 3 A x m l / x h t m l % 3 A a p p l i c a t i o n % 3 A x h t m l % 2 B x m l / c o n v e r s i o n
1
ODD → DTD# h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / T E I % 3 A t e x t % 3 A x m l / x h t m l % 3 A a p p l i c a t i o n % 3 A x h t m l % 2 B x m l / c o n v e r s i o n
2
ODD → Schematron# h t t p s : / / t e i g a r a g e . t e i - c . o r g / e g e - w e b s e r v i c e / C o n v e r s i o n s / O D D % 3 A t e x t % 3 A x m l / O D D C % 3 A t e x t % 3 A x m l / T E I % 3 A t e x t % 3 A x m l / x h t m l % 3 A a p p l i c a t i o n % 3 A x h t m l % 2 B x m l / c o n v e r s i o n
3
まとめ# TEI Garage APIを直接使用することで、Romaを経由せずにODDファイルの変換を自動化できます。この方法のメリット:
自動化 : CI/CDパイプラインに組み込み可能バッチ処理 : 複数ファイルの一括変換が容易カスタマイズ : 変換パラメータを細かく制御可能言語非依存 : curlが使える環境ならどこでも実行可能特に、ODDファイルのバージョン管理と自動ビルドを組み合わせることで、スキーマとドキュメントの一貫性を保ちながら、効率的な開発フローを構築できます。
参考資料# 関連記事#