Metadata-Version: 2.4
Name: kamus-cli
Version: 0.1.1
Summary: Command-line tool for the Kamus Dewan Malay dictionary dataset
Author-email: Your Name <you@example.com>
License: MIT
Project-URL: Homepage, https://github.com/yourusername/kamus-cli
Project-URL: Repository, https://github.com/yourusername/kamus-cli
Project-URL: Issues, https://github.com/yourusername/kamus-cli/issues
Keywords: malay,dictionary,cli,kamus,nlp,bahasa
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: License :: OSI Approved :: MIT License
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Topic :: Text Processing :: Linguistic
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: click>=8.1
Requires-Dist: rapidfuzz>=3.6
Requires-Dist: rich>=13.7
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"

# kamus

A command-line tool for looking up, searching, and exporting the **Kamus
Dewan** Malay dictionary dataset (converted from PDF to JSON, ~52,212
entries).

## Data source & schema

The dataset is a flat JSON array of word entries, originally extracted
from a PDF of Kamus Dewan. Each entry looks roughly like:

```json
{
  "word": "abadi",
  "origin": "Ar",
  "rootWord": "abad",
  "aliases": ["abadi-abadi"],
  "definitions": [
    { "sense": 1, "text": "..." },
    { "sense": 2, "text": "..." }
  ]
}
```

Schema quirks this tool accounts for:

- **Numbered homonym variants** — words like `"a I"` / `"a II"` or
  `"aba I"` / `"aba II"` disambiguate unrelated words that happen to be
  spelled the same. `kamus lookup` shows all variants together when you
  search the bare word (`a`, `aba`), and shows only the requested one
  if you include the suffix explicitly (`"aba II"`).
- **`rootWord`** — links a derived form back to its base word (e.g.
  `mengabadikan` → `abadi`). `kamus root` uses this to reconstruct full
  derivation families.
- **`aliases`** — related/alternate forms, shown alongside a lookup
  result but not used for indexing.
- **`sense`** — some definitions are numbered (multiple senses), some
  aren't (single sense, just a `text` field). Both are rendered
  appropriately.
- **`origin`** — present for loanwords (`Ar` = Arabic, `Id` =
  Indonesian, etc.), absent otherwise.

Place the full 52K-entry dataset at `data/kamus.json` (a small sample is
included there for testing — replace it with the full file).

## Installation

```bash
git clone <this repo>
cd kamus-cli
pip install -e .
```

This installs the `kamus` command globally (within your active Python
environment) via the `project.scripts` entry point in `pyproject.toml`.

## Usage

### `kamus lookup <word>`

Exact lookup. Shows origin, root word, aliases, and all definitions.
Numbered homonym variants are shown together if you omit the suffix.
Falls back to fuzzy (`rapidfuzz`) suggestions if there's no exact match.

```bash
kamus lookup abadi
kamus lookup aba          # shows both "aba I" and "aba II"
kamus lookup "aba II"     # shows only that one variant
kamus lookup abadii       # no match -> "did you mean: abadi, abad, ..."
```

### `kamus random`

Word of the day — a random entry with its full definition.

```bash
kamus random
```

### `kamus search <term>`

Substring match across all words. Returns a word list only (definitions
are omitted, since this can match many entries).

```bash
kamus search abad
```

### `kamus root <word>`

Shows a word's root word (if any) and every other word in the dataset
sharing that root — the full derivation family.

```bash
kamus root mengabadikan
# Root word: abadi
# Derivation family (3 other form(s)):
#   - terabadi
#   - keabadian
#   - pengabadian

kamus root abadi          # works from the root itself too
```

### `kamus export --format <csv|json|sqlite> --output <path>`

Exports the full dataset.

- `json`: the raw nested dataset, unflattened, written as-is.
- `csv` / `sqlite`: **one row per definition (sense)**, not per word,
  since `definitions` is a nested array. Columns:
  `word, origin, root_word, aliases, sense, definition_text`. A word
  with 2 senses produces 2 rows sharing the same word/origin/etc. See
  `src/kamus/export.py` for the full rationale.

```bash
kamus export --format csv --output kamus.csv
kamus export --format sqlite --output kamus.sqlite
kamus export --format json --output kamus_export.json
```

### `--json` on every command

Every command accepts `--json` to print raw JSON instead of formatted
output, for scripting/piping:

```bash
kamus lookup abadi --json | jq '.[0].definitions'
kamus search abad --json
```

## How the data is loaded

The full JSON file is loaded into memory once per process and indexed
(by exact word, by base word for homonym grouping, by root word for
derivation families) at startup. At ~52K entries this takes a fraction
of a second and keeps the implementation simple — see the docstring at
the top of `src/kamus/data.py` for the full reasoning, including when a
heavier on-disk index would actually be worth it.

## Tests

```bash
pip install -e ".[test]"
pytest
```

Tests run against a small fixture (`tests/fixtures/sample.json`) drawn
from the real dataset's first ~14 entries, covering exact lookup,
homonym-variant handling, fuzzy-match fallback, root-word derivation
families, and export correctness (csv/json/sqlite).

## Project structure

```
kamus-cli/
├── pyproject.toml
├── README.md
├── data/
│   └── kamus.json        # full dataset goes here
├── src/kamus/
│   ├── __init__.py
│   ├── data.py            # loading + indexing
│   ├── export.py          # csv/json/sqlite export
│   └── cli.py             # click commands
└── tests/
    ├── fixtures/sample.json
    ├── test_lookup.py
    ├── test_root.py
    └── test_export.py
```
