辞書インポート形式 辞書形式
od-dict/1 · 自作辞書をインポートするための仕様
アプリは自分の辞書を読み込めます。1 つの辞書は od-dict/1 形式の1 つの JSON
ファイルです。既存の辞書(例:Yomitan 辞書)を — 手作業または LLM で — 変換して用意すると、
アプリがそこから自前のデータベースを構築します。
この形式は jmdict-simplified のスーパーセット
(scriptin/jmdict-simplified)です。
jmdict-simplified の正しい語はそのままここでも有効なので、その出典ならほぼ変換不要です。
docs/od-dict-format.md。
1. ファイル全体
{
"format": "od-dict/1", // 必須、この文字列ちょうど
"source": "custom", // 必須;この辞書の id(§2)
"metadata": { // 任意;表示・出自情報のみ
"title": "My Dictionary",
"license": "CC BY-SA 4.0",
"url": "https://…"
},
"tags": { "v1": "Ichidan verb" }, // 任意;使用されません(§6)
"words": [
{
"id": "1259420", // 必須;ファイル内で一意(§3)
"kanji": ["食べる"], // 任意;かなのみの語では省略
"kana": ["たべる"], // 少なくとも 1 つの形(kanji か kana)が必要
"sense": [ // 必須;1 つ以上
{
"partOfSpeech": ["v1"], // 任意;コードのみ、自由文は不可(§4)
"misc": ["transitive"], // 任意;自由なラベル、そのまま表示
"gloss": [ // 訳語
{ "lang": "en", "text": "to eat" },
"食べる" // 裸の文字列 = { lang: "ru", origin: "original" }
],
"examples": [ ["ご飯を食べる", "ご飯を食べる"] ], // 任意;[日本語, 訳] の組
"references": [] // 任意;相互参照(§5)
}
]
}
]
}
2. トップレベル
| フィールド | 必須 | 意味 |
|---|---|---|
format | はい | ちょうど "od-dict/1"。 |
source | はい | 辞書全体の id 文字列。安定したスラッグ("custom"、"jitendex" など)。id と相互参照の名前空間になります。未知の source は組み込み辞書の後ろに並ぶだけで、拒否はされません。 |
metadata | いいえ | 自由なオブジェクト(title, license, url)。表示用に保存されるだけで、ビルダーは読みません。 |
tags | いいえ | jmdict-simplified 互換の コード → ラベル マップ。使用されません(§6)。表示したいラベルは misc に直接入れてください。 |
words | はい | 項目の配列。 |
セキュリティ:インポート時に source = "custom" を強制し、ファイルが "jmdict" 等を名乗れないようにする設計ですが、未実装です。検証付きインポータが入るまで source は参考値として扱ってください。
3. 語と同一性
{
"id": "1259420",
"homograph": "II", // 任意;見出し+読みが衝突する際の区別子
"label": "colloquial", // 任意;カードに表示される項目レベルのタグ
"isExpression": true, // 任意;複数語の表現
"common": true, // 任意;高頻度の項目
"kanji": ["食べる", "喰べる"], // 0…n の表記
"kana": ["たべる"], // 0…n の読み
"sense": [ /* … */ ]
}
同一性は (source, id) で、UNIQUE です。
idはファイル内で一意である必要があります。 テーブルはUNIQUE(source, source_entry_id)に対する単純なINSERTで書かれるため、idの重複はインポートのバッチを失敗・中断させます(黙って無視され ません)。出典の id を使うか、無ければ安定した一意の値(連番や見出し語)を作ってください。kanji/kanaの要素は裸の文字列(通常)か jmdict-simplified の オブジェクト{ "text": "…" }。読まれるのはtextだけで、 残りは受理されますが破棄されます。裸の文字列を推奨。- 語には少なくとも 1 つの形が必要です。日本語では
kanaを与え、 かなのみの語ではkanjiを省略します。
グループ化。 アプリは(見出し + 読み)のグループごとに 1 枚のカード
を、辞書をまたいで統合して表示します。自分のファイルでは項目ごとに 1 語
を出力し、すべての表記を kanji に、すべての読みを kana に、すべての意味を
sense にまとめてください。出典が 1 項目を複数行に分けている場合(Yomitan は共有の
sequence で行う)、先に 1 語へ統合しないと 1 項目が複数カードになります。
4. partOfSpeech — 検索を静かに壊しうる唯一のフィールド
誤った値がエラーなしに語を検索から消す唯一のフィールドです。POS は辞書形や読みでの
検索には影響しません — 食べる も たべる も常に見つかります。POS は
たった 1 か所、活用解除のゲートでのみ使われます — ユーザーが入力した活用形
(食べた、静かな)から語を見つける処理です。
| 項目の POS | 判定 | 効果 |
|---|---|---|
| 無し / 活用クラスでない | weak | それでも見つかる(順位がやや下がる) |
| 一致する活用クラス | confirmed | 見つかる(通常順位) |
| 不一致の活用クラス | rejected | 除外 — その活用形からは見つからない |
活用クラスが分からなければ partOfSpeech ごと省いてください。
無しは安全(weak)、誤りは致命的(rejected)。当てずっぽうより省略が安全です。
- コードのみ、自由文は不可。 読めるラベル(「verb」「honorific」)は
miscに入れれば、そのまま表示されます。 - 意味を持つのは活用クラスのみ。他のコード(
n、exp、vt、advなど)は検索では無視されます — 無害ですが無意味です。 - Yomitan の罠:潰れた
v5をコピーしないこと。 エンジンにv5クラスは無く、具体的なもの(v5k、v5r…)が必要です。 裸の"v5"は何にも一致せずrejectedとなり、無タグより悪いです。definitionTagsから具体コードを取るか、辞書形の末尾かなで展開するか、省略を。
エンジンが理解する活用クラス:
v1 一段(-ru): 食べる, 見る
v5u v5k v5g v5s v5t v5n v5b v5m v5r 五段(辞書形の末尾かなで区別)
vk 来る(kuru)
vs vs-i vs-s する動詞
adj-i い形容詞: 高い, 良い
adj-na な形容詞: 静か, 綺麗
5. 語釈・言語・相互参照
"гулять" // 裸の文字列 = { "lang": "ru", "origin": "original" }
{ "lang": "en", "text": "to take a walk" }
{ "lang": "ru", "text": "то же, что {0}", "origin": "original" }
- 裸の文字列はロシア語(
lang: "ru")。他の言語ではオブジェクト形式でlangを指定します。 originは"original"(既定)か"machine"(AI 生成);表示のみ。langと検索の関係:lang: "ru"の語釈はロシア語検索 チャンネルへ、それ以外のlangはすべて英語チャンネルへ入ります。 チャンネルはユーザーが入力した文字種で選ばれます(キリル → ru、ラテン → en)。よって和英辞書の 語釈は英語検索に届くようlang: "en"にする必要があります。単言語の日本語語釈 (lang: "ja")は en チャンネルに入り、事実上「表示専用」になります — 見出しと読みでは 見つかりますが、定義文では見つかりません。
相互参照 — 語釈文中の ICU プレースホルダ {0}、{1} … を
references 配列で解決します:
{
"gloss": [ { "lang": "en", "text": "polite form of {0}" } ],
"references": [ { "label": "", "to": "1234567", "text": "言う" } ]
}
{0}はその位置でreferences[0].textに、タップ可能なリンクとして置き換えられます。toは同じファイル内の対象語のidで、リンクは{ source: <この辞書>, id: to }を開きます。一致しないtoは何も開きません。labelは関係マーカー("see"、"cf.")で、{n}の無い 末尾参照に使います。語釈文中のリテラル{は'{'(ICU エスケープ)と書きます。
6. この形式が持たないもの
次のものはアプリが表記・読みをキーに自前データから付与し、辞書間で一致させます — 指定不要
です:ピッチアクセント、ふりがな、ローマ字、頻度/「common」、音声、JLPT・WaniKani レベル、漢字の
内訳。また(互換のため受理はされるが)使用されないもの:トップレベルの tags マップ、
形ごと・語釈ごとの追加属性。カードは misc/field/dialect を
自由文字列としてそのまま表示します(コード展開なし)ので、読めるラベルを直接入れてください。
7. 最小例
最小の語 — かなのみと語釈 1 つ:
{ "id": "w1", "kana": ["ありがとう"], "sense": [ { "gloss": [ { "lang": "en", "text": "thank you" } ] } ] }
// (a) JA→EN 五段。POS は具体クラス v5k で、Yomitan の "v5" ではない。
{ "id": "1578850", "kanji": ["書く"], "kana": ["かく"],
"sense": [ { "partOfSpeech": ["v5k", "vt"],
"gloss": [ { "lang": "en", "text": "to write; to compose; to pen" } ] } ] }
// (b) JA→EN 内部相互参照つき。
{ "id": "敷衍", "kanji": ["敷衍", "敷延"], "kana": ["ふえん"],
"sense": [ { "gloss": [ { "lang": "en", "text": "amplification (cf. {0})" } ],
"references": [ { "label": "", "to": "演繹", "text": "演繹" } ] } ] }
// (c) かなのみの な形容詞。adj-na は活用クラスなのでタグ付けが有効。
{ "id": "1000230", "kana": ["きれい"],
"sense": [ { "partOfSpeech": ["adj-na"], "gloss": [ { "lang": "en", "text": "pretty; clean; neat" } ] } ] }
8. POS 許可リスト
これらのいずれか(またはそれで始まる jmdict サブクラス)の場合のみ partOfSpeech に
コードを入れてください。それ以外は人間向けラベルを misc に入れ、ここでは省略します。
v1
v5u v5k v5g v5s v5t v5n v5b v5m v5r
vk
vs vs-i vs-s
adj-i
adj-na
潰れた Yomitan の "v5" → 辞書形の末尾かなで展開:
う→v5u く→v5k ぐ→v5g す→v5s つ→v5t ぬ→v5n ぶ→v5b む→v5m る→v5r。
不明なら省略。