Files
Hankan/tools/dict/grammar-lexicon.json
MechaCat02 7bd8507909 feat(dict): build pipeline, grammar lexicon, and the shipped band files
Closes REVIEW.md §2. 167 of 371 roadmap words had no lexicon entry, so the
word rail silently showed nothing. Now:

  Roadmap words: 371/371 resolve
  Spiral targets: 35/35 resolve
  Deck words: 386/386 resolve

and npm run dict:assert makes it a blocking build failure, not a silent
empty rail.

No runtime morphological analyser ships. lib/conjugation.js surfaceForms()
runs at BUILD time over every verb and adjective, so looking up a conjugated
form is an index hit on the surface table.

The frequency join had to be inverted. A subtitle frequency list holds
surface forms; a dictionary holds lemmas whose -다 citation form barely
occurs in running text, so joining on headword gives verbs a frequency of
roughly zero. Expanding each lemma into the forms it plausibly takes and
summing recovers 하다 from 118 to 89,041. Forms claimed by more than one
lemma are dropped rather than split, so homographs don't inherit each
other's mass. Those expansions score frequency only — the surface table
itself stays strictly surfaceForms() output plus the headword.

Bands are one per curriculum phase. Phase 1 admits no frequency band at
all: during the writing-system phase every word must be phonologically
legal for the unit reached, and a rank ceiling would hand the learner a
겹받침 during unit 1.4. shared/phonology.mjs lifts validate.mjs's own
feature ladder to enforce that; it agrees with the validator on all 371
words.

Sources are chosen automatically — KRDICT when vendored, otherwise the
kaikki.org extract. KRDICT's download is a JS form behind anti-bot
protection, so it cannot be fetched by CI; the derived band files are
committed instead, which the app needs offline regardless. Attribution and
the share-alike terms are in NOTICE.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 19:13:15 +02:00

88 lines
12 KiB
JSON

{
"note": "Grammatical detail for function words, layered ON TOP of data/gloss-extra.json. gloss-extra supplies a plain English gloss for all 167 roadmap words the deck does not cover; this file adds what a gloss cannot carry — a part of speech (particle / ending / contraction / bound noun), a Korean gloss, and the allomorph rule (\uc740 after a consonant, \ub294 after a vowel). Merged LAST, so these win for the (headword, pos) pairs they define. Entries always land in band 0: function words are available from the start because the curriculum introduces them explicitly.",
"license": "Written for Hankan. No third-party dictionary content.",
"entries": [
{ "headword": "은", "pos": "particle", "gloss_en": "topic marker", "gloss_ko": "주제", "note": "after a consonant; 는 after a vowel" },
{ "headword": "는", "pos": "particle", "gloss_en": "topic marker", "gloss_ko": "주제", "note": "after a vowel; 은 after a consonant" },
{ "headword": "이", "pos": "particle", "gloss_en": "subject marker", "gloss_ko": "주격", "note": "after a consonant; 가 after a vowel" },
{ "headword": "가", "pos": "particle", "gloss_en": "subject marker", "gloss_ko": "주격", "note": "after a vowel; 이 after a consonant" },
{ "headword": "을", "pos": "particle", "gloss_en": "object marker", "gloss_ko": "목적격", "note": "after a consonant; 를 after a vowel" },
{ "headword": "를", "pos": "particle", "gloss_en": "object marker", "gloss_ko": "목적격", "note": "after a vowel; 을 after a consonant" },
{ "headword": "에", "pos": "particle", "gloss_en": "at, to, in — a place or a time", "gloss_ko": "장소·시간", "note": "where something IS or is going" },
{ "headword": "에서", "pos": "particle", "gloss_en": "at, from — where an action happens", "gloss_ko": "행동의 장소", "note": "contrast with 에: 에서 is where you DO something" },
{ "headword": "도", "pos": "particle", "gloss_en": "also, too, even", "gloss_ko": "역시", "note": "replaces 은/는 and 이/가 rather than stacking" },
{ "headword": "만", "pos": "particle", "gloss_en": "only, just", "gloss_ko": "오직", "note": "" },
{ "headword": "의", "pos": "particle", "gloss_en": "of, 's — possession", "gloss_ko": "소유", "note": "often dropped in speech" },
{ "headword": "로", "pos": "particle", "gloss_en": "by, with, toward", "gloss_ko": "방향·수단", "note": "after a vowel or ㄹ; 으로 after another consonant" },
{ "headword": "으로", "pos": "particle", "gloss_en": "by, with, toward", "gloss_ko": "방향·수단", "note": "after a consonant; 로 after a vowel or ㄹ" },
{ "headword": "와", "pos": "particle", "gloss_en": "and, with", "gloss_ko": "그리고", "note": "after a vowel; 과 after a consonant. Written register" },
{ "headword": "과", "pos": "particle", "gloss_en": "and, with", "gloss_ko": "그리고", "note": "after a consonant; 와 after a vowel. Written register" },
{ "headword": "하고", "pos": "particle", "gloss_en": "and, with", "gloss_ko": "그리고", "note": "spoken; same job as 와/과" },
{ "headword": "랑", "pos": "particle", "gloss_en": "and, with", "gloss_ko": "그리고", "note": "the most casual of 와/과 · 하고 · 랑; 이랑 after a consonant" },
{ "headword": "이랑", "pos": "particle", "gloss_en": "and, with", "gloss_ko": "그리고", "note": "after a consonant; 랑 after a vowel" },
{ "headword": "부터", "pos": "particle", "gloss_en": "from — a starting point", "gloss_ko": "시작", "note": "pairs with 까지" },
{ "headword": "까지", "pos": "particle", "gloss_en": "until, as far as, up to", "gloss_ko": "끝", "note": "pairs with 부터" },
{ "headword": "처럼", "pos": "particle", "gloss_en": "like, as", "gloss_ko": "같이", "note": "" },
{ "headword": "한테", "pos": "particle", "gloss_en": "to, for — a person", "gloss_ko": "사람에게", "note": "spoken; 에게 in writing" },
{ "headword": "에게", "pos": "particle", "gloss_en": "to, for — a person", "gloss_ko": "사람에게", "note": "written; 한테 in speech" },
{ "headword": "께", "pos": "particle", "gloss_en": "to — honorific", "gloss_ko": "높임", "note": "the honorific form of 한테 / 에게" },
{ "headword": "보다", "pos": "particle", "gloss_en": "than", "gloss_ko": "비교", "note": "comparison; distinct from the verb 보다 'to see'" },
{ "headword": "마다", "pos": "particle", "gloss_en": "every, each", "gloss_ko": "각각", "note": "" },
{ "headword": "밖에", "pos": "particle", "gloss_en": "nothing but, only", "gloss_ko": "오직", "note": "always followed by a negative" },
{ "headword": "습니다", "pos": "ending", "gloss_en": "formal declarative ending", "gloss_ko": "합쇼체", "note": "after a consonant stem; ㅂ니다 after a vowel" },
{ "headword": "ㅂ니다", "pos": "ending", "gloss_en": "formal declarative ending", "gloss_ko": "합쇼체", "note": "after a vowel stem; 습니다 after a consonant" },
{ "headword": "입니다", "pos": "ending", "gloss_en": "is, am, are — formal", "gloss_ko": "이다의 합쇼체", "note": "the formal form of 이다" },
{ "headword": "그렇습니다", "pos": "phrase", "gloss_en": "that is so, yes — formal", "gloss_ko": "그렇다의 합쇼체", "note": "formal 그래" },
{ "headword": "고", "pos": "ending", "gloss_en": "and — links two clauses", "gloss_ko": "연결", "note": "" },
{ "headword": "지", "pos": "ending", "gloss_en": "isn't it, right? — also the base for 지 않다", "gloss_ko": "확인", "note": "" },
{ "headword": "면", "pos": "ending", "gloss_en": "if, when", "gloss_ko": "조건", "note": "after a vowel; 으면 after a consonant" },
{ "headword": "으면", "pos": "ending", "gloss_en": "if, when", "gloss_ko": "조건", "note": "after a consonant; 면 after a vowel" },
{ "headword": "니까", "pos": "ending", "gloss_en": "because, since", "gloss_ko": "이유", "note": "after a vowel; 으니까 after a consonant" },
{ "headword": "어서", "pos": "ending", "gloss_en": "and so, because", "gloss_ko": "이유·순서", "note": "아서 after a bright vowel" },
{ "headword": "는데", "pos": "ending", "gloss_en": "but, and — sets up background", "gloss_ko": "배경", "note": "very common in dialogue" },
{ "headword": "지만", "pos": "ending", "gloss_en": "but, although", "gloss_ko": "대조", "note": "" },
{ "headword": "라고", "pos": "ending", "gloss_en": "quoting — \"that …\"", "gloss_ko": "인용", "note": "marks reported speech; 이라고 after a consonant" },
{ "headword": "대", "pos": "ending", "gloss_en": "they say that …", "gloss_ko": "인용 축약", "note": "contracted from 다고 해" },
{ "headword": "래", "pos": "ending", "gloss_en": "he says, she says — reported", "gloss_ko": "인용 축약", "note": "contracted from 라고 해" },
{ "headword": "냬", "pos": "ending", "gloss_en": "asks whether — a reported question", "gloss_ko": "인용 축약", "note": "contracted from 냐고 해" },
{ "headword": "재", "pos": "ending", "gloss_en": "suggests that — a reported proposal", "gloss_ko": "인용 축약", "note": "contracted from 자고 해" },
{ "headword": "한다", "pos": "form", "gloss_en": "does — plain written style", "gloss_ko": "하다의 해라체", "note": "from 하다; the register of narration and manhwa captions" },
{ "headword": "했다", "pos": "form", "gloss_en": "did — plain written style", "gloss_ko": "하다의 과거 해라체", "note": "from 하다" },
{ "headword": "였다", "pos": "form", "gloss_en": "was — plain written style", "gloss_ko": "이다의 과거 해라체", "note": "from 이다; 이었다 after a consonant" },
{ "headword": "것", "pos": "noun", "gloss_en": "thing, one — a bound noun", "gloss_ko": "사물", "note": "needs a modifier in front; 거 in speech" },
{ "headword": "거", "pos": "noun", "gloss_en": "thing, one", "gloss_ko": "것의 준말", "note": "the spoken form of 것" },
{ "headword": "수", "pos": "noun", "gloss_en": "way, possibility — as in 할 수 있다 \"can\"", "gloss_ko": "가능성", "note": "bound noun; almost always with 있다 / 없다" },
{ "headword": "때", "pos": "noun", "gloss_en": "time, when", "gloss_ko": "시간", "note": "bound noun after a modifier" },
{ "headword": "곳", "pos": "noun", "gloss_en": "place", "gloss_ko": "장소", "note": "bound noun after a modifier" },
{ "headword": "적", "pos": "noun", "gloss_en": "occasion, the experience of — as in 한 적 있다", "gloss_ko": "경험", "note": "bound noun" },
{ "headword": "뿐", "pos": "noun", "gloss_en": "only, nothing but", "gloss_ko": "오직", "note": "bound noun" },
{ "headword": "줄", "pos": "noun", "gloss_en": "how to, the fact that — as in 할 줄 알다", "gloss_ko": "방법", "note": "bound noun" },
{ "headword": "난", "pos": "contraction", "gloss_en": "I — 나 + 는", "gloss_ko": "나는", "note": "" },
{ "headword": "넌", "pos": "contraction", "gloss_en": "you — 너 + 는", "gloss_ko": "너는", "note": "" },
{ "headword": "건", "pos": "contraction", "gloss_en": "the thing — 것 + 은", "gloss_ko": "것은", "note": "" },
{ "headword": "이건", "pos": "contraction", "gloss_en": "this thing — 이것 + 은", "gloss_ko": "이것은", "note": "" },
{ "headword": "그건", "pos": "contraction", "gloss_en": "that thing — 그것 + 은", "gloss_ko": "그것은", "note": "" },
{ "headword": "뭘", "pos": "contraction", "gloss_en": "what — 무엇 + 을", "gloss_ko": "무엇을", "note": "" },
{ "headword": "절", "pos": "contraction", "gloss_en": "me — 저 + 를, humble", "gloss_ko": "저를", "note": "" },
{ "headword": "날", "pos": "contraction", "gloss_en": "me — 나 + 를", "gloss_ko": "나를", "note": "" },
{ "headword": "제가", "pos": "contraction", "gloss_en": "I — 저 + 가, humble", "gloss_ko": "저가", "note": "the humble counterpart of 내가" },
{ "headword": "내가", "pos": "contraction", "gloss_en": "I — 나 + 가", "gloss_ko": "나가", "note": "" },
{ "headword": "드리다", "pos": "verb", "gloss_en": "to give — humble", "gloss_ko": "주다의 겸양", "note": "used when the speaker gives to someone higher" },
{ "headword": "계시다", "pos": "verb", "gloss_en": "to be, to stay — honorific", "gloss_ko": "있다의 높임", "note": "the honorific of 있다, for people" },
{ "headword": "주무시다", "pos": "verb", "gloss_en": "to sleep — honorific", "gloss_ko": "자다의 높임", "note": "the honorific of 자다" },
{ "headword": "앉히다", "pos": "verb", "gloss_en": "to seat someone, to sit someone down", "gloss_ko": "앉게 하다", "note": "causative of 앉다" },
{ "headword": "나중에", "pos": "adv", "gloss_en": "later, afterwards", "gloss_ko": "이따가", "note": "" },
{ "headword": "신경 쓰다", "pos": "phrase", "gloss_en": "to care about, to be bothered by", "gloss_ko": "마음을 쓰다", "note": "신경 'nerve' + 쓰다 'to use'" },
{ "headword": "몇", "pos": "det", "gloss_en": "how many, a few", "gloss_ko": "얼마나", "note": "takes a counter after it" },
{ "headword": "명", "pos": "counter", "gloss_en": "counter for people", "gloss_ko": "사람 세는 말", "note": "" },
{ "headword": "몇 명", "pos": "phrase", "gloss_en": "how many people", "gloss_ko": "사람이 얼마나", "note": "몇 + the counter 명" },
{ "headword": "신라", "pos": "noun", "gloss_en": "Silla — the ancient Korean kingdom", "gloss_ko": "옛 나라 이름", "note": "read [실라]; a standing example of ㄴ+ㄹ becoming ㄹㄹ" }
]
}