Metadata-Version: 2.5
Name: conlanggen
Version: 1.9.0
Summary: A partial-spec conlang generator: specify what you care about, sample the rest.
Project-URL: Homepage, https://codeberg.org/bmckeen/conlanggen
Project-URL: Repository, https://codeberg.org/bmckeen/conlanggen
Project-URL: Issues, https://codeberg.org/bmckeen/conlanggen/issues
Project-URL: Documentation, https://codeberg.org/bmckeen/conlanggen/src/branch/main/docs
Project-URL: Changelog, https://codeberg.org/bmckeen/conlanggen/src/branch/main/CHANGELOG.md
Author: Brian McKeen
License-Expression: MIT
License-File: LICENSE
Keywords: conlang,linguistics,procedural-generation,worldbuilding
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: pydantic<3,>=2.7
Requires-Dist: pyyaml<7,>=6
Provides-Extra: dev
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: types-pyyaml>=6; extra == 'dev'
Description-Content-Type: text/markdown

# conlang

A partial-spec constructed-language generator.

You describe only what you care about — phonology, syllable shapes, a handful of
words — and the generator **samples the rest** from typologically-plausible
defaults. Same spec plus same seed always produces byte-identical output, and
sampled entries can be locked so they survive re-sampling.

```text
spec (YAML) ──▶ generate ──▶ model (canonical JSON) ──▶ render ──▶ dictionary + grammar sketch
                                   │
                                   ├── lint   (machine-checkable invariants)
                                   └── bench  (plausibility scorecard vs. Kah)
```

The model JSON is the single source of truth; the dictionary, grammar sketch,
and every other view are rendered from it.

## Install

```powershell
pip install conlanggen
```

The distribution is `conlanggen`, but the import package and the command are both
`conlang` — `import conlang`, `conlang generate`.

## Quickstart

```powershell
# Generate from the example spec and render a Markdown dictionary.
conlang generate --spec spec\example.yaml --render

# Happy with it? Freeze it into an explicit spec so the values stick.
conlang accept --model out\veshtari.json
```

Output lands in `out/`: a model JSON and a rendered `.md`. Then:

```powershell
conlang lint   --model out\veshtari.json
conlang render --model out\veshtari.json --out out\veshtari.md
```

## Documentation

- **[Getting started](docs/getting-started.md)** — install, first language, freeze it.
- **[Spec reference](docs/spec-reference.md)** — every `spec/*.yaml` key.
- **[Feature guide](docs/guide.md)** — phonotactics, scripts, data packs, the benchmark,
  `evolve`, and syntax.
- **[The translation pipeline](docs/pipeline.md)** — translate the fixed story end to end.
- **[Releasing](docs/releasing.md)** — the Codeberg CI setup and how to cut a release.
- **[Cross-pollination](docs/cross-pollination.md)** — how `conlang` and the sibling `muna`
  project can share (the lexicon, the story, the grammar).
- **[Domain glossary](CONTEXT.md)** and **[architecture decisions](docs/adr/)**.
- **[Stability](STABILITY.md)** and the **[changelog](CHANGELOG.md)**.

## Guarantees and lint rules

Reproducibility is the one **hard** guarantee: `spec + seed ⇒ identical bytes`.
Everything else is reported by `lint` as errors or warnings, and a broken
language is still generated (conlangers want to explore broken states).

| rule | severity | meaning |
| --- | --- | --- |
| `schema` | error/warning | schema version present and known (a recognised older version warns; an unknown one errors) |
| `lexeme.root` | error | lexeme has a non-empty root |
| `phonotactics.lexeme` | error | every root is a legal word |
| `phonotactics.word` | error | every inflected form is a legal word |
| `lexicon.homophones` | warning | two roots collide (Kah has polysemy too) |
| `morphology.paradigm` | warning | a word is missing a form for a category its class realises |
| `morphology.class` | error | a word names an inflection class the language does not define |
| `lexicon.nonempty` | warning | the lexicon is empty |
| `orthography.unknown` | warning | the spelling map names a symbol that is not in the inventory |
| `orthography.collision` | warning | two symbols would spell the same thing |
| `script.coverage` | warning | the script does not cover every segment/syllable it must |

Every rule above has a test in `tests/test_lint.py`, `tests/test_lint_invariants.py`,
or `tests/test_morphology.py`.

## Stability

Starting with **1.0.0**, the model schema, the `conlang` command line, and the `Spec`
format are **stable**; within 1.x we make only additive, backwards-compatible changes. See
[`STABILITY.md`](STABILITY.md) for the promise and how deprecation works.

## Development

```powershell
.\.venv\Scripts\python.exe -m pytest
.\.venv\Scripts\python.exe -m ruff check .
.\.venv\Scripts\python.exe -m mypy src
```

The package layout:

```text
src/conlang/
  model/        canonical pydantic schema (the source of truth)
  sampling/     deterministic RNG, inventory presets, concepts, defaults
  phonology/    tokenization, syllabification, legality checks
  lexicon/      seeded root generation, stable per-item seeding
  morphology/   affixes, inflection classes, and word-form assembly
  soundchange/  ordered sound changes; derive a daughter language
  syntax/       word order, alignment, clause linearisation, place structure
  script/       writing systems (glyphs)
  render/       Markdown dictionary + grammar sketch
  lint/         machine-checkable invariants
  bench/        Kah adapter + scorecard
  cli.py        thin command-line view over the library
```

## Roadmap

**Shipped so far** (1.0 froze the core; 1.1–1.9 add tiers):

- **Phonology** — inventory, phonotactics, seeded word generation.
- **IPA inventories** — declare the inventory phonemic (`ipa: true`) and derive a
  romanised orthography alongside the phonemic forms.
- **Morphology** — affix breadth, inflection classes, and stacking.
- **Diachrony** — `conlang evolve`: ordered sound changes (with environments) derive a
  daughter language, recorded in `lineage`.
- **Syntax** — sampled word order and alignment, case marking with subject agreement, the
  predication tier, clause sequencing, and aspect.
- **Translation pipeline** — `conlang new` / `grow` / `translate` /
  `validate-translation` / `extras`, including a grammar-match **port** from a sibling.
- **Writing systems** — `conlang script`: a sampled script (alphabet / syllabary / impure
  abjad / featural) rendered as deterministic SVG glyphs.
- **Data packs** — optional, pinned PHOIBLE and WALS ground sampling (`conlang data fetch`),
  with a graceful fallback to the built-in presets.
- **Feature-driven phonology** — natural classes and feature-based sound-change rules.
- **Place structure** — an ordered list of semantic roles per predicate; role-labelled
  clauses.
- **Semantics** — negation, quantifiers, coordination, and topic/focus markers.
- **Complex clauses** — relative, complement, and reported clauses.
- **Adverbial clauses** — causal (*because*), temporal (*when*), and conditional (*if*)
  adjuncts, positioned by head direction.
- **Numerals** — a closed digit class that composes cardinals in base 10 (ordered by word
  order) and derives ordinals with an `ORD` affix.
- **Infinitives & quotation** — non-finite complements with subject control (an `inf` marker
  before a bare verb) and a `quot` particle for direct, verbatim quotation.
- **Initial mutation** — a `Mutation` table on the model plus triggers, so a language can
  **lenite/eclipse** a word's initial segment by grammatical context (Celtic); a `## Mutation`
  view and a `mutation.table` lint rule.
- **Meaning** — a compositional **meaning layer**: a typed lambda denotation per lexeme
  (derived from its place structure) and composed truth conditions (predication, negation,
  generalized quantifiers), rendered in a `## Meaning` view.
- **Model & entailment** — a spec-declared **semantic model** (a domain of individuals plus
  predicate extensions) that **evaluates** clauses to truth values and checks **entailment**
  by model-checking the declared model; a `## Model` view.
- **Lexicon converter** — `conlang convert-lexicon`: a Muna-style lexicon TSV → a spec
  `lexicon` (the `conlang` ↔ `muna` cross-pollination seam).
- **Optional alignment** — `syntax.alignment: none` marks no case (for a no-case language).
- **Modifier order** — `syntax.modifier_order` (`prenominal`/`postnominal`) decouples the noun
  phrase's modifier side from word order (so a language can be SOV and postnominal).

Planned after 1.0: validity over all models, and meaning for relatives/complements/tense.

## License

MIT (code). Kah dictionary and grammar content remains Kwesho's and is not part
of this repository.
