Next.js、CETEIcean、React TEI Routerを組み合わせたTEI/XMLビューアの開発についての備忘録です。
CETEIceanは、TEI/XML を HTML5 に変換する JavaScript ライブラリです。
https://github.com/TEIC/CETEIcean
そして、React TEI Routerは、CETEIcean をベースに React コンポーネントで TEI/XML を構造化して表示できるライブラリです。以下のように説明されています。
https://github.com/pfefferniels/react-teirouter
TEI for React using CETEIcean and routes
これらを組み合わせることで、Next.js において TEI/XML をカスタマイズして表示できるビューア を作成しました。
リポジトリ# 以下がサンプルリポジトリです。
https://github.com/nakamura196/next-ceteicean-router
実際に動作するデモも用意しています。
https://next-ceteicean-router.vercel.app/
Next.js のページコンポーネント (page.tsx)# CETEIcean を利用して XML を変換し、カスタムコンポーネントで描画します。
i i e } m m x p p p c r o o o o e r r r n < t t t t s T / u t E < T r R R d I t / E n e e e x e < t I a n f m x x b / e > < c d a l m t o < < b x ` R t e u C l > d d / d / o t ; e r l o n y i 私 d i < < d d > n f t n s > v の i v p p / i y d r f t = 名 v > p v > e o r f e " t 前 > s s > > r m o u n h y は t t m n t t p < y y x " c t e p l l m r " t = p = e e e l e @ i : " r = = C a / o ` / o s " " o c c n < / r N c c n t o ? w i a o o t " m A x w g m l l e ; p p m w i e o o n o p l . n r r t n ( t a c : : = e ) v e l o { n e i " r g g x t { r - > r r r m s s c e e e l / i . s e e C t o o p n n o e n r = ; ; n i = g " " " t " " / # > > e ; 1 n i こ こ n . s d ん ん t 0 / 1 に ば } " 1 " ち ん . > は は e 0 田 < > n " 中 / < ; c > 太 p s o 郎 > e d < g i / n p s g e t = r y " s l U N e T a = F m " - e c 8 > o " で l ? す o > 。 r : b l u e ; " > x x x < / s e g > TEIレンダリングコンポーネント# CETEIcean を使って XML を HTML5 に変換。 TEIRender + TEIRoute を使い、TEI 要素ごとにカスタムコンポーネントを適用。 import { TEIRender, TEIRoute } from "react-teirouter";を使用した上で、要素毎にコンポーネントを用意しています。
" i i i i i i i e } u m m m m m m m x s p p p p p p p p c R } i } r ) e o o o o o o o o o e , f e ; r r r r r r r r n a c } f c i } t < c t t t t t t t t s c o ; e [ ( o f u d / l t t n c c s t x t n r ) r i s } < d i R C { { { { { d . s o o e c m e s ( e ; n v t } h / i e e E e [ u t n n t h l i t t t < y d j a h 1 s } L h v n a T T D P P S f t s C s s T D C D e u d / ( l i u l e t } o 1 > t c E E i e e a e e f E t t e a o o t i r i c s < d e s s i i y f c f a > " t I I v r } g u i E e T i t n c e E n v l t T / i = p t g g l o o o d ; R s l D f t E C d D a t ) i l a y E < < < < T v { l i n h e n l n i f f e } N f } t o f c I E a o ( e E e ( s l I T T T T E > { a f I t = t o t n r r n a r c e h c T t c ) n { l m s e R E E E E I y y t : { F r S g o o d f m o f f , c D e E a ( ; t e e N = e I I I I R : C e { a : i m m e r e m r u t a a I d ] m n a { n R R R R e o m " m z T r o o n s ( t n c = a ) e t m { d o o o o n " n s c i " e E " " , m } " m c e ( a を e t ; n ) e e u u u u d f t : a l # : I r C @ t t ) イ a a a t = w r t t t t e l e l y 3 . e E T " f / " i T = ン n w ) { " r e e e e r e n " c : 3 " . a T E @ r c @ e = ス a ; = " i d > x t c ( 3 2 . c E I / o o n i > a タ = i t a e e e e " : e 1 " " 4 t I R c m m c D s ン t t i t l l l l , n 0 A , p " c o o p o R o { y ス n e n a = = = = " t 0 r x ; e u m " o m e c n 化 e C i g = " " " " c e v i " a t p @ n p n ] c w E D M { t t t t e r h a , n e o / e o d T o o t e e e e n " l " n c n n e = C E c d e i i i i t , - , ; } e o t e r E I . e i - - - - e n m s n ( R T c q : E d p p s r 1 s f t p t { e = E e u l i " e e " 2 a r s t s a > I a e " e v r g , 8 n o n e / x c ( n r v m " c s " p s m t e i t m t { ) . y e e o n x - e n / e l . ; m S r n c m a c ) s " i t e i C u a e t t o p m o " e r / s l / o s k l i } m o e m , r e e / e e n e e e c > p n " p i a l t m l t S H c a o e o f c e e e e e t T t l n n c n " t m i n m n a M o - e t o e , - e / t e t t L r r n = m n t n e / n e 5 ( l t { p t e t l p t } < ( " " = P o = i / e " / : D x t , { } n { r d m ; s o m e D e S o i e e { c l i h i n e u v n g u C - e t g t " t " x m o t i } = } e ; / ; m e n e g { r p l n t i h P " e C t e " t e ; r o n ) : r s n | t ; s n t ) " N a e n ; c a m n u a m e t l l e " : l c } ; > ( s ( 1 t n 0 r u 0 i l v n l h g ) ; - } ) 1 2 { 8 p x ) " } } カスタムコンポーネント (p.tsx の例)# pタグの例です。<TEINodes teiNodes={props.teiNode.childNodes} {...props} />を用いることで、再帰的にタグの処理を行うことができました。
i i e } m m x p p p c c r ) o o o o o e ; r r r n n t < t t t s s u p / t t r < p { { f n s T > u t s t E T g n e t ( y I E e c i y l N I t t N l e o N S i o e = d o t o d { e d y n e = s s e l t s e P = g y t ( e l e } } p p t e i r r S } N f f o o t o r r p p y c d o o s s l l e m m : . e a s t ( s = " " { e t s { r @ i e N p e / t N i a r a u e o N m o c t i d o e p t i N e d = s - l o ; e " . t s d ) m t e " e ; - e i ; : 1 i r " N o C > o u h d t i e e l . r d c " N h ; o i d l e d N } o ) d e { s } { . . . p r o p s } この方法を利用したものとして、CETEIcean を React コンポーネントとして活用し、カスタム要素を TEI にマッピングする「Astro TEI - React」がありました。
https://github.com/raffazizzi/astro-tei/tree/main/packages/react#readme
An Astro component for publishing TEI as Custom Elements powered by CETEIcean.
This utility provides the React version of CETEIcean’s default behaviors and provides a way of mapping your own React components to TEI elements via React TEI Router.
ただし、サイズが大きいTEI/XMLに対しては、 React TEI Router でレンダリングすると 再帰的に回す処理が多くなり、パフォーマンスが低下する可能性があります。
その場合、React componentとしては使用せず、CETEIceanのみを使用する方がよいかもしれません。
v C } a E ) r T d E o C I c E c u T e m E a e I n n c . t e g . a e g n t e H t = T E M l n L e e 5 m w ( e " n C U t E R B T L y E _ I I T d ( O ( ) _ " Y T O E U I R " _ ) T . E a I p . p x e m n l d " C , h i f l u d n ( c d t a i t o a n ) ( d a t a ) {
https://next-ceteicean-router.vercel.app/simple/
https://github.com/nakamura196/next-ceteicean-router/blob/main/src/app/simple/page.tsx
まとめ# ReactでのTEI/XMLの利用にあたり、参考になりましたら幸いです。