TEI Garage APIを使って、DOCX → TEI/XML 変換ツールをブラウザだけで作った

はじめに TEI (Text Encoding Initiative) は、人文学分野のテキストをデジタルで構造化するための国際標準です。図書館・博物館・学術研究などで利用されていますが、TEI/XML を直接書くにはマークアップの知識が必要で、導入のハードルが高いのが実情です。 そこで活用されるのが、Microsoft Word (.docx) から TEI/XML への変換ツールです。代表的なものに TEI Garage(旧 OxGarage)がありますが、多機能ゆえに UI がやや複雑です。今回、DOCX → TEI/XML の変換に特化した、シンプルなブラウザベースのツールを作成しました。 https://github.com/nakamura196/tei-converter デモサイト: https://tei-converter.pages.dev/ 仕組み TEI Garage は REST API を公開しており、以下のエンドポイントに DOCX ファイルを POST するだけで TEI/XML が返ってきます。 P O S d T T o E c I h x : t : t t a e p p x s p t : l : / i x / c m t a l e t / i i g o a n r : a v g n e d . . t o e p i e - n c x . m o l r f g r e m g a e t - s w - e o b f s f e i r c v e i d c o e c / u C m o e n n v t e . r w s o i r o d n p s r / o c e s s i n g m l . d o c u m e n t / 本ツールはこの API を呼び出すフロントエンドです。変換処理自体は TEI Consortium が運営するサーバ上で行われます。 ...

2026年3月1日 · 2 分 · Nakamura

ethers.js v6 の日本語チュートリアルを作った

はじめに Ethereum の JavaScript ライブラリである ethers.js の日本語チュートリアルを作成しました。 https://github.com/nakamura196/ethers-ja-tutorial VitePress で静的サイトとしても公開しています。 https://nakamura196.github.io/ethers-ja-tutorial/ 作った背景 ethers.js は Ethereum 開発において最も広く使われているライブラリの一つです。v6 に関する日本語記事は v5 からのマイグレーション解説が中心で、初心者がゼロから学べる体系的なチュートリアルは見当たりませんでした。公式ドキュメントも英語のみのため、日本語で基礎から順を追って学べるチュートリアルを作成しました。 チュートリアルの内容 全 8 章構成で、基礎から実践的な内容までカバーしています。 章 テーマ 内容 1 環境構築 Node.js と ethers.js のインストール 2 プロバイダー Ethereum ネットワークへの接続 3 ウォレット ウォレットの作成と管理 4 ブロックチェーンの読み取り 残高確認・ブロック情報の取得 5 トランザクション送信 ETH の送金 6 スマートコントラクト コントラクトとのやり取り 7 イベント イベントのリスニング 8 ユーティリティ 単位変換・ハッシュなどの便利機能 特徴 すぐに動くサンプルコード付き examples/ ディレクトリに実行可能なサンプルコードを用意しています。 g c n n i d p o t m d e e c t i l h n e o e s x n r t a e s a m - l p h j l l t a e t - s p t / s u 0 : t 1 / - r c g i o i a n t l n h e u c b t . . c m o j m s / n a k a m u r a 1 9 6 / e t h e r s - j a - t u t o r i a l . g i t たとえば 01-connect.mjs を実行すると、Ethereum メインネットの最新ブロック番号やガス価格が取得できます。 ...

2026年2月25日 · 3 分 · Nakamura

Annotoriousの描画モードがproduction buildでだけ壊れる

はじめに ある日、Vercelにデプロイした IIIF アノテーションエディタで、アノテーションが一切付与できなくなっていることに気づきました。ローカルの開発サーバーでは正常に動作するのに、本番環境でだけ描画モードに入れない。コンソールエラーも出ない。UIのボタンは正しく切り替わるのに、画像上でドラッグしても何も起きない——。 原因は、package.json のキャレット指定(^)による Annotorious の自動アップグレードと、v3.7.13 での状態管理ライブラリ移行が webpack の production build で引き起こす不具合でした。 この記事では、調査過程から根本原因の特定、そして得られた教訓までをまとめます。 環境 フレームワーク : Next.js 15 (App Router) 画像ビューア : OpenSeadragon 5 アノテーション : Annotorious v3 (@annotorious/react + @annotorious/openseadragon) バンドラ : webpack(Next.js 内蔵) デプロイ先 : Vercel 症状 本番環境(Vercel)で以下の症状が発生しました。 矩形・ポリゴンの描画ツールボタンをクリックすると、UIの状態は正しく切り替わる (React の state 更新は正常) しかし Annotorious が描画モードに入らない ——カーソルが crosshair に変わらず auto のまま 画像上でクリック&ドラッグしてもアノテーションが作成されない コンソールにエラーは一切表示されない Annotorious のアノテーションレイヤー要素(a9s-gl-canvas)自体は DOM 上に正しく描画されている ローカルの next dev では完全に正常動作するため、再現が困難な状況でした。 調査過程 1. Playwright による自動テスト まず Playwright を使って、デプロイ済みサイトに対する自動テストを実施しました。 ...

2026年2月25日 · 7 分 · Nakamura

RAWGraphs 2.0 の日本語化

はじめに データ可視化ツール RAWGraphs を日本語化し、公開しました。 https://rawgraphs-ja.vercel.app/ RAWGraphsは、複雑なデータを美しいビジュアライゼーションに変換できるオープンソースのWebアプリケーションです。コーディング不要で、CSVやJSONデータをドラッグ&ドロップするだけで、様々なチャートを作成できます。 RAWGraphsとは RAWGraphsは、イタリアのDensityDesign Research Labが開発したデータ可視化ツールです。 https://www.rawgraphs.io/ 主な特徴: コーディング不要 : ブラウザ上でデータをペーストするだけ 多様なチャート : Alluvial Diagram、Treemap、Voronoi Tessellationなど30種類以上 SVGエクスポート : 作成したチャートをSVGやPNG形式でダウンロード可能 プライバシー保護 : データはサーバーに送信されず、ブラウザ内で処理 使用ライブラリ { } " " i r 1 e 8 a n c e t x - t i " 1 : 8 n " e ^ x 2 t 1 " . : 1 0 " . ^ 0 1 " 1 , . 1 8 . 6 " ! ...

2025年12月3日 · 9 分 · Nakamura

Ace.jsでTeXをハイライトする

概要 Ace.jsでTeXをハイライトする機会がありましたので、備忘録です。 以下の記事を参考にしました。 https://banatech.net/blog/view/11 参考になりましたら幸いです。 画面例 デモサイト https://nakamura196.github.io/ace_latex/ リポジトリ https://github.com/nakamura196/ace_latex ソースコード < テ h \ \ キ \ \ / t < < u u b ス 右 e h m h / b s s e ト 注 n / t l e < h o < < < e e g { d b m a t e d d s s p p i ( { / o l l d i a y i c s i c r / c c a a n サ d c e e e e e e } e s d > a > t d > v r r n r e s r o c c { ン o d d d d d d ) d c y n l > i c t o f c i n k k d プ c n i i i i i i e e ; i r > g e i p = e s e r p s a a o ル u s e t t t t t t n n t i = > d t " g s r i t t g g c ) m t d o o o o o o a a o p " A = h r o r p > e e u } e i r r r r r r b b r t e C " t i r e t t [ { m テ n e t . . . . . . l l . > n E e t t i r > e d m e キ t d o s g g g $ s e e s " d p y g p x v u n ス } i r e e e e b e B S e > i i s = i o t i l t ト ` t . t t t t l t a n t n t : " n l p t } ; o s F S S S o O s i V o / s = i = s i r e o e e e c p i p a A r / h " c ] c t n s s s k t c p l c " c a a y ` { o = T t s s s S i A e u t d 5 n = \ g l h S i i i c o u t e i s n 1 o " \ r } a e i o o o r n t s ( o t j 2 n n u a c m z n n n o s o : t n y s - y o s p e e e ( ( ( l ( c e < l . o m - e h . ( ( ) ) ) l { o t x / e c V o r p i e " 1 . . . i m r t t = l y u e a c d a 4 s s s n p u , i " o p s f c s i c ) e e e g l e t w u 4 " e k } t e ; t t t e , 1 l i d 8 r a ( / M U T = t ) e d f / r g " t o s a i ; > t l 6 e e e h d e b I o h a 1 r { d e e W S n n : r 0 " h i m ( r i f : e D i t e " a z i 1 . 5 r o / a p e n t 0 c J a r m c M ( i r 0 o o g " o e 4 t u % m 5 i ) n d ) y e ; / 7 n ; o m e ; ; , a 7 o k o ( h j c , a d t e a v r i e r i x p y " / u g / 2 u ) l e h l v m ; a ) t i X i t ; : b + n e s F , x 4 / c c " 0 a 0 i ) 0 c k d ; p e Y } x / a ; 1 I . 6 b 2 s o 3 2 r . t d 2 Z e / R r a q : c B e R 1 . z p j j x s Z " h s 7 o + l y i / d v O g E r H a T y z ; U " e > f < b / X d k i / v B > 8 P 0 B 7 6 b O K 3 t L 1 z e F / Q c X l y i A = = "

2023年7月9日 · 5 分 · Nakamura

Fuse.jsを使用した完全不一致検索(GPT-4による解説)

はじめに 以前に以下の記事を執筆しましたが、GPT-4による解説の方が有用でしたので紹介します。 完全不一致検索を JavaScript で実装する方法 Fuse.js は、クライアントサイドで動作する軽量なファジーサーチライブラリです。ただし、今回の目的である完全不一致検索 には向いていません。代わりに、JavaScript の Array メソッドを使って簡単に実装できます。 完全不一致検索の例 次の例では、filter メソッドを使って完全不一致検索を行います。 c ] c c ) c o ; o o ; o n { } { } n n ( n s , , s s i s t t c t c t t t o i o i o e l d t n t n s r m e a l t l t e e ) . t e e e e a s l a : n : n 他 r u = o t t の c l > g = ' : ' : デ h t ( E E ー T s i r [ x ' x ' タ e t e a T a T r = e s m h m h m m u p i p i d . l l s l s = a t t e e t i s i i ' a t ) T s T s E . l ; i i x f e t a t a a i l n l n m l ! e e p t = e e l e = 1 x 2 x e r ' a ' a ( s , m , m T e p p i a l l t r e e l c e h c c T o o 1 e n n ' r t t ; m e e n n & t t & f f i o o t r r e m t t . h h c e e o n f s t i e e r c n s o t t n d ! i = t i = e t m e s . m e ' . a , ' r , c h T e r m この例では、data 配列から searchTerm と完全に一致しない要素をフィルタリングしています。title と content の両方が searchTerm と一致しない場合、要素が結果の配列に含まれます。 ...

2023年3月17日 · 2 分 · Nakamura

Fuse.jsを使用した完全不一致検索の部分的な実現

概要 Fuse.jsはJavascript製の検索エンジンです。 https://fusejs.io/ フロントエンドのみで完結するアプリを作成する際の検索エンジンとして重宝しています。 今回、Fuse.jsを用いた完全不一致検索を実現するにあたり、クエリを工夫する必要があったため、その備忘録です。 高度な検索 Fuse.jsでは、完全・部分一致、部分不一致など、多様な検索が可能です。以下のページに記載があります。 https://fusejs.io/examples.html#extended-search また、以下の記事で日本語訳が公開されています。 https://qiita.com/Sashimimochi/items/4972b3dc333c6e5fb866#より高度な検索 ただし、完全不一致検索については、クエリを工夫する必要がありました。 完全不一致検索 例えば、labelというフィールドに「悪党」という文字列を持たない検索は、以下のようなクエリで部分的に実現できました。「悪党で始まらない」または「悪党で終わらない」を検索しています。 { } " ] $ { } { } o " , " r l l " a a : b b e e [ l l " " : : " " ! ! ^ 悪 悪 党 党 $ " " # # 「 「 悪 悪 党 党 で で 始 終 ま わ ら ら な な い い 」 」 ただし、上記のクエリは完全ではなく、「悪党と悪党」といった値を持つものも除外してしまう点に注意が必要です。 ...

2023年3月14日 · 1 分 · Nakamura

[TEI x JavaScript] Nuxt3で意図しないWhitespaceを削除する

課題 TEI/XMLファイルを読み込み、JavaScript(Vue.jsなど)で可視化を行う際、意図しないWhitespaceが入ってしまうケースがありました。 具体的には、以下のようなHTMLを書いた場合、 < t / e < t m d / e p i お < お d m l v 問 a 願 i p a > い い v l t 合 h し > a e わ r ま t > せ e す e は f > = " # " > こ ち ら か ら < / a > 以下のように表示され、「お問い合わせは こちらから お願いします」と意図しないスペースが入ってしまいました。 ...

2022年10月25日 · 4 分 · Nakamura