fullseye

Fullseye の多言語対応 — 全体設計 / Internationalisation design

言語ごとの文言はすべてテーブル(JSON)に一元化し、コード変更なしで追加・上書き できる。レイヤは 5 つで、それぞれ役割と機構が違う。 All translations live in JSON tables; five layers with distinct mechanisms.

対象言語(2026-09-05 決定)

ja en zh(简体) tw(繁體/台湾) ko de6 言語。半導体サプライチェーンの 主要国を見て選んだ —— 日本・米英・中国・台湾・韓国・ドイツ。

★ 台湾向け繁体字のコードは、ファイル名を 2 文字にそろえるため tw としている。 標準タグ(BCP 47)では zh-TW / zh-Hant であり、tw は本来 ISO 639-1 で Twi 語の 記号なので、OS・ブラウザから来るロケールは必ず tools/opdocs.pynormalize_lang()(対応表 LANG_ALIASES)を通してから使うこと。

レイヤ ベース言語 テーブル 切替
① Studio UI(メニュー/ボタン/ツールチップ/ガイド) 英語 studio_assets/i18n.json(strings / tooltips / guide) Tools ▸ Language(記憶される)
② ライブラリのメッセージ(例外/CLI) 英語(traceback・ログ・検索の通貨) fullseye/i18n/<lang>.json + ユーザーの FULLSEYE_I18N_DIR(後者優先) env FULLSEYE_LANG / fsi18n.set_language()
op ヘルプの枠(見出し・ラベル・入力契約) 日本語(生成器の原文) docs/i18n/opdocs.json + docs/i18n/op_summary.json ヘルプ冒頭の言語リンク / UI 言語に追従
④ コメント・docstring・op 本文 日本語 併記は ja+en まで(zh 以降は ⑤ の方式)
⑤ 散文ドキュメント(記事・ガイド・カタログ) 日本語 兄弟ファイル <name>.<lang>.md ファイルを開く

① Studio UI

② ライブラリのメッセージ(fsi18n)

例外メッセージは英語がベース(2026-08-30 に日本語のみだった 336 箇所を英語へ統一)。 その上で、切替の下地として fsi18n を用意している:

from fsi18n import msg
raise ValueError(msg("points must be (N, 3) (got shape {shape})", shape=P.shape))

③ op ヘルプの枠(生成器の対訳 — 0.1.7)

op ヘルプ(studio_assets/op_help/**)は docs/ops/** の Markdown から生成される。 生成物を直接訳しても次の再生成で消えるので、生成の入力側を訳す。

④ コメント・docstring(併記は ja+en まで)

対象外(honest)

⑤ 散文ドキュメントの対訳(兄弟ファイル方式)

対訳は原文の横に置く: <name>.md<name>.en.md / <name>.zh.mddocs/articles/exhibits/ で既にこの形が動いている(museum.ja.md / museum.en.md)。 新しい規約を増やさず、置き場所を見れば対応が分かるのが利点。

★2026-09-06: ドキュメント索引を 6 言語にした(この方式の最初の本番適用)

docs/README.md(= GitHub Pages のトップ。独自ドメイン https://furuse.work/ で 配信されている)に、README.en.md / .zh.md / .tw.md / .ko.md / .de.md の 兄弟ファイルを揃えた。入口だけが日本語のままだったのが動機 —— op ヘルプは 既に 6 言語で出ていたのに、そこへ辿り着く索引が訳されていなかった。

決めたこと 3 つ:

訳し落としの検出は機械で数える: 見出し数(^#)と表の行数が 6 ファイルで 一致すること、](*.md) のリンク先が実在すること、README.??.mdかな・ カタカナが残っていないこと(言語スイッチャの 日本語 だけは例外)。 2026-09-06 の実測は見出し 8 / 表 25 行が 6 言語すべて一致、リンク切れ 0、 かな残り 0。

導線(どこから対訳に辿り着くか)

入口 見えるもの
PyPI プロジェクトページ README.md(英語)。冒頭に総合紹介 en/ja へのリンク
GitHub リポジトリ前面 同上(同じ README)
README.md の Documentation map 総合紹介 en/ja、docs/articles/exhibits/
docs/articles/README.md 記事ハブ。ファイルと言語の対応表
各記事の冒頭 言語スイッチャ 1 行
Studio Tools ▸ Language(ja/en/zh/tw/ko/de)
Studio の op ヘルプ 頁の冒頭に言語リンク(その頁に実在する言語だけ)

v1.0.0 までの計画(実測した分量)

対象 原文の分量 状態
Studio UI(strings 44 + tooltips 36 + guide) 2,870 字 6 言語 済(0.1.7)
op ヘルプの枠(見出し・ラベル・入力契約 40 件) 3,000 字 6 言語 済(0.1.7)
README.md(= PyPI 本文) 11,881 字 英語のみ
総合紹介記事 ja 244,200 / en 390,197 字 ja + en
op 要約(1,722 本 = 全 op) 実測 6 言語すべて 1,722/1,722 済(0.1.8)
op の説明が無い op 0 本(0.1.7 で 787 → 0。分母が 935 → 1,722 になった)
docs/OP_CATALOG.md(全 op の要約) 24,041 字
知識ガイド 12 本 24,000 字
族ガイド 26 本 91,889 字 任意
op docstring 本文(1,722 本) 54 万字超 対象外

v1.0.0 のゲート = op 要約 + OP_CATALOG + 知識ガイド(言語は需要順に足す。表に 1 列足すだけで増える形になっている)。op docstring 本文 54 万字は対象外 —— 量が 桁違いで、機械翻訳で撒くと技術的に間違った主張を 6 言語に複製することになる。 README に対象外であることを明記する。

honest: 機械翻訳で量を撒かない。この repo の実測では、翻訳を撒いても読まれない (閲覧は伸びるがストックが付かない)。訳すのは判断が移る文書に絞る。